Skip to content
Permalink
Browse files

Merge PR #2698: Add Developer Console to Mumble

  • Loading branch information...
mkrautz committed Dec 4, 2016
2 parents 681ecf6 + f62af9a commit 6ac0553add4376c5b7c00d30640f40fefb1bd55b
@@ -6,6 +6,9 @@
#ifndef MUMBLE_LOGEMITTER_H_
#define MUMBLE_LOGEMITTER_H_

#include <QtCore/QObject>
#include <QtCore/QString>

class LogEmitter : public QObject {
private:
Q_OBJECT
@@ -0,0 +1,50 @@
// Copyright 2005-2016 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "mumble_pch.hpp"

#include "DeveloperConsole.h"

#include "LogEmitter.h"
#include "Global.h"

DeveloperConsole::DeveloperConsole(QObject *parent)
: QObject(parent) {

connect(g.le.data(), SIGNAL(newLogEntry(const QString &)), this, SLOT(addLogMessage(const QString &)));
}

DeveloperConsole::~DeveloperConsole() {
QMainWindow *mw = m_window.data();
m_window.clear();
delete mw;
}

void DeveloperConsole::show() {
if (m_window.isNull()) {
QMainWindow *mw = new QMainWindow();
mw->setAttribute(Qt::WA_DeleteOnClose);
QTextBrowser *tb = new QTextBrowser();
mw->resize(675, 300);
mw->setCentralWidget(tb);
mw->setWindowTitle(tr("Developer Console"));

connect(g.le.data(), SIGNAL(newLogEntry(const QString &)), tb, SLOT(append(const QString &)));

foreach(const QString &m, m_logEntries)
tb->append(m);
m_window = QPointer<QMainWindow>(mw);
}

m_window.data()->show();
m_window.data()->activateWindow();
}

void DeveloperConsole::addLogMessage(const QString &msg) {
if (m_logEntries.count() >= 1000)
m_logEntries.removeFirst();

m_logEntries.append(msg);
}
@@ -0,0 +1,33 @@
// Copyright 2005-2016 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#ifndef MUMBLE_MUMBLE_DEVELOPERCONSOLE_H_
#define MUMBLE_MUMBLE_DEVELOPERCONSOLE_H_

#include <QtCore/QStringList>
#include <QtCore/QObject>
# include <QtCore/QPointer>
#if QT_VERSION >= 0x050000
# include <QtWidgets/QMainWindow>
#else
# include <QtGui/QMainWindow>
#endif

class DeveloperConsole : public QObject {
private:
Q_OBJECT
Q_DISABLE_COPY(DeveloperConsole);
protected:
QPointer<QMainWindow> m_window;
QStringList m_logEntries;
public slots:
void addLogMessage(const QString &);
public:
DeveloperConsole(QObject *parent = NULL);
~DeveloperConsole();
void show();
};

#endif
@@ -30,6 +30,8 @@ class LCD;
class BonjourClient;
class OverlayClient;
class CELTCodec;
class LogEmitter;
class DeveloperConsole;

class QNetworkAccessManager;

@@ -51,6 +53,8 @@ struct Global Q_DECL_FINAL {
LCD *lcd;
BonjourClient *bc;
QNetworkAccessManager *nam;
QSharedPointer<LogEmitter> le;
DeveloperConsole *c;
int iPushToTalk;
Timer tDoublePush;
quint64 uiDoublePush;
@@ -20,6 +20,7 @@
#include "Connection.h"
#include "ConnectDialog.h"
#include "Database.h"
#include "DeveloperConsole.h"
#include "Global.h"
#include "GlobalShortcut.h"
#include "Log.h"
@@ -2388,6 +2389,10 @@ void MainWindow::on_qaAudioWizard_triggered() {
delete aw;
}

void MainWindow::on_qaDeveloperConsole_triggered() {
g.c->show();
}

void MainWindow::on_qaHelpWhatsThis_triggered() {
QWhatsThis::enterWhatsThisMode();
}
@@ -233,6 +233,7 @@ class MainWindow : public QMainWindow, public MessageHandler, public Ui::MainWin
void on_qaConfigMinimal_triggered();
void on_qaConfigCert_triggered();
void on_qaAudioWizard_triggered();
void on_qaDeveloperConsole_triggered();
void on_qaHelpWhatsThis_triggered();
void on_qaHelpAbout_triggered();
void on_qaHelpAboutQt_triggered();
@@ -68,6 +68,12 @@
<addaction name="separator"/>
<addaction name="qaHelpVersionCheck"/>
</widget>
<widget class="QMenu" name="qmDeveloper">
<property name="title">
<string>&amp;Developer</string>
</property>
<addaction name="qaDeveloperConsole"/>
</widget>
<widget class="QMenu" name="qmServer">
<property name="title">
<string>S&amp;erver</string>
@@ -93,6 +99,7 @@
<addaction name="qmServer"/>
<addaction name="qmSelf"/>
<addaction name="qmConfig"/>
<addaction name="qmDeveloper"/>
<addaction name="qmHelp"/>
</widget>
<widget class="QDockWidget" name="qdwLog">
@@ -587,6 +594,17 @@ the channel's context menu.</string>
<string>This will guide you through the process of configuring your audio hardware.</string>
</property>
</action>
<action name="qaDeveloperConsole">
<property name="text">
<string>Developer &amp;Console</string>
</property>
<property name="toolTip">
<string>Show the Developer Console</string>
</property>
<property name="whatsThis">
<string>Shows the Mumble Developer Console, where Mumble's log output can be inspected.</string>
</property>
</action>
<action name="qaHelpWhatsThis">
<property name="text">
<string>&amp;What's This?</string>
@@ -15,6 +15,8 @@
#include "Database.h"
#include "Log.h"
#include "Plugins.h"
#include "LogEmitter.h"
#include "DeveloperConsole.h"
#include "Global.h"
#include "LCD.h"
#ifdef USE_BONJOUR
@@ -104,9 +106,10 @@ int main(int argc, char **argv) {

qsrand(QDateTime::currentDateTime().toTime_t());

#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
g.le = QSharedPointer<LogEmitter>(new LogEmitter());
g.c = new DeveloperConsole();

os_init();
#endif

bool bAllowMultiple = false;
bool suppressIdentity = false;
@@ -560,6 +563,9 @@ int main(int argc, char **argv) {

delete g.o;

delete g.c;
g.le.clear();

DeferInit::run_destroyers();

delete Global::g_global_struct;
@@ -128,7 +128,8 @@ HEADERS *= BanEditor.h \
ThemeInfo.h \
Themes.h \
OverlayPositionableItem.h \
widgets/MUComboBox.h
widgets/MUComboBox.h \
DeveloperConsole.h

SOURCES *= BanEditor.cpp \
ACLEditor.cpp \
@@ -193,7 +194,8 @@ SOURCES *= BanEditor.cpp \
ThemeInfo.cpp \
Themes.cpp \
OverlayPositionableItem.cpp \
widgets/MUComboBox.cpp
widgets/MUComboBox.cpp \
DeveloperConsole.cpp

DIST *= ../../icons/mumble.ico ../../icons/mumble.xpm murmur_pch.h mumble.plist
RESOURCES *= mumble.qrc mumble_translations.qrc ../../themes/MumbleTheme.qrc
@@ -469,7 +471,7 @@ unix {
HEADERS += CoreAudio.h
} else {
HEADERS *= GlobalShortcut_unix.h
SOURCES *= GlobalShortcut_unix.cpp TextToSpeech_unix.cpp Overlay_unix.cpp SharedMemory_unix.cpp Log_unix.cpp
SOURCES *= os_unix.cpp GlobalShortcut_unix.cpp TextToSpeech_unix.cpp Overlay_unix.cpp SharedMemory_unix.cpp Log_unix.cpp
must_pkgconfig(x11)
linux {
LIBS *= -lrt
@@ -4,13 +4,16 @@
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "mumble_pch.hpp"
#include "LogEmitter.h"
#include "Global.h"
#include "Overlay.h"
#include "MainWindow.h"

char *os_lang = NULL;
static FILE *fConsole = NULL;

static QSharedPointer<LogEmitter> le;

#define PATH_MAX 1024
static char crashhandler_fn[PATH_MAX];

@@ -37,10 +40,14 @@ static void mumbleMessageOutputQString(QtMsgType type, const QString &msg) {
#define LOG(f, msg) fprintf(f, "<%c>%s %s\n", c, \
qPrintable(QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"))), qPrintable(msg))

LOG(stderr, msg);
LOG(fConsole, msg);
QString date = QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"));
QString fmsg = QString::fromLatin1("<%1>%2 %3").arg(c).arg(date).arg(msg);
fprintf(stderr, "%s\n", qPrintable(fmsg));
fprintf(fConsole, "%s\n", qPrintable(fmsg));
fflush(fConsole);

le->addLogEntry(fmsg);

if (type == QtFatalMsg) {
CFStringRef csMsg = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s\n\nThe error has been logged. Please submit your log file to the Mumble project if the problem persists."), qPrintable(msg));
CFUserNotificationDisplayAlert(0, 0, NULL, NULL, NULL, CFSTR("Mumble has encountered a fatal error"), csMsg, CFSTR("OK"), NULL, NULL, NULL);
@@ -130,6 +137,11 @@ void os_init() {
const char *home = getenv("HOME");
const char *logpath = "/Library/Logs/Mumble.log";

// Make a copy of the global LogEmitter, such that
// os_macx.mm doesn't have to consider the deletion
// of the Global object and its LogEmitter object.
le = g.le;

if (home) {
size_t len = strlen(home) + strlen(logpath) + 1;
STACKVAR(char, buff, len);
@@ -0,0 +1,65 @@
// Copyright 2005-2016 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

#include "mumble_pch.hpp"
#include "LogEmitter.h"
#include "Global.h"

static QSharedPointer<LogEmitter> le;

static void mumbleMessageOutputQString(QtMsgType type, const QString &msg) {
char c;

switch (type) {
case QtDebugMsg:
c='D';
break;
case QtWarningMsg:
c='W';
break;
case QtFatalMsg:
c='F';
break;
default:
c='X';
}

#define LOG(f, msg) fprintf(f, "<%c>%s %s\n", c, \
qPrintable(QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"))), qPrintable(msg))

QString date = QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"));
QString fmsg = QString::fromLatin1("<%1>%2 %3").arg(c).arg(date).arg(msg);
fprintf(stderr, "%s\n", qPrintable(fmsg));

le->addLogEntry(fmsg);

if (type == QtFatalMsg) {
exit(1);
}
}

#if QT_VERSION < 0x050000
static void mumbleMessageOutput(QtMsgType type, const char *msg) {
mumbleMessageOutputQString(type, QString::fromUtf8(msg));
}
#elif QT_VERSION >= 0x050000
static void mumbleMessageOutputWithContext(QtMsgType type, const QMessageLogContext &ctx, const QString &msg) {
Q_UNUSED(ctx);
mumbleMessageOutputQString(type, msg);
}
#endif

void os_init() {
// Make a copy of the global LogEmitter, such that
// os_unix.cpp doesn't have to consider the deletion
// of the Global object and its LogEmitter object.
le = g.le;

#if QT_VERSION >= 0x050000
qInstallMessageHandler(mumbleMessageOutputWithContext);
#else
qInstallMsgHandler(mumbleMessageOutput);
#endif
}
@@ -13,6 +13,7 @@

#include "Global.h"
#include "Version.h"
#include "LogEmitter.h"

extern "C" {
void __cpuid(int a[4], int b);
@@ -27,6 +28,8 @@ static FILE *fConsole = NULL;
static wchar_t wcComment[PATH_MAX] = L"";
static MINIDUMP_USER_STREAM musComment;

static QSharedPointer<LogEmitter> le;

static int cpuinfo[4];

bool bIsWin7 = false;
@@ -49,9 +52,12 @@ static void mumbleMessageOutputQString(QtMsgType type, const QString &msg) {
default:
c='X';
}
fprintf(fConsole, "<%c>%s %s\n", c, qPrintable(QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"))), qPrintable(msg));
QString date = QDateTime::currentDateTime().toString(QLatin1String("yyyy-MM-dd hh:mm:ss.zzz"));
QString fmsg = QString::fromLatin1("<%1>%2 %3").arg(c).arg(date).arg(msg);
fprintf(fConsole, "%s\n", qPrintable(fmsg));
fflush(fConsole);
OutputDebugStringA(qPrintable(msg));
OutputDebugStringA(qPrintable(fmsg));
le->addLogEntry(fmsg);
if (type == QtFatalMsg) {
::MessageBoxA(NULL, qPrintable(msg), "Mumble", MB_OK | MB_ICONERROR);
exit(0);
@@ -231,6 +237,11 @@ void os_init() {
enableCrashOnCrashes();
mumble_speex_init();

// Make a copy of the global LogEmitter, such that
// os_win.cpp doesn't have to consider the deletion
// of the Global object and its LogEmitter object.
le = g.le;

#ifdef QT_NO_DEBUG
QString console = g.qdBasePath.filePath(QLatin1String("Console.txt"));
fConsole = _wfsopen(console.toStdWString().c_str(), L"a+", _SH_DENYWR);

0 comments on commit 6ac0553

Please sign in to comment.
You can’t perform that action at this time.