diff --git a/src/article-style.css b/src/article-style.css
index 99228b9f..8feb028d 100644
--- a/src/article-style.css
+++ b/src/article-style.css
@@ -323,6 +323,14 @@ div.sdct_x
margin-top: 1em;
}
+/************* Websites *****************/
+
+.website_padding
+{
+ height: 1em;
+ clear:both;
+}
+
/************* MediaWiki articles *****************
The following consist of excerpts from different .css files edited
with a .mwiki prepended to each record.
diff --git a/src/articleview.cc b/src/articleview.cc
index 15a7f98a..b317a907 100644
--- a/src/articleview.cc
+++ b/src/articleview.cc
@@ -174,6 +174,42 @@ void ArticleView::loadFinished( bool )
setCurrentArticle( url.fragment() );
}
+ // See if we have any iframes in need of expansion
+
+ QList< QWebFrame * > frames = ui.definition->page()->mainFrame()->childFrames();
+
+ bool wereFrames = false;
+
+ for( QList< QWebFrame * >::iterator i = frames.begin(); i != frames.end(); ++i )
+ {
+ if ( (*i)->frameName().startsWith( "gdexpandframe-" ) )
+ {
+ //printf( "Name: %s\n", (*i)->frameName().toUtf8().data() );
+ //printf( "Size: %d\n", (*i)->contentsSize().height() );
+ //printf( ">>>>>>>>Height = %s\n", (*i)->evaluateJavaScript( "document.body.offsetHeight;" ).toString().toUtf8().data() );
+
+ // Set the height
+ ui.definition->page()->mainFrame()->evaluateJavaScript( QString( "document.getElementById('%1').height = %2;" ).
+ arg( (*i)->frameName() ).
+ arg( (*i)->contentsSize().height() ) );
+
+ // Show it
+ ui.definition->page()->mainFrame()->evaluateJavaScript( QString( "document.getElementById('%1').style.display = 'block';" ).
+ arg( (*i)->frameName() ) );
+
+ wereFrames = true;
+ }
+ }
+
+ if ( wereFrames )
+ {
+ // There's some sort of glitch -- sometimes you need to move a mouse
+
+ QMouseEvent ev( QEvent::MouseMove, QPoint(), Qt::MouseButton(), 0, 0 );
+
+ qApp->sendEvent( ui.definition, &ev );
+ }
+
ui.definition->unsetCursor();
//QApplication::restoreOverrideCursor();
emit pageLoaded( this );
@@ -218,14 +254,14 @@ unsigned ArticleView::getGroup( QUrl const & url )
QStringList ArticleView::getArticlesList()
{
- return ui.definition->page()->currentFrame()->
+ return ui.definition->page()->mainFrame()->
evaluateJavaScript( "gdArticleContents;" ).toString().
trimmed().split( ' ', QString::SkipEmptyParts );
}
QString ArticleView::getCurrentArticle()
{
- QVariant v = ui.definition->page()->currentFrame()->evaluateJavaScript(
+ QVariant v = ui.definition->page()->mainFrame()->evaluateJavaScript(
QString( "gdCurrentArticle;" ) );
if ( v.type() == QVariant::String )
@@ -249,7 +285,7 @@ void ArticleView::setCurrentArticle( QString const & id, bool moveToIt )
}
ui.definition->history()->currentItem().setUserData( id );
- ui.definition->page()->currentFrame()->evaluateJavaScript(
+ ui.definition->page()->mainFrame()->evaluateJavaScript(
QString( "gdMakeArticleActive( '%1' );" ).arg( id.mid( 7 ) ) );
}
}
@@ -316,7 +352,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
{
if ( url.hasFragment() )
{
- ui.definition->page()->currentFrame()->evaluateJavaScript(
+ ui.definition->page()->mainFrame()->evaluateJavaScript(
QString( "window.location = \"%1\"" ).arg( QString::fromUtf8( url.toEncoded() ) ) );
}
else
@@ -440,13 +476,13 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
bool ArticleView::hasSound()
{
- return ui.definition->page()->currentFrame()->
+ return ui.definition->page()->mainFrame()->
evaluateJavaScript( "gdAudioLink;" ).type() == QVariant::String;
}
void ArticleView::playSound()
{
- QVariant v = ui.definition->page()->currentFrame()->evaluateJavaScript(
+ QVariant v = ui.definition->page()->mainFrame()->evaluateJavaScript(
QString( "gdAudioLink;" ) );
if ( v.type() == QVariant::String )
@@ -455,12 +491,12 @@ void ArticleView::playSound()
QString ArticleView::toHtml()
{
- return ui.definition->page()->currentFrame()->toHtml();
+ return ui.definition->page()->mainFrame()->toHtml();
}
QString ArticleView::getTitle()
{
- return ui.definition->page()->currentFrame()->title();
+ return ui.definition->page()->mainFrame()->title();
}
void ArticleView::print( QPrinter * printer ) const
@@ -472,7 +508,7 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
{
// Is that a link? Is there a selection?
- QWebHitTestResult r = ui.definition->page()->currentFrame()->
+ QWebHitTestResult r = ui.definition->page()->mainFrame()->
hitTestContent( pos );
QMenu menu( this );
@@ -803,14 +839,23 @@ void ArticleView::openSearch()
// Clear any current selection
if ( ui.definition->selectedText().size() )
{
- ui.definition->triggerPageAction( QWebPage::SelectAll );
- ui.definition->triggerPageAction( QWebPage::SelectStartOfDocument );
+ ui.definition->page()->currentFrame()->
+ evaluateJavaScript( "window.getSelection().removeAllRanges();" );
}
if ( ui.searchText->property( "noResults" ).toBool() )
{
ui.searchText->setProperty( "noResults", false );
- qApp->setStyleSheet( qApp->styleSheet() );
+
+ // Reload stylesheet
+ for( QWidget * w = parentWidget(); w; w = w->parentWidget() )
+ {
+ if ( w->styleSheet().size() )
+ {
+ w->setStyleSheet( w->styleSheet() );
+ break;
+ }
+ }
}
}
@@ -849,8 +894,8 @@ void ArticleView::performFindOperation( bool restart, bool backwards )
// For now we resort to this hack:
if ( ui.definition->selectedText().size() )
{
- ui.definition->triggerPageAction( QWebPage::SelectAll );
- ui.definition->triggerPageAction( QWebPage::SelectStartOfDocument );
+ ui.definition->page()->currentFrame()->
+ evaluateJavaScript( "window.getSelection().removeAllRanges();" );
}
}
@@ -867,7 +912,16 @@ void ArticleView::performFindOperation( bool restart, bool backwards )
if ( ui.searchText->property( "noResults" ).toBool() != setMark )
{
ui.searchText->setProperty( "noResults", setMark );
- qApp->setStyleSheet( qApp->styleSheet() );
+
+ // Reload stylesheet
+ for( QWidget * w = parentWidget(); w; w = w->parentWidget() )
+ {
+ if ( w->styleSheet().size() )
+ {
+ w->setStyleSheet( w->styleSheet() );
+ break;
+ }
+ }
}
}
diff --git a/src/articleview.ui b/src/articleview.ui
index 2d54ecfc..f235bd42 100644
--- a/src/articleview.ui
+++ b/src/articleview.ui
@@ -13,7 +13,7 @@
Form
-
+
0
@@ -43,6 +43,12 @@
-
+
+
+ 0
+ 0
+
+
QFrame::NoFrame
diff --git a/src/config.cc b/src/config.cc
index 00b3e1db..d6923385 100644
--- a/src/config.cc
+++ b/src/config.cc
@@ -126,6 +126,18 @@ MediaWikis makeDefaultMediaWikis( bool enable )
return mw;
}
+WebSites makeDefaultWebSites()
+{
+ WebSites ws;
+
+ ws.push_back( WebSite( "f376365a0de651fd7505e7e5e683aa45", "Urban Dictionary", "http://www.urbandictionary.com/define.php?term=%GDWORD%", false ) );
+ ws.push_back( WebSite( "324ca0306187df7511b26d3847f4b07c", "Multitran (En)", "http://multitran.ru/c/m.exe?CL=1&l1=1&s=%GD1251%", false ) );
+ ws.push_back( WebSite( "924db471b105299c82892067c0f10787", "Lingvo (En-Ru)", "http://www.abbyyonline.ru/translate.aspx?LingvoAction=translate&Ln=1&words=%GDWORD%", false ) );
+ ws.push_back( WebSite( "087a6d65615fb047f4c80eef0a9465db", "Michaelis (Pt-En)", "http://michaelis.uol.com.br/moderno/ingles/index.php?lingua=portugues-ingles&palavra=%GDISO1%", false ) );
+
+ return ws;
+}
+
/// Sets option to true of false if node is "1" or "0" respectively, or leaves
/// it intact if it's neither "1" nor "0".
void applyBoolOption( bool & option, QDomNode const & node )
@@ -225,6 +237,7 @@ Class load() throw( exError )
#endif
c.mediawikis = makeDefaultMediaWikis( true );
+ c.webSites = makeDefaultWebSites();
// Check if we have a template config file. If we do, load it instead
@@ -392,6 +405,32 @@ Class load() throw( exError )
c.mediawikis = makeDefaultMediaWikis( false );
}
+ QDomNode wss = root.namedItem( "websites" );
+
+ if ( !wss.isNull() )
+ {
+ QDomNodeList nl = wss.toElement().elementsByTagName( "website" );
+
+ for( unsigned x = 0; x < nl.length(); ++x )
+ {
+ QDomElement ws = nl.item( x ).toElement();
+
+ WebSite w;
+
+ w.id = ws.attribute( "id" );
+ w.name = ws.attribute( "name" );
+ w.url = ws.attribute( "url" );
+ w.enabled = ( ws.attribute( "enabled" ) == "1" );
+
+ c.webSites.push_back( w );
+ }
+ }
+ else
+ {
+ // Upgrading
+ c.webSites = makeDefaultWebSites();
+ }
+
QDomNode preferences = root.namedItem( "preferences" );
if ( !preferences.isNull() )
@@ -695,6 +734,33 @@ void save( Class const & c ) throw( exError )
}
}
+ {
+ QDomElement wss = dd.createElement( "websites" );
+ root.appendChild( wss );
+
+ for( WebSites::const_iterator i = c.webSites.begin(); i != c.webSites.end(); ++i )
+ {
+ QDomElement ws = dd.createElement( "website" );
+ wss.appendChild( ws );
+
+ QDomAttr id = dd.createAttribute( "id" );
+ id.setValue( i->id );
+ ws.setAttributeNode( id );
+
+ QDomAttr name = dd.createAttribute( "name" );
+ name.setValue( i->name );
+ ws.setAttributeNode( name );
+
+ QDomAttr url = dd.createAttribute( "url" );
+ url.setValue( i->url );
+ ws.setAttributeNode( url );
+
+ QDomAttr enabled = dd.createAttribute( "enabled" );
+ enabled.setValue( i->enabled ? "1" : "0" );
+ ws.setAttributeNode( enabled );
+ }
+ }
+
{
QDomElement preferences = dd.createElement( "preferences" );
root.appendChild( preferences );
diff --git a/src/config.hh b/src/config.hh
index ef926889..04364c34 100644
--- a/src/config.hh
+++ b/src/config.hh
@@ -180,6 +180,27 @@ struct MediaWiki
enabled == other.enabled; }
};
+/// Any website which can be queried though a simple template substitution
+struct WebSite
+{
+ QString id, name, url;
+ bool enabled;
+
+ WebSite(): enabled( false )
+ {}
+
+ WebSite( QString const & id_, QString const & name_, QString const & url_,
+ bool enabled_ ):
+ id( id_ ), name( name_ ), url( url_ ), enabled( enabled_ ) {}
+
+ bool operator == ( WebSite const & other ) const
+ { return id == other.id && name == other.name && url == other.url &&
+ enabled == other.enabled; }
+};
+
+/// All the WebSites
+typedef vector< WebSite > WebSites;
+
/// Hunspell configuration
struct Hunspell
{
@@ -256,6 +277,7 @@ struct Class
Groups groups;
Preferences preferences;
MediaWikis mediawikis;
+ WebSites webSites;
Hunspell hunspell;
Transliteration transliteration;
diff --git a/src/editdictionaries.cc b/src/editdictionaries.cc
index ee398da7..0e79de0a 100644
--- a/src/editdictionaries.cc
+++ b/src/editdictionaries.cc
@@ -16,7 +16,7 @@ EditDictionaries::EditDictionaries( QWidget * parent, Config::Class & cfg_,
dictNetMgr( dictNetMgr_ ),
origCfg( cfg ),
sources( this, cfg.paths, cfg.soundDirs, cfg.hunspell, cfg.transliteration,
- cfg.mediawikis ),
+ cfg.mediawikis, cfg.webSites ),
groups( new Groups( this, dictionaries, cfg.groups ) ),
dictionariesChanged( false ),
groupsChanged( false ),
@@ -105,7 +105,8 @@ bool EditDictionaries::isSourcesChanged() const
sources.getSoundDirs() != cfg.soundDirs ||
sources.getHunspell() != cfg.hunspell ||
sources.getTransliteration() != cfg.transliteration ||
- sources.getMediaWikis() != cfg.mediawikis;
+ sources.getMediaWikis() != cfg.mediawikis ||
+ sources.getWebSites() != cfg.webSites;
}
void EditDictionaries::acceptChangedSources( bool rebuildGroups )
@@ -119,7 +120,8 @@ void EditDictionaries::acceptChangedSources( bool rebuildGroups )
cfg.hunspell = sources.getHunspell();
cfg.transliteration = sources.getTransliteration();
cfg.mediawikis = sources.getMediaWikis();
-
+ cfg.webSites = sources.getWebSites();
+
groupInstances.clear(); // Those hold pointers to dictionaries, we need to
// free them.
diff --git a/src/goldendict.pro b/src/goldendict.pro
index acec0289..500e6568 100644
--- a/src/goldendict.pro
+++ b/src/goldendict.pro
@@ -1,259 +1,261 @@
-# #####################################################################
-# Automatically generated by qmake (2.01a) ?? ????. 2 18:38:07 2008
-# #####################################################################
-TEMPLATE = app
-TARGET = goldendict
-VERSION = 0.8.0+svn
-
-# DEPENDPATH += . generators
-INCLUDEPATH += .
-QT += webkit
-QT += xml
-QT += network
-CONFIG += exceptions \
- rtti \
- stl
-OBJECTS_DIR = build
-UI_DIR = build
-MOC_DIR = build
-RCC_DIR = build
-LIBS += -lvorbisfile \
- -lvorbis \
- -logg \
- -lz \
- -lhunspell-1.2
-win32 {
- LIBS += -liconv \
- -lwsock32 \
- -lwinmm \
- -lpsapi
- RC_FILE = goldendict.rc
- INCLUDEPATH += winlibs/include
- LIBS += -Lwinlibs/lib
-}
-unix {
- LIBS += -lXtst
- PREFIX = $$(PREFIX)
- isEmpty( PREFIX ):PREFIX = /usr/local
- DEFINES += PROGRAM_DATA_DIR=\\\"$$PREFIX/share/apps/goldendict/\\\"
- target.path = $$PREFIX/bin/
- locale.path = $$PREFIX/share/apps/goldendict/locale/
- locale.files = locale/*.qm
- INSTALLS += target \
- locale
- icons.path = /usr/share/pixmaps
- icons.files = redist/icons/*.*
- INSTALLS += icons
- icons2.path = /usr/share/app-install/icons
- icons2.files = redist/icons/*.*
- INSTALLS += icons2
- desktops.path = /usr/share/applications
- desktops.files = redist/*.desktop
- INSTALLS += desktops
- desktops2.path = /usr/share/app-install/desktop
- desktops2.files = redist/*.desktop
- INSTALLS += desktops2
-}
-DEFINES += PROGRAM_VERSION=\\\"$$VERSION\\\"
-
-# Input
-HEADERS += folding.hh \
- inc_case_folding.hh \
- inc_diacritic_folding.hh \
- mainwindow.hh \
- sptr.hh \
- dictionary.hh \
- ex.hh \
- config.hh \
- sources.hh \
- utf8.hh \
- file.hh \
- bgl_babylon.hh \
- bgl.hh \
- initializing.hh \
- article_netmgr.hh \
- dictzip.h \
- btreeidx.hh \
- stardict.hh \
- chunkedstorage.hh \
- xdxf2html.hh \
- iconv.hh \
- lsa.hh \
- htmlescape.hh \
- dsl.hh \
- dsl_details.hh \
- filetype.hh \
- fsencoding.hh \
- groups.hh \
- groups_widgets.hh \
- instances.hh \
- article_maker.hh \
- scanpopup.hh \
- articleview.hh \
- externalviewer.hh \
- wordfinder.hh \
- groupcombobox.hh \
- keyboardstate.hh \
- mouseover.hh \
- preferences.hh \
- mutex.hh \
- mediawiki.hh \
- sounddir.hh \
- hunspell.hh \
- dictdfiles.hh \
- audiolink.hh \
- wstring.hh \
- wstring_qt.hh \
- processwrapper.hh \
- hotkeywrapper.hh \
- searchpanewidget.hh \
- hotkeyedit.hh \
- langcoder.hh \
- editdictionaries.hh \
- loaddictionaries.hh \
- transliteration.hh \
- romaji.hh \
- russiantranslit.hh \
- german.hh
-FORMS += groups.ui \
- dictgroupwidget.ui \
- mainwindow.ui \
- sources.ui \
- initializing.ui \
- groupselectorwidget.ui \
- scanpopup.ui \
- articleview.ui \
- preferences.ui \
- about.ui \
- editdictionaries.ui
-SOURCES += folding.cc \
- main.cc \
- dictionary.cc \
- config.cc \
- sources.cc \
- mainwindow.cc \
- utf8.cc \
- file.cc \
- bgl_babylon.cc \
- bgl.cc \
- initializing.cc \
- article_netmgr.cc \
- dictzip.c \
- btreeidx.cc \
- stardict.cc \
- chunkedstorage.cc \
- xdxf2html.cc \
- iconv.cc \
- lsa.cc \
- htmlescape.cc \
- dsl.cc \
- dsl_details.cc \
- filetype.cc \
- fsencoding.cc \
- groups.cc \
- groups_widgets.cc \
- instances.cc \
- article_maker.cc \
- scanpopup.cc \
- articleview.cc \
- externalviewer.cc \
- wordfinder.cc \
- groupcombobox.cc \
- keyboardstate.cc \
- mouseover.cc \
- preferences.cc \
- mutex.cc \
- mediawiki.cc \
- sounddir.cc \
- hunspell.cc \
- dictdfiles.cc \
- audiolink.cc \
- wstring.cc \
- wstring_qt.cc \
- processwrapper.cc \
- hotkeywrapper.cc \
- hotkeyedit.cc \
- langcoder.cc \
- editdictionaries.cc \
- loaddictionaries.cc \
- transliteration.cc \
- romaji.cc \
- russiantranslit.cc \
- german.cc
-win32 {
- SOURCES += mouseover_win32/ThTypes.c
- HEADERS += mouseover_win32/ThTypes.h
-}
-RESOURCES += resources.qrc \
- flags.qrc
-TRANSLATIONS += locale/ru.ts
-
-# This makes qmake generate translations
-isEmpty(QMAKE_LRELEASE):QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
-TS_OUT = $$TRANSLATIONS
-TS_OUT ~= s/.ts/.qm
-TSQM.name = lrelease \
- ${QMAKE_FILE_IN}
-TSQM.input = TRANSLATIONS
-TSQM.output = $$TS_OUT
-TSQM.commands = $$QMAKE_LRELEASE \
- ${QMAKE_FILE_IN}
-TSQM.CONFIG = no_link
-QMAKE_EXTRA_COMPILERS += TSQM
-PRE_TARGETDEPS += $$TS_OUT
-
-# LibZip
-SOURCES += libzip/mkstemp.c \
- libzip/zip_add.c \
- libzip/zip_add_dir.c \
- libzip/zip_close.c \
- libzip/zip_delete.c \
- libzip/zip_dirent.c \
- libzip/zip_entry_free.c \
- libzip/zip_entry_new.c \
- libzip/zip_error.c \
- libzip/zip_error_clear.c \
- libzip/zip_error_get.c \
- libzip/zip_error_get_sys_type.c \
- libzip/zip_error_strerror.c \
- libzip/zip_error_to_str.c \
- libzip/zip_err_str.c \
- libzip/zip_fclose.c \
- libzip/zip_file_error_clear.c \
- libzip/zip_file_error_get.c \
- libzip/zip_file_get_offset.c \
- libzip/zip_filerange_crc.c \
- libzip/zip_file_strerror.c \
- libzip/zip_fopen.c \
- libzip/zip_fopen_index.c \
- libzip/zip_fread.c \
- libzip/zip_free.c \
- libzip/zip_get_archive_comment.c \
- libzip/zip_get_archive_flag.c \
- libzip/zip_get_file_comment.c \
- libzip/zip_get_name.c \
- libzip/zip_get_num_files.c \
- libzip/zip_memdup.c \
- libzip/zip_name_locate.c \
- libzip/zip_new.c \
- libzip/zip_open.c \
- libzip/zip_rename.c \
- libzip/zip_replace.c \
- libzip/zip_set_archive_comment.c \
- libzip/zip_set_archive_flag.c \
- libzip/zip_set_file_comment.c \
- libzip/zip_set_name.c \
- libzip/zip_source_buffer.c \
- libzip/zip_source_file.c \
- libzip/zip_source_filep.c \
- libzip/zip_source_free.c \
- libzip/zip_source_function.c \
- libzip/zip_source_zip.c \
- libzip/zip_stat.c \
- libzip/zip_stat_index.c \
- libzip/zip_stat_init.c \
- libzip/zip_strerror.c \
- libzip/zip_unchange_all.c \
- libzip/zip_unchange_archive.c \
- libzip/zip_unchange.c \
- libzip/zip_unchange_data.c
+# #####################################################################
+# Automatically generated by qmake (2.01a) ?? ????. 2 18:38:07 2008
+# #####################################################################
+TEMPLATE = app
+TARGET = goldendict
+VERSION = 0.8.0+svn
+
+# DEPENDPATH += . generators
+INCLUDEPATH += .
+QT += webkit
+QT += xml
+QT += network
+CONFIG += exceptions \
+ rtti \
+ stl
+OBJECTS_DIR = build
+UI_DIR = build
+MOC_DIR = build
+RCC_DIR = build
+LIBS += -lvorbisfile \
+ -lvorbis \
+ -logg \
+ -lz \
+ -lhunspell-1.2
+win32 {
+ LIBS += -liconv \
+ -lwsock32 \
+ -lwinmm \
+ -lpsapi
+ RC_FILE = goldendict.rc
+ INCLUDEPATH += winlibs/include
+ LIBS += -Lwinlibs/lib
+}
+unix {
+ LIBS += -lXtst
+ PREFIX = $$(PREFIX)
+ isEmpty( PREFIX ):PREFIX = /usr/local
+ DEFINES += PROGRAM_DATA_DIR=\\\"$$PREFIX/share/apps/goldendict/\\\"
+ target.path = $$PREFIX/bin/
+ locale.path = $$PREFIX/share/apps/goldendict/locale/
+ locale.files = locale/*.qm
+ INSTALLS += target \
+ locale
+ icons.path = /usr/share/pixmaps
+ icons.files = redist/icons/*.*
+ INSTALLS += icons
+ icons2.path = /usr/share/app-install/icons
+ icons2.files = redist/icons/*.*
+ INSTALLS += icons2
+ desktops.path = /usr/share/applications
+ desktops.files = redist/*.desktop
+ INSTALLS += desktops
+ desktops2.path = /usr/share/app-install/desktop
+ desktops2.files = redist/*.desktop
+ INSTALLS += desktops2
+}
+DEFINES += PROGRAM_VERSION=\\\"$$VERSION\\\"
+
+# Input
+HEADERS += folding.hh \
+ inc_case_folding.hh \
+ inc_diacritic_folding.hh \
+ mainwindow.hh \
+ sptr.hh \
+ dictionary.hh \
+ ex.hh \
+ config.hh \
+ sources.hh \
+ utf8.hh \
+ file.hh \
+ bgl_babylon.hh \
+ bgl.hh \
+ initializing.hh \
+ article_netmgr.hh \
+ dictzip.h \
+ btreeidx.hh \
+ stardict.hh \
+ chunkedstorage.hh \
+ xdxf2html.hh \
+ iconv.hh \
+ lsa.hh \
+ htmlescape.hh \
+ dsl.hh \
+ dsl_details.hh \
+ filetype.hh \
+ fsencoding.hh \
+ groups.hh \
+ groups_widgets.hh \
+ instances.hh \
+ article_maker.hh \
+ scanpopup.hh \
+ articleview.hh \
+ externalviewer.hh \
+ wordfinder.hh \
+ groupcombobox.hh \
+ keyboardstate.hh \
+ mouseover.hh \
+ preferences.hh \
+ mutex.hh \
+ mediawiki.hh \
+ sounddir.hh \
+ hunspell.hh \
+ dictdfiles.hh \
+ audiolink.hh \
+ wstring.hh \
+ wstring_qt.hh \
+ processwrapper.hh \
+ hotkeywrapper.hh \
+ searchpanewidget.hh \
+ hotkeyedit.hh \
+ langcoder.hh \
+ editdictionaries.hh \
+ loaddictionaries.hh \
+ transliteration.hh \
+ romaji.hh \
+ russiantranslit.hh \
+ german.hh \
+ website.hh
+FORMS += groups.ui \
+ dictgroupwidget.ui \
+ mainwindow.ui \
+ sources.ui \
+ initializing.ui \
+ groupselectorwidget.ui \
+ scanpopup.ui \
+ articleview.ui \
+ preferences.ui \
+ about.ui \
+ editdictionaries.ui
+SOURCES += folding.cc \
+ main.cc \
+ dictionary.cc \
+ config.cc \
+ sources.cc \
+ mainwindow.cc \
+ utf8.cc \
+ file.cc \
+ bgl_babylon.cc \
+ bgl.cc \
+ initializing.cc \
+ article_netmgr.cc \
+ dictzip.c \
+ btreeidx.cc \
+ stardict.cc \
+ chunkedstorage.cc \
+ xdxf2html.cc \
+ iconv.cc \
+ lsa.cc \
+ htmlescape.cc \
+ dsl.cc \
+ dsl_details.cc \
+ filetype.cc \
+ fsencoding.cc \
+ groups.cc \
+ groups_widgets.cc \
+ instances.cc \
+ article_maker.cc \
+ scanpopup.cc \
+ articleview.cc \
+ externalviewer.cc \
+ wordfinder.cc \
+ groupcombobox.cc \
+ keyboardstate.cc \
+ mouseover.cc \
+ preferences.cc \
+ mutex.cc \
+ mediawiki.cc \
+ sounddir.cc \
+ hunspell.cc \
+ dictdfiles.cc \
+ audiolink.cc \
+ wstring.cc \
+ wstring_qt.cc \
+ processwrapper.cc \
+ hotkeywrapper.cc \
+ hotkeyedit.cc \
+ langcoder.cc \
+ editdictionaries.cc \
+ loaddictionaries.cc \
+ transliteration.cc \
+ romaji.cc \
+ russiantranslit.cc \
+ german.cc \
+ website.cc
+win32 {
+ SOURCES += mouseover_win32/ThTypes.c
+ HEADERS += mouseover_win32/ThTypes.h
+}
+RESOURCES += resources.qrc \
+ flags.qrc
+TRANSLATIONS += locale/ru.ts
+
+# This makes qmake generate translations
+isEmpty(QMAKE_LRELEASE):QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
+TS_OUT = $$TRANSLATIONS
+TS_OUT ~= s/.ts/.qm
+TSQM.name = lrelease \
+ ${QMAKE_FILE_IN}
+TSQM.input = TRANSLATIONS
+TSQM.output = $$TS_OUT
+TSQM.commands = $$QMAKE_LRELEASE \
+ ${QMAKE_FILE_IN}
+TSQM.CONFIG = no_link
+QMAKE_EXTRA_COMPILERS += TSQM
+PRE_TARGETDEPS += $$TS_OUT
+
+# LibZip
+SOURCES += libzip/mkstemp.c \
+ libzip/zip_add.c \
+ libzip/zip_add_dir.c \
+ libzip/zip_close.c \
+ libzip/zip_delete.c \
+ libzip/zip_dirent.c \
+ libzip/zip_entry_free.c \
+ libzip/zip_entry_new.c \
+ libzip/zip_error.c \
+ libzip/zip_error_clear.c \
+ libzip/zip_error_get.c \
+ libzip/zip_error_get_sys_type.c \
+ libzip/zip_error_strerror.c \
+ libzip/zip_error_to_str.c \
+ libzip/zip_err_str.c \
+ libzip/zip_fclose.c \
+ libzip/zip_file_error_clear.c \
+ libzip/zip_file_error_get.c \
+ libzip/zip_file_get_offset.c \
+ libzip/zip_filerange_crc.c \
+ libzip/zip_file_strerror.c \
+ libzip/zip_fopen.c \
+ libzip/zip_fopen_index.c \
+ libzip/zip_fread.c \
+ libzip/zip_free.c \
+ libzip/zip_get_archive_comment.c \
+ libzip/zip_get_archive_flag.c \
+ libzip/zip_get_file_comment.c \
+ libzip/zip_get_name.c \
+ libzip/zip_get_num_files.c \
+ libzip/zip_memdup.c \
+ libzip/zip_name_locate.c \
+ libzip/zip_new.c \
+ libzip/zip_open.c \
+ libzip/zip_rename.c \
+ libzip/zip_replace.c \
+ libzip/zip_set_archive_comment.c \
+ libzip/zip_set_archive_flag.c \
+ libzip/zip_set_file_comment.c \
+ libzip/zip_set_name.c \
+ libzip/zip_source_buffer.c \
+ libzip/zip_source_file.c \
+ libzip/zip_source_filep.c \
+ libzip/zip_source_free.c \
+ libzip/zip_source_function.c \
+ libzip/zip_source_zip.c \
+ libzip/zip_stat.c \
+ libzip/zip_stat_index.c \
+ libzip/zip_stat_init.c \
+ libzip/zip_strerror.c \
+ libzip/zip_unchange_all.c \
+ libzip/zip_unchange_archive.c \
+ libzip/zip_unchange.c \
+ libzip/zip_unchange_data.c
diff --git a/src/icons/internet.png b/src/icons/internet.png
new file mode 100644
index 00000000..4ddadd60
Binary files /dev/null and b/src/icons/internet.png differ
diff --git a/src/loaddictionaries.cc b/src/loaddictionaries.cc
index 0f51a185..99516688 100644
--- a/src/loaddictionaries.cc
+++ b/src/loaddictionaries.cc
@@ -14,6 +14,7 @@
#include "romaji.hh"
#include "russiantranslit.hh"
#include "german.hh"
+#include "website.hh"
#include
#include
@@ -191,6 +192,14 @@ void loadDictionaries( QWidget * parent, bool showInitially,
dictionaries.insert( dictionaries.end(), dicts.begin(), dicts.end() );
}
+ ///// WebSites are very simple, no need to create them asyncronously
+ {
+ vector< sptr< Dictionary::Class > > dicts =
+ WebSite::makeDictionaries( cfg.webSites );
+
+ dictionaries.insert( dictionaries.end(), dicts.begin(), dicts.end() );
+ }
+
// Remove any stale index files
set< string > ids;
diff --git a/src/main.cc b/src/main.cc
index 9ebb2f35..68ad3940 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -97,9 +97,6 @@ int main( int argc, char ** argv )
translator.load( QString( Config::getProgramDataDir() ) + "/locale/" + localeName );
app.installTranslator( &translator );
- // Apply qt stylesheet
- MainWindow::applyQtStyleSheet( cfg.preferences.displayStyle );
-
MainWindow m( cfg );
int r = app.exec();
diff --git a/src/mainwindow.cc b/src/mainwindow.cc
index 072e70c8..bbdf7574 100644
--- a/src/mainwindow.cc
+++ b/src/mainwindow.cc
@@ -39,6 +39,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
wordFinder( this ),
newReleaseCheckTimer( this )
{
+ applyQtStyleSheet( cfg.preferences.displayStyle );
+
ui.setupUi( this );
// Make the search pane's titlebar
@@ -299,7 +301,7 @@ void MainWindow::applyQtStyleSheet( QString const & displayStyle )
if ( cssFile.open( QFile::ReadOnly ) )
css += cssFile.readAll();
- qApp->setStyleSheet( css );
+ setStyleSheet( css );
}
void MainWindow::updateTrayIcon()
@@ -458,6 +460,8 @@ void MainWindow::makeScanPopup()
scanPopup = new ScanPopup( 0, cfg, articleNetMgr, dictionaries, groupInstances );
+ scanPopup->setStyleSheet( styleSheet() );
+
if ( cfg.preferences.enableScanPopup && enableScanPopup->isChecked() )
scanPopup->enableScanning();
}
@@ -719,7 +723,7 @@ void MainWindow::translateInputChanged( QString const & newValue )
if ( ui.translateLine->property( "noResults" ).toBool() )
{
ui.translateLine->setProperty( "noResults", false );
- qApp->setStyleSheet( qApp->styleSheet() );
+ setStyleSheet( styleSheet() );
}
return;
}
@@ -836,7 +840,7 @@ void MainWindow::updateMatchResults( bool finished )
if ( ui.translateLine->property( "noResults" ).toBool() != setMark )
{
ui.translateLine->setProperty( "noResults", setMark );
- qApp->setStyleSheet( qApp->styleSheet() );
+ setStyleSheet( styleSheet() );
}
if ( !wordFinder.getErrorString().isEmpty() )
diff --git a/src/mainwindow.hh b/src/mainwindow.hh
index b700895f..2f69175e 100644
--- a/src/mainwindow.hh
+++ b/src/mainwindow.hh
@@ -33,9 +33,6 @@ public:
MainWindow( Config::Class & cfg );
~MainWindow();
- /// Applies the qt's stylesheet, given the style's name.
- static void applyQtStyleSheet( QString const & displayStyle );
-
private:
QSystemTrayIcon * trayIcon;
@@ -77,6 +74,9 @@ private:
QPrinter printer; // The printer we use for all printing operations
+ /// Applies the qt's stylesheet, given the style's name.
+ void applyQtStyleSheet( QString const & displayStyle );
+
/// Creates, destroys or otherwise updates tray icon, according to the
/// current configuration and situation.
void updateTrayIcon();
diff --git a/src/resources.qrc b/src/resources.qrc
index 0163770b..550030ba 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -36,5 +36,6 @@
icons/bookcase.png
qt-style-st-lingvo.css
article-style-st-lingvo.css
+ icons/internet.png
diff --git a/src/sources.cc b/src/sources.cc
index 5a7c8546..391742b6 100644
--- a/src/sources.cc
+++ b/src/sources.cc
@@ -11,8 +11,11 @@ Sources::Sources( QWidget * parent, Config::Paths const & paths,
Config::SoundDirs const & soundDirs,
Config::Hunspell const & hunspell,
Config::Transliteration const & tr,
- Config::MediaWikis const & mediawikis ): QWidget( parent ),
- mediawikisModel( this, mediawikis ), pathsModel( this, paths ),
+ Config::MediaWikis const & mediawikis,
+ Config::WebSites const & webSites ): QWidget( parent ),
+ mediawikisModel( this, mediawikis ),
+ webSitesModel( this, webSites ),
+ pathsModel( this, paths ),
soundDirsModel( this, soundDirs ),
hunspellDictsModel( this, hunspell )
{
@@ -24,6 +27,12 @@ Sources::Sources( QWidget * parent, Config::Paths const & paths,
ui.mediaWikis->resizeColumnToContents( 1 );
ui.mediaWikis->resizeColumnToContents( 2 );
+ ui.webSites->setTabKeyNavigation( true );
+ ui.webSites->setModel( &webSitesModel );
+ ui.webSites->resizeColumnToContents( 0 );
+ ui.webSites->resizeColumnToContents( 1 );
+ ui.webSites->resizeColumnToContents( 2 );
+
ui.paths->setTabKeyNavigation( true );
ui.paths->setModel( &pathsModel );
@@ -159,6 +168,30 @@ void Sources::on_removeMediaWiki_clicked()
mediawikisModel.removeWiki( current.row() );
}
+void Sources::on_addWebSite_clicked()
+{
+ webSitesModel.addNewSite();
+
+ QModelIndex result =
+ webSitesModel.index( webSitesModel.rowCount( QModelIndex() ) - 1,
+ 1, QModelIndex() );
+
+ ui.webSites->scrollTo( result );
+ ui.webSites->edit( result );
+}
+
+void Sources::on_removeWebSite_clicked()
+{
+ QModelIndex current = ui.webSites->currentIndex();
+
+ if ( current.isValid() &&
+ QMessageBox::question( this, tr( "Confirm removal" ),
+ tr( "Remove site %1 from the list?" ).arg( webSitesModel.getCurrentWebSites()[ current.row() ].name ),
+ QMessageBox::Ok,
+ QMessageBox::Cancel ) == QMessageBox::Ok )
+ webSitesModel.removeSite( current.row() );
+}
+
Config::Hunspell Sources::getHunspell() const
{
Config::Hunspell h;
@@ -337,6 +370,160 @@ bool MediaWikisModel::setData( QModelIndex const & index, const QVariant & value
return false;
}
+
+////////// WebSitesModel
+
+WebSitesModel::WebSitesModel( QWidget * parent,
+ Config::WebSites const & webSites_ ):
+ QAbstractItemModel( parent ), webSites( webSites_ )
+{
+}
+void WebSitesModel::removeSite( int index )
+{
+ beginRemoveRows( QModelIndex(), index, index );
+ webSites.erase( webSites.begin() + index );
+ endRemoveRows();
+}
+
+void WebSitesModel::addNewSite()
+{
+ Config::WebSite w;
+
+ w.enabled = false;
+
+ // That's quite some rng
+ w.id = QString(
+ QCryptographicHash::hash(
+ QDateTime::currentDateTime().toString( "\"WebSite\"dd.MM.yyyy hh:mm:ss.zzz" ).toUtf8(),
+ QCryptographicHash::Md5 ).toHex() );
+
+ w.url = "http://";
+
+ beginInsertRows( QModelIndex(), webSites.size(), webSites.size() );
+ webSites.push_back( w );
+ endInsertRows();
+}
+
+QModelIndex WebSitesModel::index( int row, int column, QModelIndex const & /*parent*/ ) const
+{
+ return createIndex( row, column, 0 );
+}
+
+QModelIndex WebSitesModel::parent( QModelIndex const & /*parent*/ ) const
+{
+ return QModelIndex();
+}
+
+Qt::ItemFlags WebSitesModel::flags( QModelIndex const & index ) const
+{
+ Qt::ItemFlags result = QAbstractItemModel::flags( index );
+
+ if ( index.isValid() )
+ {
+ if ( !index.column() )
+ result |= Qt::ItemIsUserCheckable;
+ else
+ result |= Qt::ItemIsEditable;
+ }
+
+ return result;
+}
+
+int WebSitesModel::rowCount( QModelIndex const & parent ) const
+{
+ if ( parent.isValid() )
+ return 0;
+ else
+ return webSites.size();
+}
+
+int WebSitesModel::columnCount( QModelIndex const & parent ) const
+{
+ if ( parent.isValid() )
+ return 0;
+ else
+ return 3;
+}
+
+QVariant WebSitesModel::headerData( int section, Qt::Orientation /*orientation*/, int role ) const
+{
+ if ( role == Qt::DisplayRole )
+ switch( section )
+ {
+ case 0:
+ return tr( "Enabled" );
+ case 1:
+ return tr( "Name" );
+ case 2:
+ return tr( "Address" );
+ default:
+ return QVariant();
+ }
+
+ return QVariant();
+}
+
+QVariant WebSitesModel::data( QModelIndex const & index, int role ) const
+{
+ if ( (unsigned)index.row() >= webSites.size() )
+ return QVariant();
+
+ if ( role == Qt::DisplayRole || role == Qt::EditRole )
+ {
+ switch( index.column() )
+ {
+ case 1:
+ return webSites[ index.row() ].name;
+ case 2:
+ return webSites[ index.row() ].url;
+ default:
+ return QVariant();
+ }
+ }
+
+ if ( role == Qt::CheckStateRole && !index.column() )
+ return webSites[ index.row() ].enabled;
+
+ return QVariant();
+}
+
+bool WebSitesModel::setData( QModelIndex const & index, const QVariant & value,
+ int role )
+{
+ if ( (unsigned)index.row() >= webSites.size() )
+ return false;
+
+ if ( role == Qt::CheckStateRole && !index.column() )
+ {
+ //printf( "type = %d\n", (int)value.type() );
+ //printf( "value = %d\n", (int)value.toInt() );
+
+ // XXX it seems to be always passing Int( 2 ) as a value, so we just toggle
+ webSites[ index.row() ].enabled = !webSites[ index.row() ].enabled;
+
+ dataChanged( index, index );
+ return true;
+ }
+
+ if ( role == Qt::DisplayRole || role == Qt::EditRole )
+ switch( index.column() )
+ {
+ case 1:
+ webSites[ index.row() ].name = value.toString();
+ dataChanged( index, index );
+ return true;
+ case 2:
+ webSites[ index.row() ].url = value.toString();
+ dataChanged( index, index );
+ return true;
+ default:
+ return false;
+ }
+
+ return false;
+}
+
+
////////// PathsModel
PathsModel::PathsModel( QWidget * parent,
diff --git a/src/sources.hh b/src/sources.hh
index 3b927e93..98e78a76 100644
--- a/src/sources.hh
+++ b/src/sources.hh
@@ -39,6 +39,36 @@ private:
Config::MediaWikis mediawikis;
};
+/// A model to be projected into the webSites view, according to Qt's MVC model
+class WebSitesModel: public QAbstractItemModel
+{
+ Q_OBJECT
+
+public:
+
+ WebSitesModel( QWidget * parent, Config::WebSites const & );
+
+ void removeSite( int index );
+ void addNewSite();
+
+ /// Returns the sites the model currently has listed
+ Config::WebSites const & getCurrentWebSites() const
+ { return webSites; }
+
+ QModelIndex index( int row, int column, QModelIndex const & parent ) const;
+ QModelIndex parent( QModelIndex const & parent ) const;
+ Qt::ItemFlags flags( QModelIndex const & index ) const;
+ int rowCount( QModelIndex const & parent ) const;
+ int columnCount( QModelIndex const & parent ) const;
+ QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
+ QVariant data( QModelIndex const & index, int role ) const;
+ bool setData( QModelIndex const & index, const QVariant & value, int role );
+
+private:
+
+ Config::WebSites webSites;
+};
+
/// A model to be projected into the paths view, according to Qt's MVC model
class PathsModel: public QAbstractItemModel
{
@@ -139,7 +169,8 @@ public:
Config::SoundDirs const &,
Config::Hunspell const &,
Config::Transliteration const &,
- Config::MediaWikis const & );
+ Config::MediaWikis const &,
+ Config::WebSites const & );
Config::Paths const & getPaths() const
{ return pathsModel.getCurrentPaths(); }
@@ -150,6 +181,9 @@ public:
Config::MediaWikis const & getMediaWikis() const
{ return mediawikisModel.getCurrentWikis(); }
+ Config::WebSites const & getWebSites() const
+ { return webSitesModel.getCurrentWebSites(); }
+
Config::Hunspell getHunspell() const;
Config::Transliteration getTransliteration() const;
@@ -162,6 +196,7 @@ signals:
private:
Ui::Sources ui;
MediaWikisModel mediawikisModel;
+ WebSitesModel webSitesModel;
PathsModel pathsModel;
SoundDirsModel soundDirsModel;
HunspellDictsModel hunspellDictsModel;
@@ -183,6 +218,9 @@ private slots:
void on_addMediaWiki_clicked();
void on_removeMediaWiki_clicked();
+ void on_addWebSite_clicked();
+ void on_removeWebSite_clicked();
+
void on_rescan_clicked();
};
diff --git a/src/sources.ui b/src/sources.ui
index 6b938304..c2e61d72 100644
--- a/src/sources.ui
+++ b/src/sources.ui
@@ -1,464 +1,527 @@
-
-
- Sources
-
-
-
- 0
- 0
- 578
- 336
-
-
-
- Sources
-
-
-
-
-
-
- 0
-
-
-
- 15
- 15
-
-
-
-
-
- :/icons/filesave.png:/icons/filesave.png
-
-
- Files
-
-
-
-
-
-
- Paths to search for the dictionary files:
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- &Add...
-
-
-
- -
-
-
- &Remove
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 17
- 68
-
-
-
-
- -
-
-
- Re&scan now
-
-
-
-
-
-
-
-
-
-
-
-
- :/icons/fileopen.png:/icons/fileopen.png
-
-
- Sound Dirs
-
-
- -
-
-
- Make dictionaries from bunches of audiofiles by adding paths here:
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- &Add...
-
-
-
- -
-
-
- &Remove
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
-
-
-
-
-
- :/icons/icon32_hunspell.png:/icons/icon32_hunspell.png
-
-
- Morphology
-
-
- -
-
-
- Path to a directory with Hunspell/Myspell dictionaries:
-
-
-
- -
-
-
-
-
-
- true
-
-
-
- -
-
-
- &Change...
-
-
-
-
-
- -
-
-
- Available morphology dictionaries:
-
-
-
- -
-
-
-
-
-
- -
-
-
- Each morphology dictionary appears as a
-separate auxiliary dictionary which
-provides stem words for searches and
-spelling suggestions for mistyped words.
-Add appropriate dictionaries to the bottoms
-of the appropriate groups to use them.
-
-
- Qt::PlainText
-
-
- false
-
-
-
-
-
-
-
-
-
-
- :/icons/icon32_wiki.png:/icons/icon32_wiki.png
-
-
- Wikipedia
-
-
- -
-
-
- Wikipedia (MediaWiki) sites:
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- &Add...
-
-
-
- -
-
-
- &Remove
-
-
-
- -
-
-
- Qt::Vertical
-
-
- QSizePolicy::Expanding
-
-
-
- 20
- 40
-
-
-
-
-
-
-
-
-
-
-
-
- Transliteration
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Russian transliteration
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- German transliteration
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 40
-
-
-
-
- -
-
-
- Enables to use the Latin alphabet to write the Japanese language
-
-
- Japanese Romaji
-
-
- true
-
-
- true
-
-
-
-
-
-
- Systems:
-
-
-
- -
-
-
- The most widely used method of transcription of Japanese,
-based on English phonology
-
-
- Hepburn
-
-
-
- -
-
-
- The most regular system, having a one-to-one relation to the
-kana writing systems. Standardized as ISO 3602
-
-
- Nihon-shiki
-
-
-
- -
-
-
- Based on Nihon-shiki system, but modified for modern standard Japanese.
-Standardized as ISO 3602
-
-
- Kunrei-shiki
-
-
-
- -
-
-
- Syllabaries:
-
-
-
- -
-
-
- Hiragana Japanese syllabary
-
-
- Hiragana
-
-
-
- -
-
-
- Hiragana Japanese syllabary
-
-
- Katakana
-
-
-
-
-
-
- -
-
-
- Qt::Vertical
-
-
-
- 20
- 80
-
-
-
-
-
-
-
-
-
-
-
- enableRussianTransliteration
- enableGermanTransliteration
- enableRomaji
- enableHepburn
- enableNihonShiki
- enableKunreiShiki
- enableHiragana
- enableKatakana
- hunspellPath
- changeHunspellPath
- hunspellDictionaries
- mediaWikis
- addMediaWiki
- removeMediaWiki
- tabWidget
- addPath
- removePath
- rescan
- soundDirs
- addSoundDir
- removeSoundDir
- paths
-
-
-
-
-
-
+
+
+ Sources
+
+
+
+ 0
+ 0
+ 578
+ 336
+
+
+
+ Sources
+
+
+ -
+
+
+ 0
+
+
+
+ 15
+ 15
+
+
+
+
+
+ :/icons/filesave.png:/icons/filesave.png
+
+
+ Files
+
+
+
-
+
+
+ Paths to search for the dictionary files:
+
+
+
+ -
+
+
-
+
+
+ -
+
+
-
+
+
+ &Add...
+
+
+
+ -
+
+
+ &Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 17
+ 68
+
+
+
+
+ -
+
+
+ Re&scan now
+
+
+
+
+
+
+
+
+
+
+
+
+ :/icons/fileopen.png:/icons/fileopen.png
+
+
+ Sound Dirs
+
+
+ -
+
+
+ Make dictionaries from bunches of audiofiles by adding paths here:
+
+
+
+ -
+
+
-
+
+
+ -
+
+
-
+
+
+ &Add...
+
+
+
+ -
+
+
+ &Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :/icons/icon32_hunspell.png:/icons/icon32_hunspell.png
+
+
+ Morphology
+
+
+ -
+
+
+ Path to a directory with Hunspell/Myspell dictionaries:
+
+
+
+ -
+
+
-
+
+
+ true
+
+
+
+ -
+
+
+ &Change...
+
+
+
+
+
+ -
+
+
+ Available morphology dictionaries:
+
+
+
+ -
+
+
-
+
+
+ -
+
+
+ Each morphology dictionary appears as a
+separate auxiliary dictionary which
+provides stem words for searches and
+spelling suggestions for mistyped words.
+Add appropriate dictionaries to the bottoms
+of the appropriate groups to use them.
+
+
+ Qt::PlainText
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ :/icons/icon32_wiki.png:/icons/icon32_wiki.png
+
+
+ Wikipedia
+
+
+ -
+
+
+ Wikipedia (MediaWiki) sites:
+
+
+
+ -
+
+
-
+
+
+ -
+
+
-
+
+
+ &Add...
+
+
+
+ -
+
+
+ &Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+ QSizePolicy::Expanding
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+
+
+
+
+
+ :/icons/internet.png:/icons/internet.png
+
+
+ Websites
+
+
+ -
+
+
+ Any websites. A string %GDWORD% will be replaced with the query word:
+
+
+
+ -
+
+
-
+
+
+ -
+
+
-
+
+
+ &Add...
+
+
+
+ -
+
+
+ &Remove
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+
+
+
+
+ -
+
+
+ Alternatively, use %GD1251% for CP1251, %GDISO1% for ISO 8859-1.
+
+
+
+
+
+
+
+ Transliteration
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Russian transliteration
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ German transliteration
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 40
+
+
+
+
+ -
+
+
+ Enables to use the Latin alphabet to write the Japanese language
+
+
+ Japanese Romaji
+
+
+ true
+
+
+ true
+
+
+
-
+
+
+ Systems:
+
+
+
+ -
+
+
+ The most widely used method of transcription of Japanese,
+based on English phonology
+
+
+ Hepburn
+
+
+
+ -
+
+
+ The most regular system, having a one-to-one relation to the
+kana writing systems. Standardized as ISO 3602
+
+
+ Nihon-shiki
+
+
+
+ -
+
+
+ Based on Nihon-shiki system, but modified for modern standard Japanese.
+Standardized as ISO 3602
+
+
+ Kunrei-shiki
+
+
+
+ -
+
+
+ Syllabaries:
+
+
+
+ -
+
+
+ Hiragana Japanese syllabary
+
+
+ Hiragana
+
+
+
+ -
+
+
+ Hiragana Japanese syllabary
+
+
+ Katakana
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 80
+
+
+
+
+
+
+
+
+
+
+
+ enableRussianTransliteration
+ enableGermanTransliteration
+ enableRomaji
+ enableHepburn
+ enableNihonShiki
+ enableKunreiShiki
+ enableHiragana
+ enableKatakana
+ hunspellPath
+ changeHunspellPath
+ hunspellDictionaries
+ mediaWikis
+ addMediaWiki
+ removeMediaWiki
+ tabWidget
+ addPath
+ removePath
+ rescan
+ soundDirs
+ addSoundDir
+ removeSoundDir
+ paths
+
+
+
+
+
+
diff --git a/src/website.cc b/src/website.cc
new file mode 100644
index 00000000..0730673e
--- /dev/null
+++ b/src/website.cc
@@ -0,0 +1,109 @@
+/* This file is (c) 2008-2009 Konstantin Isakov
+ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
+
+#include "website.hh"
+#include "wstring_qt.hh"
+#include
+#include
+
+namespace WebSite {
+
+using namespace Dictionary;
+
+namespace {
+
+class WebSiteDictionary: public Dictionary::Class
+{
+ string name;
+ QByteArray urlTemplate;
+
+public:
+
+ WebSiteDictionary( string const & id, string const & name_,
+ QString const & urlTemplate_ ):
+ Dictionary::Class( id, vector< string >() ),
+ name( name_ ),
+ urlTemplate( QUrl( urlTemplate_ ).toEncoded() )
+ {
+ }
+
+ virtual string getName() throw()
+ { return name; }
+
+ virtual map< Property, string > getProperties() throw()
+ { return map< Property, string >(); }
+
+ virtual unsigned long getArticleCount() throw()
+ { return 0; }
+
+ virtual unsigned long getWordCount() throw()
+ { return 0; }
+
+ virtual QIcon getIcon() throw()
+ { return QIcon(":/icons/internet.png"); }
+
+ virtual sptr< WordSearchRequest > prefixMatch( wstring const & word,
+ unsigned long ) throw( std::exception );
+
+ virtual sptr< DataRequest > getArticle( wstring const &, vector< wstring > const & alts )
+ throw( std::exception );
+};
+
+sptr< WordSearchRequest > WebSiteDictionary::prefixMatch( wstring const & word,
+ unsigned long ) throw( std::exception )
+{
+ sptr< WordSearchRequestInstant > sr = new WordSearchRequestInstant;
+
+ sr->getMatches().push_back( WordMatch( word, 1 ) );
+
+ return sr;
+}
+
+sptr< DataRequest > WebSiteDictionary::getArticle( wstring const & str, vector< wstring > const & )
+ throw( std::exception )
+{
+ sptr< DataRequestInstant > dr = new DataRequestInstant( true );
+
+ QByteArray urlString( urlTemplate );
+
+ QString inputWord = gd::toQString( str );
+
+ urlString.replace( "%25GDWORD%25", inputWord.toUtf8().toPercentEncoding() );
+ urlString.replace( "%25GD1251%25", QTextCodec::codecForName( "Windows-1251" )->fromUnicode( inputWord ).toPercentEncoding() );
+ urlString.replace( "%25GDISO1%25", QTextCodec::codecForName( "ISO 8859-1" )->fromUnicode( inputWord ).toPercentEncoding() );
+
+ string result = "";
+
+ result += string( "";
+
+ dr->getData().resize( result.size() );
+
+ memcpy( &( dr->getData().front() ), result.data(), result.size() );
+
+ return dr;
+}
+
+}
+
+vector< sptr< Dictionary::Class > > makeDictionaries( Config::WebSites const & ws )
+ throw( std::exception )
+{
+ vector< sptr< Dictionary::Class > > result;
+
+ for( unsigned x = 0; x < ws.size(); ++x )
+ {
+ if ( ws[ x ].enabled )
+ result.push_back( new WebSiteDictionary( ws[ x ].id.toUtf8().data(),
+ ws[ x ].name.toUtf8().data(),
+ ws[ x ].url ) );
+ }
+
+ return result;
+}
+
+}
diff --git a/src/website.hh b/src/website.hh
new file mode 100644
index 00000000..bb0cee24
--- /dev/null
+++ b/src/website.hh
@@ -0,0 +1,21 @@
+/* This file is (c) 2008-2009 Konstantin Isakov
+ * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
+
+#ifndef __WEBSITE_HH_INCLUDED__
+#define __WEBSITE_HH_INCLUDED__
+
+#include "dictionary.hh"
+#include "config.hh"
+
+/// Support for any web sites via a templated url.
+namespace WebSite {
+
+using std::vector;
+using std::string;
+
+vector< sptr< Dictionary::Class > > makeDictionaries( Config::WebSites const & )
+ throw( std::exception );
+
+}
+
+#endif