mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
Add input phrase's punctuation suffix to alts
Preferences::sanitizeInputPhrase() transforms an input phrase by removing its whitespace/punctuation prefix and suffix. Translating a phrase from X11 primary selection or from clipboard, via mouse-over or from the command line results in such sanitization. This is useful when a punctuation mark or a space is selected accidentally alongside a word. This sanitization can be undesirable, however, when an abbreviated word is selected. For example: "etc.", "e.g.", "i.e.". This commit implements searching for the input word with the punctuation suffix preserved as an alternative form of the sanitized word to show articles for both. For example, when the word "etc." is translated from the clipboard, both "ETC" and "etc." articles are displayed. The punctuation suffix is preserved when the word is passed from the scan popup to the main window and when the translate line text is refreshed (e.g. when the current group is changed). The suffix is not stored in history and favorites (doing so would require file format changes and possibly substantial code changes, this can be implemented later if need be). Trim the input phrase once in ArticleNetworkAccessManager::getResource() instead of verbose trimming in multiple places in ArticleMaker::makeDefinitionFor(). Closes #1350.
This commit is contained in:
parent
57c4c33780
commit
60bc05218f
|
@ -256,7 +256,8 @@ std::string ArticleMaker::makeNotFoundBody( QString const & word,
|
|||
return result;
|
||||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const & inWord, unsigned groupId,
|
||||
sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(
|
||||
Config::InputPhrase const & phrase, unsigned groupId,
|
||||
QMap< QString, QString > const & contexts,
|
||||
QSet< QString > const & mutedDicts,
|
||||
QStringList const & dictIDs , bool ignoreDiacritics ) const
|
||||
|
@ -282,9 +283,9 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
break;
|
||||
}
|
||||
|
||||
string header = makeHtmlHeader( inWord.trimmed(), QString(), true );
|
||||
string header = makeHtmlHeader( phrase.phrase, QString(), true );
|
||||
|
||||
return new ArticleRequest( inWord.trimmed(), "",
|
||||
return new ArticleRequest( phrase, "",
|
||||
contexts, ftsDicts, header,
|
||||
-1, true );
|
||||
}
|
||||
|
@ -292,9 +293,9 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
if ( groupId == Instances::Group::HelpGroupId )
|
||||
{
|
||||
// This is a special group containing internal welcome/help pages
|
||||
string result = makeHtmlHeader( inWord, QString(), needExpandOptionalParts );
|
||||
string result = makeHtmlHeader( phrase.phrase, QString(), needExpandOptionalParts );
|
||||
|
||||
if ( inWord == tr( "Welcome!" ) )
|
||||
if ( phrase.phrase == tr( "Welcome!" ) )
|
||||
{
|
||||
result += tr(
|
||||
"<h3 align=\"center\">Welcome to <b>GoldenDict</b>!</h3>"
|
||||
|
@ -312,7 +313,7 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
).toUtf8().data();
|
||||
}
|
||||
else
|
||||
if ( inWord == tr( "Working with popup" ) )
|
||||
if ( phrase.phrase == tr( "Working with popup" ) )
|
||||
{
|
||||
result += ( tr( "<h3 align=\"center\">Working with the popup</h3>"
|
||||
|
||||
|
@ -333,7 +334,7 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
else
|
||||
{
|
||||
// Not found
|
||||
return makeNotFoundTextFor( inWord, "help" );
|
||||
return makeNotFoundTextFor( phrase.phrase, "help" );
|
||||
}
|
||||
|
||||
result += "</body></html>";
|
||||
|
@ -362,7 +363,7 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
std::vector< sptr< Dictionary::Class > > const & activeDicts =
|
||||
activeGroup ? activeGroup->dictionaries : dictionaries;
|
||||
|
||||
string header = makeHtmlHeader( inWord.trimmed(),
|
||||
string header = makeHtmlHeader( phrase.phrase,
|
||||
activeGroup && activeGroup->icon.size() ?
|
||||
activeGroup->icon : QString(),
|
||||
needExpandOptionalParts );
|
||||
|
@ -378,13 +379,13 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(QString const &
|
|||
QString::fromStdString( activeDicts[ x ]->getId() ) ) )
|
||||
unmutedDicts.push_back( activeDicts[ x ] );
|
||||
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "",
|
||||
return new ArticleRequest( phrase, activeGroup ? activeGroup->name : "",
|
||||
contexts, unmutedDicts, header,
|
||||
collapseBigArticles ? articleLimitSize : -1,
|
||||
needExpandOptionalParts, ignoreDiacritics );
|
||||
}
|
||||
else
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "",
|
||||
return new ArticleRequest( phrase, activeGroup ? activeGroup->name : "",
|
||||
contexts, activeDicts, header,
|
||||
collapseBigArticles ? articleLimitSize : -1,
|
||||
needExpandOptionalParts, ignoreDiacritics );
|
||||
|
@ -466,12 +467,12 @@ bool ArticleMaker::adjustFilePath( QString & fileName )
|
|||
//////// ArticleRequest
|
||||
|
||||
ArticleRequest::ArticleRequest(
|
||||
QString const & word_, QString const & group_,
|
||||
Config::InputPhrase const & phrase, QString const & group_,
|
||||
QMap< QString, QString > const & contexts_,
|
||||
vector< sptr< Dictionary::Class > > const & activeDicts_,
|
||||
string const & header,
|
||||
int sizeLimit, bool needExpandOptionalParts_, bool ignoreDiacritics_ ):
|
||||
word( word_ ), group( group_ ), contexts( contexts_ ),
|
||||
word( phrase.phrase ), group( group_ ), contexts( contexts_ ),
|
||||
activeDicts( activeDicts_ ),
|
||||
altsDone( false ), bodyDone( false ), foundAnyDefinitions( false ),
|
||||
closePrevSpan( false )
|
||||
|
@ -479,6 +480,9 @@ ArticleRequest::ArticleRequest(
|
|||
, needExpandOptionalParts( needExpandOptionalParts_ )
|
||||
, ignoreDiacritics( ignoreDiacritics_ )
|
||||
{
|
||||
if ( !phrase.punctuationSuffix.isEmpty() )
|
||||
alts.insert( gd::toWString( phrase.phraseWithSuffix() ) );
|
||||
|
||||
// No need to lock dataMutex on construction
|
||||
|
||||
hasAnyData = true;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QMap>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include "config.hh"
|
||||
#include "dictionary.hh"
|
||||
#include "instances.hh"
|
||||
#include "wordfinder.hh"
|
||||
|
@ -41,7 +42,7 @@ public:
|
|||
/// choice of the stylesheet file.
|
||||
void setDisplayStyle( QString const &, QString const & addonStyle );
|
||||
|
||||
/// Looks up the given word within the given group, and creates a full html
|
||||
/// Looks up the given phrase within the given group, and creates a full html
|
||||
/// page text containing its definition.
|
||||
/// The result is returned as Dictionary::DataRequest just like dictionaries
|
||||
/// themselves do. The difference is that the result is a complete html page
|
||||
|
@ -50,7 +51,7 @@ public:
|
|||
/// the keys are dictionary ids.
|
||||
/// If mutedDicts is not empty, the search would be limited only to those
|
||||
/// dictionaries in group which aren't listed there.
|
||||
sptr< Dictionary::DataRequest > makeDefinitionFor( QString const & word, unsigned groupId,
|
||||
sptr< Dictionary::DataRequest > makeDefinitionFor( Config::InputPhrase const & phrase, unsigned groupId,
|
||||
QMap< QString, QString > const & contexts,
|
||||
QSet< QString > const & mutedDicts =
|
||||
QSet< QString >(),
|
||||
|
@ -129,7 +130,7 @@ class ArticleRequest: public Dictionary::DataRequest
|
|||
|
||||
public:
|
||||
|
||||
ArticleRequest( QString const & word, QString const & group,
|
||||
ArticleRequest( Config::InputPhrase const & phrase, QString const & group,
|
||||
QMap< QString, QString > const & contexts,
|
||||
std::vector< sptr< Dictionary::Class > > const & activeDicts,
|
||||
std::string const & header,
|
||||
|
|
|
@ -388,9 +388,10 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
|
|||
if ( Qt4x5::Url::queryItemValue( url, "blank" ) == "1" )
|
||||
return articleMaker.makeEmptyPage();
|
||||
|
||||
bool groupIsValid = false;
|
||||
Config::InputPhrase phrase { Qt4x5::Url::queryItemValue( url, "word" ).trimmed(),
|
||||
Qt4x5::Url::queryItemValue( url, "punctuation_suffix" ) };
|
||||
|
||||
QString word = Qt4x5::Url::queryItemValue( url, "word" );
|
||||
bool groupIsValid = false;
|
||||
unsigned group = Qt4x5::Url::queryItemValue( url, "group" ).toUInt( &groupIsValid );
|
||||
|
||||
QString dictIDs = Qt4x5::Url::queryItemValue( url, "dictionaries" );
|
||||
|
@ -398,7 +399,7 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
|
|||
{
|
||||
// Individual dictionaries set from full-text search
|
||||
QStringList dictIDList = dictIDs.split( "," );
|
||||
return articleMaker.makeDefinitionFor( word, 0, QMap< QString, QString >(), QSet< QString >(), dictIDList );
|
||||
return articleMaker.makeDefinitionFor( phrase, 0, QMap< QString, QString >(), QSet< QString >(), dictIDList );
|
||||
}
|
||||
|
||||
// See if we have some dictionaries muted
|
||||
|
@ -429,8 +430,8 @@ sptr< Dictionary::DataRequest > ArticleNetworkAccessManager::getResource(
|
|||
|
||||
bool ignoreDiacritics = Qt4x5::Url::queryItemValue( url, "ignore_diacritics" ) == "1";
|
||||
|
||||
if ( groupIsValid && word.size() ) // Require group and word to be passed
|
||||
return articleMaker.makeDefinitionFor( word, group, contexts, mutedDicts, QStringList(), ignoreDiacritics );
|
||||
if ( groupIsValid && phrase.isValid() ) // Require group and phrase to be passed
|
||||
return articleMaker.makeDefinitionFor( phrase, group, contexts, mutedDicts, QStringList(), ignoreDiacritics );
|
||||
}
|
||||
|
||||
if ( ( url.scheme() == "bres" || url.scheme() == "gdau" || url.scheme() == "gdvideo" || url.scheme() == "gico" ) &&
|
||||
|
|
|
@ -352,7 +352,7 @@ ArticleView::~ArticleView()
|
|||
#endif
|
||||
}
|
||||
|
||||
void ArticleView::showDefinition( QString const & word, unsigned group,
|
||||
void ArticleView::showDefinition( Config::InputPhrase const & phrase, unsigned group,
|
||||
QString const & scrollTo,
|
||||
Contexts const & contexts_ )
|
||||
{
|
||||
|
@ -364,7 +364,9 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
|||
|
||||
req.setScheme( "gdlookup" );
|
||||
req.setHost( "localhost" );
|
||||
Qt4x5::Url::addQueryItem( req, "word", word );
|
||||
Qt4x5::Url::addQueryItem( req, "word", phrase.phrase );
|
||||
if ( !phrase.punctuationSuffix.isEmpty() )
|
||||
Qt4x5::Url::addQueryItem( req, "punctuation_suffix", phrase.punctuationSuffix );
|
||||
Qt4x5::Url::addQueryItem( req, "group", QString::number( group ) );
|
||||
if( cfg.preferences.ignoreDiacritics )
|
||||
Qt4x5::Url::addQueryItem( req, "ignore_diacritics", "1" );
|
||||
|
@ -401,7 +403,7 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
|||
|
||||
// Update both histories (pages history and headwords history)
|
||||
saveHistoryUserData();
|
||||
emit sendWordToHistory( word );
|
||||
emit sendWordToHistory( phrase.phrase );
|
||||
|
||||
// Any search opened is probably irrelevant now
|
||||
closeSearch();
|
||||
|
@ -417,6 +419,13 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
|
|||
ui.definition->setCursor( Qt::WaitCursor );
|
||||
}
|
||||
|
||||
void ArticleView::showDefinition( QString const & word, unsigned group,
|
||||
QString const & scrollTo,
|
||||
Contexts const & contexts_ )
|
||||
{
|
||||
showDefinition( Config::InputPhrase::fromPhrase( word ), group, scrollTo, contexts_ );
|
||||
}
|
||||
|
||||
void ArticleView::showDefinition( QString const & word, QStringList const & dictIDs,
|
||||
QRegExp const & searchRegExp, unsigned group,
|
||||
bool ignoreDiacritics )
|
||||
|
@ -1668,6 +1677,13 @@ QString ArticleView::getTitle()
|
|||
return ui.definition->page()->mainFrame()->title();
|
||||
}
|
||||
|
||||
Config::InputPhrase ArticleView::getPhrase() const
|
||||
{
|
||||
const QUrl url = ui.definition->url();
|
||||
return { Qt4x5::Url::queryItemValue( url, "word" ),
|
||||
Qt4x5::Url::queryItemValue( url, "punctuation_suffix" ) };
|
||||
}
|
||||
|
||||
void ArticleView::print( QPrinter * printer ) const
|
||||
{
|
||||
ui.definition->print( printer );
|
||||
|
@ -2085,9 +2101,9 @@ void ArticleView::audioPlayerError( QString const & message )
|
|||
|
||||
void ArticleView::pasteTriggered()
|
||||
{
|
||||
QString text = cfg.preferences.sanitizeInputPhrase( QApplication::clipboard()->text() );
|
||||
Config::InputPhrase phrase = cfg.preferences.sanitizeInputPhrase( QApplication::clipboard()->text() );
|
||||
|
||||
if ( text.size() )
|
||||
if ( phrase.isValid() )
|
||||
{
|
||||
unsigned groupId = getGroup( ui.definition->url() );
|
||||
if ( groupId == 0 )
|
||||
|
@ -2096,7 +2112,7 @@ void ArticleView::pasteTriggered()
|
|||
// so let's try the currently selected group.
|
||||
groupId = groupComboBox->getCurrentGroup();
|
||||
}
|
||||
showDefinition( text, groupId, getCurrentArticle() );
|
||||
showDefinition( phrase, groupId, getCurrentArticle() );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@ public:
|
|||
/// contexts is an optional map of context values to be passed for dictionaries.
|
||||
/// The only values to pass here are ones obtained from showDefinitionInNewTab()
|
||||
/// signal or none at all.
|
||||
void showDefinition( Config::InputPhrase const & phrase, unsigned group,
|
||||
QString const & scrollTo = QString(),
|
||||
Contexts const & contexts = Contexts() );
|
||||
|
||||
void showDefinition( QString const & word, unsigned group,
|
||||
QString const & scrollTo = QString(),
|
||||
Contexts const & contexts = Contexts() );
|
||||
|
@ -161,6 +165,9 @@ public:
|
|||
/// Returns current article's title
|
||||
QString getTitle();
|
||||
|
||||
/// Returns the phrase translated by the current article.
|
||||
Config::InputPhrase getPhrase() const;
|
||||
|
||||
/// Prints current article
|
||||
void print( QPrinter * ) const;
|
||||
|
||||
|
|
22
config.cc
22
config.cc
|
@ -153,15 +153,31 @@ ScanPopupWindowFlags spwfFromInt( int id )
|
|||
return SPWF_default;
|
||||
}
|
||||
|
||||
QString Preferences::sanitizeInputPhrase( QString const & inputPhrase ) const
|
||||
InputPhrase Preferences::sanitizeInputPhrase( QString const & inputPhrase ) const
|
||||
{
|
||||
InputPhrase result;
|
||||
|
||||
if( limitInputPhraseLength && inputPhrase.size() > inputPhraseLengthLimit )
|
||||
{
|
||||
gdWarning( "Ignoring an input phrase %d symbols long. The configured maximum input phrase length is %d symbols.",
|
||||
inputPhrase.size(), inputPhraseLengthLimit );
|
||||
return QString();
|
||||
return result;
|
||||
}
|
||||
return gd::toQString( Folding::trimWhitespaceOrPunct( gd::toWString( inputPhrase ) ) ).simplified();
|
||||
|
||||
const QString withPunct = inputPhrase.simplified();
|
||||
result.phrase = gd::toQString( Folding::trimWhitespaceOrPunct( gd::toWString( withPunct ) ) );
|
||||
if ( !result.isValid() )
|
||||
return result; // The suffix of an invalid input phrase must be empty.
|
||||
|
||||
const int prefixSize = withPunct.indexOf( result.phrase.at(0) );
|
||||
const int suffixSize = withPunct.size() - prefixSize - result.phrase.size();
|
||||
Q_ASSERT( suffixSize >= 0 );
|
||||
Q_ASSERT( withPunct.size() - suffixSize - 1
|
||||
== withPunct.lastIndexOf( result.phrase.at( result.phrase.size() - 1 ) ) );
|
||||
if ( suffixSize != 0 )
|
||||
result.punctuationSuffix = withPunct.right( suffixSize );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Preferences::Preferences():
|
||||
|
|
30
config.hh
30
config.hh
|
@ -11,6 +11,7 @@
|
|||
#include <QDateTime>
|
||||
#include <QKeySequence>
|
||||
#include <QSet>
|
||||
#include <QMetaType>
|
||||
#include "cpp_features.hh"
|
||||
#include "ex.hh"
|
||||
|
||||
|
@ -243,6 +244,30 @@ enum ScanPopupWindowFlags
|
|||
};
|
||||
ScanPopupWindowFlags spwfFromInt( int id );
|
||||
|
||||
struct InputPhrase
|
||||
{
|
||||
static InputPhrase fromPhrase( QString const & phrase )
|
||||
{
|
||||
return { phrase, QString() };
|
||||
}
|
||||
|
||||
bool isValid() const { return !phrase.isEmpty(); }
|
||||
|
||||
QString phraseWithSuffix() const { return phrase + punctuationSuffix; }
|
||||
|
||||
QString phrase;
|
||||
QString punctuationSuffix;
|
||||
};
|
||||
|
||||
inline bool operator == ( InputPhrase const & a, InputPhrase const & b )
|
||||
{
|
||||
return a.phrase == b.phrase && a.punctuationSuffix == b.punctuationSuffix;
|
||||
}
|
||||
inline bool operator != ( InputPhrase const & a, InputPhrase const & b )
|
||||
{
|
||||
return !( a == b );
|
||||
}
|
||||
|
||||
/// Various user preferences
|
||||
struct Preferences
|
||||
{
|
||||
|
@ -323,7 +348,7 @@ struct Preferences
|
|||
|
||||
bool limitInputPhraseLength;
|
||||
int inputPhraseLengthLimit;
|
||||
QString sanitizeInputPhrase( QString const & inputPhrase ) const;
|
||||
InputPhrase sanitizeInputPhrase( QString const & inputPhrase ) const;
|
||||
|
||||
unsigned short maxDictionaryRefsInContextMenu;
|
||||
#ifndef Q_WS_X11
|
||||
|
@ -802,5 +827,6 @@ QString getNetworkCacheDir() throw();
|
|||
|
||||
}
|
||||
|
||||
#endif
|
||||
Q_DECLARE_METATYPE( Config::InputPhrase )
|
||||
|
||||
#endif
|
||||
|
|
112
mainwindow.cc
112
mainwindow.cc
|
@ -142,6 +142,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
QThreadPool::globalInstance()->start( new InitSSLRunnable );
|
||||
#endif
|
||||
|
||||
qRegisterMetaType< Config::InputPhrase >();
|
||||
|
||||
#ifndef NO_EPWING_SUPPORT
|
||||
Epwing::initialize();
|
||||
#endif
|
||||
|
@ -957,11 +959,7 @@ void MainWindow::updateSearchPaneAndBar( bool searchInDock )
|
|||
updateGroupList();
|
||||
applyWordsZoomLevel();
|
||||
|
||||
if ( cfg.preferences.searchInDock )
|
||||
translateLine->setText( text );
|
||||
else
|
||||
translateBox->setText( text, false );
|
||||
|
||||
setTranslateBoxTextAndKeepSuffix( text, DisablePopup );
|
||||
focusTranslateLine();
|
||||
}
|
||||
|
||||
|
@ -981,7 +979,7 @@ void MainWindow::mousePressEvent( QMouseEvent *event)
|
|||
|
||||
QString str = QApplication::clipboard()->text(subtype,
|
||||
QClipboard::Selection);
|
||||
translateLine->setText(str);
|
||||
setTranslateBoxTextAndClearSuffix( str, NoPopupChange );
|
||||
|
||||
QKeyEvent ev(QEvent::KeyPress, Qt::Key_Enter,
|
||||
Qt::NoModifier);
|
||||
|
@ -1468,8 +1466,8 @@ void MainWindow::makeScanPopup()
|
|||
connect( scanPopup.get(), SIGNAL(editGroupRequested( unsigned ) ),
|
||||
this, SLOT(editDictionaries( unsigned )), Qt::QueuedConnection );
|
||||
|
||||
connect( scanPopup.get(), SIGNAL(sendWordToMainWindow( QString const & ) ),
|
||||
this, SLOT(wordReceived( QString const & )), Qt::QueuedConnection );
|
||||
connect( scanPopup.get(), SIGNAL(sendPhraseToMainWindow( Config::InputPhrase const & ) ),
|
||||
this, SLOT(phraseReceived( Config::InputPhrase const & )), Qt::QueuedConnection );
|
||||
|
||||
connect( this, SIGNAL( setExpandOptionalParts( bool ) ),
|
||||
scanPopup.get(), SIGNAL( setViewExpandMode( bool ) ) );
|
||||
|
@ -2063,7 +2061,7 @@ void MainWindow::editDictionaries( unsigned editDictionaryGroup )
|
|||
|
||||
Config::save( cfg );
|
||||
|
||||
translateInputChanged( translateLine->text() );
|
||||
updateSuggestionList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2244,7 +2242,7 @@ void MainWindow::currentGroupChanged( QString const & )
|
|||
|
||||
// Update word search results
|
||||
translateBox->setPopupEnabled( false );
|
||||
translateInputChanged( translateLine->text() );
|
||||
updateSuggestionList();
|
||||
translateInputFinished( false );
|
||||
|
||||
updateCurrentGroupProperty();
|
||||
|
@ -2275,6 +2273,17 @@ void MainWindow::updateCurrentGroupProperty()
|
|||
}
|
||||
|
||||
void MainWindow::translateInputChanged( QString const & newValue )
|
||||
{
|
||||
updateSuggestionList( newValue );
|
||||
translateBoxSuffix = QString();
|
||||
}
|
||||
|
||||
void MainWindow::updateSuggestionList()
|
||||
{
|
||||
updateSuggestionList( translateLine->text() );
|
||||
}
|
||||
|
||||
void MainWindow::updateSuggestionList( QString const & newValue )
|
||||
{
|
||||
// If there's some status bar message present, clear it since it may be
|
||||
// about the previous search that has failed.
|
||||
|
@ -2312,17 +2321,22 @@ void MainWindow::translateInputChanged( QString const & newValue )
|
|||
wordFinder.prefixMatch( req, getActiveDicts() );
|
||||
}
|
||||
|
||||
void MainWindow::translateInputFinished( bool checkModifiers, QString const & dictID )
|
||||
void MainWindow::translateInputFinished( bool checkModifiers )
|
||||
{
|
||||
QString word = Folding::unescapeWildcardSymbols( translateLine->text() );
|
||||
respondToTranslationRequest( { word, translateBoxSuffix }, checkModifiers );
|
||||
}
|
||||
|
||||
if ( word.size() )
|
||||
void MainWindow::respondToTranslationRequest( Config::InputPhrase const & phrase,
|
||||
bool checkModifiers, QString const & dictID )
|
||||
{
|
||||
if ( phrase.isValid() )
|
||||
{
|
||||
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers();
|
||||
if ( checkModifiers && ( mods & (Qt::ControlModifier | Qt::ShiftModifier) ) )
|
||||
addNewTab();
|
||||
|
||||
showTranslationFor( word, 0, dictID );
|
||||
showTranslationFor( phrase, 0, dictID );
|
||||
|
||||
if ( cfg.preferences.searchInDock )
|
||||
{
|
||||
|
@ -2334,6 +2348,20 @@ void MainWindow::translateInputFinished( bool checkModifiers, QString const & di
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::setTranslateBoxTextAndKeepSuffix( QString const & text, TranslateBoxPopup popupAction )
|
||||
{
|
||||
if( popupAction == TranslateBoxPopup::NoPopupChange || cfg.preferences.searchInDock )
|
||||
translateLine->setText( text );
|
||||
else
|
||||
translateBox->setText( text, popupAction == TranslateBoxPopup::EnablePopup );
|
||||
}
|
||||
|
||||
void MainWindow::setTranslateBoxTextAndClearSuffix( QString const & text, TranslateBoxPopup popupAction )
|
||||
{
|
||||
setTranslateBoxTextAndKeepSuffix( text, popupAction );
|
||||
translateBoxSuffix = QString();
|
||||
}
|
||||
|
||||
void MainWindow::handleEsc()
|
||||
{
|
||||
ArticleView *view = getCurrentArticleView();
|
||||
|
@ -2370,8 +2398,7 @@ void MainWindow::applyMutedDictionariesState()
|
|||
{
|
||||
translateBox->setPopupEnabled( false );
|
||||
|
||||
// Redo the current search request
|
||||
translateInputChanged( translateLine->text() );
|
||||
updateSuggestionList();
|
||||
|
||||
ArticleView *view = getCurrentArticleView();
|
||||
|
||||
|
@ -2724,10 +2751,7 @@ void MainWindow::typingEvent( QString const & t )
|
|||
if( translateLine->isEnabled() )
|
||||
{
|
||||
translateLine->setFocus();
|
||||
if ( cfg.preferences.searchInDock )
|
||||
translateLine->setText( t );
|
||||
else
|
||||
translateBox->setText( t, true );
|
||||
setTranslateBoxTextAndClearSuffix( t, EnablePopup );
|
||||
translateLine->setCursorPosition( t.size() );
|
||||
}
|
||||
}
|
||||
|
@ -2745,17 +2769,13 @@ void MainWindow::showHistoryItem( QString const & word )
|
|||
|
||||
history.enableAdd( false );
|
||||
|
||||
if ( cfg.preferences.searchInDock )
|
||||
translateLine->setText( Folding::escapeWildcardSymbols( word ) );
|
||||
else
|
||||
translateBox->setText( Folding::escapeWildcardSymbols( word ), false );
|
||||
|
||||
setTranslateBoxTextAndClearSuffix( Folding::escapeWildcardSymbols( word ), DisablePopup );
|
||||
showTranslationFor( word );
|
||||
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
}
|
||||
|
||||
void MainWindow::showTranslationFor( QString const & inWord,
|
||||
void MainWindow::showTranslationFor( Config::InputPhrase const & phrase,
|
||||
unsigned inGroup,
|
||||
QString const & dictID )
|
||||
{
|
||||
|
@ -2767,14 +2787,14 @@ void MainWindow::showTranslationFor( QString const & inWord,
|
|||
( groupInstances.empty() ? 0 :
|
||||
groupInstances[ groupList->currentIndex() ].id );
|
||||
|
||||
view->showDefinition( inWord, group, dictID );
|
||||
view->showDefinition( phrase, group, dictID );
|
||||
|
||||
updatePronounceAvailability();
|
||||
updateFoundInDictsList();
|
||||
|
||||
// Add to history
|
||||
|
||||
addWordToHistory( inWord );
|
||||
addWordToHistory( phrase.phrase );
|
||||
|
||||
updateBackForwardButtons();
|
||||
|
||||
|
@ -2867,6 +2887,11 @@ void MainWindow::showTranslationFor( QString const & inWord,
|
|||
//ui.tabWidget->setTabText( ui.tabWidget->indexOf(ui.tab), inWord.trimmed() );
|
||||
}
|
||||
|
||||
void MainWindow::showTranslationFor( QString const & word )
|
||||
{
|
||||
showTranslationFor( Config::InputPhrase::fromPhrase( word ) );
|
||||
}
|
||||
|
||||
void MainWindow::showTranslationFor( QString const & inWord,
|
||||
QStringList const & dictIDs,
|
||||
QRegExp const & searchRegExp,
|
||||
|
@ -3639,9 +3664,7 @@ void MainWindow::on_rescanFiles_triggered()
|
|||
makeScanPopup();
|
||||
installHotKeys();
|
||||
|
||||
// Reload suggestion list
|
||||
QString word = translateLine->text();
|
||||
translateInputChanged( word );
|
||||
updateSuggestionList();
|
||||
}
|
||||
|
||||
void MainWindow::on_alwaysOnTop_triggered( bool checked )
|
||||
|
@ -3871,18 +3894,25 @@ ArticleView * MainWindow::getCurrentArticleView()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void MainWindow::phraseReceived( Config::InputPhrase const & phrase )
|
||||
{
|
||||
toggleMainWindow( true );
|
||||
setTranslateBoxTextAndKeepSuffix( Folding::escapeWildcardSymbols( phrase.phrase ), NoPopupChange );
|
||||
translateBoxSuffix = phrase.punctuationSuffix;
|
||||
respondToTranslationRequest( phrase, false );
|
||||
}
|
||||
|
||||
void MainWindow::wordReceived( const QString & word)
|
||||
{
|
||||
toggleMainWindow( true );
|
||||
translateLine->setText( Folding::escapeWildcardSymbols( word ) );
|
||||
translateInputFinished( false );
|
||||
phraseReceived( Config::InputPhrase::fromPhrase( word ) );
|
||||
}
|
||||
|
||||
void MainWindow::headwordReceived( const QString & word, const QString & ID )
|
||||
{
|
||||
toggleMainWindow( true );
|
||||
translateLine->setText( Folding::escapeWildcardSymbols( word ) );
|
||||
translateInputFinished( false, QString( "gdfrom-" )+ ID );
|
||||
toggleMainWindow( true );
|
||||
setTranslateBoxTextAndClearSuffix( Folding::escapeWildcardSymbols( word ), NoPopupChange );
|
||||
respondToTranslationRequest( Config::InputPhrase::fromPhrase( word ),
|
||||
false, "gdfrom-" + ID );
|
||||
}
|
||||
|
||||
void MainWindow::updateFavoritesMenu()
|
||||
|
@ -4520,8 +4550,7 @@ void MainWindow::foundDictsContextMenuRequested( const QPoint &pos )
|
|||
|
||||
void MainWindow::sendWordToInputLine( const QString & word )
|
||||
{
|
||||
translateLine->clear();
|
||||
translateLine->setText( word );
|
||||
setTranslateBoxTextAndClearSuffix( word, NoPopupChange );
|
||||
}
|
||||
|
||||
void MainWindow::storeResourceSavePath( const QString & newPath )
|
||||
|
@ -4824,12 +4853,7 @@ void MainWindow::headwordFromFavorites( QString const & headword,
|
|||
}
|
||||
|
||||
// Show headword without lost of focus on Favorites tree
|
||||
|
||||
if ( cfg.preferences.searchInDock )
|
||||
translateLine->setText( Folding::escapeWildcardSymbols( headword ) );
|
||||
else
|
||||
translateBox->setText( Folding::escapeWildcardSymbols( headword ), false );
|
||||
|
||||
setTranslateBoxTextAndClearSuffix( Folding::escapeWildcardSymbols( headword ), DisablePopup );
|
||||
showTranslationFor(headword );
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ public slots:
|
|||
|
||||
void messageFromAnotherInstanceReceived( QString const & );
|
||||
void showStatusBarMessage ( QString const &, int, QPixmap const & );
|
||||
void phraseReceived( Config::InputPhrase const & );
|
||||
void wordReceived( QString const & );
|
||||
void headwordReceived( QString const &, QString const & );
|
||||
void setExpandMode( bool expand );
|
||||
|
@ -158,6 +159,7 @@ private:
|
|||
|
||||
WordList * wordList;
|
||||
QLineEdit * translateLine;
|
||||
QString translateBoxSuffix; ///< A punctuation suffix that corresponds to translateLine's text.
|
||||
|
||||
WordFinder wordFinder;
|
||||
|
||||
|
@ -257,6 +259,16 @@ private:
|
|||
|
||||
QString unescapeTabHeader( QString const & header );
|
||||
|
||||
void respondToTranslationRequest( Config::InputPhrase const & phrase,
|
||||
bool checkModifiers, QString const & dictID = QString() );
|
||||
|
||||
void updateSuggestionList();
|
||||
void updateSuggestionList( QString const & text );
|
||||
|
||||
enum TranslateBoxPopup { NoPopupChange, EnablePopup, DisablePopup };
|
||||
void setTranslateBoxTextAndKeepSuffix( QString const & text, TranslateBoxPopup popupAction );
|
||||
void setTranslateBoxTextAndClearSuffix( QString const & text, TranslateBoxPopup popupAction );
|
||||
|
||||
private slots:
|
||||
|
||||
void hotKeyActivated( int );
|
||||
|
@ -358,7 +370,7 @@ private slots:
|
|||
|
||||
void currentGroupChanged( QString const & );
|
||||
void translateInputChanged( QString const & );
|
||||
void translateInputFinished( bool checkModifiers = true, QString const & dictID = QString() );
|
||||
void translateInputFinished( bool checkModifiers = true );
|
||||
|
||||
/// Closes any opened search in the article view, and focuses the translateLine/close main window to tray.
|
||||
void handleEsc();
|
||||
|
@ -393,8 +405,9 @@ private slots:
|
|||
|
||||
void mutedDictionariesChanged();
|
||||
|
||||
void showTranslationFor( QString const &, unsigned inGroup = 0,
|
||||
void showTranslationFor( Config::InputPhrase const &, unsigned inGroup = 0,
|
||||
QString const & dictID = QString() );
|
||||
void showTranslationFor( QString const & );
|
||||
|
||||
void showTranslationFor( QString const &, QStringList const & dictIDs,
|
||||
QRegExp const & searchRegExp, bool ignoreDiacritics );
|
||||
|
|
61
scanpopup.cc
61
scanpopup.cc
|
@ -492,9 +492,9 @@ void ScanPopup::translateWordFromClipboard(QClipboard::Mode m)
|
|||
|
||||
void ScanPopup::translateWord( QString const & word )
|
||||
{
|
||||
QString str = pendingInputWord = cfg.preferences.sanitizeInputPhrase( word );
|
||||
pendingInputPhrase = cfg.preferences.sanitizeInputPhrase( word );
|
||||
|
||||
if ( !str.size() )
|
||||
if ( !pendingInputPhrase.isValid() )
|
||||
return; // Nothing there
|
||||
|
||||
// In case we had any timers engaged before, cancel them now.
|
||||
|
@ -505,7 +505,7 @@ void ScanPopup::translateWord( QString const & word )
|
|||
emit hideScanFlag();
|
||||
#endif
|
||||
|
||||
inputWord = str;
|
||||
inputPhrase = pendingInputPhrase;
|
||||
engagePopup( false,
|
||||
#ifdef Q_OS_WIN
|
||||
true // We only focus popup under Windows when activated via Ctrl+C+C
|
||||
|
@ -556,18 +556,18 @@ void ScanPopup::mouseHovered( QString const & str, bool forcePopup )
|
|||
|
||||
void ScanPopup::handleInputWord( QString const & str, bool forcePopup )
|
||||
{
|
||||
QString sanitizedStr = cfg.preferences.sanitizeInputPhrase( str );
|
||||
Config::InputPhrase sanitizedPhrase = cfg.preferences.sanitizeInputPhrase( str );
|
||||
|
||||
if ( isVisible() && sanitizedStr == inputWord )
|
||||
if ( isVisible() && sanitizedPhrase == inputPhrase )
|
||||
{
|
||||
// Attempt to translate the same word we already have shown in scan popup.
|
||||
// Ignore it, as it is probably a spurious mouseover event.
|
||||
return;
|
||||
}
|
||||
|
||||
pendingInputWord = sanitizedStr;
|
||||
pendingInputPhrase = sanitizedPhrase;
|
||||
|
||||
if ( !pendingInputWord.size() )
|
||||
if ( !pendingInputPhrase.isValid() )
|
||||
{
|
||||
if ( cfg.preferences.scanPopupAltMode )
|
||||
{
|
||||
|
@ -581,7 +581,7 @@ void ScanPopup::handleInputWord( QString const & str, bool forcePopup )
|
|||
|
||||
#ifdef HAVE_X11
|
||||
if ( cfg.preferences.showScanFlag ) {
|
||||
inputWord = pendingInputWord;
|
||||
inputPhrase = pendingInputPhrase;
|
||||
emit showScanFlag( forcePopup );
|
||||
return;
|
||||
}
|
||||
|
@ -600,7 +600,7 @@ void ScanPopup::handleInputWord( QString const & str, bool forcePopup )
|
|||
return;
|
||||
}
|
||||
|
||||
inputWord = pendingInputWord;
|
||||
inputPhrase = pendingInputPhrase;
|
||||
engagePopup( forcePopup );
|
||||
}
|
||||
|
||||
|
@ -616,7 +616,7 @@ void ScanPopup::engagePopup( bool forcePopup, bool giveFocus )
|
|||
if( cfg.preferences.scanToMainWindow && !forcePopup )
|
||||
{
|
||||
// Send translated word to main window istead of show popup
|
||||
emit sendWordToMainWindow( inputWord );
|
||||
emit sendPhraseToMainWindow( inputPhrase );
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -712,13 +712,15 @@ void ScanPopup::engagePopup( bool forcePopup, bool giveFocus )
|
|||
|
||||
/// Too large strings make window expand which is probably not what user
|
||||
/// wants
|
||||
ui.translateBox->setText( inputWord, false );
|
||||
ui.translateBox->setText( inputPhrase.phrase, false );
|
||||
translateBoxSuffix = inputPhrase.punctuationSuffix;
|
||||
|
||||
showTranslationFor( inputWord );
|
||||
showTranslationFor( inputPhrase );
|
||||
}
|
||||
|
||||
QString ScanPopup::elideInputWord()
|
||||
{
|
||||
QString const & inputWord = inputPhrase.phrase;
|
||||
return inputWord.size() > 32 ? inputWord.mid( 0, 32 ) + "..." : inputWord;
|
||||
}
|
||||
|
||||
|
@ -749,7 +751,7 @@ void ScanPopup::currentGroupChanged( QString const & )
|
|||
|
||||
if ( isVisible() )
|
||||
{
|
||||
translateInputChanged( ui.translateBox->translateLine()->text() );
|
||||
updateSuggestionList();
|
||||
translateInputFinished();
|
||||
}
|
||||
|
||||
|
@ -758,10 +760,21 @@ void ScanPopup::currentGroupChanged( QString const & )
|
|||
|
||||
void ScanPopup::wordListItemActivated( QListWidgetItem * item )
|
||||
{
|
||||
showTranslationFor( item->text() );
|
||||
showTranslationFor( Config::InputPhrase::fromPhrase( item->text() ) );
|
||||
}
|
||||
|
||||
void ScanPopup::translateInputChanged( QString const & text )
|
||||
{
|
||||
updateSuggestionList( text );
|
||||
translateBoxSuffix = QString();
|
||||
}
|
||||
|
||||
void ScanPopup::updateSuggestionList()
|
||||
{
|
||||
updateSuggestionList( ui.translateBox->translateLine()->text() );
|
||||
}
|
||||
|
||||
void ScanPopup::updateSuggestionList( QString const & text )
|
||||
{
|
||||
mainStatusBar->clearMessage();
|
||||
ui.translateBox->wordList()->setCurrentItem( 0, QItemSelectionModel::Clear );
|
||||
|
@ -791,20 +804,20 @@ void ScanPopup::translateInputChanged( QString const & text )
|
|||
|
||||
void ScanPopup::translateInputFinished()
|
||||
{
|
||||
inputWord = ui.translateBox->translateLine()->text().trimmed();
|
||||
showTranslationFor( inputWord );
|
||||
inputPhrase = { ui.translateBox->translateLine()->text().trimmed(), translateBoxSuffix };
|
||||
showTranslationFor( inputPhrase );
|
||||
}
|
||||
|
||||
void ScanPopup::showTranslationFor( QString const & inputWord )
|
||||
void ScanPopup::showTranslationFor( Config::InputPhrase const & inputPhrase )
|
||||
{
|
||||
ui.pronounceButton->hide();
|
||||
|
||||
unsigned groupId = ui.groupList->getCurrentGroup();
|
||||
definition->showDefinition( inputWord, groupId );
|
||||
definition->showDefinition( inputPhrase, groupId );
|
||||
definition->focus();
|
||||
|
||||
// Add to history
|
||||
emit sendWordToHistory( inputWord.trimmed() );
|
||||
emit sendWordToHistory( inputPhrase.phrase.trimmed() );
|
||||
}
|
||||
|
||||
vector< sptr< Dictionary::Class > > const & ScanPopup::getActiveDicts()
|
||||
|
@ -1124,7 +1137,7 @@ void ScanPopup::altModeExpired()
|
|||
|
||||
void ScanPopup::altModePoll()
|
||||
{
|
||||
if ( !pendingInputWord.size() )
|
||||
if ( !pendingInputPhrase.isValid() )
|
||||
{
|
||||
altModePollingTimer.stop();
|
||||
altModeExpirationTimer.stop();
|
||||
|
@ -1135,7 +1148,7 @@ void ScanPopup::altModePoll()
|
|||
altModePollingTimer.stop();
|
||||
altModeExpirationTimer.stop();
|
||||
|
||||
inputWord = pendingInputWord;
|
||||
inputPhrase = pendingInputPhrase;
|
||||
engagePopup( false );
|
||||
}
|
||||
}
|
||||
|
@ -1232,9 +1245,7 @@ void ScanPopup::updateDictionaryBar()
|
|||
|
||||
void ScanPopup::mutedDictionariesChanged()
|
||||
{
|
||||
// Update suggestion list
|
||||
translateInputChanged( ui.translateBox->translateLine()->text() );
|
||||
|
||||
updateSuggestionList();
|
||||
if ( dictionaryBar.toggleViewAction()->isChecked() )
|
||||
definition->updateMutedContents();
|
||||
}
|
||||
|
@ -1248,7 +1259,7 @@ void ScanPopup::on_sendWordButton_clicked()
|
|||
definition->closeSearch();
|
||||
hideWindow();
|
||||
}
|
||||
emit sendWordToMainWindow( definition->getTitle() );
|
||||
emit sendPhraseToMainWindow( definition->getPhrase() );
|
||||
}
|
||||
|
||||
void ScanPopup::on_sendWordToFavoritesButton_clicked()
|
||||
|
|
10
scanpopup.hh
10
scanpopup.hh
|
@ -59,7 +59,7 @@ signals:
|
|||
/// Forwarded from the dictionary bar, so that main window could act on this.
|
||||
void editGroupRequested( unsigned id );
|
||||
/// Send word to main window
|
||||
void sendWordToMainWindow( QString const & word );
|
||||
void sendPhraseToMainWindow( Config::InputPhrase const & phrase );
|
||||
/// Close opened menus when window hide
|
||||
void closeMenu();
|
||||
/// Signals to set expand optional parts mode (retranslation from/to MainWindow and dictionary bar)
|
||||
|
@ -133,7 +133,8 @@ private:
|
|||
ArticleView * definition;
|
||||
QAction escapeAction, switchExpandModeAction, focusTranslateLineAction;
|
||||
QAction openSearchAction;
|
||||
QString pendingInputWord, inputWord;
|
||||
Config::InputPhrase pendingInputPhrase, inputPhrase;
|
||||
QString translateBoxSuffix; ///< A punctuation suffix that corresponds to translateBox's text.
|
||||
WordFinder wordFinder;
|
||||
Config::Events configEvents;
|
||||
DictionaryBar dictionaryBar;
|
||||
|
@ -183,7 +184,10 @@ private:
|
|||
|
||||
void updateBackForwardButtons();
|
||||
|
||||
void showTranslationFor( QString const & inputWord );
|
||||
void showTranslationFor( Config::InputPhrase const & inputPhrase );
|
||||
|
||||
void updateSuggestionList();
|
||||
void updateSuggestionList( QString const & text );
|
||||
|
||||
private slots:
|
||||
|
||||
|
|
Loading…
Reference in a new issue