Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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:
39
44 std::queue<Message> pending;
45 QSet<QString> doNotShow;
46 QSet<QString> doNotShowType;
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);
83 QSharedPointer<QMessageDialogOptions> options = QMessageDialogOptions::create();
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()) {
214 qtMessageHandler->showMessage(rich);
215 } else {
217 "showMessage",
219 Q_ARG(QString, rich));
220 }
221 metFatal = (t == QtFatalMsg);
222 }
223}
224
225
236 : QDialog(*new QErrorMessagePrivate, parent)
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 const auto iconSize = style()->pixelMetric(QStyle::PM_MessageBoxIconSize, nullptr, this);
261 const auto icon = style()->standardIcon(QStyle::SP_MessageBoxInformation, nullptr, this);
262 d->icon->setPixmap(icon.pixmap(QSize(iconSize, iconSize), devicePixelRatio()));
263 d->icon->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
264#endif
265 d->again->setChecked(true);
266 d->ok->setFocus();
267
268 d->retranslateStrings();
269}
270
271
277{
278 if (this == qtMessageHandler) {
279 qtMessageHandler = nullptr;
280 QtMessageHandler currentMessagHandler = qInstallMessageHandler(nullptr);
281 if (currentMessagHandler != jump)
282 qInstallMessageHandler(currentMessagHandler);
283 else
285 originalMessageHandler = nullptr;
286 }
287}
288
289
293{
294 Q_D(QErrorMessage);
295 if (!d->again->isChecked()) {
296 if (d->currentType.isEmpty()) {
297 if (!d->currentMessage.isEmpty())
298 d->doNotShow.insert(d->currentMessage);
299 } else {
300 d->doNotShowType.insert(d->currentType);
301 }
302 }
303 d->currentMessage.clear();
304 d->currentType.clear();
305
307
308 if (d->nextPending()) {
309 show();
310 } else {
311 if (this == qtMessageHandler && metFatal)
312 exit(1);
313 }
314}
315
316
339
340
344{
345 return !message.isEmpty()
347}
348
350{
351 while (!pending.empty()) {
352 QString message = std::move(pending.front().content);
353 QString type = std::move(pending.front().type);
354 pending.pop();
356#ifndef QT_NO_TEXTHTMLPARSER
358#else
360#endif
361 currentMessage = std::move(message);
362 currentType = std::move(type);
363 again->setChecked(true);
364 return true;
365 }
366 }
367 return false;
368}
369
370
384
400{
401 Q_D(QErrorMessage);
402 if (!d->isMessageToBeShown(message, type))
403 return;
404 d->pending.push({message, type});
405 if (!isVisible() && d->nextPending())
406 show();
407}
408
410{
411 Q_Q(QErrorMessage);
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:754
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:602
virtual void accept()
Hides the modal dialog and sets the result code to Accepted.
Definition qdialog.cpp:628
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 done(int) override
\reimp
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
Type type() const
Returns the event type.
Definition qcoreevent.h:304
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.
QPixmap pixmap(const QSize &size, Mode mode=Normal, State state=Off) const
Returns a pixmap with the requested size, mode, and state, generating one if necessary.
Definition qicon.cpp:834
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:42
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
qreal devicePixelRatio() const
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
bool contains(const T &value) const
Definition qset.h:71
\inmodule QtCore
Definition qsize.h:25
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
@ SP_MessageBoxInformation
Definition qstyle.h:726
@ PM_MessageBoxIconSize
Definition qstyle.h:506
virtual int pixelMetric(PixelMetric metric, const QStyleOption *option=nullptr, const QWidget *widget=nullptr) const =0
Returns the value of the given pixel metric.
The QTextEdit class provides a widget that is used to edit and display both plain and rich text.
Definition qtextedit.h:27
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:1039
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
void setWindowModality(Qt::WindowModality windowModality)
Definition qwidget.cpp:2799
void show()
Shows the widget and its child widgets.
Definition qwidget.cpp:7875
virtual void changeEvent(QEvent *)
This event handler can be reimplemented to handle state changes.
Definition qwidget.cpp:9382
QStyle * style() const
Definition qwidget.cpp:2600
bool isVisible() const
Definition qwidget.h:874
opt iconSize
else opt state
[0]
QtMessageHandler qInstallMessageHandler(QtMessageHandler h)
Combined button and popup list for selecting options.
CheckState
@ AlignTop
Definition qnamespace.h:153
@ AlignHCenter
Definition qnamespace.h:148
@ AlignCenter
Definition qnamespace.h:163
@ WA_DontShowOnScreen
Definition qnamespace.h:383
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:197
@ 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:191
#define SLOT(a)
Definition qobjectdefs.h:52
#define Q_ARG(Type, data)
Definition qobjectdefs.h:63
#define SIGNAL(a)
Definition qobjectdefs.h:53
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...