[KLF Application][KLF Tools][KLF Backend][KLF Home]
KLatexFormula Project
klfmain.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * file klfmain.cpp
3  * This file is part of the KLatexFormula Project.
4  * Copyright (C) 2011 by Philippe Faist
5  * philippe.faist at bluewin.ch
6  * *
7  * This program is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program; if not, write to the *
19  * Free Software Foundation, Inc., *
20  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  ***************************************************************************/
22 /* $Id: klfmain.cpp 603 2011-02-26 23:14:55Z phfaist $ */
23 
24 #include <QDebug>
25 #include <QString>
26 #include <QList>
27 #include <QObject>
28 #include <QDomDocument>
29 #include <QFile>
30 #include <QFileInfo>
31 #include <QResource>
32 #include <QDir>
33 #include <QTranslator>
34 #include <QLibraryInfo>
35 
36 #include <klfutil.h>
37 #include "klfpluginiface.h"
38 #include "klfconfig.h"
39 #include "klfmain.h"
40 
41 
43 
45 
46 
47 
48 
49 
51 
52 
53 
55 bool klf_addons_canimport = false;
56 
57 
58 
59 KLFAddOnInfo::KLFAddOnInfo(QString rccfpath, bool isFresh)
60 {
61  d = new Private;
62  d->ref = 1;
63  klfDbg( "KLFAddOnInfo: rccfpath="<<rccfpath<<", Private has ref "<< d->ref ) ;
64 
65  QFileInfo fi(rccfpath);
66 
67  d->fname = fi.fileName();
68  d->dir = fi.absolutePath();
69  d->fpath = fi.absoluteFilePath();
70 
71  d->islocal = fi.isWritable() || QFileInfo(d->dir).isWritable();
72 
73  d->isfresh = isFresh;
74 
75  QByteArray rccinfodata;
76 
77  // mount the resource locally
78  QString mountroot;
79  QString suffix;
80  QString minrccfpath = rccfpath.section("/", -1, -1, QString::SectionSkipEmpty);
81  int k = 0;
82  // find a unique mountroot name
83  while (QFileInfo(mountroot = QString(":/klfaddon_rccmount/%1%2").arg(minrccfpath, suffix)).exists()) {
84  suffix = QString("_%1").arg(++k);
85  }
86  d->rccmountroot = mountroot;
87  klfDbg( "Mounting resource "<<rccfpath<<" to "<<d->rccmountroot ) ;
88 
89  bool ok = QResource::registerResource(d->fpath, mountroot);
90  KLF_ASSERT_CONDITION(ok, "Failed to register resource "<<rccfpath, return; ) ;
91 
92  // read the RCC's info.xml content
93  { // code block brackets {} are to close the file immediately after reading.
94  QFile infofile(mountroot+QLatin1String("/rccinfo/info.xml"));
95  infofile.open(QIODevice::ReadOnly);
96  rccinfodata = infofile.readAll();
97  }
98 
99  // read translation list
100  QDir i18ndir(mountroot+QLatin1String("/i18n/"));
101  d->translations = i18ndir.entryList(QStringList() << "*.qm", QDir::Files);
102 
103  // set default values for title, author, description, and klfminversion in case the XML file
104  // does not provide any
105  d->title = QObject::tr("(Name Not Provided)", "[KLFAddOnInfo: add-on information XML data is invalid]");
106  d->description = QObject::tr("(Invalid XML Data Provided By Add-On)",
107  "[KLFAddOnInfo: add-on information XML data is invalid]");
108  d->klfminversion = QString();
109  d->author = QObject::tr("(No Author Provided)",
110  "[KLFAddOnInfo: add-on information XML data is invalid]");
111 
112  // parse resource's rccinfo/info.xml file
113  QDomDocument xmldoc;
114  xmldoc.setContent(rccinfodata);
115  // and explore the document
116  QDomElement xmlroot = xmldoc.documentElement();
117  if (xmlroot.nodeName() != "rccinfo") {
118  qWarning("Add-on file `%s' has invalid XML information.", qPrintable(rccfpath));
119  return;
120  }
121  QDomNode n;
122  for (n = xmlroot.firstChild(); ! n.isNull(); n = n.nextSibling()) {
123  QDomElement e = n.toElement();
124  if ( e.isNull() || n.nodeType() != QDomNode::ElementNode )
125  continue;
126  if ( e.nodeName() == "title" ) {
127  d->title = e.text().trimmed();
128  }
129  if ( e.nodeName() == "author" ) {
130  d->author = e.text().trimmed();
131  }
132  if ( e.nodeName() == "description" ) {
133  d->description = e.text().trimmed();
134  }
135  if ( e.nodeName() == "klfminversion" ) {
136  d->klfminversion = e.text().trimmed();
137  }
138  }
139 
140  initPlugins();
141 }
142 
143 KLF_EXPORT QDebug& operator<<(QDebug& str, const KLFAddOnInfo::PluginSysInfo& i)
144 {
145  return str << "KLFAddOnInfo::PluginSysInfo(qtminver="<<i.qtminversion<<"; klfminver="<<i.klfminversion
146  << "; os="<<i.os<<"; arch="<<i.arch<<")";
147 }
148 
149 
151 {
152  return
154  || klfVersionCompare(klfminversion, KLF_VERSION_STRING) <= 0) &&
156  || klfVersionCompare(qtminversion, qVersion()) <= 0) &&
157  os == KLFSysInfo::osString() &&
158  arch == KLFSysInfo::arch() ;
159 }
160 
161 
162 void KLFAddOnInfo::initPlugins()
163 {
164  // read plugin list
165  QDir plugdir(d->rccmountroot+QLatin1String("/plugins/"));
166  PluginSysInfo defpinfo;
167  defpinfo.qtminversion = ""; // by default -> no version check (empty string)
168  defpinfo.klfminversion = ""; // by default -> no version check (empty string)
169  defpinfo.os = KLFSysInfo::osString(); // by default, current OS.
170  defpinfo.arch = KLFSysInfo::arch(); // by default, current arch.
171  d->plugins = QMap<QString,PluginSysInfo>();
172  d->pluginList = QStringList();
173 
174  // first add all plugins that are in :/plugins
175  QStringList unorderedplugins = plugdir.entryList(KLF_DLL_EXT_LIST, QDir::Files);
176  int k;
177  for (k = 0; k < unorderedplugins.size(); ++k) {
178  d->pluginList << unorderedplugins[k];
179  d->plugins[unorderedplugins[k]] = defpinfo;
180  }
181 
182  if (!QFile::exists(plugdir.absoluteFilePath("plugindirinfo.xml"))) {
183  klfDbg( "KLFAddOnInfo("<<d->fname<<"): No specific plugin directories. plugdirinfo.xml="
184  <<plugdir.absoluteFilePath("plugindirinfo.xml") ) ;
185  return;
186  }
187 
188  // no plugin dirs.
189  QFile plugdirinfofile(d->rccmountroot+QLatin1String("/plugins/plugindirinfo.xml"));
190  plugdirinfofile.open(QIODevice::ReadOnly);
191  QByteArray plugdirinfodata = plugdirinfofile.readAll();
192 
193  // here, key is the plugin _dir_ itself.
194  QMap<QString,PluginSysInfo> pdirinfos;
195 
196  // parse resource's plugins/plugindirinfo.xml file
197  QDomDocument xmldoc;
198  xmldoc.setContent(plugdirinfodata);
199  // and explore the document
200  QDomElement xmlroot = xmldoc.documentElement();
201  if (xmlroot.nodeName() != "klfplugindirs") {
202  qWarning("KLFAddOnInfo: Add-on plugin dir info file `%s' has invalid XML information.",
203  qPrintable(d->fpath));
204  return;
205  }
206  QDomNode n;
207  for (n = xmlroot.firstChild(); ! n.isNull(); n = n.nextSibling()) {
208  QDomElement e = n.toElement();
209  if ( e.isNull() || n.nodeType() != QDomNode::ElementNode )
210  continue;
211  if ( e.nodeName() != "klfplugindir" ) {
212  qWarning("KLFAddOnInfo(%s): plugindirinfo.xml: skipping unexpected node %s.", qPrintable(d->fpath),
213  qPrintable(e.nodeName()));
214  continue;
215  }
216  // read a plugin dir info
217  PluginSysInfo psi;
218  QDomNode nn;
219  for (nn = e.firstChild(); ! nn.isNull(); nn = nn.nextSibling()) {
220  QDomElement ee = nn.toElement();
221  klfDbg( "Node: type="<<nn.nodeType()<<"; name="<<ee.nodeName() ) ;
222  if ( ee.isNull() || nn.nodeType() != QDomNode::ElementNode )
223  continue;
224  if ( ee.nodeName() == "dir" ) {
225  psi.dir = ee.text().trimmed();
226  } else if ( ee.nodeName() == "qtminversion" ) {
227  psi.qtminversion = ee.text().trimmed();
228  } else if ( ee.nodeName() == "klfminversion" ) {
229  psi.klfminversion = ee.text().trimmed();
230  } else if ( ee.nodeName() == "os" ) {
231  psi.os = ee.text().trimmed();
232  } else if ( ee.nodeName() == "arch" ) {
233  psi.arch = ee.text().trimmed();
234  } else {
235  qWarning("KLFAddOnInfo(%s): plugindirinfo.xml: skipping unexpected node in <klfplugindirs>: %s.",
236  qPrintable(d->fpath), qPrintable(ee.nodeName()));
237  }
238  }
239  klfDbg( "\tRead psi="<<psi ) ;
240  // add this plugin dir info
241  pdirinfos[psi.dir] = psi;
242  }
243 
244  QStringList morePluginsList;
245  for (QMap<QString,PluginSysInfo>::const_iterator it = pdirinfos.begin(); it != pdirinfos.end(); ++it) {
246  QString dir = it.key();
247  PluginSysInfo psi = it.value();
248  if ( ! QFileInfo(d->rccmountroot + "/plugins/" + dir).exists() ) {
249  qWarning("KLFAddOnInfo(%s): Plugin dir '%s' given in XML info does not exist in resource!",
250  qPrintable(d->fpath), qPrintable(dir));
251  continue;
252  }
253  QDir plugsubdir(d->rccmountroot + "/plugins/" + dir);
254  QStringList plugins = plugsubdir.entryList(KLF_DLL_EXT_LIST, QDir::Files);
255  int j;
256  for (j = 0; j < plugins.size(); ++j) {
257  QString p = dir+"/"+plugins[j];
258  morePluginsList << p;
259  d->plugins[p] = psi;
260  }
261  }
262  // prepend morePluginsList to d->pluginList
263  QStringList fullList = morePluginsList;
264  fullList << d->pluginList;
265  d->pluginList = fullList;
266 
267  klfDbg( "Loaded plugins: list="<<d->pluginList<<"; map="<<d->plugins ) ;
268 }
269 
270 
272 {
273  QStringList lplugins;
274  for (int k = 0; k < d->pluginList.size(); ++k) {
275  if ( d->plugins[d->pluginList[k]].isCompatibleWithCurrentSystem() )
276  lplugins << QDir::cleanPath(pluginLocalSubDirName(d->pluginList[k])+"/"+QFileInfo(d->pluginList[k]).fileName());
277  }
278  return lplugins;
279 }
280 
281 
283 {
284  d = other.d;
285  if (d)
286  d->ref++;
287 }
288 
290 {
291  if (d) {
292  d->ref--;
293  if (d->ref <= 0) {
294  // finished reading this resource, un-register it.
295  QResource::unregisterResource(d->fpath, d->rccmountroot);
296  delete d;
297  }
298  }
299 }
300 
301 
302 
303 
305 {
306  QFileInfo fi(filepath);
307  QString fn = fi.fileName();
308  QDir d = fi.absoluteDir();
309 
310  int firstunderscore = fn.indexOf('_');
311  int endbasename = fn.endsWith(".qm") ? fn.length() - 3 : fn.length() ;
312  if (firstunderscore == -1)
313  firstunderscore = endbasename; // no locale part if no underscore
314  // ---
315  fpath = d.absoluteFilePath(fn);
316  name = fn.mid(0, firstunderscore);
317  locale = fn.mid(firstunderscore+1, endbasename-(firstunderscore+1));
318  locale_specificity = (locale.split('_', QString::SkipEmptyParts)).size() ;
319 }
320 
321 
322 
323 
325 {
327  klfDbg("i18nfile.fpath="<<i18nfile.fpath<<" is translation to "<<i18nfile.locale) ;
328 
329  QFileInfo fi(i18nfile.fpath);
330 
331  klfDbg("fi.canonicalPath()="<<fi.canonicalPath()<<", Qt translations location="
332  <<QFileInfo(QLibraryInfo::location(QLibraryInfo::TranslationsPath)).canonicalFilePath()) ;
333 
334  if ( fi.canonicalPath() ==
335  QFileInfo(QLibraryInfo::location(QLibraryInfo::TranslationsPath)).canonicalFilePath()
336  || i18nfile.name == "qt" ) {
337  // ignore Qt's translations as available languages (identified as being in Qt's
338  // translation path or as a locally named qt_XX.qm
339  return;
340  }
341 
342  // Check if this locale is registered, and if it has a nice translated name.
343  bool needsRegistration = true;
344  bool needsNiceName = true;
345  int alreadyRegisteredIndex = -1;
346 
347  int kk;
348  for (kk = 0; kk < klf_avail_translations.size(); ++kk) {
349  if (klf_avail_translations[kk].localename == i18nfile.locale) {
350  needsRegistration = false;
351  alreadyRegisteredIndex = kk;
352  needsNiceName = ! klf_avail_translations[kk].hasnicetranslatedname;
353  klfDbg("translation "<<i18nfile.locale<<" is already registered. needs nice name?="<< needsNiceName) ;
354  }
355  }
356 
357  klfDbg("Needs registration?="<<needsRegistration<<"; needs nice name?="<<needsNiceName) ;
358  if ( ! needsRegistration && ! needsNiceName ) {
359  // needs nothing more !
360  return;
361  }
362 
363  klfDbg("will load translation file "<<fi.completeBaseName()<<", abs path="<<fi.absolutePath()) ;
364 
365  // needs something (registration and/or nice name)
366  QTranslator translator;
367  translator.load(fi.completeBaseName(), fi.absolutePath(), "_", "."+fi.suffix());
369  ti.localename = i18nfile.locale;
370  struct klf_qtTrNoop3 { const char *source; const char *comment; };
371  klf_qtTrNoop3 lang
372  = QT_TRANSLATE_NOOP3("QObject", "English (US)",
373  "[[The Language (possibly with Country) you are translating to, e.g. `Deutsch']]");
374  ti.translatedname = translator.translate("QObject", lang.source, lang.comment);
375  ti.hasnicetranslatedname = true;
376  if (ti.translatedname == "English" || ti.translatedname.isEmpty()) {
377  QLocale lc(i18nfile.locale);
378  QString s;
379  if ( i18nfile.locale.indexOf("_") != -1 ) {
380  // has country information in locale
381  s = QString("%1 (%2)").arg(QLocale::languageToString(lc.language()))
382  .arg(QLocale::countryToString(lc.country()));
383  } else {
384  s = QString("%1").arg(QLocale::languageToString(lc.language()));
385  }
386  ti.translatedname = s;
387  ti.hasnicetranslatedname = false;
388  }
389  if (needsRegistration)
390  klf_avail_translations.append(ti);
391  else if (needsNiceName && ti.hasnicetranslatedname)
392  klf_avail_translations[alreadyRegisteredIndex] = ti;
393 }
394 
395 
396 KLF_EXPORT void klf_reload_translations(QCoreApplication *app, const QString& currentLocale)
397 {
398  // refresh and load all translations. Translations are files found in the form
399  // :/i18n/<name>_<locale>.qm or homeconfig/i18n/<name>_<locale>.qm
400  //
401  // this function may be called at run-time to change language.
402 
403  int j, k;
404 
405  // clear any already set translators
406  for (k = 0; k < klf_translators.size(); ++k) {
408  delete klf_translators[k];
409  }
410  klf_translators.clear();
411 
412  // we will find all possible .qm files and store them in this structure for easy access
413  // structure is indexed by name, then locale specificity
415  // a list of names. this is redundant for i18nFiles.keys()
416  QSet<QString> names;
417 
418  QStringList i18ndirlist;
419  // add any add-on specific translations
420  for (k = 0; k < klf_addons.size(); ++k) {
421  i18ndirlist << klf_addons[k].rccmountroot()+"/i18n";
422  }
423  i18ndirlist << ":/i18n"
425  << klfconfig.globalShareDir+"/i18n"
426  << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
427 
428  for (j = 0; j < i18ndirlist.size(); ++j) {
429  // explore this directory; we expect a list of *.qm files
430  QDir i18ndir(i18ndirlist[j]);
431  if ( ! i18ndir.exists() )
432  continue;
433  QStringList files = i18ndir.entryList(QStringList() << QString::fromLatin1("*.qm"), QDir::Files);
434  for (k = 0; k < files.size(); ++k) {
435  KLFI18nFile i18nfile(i18ndir.absoluteFilePath(files[k]));
436  // qDebug("Found i18n file %s (name=%s,locale=%s,lc-spcif.=%d)", qPrintable(i18nfile.fpath),
437  // qPrintable(i18nfile.name), qPrintable(i18nfile.locale), i18nfile.locale_specificity);
438  i18nFiles[i18nfile.name][i18nfile.locale_specificity] << i18nfile;
439  names << i18nfile.name;
440  qDebug("Found translation %s", qPrintable(i18nfile.fpath));
441  klf_add_avail_translation(i18nfile);
442  }
443  }
444 
445  // get locale
446  QString lc = currentLocale;
447  if (lc.isEmpty())
448  lc = "en_US";
449  QStringList lcparts = lc.split("_");
450 
451  // qDebug("Required locale is %s", qPrintable(lc));
452 
453  // a list of translation files to load (absolute paths)
454  QStringList translationsToLoad;
455 
456  // now, load a suitable translator for each encountered name.
457  for (QSet<QString>::const_iterator it = names.begin(); it != names.end(); ++it) {
458  QString name = *it;
459  QMap< int, QList<KLFI18nFile> > translations = i18nFiles[name];
460  int specificity = lcparts.size(); // start with maximum specificity for required locale
461  while (specificity >= 0) {
462  // try to load a translation matching this specificity and locale
463  QString testlocale = QStringList(lcparts.mid(0, specificity)).join("_");
464  // qDebug("Testing locale string %s...", qPrintable(testlocale));
465  // search list:
466  QList<KLFI18nFile> list = translations[specificity];
467  for (j = 0; j < list.size(); ++j) {
468  if (list[j].locale == testlocale) {
469  // qDebug("Found translation file.");
470  // got matching translation file ! Load it !
471  translationsToLoad << list[j].fpath;
472  // and stop searching translation files for this name (break while condition);
473  specificity = -1;
474  }
475  }
476  // If we didn't find a suitable translation, try less specific locale name
477  specificity--;
478  }
479  }
480  // now we have a full list of translation files to load stored in translationsToLoad .
481 
482  // Load Translations:
483  for (j = 0; j < translationsToLoad.size(); ++j) {
484  // load this translator
485  // qDebug("Loading translator %s for %s", qPrintable(translationsToLoad[j]), qPrintable(lc));
486  QTranslator *translator = new QTranslator(app);
487  QFileInfo fi(translationsToLoad[j]);
488  // qDebug("translator->load(\"%s\", \"%s\", \"_\", \"%s\")", qPrintable(fi.completeBaseName()),
489  // qPrintable(fi.absolutePath()), qPrintable("."+fi.suffix()));
490  bool res = translator->load(fi.completeBaseName(), fi.absolutePath(), "_", "."+fi.suffix());
491  if ( res ) {
492  app->installTranslator(translator);
493  klf_translators << translator;
494  } else {
495  qWarning("Failed to load translator %s.", qPrintable(translationsToLoad[j]));
496  delete translator;
497  }
498  }
499 }
500 
501 
502 
503 
504 KLF_EXPORT QString klfFindTranslatedDataFile(const QString& baseFileName, const QString& extension)
505 {
506  QString loc = klfconfig.UI.locale;
507  QStringList suffixes;
508  suffixes << "_"+loc
509  << "_"+loc.section('_',0,0)
510  << "";
511  int k = 0;
512  QString fn;
513  while ( k < suffixes.size() &&
514  ! QFile::exists(fn = QString("%1%2%3").arg(baseFileName, suffixes[k], extension)) ) {
515  klfDbg( "base="<<baseFileName<<" extn="<<extension<<"; tried fn="<<fn ) ;
516  ++k;
517  }
518  if (k >= suffixes.size()) {
519  qWarning()<<KLF_FUNC_NAME<<": Can't find good translated file for "<<qPrintable(baseFileName+extension)
520  <<"! last try was "<<fn;
521  return QString();
522  }
523  return fn;
524 }
525 
526 
527 
528 
529 KLF_EXPORT void klfDataStreamWriteHeader(QDataStream& stream, const QString headermagic)
530 {
531  // QIODevice inherits QObject ... use dynamic properties
532  stream.device()->setProperty("klfDataStreamAppVersion",
533  QVariant::fromValue<QString>(KLF_DATA_STREAM_APP_VERSION));
534 
535  // header always written in QDataStream version Qt_3_3
536  stream.setVersion(QDataStream::Qt_3_3);
537  stream << headermagic
540  << (qint16)QDataStream::Qt_4_4;
541  stream.setVersion(QDataStream::Qt_4_4);
542  // stream is ready to be written to
543 
544 }
545 
546 KLF_EXPORT bool klfDataStreamReadHeader(QDataStream& stream, const QStringList possibleHeaders,
547  QString *readHeader, QString *readCompatKLFVersion)
548 {
550 
551  QString s;
552  stream.setVersion(QDataStream::Qt_3_3);
553  stream >> s;
554  if (!possibleHeaders.contains(s) || stream.status() != QDataStream::Ok) {
555  klfDbg("Read bad header: "<<s) ;
556  if (readHeader != NULL)
557  *readHeader = QString();
558  return false;
559  }
560  if (readHeader != NULL)
561  *readHeader = s;
562 
563  // read KLF-compat writing version
564  qint16 vmaj, vmin;
565  stream >> vmaj >> vmin;
566  if (stream.status() != QDataStream::Ok) {
567  if (readCompatKLFVersion)
568  *readCompatKLFVersion = QString();
569  return false;
570  }
571  klfDbg("read app compat version = "<<vmaj<<"."<<vmin) ;
572 
573  QString compatKLFVersion = QString("%1.%2").arg(vmaj).arg(vmin);
574 
575  if (vmaj > klfVersionMaj() || (vmaj == klfVersionMaj() && vmin > klfVersionMin())) {
576  if (readCompatKLFVersion != NULL)
577  *readCompatKLFVersion = compatKLFVersion;
578  return false;
579  }
580 
581  // decide on QDataStream version
582  if (vmaj <= 2) { // 2.x: version # not saved into stream, use Qt_3_3
583  stream.setVersion(QDataStream::Qt_3_3);
584  } else { // 3.x+: read version # from stream and set it
585  qint16 version;
586  stream >> version;
587  stream.setVersion(version);
588  }
589 
590  // set the compatibility version for reading data
591  // QIODevice inherits QObject ... use dynamic properties
592  stream.device()->setProperty("klfDataStreamAppVersion", QVariant::fromValue<QString>(compatKLFVersion));
593 
594  // the stream is ready to read data from
595  return true;
596 }
KLF_EXPORT void klf_reload_translations(QCoreApplication *app, const QString &currentLocale)
Definition: klfmain.cpp:396
QStringList translations()
Definition: klfmain.h:135
QString dir()
Definition: klfmain.h:85
registerResource(const QString &rccFileName, const QString &mapRoot=QString()
QString locale
When setting this, don't forget to call QLocale::setDefault().
Definition: klfconfig.h:177
QString pluginLocalSubDirName(const QString &plugin) const
Definition: klfmain.h:117
#define KLF_DATA_STREAM_APP_VERSION_MAJ
'Major' version part of KLF_DATA_STREAM_APP_VERSION.
Definition: klfmain.h:284
QString locale
Locale Name (e.g. "fr" or "fr_CH")
Definition: klfmain.h:246
KLFConfig klfconfig
Definition: klfconfig.cpp:88
struct KLFConfig::@1 UI
QString translatedname
Definition: klfmain.h:217
split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive)
KLF_EXPORT int klfVersionMin()
contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive)
KLF_EXPORT int klfVersionMaj()
languageToString(Language language)
#define klfDbg(streamableItems)
#define KLF_DEBUG_BLOCK(msg)
QString homeConfigDirI18n
Definition: klfconfig.h:158
KLFAddOnInfo(QString rccfpath, bool isFresh=false)
Definition: klfmain.cpp:59
tr(const char *sourceText, const char *comment=0, int n=-1)
bool isCompatibleWithCurrentSystem() const
Definition: klfmain.cpp:150
KLFI18nFile(QString filepath)
Definition: klfmain.cpp:304
QString localename
Definition: klfmain.h:216
QString fpath()
Definition: klfmain.h:89
canonicalFilePath()
QStringList localPluginList() const
Definition: klfmain.cpp:271
entryList(const QStringList &nameFilters, Filters filters=NoFilter, SortFlags sort=NoSort)
absoluteFilePath()
endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive)
QString fpath
Definition: klfmain.h:242
KLF_EXPORT QDebug & operator<<(QDebug &str, const KLFAddOnInfo::PluginSysInfo &i)
Definition: klfmain.cpp:143
open(OpenMode mode)
void klf_add_avail_translation(KLFI18nFile i18nfile)
Definition: klfmain.cpp:324
setVersion(int v)
KLF_EXPORT QString arch()
Small minimalist structure to store basic information about available translations.
Definition: klfmain.h:212
KLF_EXPORT QList< QTranslator * > klf_translators
Definition: klfmain.cpp:44
#define KLF_DLL_EXT_LIST
Definition: klfmain.h:48
#define KLF_FUNC_NAME
KLF_EXPORT QList< KLFTranslationInfo > klf_avail_translations
Definition: klfmain.cpp:42
#define KLF_DATA_STREAM_APP_VERSION
Current datastream compatibility klatexformula version.
Definition: klfmain.h:280
QList< KLFPluginInfo > klf_plugins
Definition: klfmain.cpp:50
load(const QString &filename, const QString &directory=QString()
Small structure to store information for a translation file (.qm)
Definition: klfmain.h:239
installTranslator(QTranslator *translationFile)
cleanPath(const QString &path)
mid(int position, int n=-1)
unregisterResource(const QString &rccFileName, const QString &mapRoot=QString()
KLF_EXPORT QString osString(KLFSysInfo::Os sysos=os())
KLF_EXPORT int klfVersionCompare(const QString &v1, const QString &v2)
KLF_EXPORT QString klfFindTranslatedDataFile(const QString &baseFileName, const QString &extension)
Definition: klfmain.cpp:504
QList< KLFAddOnInfo > klf_addons
Definition: klfmain.cpp:54
absoluteFilePath(const QString &fileName)
removeTranslator(QTranslator *translationFile)
section(QChar sep, int start, int end=-1, SectionFlags flags=SectionDefault)
countryToString(Country country)
completeBaseName()
fromLatin1(const char *str, int size=-1)
QString globalShareDir
Definition: klfconfig.h:152
KLF_EXPORT void klfDataStreamWriteHeader(QDataStream &stream, const QString headermagic)
Definition: klfmain.cpp:529
exists(const QString &name)
bool klf_addons_canimport
Definition: klfmain.cpp:55
#define KLF_ASSERT_CONDITION(expr, msg, failaction)
bool hasnicetranslatedname
TRUE if the translatedname was provided by translator itself.
Definition: klfmain.h:221
location(LibraryLocation loc)
indexOf(const QString &str, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive)
KLF_EXPORT bool klfDataStreamReadHeader(QDataStream &stream, const QStringList possibleHeaders, QString *readHeader, QString *readCompatKLFVersion)
Definition: klfmain.cpp:546
#define KLF_DATA_STREAM_APP_VERSION_MIN
'Minor' version part of KLF_DATA_STREAM_APP_VERSION.
Definition: klfmain.h:286
QString name
Translation file base name (e.g. 'klf' for klf_fr.qm)
Definition: klfmain.h:244
setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg=0, int *errorLine=0, int *errorColumn=0)

Generated by doxygen 1.8.8