diff --git a/src/article_maker.cc b/src/article_maker.cc index 7a0d2f40..59d19285 100644 --- a/src/article_maker.cc +++ b/src/article_maker.cc @@ -529,6 +529,26 @@ void ArticleRequest::altSearchFinished() for ( const auto & activeDict : activeDicts ) { try { + // if the dictionary is website dictionary and openinNewTab is enabled, emit a signal. + if ( GlobalBroadcaster::instance()->getPreference()->openWebsiteInNewTab ) { + if ( ( activeDict->getFeatures() | Dictionary::WebSite ) == Dictionary::WebSite ) { + //replace the word,and get the actual requested url + string url = activeDict->getProperties()[ Dictionary::Property::Url ]; + if ( url.empty() ) { + continue; + } + + QString requestUrl = Utils::WebSite::urlReplaceWord( QString::fromStdString( url ), word ); + emit GlobalBroadcaster::instance() + -> websiteDictionarySignal( QString::fromStdString( activeDict->getName() ), requestUrl ); + QStringList dictIds; + dictIds << QString::fromStdString( activeDict->getId() ); + ActiveDictIds hittedWord{ group.id, word, dictIds }; + emit GlobalBroadcaster::instance() -> dictionaryChanges( hittedWord ); + continue; + } + } + sptr< Dictionary::DataRequest > r = activeDict->getArticle( wordStd, altsVector, diff --git a/src/common/globalbroadcaster.hh b/src/common/globalbroadcaster.hh index c1d985d0..dc95141a 100644 --- a/src/common/globalbroadcaster.hh +++ b/src/common/globalbroadcaster.hh @@ -45,4 +45,6 @@ signals: void dictionaryClear( ActiveDictIds ad ); void indexingDictionary( QString ); + + void websiteDictionarySignal( QString, QString ); }; diff --git a/src/config.cc b/src/config.cc index 117ebc2e..e8cc2c47 100644 --- a/src/config.cc +++ b/src/config.cc @@ -1071,6 +1071,10 @@ Class load() ( preferences.namedItem( "removeInvalidIndexOnExit" ).toElement().text() == "1" ); } + if ( !preferences.namedItem( "openWebsiteInNewTab" ).isNull() ) { + c.preferences.openWebsiteInNewTab = ( preferences.namedItem( "openWebsiteInNewTab" ).toElement().text() == "1" ); + } + if ( !preferences.namedItem( "maxStringsInHistory" ).isNull() ) { c.preferences.maxStringsInHistory = preferences.namedItem( "maxStringsInHistory" ).toElement().text().toUInt(); } @@ -2100,6 +2104,10 @@ void save( Class const & c ) opt.appendChild( dd.createTextNode( c.preferences.removeInvalidIndexOnExit ? "1" : "0" ) ); preferences.appendChild( opt ); + opt = dd.createElement( "openWebsiteInNewTab" ); + opt.appendChild( dd.createTextNode( c.preferences.openWebsiteInNewTab ? "1" : "0" ) ); + preferences.appendChild( opt ); + opt = dd.createElement( "maxStringsInHistory" ); opt.appendChild( dd.createTextNode( QString::number( c.preferences.maxStringsInHistory ) ) ); preferences.appendChild( opt ); diff --git a/src/config.hh b/src/config.hh index 20589e05..8c7ddb73 100644 --- a/src/config.hh +++ b/src/config.hh @@ -400,6 +400,7 @@ struct Preferences int maxNetworkCacheSize; bool clearNetworkCacheOnExit; bool removeInvalidIndexOnExit = false; + bool openWebsiteInNewTab = false; qreal zoomFactor; qreal helpZoomFactor; diff --git a/src/dict/dictionary.hh b/src/dict/dictionary.hh index 0d194838..9ee8203d 100644 --- a/src/dict/dictionary.hh +++ b/src/dict/dictionary.hh @@ -34,7 +34,8 @@ enum Property { Author, Copyright, Description, - Email + Email, + Url, }; DEF_EX( Ex, "Dictionary error", std::exception ) diff --git a/src/dict/website.cc b/src/dict/website.cc index ca03d6b4..df8d0c37 100644 --- a/src/dict/website.cc +++ b/src/dict/website.cc @@ -24,7 +24,6 @@ class WebSiteDictionary: public Dictionary::Class { string name; QByteArray urlTemplate; - bool experimentalIframe; QString iconFilename; bool inside_iframe; QNetworkAccessManager & netMgr; @@ -41,14 +40,8 @@ public: name( name_ ), iconFilename( iconFilename_ ), inside_iframe( inside_iframe_ ), - netMgr( netMgr_ ), - experimentalIframe( false ) + netMgr( netMgr_ ) { - if ( urlTemplate_.startsWith( "http://" ) || urlTemplate_.startsWith( "https://" ) ) { - experimentalIframe = true; - } - //else file:/// local dictionary file path - urlTemplate = QUrl( urlTemplate_ ).toEncoded(); dictionaryDescription = urlTemplate_; } @@ -60,7 +53,9 @@ public: map< Property, string > getProperties() noexcept override { - return map< Property, string >(); + map< Property, string > properties; + properties.insert( { Property::Url, urlTemplate.toStdString() } ); + return properties; } unsigned long getArticleCount() noexcept override @@ -321,7 +316,7 @@ void WebSiteArticleRequest::requestFinished( QNetworkReply * r ) sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str, vector< wstring > const & /*alts*/, - wstring const & context, + wstring const & /*context*/, bool /*ignoreDiacritics*/ ) { QString urlString = Utils::WebSite::urlReplaceWord( QString( urlTemplate ), QString::fromStdU32String( str ) ); @@ -335,24 +330,22 @@ sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str, QUrl url( urlString ); GlobalBroadcaster::instance()->addWhitelist( url.host() ); - QString encodeUrl; - if ( experimentalIframe ) { - encodeUrl = "ifr://localhost?url=" + QUrl::toPercentEncoding( urlString ); + const QString & encodeUrl = urlString; + + if ( GlobalBroadcaster::instance()->getPreference()->openWebsiteInNewTab ) { + result += string( "
this website dictionary is opened in the new tab
" ); } else { - encodeUrl = urlString; - } - - fmt::format_to( std::back_inserter( result ), - R"()", - getId(), - encodeUrl.toStdString(), - getId() ); - + getId(), + encodeUrl.toStdString(), + getId() ); + } auto dr = std::make_shared< DataRequestInstant >( true ); dr->appendString( result ); return dr; diff --git a/src/ui/articleview.cc b/src/ui/articleview.cc index 1d68fb13..d2a070ba 100644 --- a/src/ui/articleview.cc +++ b/src/ui/articleview.cc @@ -85,6 +85,162 @@ QString ArticleView::scrollToFromDictionaryId( QString const & dictionaryId ) Q_ASSERT( !isScrollTo( dictionaryId ) ); return scrollToPrefix + dictionaryId; } +void ArticleView::setupWebview() +{ // setup GUI + this->webview = new ArticleWebView( this ); + this->ftsSearchPanel = new FtsSearchPanel( this ); + this->searchPanel = new SearchPanel( this ); + this->searchPanel->hide(); + this->ftsSearchPanel->hide(); + + auto * baseLayout = new QVBoxLayout( this ); + + this->tabWidget = new QTabWidget( this ); + baseLayout->setContentsMargins( 0, 0, 0, 0 ); + baseLayout->addWidget( this->tabWidget ); + + auto * tab1 = new QWidget( tabWidget ); + // Layout + auto * mainLayout = new QVBoxLayout( tab1 ); + mainLayout->addWidget( this->webview ); + mainLayout->addWidget( this->ftsSearchPanel ); + mainLayout->addWidget( this->searchPanel ); + + this->webview->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); + this->ftsSearchPanel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); + this->searchPanel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); + + mainLayout->setContentsMargins( 0, 0, 0, 0 ); + + this->tabWidget->addTab( tab1, "Dictionaries" ); + this->tabWidget->setTabBarAutoHide( true ); + + // end UI setup + + connect( this->searchPanel->previous, &QPushButton::clicked, this, &ArticleView::on_searchPrevious_clicked ); + connect( this->searchPanel->next, &QPushButton::clicked, this, &ArticleView::on_searchNext_clicked ); + connect( this->searchPanel->close, &QPushButton::clicked, this, &ArticleView::on_searchCloseButton_clicked ); + connect( this->searchPanel->caseSensitive, &QCheckBox::toggled, this, &ArticleView::on_searchCaseSensitive_clicked ); + connect( this->searchPanel->lineEdit, &QLineEdit::textEdited, this, &ArticleView::on_searchText_textEdited ); + connect( this->searchPanel->lineEdit, &QLineEdit::returnPressed, this, &ArticleView::on_searchText_returnPressed ); + connect( this->ftsSearchPanel->next, &QPushButton::clicked, this, &ArticleView::on_ftsSearchNext_clicked ); + connect( this->ftsSearchPanel->previous, &QPushButton::clicked, this, &ArticleView::on_ftsSearchPrevious_clicked ); + + // + + this->webview->setUp( const_cast< Config::Class * >( &this->cfg ) ); + + this->syncBackgroundColorWithCfgDarkReader(); + + this->goBackAction.setShortcut( QKeySequence( "Alt+Left" ) ); + this->webview->addAction( &this->goBackAction ); + connect( &this->goBackAction, &QAction::triggered, this, &ArticleView::back ); + + this->goForwardAction.setShortcut( QKeySequence( "Alt+Right" ) ); + this->webview->addAction( &this->goForwardAction ); + connect( &this->goForwardAction, &QAction::triggered, this, &ArticleView::forward ); + + this->webview->pageAction( QWebEnginePage::Copy )->setShortcut( QKeySequence::Copy ); + this->webview->addAction( this->webview->pageAction( QWebEnginePage::Copy ) ); + + QAction * selectAll = this->webview->pageAction( QWebEnginePage::SelectAll ); + selectAll->setShortcut( QKeySequence::SelectAll ); + selectAll->setShortcutContext( Qt::WidgetWithChildrenShortcut ); + this->webview->addAction( selectAll ); + + this->webview->setContextMenuPolicy( Qt::CustomContextMenu ); + + connect( this->webview, &QWebEngineView::loadFinished, this, &ArticleView::loadFinished ); + + connect( this->webview, &ArticleWebView::linkClicked, this, &ArticleView::linkClicked ); + + connect( this->webview->page(), &QWebEnginePage::titleChanged, this, &ArticleView::handleTitleChanged ); + + connect( this->webview, &QWidget::customContextMenuRequested, this, &ArticleView::contextMenuRequested ); + + connect( this->webview->page(), &QWebEnginePage::linkHovered, this, &ArticleView::linkHovered ); + + connect( this->webview, &ArticleWebView::doubleClicked, this, &ArticleView::doubleClicked ); + + this->pasteAction.setShortcut( QKeySequence::Paste ); + this->webview->addAction( &this->pasteAction ); + connect( &this->pasteAction, &QAction::triggered, this, &ArticleView::pasteTriggered ); + + this->articleUpAction.setShortcut( QKeySequence( "Alt+Up" ) ); + this->webview->addAction( &this->articleUpAction ); + connect( &this->articleUpAction, &QAction::triggered, this, &ArticleView::moveOneArticleUp ); + + this->articleDownAction.setShortcut( QKeySequence( "Alt+Down" ) ); + this->webview->addAction( &this->articleDownAction ); + connect( &this->articleDownAction, &QAction::triggered, this, &ArticleView::moveOneArticleDown ); + + this->selectCurrentArticleAction.setShortcut( QKeySequence( "Ctrl+Shift+A" ) ); + this->selectCurrentArticleAction.setText( tr( "Select Current Article" ) ); + this->webview->addAction( &this->selectCurrentArticleAction ); + connect( &this->selectCurrentArticleAction, &QAction::triggered, this, &ArticleView::selectCurrentArticle ); + + this->copyAsTextAction.setShortcut( QKeySequence( "Ctrl+Shift+C" ) ); + this->copyAsTextAction.setText( tr( "Copy as text" ) ); + this->webview->addAction( &this->copyAsTextAction ); + connect( &this->copyAsTextAction, &QAction::triggered, this, &ArticleView::copyAsText ); + + this->inspectAction.setShortcut( QKeySequence( Qt::Key_F12 ) ); + this->inspectAction.setText( tr( "Inspect" ) ); + this->webview->addAction( &this->inspectAction ); + + + connect( &this->inspectAction, &QAction::triggered, this, &ArticleView::inspectElement ); + + this->webview->installEventFilter( this ); + this->searchPanel->installEventFilter( this ); + this->ftsSearchPanel->installEventFilter( this ); + + QWebEngineSettings * settings = this->webview->settings(); + settings->setUnknownUrlSchemePolicy( QWebEngineSettings::UnknownUrlSchemePolicy::DisallowUnknownUrlSchemes ); +#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) ) + settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::ErrorPageEnabled, false ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::LinksIncludedInFocusChain, false ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true ); + settings->defaultSettings()->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false ); +#else + settings->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true ); + settings->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true ); + settings->setAttribute( QWebEngineSettings::ErrorPageEnabled, false ); + settings->setAttribute( QWebEngineSettings::LinksIncludedInFocusChain, false ); + settings->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false ); + settings->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true ); + settings->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false ); +#endif + + + this->expandOptionalParts = this->cfg.preferences.alwaysExpandOptionalParts; +#ifndef Q_OS_MACOS + this->webview->grabGesture( Gestures::GDPinchGestureType ); + this->webview->grabGesture( Gestures::GDSwipeGestureType ); +#endif +} + +void ArticleView::addWebsiteTab( QString name, QString url ) +{ + auto * view = new QWebEngineView( this ); + view->load( url ); + view->setZoomFactor( this->cfg.preferences.zoomFactor ); + int index = tabWidget->count(); + QString escaped = Utils::escapeAmps( name ); + tabWidget->insertTab( index, view, escaped ); +} + +void ArticleView::clearWebsiteTabs() +{ + int index = tabWidget->count(); + // keep the first tab + while ( index-- > 1 ) { + tabWidget->removeTab( index ); + } +} ArticleView::ArticleView( QWidget * parent, ArticleNetworkAccessManager & nm, @@ -115,133 +271,11 @@ ArticleView::ArticleView( QWidget * parent, translateLine( translateLine_ ) { // setup GUI - webview = new ArticleWebView( this ); - ftsSearchPanel = new FtsSearchPanel( this ); - searchPanel = new SearchPanel( this ); - searchPanel->hide(); - ftsSearchPanel->hide(); - // Layout - auto * mainLayout = new QVBoxLayout( this ); - mainLayout->addWidget( webview ); - mainLayout->addWidget( ftsSearchPanel ); - mainLayout->addWidget( searchPanel ); + setupWebview(); - webview->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ); - ftsSearchPanel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); - searchPanel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ); - - mainLayout->setContentsMargins( 0, 0, 0, 0 ); - - // end UI setup - - connect( searchPanel->previous, &QPushButton::clicked, this, &ArticleView::on_searchPrevious_clicked ); - connect( searchPanel->next, &QPushButton::clicked, this, &ArticleView::on_searchNext_clicked ); - connect( searchPanel->close, &QPushButton::clicked, this, &ArticleView::on_searchCloseButton_clicked ); - connect( searchPanel->caseSensitive, &QCheckBox::toggled, this, &ArticleView::on_searchCaseSensitive_clicked ); - connect( searchPanel->lineEdit, &QLineEdit::textEdited, this, &ArticleView::on_searchText_textEdited ); - connect( searchPanel->lineEdit, &QLineEdit::returnPressed, this, &ArticleView::on_searchText_returnPressed ); - connect( ftsSearchPanel->next, &QPushButton::clicked, this, &ArticleView::on_ftsSearchNext_clicked ); - connect( ftsSearchPanel->previous, &QPushButton::clicked, this, &ArticleView::on_ftsSearchPrevious_clicked ); - - // - - webview->setUp( const_cast< Config::Class * >( &cfg ) ); - - syncBackgroundColorWithCfgDarkReader(); - - goBackAction.setShortcut( QKeySequence( "Alt+Left" ) ); - webview->addAction( &goBackAction ); - connect( &goBackAction, &QAction::triggered, this, &ArticleView::back ); - - goForwardAction.setShortcut( QKeySequence( "Alt+Right" ) ); - webview->addAction( &goForwardAction ); - connect( &goForwardAction, &QAction::triggered, this, &ArticleView::forward ); - - webview->pageAction( QWebEnginePage::Copy )->setShortcut( QKeySequence::Copy ); - webview->addAction( webview->pageAction( QWebEnginePage::Copy ) ); - - QAction * selectAll = webview->pageAction( QWebEnginePage::SelectAll ); - selectAll->setShortcut( QKeySequence::SelectAll ); - selectAll->setShortcutContext( Qt::WidgetWithChildrenShortcut ); - webview->addAction( selectAll ); - - webview->setContextMenuPolicy( Qt::CustomContextMenu ); - - connect( webview, &QWebEngineView::loadFinished, this, &ArticleView::loadFinished ); - - connect( webview, &ArticleWebView::linkClicked, this, &ArticleView::linkClicked ); - - connect( webview->page(), &QWebEnginePage::titleChanged, this, &ArticleView::handleTitleChanged ); - - connect( webview, &QWidget::customContextMenuRequested, this, &ArticleView::contextMenuRequested ); - - connect( webview->page(), &QWebEnginePage::linkHovered, this, &ArticleView::linkHovered ); - - connect( webview, &ArticleWebView::doubleClicked, this, &ArticleView::doubleClicked ); - - pasteAction.setShortcut( QKeySequence::Paste ); - webview->addAction( &pasteAction ); - connect( &pasteAction, &QAction::triggered, this, &ArticleView::pasteTriggered ); - - articleUpAction.setShortcut( QKeySequence( "Alt+Up" ) ); - webview->addAction( &articleUpAction ); - connect( &articleUpAction, &QAction::triggered, this, &ArticleView::moveOneArticleUp ); - - articleDownAction.setShortcut( QKeySequence( "Alt+Down" ) ); - webview->addAction( &articleDownAction ); - connect( &articleDownAction, &QAction::triggered, this, &ArticleView::moveOneArticleDown ); - - selectCurrentArticleAction.setShortcut( QKeySequence( "Ctrl+Shift+A" ) ); - selectCurrentArticleAction.setText( tr( "Select Current Article" ) ); - webview->addAction( &selectCurrentArticleAction ); - connect( &selectCurrentArticleAction, &QAction::triggered, this, &ArticleView::selectCurrentArticle ); - - copyAsTextAction.setShortcut( QKeySequence( "Ctrl+Shift+C" ) ); - copyAsTextAction.setText( tr( "Copy as text" ) ); - webview->addAction( ©AsTextAction ); - connect( ©AsTextAction, &QAction::triggered, this, &ArticleView::copyAsText ); - - inspectAction.setShortcut( QKeySequence( Qt::Key_F12 ) ); - inspectAction.setText( tr( "Inspect" ) ); - webview->addAction( &inspectAction ); - - - connect( &inspectAction, &QAction::triggered, this, &ArticleView::inspectElement ); - - webview->installEventFilter( this ); - searchPanel->installEventFilter( this ); - ftsSearchPanel->installEventFilter( this ); - - QWebEngineSettings * settings = webview->settings(); - settings->setUnknownUrlSchemePolicy( QWebEngineSettings::UnknownUrlSchemePolicy::DisallowUnknownUrlSchemes ); -#if ( QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) ) - settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::ErrorPageEnabled, false ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::LinksIncludedInFocusChain, false ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true ); - settings->defaultSettings()->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false ); -#else - settings->setAttribute( QWebEngineSettings::LocalContentCanAccessRemoteUrls, true ); - settings->setAttribute( QWebEngineSettings::LocalContentCanAccessFileUrls, true ); - settings->setAttribute( QWebEngineSettings::ErrorPageEnabled, false ); - settings->setAttribute( QWebEngineSettings::LinksIncludedInFocusChain, false ); - settings->setAttribute( QWebEngineSettings::PlaybackRequiresUserGesture, false ); - settings->setAttribute( QWebEngineSettings::JavascriptCanAccessClipboard, true ); - settings->setAttribute( QWebEngineSettings::PrintElementBackgrounds, false ); -#endif - - auto html = articleNetMgr.getHtml( ResourceType::UNTITLE ); - - webview->setHtml( QString::fromStdString( html ) ); - - expandOptionalParts = cfg.preferences.alwaysExpandOptionalParts; -#ifndef Q_OS_MACOS - webview->grabGesture( Gestures::GDPinchGestureType ); - webview->grabGesture( Gestures::GDSwipeGestureType ); -#endif + auto html = this->articleNetMgr.getHtml( ResourceType::UNTITLE ); + this->webview->setHtml( QString::fromStdString( html ) ); connect( GlobalBroadcaster::instance(), &GlobalBroadcaster::dictionaryChanges, this, &ArticleView::setActiveDictIds ); connect( GlobalBroadcaster::instance(), &GlobalBroadcaster::dictionaryClear, this, &ArticleView::dictionaryClear ); @@ -304,6 +338,7 @@ void ArticleView::showDefinition( QString const & word, Contexts const & contexts_ ) { GlobalBroadcaster::instance()->pronounce_engine.reset(); + clearWebsiteTabs(); currentWord = word.trimmed(); if ( currentWord.isEmpty() ) { return; @@ -351,7 +386,7 @@ void ArticleView::showDefinition( QString const & word, QString mutedDicts = getMutedForGroup( group ); - if ( mutedDicts.size() ) { + if ( !mutedDicts.isEmpty() ) { Utils::Url::addQueryItem( req, "muted", mutedDicts ); } @@ -1235,6 +1270,17 @@ void ArticleView::syncBackgroundColorWithCfgDarkReader() const #endif } +void ArticleView::openWebsiteInNewTab( QString name, QString url ) +{ + QString escaped = Utils::escapeAmps( name ); + + //found existed QWebEngineView. + auto * view = new QWebEngineView( this ); + view->load( QUrl( url ) ); + + tabWidget->addTab( view, escaped ); +} + void ArticleView::back() { @@ -2162,6 +2208,11 @@ void ArticleView::clearContent() webview->setHtml( QString::fromStdString( html ) ); } +void ArticleView::load( QString url ) +{ + webview->load( QUrl( url ) ); +} + ResourceToSaveHandler::ResourceToSaveHandler( ArticleView * view, QString fileName ): QObject( view ), diff --git a/src/ui/articleview.hh b/src/ui/articleview.hh index 144d6d43..57534bd8 100644 --- a/src/ui/articleview.hh +++ b/src/ui/articleview.hh @@ -96,7 +96,7 @@ public: QAction * dictionaryBarToggled = nullptr, unsigned currentGroupId = 0 ); - + void openWebsiteInNewTab( QString name, QString url ); void setCurrentGroupId( unsigned currengGrgId ); unsigned getCurrentGroupId(); @@ -108,7 +108,7 @@ public: ~ArticleView(); - + void load( QString url ); /// Returns "gdfrom-" + dictionaryId. static QString scrollToFromDictionaryId( QString const & dictionaryId ); @@ -167,9 +167,14 @@ public: /// \brief Set background as black if darkreader mode is enabled. void syncBackgroundColorWithCfgDarkReader() const; + void addWebsiteTab( QString name, QString url ); + + void clearWebsiteTabs(); + private: // widgets ArticleWebView * webview; + QTabWidget * tabWidget; SearchPanel * searchPanel; FtsSearchPanel * ftsSearchPanel; @@ -411,6 +416,7 @@ private: QString getMutedForGroup( unsigned group ); QStringList getMutedDictionaries( unsigned group ); + void setupWebview(); }; class ResourceToSaveHandler: public QObject diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index b7a2ab04..45e324fd 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -66,6 +66,7 @@ #include #include #include +#include #ifdef HAVE_X11 #if ( QT_VERSION >= QT_VERSION_CHECK( 6, 0, 0 ) ) @@ -719,6 +720,10 @@ MainWindow::MainWindow( Config::Class & cfg_ ): &GlobalBroadcaster::indexingDictionary, this, &MainWindow::showFTSIndexingName ); + connect( GlobalBroadcaster::instance(), + &GlobalBroadcaster::websiteDictionarySignal, + this, + &MainWindow::openWebsiteInNewTab ); connect( &GlobalBroadcaster::instance()->pronounce_engine, &PronounceEngine::emitAudio, @@ -2156,7 +2161,7 @@ void MainWindow::updateFoundInDictsList() if ( dictionaries[ x ]->getId() == i->toUtf8().data() ) { QString dictName = QString::fromUtf8( dictionaries[ x ]->getName().c_str() ); QString dictId = QString::fromUtf8( dictionaries[ x ]->getId().c_str() ); - QListWidgetItem * item = + auto * item = new QListWidgetItem( dictionaries[ x ]->getIcon(), dictName, ui.dictsList, QListWidgetItem::Type ); item->setData( Qt::UserRole, QVariant( dictId ) ); item->setToolTip( dictName ); @@ -2170,7 +2175,7 @@ void MainWindow::updateFoundInDictsList() } } - //if no item in dict List panel has been choose ,select first one. + //if no item in dict List panel has been choosen ,select first one. if ( ui.dictsList->count() > 0 && ui.dictsList->selectedItems().empty() ) { ui.dictsList->setCurrentRow( 0 ); } @@ -2181,7 +2186,7 @@ void MainWindow::updateBackForwardButtons() { ArticleView * view = getCurrentArticleView(); - if ( view ) { + if ( view != nullptr ) { navBack->setEnabled( view->canGoBack() ); navForward->setEnabled( view->canGoForward() ); } @@ -2190,7 +2195,12 @@ void MainWindow::updateBackForwardButtons() void MainWindow::updatePronounceAvailability() { if ( ui.tabWidget->count() > 0 ) { - getCurrentArticleView()->hasSound( [ this ]( bool has ) { + ArticleView * pView = getCurrentArticleView(); + if ( pView == nullptr ) { + return; + } + + pView->hasSound( [ this ]( bool has ) { navPronounce->setEnabled( has ); } ); } @@ -3723,7 +3733,8 @@ void MainWindow::messageFromAnotherInstanceReceived( QString const & message ) ArticleView * MainWindow::getCurrentArticleView() { if ( QWidget * cw = ui.tabWidget->currentWidget() ) { - return dynamic_cast< ArticleView * >( cw ); + auto * pView = dynamic_cast< ArticleView * >( cw ); + return pView; } return nullptr; } @@ -4378,6 +4389,19 @@ void MainWindow::showFTSIndexingName( QString const & name ) } } +void MainWindow::openWebsiteInNewTab( QString name, QString url ) +{ + // QString escaped = Utils::escapeAmps( name ); + + // auto * view = new ArticleView( this, articleNetMgr, audioPlayerFactory.player(), cfg ); + // view->load( url ); + // int index = cfg.preferences.newTabsOpenAfterCurrentOne ? ui.tabWidget->currentIndex() + 1 : ui.tabWidget->count(); + + // ui.tabWidget->insertTab( index, view, escaped ); + // mruList.append( dynamic_cast< QWidget * >( view ) ); + getCurrentArticleView()->addWebsiteTab( std::move( name ), url ); +} + QString MainWindow::unescapeTabHeader( QString const & header ) { // Reset table header to original headword diff --git a/src/ui/mainwindow.hh b/src/ui/mainwindow.hh index 7a082ceb..6f0748a6 100644 --- a/src/ui/mainwindow.hh +++ b/src/ui/mainwindow.hh @@ -290,6 +290,7 @@ private slots: void openDictionaryFolder( QString const & id ); void showFTSIndexingName( QString const & name ); + void openWebsiteInNewTab( QString name, QString url ); void handleAddToFavoritesButton(); diff --git a/src/ui/preferences.cc b/src/ui/preferences.cc index 9d4578be..dbea9d3a 100644 --- a/src/ui/preferences.cc +++ b/src/ui/preferences.cc @@ -366,6 +366,7 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): //Misc ui.removeInvalidIndexOnExit->setChecked( p.removeInvalidIndexOnExit ); + ui.openWebsiteInNewTab->setChecked( p.openWebsiteInNewTab ); // Add-on styles ui.addonStylesLabel->setVisible( ui.addonStyles->count() > 1 ); @@ -525,6 +526,7 @@ Config::Preferences Preferences::getPreferences() p.clearNetworkCacheOnExit = ui.clearNetworkCacheOnExit->isChecked(); p.removeInvalidIndexOnExit = ui.removeInvalidIndexOnExit->isChecked(); + p.openWebsiteInNewTab = ui.openWebsiteInNewTab->isChecked(); p.addonStyle = ui.addonStyles->getCurrentStyle(); diff --git a/src/ui/preferences.ui b/src/ui/preferences.ui index 6c2bba01..4e232865 100644 --- a/src/ui/preferences.ui +++ b/src/ui/preferences.ui @@ -1938,6 +1938,13 @@ from Stardict, Babylon and GLS dictionaries + + + + Open website dictionary in seperate tab + + +