mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +00:00
+ Support for folloing websites' links in-place. The actual link is followed for
the website, while the query word is set to the link's text as used for all other dictionaries in the group. * Some associated cleanup (better scrolling to articles, better external link handling). The changes might cause problems - test!
This commit is contained in:
parent
2b2de01e95
commit
05d53409bf
|
@ -112,7 +112,8 @@ std::string ArticleMaker::makeNotFoundBody( QString const & word,
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(
|
||||
QString const & inWord, unsigned groupId ) const
|
||||
QString const & inWord, unsigned groupId,
|
||||
QMap< QString, QString > const & contexts ) const
|
||||
{
|
||||
if ( groupId == UINT_MAX )
|
||||
{
|
||||
|
@ -191,7 +192,8 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(
|
|||
activeGroup && activeGroup->icon.size() ?
|
||||
activeGroup->icon : QString() );
|
||||
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "", activeDicts, header );
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "",
|
||||
contexts, activeDicts, header );
|
||||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > ArticleMaker::makeNotFoundTextFor(
|
||||
|
@ -226,9 +228,11 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeEmptyPage() const
|
|||
|
||||
ArticleRequest::ArticleRequest(
|
||||
QString const & word_, QString const & group_,
|
||||
QMap< QString, QString > const & contexts_,
|
||||
vector< sptr< Dictionary::Class > > const & activeDicts_,
|
||||
string const & header ):
|
||||
word( word_ ), group( group_ ), activeDicts( activeDicts_ ),
|
||||
word( word_ ), group( group_ ), contexts( contexts_ ),
|
||||
activeDicts( activeDicts_ ),
|
||||
altsDone( false ), bodyDone( false ), foundAnyDefinitions( false ),
|
||||
closePrevSpan( false )
|
||||
{
|
||||
|
@ -295,7 +299,8 @@ void ArticleRequest::altSearchFinished()
|
|||
for( unsigned x = 0; x < activeDicts.size(); ++x )
|
||||
{
|
||||
sptr< Dictionary::DataRequest > r =
|
||||
activeDicts[ x ]->getArticle( wordStd, altsVector );
|
||||
activeDicts[ x ]->getArticle( wordStd, altsVector,
|
||||
gd::toWString( contexts.value( QString::fromStdString( activeDicts[ x ]->getId() ) ) ) );
|
||||
|
||||
connect( r.get(), SIGNAL( finished() ),
|
||||
this, SLOT( bodyFinished() ) );
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#define __ARTICLE_MAKER_HH_INCLUDED__
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include "dictionary.hh"
|
||||
|
@ -40,7 +41,10 @@ public:
|
|||
/// The result is returned as Dictionary::DataRequest just like dictionaries
|
||||
/// themselves do. The difference is that the result is a complete html page
|
||||
/// with all definitions from all the relevant dictionaries.
|
||||
sptr< Dictionary::DataRequest > makeDefinitionFor( QString const & word, unsigned groupId ) const;
|
||||
/// Contexts is a map of context values to be passed to each dictionary, where
|
||||
/// the keys are dictionary ids.
|
||||
sptr< Dictionary::DataRequest > makeDefinitionFor( QString const & word, unsigned groupId,
|
||||
QMap< QString, QString > const & contexts ) const;
|
||||
|
||||
/// Makes up a text which states that no translation for the given word
|
||||
/// was found. Sometimes it's better to call this directly when it's already
|
||||
|
@ -68,6 +72,7 @@ class ArticleRequest: public Dictionary::DataRequest
|
|||
Q_OBJECT
|
||||
|
||||
QString word, group;
|
||||
QMap< QString, QString > contexts;
|
||||
std::vector< sptr< Dictionary::Class > > const & activeDicts;
|
||||
|
||||
std::set< gd::wstring > alts; // Accumulated main forms
|
||||
|
@ -82,6 +87,7 @@ class ArticleRequest: public Dictionary::DataRequest
|
|||
public:
|
||||
|
||||
ArticleRequest( QString const & word, QString const & group,
|
||||
QMap< QString, QString > const & contexts,
|
||||
std::vector< sptr< Dictionary::Class > > const & activeDicts,
|
||||
std::string const & header );
|
||||
|
||||
|
|
|
@ -63,8 +63,27 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
|
|||
QString word = url.queryItemValue( "word" );
|
||||
unsigned group = url.queryItemValue( "group" ).toUInt( &groupIsValid );
|
||||
|
||||
// Unpack contexts
|
||||
|
||||
QMap< QString, QString > contexts;
|
||||
|
||||
QString contextsEncoded = url.queryItemValue( "contexts" );
|
||||
|
||||
if ( contextsEncoded.size() )
|
||||
{
|
||||
QByteArray ba = QByteArray::fromBase64( contextsEncoded.toAscii() );
|
||||
|
||||
QBuffer buf( & ba );
|
||||
|
||||
buf.open( QBuffer::ReadOnly );
|
||||
|
||||
QDataStream stream( &buf );
|
||||
|
||||
stream >> contexts;
|
||||
}
|
||||
|
||||
if ( groupIsValid && word.size() ) // Require group and word to be passed
|
||||
return articleMaker.makeDefinitionFor( word, group );
|
||||
return articleMaker.makeDefinitionFor( word, group, contexts );
|
||||
}
|
||||
|
||||
if ( ( url.scheme() == "bres" || url.scheme() == "gdau" ) &&
|
||||
|
|
|
@ -122,7 +122,8 @@ ArticleView::~ArticleView()
|
|||
}
|
||||
|
||||
void ArticleView::showDefinition( QString const & word, unsigned group,
|
||||
QString const & scrollTo )
|
||||
QString const & scrollTo,
|
||||
Contexts const & contexts )
|
||||
{
|
||||
QUrl req;
|
||||
|
||||
|
@ -132,7 +133,22 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
|||
req.addQueryItem( "group", QString::number( group ) );
|
||||
|
||||
if ( scrollTo.size() )
|
||||
req.setFragment( scrollTo );
|
||||
req.addQueryItem( "scrollto", scrollTo );
|
||||
|
||||
if ( contexts.size() )
|
||||
{
|
||||
QBuffer buf;
|
||||
|
||||
buf.open( QIODevice::WriteOnly );
|
||||
|
||||
QDataStream stream( &buf );
|
||||
|
||||
stream << contexts;
|
||||
|
||||
buf.close();
|
||||
|
||||
req.addQueryItem( "contexts", QString::fromAscii( buf.buffer().toBase64() ) );
|
||||
}
|
||||
|
||||
// Save current article, if any
|
||||
|
||||
|
@ -158,22 +174,6 @@ void ArticleView::loadFinished( bool )
|
|||
{
|
||||
QUrl url = ui.definition->url();
|
||||
|
||||
QVariant userData = ui.definition->history()->currentItem().userData();
|
||||
|
||||
if ( userData.type() == QVariant::String && userData.toString().startsWith( "gdfrom-" ) )
|
||||
{
|
||||
printf( "has user data\n" );
|
||||
// There's an active article saved, so set it to be active.
|
||||
setCurrentArticle( userData.toString() );
|
||||
}
|
||||
else
|
||||
if ( url.hasFragment() && url.fragment().startsWith( "gdfrom-" ) )
|
||||
{
|
||||
// There is no active article saved in history, but we have it in fragment.
|
||||
// setCurrentArticle will save it.
|
||||
setCurrentArticle( url.fragment() );
|
||||
}
|
||||
|
||||
// See if we have any iframes in need of expansion
|
||||
|
||||
QList< QWebFrame * > frames = ui.definition->page()->mainFrame()->childFrames();
|
||||
|
@ -197,6 +197,10 @@ void ArticleView::loadFinished( bool )
|
|||
ui.definition->page()->mainFrame()->evaluateJavaScript( QString( "document.getElementById('%1').style.display = 'block';" ).
|
||||
arg( (*i)->frameName() ) );
|
||||
|
||||
(*i)->evaluateJavaScript( "var gdLastUrlText;" );
|
||||
(*i)->evaluateJavaScript( "document.addEventListener( 'click', function() { gdLastUrlText = window.event.srcElement.text; }, true );" );
|
||||
(*i)->evaluateJavaScript( "document.addEventListener( 'contextmenu', function() { gdLastUrlText = window.event.srcElement.text; }, true );" );
|
||||
|
||||
wereFrames = true;
|
||||
}
|
||||
}
|
||||
|
@ -210,6 +214,23 @@ void ArticleView::loadFinished( bool )
|
|||
qApp->sendEvent( ui.definition, &ev );
|
||||
}
|
||||
|
||||
QVariant userData = ui.definition->history()->currentItem().userData();
|
||||
|
||||
if ( userData.type() == QVariant::String && userData.toString().startsWith( "gdfrom-" ) )
|
||||
{
|
||||
//printf( "has user data\n" );
|
||||
// There's an active article saved, so set it to be active.
|
||||
setCurrentArticle( userData.toString() );
|
||||
}
|
||||
else
|
||||
if ( url.queryItemValue( "scrollto" ).startsWith( "gdfrom-" ) )
|
||||
{
|
||||
// There is no active article saved in history, but we have it as a parameter.
|
||||
// setCurrentArticle will save it and scroll there.
|
||||
setCurrentArticle( url.queryItemValue( "scrollto" ), true );
|
||||
}
|
||||
|
||||
|
||||
ui.definition->unsetCursor();
|
||||
//QApplication::restoreOverrideCursor();
|
||||
emit pageLoaded( this );
|
||||
|
@ -278,11 +299,7 @@ void ArticleView::setCurrentArticle( QString const & id, bool moveToIt )
|
|||
if ( getArticlesList().contains( id.mid( 7 ) ) )
|
||||
{
|
||||
if ( moveToIt )
|
||||
{
|
||||
QUrl url( ui.definition->url() );
|
||||
url.setFragment( id );
|
||||
openLink( url, ui.definition->url() );
|
||||
}
|
||||
ui.definition->page()->mainFrame()->evaluateJavaScript( QString( "document.getElementById('%1').scrollIntoView(true);" ).arg( id ) );
|
||||
|
||||
ui.definition->history()->currentItem().setUserData( id );
|
||||
ui.definition->page()->mainFrame()->evaluateJavaScript(
|
||||
|
@ -290,6 +307,72 @@ void ArticleView::setCurrentArticle( QString const & id, bool moveToIt )
|
|||
}
|
||||
}
|
||||
|
||||
bool ArticleView::isFramedArticle( QString const & ca )
|
||||
{
|
||||
if ( ca.isEmpty() )
|
||||
return false;
|
||||
|
||||
return ui.definition->page()->mainFrame()->
|
||||
evaluateJavaScript( QString( "!!document.getElementById('gdexpandframe-%1');" ).arg( ca.mid( 7 ) ) ).toBool();
|
||||
}
|
||||
|
||||
bool ArticleView::isExternalLink( QUrl const & url )
|
||||
{
|
||||
return url.scheme() == "http" || url.scheme() == "https" ||
|
||||
url.scheme() == "ftp" || url.scheme() == "mailto";
|
||||
}
|
||||
|
||||
void ArticleView::tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts )
|
||||
{
|
||||
if( url.scheme() == "http" || url.scheme() == "https" )
|
||||
{
|
||||
// Maybe a link inside a website was clicked?
|
||||
|
||||
QString ca = getCurrentArticle();
|
||||
|
||||
if ( isFramedArticle( ca ) )
|
||||
{
|
||||
QVariant result = ui.definition->page()->currentFrame()->evaluateJavaScript( "gdLastUrlText;" );
|
||||
|
||||
if ( result.type() == QVariant::String )
|
||||
{
|
||||
// Looks this way
|
||||
|
||||
contexts[ ca.mid( 7 ) ] = QString::fromAscii( url.toEncoded() );
|
||||
|
||||
QUrl target;
|
||||
|
||||
target.setScheme( "gdlookup" );
|
||||
target.setHost( "localhost" );
|
||||
target.setPath( "/" + result.toString() );
|
||||
|
||||
url = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleView::updateCurrentArticleFromCurrentFrame( QWebFrame * frame )
|
||||
{
|
||||
if ( !frame )
|
||||
frame = ui.definition->page()->currentFrame();
|
||||
|
||||
for( ; frame; frame = frame->parentFrame() )
|
||||
{
|
||||
QString frameName = frame->frameName();
|
||||
|
||||
if ( frameName.startsWith( "gdexpandframe-" ) )
|
||||
{
|
||||
QString newCurrent = "gdfrom-" + frameName.mid( 14 );
|
||||
|
||||
if ( getCurrentArticle() != newCurrent )
|
||||
setCurrentArticle( newCurrent, false );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArticleView::cleanupTemp()
|
||||
{
|
||||
if ( desktopOpenedTempFile.size() )
|
||||
|
@ -332,13 +415,21 @@ bool ArticleView::eventFilter( QObject * obj, QEvent * ev )
|
|||
}
|
||||
|
||||
|
||||
void ArticleView::linkClicked( QUrl const & url )
|
||||
void ArticleView::linkClicked( QUrl const & url_ )
|
||||
{
|
||||
openLink( url, ui.definition->url(), getCurrentArticle() );
|
||||
updateCurrentArticleFromCurrentFrame();
|
||||
|
||||
QUrl url( url_ );
|
||||
Contexts contexts;
|
||||
|
||||
tryMangleWebsiteClickedUrl( url, contexts );
|
||||
|
||||
openLink( url, ui.definition->url(), getCurrentArticle(), contexts );
|
||||
}
|
||||
|
||||
void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
||||
QString const & scrollTo )
|
||||
QString const & scrollTo,
|
||||
Contexts const & contexts )
|
||||
{
|
||||
printf( "clicked %s\n", url.toString().toLocal8Bit().data() );
|
||||
|
||||
|
@ -346,7 +437,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
|||
showDefinition( ( url.host().startsWith( "xn--" ) ?
|
||||
QUrl::fromPunycode( url.host().toLatin1() ) :
|
||||
url.host() ) + url.path(),
|
||||
getGroup( ref ), scrollTo );
|
||||
getGroup( ref ), scrollTo, contexts );
|
||||
else
|
||||
if ( url.scheme() == "gdlookup" ) // Plain html links inherit gdlookup scheme
|
||||
{
|
||||
|
@ -357,7 +448,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
|||
}
|
||||
else
|
||||
showDefinition( url.path().mid( 1 ),
|
||||
getGroup( ref ), scrollTo );
|
||||
getGroup( ref ), scrollTo, contexts );
|
||||
}
|
||||
else
|
||||
if ( url.scheme() == "bres" || url.scheme() == "gdau" )
|
||||
|
@ -511,31 +602,45 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
QWebHitTestResult r = ui.definition->page()->mainFrame()->
|
||||
hitTestContent( pos );
|
||||
|
||||
updateCurrentArticleFromCurrentFrame( r.frame() );
|
||||
|
||||
QMenu menu( this );
|
||||
|
||||
|
||||
QAction * followLink = 0;
|
||||
QAction * followLinkExternal = 0;
|
||||
QAction * followLinkNewTab = 0;
|
||||
QAction * lookupSelection = 0;
|
||||
QAction * lookupSelectionGr = 0;
|
||||
QAction * lookupSelectionNewTab = 0;
|
||||
QAction * lookupSelectionNewTabGr = 0;
|
||||
|
||||
QUrl targetUrl( r.linkUrl() );
|
||||
Contexts contexts;
|
||||
|
||||
tryMangleWebsiteClickedUrl( targetUrl, contexts );
|
||||
|
||||
if ( !r.linkUrl().isEmpty() )
|
||||
{
|
||||
followLink = new QAction( tr( "&Open Link" ), &menu );
|
||||
menu.addAction( followLink );
|
||||
|
||||
if ( !popupView )
|
||||
if ( !isExternalLink( targetUrl ) )
|
||||
{
|
||||
followLinkNewTab = new QAction( tr( "Open Link in New &Tab" ), &menu );
|
||||
menu.addAction( followLinkNewTab );
|
||||
followLink = new QAction( tr( "&Open Link" ), &menu );
|
||||
menu.addAction( followLink );
|
||||
|
||||
if ( !popupView )
|
||||
{
|
||||
followLinkNewTab = new QAction( QIcon( ":/icons/addtab.png" ),
|
||||
tr( "Open Link in New &Tab" ), &menu );
|
||||
menu.addAction( followLinkNewTab );
|
||||
}
|
||||
}
|
||||
|
||||
QString scheme = r.linkUrl().scheme();
|
||||
|
||||
if ( scheme == "http" || scheme == "https" || scheme == "ftp" || scheme == "mailto" )
|
||||
if ( isExternalLink( r.linkUrl() ) )
|
||||
{
|
||||
followLinkExternal = new QAction( tr( "Open Link in &External Browser" ), &menu );
|
||||
menu.addAction( followLinkExternal );
|
||||
menu.addAction( ui.definition->pageAction( QWebPage::CopyLinkToClipboard ) );
|
||||
}
|
||||
}
|
||||
|
||||
QString selectedText = ui.definition->selectedText();
|
||||
|
@ -628,8 +733,14 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
{
|
||||
QAction * result = menu.exec( ui.definition->mapToGlobal( pos ) );
|
||||
|
||||
if ( !result )
|
||||
return;
|
||||
|
||||
if ( result == followLink )
|
||||
linkClicked( r.linkUrl() );
|
||||
openLink( targetUrl, ui.definition->url(), getCurrentArticle(), contexts );
|
||||
else
|
||||
if ( result == followLinkExternal )
|
||||
QDesktopServices::openUrl( r.linkUrl() );
|
||||
else
|
||||
if ( result == lookupSelection )
|
||||
showDefinition( selectedText, getGroup( ui.definition->url() ), getCurrentArticle() );
|
||||
|
@ -638,15 +749,15 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
|
|||
showDefinition( selectedText, groupComboBox->getCurrentGroup(), QString() );
|
||||
else
|
||||
if ( !popupView && result == followLinkNewTab )
|
||||
emit openLinkInNewTab( r.linkUrl(), ui.definition->url(), getCurrentArticle() );
|
||||
emit openLinkInNewTab( targetUrl, ui.definition->url(), getCurrentArticle(), contexts );
|
||||
else
|
||||
if ( !popupView && result == lookupSelectionNewTab )
|
||||
emit showDefinitionInNewTab( selectedText, getGroup( ui.definition->url() ),
|
||||
getCurrentArticle() );
|
||||
getCurrentArticle(), Contexts() );
|
||||
else
|
||||
if ( !popupView && result == lookupSelectionNewTabGr && groupComboBox )
|
||||
emit showDefinitionInNewTab( selectedText, groupComboBox->getCurrentGroup(),
|
||||
QString() );
|
||||
QString(), Contexts() );
|
||||
else
|
||||
{
|
||||
// Match against table of contents
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <QWebView>
|
||||
#include <QUrl>
|
||||
#include <QMap>
|
||||
#include <list>
|
||||
#include "article_netmgr.hh"
|
||||
#include "instances.hh"
|
||||
|
@ -65,11 +66,17 @@ public:
|
|||
|
||||
~ArticleView();
|
||||
|
||||
typedef QMap< QString, QString > Contexts;
|
||||
|
||||
/// Shows the definition of the given word with the given group.
|
||||
/// scrollTo can be optionally set to a "gdfrom-xxxx" identifier to position
|
||||
/// the page to that article on load.
|
||||
/// contexts is an optional map of context values to be passed for dictionaries.
|
||||
/// The only values to pass here are ones obtained from showDefinitionInNewTab()
|
||||
/// signal or none at all.
|
||||
void showDefinition( QString const & word, unsigned group,
|
||||
QString const & scrollTo = QString() );
|
||||
QString const & scrollTo = QString(),
|
||||
Contexts const & contexts = Contexts() );
|
||||
|
||||
/// Clears the view and sets the application-global waiting cursor,
|
||||
/// which will be restored when some article loads eventually.
|
||||
|
@ -78,8 +85,12 @@ public:
|
|||
/// Opens the given link. Supposed to be used in response to
|
||||
/// openLinkInNewTab() signal. The link scheme is therefore supposed to be
|
||||
/// one of the internal ones.
|
||||
/// contexts is an optional map of context values to be passed for dictionaries.
|
||||
/// The only values to pass here are ones obtained from showDefinitionInNewTab()
|
||||
/// signal or none at all.
|
||||
void openLink( QUrl const & url, QUrl const & referrer,
|
||||
QString const & scrollTo = QString() );
|
||||
QString const & scrollTo = QString(),
|
||||
Contexts const & contexts = Contexts() );
|
||||
|
||||
/// Goes back in history
|
||||
void back()
|
||||
|
@ -129,10 +140,12 @@ signals:
|
|||
|
||||
/// Singals that the following link was requested to be opened in new tab
|
||||
void openLinkInNewTab( QUrl const &, QUrl const & referrer,
|
||||
QString const & fromArticle );
|
||||
QString const & fromArticle,
|
||||
ArticleView::Contexts const & contexts );
|
||||
/// Singals that the following definition was requested to be showed in new tab
|
||||
void showDefinitionInNewTab( QString const & word, unsigned group,
|
||||
QString const & fromArticle );
|
||||
QString const & fromArticle,
|
||||
ArticleView::Contexts const & contexts );
|
||||
|
||||
/// Emitted when user types a text key. This should typically be used to
|
||||
/// switch focus to word input.
|
||||
|
@ -183,6 +196,23 @@ private:
|
|||
/// If moveToIt is true, it moves the focus to it as well.
|
||||
void setCurrentArticle( QString const &, bool moveToIt = false );
|
||||
|
||||
/// Checks if the given article in form of "gdfrom-xxx" is inside a "website"
|
||||
/// frame.
|
||||
bool isFramedArticle( QString const & );
|
||||
|
||||
/// Checks if the given link is to be opened externally, as opposed to opening
|
||||
/// it in-place.
|
||||
bool isExternalLink( QUrl const & url );
|
||||
|
||||
/// Sees if the last clicked link is from a website frame. If so, changes url
|
||||
/// to point to url text translation instead, and saves the original
|
||||
/// url to the appropriate "contexts" entry.
|
||||
void tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts );
|
||||
|
||||
/// Use the known information about the current frame to update the current
|
||||
/// article's value.
|
||||
void updateCurrentArticleFromCurrentFrame( QWebFrame * frame = 0 );
|
||||
|
||||
/// Attempts removing last temporary file created.
|
||||
void cleanupTemp();
|
||||
|
||||
|
|
|
@ -241,7 +241,8 @@ namespace
|
|||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getResource( string const & name )
|
||||
|
@ -673,7 +674,8 @@ void BglArticleRequest::run()
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > BglDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
return new BglArticleRequest( word, alts, *this );
|
||||
|
|
|
@ -110,7 +110,8 @@ public:
|
|||
{ return idxHeader.langTo; }
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
|
@ -185,7 +186,8 @@ uint32_t decodeBase64( string const & str )
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > DictdDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
try
|
||||
|
|
|
@ -319,7 +319,11 @@ public:
|
|||
/// The 'alts' vector could contain a list of words the definitions of which
|
||||
/// should be included in the output as well, being treated as additional
|
||||
/// synonyms for the main word.
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts )
|
||||
/// context is a dictionary-specific data, currently only used for the
|
||||
/// 'Websites' feature.
|
||||
virtual sptr< DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts,
|
||||
wstring const & context = wstring() )
|
||||
throw( std::exception )=0;
|
||||
|
||||
/// Loads contents of a resource named 'name' into the 'data' vector. This is
|
||||
|
|
|
@ -162,7 +162,8 @@ public:
|
|||
#endif
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getResource( string const & name )
|
||||
|
@ -1056,7 +1057,8 @@ void DslArticleRequest::run()
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > DslDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
return new DslArticleRequest( word, alts, *this );
|
||||
|
|
|
@ -65,7 +65,9 @@ public:
|
|||
virtual sptr< WordSearchRequest > findHeadwordsForSynonym( wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts )
|
||||
virtual sptr< DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
|
@ -252,7 +254,9 @@ void HunspellArticleRequest::run()
|
|||
finish();
|
||||
}
|
||||
|
||||
sptr< DataRequest > HunspellDictionary::getArticle( wstring const & word, vector< wstring > const & )
|
||||
sptr< DataRequest > HunspellDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const &,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
return new HunspellArticleRequest( word, hunspellMutex, hunspell );
|
||||
|
|
|
@ -173,7 +173,8 @@ public:
|
|||
{ return QIcon(":/icons/playsound.png"); }
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getResource( string const & name )
|
||||
|
@ -205,7 +206,8 @@ LsaDictionary::LsaDictionary( string const & id,
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > LsaDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
vector< WordArticleLink > chain = findArticles( word );
|
||||
|
|
|
@ -530,11 +530,11 @@ ArticleView * MainWindow::createNewTab( bool switchToIt,
|
|||
connect( view, SIGNAL( pageLoaded( ArticleView * ) ),
|
||||
this, SLOT( pageLoaded( ArticleView * ) ) );
|
||||
|
||||
connect( view, SIGNAL( openLinkInNewTab( QUrl const &, QUrl const &, QString const & ) ),
|
||||
this, SLOT( openLinkInNewTab( QUrl const &, QUrl const &, QString const & ) ) );
|
||||
connect( view, SIGNAL( openLinkInNewTab( QUrl const &, QUrl const &, QString const &, ArticleView::Contexts const & ) ),
|
||||
this, SLOT( openLinkInNewTab( QUrl const &, QUrl const &, QString const &, ArticleView::Contexts const & ) ) );
|
||||
|
||||
connect( view, SIGNAL( showDefinitionInNewTab( QString const &, unsigned, QString const & ) ),
|
||||
this, SLOT( showDefinitionInNewTab( QString const &, unsigned, QString const & ) ) );
|
||||
connect( view, SIGNAL( showDefinitionInNewTab( QString const &, unsigned, QString const &, ArticleView::Contexts const & ) ),
|
||||
this, SLOT( showDefinitionInNewTab( QString const &, unsigned, QString const &, ArticleView::Contexts const & ) ) );
|
||||
|
||||
connect( view, SIGNAL( typingEvent( QString const & ) ),
|
||||
this, SLOT( typingEvent( QString const & ) ) );
|
||||
|
@ -943,18 +943,20 @@ void MainWindow::wordListSelectionChanged()
|
|||
|
||||
void MainWindow::openLinkInNewTab( QUrl const & url,
|
||||
QUrl const & referrer,
|
||||
QString const & fromArticle )
|
||||
QString const & fromArticle,
|
||||
ArticleView::Contexts const & contexts )
|
||||
{
|
||||
createNewTab( !cfg.preferences.newTabsOpenInBackground, "" )->
|
||||
openLink( url, referrer, fromArticle );
|
||||
openLink( url, referrer, fromArticle, contexts );
|
||||
}
|
||||
|
||||
void MainWindow::showDefinitionInNewTab( QString const & word,
|
||||
unsigned group,
|
||||
QString const & fromArticle )
|
||||
QString const & fromArticle,
|
||||
ArticleView::Contexts const & contexts )
|
||||
{
|
||||
createNewTab( !cfg.preferences.newTabsOpenInBackground, word )->
|
||||
showDefinition( word, group, fromArticle );
|
||||
showDefinition( word, group, fromArticle, contexts );
|
||||
}
|
||||
|
||||
void MainWindow::typingEvent( QString const & t )
|
||||
|
|
|
@ -177,9 +177,11 @@ private slots:
|
|||
ArticleView * createNewTab( bool switchToIt,
|
||||
QString const & name );
|
||||
|
||||
void openLinkInNewTab( QUrl const &, QUrl const &, QString const & );
|
||||
void openLinkInNewTab( QUrl const &, QUrl const &, QString const &,
|
||||
ArticleView::Contexts const & contexts );
|
||||
void showDefinitionInNewTab( QString const & word, unsigned group,
|
||||
QString const & fromArticle );
|
||||
QString const & fromArticle,
|
||||
ArticleView::Contexts const & contexts );
|
||||
void typingEvent( QString const & );
|
||||
|
||||
void showTranslationFor( QString const & );
|
||||
|
|
|
@ -51,7 +51,8 @@ public:
|
|||
virtual sptr< WordSearchRequest > prefixMatch( wstring const &,
|
||||
unsigned long maxResults ) throw( std::exception );
|
||||
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts )
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
|
@ -341,7 +342,9 @@ sptr< WordSearchRequest > MediaWikiDictionary::prefixMatch( wstring const & word
|
|||
return new MediaWikiWordSearchRequest( word, url, netMgr );
|
||||
}
|
||||
|
||||
sptr< DataRequest > MediaWikiDictionary::getArticle( wstring const & word, vector< wstring > const & alts )
|
||||
sptr< DataRequest > MediaWikiDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
return new MediaWikiArticleRequest( word, alts, url, netMgr );
|
||||
|
|
|
@ -89,7 +89,8 @@ public:
|
|||
{ return QIcon(":/icons/playsound.png"); }
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getResource( string const & name )
|
||||
|
@ -114,7 +115,8 @@ SoundDirDictionary::SoundDirDictionary( string const & id,
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > SoundDirDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
vector< WordArticleLink > chain = findArticles( word );
|
||||
|
|
|
@ -153,7 +153,8 @@ public:
|
|||
throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
|
||||
private:
|
||||
|
@ -732,7 +733,8 @@ void StardictArticleRequest::run()
|
|||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > StardictDictionary::getArticle( wstring const & word,
|
||||
vector< wstring > const & alts )
|
||||
vector< wstring > const & alts,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{
|
||||
return new StardictArticleRequest( word, alts, *this );
|
||||
|
|
|
@ -47,7 +47,8 @@ sptr< Dictionary::WordSearchRequest > TransliterationDictionary::prefixMatch( ws
|
|||
{ return new Dictionary::WordSearchRequestInstant(); }
|
||||
|
||||
sptr< Dictionary::DataRequest > TransliterationDictionary::getArticle( wstring const &,
|
||||
vector< wstring > const & )
|
||||
vector< wstring > const &,
|
||||
wstring const & )
|
||||
throw( std::exception )
|
||||
{ return new Dictionary::DataRequestInstant( false ); }
|
||||
|
||||
|
|
|
@ -69,7 +69,8 @@ public:
|
|||
unsigned long ) throw( std::exception );
|
||||
|
||||
virtual sptr< Dictionary::DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & )
|
||||
vector< wstring > const &,
|
||||
wstring const & )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "website.hh"
|
||||
#include "wstring_qt.hh"
|
||||
#include "utf8.hh"
|
||||
#include <QUrl>
|
||||
#include <QTextCodec>
|
||||
|
||||
|
@ -45,7 +46,9 @@ public:
|
|||
virtual sptr< WordSearchRequest > prefixMatch( wstring const & word,
|
||||
unsigned long ) throw( std::exception );
|
||||
|
||||
virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts )
|
||||
virtual sptr< DataRequest > getArticle( wstring const &,
|
||||
vector< wstring > const & alts,
|
||||
wstring const & context )
|
||||
throw( std::exception );
|
||||
};
|
||||
|
||||
|
@ -59,18 +62,28 @@ sptr< WordSearchRequest > WebSiteDictionary::prefixMatch( wstring const & word,
|
|||
return sr;
|
||||
}
|
||||
|
||||
sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str, vector< wstring > const & )
|
||||
sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str,
|
||||
vector< wstring > const &,
|
||||
wstring const & context )
|
||||
throw( std::exception )
|
||||
{
|
||||
sptr< DataRequestInstant > dr = new DataRequestInstant( true );
|
||||
|
||||
QByteArray urlString( urlTemplate );
|
||||
QByteArray urlString;
|
||||
|
||||
QString inputWord = gd::toQString( str );
|
||||
// Context contains the right url to go to
|
||||
if ( context.size() )
|
||||
urlString = Utf8::encode( context ).c_str();
|
||||
else
|
||||
{
|
||||
urlString = urlTemplate;
|
||||
|
||||
urlString.replace( "%25GDWORD%25", inputWord.toUtf8().toPercentEncoding() );
|
||||
urlString.replace( "%25GD1251%25", QTextCodec::codecForName( "Windows-1251" )->fromUnicode( inputWord ).toPercentEncoding() );
|
||||
urlString.replace( "%25GDISO1%25", QTextCodec::codecForName( "ISO 8859-1" )->fromUnicode( inputWord ).toPercentEncoding() );
|
||||
QString inputWord = gd::toQString( str );
|
||||
|
||||
urlString.replace( "%25GDWORD%25", inputWord.toUtf8().toPercentEncoding() );
|
||||
urlString.replace( "%25GD1251%25", QTextCodec::codecForName( "Windows-1251" )->fromUnicode( inputWord ).toPercentEncoding() );
|
||||
urlString.replace( "%25GDISO1%25", QTextCodec::codecForName( "ISO 8859-1" )->fromUnicode( inputWord ).toPercentEncoding() );
|
||||
}
|
||||
|
||||
string result = "<div class=\"website_padding\"></div>";
|
||||
|
||||
|
|
Loading…
Reference in a new issue