fix conflict

This commit is contained in:
xiaoyifang 2022-01-08 22:07:33 +08:00
commit 0c55c85339
34 changed files with 292 additions and 160 deletions

View file

@ -44,7 +44,7 @@ About::About( QWidget * parent ): QDialog( parent )
{ {
QStringList creditsList = QStringList creditsList =
QString::fromUtf8( QString::fromUtf8(
creditsFile.readAll() ).split( '\n', QString::SkipEmptyParts ); creditsFile.readAll() ).split( '\n', Qt::SkipEmptyParts );
QString html = "<html><body style='color: black; background: #f4f4f4;'>"; QString html = "<html><body style='color: black; background: #f4f4f4;'>";

View file

@ -14,6 +14,7 @@
#include "langcoder.hh" #include "langcoder.hh"
#include "gddebug.hh" #include "gddebug.hh"
#include "utils.hh" #include "utils.hh"
#include "globalbroadcaster.h"
using std::vector; using std::vector;
using std::string; using std::string;
@ -55,6 +56,10 @@ std::string ArticleMaker::makeHtmlHeader( QString const & word,
{ {
result += "<script type=\"text/javascript\" " result += "<script type=\"text/javascript\" "
"src=\"qrc:///resources/jquery-3.6.0.slim.min.js\"></script>"; "src=\"qrc:///resources/jquery-3.6.0.slim.min.js\"></script>";
//custom javascript
result += "<script type=\"text/javascript\" "
"src=\"qrc:///resources/gd_custom.js\"></script>";
} }
// add qwebchannel // add qwebchannel
@ -630,6 +635,7 @@ void ArticleRequest::bodyFinished()
bool wasUpdated = false; bool wasUpdated = false;
QStringList dictIds;
while ( bodyRequests.size() ) while ( bodyRequests.size() )
{ {
// Since requests should go in order, check the first one first // Since requests should go in order, check the first one first
@ -649,7 +655,7 @@ void ArticleRequest::bodyFinished()
activeDicts[ activeDicts.size() - bodyRequests.size() ]; activeDicts[ activeDicts.size() - bodyRequests.size() ];
string dictId = activeDict->getId(); string dictId = activeDict->getId();
dictIds << QString::fromStdString(dictId);
string head; string head;
string gdFrom = "gdfrom-" + Html::escape( dictId ); string gdFrom = "gdfrom-" + Html::escape( dictId );
@ -702,14 +708,6 @@ void ArticleRequest::bodyFinished()
} }
string jsVal = Html::escapeForJavaScript( dictId ); string jsVal = Html::escapeForJavaScript( dictId );
head += "<script type=\"text/javascript\">var gdArticleContents; "
"if ( !gdArticleContents ) gdArticleContents = \"" + jsVal +" \"; "
"else gdArticleContents += \"" + jsVal + " \";"
"function playSound(sound){"
" var a=new Audio(sound);"
" a.play();"
"}"
"</script>";
head += string( "<div class=\"gdarticle" ) + head += string( "<div class=\"gdarticle" ) +
( closePrevSpan ? "" : " gdactivearticle" ) + ( closePrevSpan ? "" : " gdactivearticle" ) +
@ -787,6 +785,7 @@ void ArticleRequest::bodyFinished()
} }
} }
if ( bodyRequests.empty() ) if ( bodyRequests.empty() )
{ {
// No requests left, end the article // No requests left, end the article
@ -834,12 +833,16 @@ void ArticleRequest::bodyFinished()
if ( stemmedWordFinder.get() ) if ( stemmedWordFinder.get() )
update(); update();
else else {
finish(); finish();
qDebug() << "send dicts:" << dictIds;
emit GlobalBroadcaster::instance()->emitDictIds(ActiveDictIds{word, dictIds});
} }
else } else if (wasUpdated) {
if ( wasUpdated )
update(); update();
qDebug() << "send dicts(updated):" << dictIds;
emit GlobalBroadcaster::instance()->emitDictIds(ActiveDictIds{word, dictIds});
}
} }
void ArticleRequest::stemmedSearchFinished() void ArticleRequest::stemmedSearchFinished()

View file

@ -207,10 +207,10 @@ QNetworkReply * ArticleNetworkAccessManager::createRequest( Operation op,
return QNetworkAccessManager::createRequest( op, newReq, outgoingData ); return QNetworkAccessManager::createRequest( op, newReq, outgoingData );
} }
QString contentType;
QUrl url=req.url(); QUrl url=req.url();
QMimeType mineType=db.mimeTypeForUrl (url);
QString contentType=mineType.name();
if(req.url().scheme()=="gdlookup"){ if(req.url().scheme()=="gdlookup"){
QString path=url.path(); QString path=url.path();
if(!path.isEmpty()){ if(!path.isEmpty()){
@ -379,7 +379,6 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
{ {
if( url.scheme() == "gico" ) if( url.scheme() == "gico" )
{ {
contentType="image/png";
QByteArray bytes; QByteArray bytes;
QBuffer buffer(&bytes); QBuffer buffer(&bytes);
buffer.open(QIODevice::WriteOnly); buffer.open(QIODevice::WriteOnly);
@ -485,8 +484,6 @@ qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
if ( maxSize == 0 ) if ( maxSize == 0 )
return 0; return 0;
GD_DPRINTF( "====reading %d bytes\n", (int)maxSize );
bool finished = req->isFinished(); bool finished = req->isFinished();
qint64 avail = req->dataSize(); qint64 avail = req->dataSize();
@ -497,6 +494,7 @@ qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
qint64 left = avail - alreadyRead; qint64 left = avail - alreadyRead;
qint64 toRead = maxSize < left ? maxSize : left; qint64 toRead = maxSize < left ? maxSize : left;
GD_DPRINTF( "====reading %d bytes\n", (int)toRead );
try try
{ {
@ -517,13 +515,15 @@ qint64 ArticleResourceReply::readData( char * out, qint64 maxSize )
void ArticleResourceReply::readyReadSlot() void ArticleResourceReply::readyReadSlot()
{ {
readyRead(); emit readyRead();
} }
void ArticleResourceReply::finishedSlot() void ArticleResourceReply::finishedSlot()
{ {
if ( req->dataSize() < 0 ) if (req->dataSize() < 0) {
error( ContentNotFoundError ); emit error(ContentNotFoundError);
setError(ContentNotFoundError, "content not found");
}
emit finished(); emit finished();
} }

View file

@ -99,6 +99,7 @@ class ArticleNetworkAccessManager: public QNetworkAccessManager
ArticleMaker const & articleMaker; ArticleMaker const & articleMaker;
bool const & disallowContentFromOtherSites; bool const & disallowContentFromOtherSites;
bool const & hideGoldenDictHeader; bool const & hideGoldenDictHeader;
QMimeDatabase db;
public: public:

View file

@ -28,7 +28,7 @@
#include <QWebEngineSettings> #include <QWebEngineSettings>
#include <assert.h> #include <assert.h>
#include <map> #include <map>
#include <QWebEngineContextMenuData>
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#include <windows.h> #include <windows.h>
#include <QPainter> #include <QPainter>
@ -40,6 +40,7 @@
#include "speechclient.hh" #include "speechclient.hh"
#endif #endif
#include "globalbroadcaster.h"
using std::map; using std::map;
using std::list; using std::list;
@ -180,7 +181,7 @@ QString ArticleView::runJavaScriptSync(QWebEnginePage* frame, const QString& var
QString result; QString result;
QSharedPointer<QEventLoop> loop = QSharedPointer<QEventLoop>(new QEventLoop()); QSharedPointer<QEventLoop> loop = QSharedPointer<QEventLoop>(new QEventLoop());
QTimer::singleShot(1000, loop.data(), &QEventLoop::quit); QTimer::singleShot(1000, loop.data(), &QEventLoop::quit);
frame->runJavaScript(variable, [loop,&result](const QVariant &v) frame->runJavaScript(variable, [=,&result](const QVariant &v)
{ {
if(loop->isRunning()){ if(loop->isRunning()){
if(v.isValid()) if(v.isValid())
@ -275,8 +276,6 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm,
connect(ui.definition, SIGNAL(loadFinished(bool)), this, connect(ui.definition, SIGNAL(loadFinished(bool)), this,
SLOT(loadFinished(bool))); SLOT(loadFinished(bool)));
attachToJavaScript();
connect( ui.definition->page(), SIGNAL( titleChanged( QString const & ) ), connect( ui.definition->page(), SIGNAL( titleChanged( QString const & ) ),
this, SLOT( handleTitleChanged( QString const & ) ) ); this, SLOT( handleTitleChanged( QString const & ) ) );
@ -340,6 +339,7 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm,
QWebEngineSettings * settings = ui.definition->page()->settings(); QWebEngineSettings * settings = ui.definition->page()->settings();
settings->defaultSettings()->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true ); settings->defaultSettings()->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true );
settings->defaultSettings()->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessFileUrls, true ); settings->defaultSettings()->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessFileUrls, true );
settings->defaultSettings()->setAttribute( QWebEngineSettings::WebAttribute::ErrorPageEnabled, false);
// Load the default blank page instantly, so there would be no flicker. // Load the default blank page instantly, so there would be no flicker.
QString contentType; QString contentType;
@ -359,6 +359,12 @@ ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm,
// Variable name for store current selection range // Variable name for store current selection range
rangeVarName = QString( "sr_%1" ).arg( QString::number( (quint64)this, 16 ) ); rangeVarName = QString( "sr_%1" ).arg( QString::number( (quint64)this, 16 ) );
connect(GlobalBroadcaster::instance(), SIGNAL( emitDictIds(ActiveDictIds)), this,
SLOT(setActiveDictIds(ActiveDictIds)));
channel = new QWebChannel(ui.definition->page());
attachToJavaScript();
} }
// explicitly report the minimum size, to avoid // explicitly report the minimum size, to avoid
@ -377,7 +383,7 @@ ArticleView::~ArticleView()
{ {
cleanupTemp(); cleanupTemp();
audioPlayer->stop(); audioPlayer->stop();
channel->deregisterObject(this);
ui.definition->ungrabGesture( Gestures::GDPinchGestureType ); ui.definition->ungrabGesture( Gestures::GDPinchGestureType );
ui.definition->ungrabGesture( Gestures::GDSwipeGestureType ); ui.definition->ungrabGesture( Gestures::GDSwipeGestureType );
} }
@ -386,6 +392,8 @@ void ArticleView::showDefinition( Config::InputPhrase const & phrase, unsigned g
QString const & scrollTo, QString const & scrollTo,
Contexts const & contexts_ ) Contexts const & contexts_ )
{ {
currentWord = phrase.phrase;
currentActiveDictIds.clear();
// first, let's stop the player // first, let's stop the player
audioPlayer->stop(); audioPlayer->stop();
@ -508,15 +516,14 @@ void ArticleView::showAnticipation()
void ArticleView::loadFinished( bool ) void ArticleView::loadFinished( bool )
{ {
setZoomFactor(cfg.preferences.zoomFactor);
QUrl url = ui.definition->url(); QUrl url = ui.definition->url();
QObject* obj=sender(); qDebug() << "article view loaded url:" << url;
qDebug()<<"article view loaded url:"<<url;
QVariant userDataVariant = ui.definition->property("currentArticle"); QVariant userDataVariant = ui.definition->property("currentArticle");
if ( userDataVariant.isValid() ) if ( userDataVariant.isValid() )
{ {
QString currentArticle = userDataVariant.toString(); QString currentArticle = userDataVariant.toString();
if ( !currentArticle.isEmpty() ) if ( !currentArticle.isEmpty() )
@ -645,8 +652,7 @@ unsigned ArticleView::getGroup( QUrl const & url )
QStringList ArticleView::getArticlesList() QStringList ArticleView::getArticlesList()
{ {
return runJavaScriptSync( ui.definition->page(), "gdArticleContents" ) return currentActiveDictIds;
.trimmed().split( ' ', Qt::SkipEmptyParts );
} }
QString ArticleView::getActiveArticleId() QString ArticleView::getActiveArticleId()
@ -758,7 +764,7 @@ void ArticleView::tryMangleWebsiteClickedUrl( QUrl & url, Contexts & contexts )
void ArticleView::updateCurrentArticleFromCurrentFrame( QWebEnginePage * frame ,QPoint * point) void ArticleView::updateCurrentArticleFromCurrentFrame( QWebEnginePage * frame ,QPoint * point)
{ {
qDebug("updateCurrentArticleFromCurrentFrame");
} }
void ArticleView::saveHistoryUserData() void ArticleView::saveHistoryUserData()
@ -916,7 +922,8 @@ bool ArticleView::eventFilter( QObject * obj, QEvent * ev )
keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Tab ||
keyEvent->key() == Qt::Key_Backtab || keyEvent->key() == Qt::Key_Backtab ||
keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Return ||
keyEvent->key() == Qt::Key_Enter ) keyEvent->key() == Qt::Key_Enter ||
keyEvent->key() == Qt::Key_Escape)
return false; // Those key have other uses than to start typing return false; // Those key have other uses than to start typing
QString text = keyEvent->text(); QString text = keyEvent->text();
@ -972,16 +979,14 @@ QString ArticleView::getMutedForGroup( unsigned group )
return QString(); return QString();
} }
QStringList ArticleView::getMutedDictionaries(unsigned group) QStringList ArticleView::getMutedDictionaries(unsigned group) {
{ if (dictionaryBarToggled && dictionaryBarToggled->isChecked()) {
if (dictionaryBarToggled && dictionaryBarToggled->isChecked())
{
// Dictionary bar is active -- mute the muted dictionaries // Dictionary bar is active -- mute the muted dictionaries
Instances::Group const* groupInstance = groups.findGroup(group); Instances::Group const *groupInstance = groups.findGroup(group);
// Find muted dictionaries for current group // Find muted dictionaries for current group
Config::Group const* grp = cfg.getGroup(group); Config::Group const *grp = cfg.getGroup(group);
Config::MutedDictionaries const* mutedDictionaries; Config::MutedDictionaries const *mutedDictionaries;
if (group == Instances::Group::AllGroupId) if (group == Instances::Group::AllGroupId)
mutedDictionaries = popupView ? &cfg.popupMutedDictionaries : &cfg.mutedDictionaries; mutedDictionaries = popupView ? &cfg.popupMutedDictionaries : &cfg.mutedDictionaries;
else else
@ -991,12 +996,9 @@ QStringList ArticleView::getMutedDictionaries(unsigned group)
QStringList mutedDicts; QStringList mutedDicts;
if (groupInstance) if (groupInstance) {
{ for (unsigned x = 0; x < groupInstance->dictionaries.size(); ++x) {
for (unsigned x = 0; x < groupInstance->dictionaries.size(); ++x) QString id = QString::fromStdString(groupInstance->dictionaries[x]->getId());
{
QString id = QString::fromStdString(
groupInstance->dictionaries[x]->getId());
if (mutedDictionaries->contains(id)) if (mutedDictionaries->contains(id))
mutedDicts.append(id); mutedDicts.append(id);
@ -1084,7 +1086,7 @@ void ArticleView::linkHovered ( const QString & link )
} }
void ArticleView::attachToJavaScript() { void ArticleView::attachToJavaScript() {
QWebChannel *channel = new QWebChannel(ui.definition->page());
// set the web channel to be used by the page // set the web channel to be used by the page
// see http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel // see http://doc.qt.io/qt-5/qwebenginepage.html#setWebChannel
@ -1124,7 +1126,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
QString const & scrollTo, QString const & scrollTo,
Contexts const & contexts_ ) Contexts const & contexts_ )
{ {
qDebug() << "clicked" << url; qDebug() << "open link url:" << url;
Contexts contexts( contexts_ ); Contexts contexts( contexts_ );
@ -1716,13 +1718,14 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
QAction * saveImageAction = 0; QAction * saveImageAction = 0;
QAction * saveSoundAction = 0; QAction * saveSoundAction = 0;
//todo url() or lastclickurl ? QWebEngineContextMenuData menuData=r->contextMenuData();
QUrl targetUrl( r->url() ); QUrl targetUrl(menuData.linkUrl());
qDebug() << "menu:" << menuData.linkText()<<":"<<menuData.mediaUrl();
Contexts contexts; Contexts contexts;
tryMangleWebsiteClickedUrl( targetUrl, contexts ); tryMangleWebsiteClickedUrl( targetUrl, contexts );
if ( !r->url().isEmpty() ) if ( !targetUrl.isEmpty() )
{ {
if ( !isExternalLink( targetUrl ) ) if ( !isExternalLink( targetUrl ) )
{ {
@ -1737,7 +1740,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
} }
} }
if ( isExternalLink( r->url() ) ) if ( isExternalLink( targetUrl ) )
{ {
followLinkExternal = new QAction( tr( "Open Link in &External Browser" ), &menu ); followLinkExternal = new QAction( tr( "Open Link in &External Browser" ), &menu );
menu.addAction( followLinkExternal ); menu.addAction( followLinkExternal );
@ -1745,6 +1748,25 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
} }
} }
QUrl imageUrl;
if( !popupView && menuData.mediaType ()==QWebEngineContextMenuData::MediaTypeImage)
{
imageUrl = menuData.mediaUrl ();
if( !imageUrl.isEmpty() )
{
menu.addAction( ui.definition->pageAction( QWebEnginePage::CopyImageToClipboard ) );
saveImageAction = new QAction( tr( "Save &image..." ), &menu );
menu.addAction( saveImageAction );
}
}
if( !popupView && ( targetUrl.scheme() == "gdau"
|| Dictionary::WebMultimediaDownload::isAudioUrl( targetUrl ) ) )
{
saveSoundAction = new QAction( tr( "Save s&ound..." ), &menu );
menu.addAction( saveSoundAction );
}
QString selectedText = ui.definition->selectedText(); QString selectedText = ui.definition->selectedText();
QString text = selectedText.trimmed(); QString text = selectedText.trimmed();
@ -1896,7 +1918,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
openLink( targetUrl, ui.definition->url(), getCurrentArticle(), contexts ); openLink( targetUrl, ui.definition->url(), getCurrentArticle(), contexts );
else else
if ( result == followLinkExternal ) if ( result == followLinkExternal )
QDesktopServices::openUrl( r->url() ); QDesktopServices::openUrl( targetUrl );
else else
if ( result == lookupSelection ) if ( result == lookupSelection )
showDefinition( selectedText, getGroup( ui.definition->url() ), getCurrentArticle() ); showDefinition( selectedText, getGroup( ui.definition->url() ), getCurrentArticle() );
@ -1988,7 +2010,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
} }
} }
qDebug( "url = %s\n", r->url().toString().toLocal8Bit().data() ); qDebug( "url = %s\n", targetUrl.toString().toLocal8Bit().data() );
qDebug( "title = %s\n", r->title().toLocal8Bit().data() ); qDebug( "title = %s\n", r->title().toLocal8Bit().data() );
} }
@ -2526,6 +2548,16 @@ QString ArticleView::getWebPageTextSync(QWebEnginePage * page){
return planText; return planText;
} }
void ArticleView::setActiveDictIds(ActiveDictIds ad) {
// ignore all other signals.
if (ad.word == currentWord) {
currentActiveDictIds << ad.dictIds;
currentActiveDictIds.removeDuplicates();
qDebug() << "current word:"<<currentWord<<"receivedd:"<<ad.word<<":" << ad.dictIds<<this;
}
}
//todo ,futher refinement? //todo ,futher refinement?
void ArticleView::performFtsFindOperation( bool backwards ) void ArticleView::performFtsFindOperation( bool backwards )
{ {

View file

@ -14,6 +14,7 @@
#include "instances.hh" #include "instances.hh"
#include "groupcombobox.hh" #include "groupcombobox.hh"
#include "ui_articleview.h" #include "ui_articleview.h"
#include "globalbroadcaster.h"
class ResourceToSaveHandler; class ResourceToSaveHandler;
@ -29,7 +30,7 @@ class ArticleView: public QFrame
Instances::Groups const & groups; Instances::Groups const & groups;
bool popupView; bool popupView;
Config::Class const & cfg; Config::Class const & cfg;
QWebChannel *channel;
Ui::ArticleView ui; Ui::ArticleView ui;
QAction pasteAction, articleUpAction, articleDownAction, QAction pasteAction, articleUpAction, articleDownAction,
@ -55,7 +56,13 @@ class ArticleView: public QFrame
QSet< QString > desktopOpenedTempFiles; QSet< QString > desktopOpenedTempFiles;
QAction * dictionaryBarToggled; QAction * dictionaryBarToggled;
GroupComboBox const * groupComboBox; GroupComboBox const *groupComboBox;
/// current searching word.
QString currentWord;
/// current active dict id list;
QStringList currentActiveDictIds;
/// Search in results of full-text search /// Search in results of full-text search
QStringList allMatches; QStringList allMatches;
@ -276,14 +283,14 @@ public slots:
/// Selects an entire text of the current article /// Selects an entire text of the current article
void selectCurrentArticle(); void selectCurrentArticle();
void linkClicked( QUrl const & );
private slots: private slots:
void loadFinished( bool ok ); void loadFinished( bool ok );
void handleTitleChanged( QString const & title ); void handleTitleChanged( QString const & title );
void handleUrlChanged( QUrl const & url ); void handleUrlChanged( QUrl const & url );
void attachToJavaScript(); void attachToJavaScript();
void linkClicked( QUrl const & );
void linkHovered( const QString & link); void linkHovered( const QString & link);
void contextMenuRequested( QPoint const & ); void contextMenuRequested( QPoint const & );
@ -322,13 +329,14 @@ private slots:
/// Inspect element /// Inspect element
void inspect(); void inspect();
void setActiveDictIds(ActiveDictIds);
private: private:
/// Deduces group from the url. If there doesn't seem to be any group, /// Deduces group from the url. If there doesn't seem to be any group,
/// returns 0. /// returns 0.
unsigned getGroup( QUrl const & ); unsigned getGroup( QUrl const & );
/// Returns current article in the view, in the form of "gdfrom-xxx" id. /// Returns current article in the view, in the form of "gdfrom-xxx" id.
QString getCurrentArticle(); QString getCurrentArticle();
@ -374,6 +382,7 @@ private:
QStringList getMutedDictionaries(unsigned group); QStringList getMutedDictionaries(unsigned group);
protected: protected:
// We need this to hide the search bar when we're showed // We need this to hide the search bar when we're showed
void showEvent( QShowEvent * ); void showEvent( QShowEvent * );

View file

@ -64,7 +64,7 @@ bool ArticleWebView::eventFilter(QObject *obj, QEvent *ev)
mouseReleaseEvent(pe); mouseReleaseEvent(pe);
if (firstClicked) { if (firstClicked) {
QTimer::singleShot(QApplication::doubleClickInterval(),this,[=](){ QTimer::singleShot(QApplication::doubleClickInterval(),this,[=](){
singleClickAction(pe); singleClickAction(obj,pe);
}); });
} else { } else {
doubleClickAction(pe); doubleClickAction(pe);
@ -73,12 +73,10 @@ bool ArticleWebView::eventFilter(QObject *obj, QEvent *ev)
if (ev->type() == QEvent::Wheel) { if (ev->type() == QEvent::Wheel) {
QWheelEvent *pe = static_cast<QWheelEvent *>(ev); QWheelEvent *pe = static_cast<QWheelEvent *>(ev);
wheelEvent(pe); wheelEvent(pe);
//return true;
} }
if (ev->type() == QEvent::FocusIn) { if (ev->type() == QEvent::FocusIn) {
QFocusEvent *pe = static_cast<QFocusEvent *>(ev); QFocusEvent *pe = static_cast<QFocusEvent *>(ev);
focusInEvent(pe); focusInEvent(pe);
//return true;
} }
return QWebEngineView::eventFilter(obj, ev); return QWebEngineView::eventFilter(obj, ev);
@ -92,36 +90,31 @@ void ArticleWebView::mousePressEvent(QMouseEvent *event)
//QWebEngineView::mousePressEvent(event); //QWebEngineView::mousePressEvent(event);
} }
void ArticleWebView::singleClickAction( QMouseEvent * event ) void ArticleWebView::singleClickAction(QObject* obj, QMouseEvent * event )
{ {
if(!firstClicked) if(!firstClicked)
return; return;
if (selectionBySingleClick) { if (selectionBySingleClick) {
// findText(""); // clear the selection first, if any findText(""); // clear the selection first, if any
page()->runJavaScript(QString( //send dbl click event twice? send one time seems not work .weird really. need further investigate.
" var s = window.getSelection(); " sendCustomMouseEvent(obj, QEvent::MouseButtonDblClick);
" if(s.rangeCount>0){ " sendCustomMouseEvent(obj, QEvent::MouseButtonDblClick);
" var range = s.getRangeAt(0); "
" var node = s.anchorNode; "
" while (range.toString().indexOf(' ') != 0) { "
" range.setStart(node, (range.startOffset - 1)); "
" } "
" range.setStart(node, range.startOffset + 1); "
" do { "
" range.setEnd(node, range.endOffset+1); "
" } "
" while (range.toString().indexOf(' ') == -1 && range.toString().trim() != ''); "
" range.setEnd(node,range.endOffset-1);"
" var str = range.toString().trim(); "
" console.log(str);"
" }"));
} }
} }
void ArticleWebView::sendCustomMouseEvent(QObject *obj, QEvent::Type type) {
QPoint pt = mapFromGlobal(QCursor::pos());
QMouseEvent ev(type, pt, pt, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier,
Qt::MouseEventSynthesizedByApplication);
void ArticleWebView::mouseReleaseEvent( QMouseEvent * event ) QObjectList list = this->children();
{ for (int i = 0; i < list.size(); i++) {
QApplication::sendEvent(list[i], &ev);
}
}
void ArticleWebView::mouseReleaseEvent(QMouseEvent *event) {
bool noMidButton = !( event->buttons() & Qt::MiddleButton ); bool noMidButton = !( event->buttons() & Qt::MiddleButton );
//QWebEngineView::mouseReleaseEvent( event ); //QWebEngineView::mouseReleaseEvent( event );
@ -130,18 +123,13 @@ void ArticleWebView::mouseReleaseEvent( QMouseEvent * event )
midButtonPressed = false; midButtonPressed = false;
} }
void ArticleWebView::doubleClickAction( QMouseEvent * event ) void ArticleWebView::doubleClickAction(QMouseEvent *event) {
{ // QWebEngineView::mouseDoubleClickEvent( event );
//QWebEngineView::mouseDoubleClickEvent( event );
int scrollBarWidth = 0;
int scrollBarHeight = 0;
// emit the signal only if we are not double-clicking on scrollbars // emit the signal only if we are not double-clicking on scrollbars
if ((event->x() < width() - scrollBarWidth) && (event->y() < height() - scrollBarHeight)) { if (Qt::MouseEventSynthesizedByApplication != event->source()) {
emit doubleClicked(event->pos()); emit doubleClicked(event->pos());
} }
} }
void ArticleWebView::focusInEvent( QFocusEvent * event ) void ArticleWebView::focusInEvent( QFocusEvent * event )

View file

@ -51,7 +51,8 @@ public:
protected: protected:
bool event( QEvent * event ); bool event( QEvent * event );
void singleClickAction( QMouseEvent * event ); void singleClickAction(QObject *obj, QMouseEvent *event);
void sendCustomMouseEvent(QObject *obj, QEvent::Type type);
void mousePressEvent(QMouseEvent *event); void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent( QMouseEvent * event ); void mouseReleaseEvent( QMouseEvent * event );
void doubleClickAction( QMouseEvent * event ); void doubleClickAction( QMouseEvent * event );

View file

@ -200,11 +200,11 @@ public:
if( pos < 0 ) if( pos < 0 )
url = "dict://" + url; url = "dict://" + url;
databases = database_.split( QRegExp( "[ ,;]" ), QString::SkipEmptyParts ); databases = database_.split( QRegExp( "[ ,;]" ), Qt::SkipEmptyParts );
if( databases.isEmpty() ) if( databases.isEmpty() )
databases.append( "*" ); databases.append( "*" );
strategies = strategies_.split( QRegExp( "[ ,;]" ), QString::SkipEmptyParts ); strategies = strategies_.split( QRegExp( "[ ,;]" ), Qt::SkipEmptyParts );
if( strategies.isEmpty() ) if( strategies.isEmpty() )
strategies.append( "prefix" ); strategies.append( "prefix" );
} }

View file

@ -555,7 +555,7 @@ bool EpwingBook::setSubBook( int book_nom )
QString line = ts.readLine(); QString line = ts.readLine();
while( !line.isEmpty() ) while( !line.isEmpty() )
{ {
QStringList list = line.remove( '\n' ).split( ' ', QString::SkipEmptyParts ); QStringList list = line.remove( '\n' ).split( ' ', Qt::SkipEmptyParts );
if( list.count() == 2 ) if( list.count() == 2 )
customFontsMap[ list[ 0 ] ] = list[ 1 ]; customFontsMap[ list[ 0 ] ] = list[ 1 ];
line = ts.readLine(); line = ts.readLine();

View file

@ -976,7 +976,7 @@ bool FavoritesModel::addNewHeadword( const QString & path, const QString & headw
// Find or create target folder // Find or create target folder
QStringList folders = path.split( "/", QString::SkipEmptyParts ); QStringList folders = path.split( "/", Qt::SkipEmptyParts );
QStringList::const_iterator it = folders.begin(); QStringList::const_iterator it = folders.begin();
for( ; it != folders.end(); ++it ) for( ; it != folders.end(); ++it )
parentIdx = forceFolder( *it, parentIdx ); parentIdx = forceFolder( *it, parentIdx );
@ -992,7 +992,7 @@ bool FavoritesModel::removeHeadword( const QString & path, const QString & headw
// Find target folder // Find target folder
QStringList folders = path.split( "/", QString::SkipEmptyParts ); QStringList folders = path.split( "/", Qt::SkipEmptyParts );
QStringList::const_iterator it = folders.begin(); QStringList::const_iterator it = folders.begin();
for( ; it != folders.end(); ++it ) for( ; it != folders.end(); ++it )
{ {
@ -1022,7 +1022,7 @@ bool FavoritesModel::isHeadwordPresent( const QString & path, const QString & he
// Find target folder // Find target folder
QStringList folders = path.split( "/", QString::SkipEmptyParts ); QStringList folders = path.split( "/", Qt::SkipEmptyParts );
QStringList::const_iterator it = folders.begin(); QStringList::const_iterator it = folders.begin();
for( ; it != folders.end(); ++it ) for( ; it != folders.end(); ++it )
{ {

View file

@ -353,7 +353,7 @@ vector< sptr< Dictionary::Class > > makeDictionaries(
if ( forvo.enable ) if ( forvo.enable )
{ {
QStringList codes = forvo.languageCodes.split( ',', QString::SkipEmptyParts ); QStringList codes = forvo.languageCodes.split( ',', Qt::SkipEmptyParts );
QSet< QString > usedCodes; QSet< QString > usedCodes;

View file

@ -91,17 +91,17 @@ bool parseSearchString( QString const & str, QStringList & indexWords,
// Make words list for search in article text // Make words list for search in article text
searchWords = str.normalized( QString::NormalizationForm_C ) searchWords = str.normalized( QString::NormalizationForm_C )
.split( spacesRegExp, QString::SkipEmptyParts ); .split( spacesRegExp, Qt::SkipEmptyParts );
// Make words list for index search // Make words list for index search
QStringList list = str.normalized( QString::NormalizationForm_C ) QStringList list = str.normalized( QString::NormalizationForm_C )
.toLower().split( spacesRegExp, QString::SkipEmptyParts ); .toLower().split( spacesRegExp, Qt::SkipEmptyParts );
indexWords = list.filter( wordRegExp ); indexWords = list.filter( wordRegExp );
indexWords.removeDuplicates(); indexWords.removeDuplicates();
// Make regexp for results hilite // Make regexp for results hilite
QStringList allWords = str.split( spacesRegExp, QString::SkipEmptyParts ); QStringList allWords = str.split( spacesRegExp, Qt::SkipEmptyParts );
QString searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords ); QString searchString = makeHiliteRegExpString( allWords, searchMode, distanceBetweenWords );
searchRegExp = QRegExp( searchString, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive, searchRegExp = QRegExp( searchString, matchCase ? Qt::CaseSensitive : Qt::CaseInsensitive,
@ -124,7 +124,7 @@ bool parseSearchString( QString const & str, QStringList & indexWords,
tmp.replace( setsRegExp, " " ); tmp.replace( setsRegExp, " " );
QStringList list = tmp.normalized( QString::NormalizationForm_C ) QStringList list = tmp.normalized( QString::NormalizationForm_C )
.toLower().split( spacesRegExp, QString::SkipEmptyParts ); .toLower().split( spacesRegExp, Qt::SkipEmptyParts );
if( hasCJK ) if( hasCJK )
{ {
@ -189,7 +189,7 @@ void parseArticleForFts( uint32_t articleAddress, QString & articleText,
QStringList articleWords = articleText.normalized( QString::NormalizationForm_C ) QStringList articleWords = articleText.normalized( QString::NormalizationForm_C )
.split( QRegularExpression( handleRoundBrackets ? "[^\\w\\(\\)\\p{M}]+" : "[^\\w\\p{M}]+", .split( QRegularExpression( handleRoundBrackets ? "[^\\w\\(\\)\\p{M}]+" : "[^\\w\\p{M}]+",
QRegularExpression::UseUnicodePropertiesOption ), QRegularExpression::UseUnicodePropertiesOption ),
QString::SkipEmptyParts ); Qt::SkipEmptyParts );
QSet< QString > setOfWords; QSet< QString > setOfWords;
@ -233,7 +233,7 @@ void parseArticleForFts( uint32_t articleAddress, QString & articleText,
// Special handle for words with round brackets - DSL feature // Special handle for words with round brackets - DSL feature
QStringList list; QStringList list;
QStringList oldVariant = word.split( regSplit, QString::SkipEmptyParts ); QStringList oldVariant = word.split( regSplit, Qt::SkipEmptyParts );
for( QStringList::iterator it = oldVariant.begin(); it != oldVariant.end(); ++it ) for( QStringList::iterator it = oldVariant.begin(); it != oldVariant.end(); ++it )
if( it->size() >= FTS::MinimumWordSize && !list.contains( *it ) ) if( it->size() >= FTS::MinimumWordSize && !list.contains( *it ) )
list.append( *it ); list.append( *it );
@ -509,7 +509,7 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets,
articleText = gd::toQString( Folding::applyDiacriticsOnly( gd::toWString( articleText ) ) ); articleText = gd::toQString( Folding::applyDiacriticsOnly( gd::toWString( articleText ) ) );
QStringList articleWords = articleText.split( needHandleBrackets ? splitWithBrackets : splitWithoutBrackets, QStringList articleWords = articleText.split( needHandleBrackets ? splitWithBrackets : splitWithoutBrackets,
QString::SkipEmptyParts ); Qt::SkipEmptyParts );
int wordsNum = articleWords.length(); int wordsNum = articleWords.length();
while ( pos < wordsNum ) while ( pos < wordsNum )
@ -540,7 +540,7 @@ void FTSResultsRequest::checkArticles( QVector< uint32_t > const & offsets,
parsedWords.append( word ); parsedWords.append( word );
} }
else else
parsedWords = s.split( regSplit, QString::SkipEmptyParts ); parsedWords = s.split( regSplit, Qt::SkipEmptyParts );
} }
else else
parsedWords.append( s ); parsedWords.append( s );

View file

@ -10,10 +10,17 @@ void GicoSchemeHandler::requestStarted(QWebEngineUrlRequestJob *requestJob)
QNetworkRequest request; QNetworkRequest request;
request.setUrl( url ); request.setUrl( url );
QNetworkReply* reply=this->mManager.createRequest(QNetworkAccessManager::GetOperation,request,NULL); QNetworkReply *reply = this->mManager.createRequest(QNetworkAccessManager::GetOperation, request, NULL);
QMimeType mineType=db.mimeTypeForUrl (url); connect(reply, &QNetworkReply::finished, requestJob, [=]() {
QString contentType=mineType.name (); if (reply->error() == QNetworkReply::ContentNotFoundError) {
requestJob->fail(QWebEngineUrlRequestJob::UrlNotFound);
return;
}
QMimeType mineType = db.mimeTypeForUrl(url);
QString contentType = mineType.name();
// Reply segment // Reply segment
requestJob->reply(contentType.toLatin1(), reply); requestJob->reply(contentType.toLatin1(), reply);
});
} }

14
globalbroadcaster.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "globalbroadcaster.h"
#include <QGlobalStatic>
Q_GLOBAL_STATIC(GlobalBroadcaster, bdcaster)
GlobalBroadcaster::GlobalBroadcaster(QObject *parent) : QObject(parent)
{
}
GlobalBroadcaster* GlobalBroadcaster::instance() { return bdcaster; }
// namespace global

24
globalbroadcaster.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef GLOBAL_GLOBALBROADCASTER_H
#define GLOBAL_GLOBALBROADCASTER_H
#include <QObject>
struct ActiveDictIds {
QString word;
QStringList dictIds;
}
;
class GlobalBroadcaster : public QObject
{
Q_OBJECT
public:
GlobalBroadcaster(QObject *parent = nullptr);
static GlobalBroadcaster *instance();
signals:
void emitDictIds(ActiveDictIds ad);
};
#endif // GLOBAL_GLOBALBROADCASTER_H

View file

@ -250,6 +250,7 @@ DEFINES += PROGRAM_VERSION=\\\"$$VERSION\\\"
# Input # Input
HEADERS += folding.hh \ HEADERS += folding.hh \
gico_schemahandler.h \ gico_schemahandler.h \
globalbroadcaster.h \
inc_case_folding.hh \ inc_case_folding.hh \
inc_diacritic_folding.hh \ inc_diacritic_folding.hh \
mainwindow.hh \ mainwindow.hh \
@ -390,6 +391,7 @@ FORMS += groups.ui \
SOURCES += folding.cc \ SOURCES += folding.cc \
gico_schemahandler.cpp \ gico_schemahandler.cpp \
globalbroadcaster.cpp \
main.cc \ main.cc \
dictionary.cc \ dictionary.cc \
config.cc \ config.cc \

View file

@ -263,8 +263,7 @@ int main( int argc, char ** argv )
#endif #endif
QStringList localSchemes={"gdlookup","gdau","gico","qrcx","bres","bword","gdprg","gdvideo","gdpicture","gdtts"};
QStringList localSchemes={"gdlookup","gdau","gico","qrcx","bres","bword"};
for (int i = 0; i < localSchemes.size(); ++i) for (int i = 0; i < localSchemes.size(); ++i)
{ {
@ -272,11 +271,11 @@ int main( int argc, char ** argv )
QWebEngineUrlScheme webUiScheme(localScheme.toLatin1()); QWebEngineUrlScheme webUiScheme(localScheme.toLatin1());
webUiScheme.setFlags(QWebEngineUrlScheme::SecureScheme | webUiScheme.setFlags(QWebEngineUrlScheme::SecureScheme |
QWebEngineUrlScheme::LocalScheme | QWebEngineUrlScheme::LocalScheme |
QWebEngineUrlScheme::LocalAccessAllowed); QWebEngineUrlScheme::LocalAccessAllowed|
QWebEngineUrlScheme::CorsEnabled);
QWebEngineUrlScheme::registerScheme(webUiScheme); QWebEngineUrlScheme::registerScheme(webUiScheme);
} }
QHotkeyApplication app( "GoldenDict", argc, argv ); QHotkeyApplication app( "GoldenDict", argc, argv );
LogFilePtrGuard logFilePtrGuard; LogFilePtrGuard logFilePtrGuard;

View file

@ -150,7 +150,7 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("gdlookup", handler); QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("gdlookup", handler);
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("bword", handler); QWebEngineProfile::defaultProfile()->installUrlSchemeHandler("bword", handler);
QStringList localSchemes={"gdau","gico","qrcx","bres"}; QStringList localSchemes={"gdau","gico","qrcx","bres","gdprg","gdvideo","gdpicture","gdtts"};
GicoSchemeHandler *h=new GicoSchemeHandler(articleNetMgr); GicoSchemeHandler *h=new GicoSchemeHandler(articleNetMgr);
for(int i=0;i<localSchemes.size();i++){ for(int i=0;i<localSchemes.size();i++){
QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(localSchemes.at(i).toLatin1(), h); QWebEngineProfile::defaultProfile()->installUrlSchemeHandler(localSchemes.at(i).toLatin1(), h);
@ -1219,12 +1219,21 @@ void MainWindow::closeEvent( QCloseEvent * ev )
{ {
if ( cfg.preferences.enableTrayIcon && cfg.preferences.closeToTray ) if ( cfg.preferences.enableTrayIcon && cfg.preferences.closeToTray )
{ {
ev->ignore();
if( !cfg.preferences.searchInDock ) if( !cfg.preferences.searchInDock )
translateBox->setPopupEnabled( false ); translateBox->setPopupEnabled( false );
#ifdef HAVE_X11
// Don't ignore the close event, because doing so cancels session logout if
// the main window is visible when the user attempts to log out.
// The main window will be only hidden, because QApplication::quitOnLastWindowClosed
// property is false and Qt::WA_DeleteOnClose widget attribute is not set.
Q_ASSERT(!QApplication::quitOnLastWindowClosed());
Q_ASSERT(!testAttribute(Qt::WA_DeleteOnClose));
#else
// Ignore the close event because closing the main window breaks global hotkeys on Windows.
ev->ignore();
hide(); hide();
#endif
} }
else else
{ {
@ -1293,11 +1302,12 @@ void MainWindow::applyProxySettings()
void MainWindow::applyWebSettings() void MainWindow::applyWebSettings()
{ {
QWebEngineSettings *defaultSettings = QWebEngineSettings::globalSettings(); QWebEngineSettings *defaultSettings = QWebEngineSettings::defaultSettings();
defaultSettings->setAttribute(QWebEngineSettings::PluginsEnabled, cfg.preferences.enableWebPlugins); defaultSettings->setAttribute(QWebEngineSettings::PluginsEnabled, cfg.preferences.enableWebPlugins);
defaultSettings->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, false); defaultSettings->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, false);
defaultSettings->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true ); defaultSettings->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessRemoteUrls, true );
defaultSettings->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessFileUrls, true ); defaultSettings->setAttribute( QWebEngineSettings::WebAttribute::LocalContentCanAccessFileUrls, true );
defaultSettings->setAttribute( QWebEngineSettings::WebAttribute::ErrorPageEnabled, false);
} }
void MainWindow::setupNetworkCache( int maxSize ) void MainWindow::setupNetworkCache( int maxSize )
@ -1672,7 +1682,12 @@ ArticleView * MainWindow::createNewTab( bool switchToIt,
connect( view, SIGNAL( zoomIn()), this, SLOT( zoomin() ) ); connect( view, SIGNAL( zoomIn()), this, SLOT( zoomin() ) );
connect( view, SIGNAL( zoomOut()), this, SLOT( zoomout() ) ); connect( view, SIGNAL( zoomOut()), this, SLOT( zoomout() ) );
connect (wuri,SIGNAL(linkClicked(QUrl)),view,SLOT(linkClicked(QUrl))); connect(wuri, &WebUrlRequestInterceptor::linkClicked, view, [=](QUrl url) {
ArticleView *active = getCurrentArticleView();
if (active == view) {
view->linkClicked(url);
}
});
view->setSelectionBySingleClick( cfg.preferences.selectWordBySingleClick ); view->setSelectionBySingleClick( cfg.preferences.selectWordBySingleClick );
@ -2619,7 +2634,8 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
if ( keyEvent->key() == Qt::Key_Space || if ( keyEvent->key() == Qt::Key_Space ||
keyEvent->key() == Qt::Key_Backspace || keyEvent->key() == Qt::Key_Backspace ||
keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Tab ||
keyEvent->key() == Qt::Key_Backtab ) keyEvent->key() == Qt::Key_Backtab ||
keyEvent->key() == Qt::Key_Escape)
return false; // Those key have other uses than to start typing return false; // Those key have other uses than to start typing
// or don't make sense // or don't make sense
@ -2648,7 +2664,8 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
if ( keyEvent->key() == Qt::Key_Space || if ( keyEvent->key() == Qt::Key_Space ||
keyEvent->key() == Qt::Key_Backspace || keyEvent->key() == Qt::Key_Backspace ||
keyEvent->key() == Qt::Key_Tab || keyEvent->key() == Qt::Key_Tab ||
keyEvent->key() == Qt::Key_Backtab ) keyEvent->key() == Qt::Key_Backtab ||
keyEvent->key() == Qt::Key_Escape)
return false; // Those key have other uses than to start typing return false; // Those key have other uses than to start typing
// or don't make sense // or don't make sense

View file

@ -353,7 +353,7 @@ void ProgramWordSearchRequest::instanceFinished( QByteArray output, QString erro
// Handle any Windows artifacts // Handle any Windows artifacts
output.replace( "\r\n", "\n" ); output.replace( "\r\n", "\n" );
QStringList result = QStringList result =
QString::fromUtf8( output ).split( "\n", QString::SkipEmptyParts ); QString::fromUtf8( output ).split( "\n", Qt::SkipEmptyParts );
for( int x = 0; x < result.size(); ++x ) for( int x = 0; x < result.size(); ++x )
matches.push_back( Dictionary::WordMatch( gd::toWString( result[ x ] ) ) ); matches.push_back( Dictionary::WordMatch( gd::toWString( result[ x ] ) ) );

View file

@ -85,5 +85,6 @@
<file>icons/folder.png</file> <file>icons/folder.png</file>
<file>icons/ontop.png</file> <file>icons/ontop.png</file>
<file>resources/jquery-3.6.0.slim.min.js</file> <file>resources/jquery-3.6.0.slim.min.js</file>
<file>resources/gd_custom.js</file>
</qresource> </qresource>
</RCC> </RCC>

27
resources/gd_custom.js Normal file
View file

@ -0,0 +1,27 @@
//document ready ,
$(function() {
$("a").click(function(event) {
var link = $(this).attr("href");
if(link.indexOf(":")>=0){
return;
}
var newLink;
if (link.startsWith("#")) {
newLink = window.location.href + link;
} else {
var href = window.location.href;
var index = href.indexOf("?");
newLink = href.substring(0, index) + "?word=" + link;
}
$(this).attr("href", newLink);
});
}
);
function playSound(sound) {
var a = new Audio(sound);
a.play();
}

View file

@ -635,7 +635,7 @@ void StardictDictionary::pangoToHtml( QString & text )
{ {
// Parse font description // Parse font description
QStringList list = styleRegex.cap( 2 ).split( " ", QString::SkipEmptyParts ); QStringList list = styleRegex.cap( 2 ).split( " ", Qt::SkipEmptyParts );
int n; int n;
QString sizeStr, stylesStr, familiesStr; QString sizeStr, stylesStr, familiesStr;
for( n = list.size() - 1; n >= 0; n-- ) for( n = list.size() - 1; n >= 0; n-- )

View file

@ -26,6 +26,13 @@ inline QString rstrip(const QString& str) {
return ""; return "";
} }
inline bool isExternalLink( QUrl const & url )
{
return url.scheme() == "http" || url.scheme() == "https" ||
url.scheme() == "ftp" || url.scheme() == "mailto" ||
url.scheme() == "file";
}
inline QString escape( QString const & plain ) inline QString escape( QString const & plain )
{ {
return plain.toHtmlEscaped(); return plain.toHtmlEscaped();

View file

@ -1,13 +1,16 @@
#include "weburlrequestinterceptor.h" #include "weburlrequestinterceptor.h"
#include <QDebug> #include <QDebug>
#include "utils.hh"
WebUrlRequestInterceptor::WebUrlRequestInterceptor(QObject *p) WebUrlRequestInterceptor::WebUrlRequestInterceptor(QObject *p)
:QWebEngineUrlRequestInterceptor(p) :QWebEngineUrlRequestInterceptor(p)
{ {
} }
void WebUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) { void WebUrlRequestInterceptor::interceptRequest( QWebEngineUrlRequestInfo &info) {
if(QWebEngineUrlRequestInfo::NavigationTypeLink==info.navigationType ()&&info.resourceType ()==QWebEngineUrlRequestInfo::ResourceTypeMainFrame) if (QWebEngineUrlRequestInfo::NavigationTypeLink == info.navigationType() && info.resourceType() == QWebEngineUrlRequestInfo::ResourceTypeMainFrame) {
emit linkClicked(info.requestUrl ()); emit linkClicked(info.requestUrl());
info.block(true);
}
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

15
zim.cc
View file

@ -1188,7 +1188,7 @@ public:
~ZimArticleRequest() ~ZimArticleRequest()
{ {
isCancelled.ref(); isCancelled.ref();
hasExited.acquire(); //hasExited.acquire();
} }
}; };
@ -1353,7 +1353,7 @@ public:
~ZimResourceRequestRunnable() ~ZimResourceRequestRunnable()
{ {
hasExited.release(); //hasExited.release();
} }
virtual void run(); virtual void run();
@ -1371,12 +1371,9 @@ class ZimResourceRequest: public Dictionary::DataRequest
QSemaphore hasExited; QSemaphore hasExited;
public: public:
ZimResourceRequest(ZimDictionary &dict_, string const &resourceName_)
ZimResourceRequest( ZimDictionary & dict_, : dict(dict_), resourceName(resourceName_) {
string const & resourceName_ ): //(new ZimResourceRequestRunnable(*this, hasExited))->run();
dict( dict_ ),
resourceName( resourceName_ )
{
QThreadPool::globalInstance()->start( QThreadPool::globalInstance()->start(
new ZimResourceRequestRunnable( *this, hasExited ) ); new ZimResourceRequestRunnable( *this, hasExited ) );
} }
@ -1391,7 +1388,7 @@ public:
~ZimResourceRequest() ~ZimResourceRequest()
{ {
isCancelled.ref(); isCancelled.ref();
hasExited.acquire(); //hasExited.acquire();
} }
}; };