swift
guiapplication.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2016 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "gui/guiapplication.h"
5 
6 #include <QAction>
7 #include <QApplication>
8 #include <QCloseEvent>
9 #include <QCommandLineParser>
10 #include <QDesktopServices>
11 #include <QDir>
12 #include <QEventLoop>
13 #include <QFont>
14 #include <QGuiApplication>
15 #include <QIcon>
16 #include <QKeySequence>
17 #include <QMainWindow>
18 #include <QMenu>
19 #include <QMessageBox>
20 #include <QSettings>
21 #include <QStringBuilder>
22 #include <QStringList>
23 #include <QStyle>
24 #include <QStyleFactory>
25 #include <QToolBar>
26 #include <QUrl>
27 #include <QWhatsThis>
28 #include <QWidget>
29 #include <Qt>
30 #include <QtGlobal>
31 
32 #include "config/buildconfig.h"
34 #include "core/data/globalsetup.h"
35 #include "core/db/infodatareader.h"
36 #include "core/setupreader.h"
37 #include "core/webdataservices.h"
42 #include "gui/guiutility.h"
43 #include "gui/registermetadata.h"
44 #include "gui/splashscreen.h"
45 #include "misc/datacache.h"
46 #include "misc/logcategories.h"
47 #include "misc/loghandler.h"
48 #include "misc/logmessage.h"
49 #include "misc/metadatautils.h"
50 #include "misc/settingscache.h"
51 #include "misc/slot.h"
52 #include "misc/stringutils.h"
53 #include "misc/swiftdirectories.h"
54 #include "misc/verify.h"
55 
56 using namespace swift::config;
57 using namespace swift::misc;
58 using namespace swift::misc::db;
59 using namespace swift::misc::network;
60 using namespace swift::gui::components;
61 using namespace swift::core;
62 using namespace swift::core::data;
63 using namespace swift::core::context;
64 
65 swift::gui::CGuiApplication *sGui = nullptr; // set by constructor
66 
67 namespace swift::gui
68 {
69  CGuiApplication *CGuiApplication::instance() { return qobject_cast<CGuiApplication *>(CApplication::instance()); }
70 
71  const QStringList &CGuiApplication::getLogCategories()
72  {
73  static const QStringList l(CApplication::getLogCategories() + QStringList { CLogCategories::guiComponent() });
74  return l;
75  }
76 
77  const QString &CGuiApplication::settingsOrganization()
78  {
79  static const QString o("swift-project.org");
80  return o;
81  }
82 
83  bool CGuiApplication::removeAllWindowsSwiftRegistryEntries()
84  {
85  if (!CBuildConfig::isRunningOnWindowsNtPlatform()) { return false; }
86 
87  // On Windows, NativeFormat settings are stored in the following registry paths:
88  // HKEY_CURRENT_USER\Software\MySoft\Star Runner.
89  // HKEY_CURRENT_USER\Software\MySoft\OrganizationDefaults.
90  // HKEY_LOCAL_MACHINE\Software\MySoft\Star Runner.
91  // HKEY_LOCAL_MACHINE\Software\MySoft\OrganizationDefaults.
92 
93  QSettings s1("HKEY_CURRENT_USER\\Software\\" + settingsOrganization(), QSettings::NativeFormat);
94  s1.remove("");
95 
96  QSettings s2("HKEY_LOCAL_MACHINE\\Software\\" + settingsOrganization(), QSettings::NativeFormat);
97  s2.remove("");
98 
99  return true;
100  }
101 
102  CGuiApplication::CGuiApplication(const QString &applicationName, CApplicationInfo::Application application,
103  const QPixmap &icon)
104  : CApplication(applicationName, application, false)
105  {
106  this->addWindowModeOption();
107  this->addWindowResetSizeOption();
108 
109  // notify when app goes down
111 
112  if (!sGui)
113  {
115  CApplication::init(false); // base class without metadata
116  CGuiApplication::adjustPalette();
118  this->settingsChanged();
119  this->setCurrentFontValues(); // most likely the default font and not any stylesheet font at this time
120  sGui = this;
121 
122  connect(&m_styleSheetUtility, &CStyleSheetUtility::styleSheetsChanged, this,
123  &CGuiApplication::onStyleSheetsChanged, Qt::QueuedConnection);
124  connect(this, &CGuiApplication::startUpCompleted, this, &CGuiApplication::superviseWindowMinSizes,
126  }
127  }
128 
130 
132  {
133  CApplication::registerMetadata();
135  }
136 
138  {
139  m_cmdWindowMode = QCommandLineOption(
140  { "w", "window" }, QCoreApplication::translate("main", "Windows: (n)ormal, (f)rameless, (t)ool."),
141  "windowtype");
142  this->addParserOption(m_cmdWindowMode);
143  }
144 
146  {
147  m_cmdWindowSizeReset = QCommandLineOption(
148  { { "r", "resetsize" }, QCoreApplication::translate("main", "Reset window size (ignore saved values).") });
149  this->addParserOption(m_cmdWindowSizeReset);
150  }
151 
153  {
154  m_cmdWindowStateMinimized = QCommandLineOption(
155  { { "m", "minimized" }, QCoreApplication::translate("main", "Start minimized in system tray.") });
156  this->addParserOption(m_cmdWindowStateMinimized);
157  }
158 
160  {
161  if (m_cmdWindowStateMinimized.valueName() == "empty") { return Qt::WindowNoState; }
162  if (m_parser.isSet(m_cmdWindowStateMinimized)) { return Qt::WindowMinimized; }
163  return Qt::WindowNoState;
164  }
165 
167  {
168  if (this->isParserOptionSet(m_cmdWindowMode))
169  {
170  const QString v(this->getParserValue(m_cmdWindowMode));
172  }
173  else { return CEnableForFramelessWindow::WindowNormal; }
174  }
175 
177  {
178  if (m_splashScreen)
179  {
180  m_splashScreen.reset(); // delete old one
181  }
182 
183  QFont splashFont;
184  splashFont.setFamily("Arial");
185  // splashFont.setBold(true);
186  splashFont.setPointSize(10);
187  splashFont.setStretch(100);
188 
189  m_splashScreen.reset(new CSplashScreen(pixmap.scaled(256, 256), splashFont));
190  m_splashScreen->show();
191  m_splashScreen->showStatusMessage("Version " + CBuildConfig::getVersionString());
192  }
193 
195  {
196  if (this->isShuttingDown()) { return; }
198  }
199 
201 
203  {
205  }
206 
208  {
209  if (this->getGlobalSetup().isSwiftVersionMinimumMappingVersion()) { return true; }
210 
211  const QString msg =
212  QStringLiteral("Your are using swift version: '%1'.\nCreating mappings requires at least '%2'.")
213  .arg(CBuildConfig::getVersionString(), this->getGlobalSetup().getMappingMinimumVersionString());
215  return false;
216  }
217 
219  {
220  return qobject_cast<QMainWindow *>(CGuiApplication::mainApplicationWidget());
221  }
222 
224  {
225  IMainWindowAccess *m = qobject_cast<IMainWindowAccess *>(mainApplicationWidget());
226  return m;
227  }
228 
230  {
231  if (!mainWidget) { return; }
232  if (m_uiSetupCompleted) { return; }
233  m_uiSetupCompleted = true;
234 
235  const QString name = this->setExtraWindowTitle("", mainWidget);
237  mainWidget->setWindowIcon(m_windowIcon);
238  mainWidget->setWindowIconText(name);
241  emit this->uiObjectTreeReady();
242  }
243 
245  {
247  if (maw)
248  {
249  Qt::WindowFlags windowFlags = maw->windowFlags();
250  windowFlags |= flags;
251  maw->setWindowFlags(windowFlags);
252  }
253  else
254  {
255  QPointer<CGuiApplication> myself(this);
257  if (!myself) { return; }
258  this->addWindowFlags(flags);
259  });
260  }
261  }
262 
263  QString CGuiApplication::setExtraWindowTitle(const QString &extraInfo, QWidget *mainWindowWidget) const
264  {
266  if (!extraInfo.isEmpty()) { name = extraInfo % u' ' % name; }
267  if (!mainWindowWidget) { return name; }
268  mainWindowWidget->setWindowTitle(name);
269  return name;
270  }
271 
273  {
274  instance()->m_windowIcon = icon;
276  }
277 
278  void CGuiApplication::exit(int retcode) { CApplication::exit(retcode); }
279 
281  {
283  if (!w) return QGuiApplication::primaryScreen();
284 
285  const QWindow *win = w->windowHandle();
286 
287  if (!win) return QGuiApplication::primaryScreen();
288 
289  QScreen *screen = win->screen();
290 
291  return screen ? screen : QGuiApplication::primaryScreen();
292  }
293 
295  {
296  const QScreen *s = currentScreen();
297  if (s) return s->geometry();
298  return {};
299  }
300 
302  {
303  if (!QGuiApplication::modalWindow()) { return; }
305  }
306 
307  const QString &CGuiApplication::fileForWindowGeometryAndStateSettings()
308  {
309  static const QString filename = [] {
310  QString dir =
311  CFileUtils::appendFilePaths(CSwiftDirectories::normalizedApplicationDataDirectory(), "settings/qgeom");
312  return CFileUtils::appendFilePaths(
313  dir, QFileInfo(QCoreApplication::applicationFilePath()).completeBaseName() + ".ini");
314  }();
315  return filename;
316  }
317 
318  int CGuiApplication::hashForStateSettingsSchema(const QMainWindow *window)
319  {
320  size_t hash = 0;
321  for (auto obj : window->findChildren<QToolBar *>(QString(), Qt::FindDirectChildrenOnly))
322  {
323  hash ^= qHash(obj->objectName());
324  }
325  for (auto obj : window->findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly))
326  {
327  hash ^= qHash(obj->objectName());
328  }
329  return static_cast<int>((hash & 0xffff) ^ (hash >> 16));
330  }
331 
333  {
334  if (!window) { return false; }
335  QSettings settings(fileForWindowGeometryAndStateSettings(), QSettings::IniFormat);
336  settings.setValue("geometry", window->saveGeometry());
337  settings.setValue("windowState", window->saveState(hashForStateSettingsSchema(window)));
338  return true;
339  }
340 
342  {
343  QByteArray ba;
344  QSettings settings(fileForWindowGeometryAndStateSettings(), QSettings::IniFormat);
345  settings.setValue("geometry", ba);
346  settings.setValue("windowState", ba);
347  }
348 
350  {
351  if (!window) { return false; }
352  const QSettings settings(fileForWindowGeometryAndStateSettings(), QSettings::IniFormat);
353  const QString location = settings.fileName();
354  CLogMessage(this).info(u"GUI settings are here: '%1'") << location;
355 
356  const QByteArray g = settings.value("geometry").toByteArray();
357  const QByteArray s = settings.value("windowState").toByteArray();
358  if (g.isEmpty() || s.isEmpty()) { return false; }
359 
360  // block for subscriber
361  {
362  const auto pattern = CLogPattern().withSeverity(CStatusMessage::SeverityError);
363  const QString parameter = m_cmdWindowSizeReset.names().first();
364  CLogSubscriber logSub(this, [&](const CStatusMessage &message) {
365  // handles an error in restoreGeometry/State
366  const int ret =
368  QStringLiteral("Restoring the window state/geometry failed!\n"
369  "You need to reset the window size (command -%1).\n\n"
370  "Original msg: %2\n\n"
371  "We can try to reset the values and restart\n"
372  "Do you want to try?")
373  .arg(parameter, message.getMessage()),
375  if (ret == QMessageBox::Yes)
376  {
378  this->restartApplication();
379  }
380  // most likely crashing if we do nothing
381  });
382  logSub.changeSubscription(pattern);
383 
384  window->restoreGeometry(g);
385  window->restoreState(s, hashForStateSettingsSchema(window));
386  }
387  return true;
388  }
389 
391  {
392  CApplication::onStartUpCompleted();
393  this->setCurrentFontValues();
394 
395  const QString metricInfo = CGuiUtility::metricsInfo();
396  CLogMessage(this).info(metricInfo);
397 
398  // window size
399  if (m_minWidthChars > 0 || m_minHeightChars > 0)
400  {
401  const QSizeF fontMetricEstSize = CGuiUtility::fontMetricsEstimateSize(m_minWidthChars, m_minHeightChars);
403  if (mw)
404  {
405  // setMinimumSizeInCharacters sets m_minHeightChars/m_minWidthChars
406  QSize cs = mw->size();
407  if (m_minWidthChars > 0) { cs.setWidth(qRound(fontMetricEstSize.width())); }
408  if (m_minHeightChars > 0) { cs.setHeight(qRound(fontMetricEstSize.height())); }
409  mw->resize(cs);
410  }
411  }
412  if (m_saveMainWidgetState && !this->isSet(m_cmdWindowSizeReset))
413  {
415  const bool shiftAlt = km.testFlag(Qt::ShiftModifier) && km.testFlag(Qt::AltModifier);
416  if (!shiftAlt) { this->restoreWindowGeometryAndState(); }
417  }
418 
419  if (m_splashScreen)
420  {
421  m_splashScreen->close(); // GUI
422  m_splashScreen.reset();
423  }
424  }
425 
426  void CGuiApplication::cmdLineErrorMessage(const QString &text, const QString &informativeText) const
427  {
429  if (informativeText.length() < 300)
430  errorBox.setInformativeText(informativeText);
431  else
432  errorBox.setDetailedText(informativeText);
433 
434  errorBox.addButton(QMessageBox::Abort);
435 
436  errorBox.exec();
437  }
438 
440  {
441  if (msgs.isEmpty()) { return; }
442  if (!msgs.hasErrorMessages()) { return; }
443  static const CPropertyIndexList propertiesSingle({ CStatusMessage::IndexMessage });
444  static const CPropertyIndexList propertiesMulti(
445  { CStatusMessage::IndexSeverityAsString, CStatusMessage::IndexMessage });
446  const QString msgsHtml = msgs.toHtml(msgs.size() > 1 ? propertiesMulti : propertiesSingle);
448  "<html><head><body>" + msgsHtml + "</body></html>", QMessageBox::Abort,
450  }
451 
452  bool CGuiApplication::isCmdWindowSizeResetSet() const { return this->isParserOptionSet(m_cmdWindowSizeReset); }
453 
455  {
457  SWIFT_VERIFY_X(m, Q_FUNC_INFO, "No access interface");
458  if (!m) { return false; }
459  return m->displayInStatusBar(message);
460  }
461 
462  bool CGuiApplication::displayInOverlayWindow(const CStatusMessage &message, std::chrono::milliseconds timeout)
463  {
464  if (message.isEmpty()) { return false; }
466  SWIFT_VERIFY_X(m, Q_FUNC_INFO, "No access interface");
467  if (!m) { return IMainWindowAccess::displayInOverlayWindow(message, timeout); }
468  return m->displayInOverlayWindow(message, timeout);
469  }
470 
471  bool CGuiApplication::displayInOverlayWindow(const CStatusMessageList &messages, std::chrono::milliseconds timeout)
472  {
473  if (messages.isEmpty()) { return false; }
475  SWIFT_VERIFY_X(m, Q_FUNC_INFO, "No access interface");
476  if (!m) { return IMainWindowAccess::displayInOverlayWindow(messages, timeout); }
477  return m->displayInOverlayWindow(messages, timeout);
478  }
479 
480  bool CGuiApplication::displayInOverlayWindow(const QString &html, std::chrono::milliseconds timeout)
481  {
482  if (html.isEmpty()) { return false; }
484  SWIFT_VERIFY_X(m, Q_FUNC_INFO, "No access interface");
485  if (!m) { return IMainWindowAccess::displayInOverlayWindow(html, timeout); }
486  return m->displayInOverlayWindow(html, timeout);
487  }
488 
490  {
491  QMenu *sm = menu.addMenu(CIcons::appSettings16(), "Settings");
492  sm->setIcon(CIcons::appSettings16());
493  QAction *a = sm->addAction(CIcons::disk16(), "Settings directory");
494  bool c = connect(a, &QAction::triggered, this, [=]() {
495  if (!sGui || sGui->isShuttingDown()) { return; }
496  const QString path(QDir::toNativeSeparators(CSettingsCache::persistentStore()));
497  if (QDir(path).exists()) { QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }
498  });
499  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
500 
501  a = sm->addAction("Reset settings");
502  c = connect(a, &QAction::triggered, this, [=] {
503  if (!sGui || sGui->isShuttingDown()) { return; }
504  CSettingsCache::instance()->clearAllValues();
505  CLogMessage(this).info(u"Cleared all settings!");
506  });
507  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
508 
509  a = sm->addAction("List settings files");
510  c = connect(a, &QAction::triggered, this, [=]() {
511  if (!sGui || sGui->isShuttingDown()) { return; }
512  const QStringList files(CSettingsCache::instance()->enumerateStore());
513  CLogMessage(this).info(files.join("\n"));
514  });
515  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
516 
517  sm = menu.addMenu("Cache");
518  sm->setIcon(CIcons::appSettings16());
519  a = sm->addAction(CIcons::disk16(), "Cache directory");
520  c = connect(a, &QAction::triggered, this, [=]() {
521  const QString path(QDir::toNativeSeparators(CDataCache::persistentStore()));
522  if (QDir(path).exists()) { QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }
523  });
524  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
525 
526  a = sm->addAction("Reset cache");
527  c = connect(a, &QAction::triggered, this, [=]() {
528  if (!sGui || sGui->isShuttingDown()) { return; }
529  const QStringList files = CApplication::clearCaches();
530  CLogMessage(this).info(u"Cleared caches! " % QString::number(files.size()) + " files");
531  });
532  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
533 
534  a = sm->addAction("List cache files");
535  c = connect(a, &QAction::triggered, this, [=]() {
536  if (!sGui || sGui->isShuttingDown()) { return; }
537  const QStringList files(CDataCache::instance()->enumerateStore());
538  CLogMessage(this).info(files.join("\n"));
539  });
540  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
541 
542  a = menu.addAction(CIcons::disk16(), "Log directory");
543  c = connect(a, &QAction::triggered, this, [=]() {
544  if (!sGui || sGui->isShuttingDown()) { return; }
545  this->openStandardLogDirectory();
546  });
547  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
548 
549  a = menu.addAction(CIcons::disk16(), "Crash dumps directory");
550  c = connect(a, &QAction::triggered, this, [=]() {
551  if (!sGui || sGui->isShuttingDown()) { return; }
552  this->openStandardCrashDumpDirectory();
553  });
554  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
555 
556  a = menu.addAction(CIcons::swift24(), "Check for updates");
557  c = connect(a, &QAction::triggered, this, &CGuiApplication::checkNewVersionMenu);
558  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
559  Q_UNUSED(c)
560  }
561 
563  {
564  QMenu *sm = menu.addMenu("Style sheet");
565  QAction *aReload = sm->addAction(CIcons::refresh16(), "Reload");
566  bool c = connect(aReload, &QAction::triggered, this, [=]() {
567  if (!sGui || sGui->isShuttingDown()) { return; }
568  this->reloadStyleSheets();
569  });
570  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
571 
572  QAction *aOpen = sm->addAction(CIcons::text16(), "Open qss file");
573  c = connect(aOpen, &QAction::triggered, this, [=]() {
574  if (!sGui || sGui->isShuttingDown()) { return; }
575  this->openStandardWidgetStyleSheet();
576  });
577  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
578  Q_UNUSED(c)
579  }
580 
582  {
584  addMenuForStyleSheets(menu);
585  QAction *a = nullptr;
586  bool c = false;
587 
588  menu.addSeparator();
589  a = menu.addAction("E&xit");
590  // a->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); // avoid accidentally closing
591  c = connect(
592  a, &QAction::triggered, this,
593  [=]() {
594  // a close event might already trigger a shutdown
595  if (!sGui || sGui->isShuttingDown()) { return; }
596  if (!CGuiApplication::mainApplicationWidget()) { return; }
598 
599  // T596, do not shutdown here, as close can be canceled
600  // if shutdown is called, there is no way back
601  // this->gracefulShutdown();
602  },
604  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
605  Q_UNUSED(c)
606  }
607 
609  {
610  QMenu *sm = menu.addMenu("JSON files/Templates");
611  QAction *a = sm->addAction("JSON bootstrap");
612  bool c = connect(
613  a, &QAction::triggered, this,
614  [=]() {
615  if (!sGui || sGui->isShuttingDown()) { return; }
616  const CGlobalSetup s = this->getGlobalSetup();
617  CLogMessage(this).info(s.toJsonString());
618  },
620  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
621 
622  a = sm->addAction("JSON version update info (for info only)");
623  c = connect(
624  a, &QAction::triggered, this,
625  [=]() {
626  if (!sGui || sGui->isShuttingDown()) { return; }
627  const CUpdateInfo info = this->getUpdateInfo();
628  CLogMessage(this).info(info.toJsonString());
629  },
631  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
632 
633  if (this->hasWebDataServices())
634  {
635  a = menu.addAction("Services log.(console)");
636  c = connect(
637  a, &QAction::triggered, this,
638  [=]() {
639  if (!sGui || sGui->isShuttingDown()) { return; }
640  CLogMessage(this).info(this->getWebDataServices()->getReadersLog());
641  },
643  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
644 
645  a = sm->addAction("JSON DB info (for info only)");
646  c = connect(
647  a, &QAction::triggered, this,
648  [=]() {
649  if (!sGui || sGui->isShuttingDown()) { return; }
650  if (!this->getWebDataServices()->getDbInfoDataReader()) { return; }
652  CLogMessage(this).info(u"DB info:\n" % info.toJsonString());
653  },
655  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
656 
657  a = sm->addAction("JSON shared info (for info only)");
658  c = connect(
659  a, &QAction::triggered, this,
660  [=]() {
661  if (!sGui || sGui->isShuttingDown()) { return; }
662  if (!this->getWebDataServices()->getDbInfoDataReader()) { return; }
664  CLogMessage(this).info(u"Shared info:\n" % info.toJsonString());
665  },
667  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
668  }
669 
670  a = menu.addAction("Metadata (slow)");
671  c = connect(
672  a, &QAction::triggered, this,
673  [=]() {
674  if (!sGui || sGui->isShuttingDown()) { return; }
676  },
678  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
679  Q_UNUSED(c)
680  }
681 
683  {
685  if (!w) { return; }
686  const QSize iconSize = CIcons::empty16().size();
687  static QPixmap iconEmpty;
688 
689  QPixmap icon = w->style()->standardIcon(QStyle::SP_TitleBarMaxButton).pixmap(iconSize);
690  QAction *a = menu.addAction(icon.isNull() ? iconEmpty : icon.scaled(iconSize), "Fullscreen");
691  bool c = connect(a, &QAction::triggered, this, [=]() {
692  if (!w) { return; }
693  w->showFullScreen();
694  });
695  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
696 
697  icon = w->style()->standardIcon(QStyle::SP_TitleBarMinButton).pixmap(iconSize);
698  a = menu.addAction(icon.isNull() ? iconEmpty : icon.scaled(iconSize), "Minimize");
699  c = connect(a, &QAction::triggered, this, [=]() {
700  if (!w) { return; }
701  w->showMinimized();
702  });
703  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
704 
705  icon = w->style()->standardIcon(QStyle::SP_TitleBarNormalButton).pixmap(iconSize);
706  a = menu.addAction(icon.isNull() ? iconEmpty : icon.scaled(iconSize), "Normal");
707  c = connect(a, &QAction::triggered, this, [=]() {
708  if (!w) { return; }
709  w->showNormal();
710  });
711  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
712 
713  a = menu.addAction("Toggle stay on top");
714  c = connect(a, &QAction::triggered, this, [=]() {
715  if (!w) { return; }
716  this->toggleStayOnTop();
717  });
718  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
719 
720  a = menu.addAction("Toggle to front or back");
722  Q_ASSERT_X(c, Q_FUNC_INFO, "connect failed");
723 
724  a = menu.addAction("Window to front");
726  Q_ASSERT_X(c, Q_FUNC_INFO, "connect failed");
727 
728  a = menu.addAction("Window to back");
730  Q_ASSERT_X(c, Q_FUNC_INFO, "connect failed");
731 
732  a = menu.addAction("Toggle normal or minimized");
733  c = connect(a, &QAction::triggered, this, [=]() {
734  if (!w) { return; }
736  });
737  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
738  Q_UNUSED(c)
739  }
740 
742  {
743  if (url.isEmpty() || this->isShuttingDown()) { return; }
745  }
746 
748  {
750  if (!w) { return; }
751  QAction *a = menu.addAction(w->style()->standardIcon(QStyle::SP_TitleBarContextHelpButton), "Online help");
752 
753  bool c = connect(a, &QAction::triggered, this, [=]() {
754  if (!sGui || sGui->isShuttingDown()) { return; }
755  this->showHelp();
756  });
757  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
758 
759  a = menu.addAction(QApplication::windowIcon(), "About swift");
760  c = connect(a, &QAction::triggered, this, [=]() {
761  if (!w) { return; }
762  CAboutDialog dialog(w);
763  dialog.exec();
764  });
765  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
766  Q_UNUSED(c)
767 
768  // https://joekuan.wordpress.com/2015/09/23/list-of-qt-icons/
769  a = menu.addAction(QApplication::style()->standardIcon(QStyle::SP_TitleBarMenuButton), "About Qt");
770  c = connect(a, &QAction::triggered, this, []() { QApplication::aboutQt(); });
771  Q_ASSERT_X(c, Q_FUNC_INFO, "Connect failed");
772  Q_UNUSED(c)
773  }
774 
775  void CGuiApplication::showHelp(const QString &subpath) const
776  {
777  if (this->isShuttingDown()) { return; }
778  const CGlobalSetup gs = this->getGlobalSetup();
779  const CUrl helpPage = gs.getHelpPageUrl().withAppendedPath(subpath);
780  QDesktopServices::openUrl(helpPage);
781  }
782 
783  const CStyleSheetUtility &CGuiApplication::getStyleSheetUtility() const { return m_styleSheetUtility; }
784 
786  {
787  QString currentWidgetStyle(QApplication::style()->metaObject()->className());
788  if (currentWidgetStyle.startsWith('Q')) { currentWidgetStyle.remove(0, 1); }
789  return currentWidgetStyle.replace("Style", "");
790  }
791 
792  bool CGuiApplication::reloadStyleSheets() { return m_styleSheetUtility.read(); }
793 
795  {
798  }
799 
801  {
802  const QString path(QDir::toNativeSeparators(CSwiftDirectories::logDirectory()));
803  if (!QDir(path).exists()) { return false; }
805  }
806 
808  {
809  const QString path(QDir::toNativeSeparators(CSwiftDirectories::crashpadDatabaseDirectory()));
810  if (!QDir(path).exists()) { return false; }
812  }
813 
814  bool CGuiApplication::updateFont(const QString &fontFamily, const QString &fontSize, const QString &fontStyle,
815  const QString &fontWeight, const QString &fontColor)
816  {
817  return m_styleSheetUtility.updateFont(fontFamily, fontSize, fontStyle, fontWeight, fontColor);
818  }
819 
820  bool CGuiApplication::updateFont(const QString &qss) { return m_styleSheetUtility.updateFont(qss); }
821 
822  bool CGuiApplication::resetFont() { return m_styleSheetUtility.resetFont(); }
823 
824  void CGuiApplication::setMinimumSizeInCharacters(int widthChars, int heightChars)
825  {
826  m_minWidthChars = widthChars;
827  m_minHeightChars = heightChars;
828  }
829 
831  {
832  if (msgs.hasErrorMessages())
833  {
835  if (sGui)
836  {
837  static const QString style = sGui->getStyleSheetUtility().styles(
839  dialog.setStyleSheet(style);
840  }
841 
842  dialog.exec();
843  }
844  }
845 
847  {
848  this->saveSettingsOnShutdown(false); // saving itself will be handled in dialog
849  const bool needsDialog = this->hasUnsavedSettings();
850  if (!needsDialog) { return QDialog::Accepted; }
851  if (!m_closeDialog)
852  {
853  m_closeDialog = new CApplicationCloseDialog(mainWindow);
854  if (mainWindow && !mainWindow->windowTitle().isEmpty())
855  {
856  m_closeDialog->setWindowTitle(mainWindow->windowTitle());
857  m_closeDialog->setModal(true);
858  }
859  }
860 
861  // dialog will handle the saving
862  const auto c = static_cast<QDialog::DialogCode>(m_closeDialog->exec());
863 
864  // settings already saved when reaching here
865  switch (c)
866  {
867  case QDialog::Rejected:
868  if (closeEvent) { closeEvent->ignore(); }
869  break;
870  default: break;
871  }
872  return c;
873  }
874 
875  bool CGuiApplication::parsingHookIn() { return true; }
876 
878  {
879  // Nothing to do here
880  }
881 
882  void CGuiApplication::checkNewVersion(bool onlyIfNew)
883  {
884  if (!m_updateDialog)
885  {
886  // without parent stylesheet is not inherited
888  }
889 
890  if (onlyIfNew && !m_updateDialog->isNewVersionAvailable()) { return; }
891  const int result = m_updateDialog->exec();
892  if (result != QDialog::Accepted) { return; }
893  }
894 
896  {
898  if (!w) { return QStringLiteral("Font info not available"); }
899  return QStringLiteral("Family: '%1', average width: %2")
900  .arg(w->font().family())
901  .arg(w->fontMetrics().averageCharWidth());
902  }
903 
905  {
907  if (!w) { return false; }
908  const bool onTop = CGuiUtility::toggleStayOnTop(w);
909  CLogMessage(w).info(onTop ? QStringLiteral("Window on top") : QStringLiteral("Window not always on top"));
910  emit this->alwaysOnTop(onTop);
911  m_frontBack = onTop;
912  return onTop;
913  }
914 
916  {
917  if (this->isShuttingDown()) { return; }
919  if (!w) { return; }
920 
921  m_frontBack = true;
922  w->showNormal(); // bring window to top on OSX
923  w->raise(); // bring window from minimized state on OSX
924 
925  // if (!CGuiUtility::staysOnTop(w)) { CGuiUtility::stayOnTop(true, w); emit this->alwaysOnTop(true); }
926  w->activateWindow(); // bring window to front/unminimize on windows
927  }
928 
930  {
931  if (this->isShuttingDown()) { return; }
933  if (!w) { return; }
934 
935  m_frontBack = false;
937  {
938  CGuiUtility::stayOnTop(false, w);
939  emit this->alwaysOnTop(false);
940  }
941  w->lower();
942  }
943 
945  {
946  if (this->isShuttingDown()) { return; }
948  if (!w) { return; }
949  if (w->isMinimized())
950  {
951  this->windowToFront();
952  return;
953  }
954  if (w->isMaximized())
955  {
956  this->windowToBack();
957  return;
958  }
960  {
961  this->windowToBack();
962  return;
963  }
964 
965  if (m_frontBack) { this->windowToBack(); }
966  else { this->windowToFront(); }
967  }
968 
970  {
971  if (this->isShuttingDown()) { return; }
973  if (!w) { return; }
974  if (m_normalizeMinimize) { w->showMinimized(); }
975  else
976  {
977  // trick here is to minimize first and the normalize from minimized state
978  w->showMinimized();
979  w->showNormal();
980  }
981  m_normalizeMinimize = !m_normalizeMinimize;
982  }
983 
985  {
986  if (!m_updateSetting.get()) { return; }
987  QTimer::singleShot(delayedMs, this, [=] {
988  if (!sGui || sGui->isShuttingDown()) { return; }
989  if (m_updateDialog) { return; } // already checked elsewhere
990  this->checkNewVersion(true);
991  });
992  }
993 
995  {
996  if (m_shutdown) { return; }
997  if (m_shutdownInProgress) { return; }
998 
999  CLogMessage(this).info(u"Graceful shutdown of GUI application started");
1000  if (m_saveMainWidgetState)
1001  {
1002  CLogMessage(this).info(u"Graceful shutdown, saving geometry");
1004  }
1005 
1006  // shut down whole infrastructure
1007  CApplication::gracefulShutdown();
1008 
1009  // precautions to avoid hanging closing swift
1011  if (modals.count() > 0)
1012  {
1013  // that is a pretty normal situation
1014  CLogMessage(this).info(u"Graceful shutdown, still %1 modal widget(s), closed: %2")
1015  << modals.count() << modals.join(", ");
1016  }
1017 
1020  const QStringList docks =
1022  if (docks.count() > 0)
1023  {
1024  // that should not happen
1025  CLogMessage(this).warning(u"Graceful shutdown, still %1 floating dock widget(s), closed: %2")
1026  << docks.count() << docks.join(", ");
1027  }
1028  }
1029 
1030  void CGuiApplication::settingsChanged()
1031  {
1032  // changing widget style is slow, so I try to prevent setting it when nothing changed
1033  const QString widgetStyle = m_guiSettings.get().getWidgetStyle();
1034  const QString currentWidgetStyle(this->getWidgetStyle());
1035  Q_ASSERT_X(CThreadUtils::thisIsMainThread(), Q_FUNC_INFO, "Wrong thread");
1036  if (!stringCompare(widgetStyle, currentWidgetStyle, Qt::CaseInsensitive))
1037  {
1038  const QStringList availableStyles = QStyleFactory::keys();
1039  if (availableStyles.contains(widgetStyle))
1040  {
1041  // changing style freezes the application, so it must not be done in flight mode
1042  if (this->getIContextNetwork() && this->getIContextNetwork()->isConnected())
1043  {
1044  CLogMessage(this).validationError(u"Cannot change style while connected to network");
1045  }
1046  else
1047  {
1048  // QStyle *style = QApplication::setStyle(widgetStyle);
1049  QStyle *style = QStyleFactory::create(widgetStyle);
1050  // That can crash
1051  QApplication::setStyle(style); // subject of crash
1052  if (style)
1053  {
1054  CLogMessage(this).info(u"Changed style to '%1', req.: '%2'")
1055  << style->objectName() << widgetStyle;
1056  }
1057  else { CLogMessage(this).error(u"Unable to set requested style '%1'") << widgetStyle; }
1058  }
1059  } // valid style
1060  }
1061  }
1062 
1063  void CGuiApplication::checkNewVersionMenu() { this->checkNewVersion(false); }
1064 
1065  void CGuiApplication::adjustPalette()
1066  {
1067  // only way to change link color
1068  // https://stackoverflow.com/q/5497799/356726
1069  // Ref T84
1070  QPalette newPalette(qApp->palette());
1071  const QColor linkColor(135, 206, 250);
1072  newPalette.setColor(QPalette::Link, linkColor);
1073  newPalette.setColor(QPalette::LinkVisited, linkColor);
1074  qApp->setPalette(newPalette);
1075  }
1076 
1077  void CGuiApplication::onStyleSheetsChanged()
1078  {
1079  const QFont f = CGuiUtility::currentFont();
1080  if (f.pointSize() != m_fontPointSize || f.family() != m_fontFamily)
1081  {
1082  emit this->fontChanged();
1083  CLogMessage(this).info(this->getFontInfo());
1084  }
1085  emit this->styleSheetsChanged();
1086  }
1087 
1088  void CGuiApplication::setCurrentFontValues()
1089  {
1090  const QFont font = CGuiUtility::currentFont();
1091  m_fontFamily = font.family();
1092  m_fontPointSize = font.pointSize();
1093  }
1094 
1095  void CGuiApplication::superviseWindowMinSizes() { CGuiUtility::superviseMainWindowMinSizes(); }
1096 } // namespace swift::gui
static constexpr bool isRunningOnWindowsNtPlatform()
Running on Windows NT platform?
QString getParserValue(const QString &option) const
Delegates to QCommandLineParser::value.
std::atomic_bool m_shutdown
Is being shutdown?
Definition: application.h:579
void restartApplication(const QStringList &newArguments={}, const QStringList &removeArguments={})
Stop and restart application.
bool isParserOptionSet(const QString &option) const
Delegates to QCommandLineParser::isSet.
data::CGlobalSetup getGlobalSetup() const
Global setup.
QCommandLineParser m_parser
cmd parser
Definition: application.h:568
bool hasUnsavedSettings() const
Unsaved settings.
bool hasWebDataServices() const
Web data services available?
const context::IContextNetwork * getIContextNetwork() const
Direct access to contexts if a CCoreFacade has been initialized.
bool addParserOption(const QCommandLineOption &option)
bool isShuttingDown() const
Is application shutting down?
bool isSet(const QCommandLineOption &option) const
Flag set or explicitly set to true.
std::atomic_bool m_shutdownInProgress
shutdown in progress?
Definition: application.h:581
const QString & getApplicationNameVersionDetailed() const
Version, name beta and dev info.
CWebDataServices * getWebDataServices() const
Get the web data services.
const QString & getApplicationNameAndVersion() const
Application name and version.
void saveSettingsOnShutdown(bool saveSettings)
Save settings on shutdown.
void startUpCompleted(bool success)
Startup has been completed Will be triggered shortly before starting the event loop.
swift::core::db::CInfoDataReader * getDbInfoDataReader() const
DB info data reader.
swift::core::db::CInfoDataReader * getSharedInfoDataReader() const
Shared info data reader.
Global settings for readers, debug flags, etc.
Definition: globalsetup.h:31
swift::misc::network::CUrl getHelpPageUrl() const
Help page URL.
Definition: globalsetup.cpp:44
swift::misc::db::CDbInfoList getInfoObjects() const
Get info list (either shared or from DB)
static WindowMode stringToWindowMode(const QString &s)
String to window mode.
GUI application, a specialized version of swift::core::CApplication for GUI applications.
bool openStandardWidgetStyleSheet()
Opens the standard stylesheet.
static void modalWindowToFront()
Bring any modal dialog to front.
bool isCmdWindowSizeResetSet() const
Window size reset mode set.
QString setExtraWindowTitle(const QString &extraInfo, QWidget *mainWindowWidget=mainApplicationWidget()) const
Set window title.
QString getFontInfo() const
Info about font.
static swift::gui::IMainWindowAccess * mainWindowAccess()
Main window access interface.
void onCoreFacadeStarted()
Called when facade/contexts have been started.
void registerMainApplicationWidget(QWidget *mainWidget)
Register main application window widget if this is known.
void addWindowResetSizeOption()
CMD line arguments (reset size store)
void addWindowStateOption()
CMD line arguments.
void processEventsToRefreshGui() const
Allow the GUI to refresh by processing events, call the event loop.
Qt::WindowState getWindowState() const
Window state.
bool hasMinimumMappingVersion() const
Minimum mapping version check.
void addWindowModeOption()
CMD line arguments.
static QRect currentScreenGeometry()
Current screen resolution.
void triggerNewVersionCheck(int delayedMs)
Trigger new version check.
bool openStandardCrashDumpDirectory()
Opens the standard dumps directory.
static CGuiApplication * instance()
Similar to.
void windowToFront()
Window to front/back.
CEnableForFramelessWindow::WindowMode getWindowMode() const
Window mode (window flags)
void addMenuHelp(QMenu &menu)
Help operations.
void addMenuForStyleSheets(QMenu &menu)
Add menu for style sheets.
bool reloadStyleSheets()
Reload style sheets.
void cmdLineErrorMessage(const QString &text, const QString &informativeText) const
print messages generated during parsing / cmd handling
static void exit(int retcode=0)
Exit application, perform graceful shutdown and exit.
void addMenuFile(QMenu &menu)
File menu.
void addMenuInternals(QMenu &menu)
Internals menu.
bool displayInOverlayWindow(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
direct access to main application window
void checkNewVersion(bool onlyIfNew)
Check for a new version (update)
void splashScreen(const QPixmap &pixmap)
Add a splash screen based on resource, empty means remove splash screen.
bool restoreWindowGeometryAndState(QMainWindow *window=CGuiApplication::mainApplicationWindow())
Restore widget's geometry and state.
void fontChanged()
Font has been changed.
const CStyleSheetUtility & getStyleSheetUtility() const
Style sheet handling.
bool saveWindowGeometryAndState(const QMainWindow *window=CGuiApplication::mainApplicationWindow()) const
Save widget's geometry and state.
QDialog::DialogCode showCloseDialog(QMainWindow *mainWindow, QCloseEvent *closeEvent)
Show close dialog.
void windowToBack()
Window to front/back.
void gracefulShutdown()
Graceful shutdown.
void onStartUpCompleted()
Startup completed.
bool toggleStayOnTop()
Toggle stay on top.
void windowToFrontBackToggle()
Window to front/back.
static void registerMetadata()
Register metadata.
static void setWindowIcon(const QPixmap &icon)
Set icon.
bool resetFont()
Reset the font to default.
void displaySetupLoadFailure(swift::misc::CStatusMessageList msgs)
Display the failures caused by loading the setup file.
void windowMinimizeNormalToggle()
Window minimize/normalize.
void addMenuForSettingsAndCache(QMenu &menu)
Add menu items for settings and cache.
bool updateFont(const QString &fontFamily, const QString &fontSize, const QString &fontStyle, const QString &fontWeight, const QString &fontColor)
Update the fonts.
void showHelp(const QString &subpath={}) const
Show help page (online help)
bool displayInStatusBar(const swift::misc::CStatusMessage &message)
direct access to main application window
void alwaysOnTop(bool onTop)
always on top
static QWidget * mainApplicationWidget()
Main application window widget.
static QMainWindow * mainApplicationWindow()
Main application window.
bool parsingHookIn()
Handle parsing of special GUI cmd arguments.
void uiObjectTreeReady()
Object tree ready (means ui->setupUi() completed)
void openUrl(const swift::misc::network::CUrl &url)
Open a given URL.
bool openStandardLogDirectory()
Opens the standard log directory.
void addMenuWindow(QMenu &menu)
Window operations.
void initMainApplicationWidget(QWidget *mainWidget)
Init the main application window based on information in this application.
static QScreen * currentScreen()
Current screen.
void addWindowFlags(Qt::WindowFlags flags)
Set window flag on main application window.
QString getWidgetStyle() const
Current widget style.
void styleSheetsChanged()
Style sheet changed.
void setMinimumSizeInCharacters(int widthChars, int heightChars)
Set minimum width/height in characters.
void resetWindowGeometryAndState()
Reset the saved values.
static bool stayOnTop(bool onTop, QWidget *widget)
Window flags / stay on top.
Definition: guiutility.cpp:592
static QStringList deleteLaterAllDockWidgetsGetTitles(QWidget *parent, bool floatingOnly)
"deleteLater" all dock widgets
static bool staysOnTop(QWidget *widget)
Window on top?
Definition: guiutility.cpp:552
static void registerMainApplicationWidget(QWidget *mainWidget)
Register main application window widget if this is known.
Definition: guiutility.cpp:87
static QSizeF fontMetricsEstimateSize(int xCharacters, int yCharacters, bool withRatio=false)
Estimate size based on current font.
Definition: guiutility.cpp:756
static void superviseMainWindowMinSizes(qreal wRatio=0.85, qreal hRatio=0.85)
Make sure that the min.sizes to not exceed the screen resolution.
Definition: guiutility.cpp:816
static QString metricsInfo()
Some info about font metrics.
Definition: guiutility.cpp:791
static QWidget * mainApplicationWidget()
Main application window widget.
Definition: guiutility.cpp:92
static QStringList closeAllModalWidgetsGetTitles()
Close all modal widgets and get titles.
static QFont currentFont()
Main window font or default font.
Definition: guiutility.cpp:729
static bool toggleStayOnTop(QWidget *widget)
Toggle window flags / stay on top.
Definition: guiutility.cpp:573
Own splash screen.
Definition: splashscreen.h:22
Reads and provides style sheets.
static const QString & fileNameStandardWidget()
File name for standard widgets.
bool updateFont(const QFont &font)
Update the fonts.
static void setQSysInfoProperties(QWidget *widget, bool withChildWidgets)
Set QSysInfo properties for given widget (which can be used in stylesheet)
bool read()
Read the *.qss files.
static const QString & fileNameAndPathStandardWidget()
Full file path and name for standard widgets.
void styleSheetsChanged()
Sheets have been changed.
QString styles(const QStringList &fileNames) const
Multiple styles concatenated.
static const QString & fileNameFonts()
File name fonts.qss.
Direct acccess to main window`s status bar, info bar and such.
virtual bool displayInOverlayWindow(const swift::misc::CStatusMessage &message, std::chrono::milliseconds timeout=std::chrono::milliseconds(0))
Display in overlay window.
virtual bool displayInStatusBar(const swift::misc::CStatusMessage &message)
Display in status bar.
Setup dialog, if loading the boostrap file fails.
bool isNewVersionAvailable() const
A new version existing?
Application
Enumeration of application roles.
QString toJsonString(QJsonDocument::JsonFormat format=QJsonDocument::Indented) const
Convenience function JSON as string.
Class for emitting a log message.
Definition: logmessage.h:27
Value class for matching log messages based on their categories.
Definition: logpattern.h:49
CLogPattern withSeverity(CStatusMessage::StatusSeverity severity) const
Returns a CLogPattern which will match the same messages as this one, but only with a given severity.
Definition: logpattern.cpp:130
A helper class for subscribing to log messages matching a particular pattern, with the ability to cha...
Definition: loghandler.h:220
void changeSubscription(const CLogPattern &pattern)
Change the pattern which you want to subscribe to.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
bool isEmpty() const
Message empty.
Derived & validationError(const char16_t(&format)[N])
Set the severity to error, providing a format string, and adding the validation category.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
Value object encapsulating a list of property indexes.
size_type size() const
Returns number of elements in the sequence.
Definition: sequence.h:273
bool isEmpty() const
Synonym for empty.
Definition: sequence.h:285
Streamable status message, e.g.
QString getMessage() const
Message.
Status messages, e.g. from Core -> GUI.
QString toHtml(const CPropertyIndexList &indexes=simpleHtmlOutput()) const
Specialized version to convert to HTML.
bool hasErrorMessages() const
Error messages.
Value object encapsulating a list of info objects.
Definition: dbinfolist.h:27
Update info, i.e. artifacts and distributions.
Definition: updateinfo.h:24
Value object encapsulating information of a location, kind of simplified CValueObject compliant versi...
Definition: url.h:27
bool isEmpty() const
Empty.
Definition: url.cpp:54
CUrl withAppendedPath(const QString &path) const
Append path.
Definition: url.cpp:115
SWIFT_GUI_EXPORT swift::gui::CGuiApplication * sGui
Single instance of GUI application object.
size_t qHash(const std::string &key, uint seed)
std::string qHash
Definition: metaclass.h:84
Core data traits (aka cached values) and classes.
Backend services of the swift project, like dealing with the network or the simulators.
Definition: actionbind.cpp:7
High level reusable GUI components.
Definition: aboutdialog.cpp:13
GUI related classes.
void registerMetadata()
Register metadata for GUI.
Free functions in swift::misc.
QString getAllUserMetatypesTypes(const QString &separator)
Get all user metatypes.
QMetaObject::Connection connectOnce(T *sender, F signal, U *receiver, G &&slot, Qt::ConnectionType type=Qt::AutoConnection)
Wrapper around QObject::connect which disconnects after the signal has been emitted once.
Definition: slot.h:27
SWIFT_MISC_EXPORT bool stringCompare(const QString &c1, const QString &c2, Qt::CaseSensitivity cs)
String compare.
QString className(const QObject *object)
Class name as from QMetaObject::className with namespace.
QString applicationName()
Get application name.
Definition: filelogger.cpp:23
void triggered(bool checked)
void aboutQt()
QStyle * setStyle(const QString &style)
QStyle * style()
bool isEmpty() const const
QStringList names() const const
QString valueName() const const
bool isSet(const QCommandLineOption &option) const const
QString applicationFilePath()
void processEvents(QEventLoop::ProcessEventsFlags flags)
QString translate(const char *context, const char *sourceText, const char *disambiguation, int n)
bool openUrl(const QUrl &url)
virtual int exec()
void setModal(bool modal)
QString toNativeSeparators(const QString &pathName)
void ignore()
QString family() const const
int pointSize() const const
void setFamily(const QString &family)
void setPointSize(int pointSize)
void setStretch(int factor)
int averageCharWidth() const const
void lastWindowClosed()
QWindow * modalWindow()
Qt::KeyboardModifiers queryKeyboardModifiers()
void setWindowIcon(const QIcon &icon)
qsizetype count() const const
T & first()
bool restoreState(const QByteArray &state, int version)
QByteArray saveState(int version) const const
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
QAction * addMenu(QMenu *menu)
QAction * addSeparator()
void setIcon(const QIcon &icon)
QPushButton * addButton(QMessageBox::StandardButton button)
QMessageBox::StandardButton critical(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
void setDetailedText(const QString &text)
virtual int exec() override
void setInformativeText(const QString &text)
QMessageBox::StandardButton warning(QWidget *parent, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QList< T > findChildren(QAnyStringView name, Qt::FindChildOptions options) const const
virtual const QMetaObject * metaObject() const const
void setObjectName(QAnyStringView name)
bool isNull() const const
QPixmap scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
QString fileName() const const
void remove(QAnyStringView key)
void setValue(QAnyStringView key, const QVariant &value)
QVariant value(QAnyStringView key) const const
void setHeight(int height)
void setWidth(int width)
qreal height() const const
qreal width() const const
QString arg(Args &&... args) const const
bool isEmpty() const const
qsizetype length() const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString join(QChar separator) const const
SP_TitleBarMaxButton
QStyle * create(const QString &key)
QStringList keys()
CaseInsensitive
QueuedConnection
FindDirectChildrenOnly
typedef KeyboardModifiers
WindowState
typedef WindowFlags
QUrl fromLocalFile(const QString &localFile)
QByteArray toByteArray() const const
void setWindowIconText(const QString &)
void activateWindow()
bool close()
QFontMetrics fontMetrics() const const
void lower()
bool isMaximized() const const
bool isMinimized() const const
void raise()
bool restoreGeometry(const QByteArray &geometry)
QByteArray saveGeometry() const const
void showMinimized()
void showNormal()
void setStyleSheet(const QString &styleSheet)
QWindow * windowHandle() const const
void setWindowIcon(const QIcon &icon)
void setWindowTitle(const QString &)
void raise()
QScreen * screen() const const
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26