6 #include <QAbstractItemModel>
7 #include <QApplication>
10 #include <QGraphicsOpacityEffect>
11 #include <QJsonDocument>
12 #include <QJsonObject>
16 #include <QLayoutItem>
19 #include <QMainWindow>
24 #include <QPropertyAnimation>
25 #include <QRegularExpression>
27 #include <QStringBuilder>
29 #include <QThreadStorage>
53 QWidget *CGuiUtility::s_mainApplicationWidget =
nullptr;
57 const QWidgetList tlw = topLevelApplicationWidgetsWithName();
58 for (QWidget *w : tlw)
62 if (!mw) {
continue; }
70 QWidget *mainApplicationWidgetSearch()
76 const QWidgetList tlw = CGuiUtility::topLevelApplicationWidgetsWithName();
77 for (QWidget *w : tlw)
79 QMainWindow *qmw = qobject_cast<QMainWindow *>(w);
80 if (!qmw) {
continue; }
81 if (!qmw->parentWidget()) {
return qmw; }
87 void CGuiUtility::registerMainApplicationWidget(QWidget *mainWidget)
89 CGuiUtility::s_mainApplicationWidget = mainWidget;
92 QWidget *CGuiUtility::mainApplicationWidget()
94 if (!CGuiUtility::s_mainApplicationWidget)
96 CGuiUtility::s_mainApplicationWidget = Private::mainApplicationWidgetSearch();
98 return CGuiUtility::s_mainApplicationWidget;
101 qreal CGuiUtility::mainApplicationWidgetPixelRatio()
103 const QWidget *mw = CGuiUtility::mainApplicationWidget();
104 if (mw) {
return mw->devicePixelRatio(); }
108 QSize CGuiUtility::desktopSize()
110 const QWidget *mw = CGuiUtility::mainApplicationWidget();
111 if (!mw)
return QGuiApplication::primaryScreen()->size();
113 const QWindow *win = mw->windowHandle();
114 if (!win)
return QGuiApplication::primaryScreen()->size();
122 QSize windowsGetDesktopResolution()
140 const HWND hDesktop = GetDesktopWindow();
141 HMONITOR monitor = MonitorFromWindow(hDesktop, MONITOR_DEFAULTTONEAREST);
143 info.cbSize =
sizeof(MONITORINFO);
144 GetMonitorInfo(monitor, &info);
151 const int monitor_width = info.rcMonitor.right - info.rcMonitor.left;
152 const int monitor_height = info.rcMonitor.bottom - info.rcMonitor.top;
153 return QSize(monitor_height, monitor_width);
165 QSize CGuiUtility::physicalScreenSizeOs()
168 return Private::windowsGetDesktopResolution();
169 #elif defined(Q_OS_MAC)
171 #elif defined(Q_OS_LINUX)
178 bool CGuiUtility::isMainWindowFrameless()
184 QString CGuiUtility::screenInformation(
const QString &separator)
186 const QSize ps = physicalScreenSizeOs();
187 QString i = u
"Number of screens: " % QString::number(QGuiApplication::screens().size()) % separator %
188 u
"Primary screen: " % QGuiApplication::primaryScreen()->name() % separator %
189 u
"QT_AUTO_SCREEN_SCALE_FACTOR: " % qgetenv(
"QT_AUTO_SCREEN_SCALE_FACTOR") % separator %
190 u
"QT_SCALE_FACTOR: " % qgetenv(
"QT_SCALE_FACTOR") % separator % u
"QT_ENABLE_HIGHDPI_SCALING: " %
191 qgetenv(
"QT_ENABLE_HIGHDPI_SCALING") % separator % u
"QT_SCALE_FACTOR_ROUNDING_POLICY: " %
192 qgetenv(
"QT_SCALE_FACTOR_ROUNDING_POLICY") % separator % u
"QT_SCREEN_SCALE_FACTORS: " %
193 qgetenv(
"QT_SCREEN_SCALE_FACTORS") % separator % u
"OS screen res." % QString::number(ps.width()) %
194 u
"/" % QString::number(ps.height()) % separator;
196 for (
const QScreen *screen : QGuiApplication::screens())
198 i += separator % u
"Information for screen: " % screen->name() % separator % u
"Available geometry: " %
199 rectAsString(screen->availableGeometry()) % separator % u
"Available size: " %
200 sizeAsString(screen->availableSize()) % separator % u
"Available virtual geometry: " %
201 rectAsString(screen->availableVirtualGeometry()) % separator % u
"Available virtual size: " %
202 sizeAsString(screen->availableVirtualSize()) % separator % u
"Device ratio: " %
203 QString::number(screen->devicePixelRatio()) % separator % u
"Depth: " %
204 QString::number(screen->depth()) % u
"bits" % separator % u
"Geometry: " %
205 rectAsString(screen->geometry()) % separator % u
"Logical DPI: " %
206 QString::number(screen->logicalDotsPerInch()) % separator % u
"Logical DPI X: " %
207 QString::number(screen->logicalDotsPerInchX()) % separator % u
"Logical DPI Y: " %
208 QString::number(screen->logicalDotsPerInchY()) % separator % u
"Orientation: " %
209 orientationAsString(screen->orientation()) % separator % u
"Physical DPI: " %
210 QString::number(screen->physicalDotsPerInch()) % separator % u
"Physical DPI X: " %
211 QString::number(screen->physicalDotsPerInchX()) % separator % u
"Physical DPI Y: " %
212 QString::number(screen->physicalDotsPerInchY()) % separator % u
"Physical size: " %
213 sizeAsString(screen->physicalSize()) % u
"mm" % separator % u
"Primary orientation: " %
214 orientationAsString(screen->primaryOrientation()) % separator % u
"Refresh rate: " %
215 QString::number(screen->refreshRate()) % u
"Hz" % u
"Size: " % sizeAsString(screen->size()) % separator %
216 u
"Virtual geometry: " % rectAsString(screen->virtualGeometry()) % separator % u
"Virtual size: " %
217 sizeAsString(screen->virtualSize());
222 const QString &CGuiUtility::orientationAsString(Qt::ScreenOrientation orientation)
224 static const QString pr(
"Primary");
225 static const QString la(
"Landscape");
226 static const QString po(
"Portrait");
227 static const QString il(
"Inverted landscape");
228 static const QString ip(
"Inverted portrait");
232 case Qt::PrimaryOrientation:
return pr;
233 case Qt::LandscapeOrientation:
return la;
234 case Qt::PortraitOrientation:
return po;
235 case Qt::InvertedLandscapeOrientation:
return il;
236 case Qt::InvertedPortraitOrientation:
return ip;
240 static const QString unknown(
"Unknown");
244 QString CGuiUtility::rectAsString(
const QRect &rect)
246 return QStringLiteral(
"x: %1 y: %2 w: %3 h: %4")
253 QString CGuiUtility::rectAsString(
const QRectF &rect)
255 return QStringLiteral(
"x: %1 y: %2 w: %3 h: %4")
262 QString CGuiUtility::sizeAsString(
const QSize &size)
264 return QStringLiteral(
"w: %1 h: %2").arg(size.width()).arg(size.height());
267 QString CGuiUtility::sizeAsString(
const QSizeF &size)
269 return QStringLiteral(
"w: %1 h: %2").arg(size.width()).arg(size.height());
272 static QThreadStorage<QRegularExpression> tsRegex;
274 bool CGuiUtility::lenientTitleComparison(
const QString &title,
const QString &comparison)
276 if (title == comparison) {
return true; }
278 QString t(title.trimmed().toLower().simplified());
279 QString c(comparison.trimmed().toLower().simplified());
283 SWIFT_VERIFY_X(!c.isEmpty(), Q_FUNC_INFO,
"missing comparison value");
284 if (t.isEmpty() || c.isEmpty()) {
return false; }
287 if (t == c) {
return true; }
290 if (!tsRegex.hasLocalData()) { tsRegex.setLocalData(QRegularExpression(
"[^a-z0-9\\s]")); }
291 const QRegularExpression ®exp = tsRegex.localData();
292 t = t.remove(regexp);
293 c = c.remove(regexp);
297 bool CGuiUtility::setComboBoxValueByStartingString(QComboBox *box,
const QString &candidate,
298 const QString &unspecified)
300 if (!box) {
return false; }
301 if (!candidate.isEmpty())
303 for (
int i = 0; i < box->count(); i++)
305 const QString t(box->itemText(i));
306 if (t.startsWith(candidate, Qt::CaseInsensitive))
308 box->setCurrentIndex(i);
315 if (unspecified.isEmpty()) {
return false; }
316 for (
int i = 0; i < box->count(); i++)
318 const QString t(box->itemText(i));
319 if (t.startsWith(unspecified, Qt::CaseInsensitive))
321 box->setCurrentIndex(i);
328 bool CGuiUtility::setComboBoxValueByContainingString(QComboBox *box,
const QString &candidate,
329 const QString &unspecified)
331 if (!box) {
return false; }
332 if (!candidate.isEmpty())
334 const int ci = box->currentIndex();
335 for (
int i = 0; i < box->count(); i++)
337 const QString t(box->itemText(i));
338 if (t.contains(candidate, Qt::CaseInsensitive))
340 if (ci == i) {
return true; }
341 box->setCurrentIndex(i);
348 if (unspecified.isEmpty()) {
return false; }
349 const int ci = box->currentIndex();
350 for (
int i = 0; i < box->count(); i++)
352 const QString t(box->itemText(i));
353 if (t.contains(unspecified, Qt::CaseInsensitive))
355 if (ci == i) {
return true; }
356 box->setCurrentIndex(i);
363 bool CGuiUtility::hasSwiftVariantMimeType(
const QMimeData *mime)
365 return mime && mime->hasFormat(swiftJsonDragAndDropMimeType());
368 CVariant CGuiUtility::fromSwiftDragAndDropData(
const QMimeData *mime)
370 if (!hasSwiftVariantMimeType(mime)) {
return CVariant(); }
371 return CGuiUtility::fromSwiftDragAndDropData(mime->data(swiftJsonDragAndDropMimeType()));
374 CVariant CGuiUtility::fromSwiftDragAndDropData(
const QByteArray &utf8Data)
376 if (utf8Data.isEmpty()) {
return CVariant(); }
377 const QJsonDocument jsonDoc(QJsonDocument::fromJson(utf8Data));
378 const QJsonObject jsonObj(jsonDoc.object());
379 const QString typeName(jsonObj.value(
"type").toString());
380 const int typeId = QMetaType::type(qPrintable(typeName));
383 if (typeName.isEmpty() || typeId == QMetaType::UnknownType) {
return CVariant(); }
391 int CGuiUtility::metaTypeIdFromSwiftDragAndDropData(
const QMimeData *mime)
393 constexpr
int Unknown =
static_cast<int>(QMetaType::UnknownType);
395 if (!hasSwiftVariantMimeType(mime)) {
return Unknown; }
396 static const QJsonObject jsonObj(QJsonDocument::fromJson(mime->data(swiftJsonDragAndDropMimeType())).
object());
397 Q_ASSERT_X(!jsonObj.isEmpty(), Q_FUNC_INFO,
"Empty JSON object");
398 const QString typeName(jsonObj.value(
"type").toString());
399 if (typeName.isEmpty()) {
return Unknown; }
400 const int typeId = QMetaType::type(qPrintable(typeName));
404 const QString &CGuiUtility::swiftJsonDragAndDropMimeType()
406 static const QString m(
"text/json/swift");
410 QFileInfo CGuiUtility::representedMimeFile(
const QMimeData *mime)
412 if (!mime->hasText()) {
return QFileInfo(); }
413 const QString candidate = mime->text();
414 if (candidate.isEmpty()) {
return QFileInfo(); }
415 if (!candidate.contains(
"://")) {
return QFileInfo(candidate); }
417 const QString localFile = url.toLocalFile();
418 return QFileInfo(localFile);
421 bool CGuiUtility::isMimeRepresentingReadableFile(
const QMimeData *mime)
423 const QFileInfo fi = CGuiUtility::representedMimeFile(mime);
424 return fi.isReadable();
427 bool CGuiUtility::isMimeRepresentingReadableJsonFile(
const QMimeData *mime)
429 const QFileInfo fi = CGuiUtility::representedMimeFile(mime);
430 if (!fi.isReadable()) {
return false; }
431 const QString fn = fi.fileName();
432 return fn.endsWith(
"json", Qt::CaseInsensitive);
437 return nextOverlayMessageWidget<COverlayMessagesFrame>(widget, maxLevels);
442 return nextOverlayMessageWidget<COverlayMessagesTabWidget>(widget, maxLevels);
447 return nextOverlayMessageWidget<COverlayMessagesWizardPage>(widget, maxLevels);
450 void CGuiUtility::checkBoxReadOnly(QCheckBox *checkBox,
bool readOnly)
452 static const QCheckBox defaultBox;
454 if (!checkBox) {
return; }
456 static const QString background(
457 "background: rgb(40,40,40)");
460 checkBox->setAttribute(Qt::WA_TransparentForMouseEvents);
461 checkBox->setFocusPolicy(Qt::NoFocus);
465 checkBox->setStyleSheet(background);
469 checkBox->setAttribute(Qt::WA_TransparentForMouseEvents,
470 defaultBox.testAttribute(Qt::WA_TransparentForMouseEvents));
471 checkBox->setFocusPolicy(defaultBox.focusPolicy());
472 checkBox->setStyleSheet(
"");
476 void CGuiUtility::checkBoxesReadOnly(QWidget *parent,
bool readOnly)
478 if (!parent) {
return; }
479 QList<QCheckBox *> allCheckBoxes = parent->findChildren<QCheckBox *>();
480 for (QCheckBox *cb : allCheckBoxes) { CGuiUtility::checkBoxReadOnly(cb, readOnly); }
483 void CGuiUtility::tempUnhidePassword(QLineEdit *lineEdit,
int unhideMs)
485 if (!lineEdit) {
return; }
486 if (lineEdit->text().isEmpty()) {
return; }
487 if (lineEdit->echoMode() != QLineEdit::Password && lineEdit->echoMode() != QLineEdit::PasswordEchoOnEdit)
491 const QLineEdit::EchoMode mode = lineEdit->echoMode();
492 lineEdit->setEchoMode(QLineEdit::Normal);
493 QPointer<QLineEdit> qpLineEdit(lineEdit);
495 if (qpLineEdit) { qpLineEdit->setEchoMode(mode); }
499 QWidgetList CGuiUtility::topLevelApplicationWidgetsWithName()
501 QWidgetList tlw = QApplication::topLevelWidgets();
503 for (QWidget *w : tlw)
505 if (w->objectName().isEmpty()) {
continue; }
511 QPoint CGuiUtility::mainWidgetGlobalPosition()
513 QWidget *mw = CGuiUtility::mainApplicationWidget();
514 if (mw) {
return mw->pos(); }
518 if (!mfw || !mfw->
getWidget()) {
return QPoint(); }
522 QString CGuiUtility::replaceTabCountValue(
const QString &oldName,
int count)
524 const QString v = QString(
" (").append(QString::number(count)).append(
")");
525 if (oldName.isEmpty()) {
return v; }
526 int index = oldName.lastIndexOf(
'(');
527 if (index == 0) {
return v; }
528 if (index < 0) {
return QString(oldName).trimmed().append(v); }
529 return QString(oldName.left(index)).trimmed().append(v);
532 void CGuiUtility::deleteLayout(QLayout *layout,
bool deleteWidgets)
535 if (!layout) {
return; }
536 QLayoutItem *item {
nullptr };
537 while ((item = layout->takeAt(0)))
539 if (QLayout *sublayout = item->layout(); sublayout) { deleteLayout(sublayout, deleteWidgets); }
540 else if (QWidget *widget = item->widget(); widget)
543 if (deleteWidgets) {
delete widget; }
545 else {
delete item; }
552 bool CGuiUtility::staysOnTop(QWidget *widget)
554 if (!widget) {
return false; }
555 const Qt::WindowFlags flags = widget->windowFlags();
556 return Qt::WindowStaysOnTopHint & flags;
559 QTabWidget *CGuiUtility::parentTabWidget(QWidget *widget,
int maxLevels)
563 widget = widget->parentWidget();
564 if (!widget) {
return nullptr; }
565 QTabWidget *tw = qobject_cast<QTabWidget *>(widget);
566 if (tw) {
return tw; }
569 while (level < maxLevels);
573 bool CGuiUtility::toggleStayOnTop(QWidget *widget)
575 if (!widget) {
return false; }
576 Qt::WindowFlags flags = widget->windowFlags();
577 if (Qt::WindowStaysOnTopHint & flags)
579 flags &= ~Qt::WindowStaysOnTopHint;
584 flags &= ~Qt::WindowStaysOnBottomHint;
585 flags |= Qt::WindowStaysOnTopHint;
587 widget->setWindowFlags(flags);
589 return Qt::WindowStaysOnTopHint & flags;
592 bool CGuiUtility::stayOnTop(
bool onTop, QWidget *widget)
594 if (!widget) {
return false; }
595 Qt::WindowFlags flags = widget->windowFlags();
598 flags &= ~Qt::WindowStaysOnBottomHint;
599 flags |= Qt::WindowStaysOnTopHint;
603 flags &= ~Qt::WindowStaysOnTopHint;
606 widget->setWindowFlags(flags);
611 QString CGuiUtility::marginsToString(
const QMargins &margins)
613 return QStringLiteral(
"%1:%2:%3:%4")
616 .arg(margins.right())
617 .arg(margins.bottom());
620 QMargins CGuiUtility::stringToMargins(
const QString &str)
622 const QStringList parts = str.split(
":");
623 Q_ASSERT_X(parts.size() == 4, Q_FUNC_INFO,
"malformed");
625 const int l = parts.at(0).toInt(&ok);
626 Q_ASSERT_X(ok, Q_FUNC_INFO,
"malformed number");
627 const int t = parts.at(1).toInt(&ok);
628 Q_ASSERT_X(ok, Q_FUNC_INFO,
"malformed number");
629 const int r = parts.at(2).toInt(&ok);
630 Q_ASSERT_X(ok, Q_FUNC_INFO,
"malformed number");
631 const int b = parts.at(3).toInt(&ok);
632 Q_ASSERT_X(ok, Q_FUNC_INFO,
"malformed number");
634 return QMargins(l, t, r, b);
637 QList<int> CGuiUtility::indexToUniqueRows(
const QModelIndexList &indexes)
640 for (
const QModelIndex &i : indexes)
642 const int r = i.row();
643 if (rows.contains(r)) {
continue; }
649 int CGuiUtility::clearModel(QAbstractItemModel *model)
651 if (!model) {
return 0; }
652 const int count = model->rowCount();
653 if (count < 1) {
return 0; }
654 model->removeRows(0, count);
658 bool CGuiUtility::isTopLevelWidget(QWidget *widget)
660 if (!widget) {
return false; }
661 return QApplication::topLevelWidgets().contains(widget);
664 bool CGuiUtility::isTopLevelWindow(QWidget *widget)
666 if (!widget) {
return false; }
667 if (!widget->isWindow()) {
return false; }
668 return QApplication::topLevelWidgets().contains(widget);
671 bool CGuiUtility::isQMainWindow(
const QWidget *widget)
673 if (!widget) {
return false; }
674 const QMainWindow *mw = qobject_cast<const QMainWindow *>(widget);
678 bool CGuiUtility::isDialog(
const QWidget *widget)
680 if (!widget) {
return false; }
681 const QDialog *mw = qobject_cast<const QDialog *>(widget);
685 void CGuiUtility::disableMinMaxCloseButtons(QWidget *window)
687 if (!window->windowFlags().testFlag(Qt::CustomizeWindowHint))
689 window->setWindowFlag(Qt::CustomizeWindowHint);
690 window->setWindowFlag(Qt::WindowTitleHint);
692 window->setWindowFlag(Qt::WindowMinMaxButtonsHint,
false);
693 window->setWindowFlag(Qt::WindowCloseButtonHint,
false);
696 QGraphicsOpacityEffect *CGuiUtility::fadeInWidget(
int durationMs, QWidget *widget,
double startValue,
701 QGraphicsOpacityEffect *effect =
new QGraphicsOpacityEffect(widget);
702 widget->setGraphicsEffect(effect);
703 QPropertyAnimation *a =
new QPropertyAnimation(effect,
"opacity");
704 a->setDuration(durationMs);
705 a->setStartValue(startValue);
706 a->setEndValue(endValue);
707 a->setEasingCurve(QEasingCurve::InBack);
708 a->start(QPropertyAnimation::DeleteWhenStopped);
712 QGraphicsOpacityEffect *CGuiUtility::fadeOutWidget(
int durationMs, QWidget *widget,
double startValue,
716 QGraphicsOpacityEffect *effect =
new QGraphicsOpacityEffect(widget);
717 widget->setGraphicsEffect(effect);
718 QPropertyAnimation *a =
new QPropertyAnimation(effect,
"opacity");
719 a->setDuration(durationMs);
720 a->setStartValue(startValue);
721 a->setEndValue(endValue);
722 a->setEasingCurve(QEasingCurve::OutBack);
723 a->start(QPropertyAnimation::DeleteWhenStopped);
727 QFontMetrics CGuiUtility::currentFontMetrics()
729 const QWidget *w = CGuiUtility::mainApplicationWidget();
730 if (w) {
return w->fontMetrics(); }
731 return QApplication::fontMetrics();
734 QFontMetricsF CGuiUtility::currentFontMetricsF() {
return QFontMetricsF(CGuiUtility::currentFontMetrics()); }
736 QFont CGuiUtility::currentFont()
738 const QWidget *w = CGuiUtility::mainApplicationWidget();
739 if (w) {
return w->font(); }
740 return QApplication::font();
743 QSizeF CGuiUtility::fontMetrics80Chars(
bool withRatio)
746 static const QString s(
"01234567890123456789012345678901234567890123456789012345678901234567890123456789");
747 const QFontMetricsF fm = CGuiUtility::currentFontMetricsF();
748 const qreal scale = withRatio ? CGuiUtility::mainApplicationWidgetPixelRatio() : 1.0;
749 const QSizeF size = fm.size(Qt::TextSingleLine, s);
753 QSizeF CGuiUtility::fontMetricsLazyDog43Chars(
bool withRatio)
756 static const QString s(
"The quick brown fox jumps over the lazy dog");
757 const QFontMetricsF fm = CGuiUtility::currentFontMetrics();
758 const qreal scale = withRatio ? CGuiUtility::mainApplicationWidgetPixelRatio() : 1.0;
759 const QSizeF size = fm.size(Qt::TextSingleLine, s);
763 QSizeF CGuiUtility::fontMetricsEstimateSize(
int xCharacters,
int yCharacters,
bool withRatio)
768 const QSizeF s1 = CGuiUtility::fontMetrics80Chars(withRatio);
769 const QSizeF s2 = CGuiUtility::fontMetricsLazyDog43Chars(withRatio);
770 const QSizeF s = s1 + s2;
771 const qreal w = s.width() * xCharacters / 123;
772 const qreal h = s.height() * yCharacters / 2;
776 void CGuiUtility::centerWidget(QWidget *widget)
778 const QPoint point(widget->width() / 2.0, 0);
779 const QScreen *pScreen = QGuiApplication::screenAt(widget->mapToGlobal(point));
780 const QRect screenGeometry = pScreen->availableGeometry();
781 const int x = (screenGeometry.width() - widget->width()) / 2;
782 const int y = (screenGeometry.height() - widget->height()) / 2;
786 void CGuiUtility::centerWidget(QWidget *widget, QWidget *host)
788 if (!host) { host = widget->parentWidget(); }
792 const QRect hostRect = host->geometry();
793 widget->move(hostRect.center() - widget->rect().center());
795 else { CGuiUtility::centerWidget(widget); }
798 QString CGuiUtility::metricsInfo()
800 static const QString s(
"%1 %2 %3 | 80 chars: w%4 h%5 | 43 chars: w%6 h%7");
801 const QSizeF s80 = CGuiUtility::fontMetrics80Chars();
802 const QSizeF s43 = CGuiUtility::fontMetricsLazyDog43Chars();
805 QString desktop(
"-");
807 const QWidget *mainWidget = CGuiUtility::mainApplicationWidget();
810 const QSize sd = QGuiApplication::primaryScreen()->geometry().size();
811 desktop = QStringLiteral(
"Desktop w%1 w%2").arg(sd.width()).arg(sd.height());
812 ratio = QStringLiteral(
"ratio: %1").arg(mainWidget->devicePixelRatioF());
814 return s.arg(desktop)
815 .arg(CGuiUtility::isUsingHighDpiScreenSupport() ?
"hi DPI" :
"-")
823 bool CGuiUtility::isUsingHighDpiScreenSupport()
825 const QByteArray v = qgetenv(
"QT_AUTO_SCREEN_SCALE_FACTOR");
831 void CGuiUtility::forceStyleSheetUpdate(QWidget *widget)
833 if (!widget) {
return; }
834 widget->setStyleSheet(widget->styleSheet());
837 void CGuiUtility::superviseMainWindowMinSizes(qreal wRatio, qreal hRatio)
839 QWidget *w = CGuiUtility::mainApplicationWidget();
841 const QSize s = CGuiUtility::desktopSize();
842 const int minW = qRound(wRatio * s.width());
843 const int minH = qRound(hRatio * s.height());
844 w->setMinimumWidth(qMin(minW, w->minimumWidth()));
845 w->setMinimumHeight(qMin(minH, w->minimumHeight()));
848 QString CGuiUtility::asSimpleHtmlImageWidth(
const CIcon &icon,
int width)
853 if (width < 0) {
return QStringLiteral(
"<img src=\"%1\">").arg(p); }
854 return QStringLiteral(
"<img src=\"%1\" width=%2>").arg(p, QString::number(width));
857 QString CGuiUtility::asSimpleHtmlImageHeight(
const CIcon &icon,
int height)
859 if (height < 0) {
return CGuiUtility::asSimpleHtmlImageWidth(icon); }
863 return QStringLiteral(
"<img src=\"%1\" height=%2>").arg(p, QString::number(height));
866 QDialog *CGuiUtility::findParentDialog(QWidget *widget)
868 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
869 while (widget->parent())
871 widget = widget->parentWidget();
872 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
877 QDialog *CGuiUtility::findParentDialog(QWidget *widget,
int maxLevel)
879 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
881 while (widget->parent())
884 if (level > maxLevel) {
return nullptr; }
885 widget = widget->parentWidget();
886 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
891 void CGuiUtility::setElidedText(QLabel *label,
const QString &text, Qt::TextElideMode mode)
893 if (!label) {
return; }
895 label->setToolTip(text);
896 if (mode == Qt::ElideNone)
898 label->setText(text);
902 const QFontMetrics metrics(label->font());
903 const int width = qMax(label->width() - 2, 0);
904 const QString clippedText = metrics.elidedText(text, mode, width);
905 label->setText(clippedText);
908 void CGuiUtility::setElidedText(QLabel *label,
const QString &shortText,
const QString &longText,
909 Qt::TextElideMode mode)
911 if (!label) {
return; }
912 if (shortText.isEmpty())
914 CGuiUtility::setElidedText(label, longText, mode);
917 if (longText.isEmpty())
919 CGuiUtility::setElidedText(label, shortText, mode);
923 label->setToolTip(longText);
924 const QFontMetrics metrics(label->font());
925 const int width = qMax(label->width() - 2, 0);
926 const int wl = metrics.horizontalAdvance(longText);
929 label->setText(longText);
932 if (qRound(wl * 0.85) > wl)
934 const QString clippedText = metrics.elidedText(longText, mode, width);
935 label->setText(clippedText);
938 const QString clippedText = metrics.elidedText(shortText, mode, width);
939 label->setText(clippedText);
942 void CGuiUtility::setWizardButtonWidths(QWizard *wizard)
944 if (!wizard) {
return; }
946 const int minW = qMax(qRound(CGuiUtility::fontMetricsLazyDog43Chars(
true).width() * 6.0 / 43.0), 80);
947 if (wizard->button(QWizard::BackButton)) { wizard->button(QWizard::BackButton)->setMinimumWidth(minW); }
948 if (wizard->button(QWizard::NextButton)) { wizard->button(QWizard::NextButton)->setMinimumWidth(minW); }
949 if (wizard->button(QWizard::CancelButton)) { wizard->button(QWizard::CancelButton)->setMinimumWidth(minW); }
950 if (wizard->button(QWizard::FinishButton)) { wizard->button(QWizard::FinishButton)->setMinimumWidth(minW); }
951 if (wizard->button(QWizard::CustomButton1)) { wizard->button(QWizard::CustomButton1)->setMinimumWidth(minW); }
952 if (wizard->button(QWizard::CustomButton2)) { wizard->button(QWizard::CustomButton2)->setMinimumWidth(minW); }
953 if (wizard->button(QWizard::CustomButton3)) { wizard->button(QWizard::CustomButton3)->setMinimumWidth(minW); }
956 QWidgetList CGuiUtility::getAllModallWidgets()
958 const QWidgetList widgets = QApplication::topLevelWidgets();
959 QWidgetList openWidgets;
960 for (QWidget *w : widgets)
962 if (w->isModal()) { openWidgets.push_back(w); }
967 QStringList CGuiUtility::getAllWidgetTitles(
const QWidgetList &widgets)
970 for (
const QWidget *w : widgets)
972 if (!w) {
continue; }
973 if (!w->windowTitle().isEmpty()) { titles.push_back(w->windowTitle()); }
974 else { titles.push_back(QStringLiteral(
"name: ") % w->objectName()); }
979 QStringList CGuiUtility::getAllWidgetNames(
const QWidgetList &widgets)
982 for (
const QWidget *w : widgets)
984 if (!w) {
continue; }
985 titles.push_back(QStringLiteral(
"name: ") % w->objectName());
990 QList<QDockWidget *> CGuiUtility::getAllDockWidgets(QWidget *parent,
bool floatingOnly)
992 QList<QDockWidget *> docks;
995 const auto children = parent->findChildren<QDockWidget *>();
996 for (QDockWidget *w : children)
998 if (!w) {
continue; }
999 if (!floatingOnly || w->isFloating()) { docks.push_back(w); }
1005 QList<QDockWidget *> CGuiUtility::getAllDockWidgets(QWindow *parent,
bool floatingOnly)
1007 QList<QDockWidget *> docks;
1010 const auto children = parent->findChildren<QDockWidget *>();
1011 for (QDockWidget *w : children)
1013 if (!w) {
continue; }
1014 if (!floatingOnly || w->isFloating()) { docks.push_back(w); }
1020 QWidgetList CGuiUtility::closeAllModalWidgets()
1022 QWidgetList modals = getAllModallWidgets();
1023 for (QWidget *w : modals)
1025 if (!w) {
continue; }
1031 QStringList CGuiUtility::closeAllModalWidgetsGetTitles()
1033 const QWidgetList modals = getAllModallWidgets();
1035 for (QWidget *w : modals)
1037 if (!w) {
continue; }
1038 titles << w->windowTitle();
1044 QList<QDockWidget *> CGuiUtility::closeAllDockWidgets(QWidget *parent,
bool floatingOnly)
1046 QList<QDockWidget *> dws = getAllDockWidgets(parent, floatingOnly);
1047 for (QWidget *w : dws)
1049 if (!w) {
continue; }
1055 QList<QDockWidget *> CGuiUtility::closeAllDockWidgets(QWindow *parent,
bool floatingOnly)
1057 QList<QDockWidget *> dws = getAllDockWidgets(parent, floatingOnly);
1058 for (QWidget *w : dws)
1060 if (!w) {
continue; }
1066 QStringList CGuiUtility::closeAllDockWidgetsGetTitles(QWidget *parent,
bool floatingOnly)
1068 const QList<QDockWidget *> dws = getAllDockWidgets(parent, floatingOnly);
1070 for (QWidget *w : dws)
1072 if (!w) {
continue; }
1073 titles << w->windowTitle();
1079 QStringList CGuiUtility::closeAllDockWidgetsGetTitles(QWindow *parent,
bool floatingOnly)
1081 const QList<QDockWidget *> dws = getAllDockWidgets(parent, floatingOnly);
1083 for (QWidget *w : dws)
1085 if (!w) {
continue; }
1086 titles << w->windowTitle();
1092 QStringList CGuiUtility::deleteLaterAllDockWidgetsGetTitles(QWidget *parent,
bool floatingOnly)
1094 const QList<QDockWidget *> dws = getAllDockWidgets(parent, floatingOnly);
1096 for (QWidget *w : dws)
1098 if (!w) {
continue; }
1099 titles << w->windowTitle();
Main window which can be frameless.
bool isMainApplicationWindow() const
Is main application, explicitly set.
QWidget * getWidget() const
Corresponding QMainWindow.
bool isFrameless() const
Frameless?
Using this class provides a QFrame with the overlay functionality already integrated.
Using this class provides a QWizardPage with the overlay functionality already integrated.
Value object for icons. An icon is stored in the global icon repository and identified by its index....
bool hasFileResourcePath() const
Resource path available?
const QString & getFileResourcePath() const
Resource path if any.
Streamable status message, e.g.
bool isFailure() const
Operation considered unsuccessful.
Wrapper around QVariant which provides transparent access to CValueObject methods of the contained ob...
CStatusMessage convertFromJsonNoThrow(const QJsonObject &json, const CLogCategoryList &categories, const QString &prefix)
Call convertFromJson, catch any CJsonException that is thrown and return it as CStatusMessage.
Free functions in swift::misc.
SWIFT_MISC_EXPORT bool stringToBool(const QString &boolString)
Convert string to bool.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.