+ 'WebSites' implemented.

*! Don't set a global qt stylesheet - sometimes WebKit crashes with it.
*! Fixes for text search feature (works faster, no selection artifacts, frame
   doesn't grow).
This commit is contained in:
Konstantin Isakov 2009-05-16 18:04:21 +00:00
parent 747825a505
commit 93fe5e5301
18 changed files with 1343 additions and 754 deletions

View file

@ -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.

View file

@ -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;
}
}
}
}

View file

@ -13,7 +13,7 @@
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="1000,0">
<property name="margin">
<number>0</number>
</property>
@ -43,6 +43,12 @@
</item>
<item>
<widget class="QFrame" name="searchFrame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>

View file

@ -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 );

View file

@ -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;

View file

@ -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.

View file

@ -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

BIN
src/icons/internet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -14,6 +14,7 @@
#include "romaji.hh"
#include "russiantranslit.hh"
#include "german.hh"
#include "website.hh"
#include <QMessageBox>
#include <QDir>
@ -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;

View file

@ -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();

View file

@ -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() )

View file

@ -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();

View file

@ -36,5 +36,6 @@
<file>icons/bookcase.png</file>
<file>qt-style-st-lingvo.css</file>
<file>article-style-st-lingvo.css</file>
<file>icons/internet.png</file>
</qresource>
</RCC>

View file

@ -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 <b>%1</b> 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,

View file

@ -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();
};

View file

@ -1,464 +1,527 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Sources</class>
<widget class="QWidget" name="Sources">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<height>336</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Sources</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="iconSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<widget class="QWidget" name="filesTab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/filesave.png</normaloff>:/icons/filesave.png</iconset>
</attribute>
<attribute name="title">
<string>Files</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Paths to search for the dictionary files:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeView" name="paths"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addPath">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removePath">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>68</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="rescan">
<property name="text">
<string>Re&amp;scan now</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/fileopen.png</normaloff>:/icons/fileopen.png</iconset>
</attribute>
<attribute name="title">
<string>Sound Dirs</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Make dictionaries from bunches of audiofiles by adding paths here:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QTreeView" name="soundDirs"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QPushButton" name="addSoundDir">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeSoundDir">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/icon32_hunspell.png</normaloff>:/icons/icon32_hunspell.png</iconset>
</attribute>
<attribute name="title">
<string>Morphology</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Path to a directory with Hunspell/Myspell dictionaries:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="hunspellPath">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="changeHunspellPath">
<property name="text">
<string>&amp;Change...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Available morphology dictionaries:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QTreeView" name="hunspellDictionaries"/>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>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.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="mediaWikisTab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/icon32_wiki.png</normaloff>:/icons/icon32_wiki.png</iconset>
</attribute>
<attribute name="title">
<string>Wikipedia</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Wikipedia (MediaWiki) sites:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTreeView" name="mediaWikis"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="addMediaWiki">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeMediaWiki">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Transliteration</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="enableRussianTransliteration">
<property name="text">
<string>Russian transliteration</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="enableGermanTransliteration">
<property name="text">
<string>German transliteration</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="enableRomaji">
<property name="toolTip">
<string>Enables to use the Latin alphabet to write the Japanese language</string>
</property>
<property name="title">
<string>Japanese Romaji</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Systems:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="enableHepburn">
<property name="toolTip">
<string>The most widely used method of transcription of Japanese,
based on English phonology</string>
</property>
<property name="text">
<string>Hepburn</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="enableNihonShiki">
<property name="toolTip">
<string>The most regular system, having a one-to-one relation to the
kana writing systems. Standardized as ISO 3602</string>
</property>
<property name="text">
<string>Nihon-shiki</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QCheckBox" name="enableKunreiShiki">
<property name="toolTip">
<string>Based on Nihon-shiki system, but modified for modern standard Japanese.
Standardized as ISO 3602</string>
</property>
<property name="text">
<string>Kunrei-shiki</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Syllabaries:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="enableHiragana">
<property name="toolTip">
<string>Hiragana Japanese syllabary</string>
</property>
<property name="text">
<string>Hiragana</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QCheckBox" name="enableKatakana">
<property name="toolTip">
<string>Hiragana Japanese syllabary</string>
</property>
<property name="text">
<string>Katakana</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>enableRussianTransliteration</tabstop>
<tabstop>enableGermanTransliteration</tabstop>
<tabstop>enableRomaji</tabstop>
<tabstop>enableHepburn</tabstop>
<tabstop>enableNihonShiki</tabstop>
<tabstop>enableKunreiShiki</tabstop>
<tabstop>enableHiragana</tabstop>
<tabstop>enableKatakana</tabstop>
<tabstop>hunspellPath</tabstop>
<tabstop>changeHunspellPath</tabstop>
<tabstop>hunspellDictionaries</tabstop>
<tabstop>mediaWikis</tabstop>
<tabstop>addMediaWiki</tabstop>
<tabstop>removeMediaWiki</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>addPath</tabstop>
<tabstop>removePath</tabstop>
<tabstop>rescan</tabstop>
<tabstop>soundDirs</tabstop>
<tabstop>addSoundDir</tabstop>
<tabstop>removeSoundDir</tabstop>
<tabstop>paths</tabstop>
</tabstops>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Sources</class>
<widget class="QWidget" name="Sources">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>578</width>
<height>336</height>
</rect>
</property>
<property name="windowTitle">
<string notr="true">Sources</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<property name="iconSize">
<size>
<width>15</width>
<height>15</height>
</size>
</property>
<widget class="QWidget" name="filesTab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/filesave.png</normaloff>:/icons/filesave.png</iconset>
</attribute>
<attribute name="title">
<string>Files</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Paths to search for the dictionary files:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QTreeView" name="paths"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="addPath">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removePath">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>68</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="rescan">
<property name="text">
<string>Re&amp;scan now</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/fileopen.png</normaloff>:/icons/fileopen.png</iconset>
</attribute>
<attribute name="title">
<string>Sound Dirs</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Make dictionaries from bunches of audiofiles by adding paths here:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QTreeView" name="soundDirs"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QPushButton" name="addSoundDir">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeSoundDir">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/icon32_hunspell.png</normaloff>:/icons/icon32_hunspell.png</iconset>
</attribute>
<attribute name="title">
<string>Morphology</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Path to a directory with Hunspell/Myspell dictionaries:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="hunspellPath">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="changeHunspellPath">
<property name="text">
<string>&amp;Change...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Available morphology dictionaries:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QTreeView" name="hunspellDictionaries"/>
</item>
<item>
<widget class="QLabel" name="label_6">
<property name="text">
<string>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.</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="mediaWikisTab">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/icon32_wiki.png</normaloff>:/icons/icon32_wiki.png</iconset>
</attribute>
<attribute name="title">
<string>Wikipedia</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Wikipedia (MediaWiki) sites:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTreeView" name="mediaWikis"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="addMediaWiki">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeMediaWiki">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="icon">
<iconset resource="resources.qrc">
<normaloff>:/icons/internet.png</normaloff>:/icons/internet.png</iconset>
</attribute>
<attribute name="title">
<string>Websites</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Any websites. A string %GDWORD% will be replaced with the query word:</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QTreeView" name="webSites"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QPushButton" name="addWebSite">
<property name="text">
<string>&amp;Add...</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeWebSite">
<property name="text">
<string>&amp;Remove</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="text">
<string>Alternatively, use %GD1251% for CP1251, %GDISO1% for ISO 8859-1.</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Transliteration</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="enableRussianTransliteration">
<property name="text">
<string>Russian transliteration</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="enableGermanTransliteration">
<property name="text">
<string>German transliteration</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="enableRomaji">
<property name="toolTip">
<string>Enables to use the Latin alphabet to write the Japanese language</string>
</property>
<property name="title">
<string>Japanese Romaji</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Systems:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="enableHepburn">
<property name="toolTip">
<string>The most widely used method of transcription of Japanese,
based on English phonology</string>
</property>
<property name="text">
<string>Hepburn</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QCheckBox" name="enableNihonShiki">
<property name="toolTip">
<string>The most regular system, having a one-to-one relation to the
kana writing systems. Standardized as ISO 3602</string>
</property>
<property name="text">
<string>Nihon-shiki</string>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QCheckBox" name="enableKunreiShiki">
<property name="toolTip">
<string>Based on Nihon-shiki system, but modified for modern standard Japanese.
Standardized as ISO 3602</string>
</property>
<property name="text">
<string>Kunrei-shiki</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Syllabaries:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QCheckBox" name="enableHiragana">
<property name="toolTip">
<string>Hiragana Japanese syllabary</string>
</property>
<property name="text">
<string>Hiragana</string>
</property>
</widget>
</item>
<item row="1" column="3">
<widget class="QCheckBox" name="enableKatakana">
<property name="toolTip">
<string>Hiragana Japanese syllabary</string>
</property>
<property name="text">
<string>Katakana</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>80</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<tabstops>
<tabstop>enableRussianTransliteration</tabstop>
<tabstop>enableGermanTransliteration</tabstop>
<tabstop>enableRomaji</tabstop>
<tabstop>enableHepburn</tabstop>
<tabstop>enableNihonShiki</tabstop>
<tabstop>enableKunreiShiki</tabstop>
<tabstop>enableHiragana</tabstop>
<tabstop>enableKatakana</tabstop>
<tabstop>hunspellPath</tabstop>
<tabstop>changeHunspellPath</tabstop>
<tabstop>hunspellDictionaries</tabstop>
<tabstop>mediaWikis</tabstop>
<tabstop>addMediaWiki</tabstop>
<tabstop>removeMediaWiki</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>addPath</tabstop>
<tabstop>removePath</tabstop>
<tabstop>rescan</tabstop>
<tabstop>soundDirs</tabstop>
<tabstop>addSoundDir</tabstop>
<tabstop>removeSoundDir</tabstop>
<tabstop>paths</tabstop>
</tabstops>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>

109
src/website.cc Normal file
View file

@ -0,0 +1,109 @@
/* This file is (c) 2008-2009 Konstantin Isakov <ikm@users.berlios.de>
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
#include "website.hh"
#include "wstring_qt.hh"
#include <QUrl>
#include <QTextCodec>
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 = "<div class=\"website_padding\"></div>";
result += string( "<iframe id=\"gdexpandframe-" ) + getId() +
"\" src=\"" + urlString.data() +
"\" scrolling=\"no\" marginwidth=\"0\" marginheight=\"0\" "
"frameborder=\"0\" vspace=\"0\" hspace=\"0\" "
"style=\"overflow:visible; width:100%; display:none;\">"
"</iframe>";
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;
}
}

21
src/website.hh Normal file
View file

@ -0,0 +1,21 @@
/* This file is (c) 2008-2009 Konstantin Isakov <ikm@users.berlios.de>
* 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