From d59fb9e5683d27425c0eb41ead5e36f7968c2285 Mon Sep 17 00:00:00 2001 From: Konstantin Isakov Date: Fri, 28 May 2010 20:50:54 +0400 Subject: [PATCH] Support for portable version mode. To enable portable version mode, simply create the portable/ directory in the same directory where the executable itself lives. In portable version all dictionaries live in content/, morphologies in content/morphology. Sound dirs aren't supported in portable version. --- config.cc | 37 +++++++++++++++++++++++++++++++++++++ config.hh | 13 +++++++++++++ dictionary.cc | 32 +++++++++++++++++++++++++++++++- main.cc | 9 +++++++++ sources.cc | 46 +++++++++++++++++++++++++++++++++++++--------- 5 files changed, 127 insertions(+), 10 deletions(-) diff --git a/config.cc b/config.cc index 57b86fe2..32e00c4e 100644 --- a/config.cc +++ b/config.cc @@ -24,6 +24,9 @@ namespace { QDir getHomeDir() { + if ( isPortableVersion() ) + return QDir( QCoreApplication::applicationDirPath() + "/portable" ); + QDir result = QDir::home(); char const * pathInHome = @@ -1062,6 +1065,9 @@ QString getUserQtCssFileName() throw( exError ) QString getProgramDataDir() throw() { + if ( isPortableVersion() ) + return QCoreApplication::applicationDirPath(); + #ifdef PROGRAM_DATA_DIR return PROGRAM_DATA_DIR; #else @@ -1077,4 +1083,35 @@ QString getLocDir() throw() return QCoreApplication::applicationDirPath() + "/locale"; } +bool isPortableVersion() throw() +{ + struct IsPortable + { + bool isPortable; + + IsPortable(): isPortable( QFileInfo( QCoreApplication::applicationDirPath() + "/portable" ).isDir() ) + {} + }; + + static IsPortable p; + + return p.isPortable; +} + +QString getPortableVersionDictionaryDir() throw() +{ + if ( isPortableVersion() ) + return getProgramDataDir() + "/content"; + else + return QString(); +} + +QString getPortableVersionMorphoDir() throw() +{ + if ( isPortableVersion() ) + return getPortableVersionDictionaryDir() + "/morphology"; + else + return QString(); +} + } diff --git a/config.hh b/config.hh index 45dcdd86..27a300a8 100644 --- a/config.hh +++ b/config.hh @@ -375,6 +375,19 @@ QString getProgramDataDir() throw(); /// Returns the directory storing program localizized files (.qm). QString getLocDir() throw(); + +/// Returns true if the program is configured as a portable version. In that +/// mode, all the settings and indices are kept in the program's directory. +bool isPortableVersion() throw(); + +/// Returns directory with dictionaries for portable version. It is content/ +/// in the application's directory. +QString getPortableVersionDictionaryDir() throw(); + +/// Returns directory with morpgologies for portable version. It is +/// content/morphology in the application's directory. +QString getPortableVersionMorphoDir() throw(); + } #endif diff --git a/dictionary.cc b/dictionary.cc index df32e984..aaba4f09 100644 --- a/dictionary.cc +++ b/dictionary.cc @@ -12,6 +12,10 @@ #include #include +#include "config.hh" +#include +#include + namespace Dictionary { bool Request::isFinished() @@ -144,7 +148,33 @@ sptr< DataRequest > Class::getResource( string const & /*name*/ ) string makeDictionaryId( vector< string > const & dictionaryFiles ) throw() { - std::vector< string > sortedList( dictionaryFiles ); + std::vector< string > sortedList; + + if ( Config::isPortableVersion() ) + { + // For portable version, we use relative paths + sortedList.reserve( dictionaryFiles.size() ); + + QDir dictionariesDir( Config::getPortableVersionDictionaryDir() ); + + for( unsigned x = 0; x < dictionaryFiles.size(); ++x ) + { + string const & full( dictionaryFiles[ x ] ); + + QFileInfo fileInfo( QString::fromLocal8Bit( full.c_str() ) ); + + if ( fileInfo.isAbsolute() ) + sortedList.push_back( dictionariesDir.relativeFilePath( fileInfo.filePath() ).toLocal8Bit().data() ); + else + { + // Well, it's relative. We don't technically support those, but + // what the heck + sortedList.push_back( full ); + } + } + } + else + sortedList = dictionaryFiles; std::sort( sortedList.begin(), sortedList.end() ); diff --git a/main.cc b/main.cc index 6be02b22..6f15c220 100644 --- a/main.cc +++ b/main.cc @@ -72,6 +72,15 @@ int main( int argc, char ** argv ) Config::Class cfg( Config::load() ); + if ( Config::isPortableVersion() ) + { + // For portable version, hardcode some settings + + cfg.paths.clear(); + cfg.paths.push_back( Config::Path( Config::getPortableVersionDictionaryDir(), true ) ); + cfg.soundDirs.clear(); + cfg.hunspell.dictionariesPath = Config::getPortableVersionMorphoDir(); + } // Prevent execution of the 2nd copy diff --git a/sources.cc b/sources.cc index 3b4614ec..89f54fad 100644 --- a/sources.cc +++ b/sources.cc @@ -6,11 +6,12 @@ #include #include #include +#include Sources::Sources( QWidget * parent, Config::Paths const & paths, Config::SoundDirs const & soundDirs, Config::Hunspell const & hunspell, - Config::Transliteration const & tr, + Config::Transliteration const & trs, Config::MediaWikis const & mediawikis, Config::WebSites const & webSites ): QWidget( parent ), mediawikisModel( this, mediawikis ), @@ -49,14 +50,41 @@ Sources::Sources( QWidget * parent, Config::Paths const & paths, fitHunspellDictsColumns(); - ui.enableRussianTransliteration->setChecked( tr.enableRussianTransliteration ); - ui.enableGermanTransliteration->setChecked( tr.enableGermanTransliteration ); - ui.enableRomaji->setChecked( tr.romaji.enable ); - ui.enableHepburn->setChecked( tr.romaji.enableHepburn ); - ui.enableNihonShiki->setChecked( tr.romaji.enableNihonShiki ); - ui.enableKunreiShiki->setChecked( tr.romaji.enableKunreiShiki ); - ui.enableHiragana->setChecked( tr.romaji.enableHiragana ); - ui.enableKatakana->setChecked( tr.romaji.enableKatakana ); + ui.enableRussianTransliteration->setChecked( trs.enableRussianTransliteration ); + ui.enableGermanTransliteration->setChecked( trs.enableGermanTransliteration ); + ui.enableRomaji->setChecked( trs.romaji.enable ); + ui.enableHepburn->setChecked( trs.romaji.enableHepburn ); + ui.enableNihonShiki->setChecked( trs.romaji.enableNihonShiki ); + ui.enableKunreiShiki->setChecked( trs.romaji.enableKunreiShiki ); + ui.enableHiragana->setChecked( trs.romaji.enableHiragana ); + ui.enableKatakana->setChecked( trs.romaji.enableKatakana ); + + if ( Config::isPortableVersion() ) + { + // Paths + + ui.paths->setEnabled( false ); + ui.addPath->setEnabled( false ); + ui.removePath->setEnabled( false ); + + // Sound dirs + + { + QStandardItemModel * model = new QStandardItemModel( this ); + model->setHorizontalHeaderLabels( QStringList() << " " ); + model->invisibleRootItem()->appendRow( new QStandardItem( tr( "(not available in portable version)" ) ) ); + ui.soundDirs->setModel( model ); + ui.soundDirs->setEnabled( false ); + + ui.addSoundDir->setEnabled( false ); + ui.removeSoundDir->setEnabled( false ); + } + + // Morpho + + ui.hunspellPath->setEnabled( false ); + ui.changeHunspellPath->setEnabled( false ); + } } void Sources::fitPathsColumns()