Merge branch 'staged' into dev

This commit is contained in:
Xiao YiFang 2022-05-29 16:01:13 +08:00
commit 99876e6680
15 changed files with 194 additions and 240 deletions

View file

@ -3,6 +3,14 @@
## Until to now ## Until to now
- **CLEANING OLD/USELESS CODE** - **CLEANING OLD/USELESS CODE**
- remove Runnable Class in dsl, zim , epwing etc files.
- add "send to anki"
- right context menu actions, remove nonsense character like `OBJ`,punctuation etc.
- epwing remove duplicate entries when index.
## Until 2022-5-21
- fix a zim about:blank#block [issue](https://github.com/goldendict/goldendict/issues/1472#issuecomment-1086776611) - fix a zim about:blank#block [issue](https://github.com/goldendict/goldendict/issues/1472#issuecomment-1086776611)
- add fallback font family configuration for dictionary through preference dialog. - add fallback font family configuration for dictionary through preference dialog.
- fix mdx (compact html) display error on the last item. - fix mdx (compact html) display error on the last item.

View file

@ -10,8 +10,8 @@ ArticleInspector::ArticleInspector( QWidget * parent ) : QWidget( parent, Qt::Wi
QVBoxLayout * v = new QVBoxLayout( this ); QVBoxLayout * v = new QVBoxLayout( this );
v->setSpacing( 0 ); v->setSpacing( 0 );
v->setContentsMargins( 0, 0, 0, 0 ); v->setContentsMargins( 0, 0, 0, 0 );
inspectView = new QWebEngineView( this ); viewContainer = new QWebEngineView( this );
v->addWidget( inspectView ); v->addWidget( viewContainer );
resize(800,600); resize(800,600);
} }
@ -19,8 +19,7 @@ ArticleInspector::ArticleInspector( QWidget * parent ) : QWidget( parent, Qt::Wi
void ArticleInspector::setInspectPage( QWebEngineView * view ) void ArticleInspector::setInspectPage( QWebEngineView * view )
{ {
auto page=view->page(); auto page=view->page();
this->inspectedPage = page; viewContainer->page()->setInspectedPage(page);
page->setDevToolsPage( inspectView->page() );
#if( QT_VERSION > QT_VERSION_CHECK( 6, 0, 0 ) ) #if( QT_VERSION > QT_VERSION_CHECK( 6, 0, 0 ) )
// without this line, application will crash on qt6.2 ,see https://bugreports.qt.io/browse/QTBUG-101724 // without this line, application will crash on qt6.2 ,see https://bugreports.qt.io/browse/QTBUG-101724
if( view->lastContextMenuRequest() ) if( view->lastContextMenuRequest() )
@ -36,5 +35,5 @@ void ArticleInspector::setInspectPage( QWebEngineView * view )
void ArticleInspector::closeEvent( QCloseEvent * ) void ArticleInspector::closeEvent( QCloseEvent * )
{ {
inspectedPage->setDevToolsPage( nullptr ); viewContainer->page()->setInspectedPage(nullptr);
} }

View file

@ -9,8 +9,7 @@
class ArticleInspector : public QWidget class ArticleInspector : public QWidget
{ {
Q_OBJECT Q_OBJECT
QWebEngineView * inspectView = nullptr; QWebEngineView * viewContainer = nullptr;
QWebEnginePage * inspectedPage = nullptr;
public: public:
ArticleInspector( QWidget * parent = nullptr ); ArticleInspector( QWidget * parent = nullptr );

View file

@ -465,7 +465,7 @@ void ArticleRequest::altSearchFinished()
if ( altSearches.empty() ) if ( altSearches.empty() )
{ {
#ifdef QT_DEBUG #ifdef QT_DEBUG
qDebug( "alts finished\n" ); qDebug( "alts finished" );
#endif #endif
// They all've finished! Now we can look up bodies // They all've finished! Now we can look up bodies
@ -534,7 +534,7 @@ void ArticleRequest::bodyFinished()
if ( bodyDone ) if ( bodyDone )
return; return;
GD_DPRINTF( "some body finished\n" ); GD_DPRINTF( "some body finished" );
bool wasUpdated = false; bool wasUpdated = false;
@ -546,7 +546,7 @@ void ArticleRequest::bodyFinished()
{ {
// Good // Good
GD_DPRINTF( "one finished.\n" ); GD_DPRINTF( "one finished." );
Dictionary::DataRequest & req = *bodyRequests.front(); Dictionary::DataRequest & req = *bodyRequests.front();
@ -672,13 +672,13 @@ void ArticleRequest::bodyFinished()
foundAnyDefinitions = true; foundAnyDefinitions = true;
} }
GD_DPRINTF( "erasing..\n" ); GD_DPRINTF( "erasing.." );
bodyRequests.pop_front(); bodyRequests.pop_front();
GD_DPRINTF( "erase done..\n" ); GD_DPRINTF( "erase done.." );
} }
else else
{ {
GD_DPRINTF( "one not finished.\n" ); GD_DPRINTF( "one not finished." );
break; break;
} }
} }

View file

@ -202,7 +202,7 @@ QNetworkReply * ArticleNetworkAccessManager::getArticleReply( QNetworkRequest co
// getHostBase( refererUrl ).toUtf8().data() ); // getHostBase( refererUrl ).toUtf8().data() );
if ( !url.host().endsWith( refererUrl.host() ) && if ( !url.host().endsWith( refererUrl.host() ) &&
getHostBase( url ) != getHostBase( refererUrl ) && !url.scheme().startsWith("data") ) getHostBaseFromUrl( url ) != getHostBaseFromUrl( refererUrl ) && !url.scheme().startsWith("data") )
{ {
gdWarning( "Blocking element \"%s\" due to not same domain", url.toEncoded().data() ); gdWarning( "Blocking element \"%s\" due to not same domain", url.toEncoded().data() );
@ -254,9 +254,9 @@ QNetworkReply * ArticleNetworkAccessManager::getArticleReply( QNetworkRequest co
sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource( sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
QUrl const & url, QString & contentType ) QUrl const & url, QString & contentType )
{ {
GD_DPRINTF( "getResource: %ls\n", url.toString().toStdWString().c_str() ); GD_DPRINTF( "getResource: %ls", url.toString().toStdWString().c_str() );
GD_DPRINTF( "scheme: %ls\n", url.scheme().toStdWString().c_str() ); GD_DPRINTF( "scheme: %ls", url.scheme().toStdWString().c_str() );
GD_DPRINTF( "host: %ls\n", url.host().toStdWString().c_str() ); GD_DPRINTF( "host: %ls", url.host().toStdWString().c_str() );
if ( url.scheme() == "gdlookup" ) if ( url.scheme() == "gdlookup" )
{ {
@ -515,6 +515,17 @@ void LocalSchemeHandler::requestStarted(QWebEngineUrlRequestJob *requestJob)
QNetworkRequest request; QNetworkRequest request;
request.setUrl( url ); request.setUrl( url );
//all the url reached here must be either gdlookup or bword scheme.
auto queryWord = Utils::Url::getQueryWord( url );
auto word = queryWord.second;
// or the condition can be (!queryWord.first || word.isEmpty())
// ( queryWord.first && word.isEmpty() ) is only part of the above condition.
if( queryWord.first && word.isEmpty() )
{
// invalid gdlookup url.
return;
}
QNetworkReply * reply = this->mManager.getArticleReply( request ); QNetworkReply * reply = this->mManager.getArticleReply( request );
connect( reply, &QNetworkReply::finished, requestJob, [ = ]() { requestJob->reply( "text/html", reply ); } ); connect( reply, &QNetworkReply::finished, requestJob, [ = ]() { requestJob->reply( "text/html", reply ); } );
connect( requestJob, &QObject::destroyed, reply, &QObject::deleteLater ); connect( requestJob, &QObject::destroyed, reply, &QObject::deleteLater );

View file

@ -708,39 +708,14 @@ void ArticleView::tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts )
{ {
if( framed ) if( framed )
{ {
// QVariant result = runJavaScriptSync( ui.definition->page(), "gdLastUrlText" ); // no need to translate website internal url to gd builtin url
QVariant result; // and lack the formulation to convert them.
qDebug() << "in the website with url:" << url;
if( result.type() == QVariant::String )
{
// Looks this way
contexts[ dictionaryIdFromScrollTo( ca ) ] = QString::fromLatin1( url.toEncoded() );
QUrl target;
QString queryWord = result.toString();
// Empty requests are treated as no request, so we work this around by
// adding a space.
if( queryWord.isEmpty() )
queryWord = " ";
target.setScheme( "gdlookup" );
target.setHost( "localhost" );
target.setPath( "/" + queryWord );
url = target;
}
} }
} ); } );
} }
} }
void ArticleView::updateCurrentArticleFromCurrentFrame( QWebEnginePage * frame ,QPoint * point)
{
}
void ArticleView::saveHistoryUserData() void ArticleView::saveHistoryUserData()
{ {
ui.definition->setProperty("sx", ui.definition->page()->scrollPosition().x()); ui.definition->setProperty("sx", ui.definition->page()->scrollPosition().x());
@ -1100,8 +1075,6 @@ void ArticleView::linkClicked( QUrl const & url_ )
if( kmod & Qt::AltModifier ) if( kmod & Qt::AltModifier )
return; return;
updateCurrentArticleFromCurrentFrame();
QUrl url( url_ ); QUrl url( url_ );
Contexts contexts; Contexts contexts;
@ -1134,6 +1107,14 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
audioPlayer->stop(); audioPlayer->stop();
qDebug() << "open link url:" << url; qDebug() << "open link url:" << url;
auto queryWord = Utils::Url::getQueryWord( url );
auto word = queryWord.second;
if( queryWord.first && word.isEmpty() )
{
// invalid gdlookup url.
return;
}
Contexts contexts( contexts_ ); Contexts contexts( contexts_ );
if( url.scheme().compare( "gdpicture" ) == 0 ) if( url.scheme().compare( "gdpicture" ) == 0 )
@ -1146,10 +1127,10 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
QStringList dictsList = Utils::Url::queryItemValue( ref, "dictionaries" ) QStringList dictsList = Utils::Url::queryItemValue( ref, "dictionaries" )
.split( ",", Qt::SkipEmptyParts ); .split( ",", Qt::SkipEmptyParts );
showDefinition( url.path(), dictsList, QRegExp(), getGroup( ref ), false ); showDefinition( word, dictsList, QRegExp(), getGroup( ref ), false );
} }
else else
showDefinition( url.path(), showDefinition( word,
getGroup( ref ), scrollTo, contexts ); getGroup( ref ), scrollTo, contexts );
} }
else else
@ -1172,16 +1153,6 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
return; return;
} }
QString word;
if( Utils::Url::hasQueryItem( url, "word" ) )
{
word=Utils::Url::queryItemValue (url,"word");
}
else{
word=url.path ().mid (1);
}
QString newScrollTo( scrollTo ); QString newScrollTo( scrollTo );
if( Utils::Url::hasQueryItem( url, "dict" ) ) if( Utils::Url::hasQueryItem( url, "dict" ) )
{ {
@ -1725,8 +1696,6 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
{ {
// Is that a link? Is there a selection? // Is that a link? Is there a selection?
QWebEnginePage* r=ui.definition->page(); QWebEnginePage* r=ui.definition->page();
updateCurrentArticleFromCurrentFrame(ui.definition->page(), const_cast<QPoint *>(& pos));
QMenu menu( this ); QMenu menu( this );
QAction * followLink = 0; QAction * followLink = 0;
@ -1801,7 +1770,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
} }
QString selectedText = ui.definition->selectedText(); QString selectedText = ui.definition->selectedText();
QString text = selectedText.trimmed(); QString text = Utils::trimNonChar( selectedText );
if ( text.size() && text.size() < 60 ) if ( text.size() && text.size() < 60 )
{ {

View file

@ -380,10 +380,6 @@ private:
/// url to the appropriate "contexts" entry. /// url to the appropriate "contexts" entry.
void tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts ); void tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts );
/// Use the known information about the current frame to update the current
/// article's value.
void updateCurrentArticleFromCurrentFrame( QWebEnginePage * frame = 0 ,QPoint * point=0);
/// Saves current article and scroll position for the current history item. /// Saves current article and scroll position for the current history item.
/// Should be used when leaving the page. /// Should be used when leaving the page.
void saveHistoryUserData(); void saveHistoryUserData();

72
dsl.cc
View file

@ -1556,32 +1556,8 @@ void DslDictionary::getArticleText( uint32_t articleAddress, QString & headword,
/// DslDictionary::getArticle() /// DslDictionary::getArticle()
class DslArticleRequest;
class DslArticleRequestRunnable: public QRunnable
{
DslArticleRequest & r;
QSemaphore & hasExited;
public:
DslArticleRequestRunnable( DslArticleRequest & r_,
QSemaphore & hasExited_ ): r( r_ ),
hasExited( hasExited_ )
{}
~DslArticleRequestRunnable()
{
hasExited.release();
}
virtual void run();
};
class DslArticleRequest: public Dictionary::DataRequest class DslArticleRequest: public Dictionary::DataRequest
{ {
friend class DslArticleRequestRunnable;
wstring word; wstring word;
vector< wstring > alts; vector< wstring > alts;
DslDictionary & dict; DslDictionary & dict;
@ -1597,11 +1573,10 @@ public:
DslDictionary & dict_, bool ignoreDiacritics_ ): DslDictionary & dict_, bool ignoreDiacritics_ ):
word( word_ ), alts( alts_ ), dict( dict_ ), ignoreDiacritics( ignoreDiacritics_ ) word( word_ ), alts( alts_ ), dict( dict_ ), ignoreDiacritics( ignoreDiacritics_ )
{ {
QThreadPool::globalInstance()->start( QThreadPool::globalInstance()->start( [ this ]() { this->run(); } );
new DslArticleRequestRunnable( *this, hasExited ) );
} }
void run(); // Run from another thread by DslArticleRequestRunnable void run();
virtual void cancel() virtual void cancel()
{ {
@ -1611,15 +1586,10 @@ public:
~DslArticleRequest() ~DslArticleRequest()
{ {
isCancelled.ref(); isCancelled.ref();
hasExited.acquire(); //hasExited.acquire();
} }
}; };
void DslArticleRequestRunnable::run()
{
r.run();
}
void DslArticleRequest::run() void DslArticleRequest::run()
{ {
if ( Utils::AtomicInt::loadAcquire( isCancelled ) ) if ( Utils::AtomicInt::loadAcquire( isCancelled ) )
@ -1759,32 +1729,8 @@ sptr< Dictionary::DataRequest > DslDictionary::getArticle( wstring const & word,
//// DslDictionary::getResource() //// DslDictionary::getResource()
class DslResourceRequest;
class DslResourceRequestRunnable: public QRunnable
{
DslResourceRequest & r;
QSemaphore & hasExited;
public:
DslResourceRequestRunnable( DslResourceRequest & r_,
QSemaphore & hasExited_ ): r( r_ ),
hasExited( hasExited_ )
{}
~DslResourceRequestRunnable()
{
hasExited.release();
}
virtual void run();
};
class DslResourceRequest: public Dictionary::DataRequest class DslResourceRequest: public Dictionary::DataRequest
{ {
friend class DslResourceRequestRunnable;
DslDictionary & dict; DslDictionary & dict;
string resourceName; string resourceName;
@ -1799,11 +1745,10 @@ public:
dict( dict_ ), dict( dict_ ),
resourceName( resourceName_ ) resourceName( resourceName_ )
{ {
QThreadPool::globalInstance()->start( QThreadPool::globalInstance()->start( [ this ]() { this->run(); } );
new DslResourceRequestRunnable( *this, hasExited ) );
} }
void run(); // Run from another thread by DslResourceRequestRunnable void run();
virtual void cancel() virtual void cancel()
{ {
@ -1813,15 +1758,10 @@ public:
~DslResourceRequest() ~DslResourceRequest()
{ {
isCancelled.ref(); isCancelled.ref();
hasExited.acquire(); //hasExited.acquire();
} }
}; };
void DslResourceRequestRunnable::run()
{
r.run();
}
void DslResourceRequest::run() void DslResourceRequest::run()
{ {
// Some runnables linger enough that they are cancelled before they start // Some runnables linger enough that they are cancelled before they start

View file

@ -75,7 +75,8 @@ win32 {
DEFINES += NOMINMAX __WIN64 DEFINES += NOMINMAX __WIN64
} }
LIBS += -L$${PWD}/winlibs/lib/msvc LIBS += -L$${PWD}/winlibs/lib/msvc
QMAKE_CXXFLAGS += /wd4290 /Zc:__cplusplus /std:c++17 # silence the warning C4290: C++ exception specification ignored # silence the warning C4290: C++ exception specification ignored
QMAKE_CXXFLAGS += /wd4290 /Zc:__cplusplus /std:c++17 /permissive-
# QMAKE_LFLAGS_RELEASE += /OPT:REF /OPT:ICF # QMAKE_LFLAGS_RELEASE += /OPT:REF /OPT:ICF
# QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG # QMAKE_LFLAGS_RELEASE = /INCREMENTAL:NO /DEBUG
CONFIG+=force_debug_info CONFIG+=force_debug_info
@ -124,7 +125,6 @@ unix:!mac {
DEFINES += HAVE_X11 DEFINES += HAVE_X11
lessThan(QT_MAJOR_VERSION, 6): QT += x11extras lessThan(QT_MAJOR_VERSION, 6): QT += x11extras
greaterThan(QT_MAJOR_VERSION, 5): QT += gui-private
CONFIG += link_pkgconfig CONFIG += link_pkgconfig
@ -139,9 +139,7 @@ unix:!mac {
libavcodec \ libavcodec \
libswresample \ libswresample \
} }
arm { !arm {
#LIBS += -liconv
} else {
LIBS += -lX11 -lXtst LIBS += -lX11 -lXtst
} }

View file

@ -468,10 +468,17 @@ void HotkeyWrapper::init()
{ {
keyToUngrab = grabbedKeys.end(); keyToUngrab = grabbedKeys.end();
#if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
// We use RECORD extension instead of XGrabKey. That's because XGrabKey // We use RECORD extension instead of XGrabKey. That's because XGrabKey
// prevents other clients from getting their input if it's grabbed. // prevents other clients from getting their input if it's grabbed.
Display * display = QX11Info::display(); Display * display = displayID;
lShiftCode = XKeysymToKeycode( display, XK_Shift_L ); lShiftCode = XKeysymToKeycode( display, XK_Shift_L );
rShiftCode = XKeysymToKeycode( display, XK_Shift_R ); rShiftCode = XKeysymToKeycode( display, XK_Shift_R );
@ -678,13 +685,25 @@ public:
~X11GrabUngrabErrorHandler() ~X11GrabUngrabErrorHandler()
{ {
XFlush( QX11Info::display() ); #if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
XFlush( displayID );
(void) XSetErrorHandler( previousErrorHandler_ ); (void) XSetErrorHandler( previousErrorHandler_ );
} }
bool isError() const bool isError() const
{ {
XFlush( QX11Info::display() ); #if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
XFlush( displayID );
return error; return error;
} }
@ -706,8 +725,14 @@ HotkeyWrapper::GrabbedKeys::iterator HotkeyWrapper::grabKey( quint32 keyCode,
if ( result.second ) if ( result.second )
{ {
#if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
X11GrabUngrabErrorHandler errorHandler; X11GrabUngrabErrorHandler errorHandler;
XGrabKey( QX11Info::display(), keyCode, modifiers, QX11Info::appRootWindow(), XGrabKey( displayID, keyCode, modifiers, DefaultRootWindow(displayID),
True, GrabModeAsync, GrabModeAsync ); True, GrabModeAsync, GrabModeAsync );
if ( errorHandler.isError() ) if ( errorHandler.isError() )
@ -722,8 +747,14 @@ HotkeyWrapper::GrabbedKeys::iterator HotkeyWrapper::grabKey( quint32 keyCode,
void HotkeyWrapper::ungrabKey( GrabbedKeys::iterator i ) void HotkeyWrapper::ungrabKey( GrabbedKeys::iterator i )
{ {
#if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
X11GrabUngrabErrorHandler errorHandler; X11GrabUngrabErrorHandler errorHandler;
XUngrabKey( QX11Info::display(), i->first, i->second, QX11Info::appRootWindow() ); XUngrabKey( displayID, i->first, i->second, XDefaultRootWindow(displayID) );
grabbedKeys.erase( i ); grabbedKeys.erase( i );
@ -746,14 +777,25 @@ quint32 HotkeyWrapper::nativeKey(int key)
keySymName = QKeySequence( key ).toString(); keySymName = QKeySequence( key ).toString();
break; break;
} }
#if QT_VERSION < 0x060000
Display * display = QX11Info::display(); Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
Display * display = displayID;
return XKeysymToKeycode( display, XStringToKeysym( keySymName.toLatin1().data() ) ); return XKeysymToKeycode( display, XStringToKeysym( keySymName.toLatin1().data() ) );
} }
void HotkeyWrapper::unregister() void HotkeyWrapper::unregister()
{ {
Display * display = QX11Info::display(); #if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
Display * display = displayID;
XRecordDisableContext( display, recordContext ); XRecordDisableContext( display, recordContext );
XSync( display, False ); XSync( display, False );

View file

@ -10,7 +10,7 @@
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/extensions/record.h> #include <X11/extensions/record.h>
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QtGui/private/qtx11extras_p.h> #include <QGuiApplication>
#else #else
#include <QX11Info> #include <QX11Info>
#endif #endif

View file

@ -8,7 +8,7 @@
#include <windows.h> #include <windows.h>
#elif defined(HAVE_X11) #elif defined(HAVE_X11)
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QtGui/private/qtx11extras_p.h> #include <QGuiApplication>
#else #else
#include <QX11Info> #include <QX11Info>
#endif #endif
@ -44,9 +44,17 @@ bool KeyboardState::checkModifiersPressed( int mask )
( mask & Shift && !( keys & ( 1 << shiftKeyBit ) ) ) || ( mask & Shift && !( keys & ( 1 << shiftKeyBit ) ) ) ||
( mask & Win && !( keys & ( 1 << controlKeyBit ) ) ) ); ( mask & Win && !( keys & ( 1 << controlKeyBit ) ) ) );
#else #else
#if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
XkbStateRec state; XkbStateRec state;
XkbGetState( QX11Info::display(), XkbUseCoreKbd, &state ); XkbGetState( displayID, XkbUseCoreKbd, &state );
return !( return !(
( mask & Alt && !( state.base_mods & Mod1Mask ) ) || ( mask & Alt && !( state.base_mods & Mod1Mask ) ) ||

View file

@ -65,7 +65,7 @@
#ifdef HAVE_X11 #ifdef HAVE_X11
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0)) #if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
#include <QtGui/private/qtx11extras_p.h> #include <QGuiApplication>
#else #else
#include <QX11Info> #include <QX11Info>
#endif #endif
@ -1246,7 +1246,7 @@ void MainWindow::quitApp()
{ {
if( inspector && inspector->isVisible() ) if( inspector && inspector->isVisible() )
{ {
inspector->hide(); inspector->close();
} }
commitData(); commitData();
qApp->quit(); qApp->quit();
@ -1635,9 +1635,10 @@ ArticleView * MainWindow::createNewTab( bool switchToIt,
groupList ); groupList );
connect( view, &ArticleView::inspectSignal,this,[this](QWebEngineView * view){ connect( view, &ArticleView::inspectSignal,this,[this](QWebEngineView * view){
if(inspector){ if( !inspector ){
inspector->setInspectPage(view); inspector = new ArticleInspector( this );
} }
inspector->setInspectPage( view );
}); });
connect( view, SIGNAL( titleChanged( ArticleView *, QString const & ) ), connect( view, SIGNAL( titleChanged( ArticleView *, QString const & ) ),
@ -2903,9 +2904,15 @@ void MainWindow::toggleMainWindow( bool onlyShow )
focusTranslateLine(); focusTranslateLine();
#ifdef HAVE_X11 #ifdef HAVE_X11
#if QT_VERSION < 0x060000
Display *displayID = QX11Info::display();
#else
QNativeInterface::QX11Application *x11AppInfo = qApp->nativeInterface<QNativeInterface::QX11Application>();
Display *displayID = x11AppInfo->display();
#endif
Window wh = 0; Window wh = 0;
int rev = 0; int rev = 0;
XGetInputFocus( QX11Info::display(), &wh, &rev ); XGetInputFocus( displayID, &wh, &rev );
if( wh != translateLine->internalWinId() && !byIconClick ) if( wh != translateLine->internalWinId() && !byIconClick )
{ {
QPoint p( 1, 1 ); QPoint p( 1, 1 );
@ -2918,17 +2925,17 @@ void MainWindow::toggleMainWindow( bool onlyShow )
event.xbutton.x_root = p.x(); event.xbutton.x_root = p.x();
event.xbutton.y_root = p.y(); event.xbutton.y_root = p.y();
event.xbutton.window = internalWinId(); event.xbutton.window = internalWinId();
event.xbutton.root = QX11Info::appRootWindow( QX11Info::appScreen() ); event.xbutton.root = XDefaultRootWindow(displayID);
event.xbutton.state = Button1Mask; event.xbutton.state = Button1Mask;
event.xbutton.button = Button1; event.xbutton.button = Button1;
event.xbutton.same_screen = true; event.xbutton.same_screen = true;
event.xbutton.time = CurrentTime; event.xbutton.time = CurrentTime;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); XSendEvent( displayID, internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() ); XFlush( displayID );
event.type = ButtonRelease; event.type = ButtonRelease;
XSendEvent( QX11Info::display(), internalWinId(), true, 0xfff, &event ); XSendEvent( displayID, internalWinId(), true, 0xfff, &event );
XFlush( QX11Info::display() ); XFlush( displayID );
} }
#endif #endif
} }

View file

@ -28,6 +28,39 @@ inline QString rstrip(const QString &str) {
return ""; return "";
} }
/**
* remove punctuation , space, symbol
*
*
* " abc, '" should be "abc"
*/
inline QString trimNonChar( const QString & str )
{
QString remain;
int n = str.size() - 1;
for( ; n >= 0; --n )
{
auto c = str.at( n );
if( !c.isSpace() && !c.isSymbol() && !c.isNonCharacter() && !c.isPunct()&& !c.isNull() )
{
remain = str.left( n + 1 );
break;
}
}
n = 0;
for( ; n < remain.size(); n++ )
{
auto c = remain.at( n );
if( !c.isSpace() && !c.isSymbol() && !c.isNonCharacter() && !c.isPunct() )
{
return remain.mid( n );
}
}
return "";
}
/** /**
* str="abc\r\n\u0000" should be returned as "abc" * str="abc\r\n\u0000" should be returned as "abc"
* @brief rstripnull * @brief rstripnull
@ -37,7 +70,8 @@ inline QString rstrip(const QString &str) {
inline QString rstripnull(const QString &str) { inline QString rstripnull(const QString &str) {
int n = str.size() - 1; int n = str.size() - 1;
for (; n >= 0; --n) { for (; n >= 0; --n) {
if (!str.at(n).isSpace()&&!str.at(n).isNull()) { auto c = str.at(n);
if (!c.isSpace()&&!c.isNull()) {
return str.left(n + 1); return str.left(n + 1);
} }
} }
@ -96,6 +130,7 @@ inline int loadAcquire( QAtomicInt const & ref )
namespace Url namespace Url
{ {
// This wrapper is created due to behavior change of the setPath() method // This wrapper is created due to behavior change of the setPath() method
// See: https://bugreports.qt-project.org/browse/QTBUG-27728 // See: https://bugreports.qt-project.org/browse/QTBUG-27728
// https://codereview.qt-project.org/#change,38257 // https://codereview.qt-project.org/#change,38257
@ -158,16 +193,15 @@ inline QString fragment( const QUrl & url )
return url.fragment( QUrl::FullyDecoded ); return url.fragment( QUrl::FullyDecoded );
} }
// extract query word from url // get the query word of bword and gdlookup scheme.
inline QString getWordFromUrl( const QUrl & url ) // if the scheme is gdlookup or scheme ,the first value of pair is true,otherwise is false;
inline std::pair< bool, QString > getQueryWord( QUrl const & url )
{ {
QString word; QString word;
if( url.scheme().compare( "bword" ) == 0 ) bool validScheme = false;
{ if( url.scheme().compare( "gdlookup" ) == 0 )
word = url.path();
}
else if( url.scheme() == "gdlookup" ) // Plain html links inherit gdlookup scheme
{ {
validScheme = true;
if( hasQueryItem( url, "word" ) ) if( hasQueryItem( url, "word" ) )
{ {
word = queryItemValue( url, "word" ); word = queryItemValue( url, "word" );
@ -177,8 +211,12 @@ inline QString getWordFromUrl( const QUrl & url )
word = url.path().mid( 1 ); word = url.path().mid( 1 );
} }
} }
if( url.scheme().compare( "bword" ) == 0 )
return word; {
validScheme = true;
word = url.path().mid( 1 );
}
return std::make_pair( validScheme, word );
} }
} }
@ -188,13 +226,6 @@ namespace
{ {
/// Uses some heuristics to chop off the first domain name from the host name, /// Uses some heuristics to chop off the first domain name from the host name,
/// but only if it's not too base. Returns the resulting host name. /// but only if it's not too base. Returns the resulting host name.
inline QString getHostBase( QUrl const & url )
{
QString host = url.host();
return getHostBase(host);
}
inline QString getHostBase( QString const & host ) inline QString getHostBase( QString const & host )
{ {
QStringList domains = host.split( '.' ); QStringList domains = host.split( '.' );
@ -219,6 +250,13 @@ inline QString getHostBase( QString const & host )
else else
return host; return host;
} }
inline QString getHostBaseFromUrl( QUrl const & url )
{
QString host = url.host();
return getHostBase( host );
}
} }
#endif // UTILS_HH #endif // UTILS_HH

69
zim.cc
View file

@ -1132,32 +1132,8 @@ sptr< Dictionary::DataRequest > ZimDictionary::getSearchResults( QString const &
/// ZimDictionary::getArticle() /// ZimDictionary::getArticle()
class ZimArticleRequest;
class ZimArticleRequestRunnable: public QRunnable
{
ZimArticleRequest & r;
QSemaphore & hasExited;
public:
ZimArticleRequestRunnable( ZimArticleRequest & r_,
QSemaphore & hasExited_ ): r( r_ ),
hasExited( hasExited_ )
{}
~ZimArticleRequestRunnable()
{
hasExited.release();
}
virtual void run();
};
class ZimArticleRequest: public Dictionary::DataRequest class ZimArticleRequest: public Dictionary::DataRequest
{ {
friend class ZimArticleRequestRunnable;
wstring word; wstring word;
vector< wstring > alts; vector< wstring > alts;
ZimDictionary & dict; ZimDictionary & dict;
@ -1173,11 +1149,10 @@ public:
ZimDictionary & dict_, bool ignoreDiacritics_ ): ZimDictionary & dict_, bool ignoreDiacritics_ ):
word( word_ ), alts( alts_ ), dict( dict_ ), ignoreDiacritics( ignoreDiacritics_ ) word( word_ ), alts( alts_ ), dict( dict_ ), ignoreDiacritics( ignoreDiacritics_ )
{ {
QThreadPool::globalInstance()->start( QThreadPool::globalInstance()->start( [ this ]() { this->run(); } );
new ZimArticleRequestRunnable( *this, hasExited ) );
} }
void run(); // Run from another thread by ZimArticleRequestRunnable void run();
virtual void cancel() virtual void cancel()
{ {
@ -1191,11 +1166,6 @@ public:
} }
}; };
void ZimArticleRequestRunnable::run()
{
r.run();
}
void ZimArticleRequest::run() void ZimArticleRequest::run()
{ {
if ( Utils::AtomicInt::loadAcquire( isCancelled ) ) if ( Utils::AtomicInt::loadAcquire( isCancelled ) )
@ -1336,32 +1306,8 @@ sptr< Dictionary::DataRequest > ZimDictionary::getArticle( wstring const & word,
//// ZimDictionary::getResource() //// ZimDictionary::getResource()
class ZimResourceRequest;
class ZimResourceRequestRunnable: public QRunnable
{
ZimResourceRequest & r;
QSemaphore & hasExited;
public:
ZimResourceRequestRunnable( ZimResourceRequest & r_,
QSemaphore & hasExited_ ): r( r_ ),
hasExited( hasExited_ )
{}
~ZimResourceRequestRunnable()
{
//hasExited.release();
}
virtual void run();
};
class ZimResourceRequest: public Dictionary::DataRequest class ZimResourceRequest: public Dictionary::DataRequest
{ {
friend class ZimResourceRequestRunnable;
ZimDictionary & dict; ZimDictionary & dict;
string resourceName; string resourceName;
@ -1372,12 +1318,10 @@ class ZimResourceRequest: public Dictionary::DataRequest
public: public:
ZimResourceRequest(ZimDictionary &dict_, string const &resourceName_) ZimResourceRequest(ZimDictionary &dict_, string const &resourceName_)
: dict(dict_), resourceName(resourceName_) { : dict(dict_), resourceName(resourceName_) {
//(new ZimResourceRequestRunnable(*this, hasExited))->run(); QThreadPool::globalInstance()->start( [ this ]() { this->run(); } );
QThreadPool::globalInstance()->start(
new ZimResourceRequestRunnable( *this, hasExited ) );
} }
void run(); // Run from another thread by ZimResourceRequestRunnable void run();
virtual void cancel() virtual void cancel()
{ {
@ -1391,11 +1335,6 @@ public:
} }
}; };
void ZimResourceRequestRunnable::run()
{
r.run();
}
void ZimResourceRequest::run() void ZimResourceRequest::run()
{ {
// Some runnables linger enough that they are cancelled before they start // Some runnables linger enough that they are cancelled before they start