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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/21/2010 Added this text. :-)
19 #include <QTranslator>
22 System * System::uniqueInstance = NULL;
31 * @return Instance to the unique system object.
33 /*static*/ System * System::instance()
35 if (uniqueInstance == NULL)
36 uniqueInstance = new System();
38 return uniqueInstance;
42 * Initializes the system.
44 * @param appName Application name (e.g. "Architektonas")
45 * @param appVersion Application version (e.g. "1.2.3")
46 * @param appDirName Application directory name used for
47 * subdirectories in /usr, /etc ~/.
48 * @param appDir Absolute application directory (e.g. /opt/qcad)
49 * defaults to current directory.
51 void System::init(const QString & appName, const QString & appVersion,
52 const QString & appDirName, const QString & appDir)
54 this->appName = appName;
55 this->appVersion = appVersion;
56 this->appDirName = appDirName;
60 // this->appDir = QDir::currentDirPath();
61 this->appDir = QDir::currentPath();
65 this->appDir = appDir;
68 DEBUG->print("System::init: System %s initialized.", appName.toLatin1().data());
69 DEBUG->print("System::init: App dir: %s", appDir.toLatin1().data());
76 * Initializes the list of available translations.
78 void System::initLanguageList()
80 DEBUG->print("System::initLanguageList");
81 QStringList lst = getFileList("qm", "qm");
83 settings.beginGroup("Paths");
84 // lst += QStringList::split(";", RS_SETTINGS->readEntry("/Translations", ""));
85 lst += settings.value("Translations", "").toString().split(";");
88 for(QStringList::Iterator it=lst.begin(); it!=lst.end(); ++it)
90 DEBUG->print("System::initLanguageList: qm file: %s", (*it).toLatin1().data());
92 // int i1 = (*it).findRev('_');
93 int i1 = (*it).lastIndexOf('_');
94 // int i2 = (*it).find('.', i1);
95 int i2 = (*it).indexOf('.', i1);
96 QString l = (*it).mid(i1 + 1, i2 - i1 - 1);
98 // if (languageList.find(l) == languageList.end())
99 if (languageList.indexOf(l) == -1)
101 DEBUG->print("System::initLanguageList: append language: %s", l.toLatin1().data());
102 languageList.append(l);
106 DEBUG->print("System::initLanguageList: OK");
110 * Loads a different translation for the application GUI.
112 void System::loadTranslation(const QString & lang, const QString & langCmd)
114 static QTranslator * tQt = NULL;
115 static QTranslator * tQCad = NULL;
116 static QTranslator * tQCadGuiQt = NULL;
117 static QTranslator * tQCadActions = NULL;
118 static QTranslator * tQCadCmd = NULL;
119 static QTranslator * tQCadLib = NULL;
120 static QTranslator * tQCadCam = NULL;
121 static QTranslator * tQCadProf = NULL;
125 // search in various directories for translations
126 QStringList lst = getDirectoryList("qm");
128 settings.beginGroup("Paths");
129 // lst += QStringList::split(";", RS_SETTINGS->readEntry("/Translations", ""));
130 lst += settings.value("Translations", "").toString().split(";");
133 for(QStringList::Iterator it=lst.begin(); it!=lst.end(); ++it)
135 langFile = "qt_" + lang + ".qm";
139 qApp->removeTranslator(tQt);
143 tQt = new QTranslator(0);
145 if (tQt->load(langFile, (*it)))
147 qApp->installTranslator(tQt);
150 langFile = "qcad_" + lang + ".qm";
154 qApp->removeTranslator(tQCad);
158 tQCad = new QTranslator(0);
160 if (tQCad->load(langFile, (*it)))
162 qApp->installTranslator(tQCad);
165 langFile = "qcadguiqt_" + lang + ".qm";
167 if (tQCadGuiQt != NULL)
169 qApp->removeTranslator(tQCadGuiQt);
173 tQCadGuiQt = new QTranslator(0);
175 if (tQCadGuiQt->load(langFile, (*it)))
177 qApp->installTranslator(tQCadGuiQt);
180 langFile = "qcadactions_" + lang + ".qm";
182 if (tQCadActions != NULL)
184 qApp->removeTranslator(tQCadActions);
188 tQCadActions = new QTranslator(0);
190 if (tQCadActions->load(langFile, (*it)))
192 qApp->installTranslator(tQCadActions);
195 langFile = "qcadcmd_" + langCmd + ".qm";
197 if (tQCadCmd != NULL)
199 qApp->removeTranslator(tQCadCmd);
203 tQCadCmd = new QTranslator(0);
205 if (tQCadCmd->load(langFile, (*it)))
207 qApp->installTranslator(tQCadCmd);
210 langFile = "qcadlib_" + lang + ".qm";
212 if (tQCadLib != NULL)
214 qApp->removeTranslator(tQCadLib);
218 tQCadLib = new QTranslator(0);
220 if (tQCadLib->load(langFile, (*it)))
222 qApp->installTranslator(tQCadLib);
225 langFile = "qcadcam_" + lang + ".qm";
227 if (tQCadLib != NULL)
229 qApp->removeTranslator(tQCadCam);
233 tQCadCam = new QTranslator(0);
235 if (tQCadCam->load(langFile, (*it)))
237 qApp->installTranslator(tQCadCam);
240 langFile = "qcadprof_" + lang + ".qm";
242 if (tQCadProf != NULL)
244 qApp->removeTranslator(tQCadProf);
248 tQCadProf = new QTranslator(0);
250 if (tQCadProf->load(langFile, (*it)))
252 qApp->installTranslator(tQCadProf);
258 * Checks if the system has been initialized and prints a warning
259 * otherwise to stderr.
261 bool System::checkInit()
265 DEBUG->print(Debug::D_WARNING, "System::checkInit: System not initialized.\n"
266 "Use SYSTEM->init(appname, appdirname) to do so.");
273 * Creates all given directories in the user's home.
275 bool System::createHomePath(const QString & p)
279 // QStringList dirs = QStringList::split('/', p, false);
280 QStringList dirs = p.split('/', QString::SkipEmptyParts);
281 QString created = getHomeDir();
283 for(QStringList::Iterator it=dirs.begin(); it!=dirs.end(); ++it)
285 created += QString("/%1").arg(*it);
287 // if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created, true))
288 if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created))
290 DEBUG->print("System::createHomePath: Created directory '%s'",
291 created.toLatin1().data());
295 DEBUG->print(Debug::D_ERROR, "System::createHomePath: Cannot create directory '%s'",
296 created.toLatin1().data());
305 * @return Users home directory.
307 QString System::getHomeDir()
309 // return QDir::homeDirPath();
310 return QDir::homePath();
314 * @return Current directory.
316 QString System::getCurrentDir()
318 // return QDir::currentDirPath();
319 return QDir::currentPath();
323 * @return Application directory.
325 QString System::getAppDir()
331 * @return A list of absolute paths to all font files found.
333 QStringList System::getFontList()
335 QStringList ret = getFileList("fonts", "cxf");
340 * @return A list of absolute paths to all hatch pattern files found.
342 QStringList System::getPatternList()
344 QStringList ret = getFileList("patterns", "dxf");
349 * @return A list of absolute paths to all script files found.
351 QStringList System::getScriptList()
353 QStringList ret = getFileList("scripts/qsa", "qs");
358 * @return A list of absolute paths to all machine configuration files found.
360 QStringList System::getMachineList()
362 QStringList ret = getFileList("machines", "cxm");
367 * @return Absolute path to the documentation.
369 QString System::getDocPath()
371 QStringList lst = getDirectoryList("doc");
376 * @return The application name.
378 QString System::getAppName()
384 * @return The application version.
386 QString System::getAppVersion()
392 * Searches for files in an application shared directory in the given
393 * subdirectory with the given extension.
395 * @return List of the absolute paths of the files found.
397 QStringList System::getFileList(const QString & subDirectory, const QString & fileExtension)
401 /*QStringList dirList;
404 dirList.append("/usr/share/" + appDirName);
407 dirList.append("/usr/X11R6/" + appDirName);
409 dirList.append("/usr/X11R6/share/" + appDirName);
410 dirList.append(getHomeDir() + "/." + appDirName);
414 //dirList.append(getCurrentDir());
417 /usr/share/doc/qcad/html/en/
420 QStringList dirList = getDirectoryList(subDirectory);
422 QStringList fileList;
426 for(QStringList::Iterator it=dirList.begin(); it!=dirList.end(); ++it)
428 //path = QString(*it) + "/" + subDirectory;
432 if (dir.exists() && dir.isReadable())
434 // QStringList files = dir.entryList("*." + fileExtension);
436 filters << "*." + fileExtension;
437 QStringList files = dir.entryList(filters);
439 for(QStringList::Iterator it2=files.begin(); it2!=files.end(); it2++)
440 fileList += path + "/" + (*it2);
448 * @return List of all directories in subdirectory 'subDirectory' in
449 * all possible QCad directories.
451 QStringList System::getDirectoryList(const QString & subDirectory)
456 if (subDirectory != "library")
459 // Local (application) directory has priority over other dirs:
460 if (!appDir.isEmpty() && appDir != "/" && appDir != getHomeDir())
462 dirList.append(appDir + "/" + subDirectory);
466 dirList.append("/usr/share/" + appDirName + "/" + subDirectory);
468 dirList.append("/usr/X11R6/" + appDirName + "/" + subDirectory);
469 dirList.append("/usr/X11R6/share/" + appDirName + "/" + subDirectory);
470 //This is what's picking up crap in .architektonas...
471 //We'll take it out for now...
472 //But maybe we can check to see if it's "library" and bypass if so...
473 // dirList.append(getHomeDir() + "/." + appDirName + "/" + subDirectory);
479 // Mac OS X - don't scan for library since this might lead us into the
480 // wrong directory tree:
481 if (!appDir.isEmpty() && appDir != "/" /*&& subDirectory!="library"*/)
483 dirList.append(appDir + "/../Resources/" + subDirectory);
484 dirList.append(appDir + "/../../../" + subDirectory);
488 // Individual directories:
489 settings.beginGroup("Paths");
491 if (subDirectory == "fonts")
493 dirList += settings.value("Fonts", "").toString().split(QRegExp("[;]"));
495 else if (subDirectory == "patterns")
497 dirList += settings.value("Patterns", "").toString().split(QRegExp("[;]"));
499 else if (subDirectory.startsWith("scripts"))
501 dirList += settings.value("Scripts", "").toString().split(QRegExp("[;]"));
503 else if (subDirectory.startsWith("library"))
505 dirList += settings.value("Library", "").toString().split(QRegExp("[;]"));
507 else if (subDirectory.startsWith("po"))
509 dirList += settings.value("Translations", "").toString().split(QRegExp("[;]"));
516 DEBUG->print("System::getDirectoryList: Paths:");
518 for(QStringList::Iterator it=dirList.begin(); it!=dirList.end(); ++it)
520 if (QFileInfo(*it).isDir())
523 DEBUG->print((*it).toLatin1().data());
524 //printf("System: *it=\"%s\"\n", (*it).toAscii().data());
531 QStringList System::getLanguageList()
537 * Converts a language string to a symbol (e.g. Deutsch or German to 'de').
539 * Supported languages: http://ftp.ics.uci.edu/pub/ietf/http/related/iso639.txt
541 QString System::languageToSymbol(const QString& lang)
543 QString l = lang.toLower();
545 // don't use else if.. M$ visual wannabe c++ can't handle it
550 if (l=="abkhazian") {
553 if (l=="afrikaans") {
568 if (l=="azerbaijani") {
574 if (l=="byelorussian") {
577 if (l=="bulgarian") {
586 if (l=="bengali" || l=="bangla") {
610 if (l=="german" || l=="deutsch") {
622 if (l=="esperanto") {
646 if (l=="french" || l=="francais") {
655 if (l=="scots gaelic" || l=="gaelic") {
679 if (l=="hungarian") {
685 if (l=="interlingua") {
688 if (l=="indonesian") {
691 if (l=="interlingue") {
697 if (l=="icelandic") {
703 if (l=="inuktitut") {
718 if (l=="greenlandic") {
721 if (l=="cambodian") {
748 if (l=="lithuanian") {
751 if (l=="latvian" || l=="lettish") {
760 if (l=="macedonian") {
763 if (l=="malayalam") {
766 if (l=="mongolian") {
769 if (l=="moldavian") {
793 if (l=="norwegian") {
799 if (l=="afan" || l=="oromo" || l=="afan oromo") {
811 if (l=="pashto" || l=="pushto") {
814 if (l=="portuguese") {
817 if (l=="brasilian portuguese") {
823 if (l=="rhaeto-romance") {
835 if (l=="kinyarwanda") {
847 if (l=="serbo-Croatian") {
850 if (l=="sinhalese") {
856 if (l=="slovenian") {
880 if (l=="sundanese") {
931 if (l=="ukrainian") {
940 if (l=="vietnamese") {
972 * Converst a language two-letter-code into a readable string
973 * (e.g. 'de' to Deutsch)
975 QString System::symbolToLanguage(const QString & symb)
977 QString l = symb.toLower();
1001 return "Azerbaijani";
1007 return "Byelorussian";
1088 return "Scots Gaelic";
1118 return "Interlingua";
1121 return "Indonesian";
1124 return "Interlingue";
1151 return "Greenlandic";
1181 return "Lithuanian";
1193 return "Macedonian";
1232 return "Afan Oromo";
1247 return "Portuguese";
1250 return "Brasilian Portuguese";
1256 return "Rhaeto-Romance";
1268 return "Kinyarwanda";
1280 return "Serbo-croatian";
1373 return "Vietnamese";
1404 * Tries to convert the given encoding string to an encoding Qt knows.
1406 QString System::getEncoding(const QString & str)
1408 QString l=str.toLower();
1410 if (l=="latin1" || l=="ansi_1252" || l=="iso-8859-1" ||
1411 l=="cp819" || l=="csiso" || l=="ibm819" || l=="iso_8859-1" ||
1412 l=="iso8859-1" || l=="iso-ir-100" || l=="l1") {
1414 } else if (l=="big5" || l=="ansi_950" || l=="cn-big5" || l=="csbig5" ||
1417 } else if (l=="big5-hkscs") {
1418 return "Big5-HKSCS";
1419 } else if (l=="eucjp" || l=="euc-jp" || l=="cseucpkdfmtjapanese" ||
1420 l=="x-euc" || l=="x-euc-jp") {
1422 } else if (l=="euckr") {
1424 } else if (l=="gb2312" || l=="gb2312" || l=="chinese" || l=="cn-gb" ||
1425 l=="csgb2312" || l=="csgb231280" || l=="csiso58gb231280" ||
1426 l=="gb_2312-80" || l=="gb231280" || l=="gb2312-80" || l=="gbk" ||
1429 } else if (l=="gbk") {
1431 } else if (l=="gb18030") {
1433 } else if (l=="jis7") {
1435 } else if (l=="shift-jis" || l=="ansi_932" || l=="shift_jis" || l=="csShiftJIS" ||
1436 l=="cswindows31j" || l=="ms_kanji" || l=="x-ms-cp932" || l=="x-sjis") {
1438 } else if (l=="tscii") {
1440 } else if (l=="utf88-bit") {
1442 } else if (l=="utf16") {
1444 } else if (l=="koi8-r") {
1446 } else if (l=="koi8-u") {
1448 } else if (l=="iso8859-1") {
1450 } else if (l=="iso8859-2") {
1452 } else if (l=="iso8859-3") {
1454 } else if (l=="iso8859-4" || l=="ansi_1257") {
1456 } else if (l=="iso8859-5") {
1458 } else if (l=="iso8859-6" || l=="ansi_1256") {
1460 } else if (l=="iso8859-7" || l=="ansi_1253") {
1462 } else if (l=="iso8859-8") {
1464 } else if (l=="iso8859-8-i" || l=="ansi_1255") {
1465 return "ISO8859-8-i";
1466 } else if (l=="iso8859-9" || l=="ansi_1254") {
1468 } else if (l=="iso8859-10") {
1469 return "ISO8859-10";
1470 } else if (l=="iso8859-13") {
1471 return "ISO8859-13";
1472 } else if (l=="iso8859-14") {
1473 return "ISO8859-14";
1474 } else if (l=="iso8859-15") {
1475 return "ISO8859-15";
1476 } else if (l=="ibm 850") {
1478 } else if (l=="ibm 866") {
1480 } else if (l=="cp874") {
1482 } else if (l=="cp1250") {
1484 } else if (l=="cp1251") {
1486 } else if (l=="cp1252") {
1488 } else if (l=="cp1253") {
1490 } else if (l=="cp1254") {
1492 } else if (l=="cp1255") {
1494 } else if (l=="cp1256") {
1496 } else if (l=="cp1257") {
1498 } else if (l=="cp1258") {
1500 } else if (l=="apple roman") {
1501 return "Apple Roman";
1502 } else if (l=="tis-620") {
1509 /** Returns ISO code for given locale. Needed for win32 to convert
1510 from system encodings.
1511 Locale names mostly copied from XFree86.
1513 The code may be incomplete (chinese/japanese locales, etc.)
1515 2004-05-13, J Staniek
1517 static QMap<QString, QString> loc_map;
1519 QString System::localeToISO(const QString & locale)
1521 if (loc_map.isEmpty())
1523 loc_map["croatian"]="ISO8859-2";
1524 loc_map["cs"]="ISO8859-2";
1525 loc_map["cs_CS"]="ISO8859-2";
1526 loc_map["cs_CZ"]="ISO8859-2";
1527 loc_map["cz"]="ISO8859-2";
1528 loc_map["cz_CZ"]="ISO8859-2";
1529 loc_map["czech"]="ISO8859-2";
1530 loc_map["hr"]="ISO8859-2";
1531 loc_map["hr_HR"]="ISO8859-2";
1532 loc_map["hu"]="ISO8859-2";
1533 loc_map["hu_HU"]="ISO8859-2";
1534 loc_map["hungarian"]="ISO8859-2";
1535 loc_map["pl"]="ISO8859-2";
1536 loc_map["pl_PL"]="ISO8859-2";
1537 loc_map["polish"]="ISO8859-2";
1538 loc_map["ro"]="ISO8859-2";
1539 loc_map["ro_RO"]="ISO8859-2";
1540 loc_map["rumanian"]="ISO8859-2";
1541 loc_map["serbocroatian"]="ISO8859-2";
1542 loc_map["sh"]="ISO8859-2";
1543 loc_map["sh_SP"]="ISO8859-2";
1544 loc_map["sh_YU"]="ISO8859-2";
1545 loc_map["sk"]="ISO8859-2";
1546 loc_map["sk_SK"]="ISO8859-2";
1547 loc_map["sl"]="ISO8859-2";
1548 loc_map["sl_CS"]="ISO8859-2";
1549 loc_map["sl_SI"]="ISO8859-2";
1550 loc_map["slovak"]="ISO8859-2";
1551 loc_map["slovene"]="ISO8859-2";
1552 loc_map["sr_SP"]="ISO8859-2";
1554 loc_map["eo"]="ISO8859-3";
1556 loc_map["ee"]="ISO8859-4";
1557 loc_map["ee_EE"]="ISO8859-4";
1559 loc_map["mk"]="ISO8859-5";
1560 loc_map["mk_MK"]="ISO8859-5";
1561 loc_map["sp"]="ISO8859-5";
1562 loc_map["sp_YU"]="ISO8859-5";
1564 loc_map["ar_AA"]="ISO8859-6";
1565 loc_map["ar_SA"]="ISO8859-6";
1566 loc_map["arabic"]="ISO8859-6";
1568 loc_map["el"]="ISO8859-7";
1569 loc_map["el_GR"]="ISO8859-7";
1570 loc_map["greek"]="ISO8859-7";
1572 loc_map["hebrew"]="ISO8859-8";
1573 loc_map["he"]="ISO8859-8";
1574 loc_map["he_IL"]="ISO8859-8";
1575 loc_map["iw"]="ISO8859-8";
1576 loc_map["iw_IL"]="ISO8859-8";
1578 loc_map["tr"]="ISO8859-9";
1579 loc_map["tr_TR"]="ISO8859-9";
1580 loc_map["turkish"]="ISO8859-9";
1582 loc_map["lt"]="ISO8859-13";
1583 loc_map["lt_LT"]="ISO8859-13";
1584 loc_map["lv"]="ISO8859-13";
1585 loc_map["lv_LV"]="ISO8859-13";
1587 loc_map["et"]="ISO8859-15";
1588 loc_map["et_EE"]="ISO8859-15";
1589 loc_map["br_FR"]="ISO8859-15";
1590 loc_map["ca_ES"]="ISO8859-15";
1591 loc_map["de"]="ISO8859-15";
1592 loc_map["de_AT"]="ISO8859-15";
1593 loc_map["de_BE"]="ISO8859-15";
1594 loc_map["de_DE"]="ISO8859-15";
1595 loc_map["de_LU"]="ISO8859-15";
1596 loc_map["en_IE"]="ISO8859-15";
1597 loc_map["es"]="ISO8859-15";
1598 loc_map["es_ES"]="ISO8859-15";
1599 loc_map["eu_ES"]="ISO8859-15";
1600 loc_map["fi"]="ISO8859-15";
1601 loc_map["fi_FI"]="ISO8859-15";
1602 loc_map["finnish"]="ISO8859-15";
1603 loc_map["fr"]="ISO8859-15";
1604 loc_map["fr_FR"]="ISO8859-15";
1605 loc_map["fr_BE"]="ISO8859-15";
1606 loc_map["fr_LU"]="ISO8859-15";
1607 loc_map["french"]="ISO8859-15";
1608 loc_map["ga_IE"]="ISO8859-15";
1609 loc_map["gl_ES"]="ISO8859-15";
1610 loc_map["it"]="ISO8859-15";
1611 loc_map["it_IT"]="ISO8859-15";
1612 loc_map["oc_FR"]="ISO8859-15";
1613 loc_map["nl"]="ISO8859-15";
1614 loc_map["nl_BE"]="ISO8859-15";
1615 loc_map["nl_NL"]="ISO8859-15";
1616 loc_map["pt"]="ISO8859-15";
1617 loc_map["pt_PT"]="ISO8859-15";
1618 loc_map["sv_FI"]="ISO8859-15";
1619 loc_map["wa_BE"]="ISO8859-15";
1621 loc_map["uk"]="KOI8-U";
1622 loc_map["uk_UA"]="KOI8-U";
1623 loc_map["ru_YA"]="KOI8-U";
1624 loc_map["ukrainian"]="KOI8-U";
1626 loc_map["be"]="KOI8-R";
1627 loc_map["be_BY"]="KOI8-R";
1628 loc_map["bg"]="KOI8-R";
1629 loc_map["bg_BG"]="KOI8-R";
1630 loc_map["bulgarian"]="KOI8-R";
1631 loc_map["ba_RU"]="KOI8-R";
1632 loc_map["ky"]="KOI8-R";
1633 loc_map["ky_KG"]="KOI8-R";
1634 loc_map["kk"]="KOI8-R";
1635 loc_map["kk_KZ"]="KOI8-R";
1638 QString l = loc_map[locale];