QElectroTech  0.70
qetapp.cpp
Go to the documentation of this file.
1 /*
2  Copyright 2006-2019 The QElectroTech Team
3  This file is part of QElectroTech.
4 
5  QElectroTech is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 2 of the License, or
8  (at your option) any later version.
9 
10  QElectroTech is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QElectroTech. If not, see <http://www.gnu.org/licenses/>.
17 */
18 #include "qetapp.h"
19 #include "aboutqet.h"
20 #include "configdialog.h"
21 #include "configpages.h"
22 #include "qetdiagrameditor.h"
23 #include "qetelementeditor.h"
25 #include "titleblocktemplate.h"
26 #include "qettemplateeditor.h"
27 #include "qetproject.h"
29 #include "recentfiles.h"
30 #include "qeticons.h"
31 #include "templatescollection.h"
33 #include "qetmessagebox.h"
34 #include "projectview.h"
35 #include "elementpicturefactory.h"
36 
37 #include <cstdlib>
38 #include <iostream>
39 #define QUOTE(x) STRINGIFY(x)
40 #define STRINGIFY(x) #x
41 #include <QProcessEnvironment>
42 #include "factory/elementfactory.h"
43 
44 #include <KAutoSaveFile>
45 
46 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
47 QString QETApp::common_elements_dir = QString();
48 #endif
49 #ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION
50 QString QETApp::common_tbt_dir_ = QString();
51 #endif
52 #ifdef QET_ALLOW_OVERRIDE_CD_OPTION
53 QString QETApp::config_dir = QString();
54 #endif
55 QString QETApp::lang_dir = QString();
59 QMap<uint, QETProject *> QETApp::registered_projects_ = QMap<uint, QETProject *>();
64 QString QETApp::m_user_common_elements_dir = QString();
65 QString QETApp::m_user_custom_elements_dir = QString();
66 QString QETApp::m_user_custom_tbt_dir = QString();
67 QETApp *QETApp::m_qetapp = nullptr;
68 
69 
74  m_splash_screen(nullptr),
75  non_interactive_execution_(false)
76 {
77  m_qetapp = this;
80  std::exit(EXIT_SUCCESS);
81  }
83  initLanguage();
85  initStyle();
88 
89  connect(&signal_map, SIGNAL(mapped(QWidget *)), this, SLOT(invertMainWindowVisibility(QWidget *)));
90  qApp->setQuitOnLastWindowClosed(false);
91  connect(qApp, &QApplication::lastWindowClosed, this, &QETApp::checkRemainingWindows);
92 
93  setSplashScreenStep(tr("Chargement... Initialisation du cache des collections d'éléments", "splash screen caption"));
94  if (!collections_cache_) {
95  QString cache_path = QETApp::configDir() + "/elements_cache.sqlite";
96  collections_cache_ = new ElementsCollectionCache(cache_path, this);
98  }
99 
100  if (qet_arguments_.files().isEmpty())
101  {
102  setSplashScreenStep(tr("Chargement... Éditeur de schéma", "splash screen caption"));
103  new QETDiagramEditor();
104  } else
105  {
106  setSplashScreenStep(tr("Chargement... Ouverture des fichiers", "splash screen caption"));
108  }
109 
111  if (m_splash_screen) {
112  m_splash_screen -> hide();
113  }
114 
116 }
117 
122 {
125 
126  delete m_splash_screen;
129  delete m_qsti;
130 
135 
138 }
139 
144 {
145  return m_qetapp;
146 }
147 
152 void QETApp::setLanguage(const QString &desired_language) {
153  QString languages_path = languagesPath();
154 
155  // load Qt library translations
156  QString qt_l10n_path = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
157  if (!qtTranslator.load("qt_" + desired_language, qt_l10n_path)) {
158  qtTranslator.load("qt_" + desired_language, languages_path);
159  }
160  qApp->installTranslator(&qtTranslator);
161 
162  // charge les traductions pour l'application QET
163  if (!qetTranslator.load("qet_" + desired_language, languages_path)) {
164  // en cas d'echec, on retombe sur les chaines natives pour le francais
165  if (desired_language != "fr") {
166  // utilisation de la version anglaise par defaut
167  qetTranslator.load("qet_en", languages_path);
168  }
169  }
170  qApp->installTranslator(&qetTranslator);
171 
172  QString ltr_special_string = tr(
173  "LTR",
174  "Translate this string to RTL if you are translating to a Right-to-Left language, else translate to LTR"
175  );
176  if (ltr_special_string == "RTL") switchLayout(Qt::RightToLeft);
177 }
178 
185 {
186  QSettings settings;
187  QString system_language = settings.value("lang", "system").toString();
188  if(system_language == "system") {system_language = QLocale::system().name().left(2);}
189  return system_language;
190 }
194 void QETApp::switchLayout(Qt::LayoutDirection direction) {
195  qApp->setLayoutDirection(direction);
196 }
197 
202 void QETApp::systray(QSystemTrayIcon::ActivationReason reason) {
203  if (!QSystemTrayIcon::isSystemTrayAvailable()) return;
204  switch(reason) {
205  case QSystemTrayIcon::Context:
206  // affichage du menu
208  m_qsti -> contextMenu() -> show();
209  break;
210  case QSystemTrayIcon::DoubleClick:
211  case QSystemTrayIcon::Trigger:
212  // reduction ou restauration de l'application
215  break;
216  case QSystemTrayIcon::Unknown:
217  default: // ne rien faire
218  break;
219  }
220 }
221 
227  every_editor_reduced = true;
228 }
229 
235  every_editor_reduced = false;
236 }
237 
240  setMainWindowsVisible<QETDiagramEditor>(false);
241 }
242 
245  setMainWindowsVisible<QETDiagramEditor>(true);
246 }
247 
250  setMainWindowsVisible<QETElementEditor>(false);
251 }
252 
255  setMainWindowsVisible<QETElementEditor>(true);
256 }
257 
260  setMainWindowsVisible<QETTitleBlockTemplateEditor>(false);
261 }
262 
265  setMainWindowsVisible<QETTitleBlockTemplateEditor>(true);
266 }
267 
270  new QETDiagramEditor();
271 }
272 
275  new QETElementEditor();
276 }
277 
282  return(collections_cache_);
283 }
284 
290 {
291  QStringList info_list;
292  info_list << "formula"
293  << "label"
294  << "plant"
295  << "location"
296 
297  << "comment"
298  << "function"
299  << "tension-protocol"
300  << "auxiliary1"
301  << "auxiliary2"
302 
303  << "description"
304  << "designation"
305  << "manufacturer"
306  << "manufacturer-reference"
307  << "machine-manufacturer-reference"
308  << "supplier"
309  << "quantity"
310  << "unity";
311  return info_list;
312 }
313 
321 QString QETApp::elementTranslatedInfoKey(const QString &info)
322 {
323  if (info == "formula") return tr("Formule du label");
324  else if (info == "label") return tr("Label");
325  else if (info == "plant") return tr("Installation");
326  else if (info == "location") return tr("Localisation");
327 
328  else if (info == "comment") return tr("Commentaire");
329  else if (info == "function") return tr("Fonction");
330  else if (info == "tension-protocol") return tr("Tension / Protocole");
331  else if (info == "auxiliary1") return tr("Bloc auxiliaire 1");
332  else if (info == "auxiliary2") return tr("Bloc auxiliaire 2");
333 
334  else if (info == "description") return tr("Description textuelle");
335  else if (info == "designation") return tr("Numéro d'article");
336  else if (info == "manufacturer") return tr("Fabricant");
337  else if (info == "manufacturer-reference") return tr("Numéro de commande");
338  else if (info == "machine-manufacturer-reference") return tr("Numéro interne");
339  else if (info == "supplier") return tr("Fournisseur");
340  else if (info == "quantity") return tr("Quantité");
341  else if (info == "unity") return tr("Unité");
342 
343 
344 
345 
346  return (info);
347 }
348 
355 QString QETApp::elementInfoToVar(const QString &info)
356 {
357  if (info == "formula") return QString("%{formula}");
358  else if (info == "label") return QString("%{label}");
359  else if (info == "plant") return QString("%{plant}");
360  else if (info == "comment") return QString("%{comment}");
361  else if (info == "description") return QString("%{description}");
362  else if (info == "designation") return QString("%{designation}");
363  else if (info == "manufacturer") return QString("%{manufacturer}");
364  else if (info == "manufacturer-reference") return QString("%{manufacturer-reference}");
365  else if (info == "supplier") return QString("%{supplier}");
366  else if (info == "quantity") return QString("%{quantity}");
367  else if (info == "unity") return QString("%{unity}");
368  else if (info == "auxiliary1") return QString("%{auxiliary1}");
369  else if (info == "auxiliary2") return QString("%{auxiliary2}");
370  else if (info == "machine-manufacturer-reference") return QString("%{machine-manufacturer-reference}");
371  else if (info == "location") return QString("%{location}");
372  else if (info == "function") return QString("%{function}");
373  else if (info == "tension-protocol") return QString("%{tension-protocol}");
374 
375  return (QString ("%{void}"));
376 }
377 
383 {
384  QStringList keys;
385  keys.append("formula");
386  keys.append("text");
387  keys.append("function");
388  keys.append("tension/protocol");
389 
390  return keys;
391 }
392 
399 QString QETApp::conductorTranslatedInfoKey(const QString &key)
400 {
401  if (key == "formula") return tr("Formule du texte");
402  else if (key == "text") return tr("Texte");
403  else if (key == "function") return tr("Fonction");
404  else if (key == "tension/protocol") return tr("Tension / Protocole");
405  return QString();
406 }
407 
413 {
414  QStringList list;
415  list.append("title");
416  list.append("author");
417  list.append("filename");
418  list.append("folio");
419  list.append("plant");
420  list.append("locmach");
421  list.append("indexrev");
422 
423  return list;
424 }
425 
432 QString QETApp::diagramTranslatedInfoKey(const QString &key)
433 {
434  if (key == "title") return tr("Titre");
435  else if (key == "author") return tr("Auteur");
436  else if (key == "filename") return tr("Fichier");
437  else if (key == "folio") return tr("Folio");
438  else if (key == "plant") return tr("Installation");
439  else if (key == "locmach") return tr("Localisation");
440  else if (key == "indexrev") return tr("Indice Rev");
441  else return QString();
442 }
443 
451  m_common_tbt_collection -> setTitle(tr("Cartouches QET", "title of the title block templates collection provided by QElectroTech"));
454  }
455  return(m_common_tbt_collection);
456 }
457 
465  m_custom_tbt_collection -> setTitle(tr("Cartouches utilisateur", "title of the user's title block templates collection"));
468  }
469  return(m_custom_tbt_collection);
470 }
471 
476 QList<TitleBlockTemplatesCollection *> QETApp::availableTitleBlockTemplatesCollections() {
477  QList<TitleBlockTemplatesCollection *> collections_list;
478 
479  collections_list << commonTitleBlockTemplatesCollection();
480  collections_list << customTitleBlockTemplatesCollection();
481 
482  foreach(QETProject *opened_project, registered_projects_) {
483  collections_list << opened_project -> embeddedTitleBlockTemplatesCollection();
484  }
485 
486  return(collections_list);
487 }
488 
494  if (protocol == QETAPP_COMMON_TBT_PROTOCOL) {
495  return(m_common_tbt_collection);
496  } else if (protocol == QETAPP_CUSTOM_TBT_PROTOCOL) {
497  return(m_custom_tbt_collection);
498  } else {
500  if (project) {
501  return(project -> embeddedTitleBlockTemplatesCollection());
502  }
503  }
504  return(nullptr);
505 }
506 
512 {
513  if (m_user_common_elements_dir.isEmpty())
514  {
515  QSettings settings;
516  QString path = settings.value("elements-collections/common-collection-path", "default").toString();
517  if (path != "default" && !path.isEmpty())
518  {
519  QDir dir(path);
520  if (dir.exists())
521  {
524  }
525  }
526  else {
527  m_user_common_elements_dir = "default";
528  }
529  }
530  else if (m_user_common_elements_dir != "default") {
532  }
533 
534 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
535  if (common_elements_dir != QString()) return(common_elements_dir);
536 #endif
537 #ifndef QET_COMMON_COLLECTION_PATH
538  // en l'absence d'option de compilation, on utilise le dossier elements, situe a cote du binaire executable
539  return(QCoreApplication::applicationDirPath() + "/elements/");
540 #else
541  #ifndef QET_COMMON_COLLECTION_PATH_RELATIVE_TO_BINARY_PATH
542  // l'option de compilation represente un chemin absolu ou relatif classique
543  return(QUOTE(QET_COMMON_COLLECTION_PATH));
544  #else
545  // l'option de compilation represente un chemin relatif au dossier contenant le binaire executable
546  return(QCoreApplication::applicationDirPath() + "/" + QUOTE(QET_COMMON_COLLECTION_PATH));
547  #endif
548 #endif
549 }
550 
556 {
557  if (m_user_custom_elements_dir.isEmpty())
558  {
559  QSettings settings;
560  QString path = settings.value("elements-collections/custom-collection-path", "default").toString();
561  if (path != "default" && !path.isEmpty())
562  {
563  QDir dir(path);
564  if (dir.exists())
565  {
568  }
569  }
570  else {
571  m_user_custom_elements_dir = "default";
572  }
573  }
574  else if (m_user_custom_elements_dir != "default") {
576  }
577 
578  return(configDir() + "elements/");
579 }
580 
587 {
588  QString path = commonElementsDir();
589  if (path.endsWith("/")) path.remove(path.length()-1, 1);
590  return path;
591 }
592 
599 {
600  QString path = customElementsDir();
601  if (path.endsWith("/")) path.remove(path.length()-1, 1);
602  return path;
603 }
604 
611 {
614  m_user_custom_tbt_dir.clear();
615 }
616 
622 #ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION
623  if (common_tbt_dir_ != QString()) return(common_tbt_dir_);
624 #endif
625 #ifndef QET_COMMON_TBT_PATH
626  // without any compile-time option, use the "titleblocks" directory next to the executable binary
627  return(QCoreApplication::applicationDirPath() + "/titleblocks/");
628 #else
629  #ifndef QET_COMMON_COLLECTION_PATH_RELATIVE_TO_BINARY_PATH
630  // the compile-time option represents a usual path (be it absolute or relative)
631  return(QUOTE(QET_COMMON_TBT_PATH));
632  #else
633  // the compile-time option represents a path relative to the directory that contains the executable binary
634  return(QCoreApplication::applicationDirPath() + "/" + QUOTE(QET_COMMON_TBT_PATH));
635  #endif
636 #endif
637 }
638 
644  if (m_user_custom_tbt_dir.isEmpty())
645  {
646  QSettings settings;
647  QString path = settings.value("elements-collections/custom-tbt-path", "default").toString();
648  if (path != "default" && !path.isEmpty())
649  {
650  QDir dir(path);
651  if (dir.exists())
652  {
653  m_user_custom_tbt_dir = path;
654  return m_user_custom_tbt_dir;
655  }
656  }
657  else {
658  m_user_custom_tbt_dir = "default";
659  }
660  }
661  else if (m_user_custom_tbt_dir != "default") {
662  return m_user_custom_tbt_dir;
663  }
664 
665  return(configDir() + "titleblocks/");
666 }
667 
676 QString QETApp::configDir() {
677 #ifdef QET_ALLOW_OVERRIDE_CD_OPTION
678  if (config_dir != QString()) return(config_dir);
679 #endif
680 #ifdef Q_OS_WIN32
681  // recupere l'emplacement du dossier Application Data
682  // char *app_data_env = getenv("APPDATA");
683  // QString app_data_str(app_data_env);
684  QProcess * process = new QProcess();
685  QString app_data_str = (process->processEnvironment()).value("APPDATA");
686  // delete app_data_env;
687  delete process;
688  if (app_data_str.isEmpty()) {
689  app_data_str = QDir::homePath() + "/Application Data";
690  }
691  return(app_data_str + "/qet/");
692 #else
693  return(QDir::homePath() + "/.qet/");
694 #endif
695 }
696 
704 QString QETApp::realPath(const QString &sym_path) {
705  QString directory;
706  if (sym_path.startsWith("common://")) {
707  directory = commonElementsDir();
708  } else if (sym_path.startsWith("custom://")) {
709  directory = customElementsDir();
710  } else if (sym_path.startsWith(QETAPP_COMMON_TBT_PROTOCOL "://")) {
711  directory = commonTitleBlockTemplatesDir();
712  } else if (sym_path.startsWith(QETAPP_CUSTOM_TBT_PROTOCOL "://")) {
713  directory = customTitleBlockTemplatesDir();
714  } else return(QString());
715  return(directory + QDir::toNativeSeparators(sym_path.right(sym_path.length() - 9)));
716 }
717 
725 QString QETApp::symbolicPath(const QString &real_path) {
726  // recupere les dossier common et custom
727  QString commond = commonElementsDir();
728  QString customd = customElementsDir();
729  QString chemin;
730  // analyse le chemin de fichier passe en parametre
731  if (real_path.startsWith(commond)) {
732  chemin = "common://" + real_path.right(real_path.length() - commond.length());
733  } else if (real_path.startsWith(customd)) {
734  chemin = "custom://" + real_path.right(real_path.length() - customd.length());
735  } else chemin = QString();
736  return(chemin);
737 }
738 
744  static QStringList ext;
745  if (!ext.count()) {
746  ext << "qet";
747  ext << "elmt";
748  ext << QString(TITLEBLOCKS_FILE_EXTENSION).remove(QRegExp("^\\."));
749  }
750  return(ext);
751 }
752 
757 QStringList QETApp::handledFiles(const QList<QUrl> &urls) {
758  QList<QString> filepaths;
759  foreach (QUrl url, urls) {
760  if (url.scheme() != "file") continue;
761  QString local_path = url.toLocalFile();
762  QFileInfo local_path_info(local_path);
763  QString local_path_ext = local_path_info.completeSuffix();
764  if (handledFileExtensions().contains(local_path_ext)) {
765  filepaths << local_path;
766  }
767  }
768  return(filepaths);
769 }
770 
778  if (filepath.isEmpty()) return(nullptr);
779 
780  QETApp *qet_app(QETApp::instance());
781  foreach (QETDiagramEditor *diagram_editor, qet_app -> diagramEditors()) {
782  if (diagram_editor -> viewForFile(filepath)) {
783  return(diagram_editor);
784  }
785  }
786 
787  return(nullptr);
788 }
789 
797 {
798  foreach (QETDiagramEditor *qde, QETApp::diagramEditors()) {
799  if (qde->isAncestorOf(child)) {
800  return qde;
801  }
802  }
803 
804  return nullptr;
805 }
806 
807 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
808 
812 void QETApp::overrideCommonElementsDir(const QString &new_ced) {
813  QFileInfo new_ced_info(new_ced);
814  if (new_ced_info.isDir()) {
815  common_elements_dir = new_ced_info.absoluteFilePath();
816  if (!common_elements_dir.endsWith("/")) common_elements_dir += "/";
817  }
818 }
819 #endif
820 
821 #ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION
822 
826 void QETApp::overrideCommonTitleBlockTemplatesDir(const QString &new_ctbtd) {
827  QFileInfo new_ctbtd_info(new_ctbtd);
828  if (new_ctbtd_info.isDir()) {
829  common_tbt_dir_ = new_ctbtd_info.absoluteFilePath();
830  if (!common_tbt_dir_.endsWith("/")) common_tbt_dir_ += "/";
831  }
832 }
833 #endif
834 
835 #ifdef QET_ALLOW_OVERRIDE_CD_OPTION
836 
840 void QETApp::overrideConfigDir(const QString &new_cd) {
841  QFileInfo new_cd_info(new_cd);
842  if (new_cd_info.isDir()) {
843  config_dir = new_cd_info.absoluteFilePath();
844  if (!config_dir.endsWith("/")) config_dir += "/";
845  }
846 }
847 #endif
848 
853 void QETApp::overrideLangDir(const QString &new_ld) {
854  QFileInfo new_ld_info(new_ld);
855  if (new_ld_info.isDir()) {
856  lang_dir = new_ld_info.absoluteFilePath();
857  if (!lang_dir.endsWith("/")) lang_dir += "/";
858  }
859 }
860 
865  if (!lang_dir.isEmpty()) {
866  return(lang_dir);
867  } else {
868 #ifndef QET_LANG_PATH
869  // en l'absence d'option de compilation, on utilise le dossier lang, situe a cote du binaire executable
870  return(QCoreApplication::applicationDirPath() + "/lang/");
871 #else
872  #ifndef QET_LANG_PATH_RELATIVE_TO_BINARY_PATH
873  // l'option de compilation represente un chemin absolu ou relatif classique
874  return(QUOTE(QET_LANG_PATH));
875  #else
876  // l'option de compilation represente un chemin relatif au dossier contenant le binaire executable
877  return(QCoreApplication::applicationDirPath() + "/" + QUOTE(QET_LANG_PATH));
878  #endif
879 #endif
880  }
881 }
882 
888  // s'assure que toutes les fenetres soient visibles avant de quitter
891  project -> close();
892  }
893  bool every_window_closed = true;
894  foreach(QETDiagramEditor *e, diagramEditors()) {
895  every_window_closed = every_window_closed && e -> close();
896  }
897  foreach(QETElementEditor *e, elementEditors()) {
898  every_window_closed = every_window_closed && e -> close();
899  }
900  return(every_window_closed);
901 }
902 
910 QFont QETApp::diagramTextsFont(qreal size)
911 {
912  QSettings settings;
913 
914  //Font to use
915  QString diagram_texts_family = settings.value("diagramfont", "Sans Serif").toString();
916  qreal diagram_texts_size = settings.value("diagramsize", 9.0).toDouble();
917 
918  if (size != -1.0) {
919  diagram_texts_size = size;
920  }
921  QFont diagram_texts_font = QFont(diagram_texts_family);
922  diagram_texts_font.setPointSizeF(diagram_texts_size);
923  if (diagram_texts_size <= 4.0) {
924  diagram_texts_font.setWeight(QFont::Light);
925  }
926  return(diagram_texts_font);
927 }
935 {
936  QSettings settings;
937 
938  //Font to use
939  QString diagram_texts_item_family = settings.value("diagramitemfont", "Sans Serif").toString();
940  qreal diagram_texts_item_size = settings.value("diagramitemsize", 9.0).toDouble();
941  qreal diagram_texts_item_weight = settings.value("diagramitemweight").toDouble();
942  QString diagram_texts_item_style = settings.value("diagramitemstyle", "normal").toString();
943 
944  if (size != -1.0) {
945  diagram_texts_item_size = size;
946  }
947  QFont diagram_texts_item_font = QFont(diagram_texts_item_family);
948  diagram_texts_item_font.setPointSizeF(diagram_texts_item_size);
949  diagram_texts_item_font.setWeight(diagram_texts_item_weight);
950  diagram_texts_item_font.setStyleName(diagram_texts_item_style);
951  if (diagram_texts_item_size <= 4.0) {
952  diagram_texts_item_font.setWeight(QFont::Light);
953  }
954  return(diagram_texts_item_font);
955 }
963 {
964  QSettings settings;
965  //Font to use
966  QFont font_ = diagramTextsItemFont();
967  if (settings.contains("diagrameditor/dynamic_text_font")) {
968  font_.fromString(settings.value("diagrameditor/dynamic_text_font").toString());
969  }
970  if (size > 0) {
971  font_.setPointSizeF(size);
972  }
973  return(font_);
974 }
975 
982 QFont QETApp::foliolistTextsFont(qreal size)
983 {
984  QSettings settings;
985 
986  //Font to use
987  QString foliolist_texts_family = settings.value("foliolistfont", "Sans Serif").toString();
988  qreal foliolist_texts_size = settings.value("foliolistsize", 9.0).toDouble();
989 
990  if (size != -1.0) {
991  foliolist_texts_size = size;
992  }
993  QFont foliolist_texts_font = QFont(foliolist_texts_family);
994  foliolist_texts_font.setPointSizeF(foliolist_texts_size);
995  if (foliolist_texts_size <= 4.0) {
996  foliolist_texts_font.setWeight(QFont::Light);
997  }
998  return(foliolist_texts_font);
999 }
1000 
1007 QFont QETApp::indiTextsItemFont(qreal size)
1008 {
1009  QSettings settings;
1010  //Font to use
1011  QFont font_ = diagramTextsItemFont();
1012  if (settings.contains("diagrameditor/independent_text_font")) {
1013  font_.fromString(settings.value("diagrameditor/independent_text_font").toString());
1014  }
1015  if (size > 0) {
1016  font_.setPointSizeF(size);
1017  }
1018  return(font_);
1019 }
1020 
1021 
1025 QList<QETDiagramEditor *> QETApp::diagramEditors() {
1026  return(QETApp::instance() -> detectWindows<QETDiagramEditor>());
1027 }
1028 
1032 QList<QETElementEditor *> QETApp::elementEditors() {
1033  return(QETApp::instance() -> detectWindows<QETElementEditor>());
1034 }
1035 
1039 QList<QETTitleBlockTemplateEditor *> QETApp::titleBlockTemplateEditors() {
1040  return(QETApp::instance() -> detectWindows<QETTitleBlockTemplateEditor>());
1041 }
1042 
1048 QList<QETTitleBlockTemplateEditor *> QETApp::titleBlockTemplateEditors(QETProject *project) {
1049  QList<QETTitleBlockTemplateEditor *> editors;
1050  if (!project) return(editors);
1051 
1052  // foreach known template editor
1053  foreach (QETTitleBlockTemplateEditor *tbt_editor, titleBlockTemplateEditors()) {
1054  if (tbt_editor -> location().parentProject() == project) {
1055  editors << tbt_editor;
1056  }
1057  }
1058 
1059  return(editors);
1060 }
1061 
1074  widget -> orientationWidget() -> setFont(QETApp::diagramTextsFont());
1075  widget -> orientationWidget() -> setUsableTexts(QList<QString>()
1076  << QETApp::tr("Q", "Single-letter example text - translate length, not meaning")
1077  << QETApp::tr("QET", "Small example text - translate length, not meaning")
1078  << QETApp::tr("Schema", "Normal example text - translate length, not meaning")
1079  << QETApp::tr("Electrique", "Normal example text - translate length, not meaning")
1080  << QETApp::tr("QElectroTech", "Long example text - translate length, not meaning")
1081  );
1082  return(widget);
1083 }
1084 
1090  TitleBlockTemplate *titleblock_template = new TitleBlockTemplate(QETApp::instance());
1091  if (titleblock_template -> loadFromXmlFile(":/titleblocks/default.titleblock")) {
1092  QETApp::default_titleblock_template_ = titleblock_template;
1093  }
1094  }
1096 }
1097 
1098 
1104 QList<QETElementEditor *> QETApp::elementEditors(QETProject *project) {
1105  QList<QETElementEditor *> editors;
1106  if (!project) return(editors);
1107 
1108  // pour chaque editeur d'element...
1109  foreach(QETElementEditor *elmt_editor, elementEditors()) {
1110  // on recupere l'emplacement de l'element qu'il edite
1111  ElementsLocation elmt_editor_loc(elmt_editor -> location());
1112 
1113  // il se peut que l'editeur edite un element non enregistre ou un fichier
1114  if (elmt_editor_loc.isNull()) continue;
1115 
1116  if (elmt_editor_loc.project() == project) {
1117  editors << elmt_editor;
1118  }
1119  }
1120 
1121  return(editors);
1122 }
1123 
1124 void QETApp::receiveMessage(int instanceId, QByteArray message)
1125 {
1126  Q_UNUSED(instanceId);
1127 
1128  QString str(message);
1129 
1130  if (str.startsWith("launched-with-args: "))
1131  {
1132  QString my_message(str.mid(20));
1133  QStringList args_list = QET::splitWithSpaces(my_message);
1134  openFiles(QETArguments(args_list));
1135  }
1136 }
1137 
1142 template <class T> QList<T *> QETApp::detectWindows() const {
1143  QList<T *> windows;
1144  foreach(QWidget *widget, qApp->topLevelWidgets()) {
1145  if (!widget -> isWindow()) continue;
1146  if (T *window = qobject_cast<T *>(widget)) {
1147  windows << window;
1148  }
1149  }
1150  return(windows);
1151 }
1152 
1157 template <class T> void QETApp::setMainWindowsVisible(bool visible) {
1158  foreach(T *e, detectWindows<T>()) {
1159  setMainWindowVisible(e, visible);
1160  }
1161 }
1162 
1167  return(m_projects_recent_files);
1168 }
1169 
1174  return(m_elements_recent_files);
1175 }
1176 
1182 void QETApp::setMainWindowVisible(QMainWindow *window, bool visible) {
1183  if (window -> isVisible() == visible) return;
1184  if (!visible) {
1185  window_geometries.insert(window, window -> saveGeometry());
1186  window_states.insert(window, window -> saveState());
1187  window -> hide();
1188  // cache aussi les toolbars et les docks
1189  foreach (QWidget *qw, floatingToolbarsAndDocksForMainWindow(window)) {
1190  qw -> hide();
1191  }
1192  } else {
1193  window -> show();
1194 #ifndef Q_OS_WIN32
1195  window -> restoreGeometry(window_geometries[window]);
1196 #endif
1197  window -> restoreState(window_states[window]);
1198  }
1199 }
1200 
1206 void QETApp::invertMainWindowVisibility(QWidget *window) {
1207  if (QMainWindow *w = qobject_cast<QMainWindow *>(window)) setMainWindowVisible(w, !w -> isVisible());
1208 }
1209 
1214 #if defined(Q_OS_WIN) && defined(Q_OS_WINCE)
1215 
1216 if defined(Q_OS_WIN)
1217  if ((QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA
1218  && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
1219  style = QLatin1String("WindowsVista");
1220  else if ((QSysInfo::WindowsVersion >= QSysInfo::WV_XP
1221  && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based))
1222  style = QLatin1String("WindowsXP");
1223  else
1224  style = QLatin1String("Windows"); // default styles for Windows
1225 #endif
1226 
1227 
1233  if (use) {
1234  qApp->setPalette(initial_palette_);
1235  qApp->setStyleSheet(
1236  "QTabBar::tab:!selected { background-color: transparent; }"
1237  "QAbstractScrollArea#mdiarea {"
1238  "background-color -> setPalette(initial_palette_);"
1239  "}"
1240  );
1241  } else {
1242  QFile file(configDir() + "style.css");
1243  file.open(QFile::ReadOnly);
1244  QString styleSheet = QLatin1String(file.readAll());
1245  qApp->setStyleSheet(styleSheet);
1246  file.close();
1247  }
1248 }
1249 
1255  if (closeEveryEditor()) {
1256  qApp->quit();
1257  }
1258 }
1259 
1265  /* petite bidouille : le slot se rappelle apres 500 ms d'attente
1266  afin de compenser le fait que certaines fenetres peuvent encore
1267  paraitre vivantes alors qu'elles viennent d'etre fermees
1268  */
1269  static bool sleep = true;
1270  if (sleep) {
1271  QTimer::singleShot(500, this, SLOT(checkRemainingWindows()));
1272  } else {
1273  if (!diagramEditors().count() && !elementEditors().count()) {
1274  qApp->quit();
1275  }
1276  }
1277  sleep = !sleep;
1278 }
1279 
1285 void QETApp::openFiles(const QETArguments &args) {
1289 }
1290 
1299 void QETApp::openProjectFiles(const QStringList &files_list) {
1300  if (files_list.isEmpty()) return;
1301 
1302  // liste des editeurs de schema ouverts
1303  QList<QETDiagramEditor *> diagrams_editors = diagramEditors();
1304 
1305  // s'il y a des editeur de schemas ouvert, on cherche ceux qui sont visibles
1306  if (diagrams_editors.count()) {
1307  QList<QETDiagramEditor *> visible_diagrams_editors;
1308  foreach(QETDiagramEditor *de, diagrams_editors) {
1309  if (de -> isVisible()) visible_diagrams_editors << de;
1310  }
1311 
1312  // on choisit soit le premier visible soit le premier tout court
1313  QETDiagramEditor *de_open;
1314  if (visible_diagrams_editors.count()) {
1315  de_open = visible_diagrams_editors.first();
1316  } else {
1317  de_open = diagrams_editors.first();
1318  de_open -> setVisible(true);
1319  }
1320 
1321  // ouvre les fichiers dans l'editeur ainsi choisi
1322  foreach(QString file, files_list) {
1323  de_open -> openAndAddProject(file);
1324  }
1325  } else {
1326  // cree un nouvel editeur qui ouvrira les fichiers
1327  new QETDiagramEditor(files_list);
1328  }
1329 }
1330 
1336 void QETApp::openElementFiles(const QStringList &files_list) {
1337  if (files_list.isEmpty()) return;
1338 
1339  // evite autant que possible les doublons dans la liste fournie
1340  QSet<QString> files_set;
1341  foreach(QString file, files_list) {
1342  QString canonical_filepath = QFileInfo(file).canonicalFilePath();
1343  if (!canonical_filepath.isEmpty()) files_set << canonical_filepath;
1344  }
1345  // a ce stade, tous les fichiers dans le Set existent et sont a priori differents
1346  if (files_set.isEmpty()) return;
1347 
1348  // liste des editeurs d'element ouverts
1349  QList<QETElementEditor *> element_editors = elementEditors();
1350 
1351  // on traite les fichiers a la queue leu leu...
1352  foreach(QString element_file, files_set) {
1353  bool already_opened_in_existing_element_editor = false;
1354  foreach(QETElementEditor *element_editor, element_editors) {
1355  if (element_editor -> isEditing(element_file)) {
1356  // ce fichier est deja ouvert dans un editeur
1357  already_opened_in_existing_element_editor = true;
1358  element_editor -> setVisible(true);
1359  element_editor -> raise();
1360  element_editor -> activateWindow();
1361  break;
1362  }
1363  }
1364  if (!already_opened_in_existing_element_editor) {
1365  // ce fichier n'est ouvert dans aucun editeur
1366  QETElementEditor *element_editor = new QETElementEditor();
1367  element_editor -> fromFile(element_file);
1368  }
1369  }
1370 }
1371 
1377 void QETApp::openElementLocations(const QList<ElementsLocation> &locations_list) {
1378  if (locations_list.isEmpty()) return;
1379 
1380  // liste des editeurs d'element ouverts
1381  QList<QETElementEditor *> element_editors = elementEditors();
1382 
1383  // on traite les emplacements a la queue leu leu...
1384  foreach(ElementsLocation element_location, locations_list) {
1385  bool already_opened_in_existing_element_editor = false;
1386  foreach(QETElementEditor *element_editor, element_editors) {
1387  if (element_editor -> isEditing(element_location)) {
1388  // cet emplacement est deja ouvert dans un editeur
1389  already_opened_in_existing_element_editor = true;
1390  element_editor -> setVisible(true);
1391  element_editor -> raise();
1392  element_editor -> activateWindow();
1393  break;
1394  }
1395  }
1396  if (!already_opened_in_existing_element_editor) {
1397  // cet emplacement n'est ouvert dans aucun editeur
1398  QETElementEditor *element_editor = new QETElementEditor();
1399  element_editor -> fromLocation(element_location);
1400  }
1401  }
1402 }
1403 
1412 void QETApp::openTitleBlockTemplate(const TitleBlockTemplateLocation &location, bool duplicate) {
1413  QETTitleBlockTemplateEditor *qet_template_editor = new QETTitleBlockTemplateEditor();
1414  qet_template_editor -> setOpenForDuplication(duplicate);
1415  qet_template_editor -> edit(location);
1416  qet_template_editor -> show();
1417 }
1418 
1423 void QETApp::openTitleBlockTemplate(const QString &filepath) {
1424  QETTitleBlockTemplateEditor *qet_template_editor = new QETTitleBlockTemplateEditor();
1425  qet_template_editor -> edit(filepath);
1426  qet_template_editor -> show();
1427 }
1428 
1434 void QETApp::openTitleBlockTemplateFiles(const QStringList &files_list) {
1435  if (files_list.isEmpty()) return;
1436 
1437  // avoid duplicates in the provided files list
1438  QSet<QString> files_set;
1439  foreach (QString file, files_list) {
1440  QString canonical_filepath = QFileInfo(file).canonicalFilePath();
1441  if (!canonical_filepath.isEmpty()) files_set << canonical_filepath;
1442  }
1443  // here, we can assume all files in the set exist and are different
1444  if (files_set.isEmpty()) return;
1445 
1446  // opened title block template editors
1447  QList<QETTitleBlockTemplateEditor *> tbt_editors = titleBlockTemplateEditors();
1448 
1449  foreach(QString tbt_file, files_set) {
1450  bool already_opened_in_existing_tbt_editor = false;
1451  foreach(QETTitleBlockTemplateEditor *tbt_editor, tbt_editors) {
1452  if (tbt_editor -> isEditing(tbt_file)) {
1453  // this file is already opened
1454  already_opened_in_existing_tbt_editor = true;
1455  tbt_editor -> setVisible(true);
1456  tbt_editor -> raise();
1457  tbt_editor -> activateWindow();
1458  break;
1459  }
1460  }
1461  if (!already_opened_in_existing_tbt_editor) {
1462  // this file is not opened yet
1463  openTitleBlockTemplate(tbt_file);
1464  }
1465  }
1466 }
1467 
1473  // determine le widget parent a utiliser pour le dialogue
1474  QWidget *parent_widget = qApp->activeWindow();
1475 
1476  // cree le dialogue
1477  ConfigDialog cd;
1478  cd.setWindowTitle(tr("Configurer QElectroTech", "window title"));
1479  cd.setWindowModality(Qt::WindowModal);
1481  cd.addPage(new NewDiagramPage());
1482  cd.addPage(new ExportConfigPage());
1483  cd.addPage(new PrintConfigPage());
1484 
1485 
1486  // associe le dialogue a un eventuel widget parent
1487  if (parent_widget) {
1488  cd.setParent(parent_widget, cd.windowFlags());
1489  }
1490 
1491  // affiche le dialogue puis evite de le lier a un quelconque widget parent
1492  cd.exec();
1493  cd.setParent(nullptr, cd.windowFlags());
1494 }
1495 
1501 {
1502  AboutQET aq(qApp->activeWindow());
1503 
1504 #ifdef Q_OS_MACOS
1505  aq.setWindowFlags(Qt::Sheet);
1506 #endif
1507  aq.exec();
1508 }
1509 
1514 QList<QWidget *> QETApp::floatingToolbarsAndDocksForMainWindow(QMainWindow *window) const {
1515  QList<QWidget *> widgets;
1516  foreach(QWidget *qw, qApp->topLevelWidgets()) {
1517  if (!qw -> isWindow()) continue;
1518  if (qobject_cast<QToolBar *>(qw) || qobject_cast<QDockWidget *>(qw)) {
1519  if (qw -> parent() == window) widgets << qw;
1520  }
1521  }
1522  return(widgets);
1523 }
1524 
1538  // recupere les arguments
1539  QList<QString> arguments_list(qApp->arguments());
1540 
1541  // enleve le premier argument : il s'agit du fichier binaire
1542  arguments_list.takeFirst();
1543 
1544  // analyse les arguments
1545  qet_arguments_ = QETArguments(arguments_list);
1546 
1547 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
1548  if (qet_arguments_.commonElementsDirSpecified()) {
1549  overrideCommonElementsDir(qet_arguments_.commonElementsDir());
1550  }
1551 #endif
1552 #ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION
1553  if (qet_arguments_.commonTitleBlockTemplatesDirSpecified()) {
1554  overrideCommonTitleBlockTemplatesDir(qet_arguments_.commonTitleBlockTemplatesDir());
1555  }
1556 #endif
1557 #ifdef QET_ALLOW_OVERRIDE_CD_OPTION
1558  if (qet_arguments_.configDirSpecified()) {
1559  overrideConfigDir(qet_arguments_.configDir());
1560  }
1561 #endif
1562 
1565  }
1566 
1568  printLicense();
1570  }
1572  printHelp();
1574  }
1576  printVersion();
1578  }
1579 }
1580 
1586  if (non_interactive_execution_) return;
1587  m_splash_screen = new QSplashScreen(QPixmap(":/ico/splash.png"));
1588  m_splash_screen -> show();
1589  setSplashScreenStep(tr("Chargement...", "splash screen caption"));
1590 }
1591 
1597 void QETApp::setSplashScreenStep(const QString &message) {
1598  if (!m_splash_screen) return;
1599  if (!message.isEmpty()) {
1600  m_splash_screen -> showMessage(message, Qt::AlignBottom | Qt::AlignLeft);
1601  }
1602  qApp->processEvents();
1603 }
1604 
1610 }
1611 
1617  initial_palette_ = qApp->palette();
1618 
1619  //Apply or not the system style
1620  QSettings settings;
1621  useSystemPalette(settings.value("usesystemcolors", true).toBool());
1622 }
1623 
1632  // cree les dossiers de configuration si necessaire
1633  QDir config_dir(QETApp::configDir());
1634  if (!config_dir.exists()) config_dir.mkpath(QETApp::configDir());
1635 
1636  QDir custom_elements_dir(QETApp::customElementsDir());
1637  if (!custom_elements_dir.exists()) custom_elements_dir.mkpath(QETApp::customElementsDir());
1638 
1639  QDir custom_tbt_dir(QETApp::customTitleBlockTemplatesDir());
1640  if (!custom_tbt_dir.exists()) custom_tbt_dir.mkpath(QETApp::customTitleBlockTemplatesDir());
1641 
1642  // fichiers recents
1643  // note : les icones doivent etre initialisees avant ces instructions (qui creent des menus en interne)
1644  m_projects_recent_files = new RecentFiles("projects");
1646  m_elements_recent_files = new RecentFiles("elements");
1647  m_elements_recent_files -> setIconForFiles(QET::Icons::Element);
1648 }
1649 
1654  setSplashScreenStep(tr("Chargement... icône du systray", "splash screen caption"));
1655  // initialisation des menus de l'icone dans le systray
1656  menu_systray = new QMenu(tr("QElectroTech", "systray menu title"));
1657 
1658  quitter_qet = new QAction(QET::Icons::ApplicationExit, tr("&Quitter"), this);
1659  reduce_appli = new QAction(QET::Icons::Hide, tr("&Masquer"), this);
1660  restore_appli = new QAction(QET::Icons::Restore, tr("&Restaurer"), this);
1661  reduce_diagrams = new QAction(QET::Icons::Hide, tr("&Masquer tous les éditeurs de schéma"), this);
1662  restore_diagrams = new QAction(QET::Icons::Restore, tr("&Restaurer tous les éditeurs de schéma"), this);
1663  reduce_elements = new QAction(QET::Icons::Hide, tr("&Masquer tous les éditeurs d'élément"), this);
1664  restore_elements = new QAction(QET::Icons::Restore, tr("&Restaurer tous les éditeurs d'élément"), this);
1665  reduce_templates = new QAction(QET::Icons::Hide, tr("&Masquer tous les éditeurs de cartouche", "systray submenu entry"), this);
1666  restore_templates = new QAction(QET::Icons::Restore, tr("&Restaurer tous les éditeurs de cartouche", "systray submenu entry"), this);
1667  new_diagram = new QAction(QET::Icons::WindowNew, tr("&Nouvel éditeur de schéma"), this);
1668  new_element = new QAction(QET::Icons::WindowNew, tr("&Nouvel éditeur d'élément"), this);
1669 
1670  quitter_qet -> setStatusTip(tr("Ferme l'application QElectroTech"));
1671  reduce_appli -> setToolTip(tr("Réduire QElectroTech dans le systray"));
1672  restore_appli -> setToolTip(tr("Restaurer QElectroTech"));
1673 
1674  connect(quitter_qet, SIGNAL(triggered()), this, SLOT(quitQET()));
1675  connect(reduce_appli, SIGNAL(triggered()), this, SLOT(reduceEveryEditor()));
1676  connect(restore_appli, SIGNAL(triggered()), this, SLOT(restoreEveryEditor()));
1677  connect(reduce_diagrams, SIGNAL(triggered()), this, SLOT(reduceDiagramEditors()));
1678  connect(restore_diagrams, SIGNAL(triggered()), this, SLOT(restoreDiagramEditors()));
1679  connect(reduce_elements, SIGNAL(triggered()), this, SLOT(reduceElementEditors()));
1680  connect(restore_elements, SIGNAL(triggered()), this, SLOT(restoreElementEditors()));
1681  connect(reduce_templates, SIGNAL(triggered()), this, SLOT(reduceTitleBlockTemplateEditors()));
1682  connect(restore_templates,SIGNAL(triggered()), this, SLOT(restoreTitleBlockTemplateEditors()));
1683  connect(new_diagram, SIGNAL(triggered()), this, SLOT(newDiagramEditor()));
1684  connect(new_element, SIGNAL(triggered()), this, SLOT(newElementEditor()));
1685 
1686  // initialisation de l'icone du systray
1687  m_qsti = new QSystemTrayIcon(QET::Icons::QETLogo, this);
1688  m_qsti -> setToolTip(tr("QElectroTech", "systray icon tooltip"));
1689  connect(m_qsti, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(systray(QSystemTrayIcon::ActivationReason)));
1690  m_qsti -> setContextMenu(menu_systray);
1691  m_qsti -> show();
1692 }
1693 
1702 template <class T> void QETApp::addWindowsListToMenu(QMenu *menu, const QList<T *> &windows) {
1703  menu -> addSeparator();
1704  foreach (QMainWindow *window, windows) {
1705  QAction *current_menu = menu -> addAction(window -> windowTitle());
1706  current_menu -> setCheckable(true);
1707  current_menu -> setChecked(window -> isVisible());
1708  connect(current_menu, SIGNAL(triggered()), &signal_map, SLOT(map()));
1709  signal_map.setMapping(current_menu, window);
1710  }
1711 }
1712 
1719 int QETApp::projectIdFromString(const QString &url) {
1720  QRegExp embedded("^project([0-9]+)\\+embed.*$", Qt::CaseInsensitive);
1721  if (embedded.exactMatch(url)) {
1722  bool conv_ok = false;
1723  int project_id = embedded.capturedTexts().at(1).toInt(&conv_ok);
1724  if (conv_ok) {
1725  return(project_id);
1726  }
1727  }
1728  return(-1);
1729 }
1730 
1738  int project_id = projectIdFromString(url);
1739  if (project_id == -1) return(nullptr);
1740  return(project(project_id));
1741 }
1742 
1745  menu_systray -> clear();
1746 
1747  // recupere les editeurs
1748  QList<QETDiagramEditor *> diagrams = diagramEditors();
1749  QList<QETElementEditor *> elements = elementEditors();
1750  QList<QETTitleBlockTemplateEditor *> tbtemplates = titleBlockTemplateEditors();
1751  fetchWindowStats(diagrams, elements, tbtemplates);
1752 
1753  // ajoute le bouton reduire / restaurer au menu
1755 
1756  // ajoute les editeurs de schemas dans un sous-menu
1757  QMenu *diagrams_submenu = menu_systray -> addMenu(tr("Éditeurs de schémas"));
1758  diagrams_submenu -> addAction(reduce_diagrams);
1759  diagrams_submenu -> addAction(restore_diagrams);
1760  diagrams_submenu -> addAction(new_diagram);
1761  reduce_diagrams -> setEnabled(!diagrams.isEmpty() && !every_diagram_reduced);
1762  restore_diagrams -> setEnabled(!diagrams.isEmpty() && !every_diagram_visible);
1763  addWindowsListToMenu<QETDiagramEditor>(diagrams_submenu, diagrams);
1764 
1765  // ajoute les editeurs d'elements au menu
1766  QMenu *elements_submenu = menu_systray -> addMenu(tr("Éditeurs d'élément"));
1767  elements_submenu -> addAction(reduce_elements);
1768  elements_submenu -> addAction(restore_elements);
1769  elements_submenu -> addAction(new_element);
1770  reduce_elements -> setEnabled(!elements.isEmpty() && !every_element_reduced);
1771  restore_elements -> setEnabled(!elements.isEmpty() && !every_element_visible);
1772  elements_submenu -> addSeparator();
1773  addWindowsListToMenu<QETElementEditor>(elements_submenu, elements);
1774 
1775  // add title block template editors in a submenu
1776  QMenu *tbtemplates_submenu = menu_systray -> addMenu(tr("Éditeurs de cartouche", "systray menu entry"));
1777  tbtemplates_submenu -> addAction(reduce_templates);
1778  tbtemplates_submenu -> addAction(restore_templates);
1779  reduce_templates -> setEnabled(!tbtemplates.isEmpty() && !every_template_reduced);
1780  restore_templates -> setEnabled(!tbtemplates.isEmpty() && !every_template_visible);
1781  addWindowsListToMenu<QETTitleBlockTemplateEditor>(tbtemplates_submenu, tbtemplates);
1782 
1783  // ajoute le bouton quitter au menu
1784  menu_systray -> addSeparator();
1785  menu_systray -> addAction(quitter_qet);
1786 }
1787 
1794 {
1795  QList<KAutoSaveFile *> stale_files = KAutoSaveFile::allStaleFiles();
1796 
1797  //Remove from the list @stale_files, the stales file of opened project
1798  const QList<KAutoSaveFile *> sf = stale_files;
1799  for (KAutoSaveFile *kasf : sf)
1800  {
1801  for (QETProject *project : registeredProjects().values())
1802  {
1803  //We must to adjust with the flag QUrl::StripTrailingSlash to compar a path formated like the path returned by KAutoSaveFile
1804  const QString path = QUrl::fromLocalFile(project->filePath()).adjusted(QUrl::RemoveScheme | QUrl::StripTrailingSlash).path();
1805  if (kasf->managedFile() == path) {
1806  stale_files.removeOne(kasf);
1807  }
1808  }
1809  }
1810 
1811  if (stale_files.isEmpty()) {
1812  return;
1813  }
1814 
1815  QString text;
1816  if(stale_files.size() == 1) {
1817  text.append(tr("<b>Le fichier de restauration suivant a été trouvé,<br>"
1818  "Voulez-vous l'ouvrir ?</b><br>"));
1819  } else {
1820  text.append(tr("<b>Les fichiers de restauration suivant on été trouvé,<br>"
1821  "Voulez-vous les ouvrir ?</b><br>"));
1822  }
1823  for(const KAutoSaveFile *kasf : stale_files)
1824  {
1825 #ifdef Q_OS_WIN
1826  //Remove the first character '/' before the name of the drive
1827  text.append("<br>" + kasf->managedFile().path().remove(0,1));
1828 #else
1829  text.append("<br>" + kasf->managedFile().path());
1830 #endif
1831  }
1832 
1833  //Open backup file
1834  if (QET::QetMessageBox::question(nullptr, tr("Fichier de restauration"), text, QMessageBox::Ok|QMessageBox::Cancel) == QMessageBox::Ok)
1835  {
1836  //If there is opened editors, we find those who are visible
1837  if (diagramEditors().count())
1838  {
1839  diagramEditors().first()->setVisible(true);
1840  diagramEditors().first()->openBackupFiles(stale_files);
1841  }
1842  else
1843  {
1844  QETDiagramEditor *editor = new QETDiagramEditor();
1845  editor->openBackupFiles(stale_files);
1846  }
1847  }
1848  else //Clear backup file
1849  {
1850  //Remove the stale files
1851  for (KAutoSaveFile *stale : stale_files)
1852  {
1853  stale->open(QIODevice::ReadWrite);
1854  delete stale;
1855  }
1856  }
1857 }
1858 
1861  const QList<QETDiagramEditor *> &diagrams,
1862  const QList<QETElementEditor *> &elements,
1863  const QList<QETTitleBlockTemplateEditor *> &tbtemplates
1864 ) {
1865  // compte le nombre de schemas visibles
1866  int visible_diagrams = 0;
1867  foreach(QMainWindow *w, diagrams) if (w -> isVisible()) ++ visible_diagrams;
1868  every_diagram_reduced = !visible_diagrams;
1869  every_diagram_visible = visible_diagrams == diagrams.count();
1870 
1871  // compte le nombre de schemas visibles
1872  int visible_elements = 0;
1873  foreach(QMainWindow *w, elements) if (w -> isVisible()) ++ visible_elements;
1874  every_element_reduced = !visible_elements;
1875  every_element_visible = visible_elements == elements.count();
1876 
1877  // count visible template editors
1878  int visible_templates = 0;
1879  foreach(QMainWindow *window, tbtemplates) {
1880  if (window -> isVisible()) ++ visible_templates;
1881  }
1882  every_template_reduced = !visible_templates;
1883  every_template_visible = visible_templates == tbtemplates.count();
1884 
1885  // determine si tous les elements sont reduits
1887 }
1888 
1889 #ifdef Q_OS_DARWIN
1890 
1894 bool QETApp::eventFiltrer(QObject *object, QEvent *e) {
1895  // gere l'ouverture de fichiers (sous MacOs)
1896  if (e -> type() == QEvent::FileOpen) {
1897  // nom du fichier a ouvrir
1898  QString filename = static_cast<QFileOpenEvent *>(e) -> file();
1899  openFiles(QStringList() << filename);
1900  return(true);
1901  } else {
1902  return QObject::eventFilter(object, e);
1903  }
1904 }
1905 #endif
1906 
1911  QString help(
1912  tr("Usage : ") + QFileInfo(qApp->applicationFilePath()).fileName() + tr(" [options] [fichier]...\n\n") +
1913  tr("QElectroTech, une application de réalisation de schémas électriques.\n\n"
1914  "Options disponibles : \n"
1915  " --help Afficher l'aide sur les options\n"
1916  " -v, --version Afficher la version\n"
1917  " --license Afficher la licence\n")
1918 #ifdef QET_ALLOW_OVERRIDE_CED_OPTION
1919  + tr(" --common-elements-dir=DIR Definir le dossier de la collection d'elements\n")
1920 #endif
1921 #ifdef QET_ALLOW_OVERRIDE_CTBTD_OPTION
1922  + tr(" --common-tbt-dir=DIR Definir le dossier de la collection de modeles de cartouches\n")
1923 #endif
1924 #ifdef QET_ALLOW_OVERRIDE_CD_OPTION
1925  + tr(" --config-dir=DIR Definir le dossier de configuration\n")
1926 #endif
1927  + tr(" --lang-dir=DIR Definir le dossier contenant les fichiers de langue\n")
1928  );
1929  std::cout << qPrintable(help) << std::endl;
1930 }
1931 
1936  std::cout << qPrintable(QET::displayedVersion) << std::endl;
1937 }
1938 
1943  std::cout << qPrintable(QET::license()) << std::endl;
1944 }
1945 
1949 QMap<uint, QETProject *> QETApp::registeredProjects() {
1950  return(registered_projects_);
1951 }
1952 
1959  // le projet doit sembler valide
1960  if (!project) return(false);
1961 
1962  // si le projet est deja enregistre, renvoie false
1963  if (projectId(project) != -1) return(false);
1964 
1965  // enregistre le projet
1967  return(true);
1968 }
1969 
1977  int project_id = projectId(project);
1978 
1979  // si le projet n'est pas enregistre, renvoie false
1980  if (project_id == -1) return(false);
1981 
1982  // annule l'enregistrement du projet
1983  return(registered_projects_.remove(project_id) == 1);
1984 }
1985 
1990 QETProject *QETApp::project(const uint &id) {
1991  if (registered_projects_.contains(id)) {
1992  return(registered_projects_[id]);
1993  } else {
1994  return(nullptr);
1995  }
1996 }
1997 
2002 int QETApp::projectId(const QETProject *project) {
2003  foreach(int id, registered_projects_.keys()) {
2004  if (registered_projects_[id] == project) {
2005  return(id);
2006  }
2007  }
2008  return(-1);
2009 }
void configureQET()
Definition: qetapp.cpp:1472
static TitleBlockTemplatesFilesCollection * commonTitleBlockTemplatesCollection()
Definition: qetapp.cpp:448
static QTextOrientationSpinBoxWidget * createTextOrientationSpinBoxWidget()
Definition: qetapp.cpp:1072
static QString symbolicPath(const QString &)
Definition: qetapp.cpp:725
void fetchWindowStats(const QList< QETDiagramEditor *> &, const QList< QETElementEditor *> &, const QList< QETTitleBlockTemplateEditor *> &)
Met a jour les booleens concernant l&#39;etat des fenetres.
Definition: qetapp.cpp:1860
void reduceEveryEditor()
Reduit toutes les fenetres de l&#39;application dans le systray.
Definition: qetapp.cpp:223
#define QETAPP_COMMON_TBT_PROTOCOL
Definition: qetapp.h:35
static QString customTitleBlockTemplatesDir()
Definition: qetapp.cpp:643
static QString commonTitleBlockTemplatesDir()
Definition: qetapp.cpp:621
static bool unregisterProject(QETProject *)
Definition: qetapp.cpp:1976
static QStringList handledFiles(const QList< QUrl > &)
Definition: qetapp.cpp:757
QPalette initial_palette_
System color palette.
Definition: qetapp.h:187
void invertMainWindowVisibility(QWidget *)
Definition: qetapp.cpp:1206
QIcon Element
Definition: qeticons.cpp:83
static TitleBlockTemplate * defaultTitleBlockTemplate()
Definition: qetapp.cpp:1088
void initSplashScreen()
Definition: qetapp.cpp:1585
void openElementFiles(const QStringList &)
Definition: qetapp.cpp:1336
QStringList splitWithSpaces(const QString &)
Definition: qet.cpp:434
static void printHelp()
Definition: qetapp.cpp:1910
QETArguments qet_arguments_
Comand-line arguments parser.
Definition: qetapp.h:185
void reduceDiagramEditors()
Reduit tous les editeurs de schemas dans le systray.
Definition: qetapp.cpp:239
static RecentFiles * m_elements_recent_files
Definition: qetapp.h:195
void restoreElementEditors()
Restaure tous les editeurs d&#39;element dans le systray.
Definition: qetapp.cpp:254
From user collection.
Definition: qet.h:152
void newElementEditor()
lance un nouvel editeur d&#39;element
Definition: qetapp.cpp:274
static QMap< uint, QETProject * > registeredProjects()
Definition: qetapp.cpp:1949
static QString customElementsDir()
QETApp::customElementsDir.
Definition: qetapp.cpp:555
static QStringList handledFileExtensions()
Definition: qetapp.cpp:743
QAction * restore_appli
Definition: qetapp.h:166
virtual QList< QString > projectFiles() const
void addWindowsListToMenu(QMenu *, const QList< T *> &)
Definition: qetapp.cpp:1702
void initLanguage()
Definition: qetapp.cpp:1608
bool every_diagram_visible
Definition: qetapp.h:179
void aboutQET()
QETApp::aboutQET Open the dialog about qet.
Definition: qetapp.cpp:1500
QAction * new_element
Definition: qetapp.h:174
QSignalMapper signal_map
Definition: qetapp.h:184
void systray(QSystemTrayIcon::ActivationReason)
Definition: qetapp.cpp:202
static int projectIdFromString(const QString &)
Definition: qetapp.cpp:1719
QIcon QETLogo
Definition: qeticons.cpp:151
void setMainWindowVisible(QMainWindow *, bool)
Definition: qetapp.cpp:1182
static QFont foliolistTextsFont(qreal=-1.0)
QETApp::foliolistTextsFont the font for to use in summary pages.
Definition: qetapp.cpp:982
bool non_interactive_execution_
Whether the application will end without any user interaction.
Definition: qetapp.h:186
QHash< QMainWindow *, QByteArray > window_geometries
Definition: qetapp.h:175
QString license()
Definition: qet.cpp:338
void openFiles(const QETArguments &)
Definition: qetapp.cpp:1285
QIcon Hide
Definition: qeticons.cpp:113
void initStyle()
QETApp::initStyle Setup the gui style.
Definition: qetapp.cpp:1616
const QString displayedVersion
QElectroTech displayed version.
Definition: qet.h:32
QAction * reduce_templates
Definition: qetapp.h:171
void reduceElementEditors()
Reduit tous les editeurs d&#39;element dans le systray.
Definition: qetapp.cpp:249
void buildSystemTrayMenu()
construit le menu de l&#39;icone dans le systray
Definition: qetapp.cpp:1744
QAction * new_diagram
Definition: qetapp.h:173
QAction * restore_elements
Definition: qetapp.h:170
static ElementsCollectionCache * collectionCache()
Definition: qetapp.cpp:281
void parseArguments()
Definition: qetapp.cpp:1537
~QETApp() override
QETApp::~QETApp.
Definition: qetapp.cpp:121
static void dropInstance()
void openTitleBlockTemplate(const TitleBlockTemplateLocation &, bool=false)
Definition: qetapp.cpp:1412
QAction * reduce_elements
Definition: qetapp.h:169
static bool registerProject(QETProject *)
Definition: qetapp.cpp:1958
void setSplashScreenStep(const QString &=QString())
Definition: qetapp.cpp:1597
static int projectId(const QETProject *)
Definition: qetapp.cpp:2002
static QETProject * project(const uint &)
Definition: qetapp.cpp:1990
static QString langFromSetting()
QETApp::langFromSetting.
Definition: qetapp.cpp:184
void receiveMessage(int instanceId, QByteArray message)
Definition: qetapp.cpp:1124
static QString languagesPath()
Definition: qetapp.cpp:864
void initSystemTray()
Definition: qetapp.cpp:1653
void quitQET()
Definition: qetapp.cpp:1254
void initIcons()
Definition: qeticons.cpp:226
QAction * reduce_diagrams
Definition: qetapp.h:167
#define QETAPP_CUSTOM_TBT_PROTOCOL
Definition: qetapp.h:36
static QStringList conductorInfoKeys()
QETApp::conductorInfoKeys.
Definition: qetapp.cpp:382
virtual QList< QString > elementFiles() const
static QString m_user_common_elements_dir
Definition: qetapp.h:197
static QString diagramTranslatedInfoKey(const QString &key)
QETApp::diagramTranslatedInfoKey.
Definition: qetapp.cpp:432
QAction * restore_diagrams
Definition: qetapp.h:168
static QETProject * projectFromString(const QString &)
Definition: qetapp.cpp:1737
static TitleBlockTemplatesFilesCollection * customTitleBlockTemplatesCollection()
Definition: qetapp.cpp:462
bool every_editor_reduced
Definition: qetapp.h:177
static QETApp * m_qetapp
Definition: qetapp.h:158
QList< QWidget * > floatingToolbarsAndDocksForMainWindow(QMainWindow *) const
Definition: qetapp.cpp:1514
bool every_element_reduced
Definition: qetapp.h:180
bool every_template_visible
Definition: qetapp.h:183
bool every_diagram_reduced
Definition: qetapp.h:178
QAction * reduce_appli
Definition: qetapp.h:165
void addPage(ConfigPage *)
static QFont indiTextsItemFont(qreal=-1.0)
QETApp::indiTextsItemFont The default font to use for independent text item.
Definition: qetapp.cpp:1007
bool closeEveryEditor()
Definition: qetapp.cpp:887
static void overrideLangDir(const QString &)
Definition: qetapp.cpp:853
void checkBackupFiles()
QETApp::checkBackupFiles Check for backup files. If backup was found, open a dialog and ask user what...
Definition: qetapp.cpp:1793
QMenu * menu_systray
Definition: qetapp.h:163
static RecentFiles * projectsRecentFiles()
Definition: qetapp.cpp:1166
static QList< QETTitleBlockTemplateEditor * > titleBlockTemplateEditors()
Definition: qetapp.cpp:1039
virtual bool printVersionRequested() const
static RecentFiles * m_projects_recent_files
Definition: qetapp.h:194
virtual bool printLicenseRequested() const
QETProject * project() const
static QList< QETElementEditor * > elementEditors()
Definition: qetapp.cpp:1032
static QString m_user_custom_elements_dir
Definition: qetapp.h:198
static QMap< uint, QETProject * > registered_projects_
Definition: qetapp.h:192
static QString elementInfoToVar(const QString &info)
QETApp::elementInfoToVar.
Definition: qetapp.cpp:355
QSplashScreen * m_splash_screen
Definition: qetapp.h:162
Definition: qetapp.h:53
QIcon tr
Definition: qeticons.cpp:204
static QStringList elementInfoKeys()
QETApp::elementInfoKeys.
Definition: qetapp.cpp:289
static QFont dynamicTextsItemFont(qreal=-1.0)
QETApp::dynamicTextsFont the defaukt font of dynamic element text item.
Definition: qetapp.cpp:962
static void printVersion()
Definition: qetapp.cpp:1935
virtual bool langDirSpecified() const
bool every_template_reduced
Definition: qetapp.h:182
QIcon ProjectFile
Definition: qeticons.cpp:147
static ElementsCollectionCache * collections_cache_
Definition: qetapp.h:191
QAction * restore_templates
Definition: qetapp.h:172
static void dropInstance()
dropInstance Drop the instance of factory
void switchLayout(Qt::LayoutDirection)
Definition: qetapp.cpp:194
void restoreEveryEditor()
Restaure toutes les fenetres de l&#39;application dans le systray.
Definition: qetapp.cpp:231
QHash< QMainWindow *, QByteArray > window_states
Definition: qetapp.h:176
QAction * quitter_qet
Definition: qetapp.h:164
static TitleBlockTemplatesFilesCollection * m_custom_tbt_collection
Definition: qetapp.h:190
QString filePath()
Definition: qetproject.cpp:243
virtual QString langDir() const
void setLanguage(const QString &)
Definition: qetapp.cpp:152
QTranslator qetTranslator
Definition: qetapp.h:160
static QString conductorTranslatedInfoKey(const QString &key)
QETApp::conductorTranslatedInfoKey.
Definition: qetapp.cpp:399
static QFont diagramTextsItemFont(qreal=-1.0)
QETApp::diagramTextsItemFont the font for to use in independent text item.
Definition: qetapp.cpp:934
#define TITLEBLOCKS_FILE_EXTENSION
void openProjectFiles(const QStringList &)
Definition: qetapp.cpp:1299
#define QUOTE(x)
Definition: qetapp.cpp:39
virtual QList< QString > titleBlockTemplateFiles() const
void useSystemPalette(bool)
Definition: qetapp.cpp:1232
void openBackupFiles(QList< KAutoSaveFile *> backup_files)
QETDiagramEditor::openBackupFiles.
void setMainWindowsVisible(bool)
Definition: qetapp.cpp:1157
static TitleBlockTemplate * default_titleblock_template_
Definition: qetapp.h:196
void openTitleBlockTemplateFiles(const QStringList &)
Definition: qetapp.cpp:1434
static TitleBlockTemplatesCollection * titleBlockTemplatesCollection(const QString &)
Definition: qetapp.cpp:493
void newDiagramEditor()
lance un nouvel editeur de schemas
Definition: qetapp.cpp:269
bool every_element_visible
Definition: qetapp.h:181
static QFont diagramTextsFont(qreal=-1.0)
QETApp::diagramTextsFont The font to use By default the font is "sans Serif" and size 9...
Definition: qetapp.cpp:910
void reduceTitleBlockTemplateEditors()
Reduce all known template editors.
Definition: qetapp.cpp:259
QIcon Cancel
Definition: qeticons.cpp:34
static QETDiagramEditor * diagramEditorAncestorOf(const QWidget *child)
QETApp::diagramEditorAncestorOf.
Definition: qetapp.cpp:796
QIcon ApplicationExit
Definition: qeticons.cpp:27
QMessageBox::StandardButton question(QWidget *, const QString &, const QString &, QMessageBox::StandardButtons=QMessageBox::Ok, QMessageBox::StandardButton=QMessageBox::NoButton)
static QString customElementsDirN()
QETApp::customElementsDirN like QString QETApp::customElementsDir but without "/" at the end...
Definition: qetapp.cpp:598
void initConfiguration()
Definition: qetapp.cpp:1631
static QList< TitleBlockTemplatesCollection * > availableTitleBlockTemplatesCollections()
Definition: qetapp.cpp:476
static QString elementTranslatedInfoKey(const QString &)
ElementsProperties::translatedInfo Return the translated information key given by If don&#39;t match...
Definition: qetapp.cpp:321
void restoreTitleBlockTemplateEditors()
Restore all known template editors.
Definition: qetapp.cpp:264
static QList< QETDiagramEditor * > diagramEditors()
Definition: qetapp.cpp:1025
virtual bool printHelpRequested() const
static QString commonElementsDir()
QETApp::commonElementsDir.
Definition: qetapp.cpp:511
QSystemTrayIcon * m_qsti
Definition: qetapp.h:161
void openElementLocations(const QList< ElementsLocation > &)
Definition: qetapp.cpp:1377
static TitleBlockTemplatesFilesCollection * m_common_tbt_collection
Definition: qetapp.h:189
QETApp()
QETApp::QETApp.
Definition: qetapp.cpp:73
static QString lang_dir
Directory containing localization files.
Definition: qetapp.h:134
void checkRemainingWindows()
Definition: qetapp.cpp:1264
static QString commonElementsDirN()
QETApp::commonElementsDirN like QString QETApp::commonElementsDir but without "/" at the end...
Definition: qetapp.cpp:586
static RecentFiles * elementsRecentFiles()
Definition: qetapp.cpp:1173
From common collection.
Definition: qet.h:151
static QString m_user_custom_tbt_dir
Definition: qetapp.h:199
virtual QList< QString > files() const
static void resetUserElementsDir()
QETApp::resetUserElementsDir Reset the path of the user common and custom elements dir...
Definition: qetapp.cpp:610
static uint next_project_id
Definition: qetapp.h:193
static QETApp * instance()
Definition: qetapp.cpp:143
static void printLicense()
Definition: qetapp.cpp:1942
QList< T * > detectWindows() const
Definition: qetapp.cpp:1142
QIcon de
Definition: qeticons.cpp:188
QTranslator qtTranslator
Definition: qetapp.h:159
static QETDiagramEditor * diagramEditorForFile(const QString &)
Definition: qetapp.cpp:777
QIcon Restore
Definition: qeticons.cpp:156
QIcon WindowNew
Definition: qeticons.cpp:175
void restoreDiagramEditors()
Restaure tous les editeurs de schemas dans le systray.
Definition: qetapp.cpp:244
static QString realPath(const QString &)
Definition: qetapp.cpp:704
static QString configDir()
Definition: qetapp.cpp:676
static QStringList diagramInfoKeys()
QETApp::diagramInfoKeys.
Definition: qetapp.cpp:412