+ Save currently focused articles when navigating.

+ Lingvo style headers look closer to Lingvo now, and the currently chosen
  article gets its header highlighted, too.
This commit is contained in:
Konstantin Isakov 2009-05-11 22:25:22 +00:00
parent 527035f450
commit ac2d24709b
4 changed files with 123 additions and 10 deletions

View file

@ -28,3 +28,53 @@ a:hover
display: none;
}
.gddictname
{
font-size: 13px;
font-weight: normal;
float: right;
border: 1px solid white;
margin-top: 7px;
color: #7f7f7f;
background: white;
}
.gdarticleseparator + script + .gdarticle .gddictname
{
/* border-top: 1px solid #ccc;*/
margin-top: 11px;
}
.gdactivearticle .gddictname
{
font-size: 13px;
font-weight: normal;
float: right;
border: 1px solid #b3d7f7;
margin-top: 7px;
color: #0066ff;
background: #deecf8;
}
.gdarticleseparator + script + .gdactivearticle .gddictname
{
/* border-top: 1px solid #b3d7f7;*/
margin-top: 11px;
}
.gdarticleseparator
{
margin-top: 10px;
border-bottom: 1px solid #cccccc;
margin-bottom: -1px;
display: block;
clear: both;
}
.gddictname + h3, .gddictname + .dsl_article > .dsl_headwords
{
margin-top: 10px;
}

View file

@ -86,6 +86,14 @@ std::string ArticleMaker::makeHtmlHeader( QString const & word,
if ( icon.size() )
result += "<link rel=\"icon\" type=\"image/png\" href=\"qrcx://localhost/flags/" + Html::escape( icon.toUtf8().data() ) + "\" />\n";
result += "<script language=\"JavaScript\">"
"function gdMakeArticleActive( newId ) {"
"if ( gdCurrentArticle != newId ) {"
"document.getElementById( gdCurrentArticle ).className = 'gdarticle';"
"document.getElementById( newId ).className = 'gdarticle gdactivearticle';"
"gdCurrentArticle = newId; } }"
"</script>";
result += "</head><body>";
return result;
@ -335,7 +343,6 @@ void ArticleRequest::bodyFinished()
if ( closePrevSpan )
{
head += "</span><span class=\"gdarticleseparator\"></span>";
closePrevSpan = false;
}
else
{
@ -349,9 +356,11 @@ void ArticleRequest::bodyFinished()
"if ( !gdArticleContents ) gdArticleContents = \"" + jsVal +" \"; "
"else gdArticleContents += \"" + jsVal + " \";</script>";
head += "<span class=\"gdarticle\" id=\"" + gdFrom +
"\" onClick=\"gdCurrentArticle='" + gdFrom + "';\""
" onContextMenu=\"gdCurrentArticle='" + gdFrom + "';\""
head += string( "<span class=\"gdarticle" ) +
( closePrevSpan ? "" : " gdactivearticle" ) +
"\" id=\"" + gdFrom +
"\" onClick=\"gdMakeArticleActive( '" + gdFrom + "' );\" " +
" onContextMenu=\"gdMakeArticleActive( '" + gdFrom + "' );\""
+ ">";
closePrevSpan = true;

View file

@ -8,6 +8,7 @@
#include <QWebHitTestResult>
#include <QMenu>
#include <QDesktopServices>
#include <QWebHistory>
#ifdef Q_OS_WIN32
#include <windows.h>
@ -93,7 +94,15 @@ void ArticleView::showDefinition( QString const & word, unsigned group,
if ( scrollTo.size() )
req.setFragment( scrollTo );
// Save current article, if any
QString currentArticle = getCurrentArticle();
if ( currentArticle.size() )
ui.definition->history()->currentItem().setUserData( currentArticle );
ui.definition->load( req );
//QApplication::setOverrideCursor( Qt::WaitCursor );
ui.definition->setCursor( Qt::WaitCursor );
}
@ -107,6 +116,24 @@ void ArticleView::showAnticipation()
void ArticleView::loadFinished( bool )
{
QUrl url = ui.definition->url();
QVariant userData = ui.definition->history()->currentItem().userData();
if ( userData.type() == QVariant::String && userData.toString().startsWith( "gdfrom-" ) )
{
printf( "has user data\n" );
// There's an active article saved, so set it to be active.
setCurrentArticle( userData.toString() );
}
else
if ( url.hasFragment() && url.fragment().startsWith( "gdfrom-" ) )
{
// There is no active article saved in history, but we have it in fragment.
// setCurrentArticle will save it.
setCurrentArticle( url.fragment() );
}
ui.definition->unsetCursor();
//QApplication::restoreOverrideCursor();
emit pageLoaded();
@ -149,6 +176,13 @@ unsigned ArticleView::getGroup( QUrl const & url )
return 0;
}
QStringList ArticleView::getArticlesList()
{
return ui.definition->page()->currentFrame()->
evaluateJavaScript( "gdArticleContents;" ).toString().
trimmed().split( ' ', QString::SkipEmptyParts );
}
QString ArticleView::getCurrentArticle()
{
QVariant v = ui.definition->page()->currentFrame()->evaluateJavaScript(
@ -160,6 +194,19 @@ QString ArticleView::getCurrentArticle()
return QString();
}
void ArticleView::setCurrentArticle( QString const & id )
{
if ( !id.startsWith( "gdfrom-" ) )
return; // Incorrect id
if ( getArticlesList().contains( id.mid( 7 ) ) )
{
ui.definition->history()->currentItem().setUserData( id );
ui.definition->page()->currentFrame()->evaluateJavaScript(
QString( "gdMakeArticleActive( '%1' );" ).arg( id ) );
}
}
void ArticleView::cleanupTemp()
{
if ( desktopOpenedTempFile.size() )
@ -393,9 +440,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
map< QAction *, QString > tableOfContents;
// Add table of contents
QStringList ids = ui.definition->page()->currentFrame()->
evaluateJavaScript( "gdArticleContents;" ).toString().
trimmed().split( ' ', QString::SkipEmptyParts );
QStringList ids = getArticlesList();
if ( !menu.isEmpty() && ids.size() )
menu.addSeparator();
@ -456,9 +501,11 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
if ( id.size() )
{
QString targetArticle = "gdfrom-" + id;
QUrl url( ui.definition->url() );
url.setFragment( "gdfrom-" + id );
url.setFragment( targetArticle );
openLink( url, ui.definition->url() );
setCurrentArticle( targetArticle );
}
}
}

View file

@ -134,9 +134,16 @@ private:
/// returns 0.
unsigned getGroup( QUrl const & );
/// Returns current article in the view, in the form of "gdform-xxx" id.
/// Returns all articles current present in view, as a list of dictionary
/// string ids.
QStringList getArticlesList();
/// Returns current article in the view, in the form of "gdfrom-xxx" id.
QString getCurrentArticle();
/// Sets the current article by executing a javascript code.
void setCurrentArticle( QString const & );
/// Attempts removing last temporary file created.
void cleanupTemp();