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();
62 if (!mw) {
continue; }
70 QWidget *mainApplicationWidgetSearch()
76 const QWidgetList tlw = CGuiUtility::topLevelApplicationWidgetsWithName();
80 if (!qmw) {
continue; }
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();
110 const QWidget *mw = CGuiUtility::mainApplicationWidget();
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()
186 const QSize ps = physicalScreenSizeOs();
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()) %
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: " %
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());
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");
240 static const QString unknown(
"Unknown");
246 return QStringLiteral(
"x: %1 y: %2 w: %3 h: %4")
255 return QStringLiteral(
"x: %1 y: %2 w: %3 h: %4")
274 bool CGuiUtility::lenientTitleComparison(
const QString &title,
const QString &comparison)
276 if (title == comparison) {
return true; }
287 if (t == c) {
return true; }
290 if (!tsRegex.hasLocalData()) { tsRegex.setLocalData(
QRegularExpression(
"[^a-z0-9\\s]")); }
297 bool CGuiUtility::setComboBoxValueByStartingString(
QComboBox *box,
const QString &candidate,
300 if (!box) {
return false; }
303 for (
int i = 0; i < box->
count(); i++)
315 if (unspecified.
isEmpty()) {
return false; }
316 for (
int i = 0; i < box->
count(); i++)
328 bool CGuiUtility::setComboBoxValueByContainingString(
QComboBox *box,
const QString &candidate,
331 if (!box) {
return false; }
335 for (
int i = 0; i < box->
count(); i++)
340 if (ci == i) {
return true; }
348 if (unspecified.
isEmpty()) {
return false; }
350 for (
int i = 0; i < box->
count(); i++)
355 if (ci == i) {
return true; }
363 bool CGuiUtility::hasSwiftVariantMimeType(
const QMimeData *mime)
365 return mime && mime->
hasFormat(swiftJsonDragAndDropMimeType());
370 if (!hasSwiftVariantMimeType(mime)) {
return CVariant(); }
371 return CGuiUtility::fromSwiftDragAndDropData(mime->
data(swiftJsonDragAndDropMimeType()));
391 int CGuiUtility::metaTypeIdFromSwiftDragAndDropData(
const QMimeData *mime)
395 if (!hasSwiftVariantMimeType(mime)) {
return Unknown; }
397 Q_ASSERT_X(!jsonObj.
isEmpty(), Q_FUNC_INFO,
"Empty JSON object");
399 if (typeName.
isEmpty()) {
return Unknown; }
404 const QString &CGuiUtility::swiftJsonDragAndDropMimeType()
406 static const QString m(
"text/json/swift");
421 bool CGuiUtility::isMimeRepresentingReadableFile(
const QMimeData *mime)
423 const QFileInfo fi = CGuiUtility::representedMimeFile(mime);
427 bool CGuiUtility::isMimeRepresentingReadableJsonFile(
const QMimeData *mime)
429 const QFileInfo fi = CGuiUtility::representedMimeFile(mime);
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)
454 if (!checkBox) {
return; }
456 static const QString background(
457 "background: rgb(40,40,40)");
476 void CGuiUtility::checkBoxesReadOnly(
QWidget *parent,
bool readOnly)
478 if (!parent) {
return; }
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; }
495 if (qpLineEdit) { qpLineEdit->setEchoMode(mode); }
499 QWidgetList CGuiUtility::topLevelApplicationWidgetsWithName()
505 if (w->objectName().isEmpty()) {
continue; }
511 QPoint CGuiUtility::mainWidgetGlobalPosition()
513 QWidget *mw = CGuiUtility::mainApplicationWidget();
514 if (mw) {
return mw->
pos(); }
525 if (oldName.
isEmpty()) {
return v; }
527 if (index == 0) {
return v; }
532 void CGuiUtility::deleteLayout(
QLayout *layout,
bool deleteWidgets)
535 if (!layout) {
return; }
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; }
554 if (!widget) {
return false; }
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; }
579 flags &= ~
Qt::WindowStaysOnTopHint;
584 flags &= ~
Qt::WindowStaysOnBottomHint;
592 bool CGuiUtility::stayOnTop(
bool onTop,
QWidget *widget)
594 if (!widget) {
return false; }
598 flags &= ~
Qt::WindowStaysOnBottomHint;
603 flags &= ~
Qt::WindowStaysOnTopHint;
613 return QStringLiteral(
"%1:%2:%3:%4")
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");
637 QList<int> CGuiUtility::indexToUniqueRows(
const QModelIndexList &indexes)
642 const int r = i.row();
651 if (!model) {
return 0; }
652 const int count = model->
rowCount();
653 if (count < 1) {
return 0; }
658 bool CGuiUtility::isTopLevelWidget(
QWidget *widget)
660 if (!widget) {
return false; }
664 bool CGuiUtility::isTopLevelWindow(
QWidget *widget)
666 if (!widget) {
return false; }
667 if (!widget->
isWindow()) {
return false; }
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)
731 const QWidget *w = CGuiUtility::mainApplicationWidget();
732 if (w) {
return w->
font(); }
736 QSizeF CGuiUtility::fontMetrics80Chars(
bool withRatio)
739 static const QString s(
"01234567890123456789012345678901234567890123456789012345678901234567890123456789");
741 const qreal scale = withRatio ? CGuiUtility::mainApplicationWidgetPixelRatio() : 1.0;
746 QSizeF CGuiUtility::fontMetricsLazyDog43Chars(
bool withRatio)
749 static const QString s(
"The quick brown fox jumps over the lazy dog");
751 const qreal scale = withRatio ? CGuiUtility::mainApplicationWidgetPixelRatio() : 1.0;
756 QSizeF CGuiUtility::fontMetricsEstimateSize(
int xCharacters,
int yCharacters,
bool withRatio)
761 const QSizeF s1 = CGuiUtility::fontMetrics80Chars(withRatio);
762 const QSizeF s2 = CGuiUtility::fontMetricsLazyDog43Chars(withRatio);
764 const qreal w = s.
width() * xCharacters / 123;
765 const qreal h = s.
height() * yCharacters / 2;
769 void CGuiUtility::centerWidget(
QWidget *widget)
774 const int x = (screenGeometry.
width() - widget->
width()) / 2;
775 const int y = (screenGeometry.
height() - widget->
height()) / 2;
788 else { CGuiUtility::centerWidget(widget); }
793 static const QString s(
"%1 %2 | 80 chars: w%3 h%4 | 43 chars: w%5 h%6");
794 const QSizeF s80 = CGuiUtility::fontMetrics80Chars();
795 const QSizeF s43 = CGuiUtility::fontMetricsLazyDog43Chars();
800 const QWidget *mainWidget = CGuiUtility::mainApplicationWidget();
810 void CGuiUtility::forceStyleSheetUpdate(
QWidget *widget)
812 if (!widget) {
return; }
816 void CGuiUtility::superviseMainWindowMinSizes(qreal wRatio, qreal hRatio)
818 QWidget *w = CGuiUtility::mainApplicationWidget();
820 const QSize s = CGuiUtility::desktopSize();
821 const int minW = qRound(wRatio * s.
width());
822 const int minH = qRound(hRatio * s.
height());
827 QString CGuiUtility::asSimpleHtmlImageWidth(
const CIcon &icon,
int width)
832 if (width < 0) {
return QStringLiteral(
"<img src=\"%1\">").
arg(p); }
836 QString CGuiUtility::asSimpleHtmlImageHeight(
const CIcon &icon,
int height)
838 if (height < 0) {
return CGuiUtility::asSimpleHtmlImageWidth(icon); }
847 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
851 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
858 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
863 if (level > maxLevel) {
return nullptr; }
865 if (CGuiUtility::isDialog(widget)) {
return qobject_cast<QDialog *>(widget); }
872 if (!label) {
return; }
882 const int width = qMax(label->
width() - 2, 0);
890 if (!label) {
return; }
893 CGuiUtility::setElidedText(label, longText, mode);
898 CGuiUtility::setElidedText(label, shortText, mode);
904 const int width = qMax(label->
width() - 2, 0);
911 if (qRound(wl * 0.85) > wl)
921 void CGuiUtility::setWizardButtonWidths(
QWizard *wizard)
923 if (!wizard) {
return; }
925 const int minW = qMax(qRound(CGuiUtility::fontMetricsLazyDog43Chars(
true).width() * 6.0 / 43.0), 80);
935 QWidgetList CGuiUtility::getAllModallWidgets()
938 QWidgetList openWidgets;
941 if (w->isModal()) { openWidgets.push_back(w); }
946 QStringList CGuiUtility::getAllWidgetTitles(
const QWidgetList &widgets)
949 for (
const QWidget *w : widgets)
951 if (!w) {
continue; }
952 if (!w->windowTitle().isEmpty()) { titles.
push_back(w->windowTitle()); }
953 else { titles.
push_back(QStringLiteral(
"name: ") % w->objectName()); }
958 QStringList CGuiUtility::getAllWidgetNames(
const QWidgetList &widgets)
961 for (
const QWidget *w : widgets)
963 if (!w) {
continue; }
964 titles.
push_back(QStringLiteral(
"name: ") % w->objectName());
977 if (!w) {
continue; }
978 if (!floatingOnly || w->isFloating()) { docks.
push_back(w); }
992 if (!w) {
continue; }
993 if (!floatingOnly || w->isFloating()) { docks.
push_back(w); }
999 QWidgetList CGuiUtility::closeAllModalWidgets()
1001 QWidgetList modals = getAllModallWidgets();
1004 if (!w) {
continue; }
1012 const QWidgetList modals = getAllModallWidgets();
1016 if (!w) {
continue; }
1017 titles << w->windowTitle();
1028 if (!w) {
continue; }
1039 if (!w) {
continue; }
1051 if (!w) {
continue; }
1052 titles << w->windowTitle();
1064 if (!w) {
continue; }
1065 titles << w->windowTitle();
1077 if (!w) {
continue; }
1078 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.
void start(QAbstractAnimation::DeletionPolicy policy)
virtual bool removeRows(int row, int count, const QModelIndex &parent)
virtual int rowCount(const QModelIndex &parent) const const=0
bool isEmpty() const const
void setCurrentIndex(int index)
QString itemText(int index) const const
QString fileName() const const
bool isReadable() const const
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const const
int horizontalAdvance(QChar ch) const const
QSizeF size(int flags, const QString &text, int tabStops, int *tabArray) const const
QScreen * screenAt(const QPoint &point)
QList< QScreen * > screens()
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
QJsonObject object() const const
bool isEmpty() const const
QJsonValue value(QLatin1StringView key) const const
QString toString() const const
void setText(const QString &)
virtual QLayout * layout() override
virtual QLayoutItem * takeAt(int index)=0
void append(QList< T > &&value)
QList< T >::const_reference at(qsizetype i) const const
bool contains(const AT &value) const const
void push_back(QList< T >::parameter_type value)
qsizetype size() const const
QByteArray data(const QString &mimeType) const const
bool hasText() const const
QString text() const const
QList< T > findChildren(QAnyStringView name, Qt::FindChildOptions options) const const
QObject * parent() const const
qreal devicePixelRatio() const const
qreal devicePixelRatioF() const const
QPoint center() const const
qreal height() const const
qreal width() const const
qreal height() const const
qreal width() const const
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool endsWith(QChar c, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
qsizetype lastIndexOf(QChar ch, Qt::CaseSensitivity cs) const const
QString left(qsizetype n) &&
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString simplified() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toLower() const const
QString trimmed() const const
QString toLocalFile() const const
void setDuration(int msecs)
void setEasingCurve(const QEasingCurve &easing)
void setEndValue(const QVariant &value)
void setStartValue(const QVariant &value)
virtual QSize size() const const override
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.