mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
Allow to collapse/expand articles; auto collapse for big articles (issue #331)
This commit is contained in:
parent
4a9d65232d
commit
d721e627b1
|
@ -2713,3 +2713,19 @@ in bg url to hide it from iemac */
|
|||
.mwiki .infl-table { display: none }
|
||||
/****default hide dict icon ***/
|
||||
.gddicticon{display:none;}
|
||||
|
||||
.gdexpandicon {
|
||||
cursor:pointer;
|
||||
width:16px;
|
||||
height:16px;
|
||||
vertical-align: text-bottom;
|
||||
background-image:url('qrcx://localhost/icons/arrow.png');
|
||||
}
|
||||
|
||||
.gdcollapseicon {
|
||||
cursor:pointer;
|
||||
width:16px;
|
||||
height:16px;
|
||||
vertical-align: text-bottom;
|
||||
background-image:url('qrcx://localhost/icons/downarrow.png');
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <limits.h>
|
||||
#include <QFile>
|
||||
#include <QUrl>
|
||||
#include <QTextDocumentFragment>
|
||||
#include "folding.hh"
|
||||
#include "langcoder.hh"
|
||||
#include "dprintf.hh"
|
||||
|
@ -28,6 +29,8 @@ ArticleMaker::ArticleMaker( vector< sptr< Dictionary::Class > > const & dictiona
|
|||
displayStyle( displayStyle_ ),
|
||||
addonStyle( addonStyle_ ),
|
||||
needExpandOptionalParts( true )
|
||||
, collapseBigArticles( true )
|
||||
, articleLimitSize( 500 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -121,8 +124,8 @@ std::string ArticleMaker::makeHtmlHeader( QString const & word,
|
|||
"gdAudioLinks = { first: null, current: null };"
|
||||
"function gdMakeArticleActive( newId ) {"
|
||||
"if ( gdCurrentArticle != 'gdfrom-' + newId ) {"
|
||||
"document.getElementById( gdCurrentArticle ).className = 'gdarticle';"
|
||||
"document.getElementById( 'gdfrom-' + newId ).className = 'gdarticle gdactivearticle';"
|
||||
"el=document.getElementById( gdCurrentArticle ); el.className = el.className.replace(' gdactivearticle','');"
|
||||
"el=document.getElementById( 'gdfrom-' + newId ); el.className = el.className + ' gdactivearticle';"
|
||||
"gdCurrentArticle = 'gdfrom-' + newId; gdAudioLinks.current = newId;"
|
||||
"articleview.onJsActiveArticleChanged(gdCurrentArticle); } }"
|
||||
"var overIframeId = null;"
|
||||
|
@ -137,7 +140,22 @@ std::string ArticleMaker::makeHtmlHeader( QString const & word,
|
|||
"window.addEventListener('load', init, false);"
|
||||
"function gdExpandOptPart( expanderId, optionalId ) { var d1=document.getElementById(expanderId); var i = 0; if( d1.alt == '[+]' ) {"
|
||||
"d1.alt = '[-]'; d1.src = 'qrcx://localhost/icons/collapse_opt.png'; for( i = 0; i < 1000; i++ ) { var d2=document.getElementById( optionalId + i ); if( !d2 ) break; d2.style.display='inline'; } }"
|
||||
"else { d1.alt = '[+]'; d1.src = 'qrcx://localhost/icons/expand_opt.png'; for( i = 0; i < 1000; i++ ) { var d2=document.getElementById( optionalId + i ); if( !d2 ) break; d2.style.display='none'; } } }"
|
||||
"else { d1.alt = '[+]'; d1.src = 'qrcx://localhost/icons/expand_opt.png'; for( i = 0; i < 1000; i++ ) { var d2=document.getElementById( optionalId + i ); if( !d2 ) break; d2.style.display='none'; } } };"
|
||||
"function gdExpandArticle( id ) { elem = document.getElementById('gdarticlefrom-'+id); ico = document.getElementById('expandicon-'+id); art=document.getElementById('gdfrom-'+id);"
|
||||
"t=window.event.target || window.event.srcElement;"
|
||||
"if(elem.style.display=='inline' && t==ico) {"
|
||||
"elem.style.display='none'; ico.className='gdexpandicon';"
|
||||
"art.className = art.className+' gdcollapsedarticle';"
|
||||
"nm=document.getElementById('gddictname-'+id); nm.style.cursor='pointer';"
|
||||
"window.event.stopPropagation(); ico.title=''; nm.title='";
|
||||
result += tr( "Expand article" ).toUtf8().data();
|
||||
result += "' } else {"
|
||||
"elem.style.display='inline'; ico.className='gdcollapseicon';"
|
||||
"art.className=art.className.replace(' gdcollapsedarticle','');"
|
||||
"nm=document.getElementById('gddictname-'+id); nm.style.cursor='default';"
|
||||
"nm.title=''; ico.title='";
|
||||
result += tr( "Collapse article").toUtf8().data();
|
||||
result += "' } }"
|
||||
"</script>";
|
||||
|
||||
result += "</head><body>";
|
||||
|
@ -259,11 +277,13 @@ sptr< Dictionary::DataRequest > ArticleMaker::makeDefinitionFor(
|
|||
unmutedDicts.push_back( activeDicts[ x ] );
|
||||
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "",
|
||||
contexts, unmutedDicts, header );
|
||||
contexts, unmutedDicts, header,
|
||||
collapseBigArticles ? articleLimitSize : -1 );
|
||||
}
|
||||
else
|
||||
return new ArticleRequest( inWord.trimmed(), activeGroup ? activeGroup->name : "",
|
||||
contexts, activeDicts, header );
|
||||
contexts, activeDicts, header,
|
||||
collapseBigArticles ? articleLimitSize : -1 );
|
||||
}
|
||||
|
||||
sptr< Dictionary::DataRequest > ArticleMaker::makeNotFoundTextFor(
|
||||
|
@ -315,6 +335,13 @@ void ArticleMaker::setExpandOptionalParts( bool expand )
|
|||
needExpandOptionalParts = expand;
|
||||
}
|
||||
|
||||
void ArticleMaker::setCollapseParameters( bool autoCollapse, int articleSize )
|
||||
{
|
||||
collapseBigArticles = autoCollapse;
|
||||
articleLimitSize = articleSize;
|
||||
}
|
||||
|
||||
|
||||
bool ArticleMaker::adjustFilePath( QString & fileName )
|
||||
{
|
||||
QFileInfo info( fileName );
|
||||
|
@ -338,11 +365,13 @@ ArticleRequest::ArticleRequest(
|
|||
QString const & word_, QString const & group_,
|
||||
QMap< QString, QString > const & contexts_,
|
||||
vector< sptr< Dictionary::Class > > const & activeDicts_,
|
||||
string const & header ):
|
||||
string const & header,
|
||||
int sizeLimit ):
|
||||
word( word_ ), group( group_ ), contexts( contexts_ ),
|
||||
activeDicts( activeDicts_ ),
|
||||
altsDone( false ), bodyDone( false ), foundAnyDefinitions( false ),
|
||||
closePrevSpan( false )
|
||||
, articleSizeLimit( sizeLimit )
|
||||
{
|
||||
// No need to lock dataMutex on construction
|
||||
|
||||
|
@ -461,7 +490,7 @@ void ArticleRequest::bodyFinished()
|
|||
|
||||
if ( closePrevSpan )
|
||||
{
|
||||
head += "</span></span><span class=\"gdarticleseparator\"></span>";
|
||||
head += "</span></span><div style=\"clear:both;\"></div><span class=\"gdarticleseparator\"></span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -471,6 +500,22 @@ void ArticleRequest::bodyFinished()
|
|||
"articleview.onJsActiveArticleChanged(gdCurrentArticle)</script>";
|
||||
}
|
||||
|
||||
bool collapse = false;
|
||||
if( articleSizeLimit >= 0 )
|
||||
{
|
||||
try
|
||||
{
|
||||
Mutex::Lock _( dataMutex );
|
||||
QString text = QString::fromUtf8( req.getFullData().data(), req.getFullData().size() );
|
||||
int size = QTextDocumentFragment::fromHtml( text ).toPlainText().length();
|
||||
if( size > articleSizeLimit )
|
||||
collapse = true;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
string jsVal = Html::escapeForJavaScript( dictId );
|
||||
head += "<script type=\"text/javascript\">var gdArticleContents; "
|
||||
"if ( !gdArticleContents ) gdArticleContents = \"" + jsVal +" \"; "
|
||||
|
@ -478,6 +523,7 @@ void ArticleRequest::bodyFinished()
|
|||
|
||||
head += string( "<span class=\"gdarticle" ) +
|
||||
( closePrevSpan ? "" : " gdactivearticle" ) +
|
||||
( collapse ? " gdcollapsedarticle" : "" ) +
|
||||
"\" id=\"" + gdFrom +
|
||||
"\" onClick=\"gdMakeArticleActive( '" + jsVal + "' );\" " +
|
||||
" onContextMenu=\"gdMakeArticleActive( '" + jsVal + "' );\""
|
||||
|
@ -485,18 +531,28 @@ void ArticleRequest::bodyFinished()
|
|||
|
||||
closePrevSpan = true;
|
||||
|
||||
head += string( "<div class=\"gddictname\"><span class=\"gddicticon\"><img src=\"gico://")
|
||||
+ Html::escape( dictId )
|
||||
head += string( "<div class=\"gddictname\" onclick=\"gdExpandArticle(\'" ) + dictId + "\');"
|
||||
+ ( collapse ? "\" style=\"cursor:pointer;" : "" )
|
||||
+ "\" id=\"gddictname-" + Html::escape( dictId ) + "\""
|
||||
+ ( collapse ? string( " title=\"" ) + tr( "Expand article" ).toUtf8().data() + "\"" : "" )
|
||||
+ "><span class=\"gddicticon\"><img src=\"gico://" + Html::escape( dictId )
|
||||
+ "/dicticon.png\"></span><span class=\"gdfromprefix\">" +
|
||||
Html::escape( tr( "From " ).toUtf8().data() ) + "</span>" +
|
||||
Html::escape( activeDict->getName().c_str() )
|
||||
+ "</div>";
|
||||
+ "<span><img src=\"qrcx://localhost/icons/blank.png\" class=\""
|
||||
+ ( collapse ? "gdexpandicon" : "gdcollapseicon" )
|
||||
+ "\" id=\"expandicon-" + Html::escape( dictId ) + "\""
|
||||
+ ( collapse ? "" : string( " title=\"" ) + tr( "Collapse article" ).toUtf8().data() + "\"" )
|
||||
+ "></span>" + "</div>";
|
||||
|
||||
head += "<span class=\"gdarticlebody gdlangfrom-";
|
||||
head += LangCoder::intToCode2( activeDict->getLangFrom() ).toLatin1().data();
|
||||
head += "\" lang=\"";
|
||||
head += LangCoder::intToCode2( activeDict->getLangTo() ).toLatin1().data();
|
||||
head += "\">";
|
||||
head += "\"";
|
||||
head += " style=\"display:";
|
||||
head += collapse ? "none" : "inline";
|
||||
head += string( "\" id=\"gdarticlefrom-" ) + Html::escape( dictId ) + "\">";
|
||||
|
||||
if ( errorString.size() )
|
||||
{
|
||||
|
|
|
@ -23,6 +23,8 @@ class ArticleMaker: public QObject
|
|||
QString displayStyle, addonStyle;
|
||||
|
||||
bool needExpandOptionalParts;
|
||||
bool collapseBigArticles;
|
||||
int articleLimitSize;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -71,6 +73,9 @@ public:
|
|||
/// Return true if path successfully adjusted
|
||||
static bool adjustFilePath( QString & fileName );
|
||||
|
||||
/// Set collapse articles parameters
|
||||
void setCollapseParameters( bool autoCollapse, int articleSize );
|
||||
|
||||
private:
|
||||
|
||||
/// Makes everything up to and including the opening body tag.
|
||||
|
@ -115,13 +120,15 @@ class ArticleRequest: public Dictionary::DataRequest
|
|||
QString currentSplittedWordCompound;
|
||||
QString lastGoodCompoundResult;
|
||||
bool firstCompoundWasFound;
|
||||
int articleSizeLimit;
|
||||
|
||||
public:
|
||||
|
||||
ArticleRequest( QString const & word, QString const & group,
|
||||
QMap< QString, QString > const & contexts,
|
||||
std::vector< sptr< Dictionary::Class > > const & activeDicts,
|
||||
std::string const & header );
|
||||
std::string const & header,
|
||||
int sizeLimit );
|
||||
|
||||
virtual void cancel();
|
||||
// { finish(); } // Add our own requests cancellation here
|
||||
|
|
17
config.cc
17
config.cc
|
@ -122,6 +122,8 @@ Preferences::Preferences():
|
|||
storeHistory( 1 ),
|
||||
alwaysExpandOptionalParts( true )
|
||||
, historyStoreInterval( 0 )
|
||||
, collapseBigArticles( false )
|
||||
, articleSizeLimit( 2000 )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -725,6 +727,12 @@ Class load() throw( exError )
|
|||
|
||||
if ( !preferences.namedItem( "historyStoreInterval" ).isNull() )
|
||||
c.preferences.historyStoreInterval = preferences.namedItem( "historyStoreInterval" ).toElement().text().toUInt() ;
|
||||
|
||||
if ( !preferences.namedItem( "collapseBigArticles" ).isNull() )
|
||||
c.preferences.collapseBigArticles = ( preferences.namedItem( "collapseBigArticles" ).toElement().text() == "1" );
|
||||
|
||||
if ( !preferences.namedItem( "articleSizeLimit" ).isNull() )
|
||||
c.preferences.articleSizeLimit = preferences.namedItem( "articleSizeLimit" ).toElement().text().toUInt() ;
|
||||
}
|
||||
|
||||
c.lastMainGroupId = root.namedItem( "lastMainGroupId" ).toElement().text().toUInt();
|
||||
|
@ -1446,7 +1454,14 @@ void save( Class const & c ) throw( exError )
|
|||
opt = dd.createElement( "addonStyle" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.addonStyle ) );
|
||||
preferences.appendChild( opt );
|
||||
}
|
||||
|
||||
opt = dd.createElement( "collapseBigArticles" );
|
||||
opt.appendChild( dd.createTextNode( c.preferences.collapseBigArticles ? "1" : "0" ) );
|
||||
preferences.appendChild( opt );
|
||||
|
||||
opt = dd.createElement( "articleSizeLimit" );
|
||||
opt.appendChild( dd.createTextNode( QString::number( c.preferences.articleSizeLimit ) ) );
|
||||
preferences.appendChild( opt ); }
|
||||
|
||||
{
|
||||
QDomElement opt = dd.createElement( "lastMainGroupId" );
|
||||
|
|
|
@ -207,6 +207,9 @@ struct Preferences
|
|||
|
||||
unsigned historyStoreInterval;
|
||||
|
||||
bool collapseBigArticles;
|
||||
int articleSizeLimit;
|
||||
|
||||
QString addonStyle;
|
||||
|
||||
Preferences();
|
||||
|
|
BIN
icons/blank.png
Normal file
BIN
icons/blank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 B |
BIN
icons/downarrow.png
Normal file
BIN
icons/downarrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 479 B |
|
@ -87,6 +87,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
|
||||
ui.setupUi( this );
|
||||
|
||||
articleMaker.setCollapseParameters( cfg.preferences.collapseBigArticles, cfg.preferences.articleSizeLimit );
|
||||
|
||||
// use our own, cutsom statusbar
|
||||
setStatusBar(0);
|
||||
mainStatusBar = new MainStatusBar( this );
|
||||
|
@ -1741,6 +1743,12 @@ void MainWindow::editPreferences()
|
|||
needReload = true;
|
||||
}
|
||||
|
||||
if( cfg.preferences.collapseBigArticles != p.collapseBigArticles
|
||||
|| cfg.preferences.articleSizeLimit != p.articleSizeLimit )
|
||||
{
|
||||
articleMaker.setCollapseParameters( p.collapseBigArticles, p.articleSizeLimit );
|
||||
}
|
||||
|
||||
// See if we need to reapply expand optional parts mode
|
||||
if( cfg.preferences.alwaysExpandOptionalParts != p.alwaysExpandOptionalParts )
|
||||
{
|
||||
|
|
|
@ -135,6 +135,9 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ):
|
|||
ui.historySaveIntervalField->setValue( p.historyStoreInterval );
|
||||
ui.alwaysExpandOptionalParts->setChecked( p.alwaysExpandOptionalParts );
|
||||
|
||||
ui.collapseBigArticles->setChecked( p.collapseBigArticles );
|
||||
ui.articleSizeLimit->setValue( p.articleSizeLimit );
|
||||
|
||||
// Different platforms have different keys available
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
@ -252,6 +255,9 @@ Config::Preferences Preferences::getPreferences()
|
|||
p.historyStoreInterval = ui.historySaveIntervalField->text().toUInt();
|
||||
p.alwaysExpandOptionalParts = ui.alwaysExpandOptionalParts->isChecked();
|
||||
|
||||
p.collapseBigArticles = ui.collapseBigArticles->isChecked();
|
||||
p.articleSizeLimit = ui.articleSizeLimit->text().toInt();
|
||||
|
||||
p.pronounceOnLoadMain = ui.pronounceOnLoadMain->isChecked();
|
||||
p.pronounceOnLoadPopup = ui.pronounceOnLoadPopup->isChecked();
|
||||
p.useExternalPlayer = ui.useExternalPlayer->isChecked();
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>572</width>
|
||||
<height>394</height>
|
||||
<height>403</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
|
@ -1231,6 +1231,56 @@ It is not needed to select this option if you don't use such programs.</string>
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_11">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="collapseBigArticles">
|
||||
<property name="toolTip">
|
||||
<string>Select this option to automatic collapse big articles</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Collapse articles more than</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="articleSizeLimit">
|
||||
<property name="toolTip">
|
||||
<string>Artiles longer than this size will be collapsed</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100000</number>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>2000</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_13">
|
||||
<property name="text">
|
||||
<string>symbols</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -65,5 +65,7 @@
|
|||
<file>qt-style-st-lingoes-blue.css</file>
|
||||
<file>qt-style-macos.css</file>
|
||||
<file>icons/mdict.png</file>
|
||||
<file>icons/downarrow.png</file>
|
||||
<file>icons/blank.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
Loading…
Reference in a new issue