Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qerrormessage.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qerrormessage.h"
5
6#include "qapplication.h"
7#include "qcheckbox.h"
8#include "qlabel.h"
9#include "qlayout.h"
10#if QT_CONFIG(messagebox)
11#include "qmessagebox.h"
12#endif
13#include "qpushbutton.h"
14#include "qstringlist.h"
15#include "qtextedit.h"
16#include "qdialog_p.h"
17#include "qpixmap.h"
18#include "qmetaobject.h"
19#include "qthread.h"
20#include "qset.h"
21
22#include <queue>
23
24#include <stdio.h>
25#include <stdlib.h>
26
28
29using namespace Qt::StringLiterals;
30
32{
33 Q_DECLARE_PUBLIC(QErrorMessage)
34public:
35 struct Message {
38 };
39
44 std::queue<Message> pending;
49
50 bool isMessageToBeShown(const QString &message, const QString &type) const;
51 bool nextPending();
52 void retranslateStrings();
53
54 void setVisible(bool) override;
55
56private:
57 void initHelper(QPlatformDialogHelper *) override;
59};
60
61
63{
64 Q_Q(QErrorMessage);
65 auto *messageDialogHelper = static_cast<QPlatformMessageDialogHelper *>(helper);
67 [this](Qt::CheckState state) {
69 }
70 );
73 Q_Q(QErrorMessage);
74 q->accept();
75 }
76 );
77}
78
80{
81 Q_Q(QErrorMessage);
82 auto *messageDialogHelper = static_cast<QPlatformMessageDialogHelper *>(helper);
84 options->setText(currentMessage);
85 options->setWindowTitle(q->windowTitle());
86 options->setText(QErrorMessage::tr("An error occurred"));
87 options->setInformativeText(currentMessage);
88 options->setStandardIcon(QMessageDialogOptions::Critical);
89 options->setCheckBox(again->text(), again->checkState());
90 messageDialogHelper->setOptions(options);
91}
92
93namespace {
94class QErrorMessageTextView : public QTextEdit
95{
96public:
97 QErrorMessageTextView(QWidget *parent)
98 : QTextEdit(parent) { setReadOnly(true); }
99
100 virtual QSize minimumSizeHint() const override;
101 virtual QSize sizeHint() const override;
102};
103} // unnamed namespace
104
105QSize QErrorMessageTextView::minimumSizeHint() const
106{
107 return QSize(50, 50);
108}
109
110QSize QErrorMessageTextView::sizeHint() const
111{
112 return QSize(250, 75);
113}
114
155
156static void deleteStaticcQErrorMessage() // post-routine
157{
158 if (qtMessageHandler) {
159 delete qtMessageHandler;
160 qtMessageHandler = nullptr;
161 }
162}
163
164static bool metFatal = false;
165
167{
168 static_assert(QtDebugMsg == 0);
169 static_assert(QtWarningMsg == 1);
170 static_assert(QtCriticalMsg == 2);
171 static_assert(QtFatalMsg == 3);
172 static_assert(QtInfoMsg == 4);
173
174 // adjust the array below if any of the above fire...
175
176 const char * const messages[] = {
177 QT_TRANSLATE_NOOP("QErrorMessage", "Debug Message:"),
178 QT_TRANSLATE_NOOP("QErrorMessage", "Warning:"),
179 QT_TRANSLATE_NOOP("QErrorMessage", "Critical Error:"),
180 QT_TRANSLATE_NOOP("QErrorMessage", "Fatal Error:"),
181 QT_TRANSLATE_NOOP("QErrorMessage", "Information:"),
182 };
183 Q_ASSERT(size_t(t) < sizeof messages / sizeof *messages);
184
185 return QCoreApplication::translate("QErrorMessage", messages[t]);
186}
187
189
190static void jump(QtMsgType t, const QMessageLogContext &context, const QString &m)
191{
192 const auto forwardToOriginalHandler = qScopeGuard([&] {
195 });
196
197 if (!qtMessageHandler)
198 return;
199
200 auto *defaultCategory = QLoggingCategory::defaultCategory();
201 if (context.category && defaultCategory
202 && qstrcmp(context.category, defaultCategory->categoryName()) != 0)
203 return;
204
205 QString rich = "<p><b>"_L1 + msgType2i18nString(t) + "</b></p>"_L1
207
208 // ### work around text engine quirk
209 if (rich.endsWith("</p>"_L1))
210 rich.chop(4);
211
212 if (!metFatal) {
213 if (QThread::currentThread() == qApp->thread()) {
215 } else {
217 "showMessage",
219 Q_ARG(QString, rich));
220 }
221 metFatal = (t == QtFatalMsg);
222 }
223}
224
225
237{
238 Q_D(QErrorMessage);
239
240#if defined(Q_OS_MACOS)
242#endif
243
244 d->icon = new QLabel(this);
245 d->errors = new QErrorMessageTextView(this);
246 d->again = new QCheckBox(this);
247 d->ok = new QPushButton(this);
248 QGridLayout * grid = new QGridLayout(this);
249
250 connect(d->ok, SIGNAL(clicked()), this, SLOT(accept()));
251
252 grid->addWidget(d->icon, 0, 0, Qt::AlignTop);
253 grid->addWidget(d->errors, 0, 1);
254 grid->addWidget(d->again, 1, 1, Qt::AlignTop);
255 grid->addWidget(d->ok, 2, 0, 1, 2, Qt::AlignCenter);
256 grid->setColumnStretch(1, 42);
257 grid->setRowStretch(0, 42);
258
259#if QT_CONFIG(messagebox)
260 d->icon->setPixmap(style()->standardPixmap(QStyle::SP_MessageBoxInformation));
261 d->icon->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
262#endif
263 d->again->setChecked(true);
264 d->ok->setFocus();
265
266 d->retranslateStrings();
267}
268
269
275{
276 if (this == qtMessageHandler) {
277 qtMessageHandler = nullptr;
278 QtMessageHandler currentMessagHandler = qInstallMessageHandler(nullptr);
279 if (currentMessagHandler != jump)
280 qInstallMessageHandler(currentMessagHandler);
281 else
283 originalMessageHandler = nullptr;
284 }
285}
286
287
291{
292 Q_D(QErrorMessage);
293 if (!d->again->isChecked()) {
294 if (d->currentType.isEmpty()) {
295 if (!d->currentMessage.isEmpty())
296 d->doNotShow.insert(d->currentMessage);
297 } else {
298 d->doNotShowType.insert(d->currentType);
299 }
300 }
301 d->currentMessage.clear();
302 d->currentType.clear();
303
305
306 if (d->nextPending()) {
307 show();
308 } else {
309 if (this == qtMessageHandler && metFatal)
310 exit(1);
311 }
312}
313
314
328{
329 if (!qtMessageHandler) {
330 qtMessageHandler = new QErrorMessage(nullptr);
334 }
335 return qtMessageHandler;
336}
337
338
342{
343 return !message.isEmpty()
345}
346
348{
349 while (!pending.empty()) {
350 QString message = std::move(pending.front().content);
351 QString type = std::move(pending.front().type);
352 pending.pop();
354#ifndef QT_NO_TEXTHTMLPARSER
356#else
358#endif
359 currentMessage = std::move(message);
360 currentType = std::move(type);
361 again->setChecked(true);
362 return true;
363 }
364 }
365 return false;
366}
367
368
379{
381}
382
398{
399 Q_D(QErrorMessage);
400 if (!d->isMessageToBeShown(message, type))
401 return;
402 d->pending.push({message, type});
403 if (!isVisible() && d->nextPending())
404 show();
405}
406
408{
409 Q_Q(QErrorMessage);
410 if (q->testAttribute(Qt::WA_WState_ExplicitShowHide) && q->testAttribute(Qt::WA_WState_Hidden) != visible)
411 return;
412
413 if (canBeNativeDialog())
414 setNativeDialogVisible(visible);
415
416 // Update WA_DontShowOnScreen based on whether the native dialog was shown,
417 // so that QDialog::setVisible(visible) below updates the QWidget state correctly,
418 // but skips showing the non-native version.
420
422}
423
428{
429 Q_D(QErrorMessage);
430 if (e->type() == QEvent::LanguageChange) {
431 d->retranslateStrings();
432 }
434}
435
437{
438 again->setText(QErrorMessage::tr("&Show this message again"));
439 ok->setText(QErrorMessage::tr("&OK"));
440}
441
443
444#include "moc_qerrormessage.cpp"
void setText(const QString &text)
QString text
the text shown on the button
The QCheckBox widget provides a checkbox with a text label.
Definition qcheckbox.h:19
void setCheckState(Qt::CheckState state)
Sets the checkbox's check state to state.
Qt::CheckState checkState() const
Returns the checkbox's check state.
static QString translate(const char *context, const char *key, const char *disambiguation=nullptr, int n=-1)
\threadsafe
QString applicationName
the name of this application
bool setNativeDialogVisible(bool visible)
Definition qdialog.cpp:162
virtual void setVisible(bool visible)
Definition qdialog.cpp:746
virtual bool canBeNativeDialog() const
Definition qdialog.cpp:99
bool nativeDialogInUse
Definition qdialog_p.h:86
The QDialog class is the base class of dialog windows.
Definition qdialog.h:19
friend class QPushButton
[1]
Definition qdialog.h:21
virtual void done(int)
Closes the dialog and sets its result code to r.
Definition qdialog.cpp:598
virtual void accept()
Hides the modal dialog and sets the result code to Accepted.
Definition qdialog.cpp:624
void helperPrepareShow(QPlatformDialogHelper *) override
void initHelper(QPlatformDialogHelper *) override
QSet< QString > doNotShowType
bool isMessageToBeShown(const QString &message, const QString &type) const
std::queue< Message > pending
void setVisible(bool) override
QSet< QString > doNotShow
The QErrorMessage class provides an error message display dialog.
static QErrorMessage * qtHandler()
Returns a pointer to a QErrorMessage object that outputs the default Qt messages.
void showMessage(const QString &message)
Shows the given message, message, and returns immediately.
void changeEvent(QEvent *e) override
\reimp
QErrorMessage(QWidget *parent=nullptr)
Constructs and installs an error handler window with the given parent.
~QErrorMessage()
Destroys the error message dialog.
\inmodule QtCore
Definition qcoreevent.h:45
@ LanguageChange
Definition qcoreevent.h:123
The QGridLayout class lays out widgets in a grid.
Definition qgridlayout.h:21
void addWidget(QWidget *w)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qgridlayout.h:64
void setRowStretch(int row, int stretch)
Sets the stretch factor of row row to stretch.
void setColumnStretch(int column, int stretch)
Sets the stretch factor of column column to stretch.
The QLabel widget provides a text or image display.
Definition qlabel.h:20
static QLoggingCategory * defaultCategory()
Returns a pointer to the global category "default" that is used, for example, by qDebug(),...
static QSharedPointer< QMessageDialogOptions > create()
\inmodule QtCore
Definition qlogging.h:39
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
The QPlatformDialogHelper class allows for platform-specific customization of dialogs.
The QPlatformMessageDialogHelper class allows for platform-specific customization of Message dialogs.
void checkBoxStateChanged(Qt::CheckState state)
void clicked(QPlatformDialogHelper::StandardButton button, QPlatformDialogHelper::ButtonRole role)
The QPushButton widget provides a command button.
Definition qpushbutton.h:20
Definition qset.h:18
bool contains(const T &value) const
Definition qset.h:71
\inmodule QtCore
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition qstring.cpp:5350
@ SP_MessageBoxInformation
Definition qstyle.h:724
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
Definition qtextedit.h:27
void setReadOnly(bool ro)
void setPlainText(const QString &text)
Changes the text of the text edit to the string text.
void setHtml(const QString &text)
static QThread * currentThread()
Definition qthread.cpp:966
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setWindowModality(Qt::WindowModality windowModality)
Definition qwidget.cpp:2806
void show()
Shows the widget and its child widgets.
Definition qwidget.cpp:7956
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition qwidget.cpp:9428
void setWindowTitle(const QString &)
Definition qwidget.cpp:6109
QStyle * style() const
Definition qwidget.cpp:2607
bool isVisible() const
Definition qwidget.h:874
double e
else opt state
[0]
QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
Combined button and popup list for selecting options.
CheckState
@ AlignTop
Definition qnamespace.h:152
@ AlignHCenter
Definition qnamespace.h:147
@ AlignCenter
Definition qnamespace.h:162
@ WA_WState_ExplicitShowHide
Definition qnamespace.h:334
@ WA_DontShowOnScreen
Definition qnamespace.h:382
@ WA_WState_Hidden
Definition qnamespace.h:296
Q_GUI_EXPORT QString convertFromPlainText(const QString &plain, WhiteSpaceMode mode=WhiteSpacePre)
Converts the plain text string plain to an HTML-formatted paragraph while preserving most of its look...
@ WindowModal
@ ApplicationModal
@ WhiteSpaceNormal
Definition qnamespace.h:196
@ QueuedConnection
static void * context
Q_CORE_EXPORT int qstrcmp(const char *str1, const char *str2)
void qAddPostRoutine(QtCleanUpFunction p)
#define qApp
static QString msgType2i18nString(QtMsgType t)
static void deleteStaticcQErrorMessage()
static QErrorMessage * qtMessageHandler
static QtMessageHandler originalMessageHandler
static bool metFatal
static void jump(QtMsgType t, const QMessageLogContext &context, const QString &m)
QtMsgType
Definition qlogging.h:29
@ QtCriticalMsg
Definition qlogging.h:32
@ QtInfoMsg
Definition qlogging.h:34
@ QtWarningMsg
Definition qlogging.h:31
@ QtFatalMsg
Definition qlogging.h:33
@ QtDebugMsg
Definition qlogging.h:30
void(* QtMessageHandler)(QtMsgType, const QMessageLogContext &, const QString &)
Definition qlogging.h:187
#define SLOT(a)
Definition qobjectdefs.h:51
#define Q_ARG(Type, data)
Definition qobjectdefs.h:62
#define SIGNAL(a)
Definition qobjectdefs.h:52
const GLfloat * m
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum type
GLuint GLsizei const GLchar * message
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
#define QT_TRANSLATE_NOOP(scope, x)
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent