Qt Utilities  6.4.1
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
dialogutils.cpp
Go to the documentation of this file.
1 #include "./dialogutils.h"
2 
3 #include <QCoreApplication>
4 #include <QDir>
5 #include <QFileInfo>
6 
7 #if defined(QT_UTILITIES_GUI_QTWIDGETS) || defined(QT_UTILITIES_GUI_QTQUICK)
8 #include <QGuiApplication>
9 #include <QPalette>
10 #endif
11 
12 #if defined(QT_UTILITIES_GUI_QTWIDGETS)
13 #include <QApplication>
14 #include <QCursor>
15 #if (QT_VERSION < QT_VERSION_CHECK(5, 10, 0))
16 #include <QDesktopWidget>
17 #endif
18 #include <QScreen>
19 #include <QStyle>
20 #include <QWidget>
21 #endif
22 
23 namespace QtUtilities {
24 
29 QString generateWindowTitle(DocumentStatus documentStatus, const QString &documentPath)
30 {
31  switch (documentStatus) {
33  if (documentPath.isEmpty()) {
34  return QCoreApplication::translate("Utilities::windowTitle", "Unsaved - %1").arg(QCoreApplication::applicationName());
35  } else {
36  const QFileInfo file(documentPath);
37  return QCoreApplication::translate("Utilities::windowTitle", "%1 - %2 - %3")
38  .arg(file.fileName(), file.dir().path(), QCoreApplication::applicationName());
39  }
41  if (documentPath.isEmpty()) {
42  return QCoreApplication::translate("Utilities::windowTitle", "*Unsaved - %1").arg(QCoreApplication::applicationName());
43  } else {
44  const QFileInfo file(documentPath);
45  return QCoreApplication::translate("Utilities::windowTitle", "*%1 - %2 - %3")
46  .arg(file.fileName(), file.dir().path(), QCoreApplication::applicationName());
47  }
49  return QCoreApplication::applicationName();
50  default:
51  return QString(); // to suppress warning: "control reaches end of non-void
52  // function"
53  }
54 }
55 
56 #if defined(QT_UTILITIES_GUI_QTWIDGETS) || defined(QT_UTILITIES_GUI_QTQUICK)
57 
58 #ifdef Q_OS_WIN32
59 
63 QColor windowFrameColor()
64 {
65  return QGuiApplication::palette().window().color().darker(108);
66 }
67 
71 QColor instructionTextColor()
72 {
73  const auto baseColor = QGuiApplication::palette().base().color();
74  return (baseColor.value() > 204 && baseColor.saturation() < 63) ? QColor(0x00, 0x33, 0x99) : QGuiApplication::palette().text().color();
75 }
76 
77 #endif
78 
83 const QString &dialogStyle()
84 {
85 #ifdef Q_OS_WIN32
86  static const auto style = QStringLiteral("#mainWidget { color: palette(text); background-color: "
87  "palette(base); border: none; }"
88  "#bottomWidget { background-color: palette(window); "
89  "color: palette(window-text); border-top: 1px solid %1; }"
90  "QMessageBox QLabel, QInputDialog QLabel, "
91  "*[classNames~=\"heading\"] { font-size: 12pt; color: %2; "
92  "}"
93  "*[classNames~=\"input-invalid\"] { color: red; }")
94  .arg(windowFrameColor().name(), instructionTextColor().name());
95 #else
96  static const auto style = QStringLiteral("*[classNames~=\"heading\"] { font-weight: bold; }"
97  "*[classNames~=\"input-invalid\"] { color: red; }");
98 #endif
99  return style;
100 }
101 
102 #ifdef QT_UTILITIES_GUI_QTWIDGETS
103 
104 QRect availableScreenGeometryAtPoint(const QPoint &point)
105 {
106 #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
107  QScreen *const screen = QGuiApplication::screenAt(point);
108  if (!screen) {
109  return QRect();
110  }
111  return screen->availableGeometry();
112 #else
113  return QApplication::desktop()->availableGeometry(point);
114 #endif
115 }
116 
118 static QRect shrinkRectByMargins(QRect rect, const QMargins &margins)
119 {
120  rect.setLeft(rect.left() + margins.left());
121  rect.setTop(rect.top() + margins.top());
122  rect.setRight(rect.right() - margins.right());
123  rect.setBottom(rect.bottom() - margins.bottom());
124  return rect;
125 }
126 
127 static QRect limitRect(QRect rect, const QRect &bounds)
128 {
129  if (rect.left() < bounds.left()) {
130  rect.setLeft(bounds.left());
131  }
132  if (rect.top() < bounds.top()) {
133  rect.setTop(bounds.top());
134  }
135  if (rect.right() > bounds.right()) {
136  rect.setRight(bounds.right());
137  }
138  if (rect.bottom() > bounds.bottom()) {
139  rect.setBottom(bounds.bottom());
140  }
141  return rect;
142 }
143 
144 static QMargins widgetFrame(QWidget *widget, const QMargins &defaultAssumption = QMargins(10, 25, 10, 10))
145 {
146  if (!widget->isWindow()) {
147  return QMargins();
148  }
149  const auto widgetGeometry = widget->geometry();
150  const auto frameGeometry = widget->frameGeometry();
151  const auto frame = QMargins(widgetGeometry.left() - frameGeometry.left(), widgetGeometry.top() - frameGeometry.top(),
152  frameGeometry.right() - widgetGeometry.right(), frameGeometry.bottom() - widgetGeometry.bottom());
153  return frame.isNull() ? defaultAssumption : frame;
154 }
155 
156 static bool centerWidgetInternal(QWidget *widget, const QWidget *parent, const QPoint *position, bool avoidOverflow)
157 {
158  const auto availableGeometry = parent ? parent->geometry() : availableScreenGeometryAtPoint(position ? *position : QCursor::pos());
159  const auto alignedRect = QStyle::alignedRect(Qt::LeftToRight, Qt::AlignCenter, widget->size(), availableGeometry);
160  if (!avoidOverflow) {
161  widget->setGeometry(alignedRect);
162  return false;
163  }
164  const auto limitedRect = limitRect(alignedRect, shrinkRectByMargins(availableGeometry, widgetFrame(widget)));
165  widget->setGeometry(limitedRect);
166  return alignedRect != limitedRect;
167 }
169 
175 void centerWidget(QWidget *widget, const QWidget *parent, const QPoint *position)
176 {
177  centerWidgetInternal(widget, parent, position, false);
178 }
179 
190 bool centerWidgetAvoidingOverflow(QWidget *widget, const QWidget *parent, const QPoint *position)
191 {
192  return centerWidgetInternal(widget, parent, position, true);
193 }
194 
202 void cornerWidget(QWidget *widget, const QPoint *position)
203 {
204  const QPoint cursorPos(position ? *position : QCursor::pos());
205  const QRect availableGeometry(availableScreenGeometryAtPoint(cursorPos));
206  const Qt::Alignment alignment
207  = (cursorPos.x() - availableGeometry.left() < availableGeometry.right() - cursorPos.x() ? Qt::AlignLeft : Qt::AlignRight)
208  | (cursorPos.y() - availableGeometry.top() < availableGeometry.bottom() - cursorPos.y() ? Qt::AlignTop : Qt::AlignBottom);
209  widget->setGeometry(QStyle::alignedRect(Qt::LeftToRight, alignment, widget->size(), availableGeometry));
210 }
211 
215 void makeHeading(QWidget *widget)
216 {
217  widget->setProperty("classNames", widget->property("classNames").toStringList() << QStringLiteral("heading"));
218 }
219 
226 void updateStyle(QWidget *widget)
227 {
228  widget->style()->unpolish(widget);
229  widget->style()->polish(widget);
230  widget->update();
231 }
232 
233 #endif
234 
235 #endif
236 
237 } // namespace QtUtilities
DocumentStatus
The DocumentStatus enum specifies the status of the document in a window.
Definition: dialogutils.h:20
QT_UTILITIES_EXPORT QString generateWindowTitle(DocumentStatus documentStatus, const QString &documentPath)
Generates the window title string for the specified documentStatus and documentPath.
Definition: dialogutils.cpp:29
#define text