3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/21/2010 Added this text. :-)
15 #include "rs_system.h"
17 #include <QTranslator>
20 RS_System * RS_System::uniqueInstance = NULL;
23 RS_System::RS_System()
29 * @return Instance to the unique system object.
31 /*static*/ RS_System * RS_System::instance()
33 if (uniqueInstance == NULL)
34 uniqueInstance = new RS_System();
36 return uniqueInstance;
40 * Initializes the system.
42 * @param appName Application name (e.g. "QCad II")
43 * @param appVersion Application version (e.g. "1.2.3")
44 * @param appDirName Application directory name used for
45 * subdirectories in /usr, /etc ~/.
46 * @param appDir Absolute application directory (e.g. /opt/qcad)
47 * defaults to current directory.
49 void RS_System::init(const QString & appName, const QString & appVersion,
50 const QString & appDirName, const QString & appDir)
52 this->appName = appName;
53 this->appVersion = appVersion;
54 this->appDirName = appDirName;
58 // this->appDir = QDir::currentDirPath();
59 this->appDir = QDir::currentPath();
63 this->appDir = appDir;
66 RS_DEBUG->print("RS_System::init: System %s initialized.", appName.toLatin1().data());
67 RS_DEBUG->print("RS_System::init: App dir: %s", appDir.toLatin1().data());
74 * Initializes the list of available translations.
76 void RS_System::initLanguageList()
78 RS_DEBUG->print("RS_System::initLanguageList");
79 QStringList lst = getFileList("qm", "qm");
81 settings.beginGroup("Paths");
82 // lst += QStringList::split(";", RS_SETTINGS->readEntry("/Translations", ""));
83 lst += settings.value("Translations", "").toString().split(";");
86 for(QStringList::Iterator it=lst.begin(); it!=lst.end(); ++it)
88 RS_DEBUG->print("RS_System::initLanguageList: qm file: %s", (*it).toLatin1().data());
90 // int i1 = (*it).findRev('_');
91 int i1 = (*it).lastIndexOf('_');
92 // int i2 = (*it).find('.', i1);
93 int i2 = (*it).indexOf('.', i1);
94 QString l = (*it).mid(i1 + 1, i2 - i1 - 1);
96 // if (languageList.find(l) == languageList.end())
97 if (languageList.indexOf(l) == -1)
99 RS_DEBUG->print("RS_System::initLanguageList: append language: %s", l.toLatin1().data());
100 languageList.append(l);
104 RS_DEBUG->print("RS_System::initLanguageList: OK");
108 * Loads a different translation for the application GUI.
110 void RS_System::loadTranslation(const QString & lang, const QString & langCmd)
112 static QTranslator * tQt = NULL;
113 static QTranslator * tQCad = NULL;
114 static QTranslator * tQCadGuiQt = NULL;
115 static QTranslator * tQCadActions = NULL;
116 static QTranslator * tQCadCmd = NULL;
117 static QTranslator * tQCadLib = NULL;
118 static QTranslator * tQCadCam = NULL;
119 static QTranslator * tQCadProf = NULL;
123 // search in various directories for translations
124 QStringList lst = getDirectoryList("qm");
126 settings.beginGroup("Paths");
127 // lst += QStringList::split(";", RS_SETTINGS->readEntry("/Translations", ""));
128 lst += settings.value("Translations", "").toString().split(";");
131 for(QStringList::Iterator it=lst.begin(); it!=lst.end(); ++it)
133 langFile = "qt_" + lang + ".qm";
137 qApp->removeTranslator(tQt);
141 tQt = new QTranslator(0);
143 if (tQt->load(langFile, (*it)))
145 qApp->installTranslator(tQt);
148 langFile = "qcad_" + lang + ".qm";
152 qApp->removeTranslator(tQCad);
156 tQCad = new QTranslator(0);
158 if (tQCad->load(langFile, (*it)))
160 qApp->installTranslator(tQCad);
163 langFile = "qcadguiqt_" + lang + ".qm";
165 if (tQCadGuiQt != NULL)
167 qApp->removeTranslator(tQCadGuiQt);
171 tQCadGuiQt = new QTranslator(0);
173 if (tQCadGuiQt->load(langFile, (*it)))
175 qApp->installTranslator(tQCadGuiQt);
178 langFile = "qcadactions_" + lang + ".qm";
180 if (tQCadActions != NULL)
182 qApp->removeTranslator(tQCadActions);
186 tQCadActions = new QTranslator(0);
188 if (tQCadActions->load(langFile, (*it)))
190 qApp->installTranslator(tQCadActions);
193 langFile = "qcadcmd_" + langCmd + ".qm";
195 if (tQCadCmd != NULL)
197 qApp->removeTranslator(tQCadCmd);
201 tQCadCmd = new QTranslator(0);
203 if (tQCadCmd->load(langFile, (*it)))
205 qApp->installTranslator(tQCadCmd);
208 langFile = "qcadlib_" + lang + ".qm";
210 if (tQCadLib != NULL)
212 qApp->removeTranslator(tQCadLib);
216 tQCadLib = new QTranslator(0);
218 if (tQCadLib->load(langFile, (*it)))
220 qApp->installTranslator(tQCadLib);
223 langFile = "qcadcam_" + lang + ".qm";
225 if (tQCadLib != NULL)
227 qApp->removeTranslator(tQCadCam);
231 tQCadCam = new QTranslator(0);
233 if (tQCadCam->load(langFile, (*it)))
235 qApp->installTranslator(tQCadCam);
238 langFile = "qcadprof_" + lang + ".qm";
240 if (tQCadProf != NULL)
242 qApp->removeTranslator(tQCadProf);
246 tQCadProf = new QTranslator(0);
248 if (tQCadProf->load(langFile, (*it)))
250 qApp->installTranslator(tQCadProf);
256 * Checks if the system has been initialized and prints a warning
257 * otherwise to stderr.
259 bool RS_System::checkInit()
263 RS_DEBUG->print(RS_Debug::D_WARNING, "RS_System::checkInit: System not initialized.\n"
264 "Use RS_SYSTEM->init(appname, appdirname) to do so.");
271 * Creates all given directories in the user's home.
273 bool RS_System::createHomePath(const QString & p)
277 // QStringList dirs = QStringList::split('/', p, false);
278 QStringList dirs = p.split('/', QString::SkipEmptyParts);
279 QString created = getHomeDir();
281 for(QStringList::Iterator it=dirs.begin(); it!=dirs.end(); ++it)
283 created += QString("/%1").arg(*it);
285 // if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created, true))
286 if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created))
288 RS_DEBUG->print("RS_System::createHomePath: Created directory '%s'",
289 created.toLatin1().data());
293 RS_DEBUG->print(RS_Debug::D_ERROR, "RS_System::createHomePath: Cannot create directory '%s'",
294 created.toLatin1().data());
303 * @return Users home directory.
305 QString RS_System::getHomeDir()
307 // return QDir::homeDirPath();
308 return QDir::homePath();
312 * @return Current directory.
314 QString RS_System::getCurrentDir()
316 // return QDir::currentDirPath();
317 return QDir::currentPath();
321 * @return Application directory.
323 QString RS_System::getAppDir()
329 * @return A list of absolute paths to all font files found.
331 QStringList RS_System::getFontList()
333 QStringList ret = getFileList("fonts", "cxf");
338 * @return A list of absolute paths to all hatch pattern files found.
340 QStringList RS_System::getPatternList()
342 QStringList ret = getFileList("patterns", "dxf");
347 * @return A list of absolute paths to all script files found.
349 QStringList RS_System::getScriptList()
351 QStringList ret = getFileList("scripts/qsa", "qs");
356 * @return A list of absolute paths to all machine configuration files found.
358 QStringList RS_System::getMachineList()
360 QStringList ret = getFileList("machines", "cxm");
365 * @return Absolute path to the documentation.
367 QString RS_System::getDocPath()
369 QStringList lst = getDirectoryList("doc");
374 * @return The application name.
376 QString RS_System::getAppName()
382 * @return The application version.
384 QString RS_System::getAppVersion()
390 * Searches for files in an application shared directory in the given
391 * subdirectory with the given extension.
393 * @return List of the absolute paths of the files found.
395 QStringList RS_System::getFileList(const QString & subDirectory, const QString & fileExtension)
399 /*QStringList dirList;
402 dirList.append("/usr/share/" + appDirName);
405 dirList.append("/usr/X11R6/" + appDirName);
407 dirList.append("/usr/X11R6/share/" + appDirName);
408 dirList.append(getHomeDir() + "/." + appDirName);
412 //dirList.append(getCurrentDir());
415 /usr/share/doc/qcad/html/en/
418 QStringList dirList = getDirectoryList(subDirectory);
420 QStringList fileList;
424 for(QStringList::Iterator it=dirList.begin(); it!=dirList.end(); ++it)
426 //path = QString(*it) + "/" + subDirectory;
430 if (dir.exists() && dir.isReadable())
432 // QStringList files = dir.entryList("*." + fileExtension);
434 filters << "*." + fileExtension;
435 QStringList files = dir.entryList(filters);
437 for(QStringList::Iterator it2=files.begin(); it2!=files.end(); it2++)
438 fileList += path + "/" + (*it2);
446 * @return List of all directories in subdirectory 'subDirectory' in
447 * all possible QCad directories.
449 QStringList RS_System::getDirectoryList(const QString & subDirectory)
454 if (subDirectory != "library")
457 //local (application) directory has priority over other dirs:
458 if (!appDir.isEmpty() && appDir != "/" && appDir != getHomeDir())
460 dirList.append(appDir + "/" + subDirectory);
464 dirList.append("/usr/share/" + appDirName + "/" + subDirectory);
466 dirList.append("/usr/X11R6/" + appDirName + "/" + subDirectory);
467 dirList.append("/usr/X11R6/share/" + appDirName + "/" + subDirectory);
468 dirList.append(getHomeDir() + "/." + appDirName + "/" + subDirectory);
474 // Mac OS X - don't scan for library since this might lead us into the
475 // wrong directory tree:
476 if (!appDir.isEmpty() && appDir != "/" /*&& subDirectory!="library"*/)
478 dirList.append(appDir + "/../Resources/" + subDirectory);
479 dirList.append(appDir + "/../../../" + subDirectory);
483 // Individual directories:
484 settings.beginGroup("Paths");
486 if (subDirectory == "fonts")
488 dirList += settings.value("Fonts", "").toString().split(QRegExp("[;]"));
490 else if (subDirectory == "patterns")
492 dirList += settings.value("Patterns", "").toString().split(QRegExp("[;]"));
494 else if (subDirectory.startsWith("scripts"))
496 dirList += settings.value("Scripts", "").toString().split(QRegExp("[;]"));
498 else if (subDirectory.startsWith("library"))
500 dirList += settings.value("Library", "").toString().split(QRegExp("[;]"));
502 else if (subDirectory.startsWith("po"))
504 dirList += settings.value("Translations", "").toString().split(QRegExp("[;]"));
511 RS_DEBUG->print("RS_System::getDirectoryList: Paths:");
513 for(QStringList::Iterator it=dirList.begin(); it!=dirList.end(); ++it)
515 if (QFileInfo(*it).isDir())
518 RS_DEBUG->print((*it).toLatin1().data());
525 QStringList RS_System::getLanguageList()
531 * Converts a language string to a symbol (e.g. Deutsch or German to 'de').
533 * Supported languages: http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt
535 QString RS_System::languageToSymbol(const QString& lang)
537 QString l = lang.toLower();
539 // don't use else if.. M$ visual wannabe c++ can't handle it
544 if (l=="abkhazian") {
547 if (l=="afrikaans") {
562 if (l=="azerbaijani") {
568 if (l=="byelorussian") {
571 if (l=="bulgarian") {
580 if (l=="bengali" || l=="bangla") {
604 if (l=="german" || l=="deutsch") {
616 if (l=="esperanto") {
640 if (l=="french" || l=="francais") {
649 if (l=="scots gaelic" || l=="gaelic") {
673 if (l=="hungarian") {
679 if (l=="interlingua") {
682 if (l=="indonesian") {
685 if (l=="interlingue") {
691 if (l=="icelandic") {
697 if (l=="inuktitut") {
712 if (l=="greenlandic") {
715 if (l=="cambodian") {
742 if (l=="lithuanian") {
745 if (l=="latvian" || l=="lettish") {
754 if (l=="macedonian") {
757 if (l=="malayalam") {
760 if (l=="mongolian") {
763 if (l=="moldavian") {
787 if (l=="norwegian") {
793 if (l=="afan" || l=="oromo" || l=="afan oromo") {
805 if (l=="pashto" || l=="pushto") {
808 if (l=="portuguese") {
811 if (l=="brasilian portuguese") {
817 if (l=="rhaeto-romance") {
829 if (l=="kinyarwanda") {
841 if (l=="serbo-Croatian") {
844 if (l=="sinhalese") {
850 if (l=="slovenian") {
874 if (l=="sundanese") {
925 if (l=="ukrainian") {
934 if (l=="vietnamese") {
966 * Converst a language two-letter-code into a readable string
967 * (e.g. 'de' to Deutsch)
969 QString RS_System::symbolToLanguage(const QString & symb)
971 QString l = symb.toLower();
995 return "Azerbaijani";
1001 return "Byelorussian";
1082 return "Scots Gaelic";
1112 return "Interlingua";
1115 return "Indonesian";
1118 return "Interlingue";
1145 return "Greenlandic";
1175 return "Lithuanian";
1187 return "Macedonian";
1226 return "Afan Oromo";
1241 return "Portuguese";
1244 return "Brasilian Portuguese";
1250 return "Rhaeto-Romance";
1262 return "Kinyarwanda";
1274 return "Serbo-croatian";
1367 return "Vietnamese";
1398 * Tries to convert the given encoding string to an encoding Qt knows.
1400 QString RS_System::getEncoding(const QString & str)
1402 QString l=str.toLower();
1404 if (l=="latin1" || l=="ansi_1252" || l=="iso-8859-1" ||
1405 l=="cp819" || l=="csiso" || l=="ibm819" || l=="iso_8859-1" ||
1406 l=="iso8859-1" || l=="iso-ir-100" || l=="l1") {
1408 } else if (l=="big5" || l=="ansi_950" || l=="cn-big5" || l=="csbig5" ||
1411 } else if (l=="big5-hkscs") {
1412 return "Big5-HKSCS";
1413 } else if (l=="eucjp" || l=="euc-jp" || l=="cseucpkdfmtjapanese" ||
1414 l=="x-euc" || l=="x-euc-jp") {
1416 } else if (l=="euckr") {
1418 } else if (l=="gb2312" || l=="gb2312" || l=="chinese" || l=="cn-gb" ||
1419 l=="csgb2312" || l=="csgb231280" || l=="csiso58gb231280" ||
1420 l=="gb_2312-80" || l=="gb231280" || l=="gb2312-80" || l=="gbk" ||
1423 } else if (l=="gbk") {
1425 } else if (l=="gb18030") {
1427 } else if (l=="jis7") {
1429 } else if (l=="shift-jis" || l=="ansi_932" || l=="shift_jis" || l=="csShiftJIS" ||
1430 l=="cswindows31j" || l=="ms_kanji" || l=="x-ms-cp932" || l=="x-sjis") {
1432 } else if (l=="tscii") {
1434 } else if (l=="utf88-bit") {
1436 } else if (l=="utf16") {
1438 } else if (l=="koi8-r") {
1440 } else if (l=="koi8-u") {
1442 } else if (l=="iso8859-1") {
1444 } else if (l=="iso8859-2") {
1446 } else if (l=="iso8859-3") {
1448 } else if (l=="iso8859-4" || l=="ansi_1257") {
1450 } else if (l=="iso8859-5") {
1452 } else if (l=="iso8859-6" || l=="ansi_1256") {
1454 } else if (l=="iso8859-7" || l=="ansi_1253") {
1456 } else if (l=="iso8859-8") {
1458 } else if (l=="iso8859-8-i" || l=="ansi_1255") {
1459 return "ISO8859-8-i";
1460 } else if (l=="iso8859-9" || l=="ansi_1254") {
1462 } else if (l=="iso8859-10") {
1463 return "ISO8859-10";
1464 } else if (l=="iso8859-13") {
1465 return "ISO8859-13";
1466 } else if (l=="iso8859-14") {
1467 return "ISO8859-14";
1468 } else if (l=="iso8859-15") {
1469 return "ISO8859-15";
1470 } else if (l=="ibm 850") {
1472 } else if (l=="ibm 866") {
1474 } else if (l=="cp874") {
1476 } else if (l=="cp1250") {
1478 } else if (l=="cp1251") {
1480 } else if (l=="cp1252") {
1482 } else if (l=="cp1253") {
1484 } else if (l=="cp1254") {
1486 } else if (l=="cp1255") {
1488 } else if (l=="cp1256") {
1490 } else if (l=="cp1257") {
1492 } else if (l=="cp1258") {
1494 } else if (l=="apple roman") {
1495 return "Apple Roman";
1496 } else if (l=="tis-620") {
1503 /** Returns ISO code for given locale. Needed for win32 to convert
1504 from system encodings.
1505 Locale names mostly copied from XFree86.
1507 The code may be incomplete (chinese/japanese locales, etc.)
1509 2004-05-13, J Staniek
1511 static QMap<QString, QString> loc_map;
1513 QString RS_System::localeToISO(const QString & locale)
1515 if (loc_map.isEmpty())
1517 loc_map["croatian"]="ISO8859-2";
1518 loc_map["cs"]="ISO8859-2";
1519 loc_map["cs_CS"]="ISO8859-2";
1520 loc_map["cs_CZ"]="ISO8859-2";
1521 loc_map["cz"]="ISO8859-2";
1522 loc_map["cz_CZ"]="ISO8859-2";
1523 loc_map["czech"]="ISO8859-2";
1524 loc_map["hr"]="ISO8859-2";
1525 loc_map["hr_HR"]="ISO8859-2";
1526 loc_map["hu"]="ISO8859-2";
1527 loc_map["hu_HU"]="ISO8859-2";
1528 loc_map["hungarian"]="ISO8859-2";
1529 loc_map["pl"]="ISO8859-2";
1530 loc_map["pl_PL"]="ISO8859-2";
1531 loc_map["polish"]="ISO8859-2";
1532 loc_map["ro"]="ISO8859-2";
1533 loc_map["ro_RO"]="ISO8859-2";
1534 loc_map["rumanian"]="ISO8859-2";
1535 loc_map["serbocroatian"]="ISO8859-2";
1536 loc_map["sh"]="ISO8859-2";
1537 loc_map["sh_SP"]="ISO8859-2";
1538 loc_map["sh_YU"]="ISO8859-2";
1539 loc_map["sk"]="ISO8859-2";
1540 loc_map["sk_SK"]="ISO8859-2";
1541 loc_map["sl"]="ISO8859-2";
1542 loc_map["sl_CS"]="ISO8859-2";
1543 loc_map["sl_SI"]="ISO8859-2";
1544 loc_map["slovak"]="ISO8859-2";
1545 loc_map["slovene"]="ISO8859-2";
1546 loc_map["sr_SP"]="ISO8859-2";
1548 loc_map["eo"]="ISO8859-3";
1550 loc_map["ee"]="ISO8859-4";
1551 loc_map["ee_EE"]="ISO8859-4";
1553 loc_map["mk"]="ISO8859-5";
1554 loc_map["mk_MK"]="ISO8859-5";
1555 loc_map["sp"]="ISO8859-5";
1556 loc_map["sp_YU"]="ISO8859-5";
1558 loc_map["ar_AA"]="ISO8859-6";
1559 loc_map["ar_SA"]="ISO8859-6";
1560 loc_map["arabic"]="ISO8859-6";
1562 loc_map["el"]="ISO8859-7";
1563 loc_map["el_GR"]="ISO8859-7";
1564 loc_map["greek"]="ISO8859-7";
1566 loc_map["hebrew"]="ISO8859-8";
1567 loc_map["he"]="ISO8859-8";
1568 loc_map["he_IL"]="ISO8859-8";
1569 loc_map["iw"]="ISO8859-8";
1570 loc_map["iw_IL"]="ISO8859-8";
1572 loc_map["tr"]="ISO8859-9";
1573 loc_map["tr_TR"]="ISO8859-9";
1574 loc_map["turkish"]="ISO8859-9";
1576 loc_map["lt"]="ISO8859-13";
1577 loc_map["lt_LT"]="ISO8859-13";
1578 loc_map["lv"]="ISO8859-13";
1579 loc_map["lv_LV"]="ISO8859-13";
1581 loc_map["et"]="ISO8859-15";
1582 loc_map["et_EE"]="ISO8859-15";
1583 loc_map["br_FR"]="ISO8859-15";
1584 loc_map["ca_ES"]="ISO8859-15";
1585 loc_map["de"]="ISO8859-15";
1586 loc_map["de_AT"]="ISO8859-15";
1587 loc_map["de_BE"]="ISO8859-15";
1588 loc_map["de_DE"]="ISO8859-15";
1589 loc_map["de_LU"]="ISO8859-15";
1590 loc_map["en_IE"]="ISO8859-15";
1591 loc_map["es"]="ISO8859-15";
1592 loc_map["es_ES"]="ISO8859-15";
1593 loc_map["eu_ES"]="ISO8859-15";
1594 loc_map["fi"]="ISO8859-15";
1595 loc_map["fi_FI"]="ISO8859-15";
1596 loc_map["finnish"]="ISO8859-15";
1597 loc_map["fr"]="ISO8859-15";
1598 loc_map["fr_FR"]="ISO8859-15";
1599 loc_map["fr_BE"]="ISO8859-15";
1600 loc_map["fr_LU"]="ISO8859-15";
1601 loc_map["french"]="ISO8859-15";
1602 loc_map["ga_IE"]="ISO8859-15";
1603 loc_map["gl_ES"]="ISO8859-15";
1604 loc_map["it"]="ISO8859-15";
1605 loc_map["it_IT"]="ISO8859-15";
1606 loc_map["oc_FR"]="ISO8859-15";
1607 loc_map["nl"]="ISO8859-15";
1608 loc_map["nl_BE"]="ISO8859-15";
1609 loc_map["nl_NL"]="ISO8859-15";
1610 loc_map["pt"]="ISO8859-15";
1611 loc_map["pt_PT"]="ISO8859-15";
1612 loc_map["sv_FI"]="ISO8859-15";
1613 loc_map["wa_BE"]="ISO8859-15";
1615 loc_map["uk"]="KOI8-U";
1616 loc_map["uk_UA"]="KOI8-U";
1617 loc_map["ru_YA"]="KOI8-U";
1618 loc_map["ukrainian"]="KOI8-U";
1620 loc_map["be"]="KOI8-R";
1621 loc_map["be_BY"]="KOI8-R";
1622 loc_map["bg"]="KOI8-R";
1623 loc_map["bg_BG"]="KOI8-R";
1624 loc_map["bulgarian"]="KOI8-R";
1625 loc_map["ba_RU"]="KOI8-R";
1626 loc_map["ky"]="KOI8-R";
1627 loc_map["ky_KG"]="KOI8-R";
1628 loc_map["kk"]="KOI8-R";
1629 loc_map["kk_KZ"]="KOI8-R";
1632 QString l = loc_map[locale];