/**************************************************************************** ** ** This file is part of the LibreCAD project, a 2D CAD program ** ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) ** Copyright (C) 2021 A. Stebich (librecad@mail.lordofbikes.de) ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file gpl-2.0.txt included in the ** packaging of this file. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ** ** This copyright notice MUST APPEAR in all copies of the script! ** **********************************************************************/ #include #include #include #include #include #include #include "rs_settings.h" #include "rs_system.h" #include "rs.h" #include "rs_debug.h" #include RS_System* RS_System::uniqueInstance = NULL; /** * Initializes the system. * * @param appName Application name (e.g. "librecad II") * @param appVersion Application version (e.g. "1.2.3") * @param appDirName Application directory name used for * subdirectories in /usr, /etc ~/. */ void RS_System::init(const QString& appName, const QString& appVersion, const QString& appDirName, const char *arg0) { this->appName = appName; this->appVersion = appVersion; this->appDirName = appDirName; if (QFile::decodeName( arg0).contains( "/.mount")) { // in AppImage QCoreApplication::applicationDirPath() directs to /lib64 of mounted AppImage // thus use argv[0] to extract the correct path to librecad executable appDir = QFileInfo( QFile::decodeName( arg0)).absolutePath(); } else { // in regular application QCoreApplication::applicationDirPath() is preferred, see GitHub #1488 appDir = QCoreApplication::applicationDirPath(); } // when appDir is not HOME or CURRENT dir, search appDir too in getDirectoryList() externalAppDir = (!appDir.isEmpty() && "/" != appDir && getHomeDir() != appDir && getCurrentDir() != appDir); RS_DEBUG->print("RS_System::init: System %s initialized.", appName.toLatin1().data()); RS_DEBUG->print("RS_System::init: App dir: %s", appDir.toLatin1().data()); initialized = true; initAllLanguagesList(); initLanguageList(); } /** * Initializes the list of available translations. */ void RS_System::initLanguageList() { RS_DEBUG->print("RS_System::initLanguageList"); QStringList lst = getFileList("qm", "qm"); RS_SETTINGS->beginGroup("/Paths"); lst += (RS_SETTINGS->readEntry("/Translations", "")).split(";", QString::SkipEmptyParts); RS_SETTINGS->endGroup(); for (QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) { RS_DEBUG->print("RS_System::initLanguageList: qm file: %s", (*it).toLatin1().data()); int i0 = (*it).lastIndexOf(QString("librecad"),-1,Qt::CaseInsensitive); int i1 = (*it).indexOf('_',i0); int i2 = (*it).indexOf('.', i1); if (i1 == -1 || i2 == -1) { continue; } QString l = (*it).mid(i1+1, i2-i1-1); if (!(languageList.contains(l)) ) { RS_DEBUG->print("RS_System::initLanguageList: append language: %s", l.toLatin1().data()); languageList.append(l); } } RS_DEBUG->print("RS_System::initLanguageList: OK"); } void RS_System::addLocale(RS_Locale *locale) { allKnownLocales.push_back( QSharedPointer( locale)); } #define LNG(canonical, direction, name) \ locale = new RS_Locale(); \ locale->setCanonical( canonical); \ locale->setDirection( direction); \ locale->setName( name); \ addLocale( locale); void RS_System::initAllLanguagesList() { // RVT uk_AU renamed to uk so that we don't have to change the pootle server allKnownLocales.clear(); RS_Locale *locale; LNG( "ab" , RS2::locLeftToRight, "Abkhazian") LNG( "aa" , RS2::locLeftToRight, "Afar") LNG( "af_ZA", RS2::locLeftToRight, "Afrikaans") LNG( "sq_AL", RS2::locLeftToRight, "Albanian") LNG( "am" , RS2::locLeftToRight, "Amharic") LNG( "ar" , RS2::locRightToLeft, "Arabic") LNG( "ar_DZ", RS2::locRightToLeft, "Arabic (Algeria)") LNG( "ar_BH", RS2::locRightToLeft, "Arabic (Bahrain)") LNG( "ar_EG", RS2::locRightToLeft, "Arabic (Egypt)") LNG( "ar_IQ", RS2::locRightToLeft, "Arabic (Iraq)") LNG( "ar_JO", RS2::locRightToLeft, "Arabic (Jordan)") LNG( "ar_KW", RS2::locRightToLeft, "Arabic (Kuwait)") LNG( "ar_LB", RS2::locRightToLeft, "Arabic (Lebanon)") LNG( "ar_LY", RS2::locRightToLeft, "Arabic (Libya)") LNG( "ar_MA", RS2::locRightToLeft, "Arabic (Morocco)") LNG( "ar_OM", RS2::locRightToLeft, "Arabic (Oman)") LNG( "ar_QA", RS2::locRightToLeft, "Arabic (Qatar)") LNG( "ar_SA", RS2::locRightToLeft, "Arabic (Saudi Arabia)") LNG( "ar_SD", RS2::locRightToLeft, "Arabic (Sudan)") LNG( "ar_SY", RS2::locRightToLeft, "Arabic (Syria)") LNG( "ar_TN", RS2::locRightToLeft, "Arabic (Tunisia)") LNG( "ar_AE", RS2::locRightToLeft, "Arabic (Uae)") LNG( "ar_YE", RS2::locRightToLeft, "Arabic (Yemen)") LNG( "hy" , RS2::locLeftToRight, "Armenian") LNG( "as" , RS2::locLeftToRight, "Assamese") LNG( "ay" , RS2::locLeftToRight, "Aymara") LNG( "az" , RS2::locLeftToRight, "Azeri") LNG( "az" , RS2::locLeftToRight, "Azeri (Cyrillic)") LNG( "az" , RS2::locLeftToRight, "Azeri (Latin)") LNG( "ba" , RS2::locLeftToRight, "Bashkir") LNG( "eu_ES", RS2::locLeftToRight, "Basque") LNG( "be_BY", RS2::locLeftToRight, "Belarusian") LNG( "bn" , RS2::locLeftToRight, "Bengali") LNG( "dz" , RS2::locLeftToRight, "Bhutani") LNG( "bh" , RS2::locLeftToRight, "Bihari") LNG( "bi" , RS2::locLeftToRight, "Bislama") LNG( "br" , RS2::locLeftToRight, "Breton") LNG( "bg_BG", RS2::locLeftToRight, "Bulgarian") LNG( "my" , RS2::locLeftToRight, "Burmese") LNG( "km" , RS2::locLeftToRight, "Cambodian") LNG( "ca_ES", RS2::locLeftToRight, "Catalan") LNG( "zh_TW", RS2::locLeftToRight, "Chinese") LNG( "zh_CN", RS2::locLeftToRight, "Chinese (Simplified)") LNG( "zh_TW", RS2::locLeftToRight, "Chinese (Traditional)") LNG( "zh_HK", RS2::locLeftToRight, "Chinese (Hongkong)") LNG( "zh_MO", RS2::locLeftToRight, "Chinese (Macau)") LNG( "zh_SG", RS2::locLeftToRight, "Chinese (Singapore)") LNG( "zh_TW", RS2::locLeftToRight, "Chinese (Taiwan)") LNG( "co" , RS2::locLeftToRight, "Corsican") LNG( "hr_HR", RS2::locLeftToRight, "Croatian") LNG( "cs_CZ", RS2::locLeftToRight, "Czech") LNG( "da_DK", RS2::locLeftToRight, "Danish") LNG( "nl_NL", RS2::locLeftToRight, "Dutch") LNG( "nl_BE", RS2::locLeftToRight, "Dutch (Belgian)") LNG( "en_GB", RS2::locLeftToRight, "English") LNG( "en_GB", RS2::locLeftToRight, "English (U.K.)") LNG( "en_US", RS2::locLeftToRight, "English (U.S.)") LNG( "en_AU", RS2::locLeftToRight, "English (Australia)") LNG( "en_BZ", RS2::locLeftToRight, "English (Belize)") LNG( "en_BW", RS2::locLeftToRight, "English (Botswana)") LNG( "en_CA", RS2::locLeftToRight, "English (Canada)") LNG( "en_CB", RS2::locLeftToRight, "English (Caribbean)") LNG( "en_DK", RS2::locLeftToRight, "English (Denmark)") LNG( "en_IE", RS2::locLeftToRight, "English (Eire)") LNG( "en_JM", RS2::locLeftToRight, "English (Jamaica)") LNG( "en_NZ", RS2::locLeftToRight, "English (New Zealand)") LNG( "en_PH", RS2::locLeftToRight, "English (Philippines)") LNG( "en_ZA", RS2::locLeftToRight, "English (South Africa)") LNG( "en_TT", RS2::locLeftToRight, "English (Trinidad)") LNG( "en_ZW", RS2::locLeftToRight, "English (Zimbabwe)") LNG( "eo" , RS2::locLeftToRight, "Esperanto") LNG( "et_EE", RS2::locLeftToRight, "Estonian") LNG( "fo_FO", RS2::locLeftToRight, "Faeroese") LNG( "fa_IR", RS2::locLeftToRight, "Farsi") LNG( "fj" , RS2::locLeftToRight, "Fiji") LNG( "fi_FI", RS2::locLeftToRight, "Finnish") LNG( "fr_FR", RS2::locLeftToRight, "French") LNG( "fr_BE", RS2::locLeftToRight, "French (Belgian)") LNG( "fr_CA", RS2::locLeftToRight, "French (Canadian)") LNG( "fr_LU", RS2::locLeftToRight, "French (Luxembourg)") LNG( "fr_MC", RS2::locLeftToRight, "French (Monaco)") LNG( "fr_CH", RS2::locLeftToRight, "French (Swiss)") LNG( "fy" , RS2::locLeftToRight, "Frisian") LNG( "gl_ES", RS2::locLeftToRight, "Galician") LNG( "ka_GE", RS2::locLeftToRight, "Georgian") LNG( "de_DE", RS2::locLeftToRight, "German") LNG( "de_AT", RS2::locLeftToRight, "German (Austrian)") LNG( "de_BE", RS2::locLeftToRight, "German (Belgium)") LNG( "de_LI", RS2::locLeftToRight, "German (Liechtenstein)") LNG( "de_LU", RS2::locLeftToRight, "German (Luxembourg)") LNG( "de_CH", RS2::locLeftToRight, "German (Swiss)") LNG( "el_GR", RS2::locLeftToRight, "Greek") LNG( "kl_GL", RS2::locLeftToRight, "Greenlandic") LNG( "gn" , RS2::locLeftToRight, "Guarani") LNG( "gu" , RS2::locLeftToRight, "Gujarati") LNG( "ha" , RS2::locLeftToRight, "Hausa") LNG( "he_IL", RS2::locRightToLeft, "Hebrew") LNG( "hi_IN", RS2::locLeftToRight, "Hindi") LNG( "hu_HU", RS2::locLeftToRight, "Hungarian") LNG( "is_IS", RS2::locLeftToRight, "Icelandic") LNG( "id_ID", RS2::locLeftToRight, "Indonesian") LNG( "ia" , RS2::locLeftToRight, "Interlingua") LNG( "ie" , RS2::locLeftToRight, "Interlingue") LNG( "iu" , RS2::locLeftToRight, "Inuktitut") LNG( "ik" , RS2::locLeftToRight, "Inupiak") LNG( "ga_IE", RS2::locLeftToRight, "Irish") LNG( "it_IT", RS2::locLeftToRight, "Italian") LNG( "it_CH", RS2::locLeftToRight, "Italian (Swiss)") LNG( "ja_JP", RS2::locLeftToRight, "Japanese") LNG( "jw" , RS2::locLeftToRight, "Javanese") LNG( "kn" , RS2::locLeftToRight, "Kannada") LNG( "ks" , RS2::locLeftToRight, "Kashmiri") LNG( "ks_IN", RS2::locLeftToRight, "Kashmiri (India)") LNG( "kk" , RS2::locLeftToRight, "Kazakh") LNG( "kw_GB", RS2::locLeftToRight, "Kernewek") LNG( "rw" , RS2::locLeftToRight, "Kinyarwanda") LNG( "ky" , RS2::locLeftToRight, "Kirghiz") LNG( "rn" , RS2::locLeftToRight, "Kirundi") LNG( "" , RS2::locLeftToRight, "Konkani") LNG( "ko_KR", RS2::locLeftToRight, "Korean") LNG( "ku_TR", RS2::locLeftToRight, "Kurdish") LNG( "lo" , RS2::locLeftToRight, "Laothian") LNG( "la" , RS2::locLeftToRight, "Latin") LNG( "lv_LV", RS2::locLeftToRight, "Latvian") LNG( "ln" , RS2::locLeftToRight, "Lingala") LNG( "lt_LT", RS2::locLeftToRight, "Lithuanian") LNG( "mk_MK", RS2::locLeftToRight, "Macedonian") LNG( "mg" , RS2::locLeftToRight, "Malagasy") LNG( "ms_MY", RS2::locLeftToRight, "Malay") LNG( "ml" , RS2::locLeftToRight, "Malayalam") LNG( "ms_BN", RS2::locLeftToRight, "Malay (Brunei Darussalam)") LNG( "ms_MY", RS2::locLeftToRight, "Malay (Malaysia)") LNG( "mt_MT", RS2::locLeftToRight, "Maltese") LNG( "" , RS2::locLeftToRight, "Manipuri") LNG( "mi" , RS2::locLeftToRight, "Maori") LNG( "mr_IN", RS2::locLeftToRight, "Marathi") LNG( "mo" , RS2::locLeftToRight, "Moldavian") LNG( "mn" , RS2::locLeftToRight, "Mongolian") LNG( "na" , RS2::locLeftToRight, "Nauru") LNG( "ne_NP", RS2::locLeftToRight, "Nepali") LNG( "ne_IN", RS2::locLeftToRight, "Nepali (India)") LNG( "nb_NO", RS2::locLeftToRight, "Norwegian (Bokmal)") LNG( "nn_NO", RS2::locLeftToRight, "Norwegian (Nynorsk)") LNG( "oc" , RS2::locLeftToRight, "Occitan") LNG( "or" , RS2::locLeftToRight, "Oriya") LNG( "om" , RS2::locLeftToRight, "(Afan) Oromo") LNG( "ps" , RS2::locLeftToRight, "Pashto, Pushto") LNG( "pl_PL", RS2::locLeftToRight, "Polish") LNG( "pt_PT", RS2::locLeftToRight, "Portuguese") LNG( "pt_BR", RS2::locLeftToRight, "Portuguese (Brazilian)") LNG( "pa" , RS2::locLeftToRight, "Punjabi") LNG( "qu" , RS2::locLeftToRight, "Quechua") LNG( "rm" , RS2::locLeftToRight, "Rhaeto-Romance") LNG( "ro_RO", RS2::locLeftToRight, "Romanian") LNG( "ru_RU", RS2::locLeftToRight, "Russian") LNG( "ru_UA", RS2::locLeftToRight, "Russian (Ukraine)") LNG( "sm" , RS2::locLeftToRight, "Samoan") LNG( "sg" , RS2::locLeftToRight, "Sangho") LNG( "sa" , RS2::locLeftToRight, "Sanskrit") LNG( "gd" , RS2::locLeftToRight, "Scots Gaelic") LNG( "se_NO", RS2::locLeftToRight, "Northern Sami") LNG( "sr_SR", RS2::locLeftToRight, "Serbian") LNG( "sr_SR", RS2::locLeftToRight, "Serbian (Cyrillic)") LNG( "sr_SR@latin", RS2::locLeftToRight, "Serbian (Latin)") LNG( "sr_YU", RS2::locLeftToRight, "Serbian (Cyrillic)") LNG( "sr_YU@latin", RS2::locLeftToRight, "Serbian (Latin)") LNG( "sh" , RS2::locLeftToRight, "Serbo-Croatian") LNG( "st" , RS2::locLeftToRight, "Sesotho") LNG( "tn" , RS2::locLeftToRight, "Setswana") LNG( "sn" , RS2::locLeftToRight, "Shona") LNG( "sd" , RS2::locLeftToRight, "Sindhi") LNG( "si" , RS2::locLeftToRight, "Sinhalese") LNG( "ss" , RS2::locLeftToRight, "Siswati") LNG( "sk_SK", RS2::locLeftToRight, "Slovak") LNG( "sl_SI", RS2::locLeftToRight, "Slovenian") LNG( "so" , RS2::locLeftToRight, "Somali") LNG( "es_ES", RS2::locLeftToRight, "Spanish") LNG( "es_AR", RS2::locLeftToRight, "Spanish (Argentina)") LNG( "es_BO", RS2::locLeftToRight, "Spanish (Bolivia)") LNG( "es_CL", RS2::locLeftToRight, "Spanish (Chile)") LNG( "es_CO", RS2::locLeftToRight, "Spanish (Colombia)") LNG( "es_CR", RS2::locLeftToRight, "Spanish (Costa Rica)") LNG( "es_DO", RS2::locLeftToRight, "Spanish (Dominican republic)") LNG( "es_EC", RS2::locLeftToRight, "Spanish (Ecuador)") LNG( "es_SV", RS2::locLeftToRight, "Spanish (El Salvador)") LNG( "es_GT", RS2::locLeftToRight, "Spanish (Guatemala)") LNG( "es_HN", RS2::locLeftToRight, "Spanish (Honduras)") LNG( "es_MX", RS2::locLeftToRight, "Spanish (Mexican)") LNG( "es_ES", RS2::locLeftToRight, "Spanish (Modern)") LNG( "es_NI", RS2::locLeftToRight, "Spanish (Nicaragua)") LNG( "es_PA", RS2::locLeftToRight, "Spanish (Panama)") LNG( "es_PY", RS2::locLeftToRight, "Spanish (Paraguay)") LNG( "es_PE", RS2::locLeftToRight, "Spanish (Peru)") LNG( "es_PR", RS2::locLeftToRight, "Spanish (Puerto Rico)") LNG( "es_UY", RS2::locLeftToRight, "Spanish (Uruguay)") LNG( "es_US", RS2::locLeftToRight, "Spanish (U.S.)") LNG( "es_VE", RS2::locLeftToRight, "Spanish (Venezuela)") LNG( "su" , RS2::locLeftToRight, "Sundanese") LNG( "sw_KE", RS2::locLeftToRight, "Swahili") LNG( "sv_SE", RS2::locLeftToRight, "Swedish") LNG( "sv_FI", RS2::locLeftToRight, "Swedish (Finland)") LNG( "tl_PH", RS2::locLeftToRight, "Tagalog") LNG( "tg" , RS2::locLeftToRight, "Tajik") LNG( "ta" , RS2::locLeftToRight, "Tamil") LNG( "tt" , RS2::locLeftToRight, "Tatar") LNG( "te" , RS2::locLeftToRight, "Telugu") LNG( "th_TH", RS2::locLeftToRight, "Thai") LNG( "bo" , RS2::locLeftToRight, "Tibetan") LNG( "ti" , RS2::locLeftToRight, "Tigrinya") LNG( "to" , RS2::locLeftToRight, "Tonga") LNG( "ts" , RS2::locLeftToRight, "Tsonga") LNG( "tr_TR", RS2::locLeftToRight, "Turkish") LNG( "tk" , RS2::locLeftToRight, "Turkmen") LNG( "tw" , RS2::locLeftToRight, "Twi") LNG( "ug" , RS2::locLeftToRight, "Uighur") LNG( "uk" , RS2::locLeftToRight, "Ukrainian") LNG( "ur" , RS2::locLeftToRight, "Urdu") LNG( "ur_IN", RS2::locLeftToRight, "Urdu (India)") LNG( "ur_PK", RS2::locLeftToRight, "Urdu (Pakistan)") LNG( "uz" , RS2::locLeftToRight, "Uzbek") LNG( "uz" , RS2::locLeftToRight, "Uzbek (Cyrillic)") LNG( "uz" , RS2::locLeftToRight, "Uzbek (Latin)") LNG( "ca_ES@valencia", RS2::locLeftToRight, "Valencian") LNG( "vi_VN", RS2::locLeftToRight, "Vietnamese") LNG( "vo" , RS2::locLeftToRight, "Volapuk") LNG( "cy" , RS2::locLeftToRight, "Welsh") LNG( "wo" , RS2::locLeftToRight, "Wolof") LNG( "xh" , RS2::locLeftToRight, "Xhosa") LNG( "yi" , RS2::locLeftToRight, "Yiddish") LNG( "yo" , RS2::locLeftToRight, "Yoruba") LNG( "za" , RS2::locLeftToRight, "Zhuang") LNG( "zu" , RS2::locLeftToRight, "Zulu") } /** * Loads a different translation for the application GUI. * *fixme, need to support command language */ void RS_System::loadTranslation(const QString& lang, const QString& /*langCmd*/) { static QTranslator* tQt = NULL; static QTranslator* tLibreCAD = NULL; static QTranslator* tPlugIns = NULL; //make translation filenames case insensitive, #276 QString langLower(""); QString langUpper(""); int i0 = lang.indexOf('_'); if (i0 >= 2 && lang.size() - i0 >= 2) { //contains region code langLower = lang.left( i0) + '_' + lang.mid( i0 + 1).toLower(); langUpper = lang.left( i0) + '_' + lang.mid( i0 + 1).toUpper(); } else { langLower = lang; langUpper.clear(); } // search in various directories for translations QStringList lst = getDirectoryList( "qm"); RS_SETTINGS->beginGroup( "/Paths"); lst += (RS_SETTINGS->readEntry( "/Translations", "")).split( ";", QString::SkipEmptyParts); RS_SETTINGS->endGroup(); if( tLibreCAD != NULL) { qApp->removeTranslator( tLibreCAD); delete tLibreCAD; } if( tPlugIns != NULL) { qApp->removeTranslator( tPlugIns); delete tPlugIns; } if( tQt != NULL) { qApp->removeTranslator( tQt); delete tQt; } QString langFileLower = "librecad_" + langLower + ".qm", langFileUpper = "librecad_" + langUpper + ".qm", langPlugInsLower = "plugins_" + langLower + ".qm", langPlugInsUpper = "plugins_" + langUpper + ".qm", langQtLower = "qt_" + langLower + ".qm", langQtUpper = "qt_" + langUpper + ".qm"; QTranslator* t = new QTranslator(0); for (QStringList::Iterator it = lst.begin(); it != lst.end(); ++it) { // load LibreCAD translations if (NULL == tLibreCAD) { if (t->load( langFileLower, *it) == true || ( ! langUpper.isEmpty() && t->load( langFileUpper, *it) == true)) { tLibreCAD = t; qApp->installTranslator( tLibreCAD); t = new QTranslator(0); } } // load PlugIns translations if (NULL == tPlugIns) { if (t->load( langPlugInsLower, *it) == true || ( ! langUpper.isEmpty() && t->load( langPlugInsUpper, *it) == true)) { tPlugIns = t; qApp->installTranslator( tPlugIns); t = new QTranslator(0); } } // load Qt standard dialog translations if (NULL == tQt) { if (t->load( langQtLower, *it) == true || ( ! langUpper.isEmpty() && t->load( langQtUpper, *it) == true)) { tQt = t; qApp->installTranslator( tQt); t = new QTranslator(0); } } if (NULL != tLibreCAD && NULL != tPlugIns && NULL != tQt) { break; } } if (NULL != t) { delete t; } } /** * Checks if the system has been initialized and prints a warning * otherwise to stderr. */ bool RS_System::checkInit() { if (!initialized) { RS_DEBUG->print(RS_Debug::D_WARNING, "RS_System::checkInit: System not initialized.\n" "Use RS_SYSTEM->init(appname, appdirname) to do so."); } return initialized; } /** * Creates all given directories in the user's home. */ bool RS_System::createPaths(const QString& directory) { QDir dir; dir.cd( QDir::homePath()); dir.mkpath( directory); return true; } /** * Create if not exist and return the Application data directory. * In OS_WIN32 "c:\documents&settings\\local configuration\application data\LibreCAD" * In OS_MAC "/Users//Library/Application Support/LibreCAD" * In OS_LINUX "/home//.local/share/data/LibreCAD" * * @return Application data directory. */ QString RS_System::getAppDataDir() { QString appData = QStandardPaths::writableLocation( QStandardPaths::DataLocation); QDir dir( appData); if (!dir.exists()) { if (!dir.mkpath( appData)) return QString(); } return appData; } /** * Searches for files in an application shared directory in the given * subdirectory with the given extension. * * @return List of the absolute paths of the files found. */ QStringList RS_System::getFileList(const QString& subDirectory, const QString& fileExtension) { checkInit(); RS_DEBUG->print( "RS_System::getFileList: subdirectory %s ", subDirectory.toLatin1().data()); RS_DEBUG->print( "RS_System::getFileList: appDirName %s ", appDirName.toLatin1().data()); RS_DEBUG->print( "RS_System::getFileList: getCurrentDir %s ", getCurrentDir().toLatin1().data()); QStringList dirList = getDirectoryList( subDirectory); QStringList fileList; QString path; QDir dir; for (QStringList::Iterator it = dirList.begin(); it != dirList.end(); ++it) { //path = QString(*it) + "/" + subDirectory; path = QString( *it); dir = QDir( path); if (dir.exists() && dir.isReadable()) { QStringList files = dir.entryList( QStringList( "*." + fileExtension)); for (QStringList::Iterator it2 = files.begin(); it2 != files.end(); it2++) { fileList += path + "/" + (*it2); } } } return fileList; } /** * @return List of all directories in subdirectory 'subDirectory' in * all possible LibreCAD directories. */ QStringList RS_System::getDirectoryList(const QString& _subDirectory) { QStringList dirList; QString subDirectory = QDir::fromNativeSeparators( _subDirectory); #ifdef Q_OS_MAC dirList.append( QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation) + "/" + appDirName + "/" + subDirectory); #endif // Q_OS_MAC #ifdef Q_OS_WIN32 dirList.append( QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation) + "/" + appDirName + "/" + subDirectory); #endif // Q_OS_WIN32 // Unix home directory, it's old style but some people might have stuff there. dirList.append( getHomeDir() + "/." + appDirName + "/" + subDirectory); //local (application) directory has priority over other dirs: if (!subDirectory.compare( "plugins")) { // 17 Aug, 2011, Dongxu Li, do not look for plugins in the current folder, // we should install plugins to system or ~/.librecad/plugins/ if (externalAppDir) { dirList.append( appDir + "/" + subDirectory); } } #ifdef Q_OS_UNIX // for AppImage use relative paths from executable // from package manager the executable is in /usr/bin // in AppImage the executable is APPDIR/usr/bin // so this should work for package manager and AppImage distribution dirList.append( QDir::cleanPath( appDir + "/../share/doc/" + appDirName + "/" + subDirectory)); // Redhat style: dirList.append( QDir::cleanPath( appDir + "/../share/" + appDirName + "/" + subDirectory)); // Debian style: dirList.append( QDir::cleanPath( appDir + "/../lib/" + appDirName + "/" + subDirectory)); if (QStringLiteral( "plugins") == subDirectory) { dirList.append( QDir::cleanPath( appDir + "/../lib/" + appDirName)); } #endif #ifdef Q_OS_MAC // Apple uses the resource directory if (!appDir.isEmpty() && appDir!="/") { dirList.append( QDir::cleanPath( appDir + "/../Resources/" + subDirectory)); } #endif #ifndef Q_OS_MAC // Add support directory if librecad is run-in-place, // not for Apple because it uses resources this is more for unix systems dirList.append( appDir + "/resources/" + subDirectory); #endif // Individual directories: RS_SETTINGS->beginGroup( "/Paths"); if (subDirectory == "fonts") { dirList += (RS_SETTINGS->readEntry( "/Fonts", "")).split( QRegExp("[;]"), QString::SkipEmptyParts); } else if (subDirectory == "patterns") { dirList += (RS_SETTINGS->readEntry( "/Patterns", "")).split( QRegExp("[;]"), QString::SkipEmptyParts); } else if (subDirectory.startsWith( "scripts")) { dirList += (RS_SETTINGS->readEntry( "/Scripts", "")).split( QRegExp("[;]"), QString::SkipEmptyParts); } else if (subDirectory.startsWith( "library")) { dirList += (RS_SETTINGS->readEntry( "/Library", "")).split( QRegExp("[;]"), QString::SkipEmptyParts); } else if (subDirectory.startsWith( "qm")) { dirList += (RS_SETTINGS->readEntry( "/Translations", "")).split( QRegExp("[;]"), QString::SkipEmptyParts); } RS_SETTINGS->endGroup(); QStringList ret; RS_DEBUG->print("RS_System::getDirectoryList: Paths:"); for (QStringList::Iterator it = dirList.begin(); it != dirList.end(); ++it ) { if (QFileInfo( *it).isDir()) { ret += (*it); RS_DEBUG->print( (*it).toLatin1() ); } } return ret; } /** * Converts a language string to a symbol (e.g. Deutsch or German to 'de'). * Languages taken from RFC3066 */ QString RS_System::languageToSymbol(const QString& lang) { int i1 = lang.indexOf( ' '); QString l = lang; if (i1 >= 2){ l = lang.mid( 0, i1); } return l; // RS_Locale *locale; // foreach (locale, *RS_SYSTEM->allKnownLocales) { // if (locale->getName().toLower() == l) { // return locale->getCanonical(); // } // } // return ""; } /** * Converts a locale code into a readable string * (e.g. 'de' to 'German Deutsch' * (e.g. 'en_au' to 'English (Australia)' */ QString RS_System::symbolToLanguage(const QString& symb) { RS_Locale loc( symb); QString ret; if (symb.contains( QRegExp( "^en"))) { ret = RS_Locale::languageToString( loc.language()); if( symb.contains('_') ) { ret += " (" + RS_Locale::countryToString( loc.country()) + ')'; } } else { ret = RS_Locale::languageToString( loc.language()) + ' ' + loc.nativeLanguageName(); if( symb.contains( '_') ) { ret += " (" + RS_Locale::countryToString( loc.country()) + ' ' + loc.nativeCountryName() + ')'; } } return ret; } /** * Tries to convert the given encoding string to an encoding Qt knows. */ QString RS_System::getEncoding(const QString& str) { QString l=str.toLower(); if (l=="latin1" || l=="ansi_1252" || l=="iso-8859-1" || l=="cp819" || l=="csiso" || l=="ibm819" || l=="iso_8859-1" || l=="iso8859-1" || l=="iso-ir-100" || l=="l1") { return "Latin1"; } else if (l=="big5" || l=="ansi_950" || l=="cn-big5" || l=="csbig5" || l=="x-x-big5") { return "Big5"; } else if (l=="big5-hkscs") { return "Big5-HKSCS"; } else if (l=="eucjp" || l=="euc-jp" || l=="cseucpkdfmtjapanese" || l=="x-euc" || l=="x-euc-jp") { return "eucJP"; } else if (l=="euckr") { return "eucKR"; } else if (l=="gb2312" || l=="chinese" || l=="cn-gb" || l=="csgb2312" || l=="csgb231280" || l=="csiso58gb231280" || l=="gb_2312-80" || l=="gb231280" || l=="gb2312-80" || l=="gbk" || l=="iso-ir-58") { return "GB2312"; } else if (l=="gbk") { return "GBK"; } else if (l=="gb18030") { return "GB18030"; } else if (l=="jis7") { return "JIS7"; } else if (l=="shift-jis" || l=="ansi_932" || l=="shift_jis" || l=="csShiftJIS" || l=="cswindows31j" || l=="ms_kanji" || l=="x-ms-cp932" || l=="x-sjis") { return "Shift-JIS"; } else if (l=="tscii") { return "TSCII"; } else if (l=="utf88-bit") { return "utf88-bit"; } else if (l=="utf16") { return "utf16"; } else if (l=="utf8" || l=="utf-8") { return "utf-8"; } else if (l=="koi8-r") { return "KOI8-R"; } else if (l=="koi8-u") { return "KOI8-U"; } else if (l=="iso8859-1") { return "ISO8859-1"; } else if (l=="iso8859-2") { return "ISO8859-2"; } else if (l=="iso8859-3") { return "ISO8859-3"; } else if (l=="iso8859-4" || l=="ansi_1257") { return "ISO8859-4"; } else if (l=="iso8859-5") { return "ISO8859-5"; } else if (l=="iso8859-6" || l=="ansi_1256") { return "ISO8859-6"; } else if (l=="iso8859-7" || l=="ansi_1253") { return "ISO8859-7"; } else if (l=="iso8859-8") { return "ISO8859-8"; } else if (l=="iso8859-8-i" || l=="ansi_1255") { return "ISO8859-8-i"; } else if (l=="iso8859-9" || l=="ansi_1254") { return "ISO8859-9"; } else if (l=="iso8859-10") { return "ISO8859-10"; } else if (l=="iso8859-13") { return "ISO8859-13"; } else if (l=="iso8859-14") { return "ISO8859-14"; } else if (l=="iso8859-15") { return "ISO8859-15"; } else if (l=="ibm 850") { return "IBM 850"; } else if (l=="ibm 866") { return "IBM 866"; } else if (l=="cp874") { return "CP874"; } else if (l=="cp1250") { return "CP1250"; } else if (l=="cp1251" || l=="ansi_1251") { return "CP1251"; } else if (l=="cp1252") { return "CP1252"; } else if (l=="cp1253") { return "CP1253"; } else if (l=="cp1254") { return "CP1254"; } else if (l=="cp1255") { return "CP1255"; } else if (l=="cp1256") { return "CP1256"; } else if (l=="cp1257") { return "CP1257"; } else if (l=="cp1258") { return "CP1258"; } else if (l=="apple roman") { return "Apple Roman"; } else if (l=="tis-620") { return "TIS-620"; } return "latin1"; } /** Returns ISO code for given locale. Needed for win32 to convert from system encodings. Locale names mostly copied from XFree86. The code may be incomplete (chinese/japanese locales, etc.) 2004-05-13, J Staniek */ static QMap loc_map; QByteArray RS_System::localeToISO(const QByteArray& locale) { if (loc_map.isEmpty()) { loc_map["croatian"]="ISO8859-2"; loc_map["cs"]="ISO8859-2"; loc_map["cs_CS"]="ISO8859-2"; loc_map["cs_CZ"]="ISO8859-2"; loc_map["cz"]="ISO8859-2"; loc_map["cz_CZ"]="ISO8859-2"; loc_map["czech"]="ISO8859-2"; loc_map["hr"]="ISO8859-2"; loc_map["hr_HR"]="ISO8859-2"; loc_map["hu"]="ISO8859-2"; loc_map["hu_HU"]="ISO8859-2"; loc_map["hungarian"]="ISO8859-2"; loc_map["pl"]="ISO8859-2"; loc_map["pl_PL"]="ISO8859-2"; loc_map["polish"]="ISO8859-2"; loc_map["ro"]="ISO8859-2"; loc_map["ro_RO"]="ISO8859-2"; loc_map["rumanian"]="ISO8859-2"; loc_map["serbocroatian"]="ISO8859-2"; loc_map["sh"]="ISO8859-2"; loc_map["sh_SP"]="ISO8859-2"; loc_map["sh_YU"]="ISO8859-2"; loc_map["sk"]="ISO8859-2"; loc_map["sk_SK"]="ISO8859-2"; loc_map["sl"]="ISO8859-2"; loc_map["sl_CS"]="ISO8859-2"; loc_map["sl_SI"]="ISO8859-2"; loc_map["slovak"]="ISO8859-2"; loc_map["slovene"]="ISO8859-2"; loc_map["sr_SP"]="ISO8859-2"; loc_map["eo"]="ISO8859-3"; loc_map["ee"]="ISO8859-4"; loc_map["ee_EE"]="ISO8859-4"; loc_map["mk"]="ISO8859-5"; loc_map["mk_MK"]="ISO8859-5"; loc_map["sp"]="ISO8859-5"; loc_map["sp_YU"]="ISO8859-5"; loc_map["ar_AA"]="ISO8859-6"; loc_map["ar_SA"]="ISO8859-6"; loc_map["arabic"]="ISO8859-6"; loc_map["el"]="ISO8859-7"; loc_map["el_GR"]="ISO8859-7"; loc_map["greek"]="ISO8859-7"; loc_map["hebrew"]="ISO8859-8"; loc_map["he"]="ISO8859-8"; loc_map["he_IL"]="ISO8859-8"; loc_map["iw"]="ISO8859-8"; loc_map["iw_IL"]="ISO8859-8"; loc_map["tr"]="ISO8859-9"; loc_map["tr_TR"]="ISO8859-9"; loc_map["turkish"]="ISO8859-9"; loc_map["lt"]="ISO8859-13"; loc_map["lt_LT"]="ISO8859-13"; loc_map["lv"]="ISO8859-13"; loc_map["lv_LV"]="ISO8859-13"; loc_map["et"]="ISO8859-15"; loc_map["et_EE"]="ISO8859-15"; loc_map["br_FR"]="ISO8859-15"; loc_map["ca_ES"]="ISO8859-15"; loc_map["de"]="ISO8859-15"; loc_map["de_AT"]="ISO8859-15"; loc_map["de_BE"]="ISO8859-15"; loc_map["de_DE"]="ISO8859-15"; loc_map["de_LU"]="ISO8859-15"; loc_map["en_IE"]="ISO8859-15"; loc_map["es"]="ISO8859-15"; loc_map["es_EC"]="ISO8859-15"; loc_map["es_ES"]="ISO8859-15"; loc_map["eu_ES"]="ISO8859-15"; loc_map["fi"]="ISO8859-15"; loc_map["fi_FI"]="ISO8859-15"; loc_map["finnish"]="ISO8859-15"; loc_map["fr"]="ISO8859-15"; loc_map["fr_FR"]="ISO8859-15"; loc_map["fr_BE"]="ISO8859-15"; loc_map["fr_LU"]="ISO8859-15"; loc_map["french"]="ISO8859-15"; loc_map["ga_IE"]="ISO8859-15"; loc_map["gl_ES"]="ISO8859-15"; loc_map["it"]="ISO8859-15"; loc_map["it_IT"]="ISO8859-15"; loc_map["oc_FR"]="ISO8859-15"; loc_map["nl"]="ISO8859-15"; loc_map["nl_BE"]="ISO8859-15"; loc_map["nl_NL"]="ISO8859-15"; loc_map["pt"]="ISO8859-15"; loc_map["pt_PT"]="ISO8859-15"; loc_map["sv_FI"]="ISO8859-15"; loc_map["wa_BE"]="ISO8859-15"; loc_map["uk"]="KOI8-U"; loc_map["uk_UA"]="KOI8-U"; loc_map["ru_YA"]="KOI8-U"; loc_map["ukrainian"]="KOI8-U"; loc_map["be"]="KOI8-R"; loc_map["be_BY"]="KOI8-R"; loc_map["bg"]="KOI8-R"; loc_map["bg_BG"]="KOI8-R"; loc_map["bulgarian"]="KOI8-R"; loc_map["ba_RU"]="KOI8-R"; loc_map["ky"]="KOI8-R"; loc_map["ky_KG"]="KOI8-R"; loc_map["kk"]="KOI8-R"; loc_map["kk_KZ"]="KOI8-R"; } QByteArray l = loc_map[locale]; if (l.isEmpty()) { return "ISO8859-1"; } return l; }