commit
478f1de846
|
@ -244,7 +244,8 @@ set(obs_SOURCES
|
|||
source-label.cpp
|
||||
remote-text.cpp
|
||||
audio-encoders.cpp
|
||||
qt-wrappers.cpp)
|
||||
qt-wrappers.cpp
|
||||
log-viewer.cpp)
|
||||
|
||||
set(obs_HEADERS
|
||||
${obs_PLATFORM_HEADERS}
|
||||
|
@ -308,7 +309,8 @@ set(obs_HEADERS
|
|||
remote-text.hpp
|
||||
audio-encoders.hpp
|
||||
qt-wrappers.hpp
|
||||
clickable-label.hpp)
|
||||
clickable-label.hpp
|
||||
log-viewer.hpp)
|
||||
|
||||
set(obs_importers_HEADERS
|
||||
importers/importers.hpp)
|
||||
|
|
|
@ -94,6 +94,8 @@ Windowed="Windowed"
|
|||
Percent="Percent"
|
||||
AspectRatio="Aspect Ratio <b>%1:%2</b>"
|
||||
LockVolume="Lock Volume"
|
||||
LogViewer="Log Viewer"
|
||||
ShowOnStartup="Show on startup"
|
||||
|
||||
# warning if program already open
|
||||
AlreadyRunning.Title="OBS is already running"
|
||||
|
|
|
@ -1768,6 +1768,17 @@
|
|||
<string>Basic.MainMenu.View.SourceIcons</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="toggleLog">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>LogViewer</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
#include <QScrollBar>
|
||||
#include <QFont>
|
||||
#include <QFontDatabase>
|
||||
#include <QPushButton>
|
||||
#include <QCheckBox>
|
||||
#include <QLayout>
|
||||
#include <string>
|
||||
|
||||
#include "log-viewer.hpp"
|
||||
#include "qt-wrappers.hpp"
|
||||
|
||||
OBSLogViewer::OBSLogViewer(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout();
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
const QFont fixedFont =
|
||||
QFontDatabase::systemFont(QFontDatabase::FixedFont);
|
||||
|
||||
textArea = new QTextEdit();
|
||||
textArea->setReadOnly(true);
|
||||
textArea->setFont(fixedFont);
|
||||
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout();
|
||||
QPushButton *clearButton = new QPushButton(QTStr("Clear"));
|
||||
connect(clearButton, &QPushButton::clicked, this,
|
||||
&OBSLogViewer::ClearText);
|
||||
QPushButton *closeButton = new QPushButton(QTStr("Close"));
|
||||
connect(closeButton, &QPushButton::clicked, this, &QDialog::hide);
|
||||
|
||||
QCheckBox *showStartup = new QCheckBox(QTStr("ShowOnStartup"));
|
||||
showStartup->setChecked(ShowOnStartup());
|
||||
connect(showStartup, SIGNAL(toggled(bool)), this,
|
||||
SLOT(ToggleShowStartup(bool)));
|
||||
|
||||
buttonLayout->addSpacing(10);
|
||||
buttonLayout->addWidget(showStartup);
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(clearButton);
|
||||
buttonLayout->addWidget(closeButton);
|
||||
buttonLayout->addSpacing(10);
|
||||
buttonLayout->setContentsMargins(0, 0, 0, 4);
|
||||
|
||||
layout->addWidget(textArea);
|
||||
layout->addLayout(buttonLayout);
|
||||
setLayout(layout);
|
||||
|
||||
setWindowTitle(QTStr("LogViewer"));
|
||||
resize(800, 300);
|
||||
|
||||
const char *geom = config_get_string(App()->GlobalConfig(), "LogViewer",
|
||||
"geometry");
|
||||
|
||||
if (geom != nullptr) {
|
||||
QByteArray ba = QByteArray::fromBase64(QByteArray(geom));
|
||||
restoreGeometry(ba);
|
||||
}
|
||||
|
||||
InitLog();
|
||||
}
|
||||
|
||||
OBSLogViewer::~OBSLogViewer()
|
||||
{
|
||||
config_set_string(App()->GlobalConfig(), "LogViewer", "geometry",
|
||||
saveGeometry().toBase64().constData());
|
||||
}
|
||||
|
||||
void OBSLogViewer::ToggleShowStartup(bool checked)
|
||||
{
|
||||
config_set_bool(App()->GlobalConfig(), "LogViewer", "ShowLogStartup",
|
||||
checked);
|
||||
}
|
||||
|
||||
bool OBSLogViewer::ShowOnStartup()
|
||||
{
|
||||
return config_get_bool(App()->GlobalConfig(), "LogViewer",
|
||||
"ShowLogStartup");
|
||||
}
|
||||
|
||||
extern QPointer<OBSLogViewer> obsLogViewer;
|
||||
|
||||
void OBSLogViewer::InitLog()
|
||||
{
|
||||
char logDir[512];
|
||||
std::string path;
|
||||
|
||||
if (GetConfigPath(logDir, sizeof(logDir), "obs-studio/logs")) {
|
||||
path += logDir;
|
||||
path += "/";
|
||||
path += App()->GetCurrentLog();
|
||||
}
|
||||
|
||||
QFile file(QT_UTF8(path.c_str()));
|
||||
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QTextStream in(&file);
|
||||
|
||||
while (!in.atEnd()) {
|
||||
QString line = in.readLine();
|
||||
AddLine(LOG_INFO, line);
|
||||
}
|
||||
|
||||
file.close();
|
||||
}
|
||||
|
||||
obsLogViewer = this;
|
||||
}
|
||||
|
||||
void OBSLogViewer::AddLine(int type, const QString &str)
|
||||
{
|
||||
QString msg = str.toHtmlEscaped();
|
||||
|
||||
switch (type) {
|
||||
case LOG_WARNING:
|
||||
msg = QStringLiteral("<font color=\"#c08000\">") + msg +
|
||||
QStringLiteral("</font>");
|
||||
break;
|
||||
case LOG_ERROR:
|
||||
msg = QStringLiteral("<font color=\"#c00000\">") + msg +
|
||||
QStringLiteral("</font>");
|
||||
break;
|
||||
}
|
||||
|
||||
QScrollBar *scroll = textArea->verticalScrollBar();
|
||||
bool bottomScrolled = scroll->value() >= scroll->maximum() - 10;
|
||||
|
||||
if (bottomScrolled)
|
||||
scroll->setValue(scroll->maximum());
|
||||
|
||||
QTextCursor newCursor = textArea->textCursor();
|
||||
newCursor.movePosition(QTextCursor::End);
|
||||
newCursor.insertHtml(msg + QStringLiteral("<br>"));
|
||||
|
||||
if (bottomScrolled)
|
||||
scroll->setValue(scroll->maximum());
|
||||
}
|
||||
|
||||
void OBSLogViewer::ClearText()
|
||||
{
|
||||
textArea->clear();
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
#include <QTextEdit>
|
||||
#include "obs-app.hpp"
|
||||
|
||||
class OBSLogViewer : public QDialog {
|
||||
Q_OBJECT
|
||||
|
||||
QPointer<QTextEdit> textArea;
|
||||
|
||||
void InitLog();
|
||||
|
||||
private slots:
|
||||
void AddLine(int type, const QString &text);
|
||||
void ClearText();
|
||||
void ToggleShowStartup(bool checked);
|
||||
|
||||
public:
|
||||
OBSLogViewer(QWidget *parent = 0);
|
||||
~OBSLogViewer();
|
||||
|
||||
bool ShowOnStartup();
|
||||
};
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "qt-wrappers.hpp"
|
||||
#include "obs-app.hpp"
|
||||
#include "log-viewer.hpp"
|
||||
#include "window-basic-main.hpp"
|
||||
#include "window-basic-settings.hpp"
|
||||
#include "crash-report.hpp"
|
||||
|
@ -89,6 +90,8 @@ string remuxFilename;
|
|||
|
||||
bool restart = false;
|
||||
|
||||
QPointer<OBSLogViewer> obsLogViewer;
|
||||
|
||||
// GPU hint exports for AMD/NVIDIA laptops
|
||||
#ifdef _MSC_VER
|
||||
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
|
||||
|
@ -250,12 +253,22 @@ string CurrentDateTimeString()
|
|||
}
|
||||
|
||||
static inline void LogString(fstream &logFile, const char *timeString,
|
||||
char *str)
|
||||
char *str, int log_level)
|
||||
{
|
||||
logFile << timeString << str << endl;
|
||||
string msg;
|
||||
msg += timeString;
|
||||
msg += str;
|
||||
|
||||
logFile << msg << endl;
|
||||
|
||||
if (!!obsLogViewer)
|
||||
QMetaObject::invokeMethod(obsLogViewer.data(), "AddLine",
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(int, log_level),
|
||||
Q_ARG(QString, QString(msg.c_str())));
|
||||
}
|
||||
|
||||
static inline void LogStringChunk(fstream &logFile, char *str)
|
||||
static inline void LogStringChunk(fstream &logFile, char *str, int log_level)
|
||||
{
|
||||
char *nextLine = str;
|
||||
string timeString = CurrentTimeString();
|
||||
|
@ -272,12 +285,12 @@ static inline void LogStringChunk(fstream &logFile, char *str)
|
|||
nextLine[0] = 0;
|
||||
}
|
||||
|
||||
LogString(logFile, timeString.c_str(), str);
|
||||
LogString(logFile, timeString.c_str(), str, log_level);
|
||||
nextLine++;
|
||||
str = nextLine;
|
||||
}
|
||||
|
||||
LogString(logFile, timeString.c_str(), str);
|
||||
LogString(logFile, timeString.c_str(), str, log_level);
|
||||
}
|
||||
|
||||
#define MAX_REPEATED_LINES 30
|
||||
|
@ -368,7 +381,7 @@ static void do_log(int log_level, const char *msg, va_list args, void *param)
|
|||
if (log_level <= LOG_INFO || log_verbose) {
|
||||
if (too_many_repeated_entries(logFile, msg, str))
|
||||
return;
|
||||
LogStringChunk(logFile, str);
|
||||
LogStringChunk(logFile, str, log_level);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && defined(OBS_DEBUGBREAK_ON_ERROR)
|
||||
|
|
|
@ -190,6 +190,9 @@ extern void RegisterRestreamAuth();
|
|||
OBSBasic::OBSBasic(QWidget *parent)
|
||||
: OBSMainWindow(parent), ui(new Ui::OBSBasic)
|
||||
{
|
||||
/* setup log viewer */
|
||||
logView = new OBSLogViewer();
|
||||
|
||||
qRegisterMetaTypeStreamOperators<SignalContainer<OBSScene>>(
|
||||
"SignalContainer<OBSScene>");
|
||||
|
||||
|
@ -377,6 +380,7 @@ OBSBasic::OBSBasic(QWidget *parent)
|
|||
}
|
||||
|
||||
QPoint curSize(width(), height());
|
||||
|
||||
QPoint statsDockSize(statsDock->width(), statsDock->height());
|
||||
QPoint statsDockPos = curSize / 2 - statsDockSize / 2;
|
||||
QPoint newPos = curPos + statsDockPos;
|
||||
|
@ -1926,6 +1930,9 @@ void OBSBasic::OnFirstLoad()
|
|||
#endif
|
||||
|
||||
Auth::Load();
|
||||
|
||||
if (logView && logView->ShowOnStartup())
|
||||
logView->show();
|
||||
}
|
||||
|
||||
void OBSBasic::DeferredSysTrayLoad(int requeueCount)
|
||||
|
@ -2398,6 +2405,7 @@ OBSBasic::~OBSBasic()
|
|||
updateCheckThread->wait();
|
||||
|
||||
delete screenshotData;
|
||||
delete logView;
|
||||
delete multiviewProjectorMenu;
|
||||
delete previewProjector;
|
||||
delete studioProgramProjector;
|
||||
|
@ -5183,18 +5191,7 @@ void OBSBasic::on_actionUploadLastLog_triggered()
|
|||
|
||||
void OBSBasic::on_actionViewCurrentLog_triggered()
|
||||
{
|
||||
char logDir[512];
|
||||
if (GetConfigPath(logDir, sizeof(logDir), "obs-studio/logs") <= 0)
|
||||
return;
|
||||
|
||||
const char *log = App()->GetCurrentLog();
|
||||
|
||||
string path = logDir;
|
||||
path += "/";
|
||||
path += log;
|
||||
|
||||
QUrl url = QUrl::fromLocalFile(QT_UTF8(path.c_str()));
|
||||
QDesktopServices::openUrl(url);
|
||||
logView->setVisible(!logView->isVisible());
|
||||
}
|
||||
|
||||
void OBSBasic::on_actionShowCrashLogs_triggered()
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "window-projector.hpp"
|
||||
#include "window-basic-about.hpp"
|
||||
#include "auth-base.hpp"
|
||||
#include "log-viewer.hpp"
|
||||
|
||||
#include <obs-frontend-internal.hpp>
|
||||
|
||||
|
@ -210,6 +211,8 @@ private:
|
|||
QPointer<QDockWidget> statsDock;
|
||||
QPointer<OBSAbout> about;
|
||||
|
||||
OBSLogViewer *logView;
|
||||
|
||||
QPointer<QTimer> cpuUsageTimer;
|
||||
QPointer<QTimer> diskFullTimer;
|
||||
|
||||
|
|
Loading…
Reference in New Issue