Noisy Debug Hook for Qt.

--HG--
branch : feature
This commit is contained in:
dismine 2014-03-27 13:41:00 +02:00
parent 7c18e85305
commit 26c8884af0

View File

@ -30,31 +30,87 @@
#include "widgets/vapplication.h" #include "widgets/vapplication.h"
#include <QTextCodec> #include <QTextCodec>
#include <QtCore> #include <QtCore>
#include <QMessageBox>
#include <QThread>
#include "tablewindow.h" #include "tablewindow.h"
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
QByteArray localMsg = msg.toLocal8Bit(); // Why on earth didn't Qt want to make failed signal/slot connections qWarning?
switch (type) if ((type == QtDebugMsg) && msg.contains("::connect"))
{ {
case QtDebugMsg: type = QtWarningMsg;
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, }
context.function);
break; // this is another one that doesn't make sense as just a debug message. pretty serious
case QtWarningMsg: // sign of a problem
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, // http://www.developer.nokia.com/Community/Wiki/QPainter::begin:Paint_device_returned_engine_%3D%3D_0_(Known_Issue)
context.function); if ((type == QtDebugMsg) && msg.contains("QPainter::begin") && msg.contains("Paint device returned engine"))
break; {
case QtCriticalMsg: type = QtWarningMsg;
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, }
context.function);
break; // This qWarning about "Cowardly refusing to send clipboard message to hung application..."
case QtFatalMsg: // is something that can easily happen if you are debugging and the application is paused.
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, // As it is so common, not worth popping up a dialog.
context.function); if ((type == QtWarningMsg) && QString(msg).contains("QClipboard::event")
&& QString(msg).contains("Cowardly refusing"))
{
type = QtDebugMsg;
}
// only the GUI thread should display message boxes. If you are
// writing a multithreaded application and the error happens on
// a non-GUI thread, you'll have to queue the message to the GUI
QCoreApplication *instance = QCoreApplication::instance();
const bool isGuiThread = instance && (QThread::currentThread() == instance->thread());
if (isGuiThread)
{
QByteArray localMsg = msg.toLocal8Bit();
QMessageBox messageBox;
switch (type) {
case QtDebugMsg:
fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line,
context.function);
return;
case QtWarningMsg:
messageBox.setIcon(QMessageBox::Warning);
messageBox.setInformativeText(msg);
messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
fprintf(stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line,
context.function);
break;
case QtCriticalMsg:
messageBox.setIcon(QMessageBox::Critical);
messageBox.setInformativeText(msg);
messageBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
fprintf(stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line,
context.function);
break;
case QtFatalMsg:
messageBox.setIcon(QMessageBox::Critical);
messageBox.setInformativeText(msg);
messageBox.setStandardButtons(QMessageBox::Cancel);
fprintf(stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line,
context.function);
break;
default:
break;
}
const int ret = messageBox.exec();
if (ret == QMessageBox::Cancel)
{
abort(); abort();
default: }
break; }
else
{
if (type != QtDebugMsg)
{
abort(); // be NOISY unless overridden!
}
} }
} }
@ -65,8 +121,15 @@ int main(int argc, char *argv[])
Q_INIT_RESOURCE(schema); Q_INIT_RESOURCE(schema);
Q_INIT_RESOURCE(theme); Q_INIT_RESOURCE(theme);
qInstallMessageHandler(myMessageOutput);
VApplication app(argc, argv); VApplication app(argc, argv);
#ifdef QT_DEBUG
// Because our "noisy" message handler uses the GUI subsystem for message
// boxes, we can't install it until after the QApplication is constructed. But it
// is good to be the very next thing to run, to start catching warnings ASAP.
{
qInstallMessageHandler(noisyFailureMsgHandler);
}
#endif
app.setApplicationDisplayName("Valentina"); app.setApplicationDisplayName("Valentina");
app.setApplicationName("Valentina"); app.setApplicationName("Valentina");
app.setOrganizationName("ValentinaTeam"); app.setOrganizationName("ValentinaTeam");