mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-12-17 23:04:06 +00:00
Compare commits
20 commits
ae69d14b3b
...
18ff0458b5
Author | SHA1 | Date | |
---|---|---|---|
18ff0458b5 | |||
dcc4579544 | |||
d3ad40f988 | |||
081cba6b23 | |||
59f9b3d04f | |||
f6434f4219 | |||
f694c3210e | |||
c0697ecdda | |||
701a4effb3 | |||
f9a3705942 | |||
2c91b78e13 | |||
c6387df392 | |||
43c982cf8a | |||
e07e730a09 | |||
ab214cfb05 | |||
c00239a1b1 | |||
469896bbf1 | |||
0d89c4ab56 | |||
9e99389cc3 | |||
6edfd15962 |
|
@ -529,6 +529,22 @@ 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()
|
||||
-> websiteDictionary( QString::fromStdString( activeDict->getName() ), requestUrl );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > r = activeDict->getArticle(
|
||||
wordStd,
|
||||
altsVector,
|
||||
|
|
|
@ -45,4 +45,6 @@ signals:
|
|||
void dictionaryClear( ActiveDictIds ad );
|
||||
|
||||
void indexingDictionary( QString );
|
||||
|
||||
void websiteDictionary( QString, QString );
|
||||
};
|
||||
|
|
|
@ -111,7 +111,7 @@ HotKey::HotKey( QKeySequence const & seq ):
|
|||
|
||||
QKeySequence HotKey::toKeySequence() const
|
||||
{
|
||||
if ( key2 != 0 || key2 != Qt::Key::Key_unknown ) {
|
||||
if ( key2 != 0 && key2 != Qt::Key::Key_unknown ) {
|
||||
return { QKeyCombination( modifiers, static_cast< Qt::Key >( key1 ) ),
|
||||
QKeyCombination( modifiers, static_cast< Qt::Key >( key2 ) ) };
|
||||
}
|
||||
|
@ -1073,6 +1073,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();
|
||||
}
|
||||
|
@ -2102,6 +2106,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 );
|
||||
|
|
|
@ -392,6 +392,7 @@ struct Preferences
|
|||
int maxNetworkCacheSize;
|
||||
bool clearNetworkCacheOnExit;
|
||||
bool removeInvalidIndexOnExit = false;
|
||||
bool openWebsiteInNewTab = false;
|
||||
|
||||
qreal zoomFactor;
|
||||
qreal helpZoomFactor;
|
||||
|
|
|
@ -34,7 +34,8 @@ enum Property {
|
|||
Author,
|
||||
Copyright,
|
||||
Description,
|
||||
Email
|
||||
Email,
|
||||
Url,
|
||||
};
|
||||
|
||||
DEF_EX( Ex, "Dictionary error", std::exception )
|
||||
|
|
|
@ -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,14 +330,12 @@ 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( "<div><span>this website dictionary is opened in the new tab</span></div>" );
|
||||
}
|
||||
else {
|
||||
encodeUrl = urlString;
|
||||
}
|
||||
|
||||
fmt::format_to( std::back_inserter( result ),
|
||||
R"(<iframe id="gdexpandframe-{}" src="{}"
|
||||
onmouseover="processIframeMouseOver('gdexpandframe-{}');"
|
||||
|
@ -352,7 +345,7 @@ sandbox="allow-same-origin allow-scripts allow-popups"></iframe>)",
|
|||
getId(),
|
||||
encodeUrl.toStdString(),
|
||||
getId() );
|
||||
|
||||
}
|
||||
auto dr = std::make_shared< DataRequestInstant >( true );
|
||||
dr->appendString( result );
|
||||
return dr;
|
||||
|
|
|
@ -53,9 +53,8 @@ Group::Group( Config::Group const & cfgGroup,
|
|||
}
|
||||
}
|
||||
|
||||
Group::Group( QString name_ ):
|
||||
id( 0 ),
|
||||
name( std::move( name_ ) )
|
||||
Group::Group():
|
||||
id( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ struct Group
|
|||
Config::Group const & inactiveGroup );
|
||||
|
||||
/// Creates an empty group.
|
||||
explicit Group( QString name_ );
|
||||
explicit Group();
|
||||
|
||||
Group( unsigned id, QString name_ );
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ SpeechClient::Engines SpeechClient::availableEngines()
|
|||
for ( const QVoice & voice : sp->availableVoices() ) {
|
||||
const QString name( QString( "%4 - %3 %1 (%2)" )
|
||||
.arg( QLocale::languageToString( locale.language() ),
|
||||
( QLocale::countryToString( locale.country() ) ),
|
||||
( QLocale::territoryToString( locale.territory() ) ),
|
||||
voice.name(),
|
||||
engine_name ) );
|
||||
Engine engine( Config::VoiceEngine( engine_name, name, voice.name(), QLocale( locale ), 50, 0 ) );
|
||||
|
|
|
@ -85,7 +85,154 @@ QString ArticleView::scrollToFromDictionaryId( QString const & dictionaryId )
|
|||
Q_ASSERT( !isScrollTo( dictionaryId ) );
|
||||
return scrollToPrefix + dictionaryId;
|
||||
}
|
||||
ArticleView::ArticleView( QWidget * parent,
|
||||
ArticleNetworkAccessManager & nm,
|
||||
AudioPlayerPtr const & audioPlayer_,
|
||||
Config::Class const & cfg_ ):
|
||||
QWidget( parent ),
|
||||
articleNetMgr( nm ),
|
||||
audioPlayer( audioPlayer_ ),
|
||||
cfg( cfg_ )
|
||||
{
|
||||
// setup GUI
|
||||
setupWebview();
|
||||
}
|
||||
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->addWidget( this->tabWidget );
|
||||
|
||||
QWidget * 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
|
||||
}
|
||||
ArticleView::ArticleView( QWidget * parent,
|
||||
ArticleNetworkAccessManager & nm,
|
||||
AudioPlayerPtr const & audioPlayer_,
|
||||
|
@ -115,133 +262,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 );
|
||||
|
||||
|
@ -1235,6 +1260,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 +2198,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 ),
|
||||
|
|
|
@ -95,7 +95,10 @@ public:
|
|||
QLineEdit const * translateLine,
|
||||
QAction * dictionaryBarToggled = nullptr,
|
||||
unsigned currentGroupId = 0 );
|
||||
|
||||
explicit ArticleView( QWidget * parent,
|
||||
ArticleNetworkAccessManager & nm,
|
||||
AudioPlayerPtr const & audioPlayer_,
|
||||
Config::Class const & cfg_ );
|
||||
|
||||
void setCurrentGroupId( unsigned currengGrgId );
|
||||
unsigned getCurrentGroupId();
|
||||
|
@ -108,7 +111,7 @@ public:
|
|||
|
||||
~ArticleView();
|
||||
|
||||
|
||||
void load( QString url );
|
||||
/// Returns "gdfrom-" + dictionaryId.
|
||||
static QString scrollToFromDictionaryId( QString const & dictionaryId );
|
||||
|
||||
|
@ -167,9 +170,12 @@ public:
|
|||
/// \brief Set background as black if darkreader mode is enabled.
|
||||
void syncBackgroundColorWithCfgDarkReader() const;
|
||||
|
||||
void openWebsiteInNewTab( QString name, QString url );
|
||||
|
||||
private:
|
||||
// widgets
|
||||
ArticleWebView * webview;
|
||||
QTabWidget * tabWidget;
|
||||
SearchPanel * searchPanel;
|
||||
FtsSearchPanel * ftsSearchPanel;
|
||||
|
||||
|
@ -411,6 +417,7 @@ private:
|
|||
QString getMutedForGroup( unsigned group );
|
||||
|
||||
QStringList getMutedDictionaries( unsigned group );
|
||||
void setupWebview();
|
||||
};
|
||||
|
||||
class ResourceToSaveHandler: public QObject
|
||||
|
|
|
@ -200,7 +200,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
|
|||
#ifndef NO_TTS_SUPPORT
|
||||
cfg.voiceEngines = sources.getVoiceEngines();
|
||||
#endif
|
||||
ui.tabs->setUpdatesEnabled( false );
|
||||
setUpdatesEnabled( false );
|
||||
// Those hold pointers to dictionaries, we need to free them.
|
||||
groupInstances.clear();
|
||||
|
||||
|
@ -225,7 +225,7 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
|
|||
connect( groups, &Groups::showDictionaryInfo, this, &EditDictionaries::showDictionaryInfo );
|
||||
connect( orderAndProps, &OrderAndProps::showDictionaryHeadwords, this, &EditDictionaries::showDictionaryHeadwords );
|
||||
}
|
||||
ui.tabs->setUpdatesEnabled( true );
|
||||
setUpdatesEnabled( true );
|
||||
}
|
||||
EditDictionaries::~EditDictionaries()
|
||||
{
|
||||
|
|
|
@ -122,7 +122,7 @@ void DictGroupWidget::groupIconActivated( int index )
|
|||
|
||||
Config::Group DictGroupWidget::makeGroup() const
|
||||
{
|
||||
Instances::Group g( "" );
|
||||
Instances::Group g;
|
||||
|
||||
g.id = groupId;
|
||||
|
||||
|
|
|
@ -716,6 +716,10 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
&GlobalBroadcaster::indexingDictionary,
|
||||
this,
|
||||
&MainWindow::showFTSIndexingName );
|
||||
connect( GlobalBroadcaster::instance(),
|
||||
&GlobalBroadcaster::websiteDictionary,
|
||||
this,
|
||||
&MainWindow::openWebsiteInNewTab );
|
||||
|
||||
connect( &GlobalBroadcaster::instance()->pronounce_engine,
|
||||
&PronounceEngine::emitAudio,
|
||||
|
@ -2172,7 +2176,7 @@ void MainWindow::updateBackForwardButtons()
|
|||
{
|
||||
ArticleView * view = getCurrentArticleView();
|
||||
|
||||
if ( view ) {
|
||||
if ( view != nullptr ) {
|
||||
navBack->setEnabled( view->canGoBack() );
|
||||
navForward->setEnabled( view->canGoForward() );
|
||||
}
|
||||
|
@ -2181,7 +2185,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 );
|
||||
} );
|
||||
}
|
||||
|
@ -3718,7 +3727,13 @@ 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 );
|
||||
if ( pView != nullptr ) {
|
||||
if ( pView->getParentView() != nullptr ) {
|
||||
return pView->getParentView();
|
||||
}
|
||||
}
|
||||
return pView;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -4374,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( name, url );
|
||||
}
|
||||
|
||||
QString MainWindow::unescapeTabHeader( QString const & header )
|
||||
{
|
||||
// Reset table header to original headword
|
||||
|
|
|
@ -292,6 +292,7 @@ private slots:
|
|||
void openDictionaryFolder( QString const & id );
|
||||
|
||||
void showFTSIndexingName( QString const & name );
|
||||
void openWebsiteInNewTab( QString name, QString url );
|
||||
|
||||
void handleAddToFavoritesButton();
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ OrderAndProps::OrderAndProps( QWidget * parent,
|
|||
|
||||
Config::Group OrderAndProps::getCurrentDictionaryOrder() const
|
||||
{
|
||||
Instances::Group g( "" );
|
||||
Instances::Group g;
|
||||
|
||||
g.dictionaries = ui.dictionaryOrder->getCurrentDictionaries();
|
||||
|
||||
|
@ -144,7 +144,7 @@ Config::Group OrderAndProps::getCurrentDictionaryOrder() const
|
|||
|
||||
Config::Group OrderAndProps::getCurrentInactiveDictionaries() const
|
||||
{
|
||||
Instances::Group g( "" );
|
||||
Instances::Group g;
|
||||
|
||||
g.dictionaries = ui.inactiveDictionaries->getCurrentDictionaries();
|
||||
|
||||
|
|
|
@ -361,6 +361,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 );
|
||||
|
@ -520,6 +521,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();
|
||||
|
||||
|
|
|
@ -1938,6 +1938,13 @@ from Stardict, Babylon and GLS dictionaries</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="openWebsiteInNewTab">
|
||||
<property name="text">
|
||||
<string>Open website dictionary in seperate tab</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
Loading…
Reference in a new issue