mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add a viewer of the diagnostic log in the UI itself
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
#include "Windows/Dialogs/LiveCapture.h"
|
||||
#include "Windows/Dialogs/SettingsDialog.h"
|
||||
#include "Windows/EventBrowser.h"
|
||||
#include "Windows/LogView.h"
|
||||
#include "Windows/MainWindow.h"
|
||||
#include "Windows/PerformanceCounterViewer.h"
|
||||
#include "Windows/PipelineState/PipelineStateViewer.h"
|
||||
@@ -1896,6 +1897,18 @@ IDebugMessageView *CaptureContext::GetDebugMessageView()
|
||||
return m_DebugMessageView;
|
||||
}
|
||||
|
||||
IDiagnosticLogView *CaptureContext::GetDiagnosticLogView()
|
||||
{
|
||||
if(m_DiagnosticLogView)
|
||||
return m_DiagnosticLogView;
|
||||
|
||||
m_DiagnosticLogView = new LogView(*this, m_MainWindow);
|
||||
m_DiagnosticLogView->setObjectName(lit("diagnosticLogView"));
|
||||
setupDockWindow(m_DiagnosticLogView);
|
||||
|
||||
return m_DiagnosticLogView;
|
||||
}
|
||||
|
||||
ICommentView *CaptureContext::GetCommentView()
|
||||
{
|
||||
if(m_CommentView)
|
||||
@@ -2003,6 +2016,11 @@ void CaptureContext::ShowDebugMessageView()
|
||||
m_MainWindow->showDebugMessageView();
|
||||
}
|
||||
|
||||
void CaptureContext::ShowDiagnosticLogView()
|
||||
{
|
||||
m_MainWindow->showDiagnosticLogView();
|
||||
}
|
||||
|
||||
void CaptureContext::ShowCommentView()
|
||||
{
|
||||
m_MainWindow->showCommentView();
|
||||
@@ -2122,6 +2140,10 @@ QWidget *CaptureContext::CreateBuiltinWindow(const rdcstr &objectName)
|
||||
{
|
||||
return GetDebugMessageView()->Widget();
|
||||
}
|
||||
else if(objectName == "diagnosticLogView")
|
||||
{
|
||||
return GetDiagnosticLogView()->Widget();
|
||||
}
|
||||
else if(objectName == "commentView")
|
||||
{
|
||||
return GetCommentView()->Widget();
|
||||
@@ -2166,6 +2188,8 @@ void CaptureContext::BuiltinWindowClosed(QWidget *window)
|
||||
m_MeshPreview = NULL;
|
||||
else if(m_DebugMessageView && m_DebugMessageView->Widget() == window)
|
||||
m_DebugMessageView = NULL;
|
||||
else if(m_DiagnosticLogView && m_DiagnosticLogView->Widget() == window)
|
||||
m_DiagnosticLogView = NULL;
|
||||
else if(m_CommentView && m_CommentView->Widget() == window)
|
||||
m_CommentView = NULL;
|
||||
else if(m_StatisticsViewer && m_StatisticsViewer->Widget() == window)
|
||||
|
||||
@@ -45,6 +45,7 @@ class BufferViewer;
|
||||
class TextureViewer;
|
||||
class CaptureDialog;
|
||||
class DebugMessageView;
|
||||
class LogView;
|
||||
class CommentView;
|
||||
class PerformanceCounterViewer;
|
||||
class StatisticsViewer;
|
||||
@@ -193,6 +194,7 @@ public:
|
||||
IPipelineStateViewer *GetPipelineViewer() override;
|
||||
ICaptureDialog *GetCaptureDialog() override;
|
||||
IDebugMessageView *GetDebugMessageView() override;
|
||||
IDiagnosticLogView *GetDiagnosticLogView() override;
|
||||
ICommentView *GetCommentView() override;
|
||||
IPerformanceCounterViewer *GetPerformanceCounterViewer() override;
|
||||
IStatisticsViewer *GetStatisticsViewer() override;
|
||||
@@ -207,6 +209,7 @@ public:
|
||||
bool HasMeshPreview() override { return m_MeshPreview != NULL; }
|
||||
bool HasCaptureDialog() override { return m_CaptureDialog != NULL; }
|
||||
bool HasDebugMessageView() override { return m_DebugMessageView != NULL; }
|
||||
bool HasDiagnosticLogView() override { return m_DiagnosticLogView != NULL; }
|
||||
bool HasCommentView() override { return m_CommentView != NULL; }
|
||||
bool HasPerformanceCounterViewer() override { return m_PerformanceCounterViewer != NULL; }
|
||||
bool HasStatisticsViewer() override { return m_StatisticsViewer != NULL; }
|
||||
@@ -220,6 +223,7 @@ public:
|
||||
void ShowPipelineViewer() override;
|
||||
void ShowCaptureDialog() override;
|
||||
void ShowDebugMessageView() override;
|
||||
void ShowDiagnosticLogView() override;
|
||||
void ShowCommentView() override;
|
||||
void ShowPerformanceCounterViewer() override;
|
||||
void ShowStatisticsViewer() override;
|
||||
@@ -383,6 +387,7 @@ private:
|
||||
PipelineStateViewer *m_PipelineViewer = NULL;
|
||||
CaptureDialog *m_CaptureDialog = NULL;
|
||||
DebugMessageView *m_DebugMessageView = NULL;
|
||||
LogView *m_DiagnosticLogView = NULL;
|
||||
CommentView *m_CommentView = NULL;
|
||||
PerformanceCounterViewer *m_PerformanceCounterViewer = NULL;
|
||||
StatisticsViewer *m_StatisticsViewer = NULL;
|
||||
|
||||
@@ -238,7 +238,7 @@ void PersistantConfig::AddAndroidHosts()
|
||||
SetConfigSetting("MaxConnectTimeout", QString::number(Android_MaxConnectTimeout));
|
||||
|
||||
rdcstr androidHosts;
|
||||
RENDERDOC_EnumerateAndroidDevices(&androidHosts);
|
||||
RENDERDOC_EnumerateAndroidDevices(androidHosts);
|
||||
for(const QString &hostName :
|
||||
QString(androidHosts).split(QLatin1Char(','), QString::SkipEmptyParts))
|
||||
{
|
||||
|
||||
@@ -441,6 +441,22 @@ protected:
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(IDebugMessageView);
|
||||
|
||||
DOCUMENT("The diagnostic log viewing window.");
|
||||
struct IDiagnosticLogView
|
||||
{
|
||||
DOCUMENT(
|
||||
"Retrieves the QWidget for this :class:`DiagnosticLogView` if PySide2 is available, or "
|
||||
"otherwise unique opaque pointer that can be passed to RenderDoc functions expecting a "
|
||||
"QWidget.");
|
||||
virtual QWidget *Widget() = 0;
|
||||
|
||||
protected:
|
||||
IDiagnosticLogView() = default;
|
||||
~IDiagnosticLogView() = default;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(IDiagnosticLogView);
|
||||
|
||||
DOCUMENT("The capture comments window.");
|
||||
struct ICommentView
|
||||
{
|
||||
@@ -1597,6 +1613,13 @@ If no bookmark exists, this function will do nothing.
|
||||
)");
|
||||
virtual IDebugMessageView *GetDebugMessageView() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the current singleton :class:`LogView`.
|
||||
|
||||
:return: The current window, which is created (but not shown) it there wasn't one open.
|
||||
:rtype: LogView
|
||||
)");
|
||||
virtual IDiagnosticLogView *GetDiagnosticLogView() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the current singleton :class:`CommentView`.
|
||||
|
||||
:return: The current window, which is created (but not shown) it there wasn't one open.
|
||||
@@ -1688,6 +1711,13 @@ If no bookmark exists, this function will do nothing.
|
||||
)");
|
||||
virtual bool HasDebugMessageView() = 0;
|
||||
|
||||
DOCUMENT(R"(Check if there is a current :class:`DiagnosticLogView` open.
|
||||
|
||||
:return: ``True`` if there is a window open.
|
||||
:rtype: ``bool``
|
||||
)");
|
||||
virtual bool HasDiagnosticLogView() = 0;
|
||||
|
||||
DOCUMENT(R"(Check if there is a current :class:`CommentView` open.
|
||||
|
||||
:return: ``True`` if there is a window open.
|
||||
@@ -1748,6 +1778,9 @@ place if needed.
|
||||
DOCUMENT(
|
||||
"Raise the current :class:`DebugMessageView`, showing it in the default place if needed.");
|
||||
virtual void ShowDebugMessageView() = 0;
|
||||
DOCUMENT(
|
||||
"Raise the current :class:`DiagnosticLogView`, showing it in the default place if needed.");
|
||||
virtual void ShowDiagnosticLogView() = 0;
|
||||
DOCUMENT("Raise the current :class:`CommentView`, showing it in the default place if needed.");
|
||||
virtual void ShowCommentView() = 0;
|
||||
DOCUMENT(
|
||||
|
||||
@@ -165,9 +165,8 @@ void RDTreeView::leaveEvent(QEvent *e)
|
||||
|
||||
void RDTreeView::keyPressEvent(QKeyEvent *e)
|
||||
{
|
||||
emit(keyPress(e));
|
||||
|
||||
QTreeView::keyPressEvent(e);
|
||||
emit(keyPress(e));
|
||||
}
|
||||
|
||||
bool RDTreeView::viewportEvent(QEvent *event)
|
||||
|
||||
@@ -67,7 +67,6 @@ private:
|
||||
Ui::DebugMessageView *ui;
|
||||
ICaptureContext &m_Ctx;
|
||||
|
||||
QVector<DebugMessage> m_Messages;
|
||||
DebugMessageItemModel *m_ItemModel;
|
||||
DebugMessageFilterModel *m_FilterModel;
|
||||
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017-2019 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "LogView.h"
|
||||
#include <QClipboard>
|
||||
#include <QDesktopServices>
|
||||
#include <QFontDatabase>
|
||||
#include <QStandardItemModel>
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "Widgets/Extended/RDHeaderView.h"
|
||||
#include "ui_LogView.h"
|
||||
|
||||
enum Columns
|
||||
{
|
||||
Column_Source,
|
||||
Column_PID,
|
||||
Column_Timestamp,
|
||||
Column_Location,
|
||||
Column_Type,
|
||||
Column_Message,
|
||||
Column_Count,
|
||||
};
|
||||
|
||||
class LogItemModel : public QAbstractItemModel
|
||||
{
|
||||
public:
|
||||
LogItemModel(LogView *view) : QAbstractItemModel(view), m_Viewer(view) {}
|
||||
void refresh()
|
||||
{
|
||||
emit beginResetModel();
|
||||
emit endResetModel();
|
||||
}
|
||||
|
||||
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
if(row < 0 || row >= rowCount())
|
||||
return QModelIndex();
|
||||
|
||||
return createIndex(row, column);
|
||||
}
|
||||
|
||||
QModelIndex parent(const QModelIndex &index) const override { return QModelIndex(); }
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
if(parent == QModelIndex())
|
||||
return m_Viewer->m_Messages.count();
|
||||
return 0;
|
||||
}
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override { return Column_Count; }
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
||||
{
|
||||
if(!index.isValid())
|
||||
return 0;
|
||||
|
||||
return QAbstractItemModel::flags(index);
|
||||
}
|
||||
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override
|
||||
{
|
||||
if(orientation == Qt::Horizontal && role == Qt::DisplayRole)
|
||||
{
|
||||
switch(section)
|
||||
{
|
||||
case Column_Source: return lit("Source");
|
||||
case Column_PID: return lit("PID");
|
||||
case Column_Timestamp: return lit("Timestamp");
|
||||
case Column_Location: return lit("Location");
|
||||
case Column_Type: return lit("Type");
|
||||
case Column_Message: return lit("Message");
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
|
||||
{
|
||||
if(index.isValid())
|
||||
{
|
||||
int row = index.row();
|
||||
int col = index.column();
|
||||
|
||||
if(col >= 0 && col < columnCount() && row < rowCount())
|
||||
{
|
||||
const LogMessage &msg = m_Viewer->m_Messages[row];
|
||||
|
||||
if(role == Qt::DisplayRole)
|
||||
{
|
||||
switch(col)
|
||||
{
|
||||
case Column_Source: return msg.Source;
|
||||
case Column_PID: return QString::number(msg.PID);
|
||||
case Column_Timestamp: return msg.Timestamp.toString(lit("HH:mm:ss"));
|
||||
case Column_Location: return msg.Location;
|
||||
case Column_Type: return ToQStr(msg.Type);
|
||||
case Column_Message:
|
||||
{
|
||||
QVariant desc = msg.Message;
|
||||
RichResourceTextInitialise(desc);
|
||||
return desc;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else if(msg.Type == LogType::Error)
|
||||
{
|
||||
if(role == Qt::BackgroundRole)
|
||||
return QBrush(QColor(255, 70, 70));
|
||||
if(role == Qt::ForegroundRole)
|
||||
return QBrush(QColor(0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
private:
|
||||
LogView *m_Viewer;
|
||||
};
|
||||
|
||||
class LogFilterModel : public QSortFilterProxyModel
|
||||
{
|
||||
public:
|
||||
LogFilterModel(LogView *view) : QSortFilterProxyModel(view), m_Viewer(view) {}
|
||||
bool m_UseRegexp = false;
|
||||
bool m_IncludeTextMatches = true;
|
||||
QString m_FilterText;
|
||||
QRegularExpression m_FilterRegexp;
|
||||
QSet<uint32_t> m_HiddenPIDs;
|
||||
QSet<uint32_t> m_HiddenTypes;
|
||||
|
||||
void refresh() { invalidateFilter(); }
|
||||
protected:
|
||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
|
||||
{
|
||||
return isVisibleRow(sourceRow);
|
||||
}
|
||||
|
||||
bool isVisibleRow(int sourceRow) const
|
||||
{
|
||||
const LogMessage &msg = m_Viewer->m_Messages[sourceRow];
|
||||
|
||||
if(m_HiddenPIDs.contains(msg.PID))
|
||||
return false;
|
||||
|
||||
if(m_HiddenTypes.contains((uint32_t)msg.Type))
|
||||
return false;
|
||||
|
||||
if(m_UseRegexp)
|
||||
{
|
||||
if(m_FilterRegexp.isValid())
|
||||
{
|
||||
return (m_FilterRegexp.match(msg.Message).hasMatch()) == m_IncludeTextMatches;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!m_FilterText.isEmpty())
|
||||
{
|
||||
return (msg.Message.contains(m_FilterText, Qt::CaseInsensitive)) == m_IncludeTextMatches;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
LogView *m_Viewer;
|
||||
};
|
||||
|
||||
static QList<QString> logTypeStrings;
|
||||
|
||||
LogView::LogView(ICaptureContext &ctx, QWidget *parent)
|
||||
: QFrame(parent), ui(new Ui::LogView), m_Ctx(ctx)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
m_ItemModel = new LogItemModel(this);
|
||||
m_FilterModel = new LogFilterModel(this);
|
||||
|
||||
m_FilterModel->setSourceModel(m_ItemModel);
|
||||
ui->messages->setModel(m_FilterModel);
|
||||
|
||||
ui->messages->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
|
||||
|
||||
m_TypeModel = new QStandardItemModel(0, 1, this);
|
||||
|
||||
m_TypeModel->appendRow(new QStandardItem(tr("Log Type")));
|
||||
|
||||
for(LogType type : values<LogType>())
|
||||
{
|
||||
// don't bother allowing fatal filtering. The UI is no longer running when one of these is
|
||||
// logged
|
||||
if(type == LogType::Fatal)
|
||||
continue;
|
||||
|
||||
logTypeStrings.push_back(ToQStr(type));
|
||||
|
||||
QStandardItem *item = new QStandardItem(ToQStr(type));
|
||||
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
||||
item->setData(Qt::Checked, Qt::CheckStateRole);
|
||||
m_TypeModel->appendRow(item);
|
||||
}
|
||||
|
||||
ui->typeFilter->setModel(m_TypeModel);
|
||||
|
||||
m_PIDModel = new QStandardItemModel(0, 1, this);
|
||||
|
||||
m_PIDModel->appendRow(new QStandardItem(tr("PID")));
|
||||
|
||||
ui->pidFilter->setModel(m_PIDModel);
|
||||
|
||||
{
|
||||
RDHeaderView *header = new RDHeaderView(Qt::Horizontal, this);
|
||||
ui->messages->setHeader(header);
|
||||
|
||||
header->setColumnStretchHints({-1, -1, -1, -1, -1, 1});
|
||||
}
|
||||
|
||||
messages_refresh();
|
||||
|
||||
QObject::connect(m_TypeModel, &QStandardItemModel::itemChanged, this, &LogView::typeFilter_changed);
|
||||
QObject::connect(m_PIDModel, &QStandardItemModel::itemChanged, this, &LogView::pidFilter_changed);
|
||||
|
||||
QObject::connect(ui->messages, &RDTreeView::keyPress, this, &LogView::messages_keyPress);
|
||||
|
||||
QObject::connect(&m_RefreshTimer, &QTimer::timeout, this, &LogView::messages_refresh);
|
||||
m_RefreshTimer.setSingleShot(false);
|
||||
m_RefreshTimer.setInterval(125);
|
||||
m_RefreshTimer.start();
|
||||
}
|
||||
|
||||
LogView::~LogView()
|
||||
{
|
||||
m_Ctx.BuiltinWindowClosed(this);
|
||||
|
||||
m_Messages.clear();
|
||||
m_ItemModel->refresh();
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void LogView::on_openExternal_clicked()
|
||||
{
|
||||
QString logPath = QString::fromUtf8(RENDERDOC_GetLogFile());
|
||||
if(QFileInfo::exists(logPath))
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(logPath));
|
||||
}
|
||||
|
||||
void LogView::on_save_clicked()
|
||||
{
|
||||
QString filename =
|
||||
RDDialog::getSaveFileName(this, tr("Export log to disk"), QString(),
|
||||
tr("Log Files (*.log);;Text files (*.txt);;All files (*)"));
|
||||
|
||||
if(filename.isEmpty())
|
||||
return;
|
||||
|
||||
QFile *f = new QFile(filename);
|
||||
|
||||
if(!f->open(QIODevice::WriteOnly | QFile::Truncate))
|
||||
{
|
||||
delete f;
|
||||
RDDialog::critical(this, tr("Error exporting log"),
|
||||
tr("Couldn't open file '%1' for writing").arg(filename));
|
||||
return;
|
||||
}
|
||||
|
||||
rdcstr contents;
|
||||
RENDERDOC_GetLogFileContents(contents);
|
||||
|
||||
f->write(QByteArray(contents.c_str(), contents.count()));
|
||||
|
||||
delete f;
|
||||
}
|
||||
|
||||
void LogView::on_textFilter_textChanged(const QString &text)
|
||||
{
|
||||
m_FilterModel->m_FilterText = text;
|
||||
m_FilterModel->m_FilterRegexp = QRegularExpression(text);
|
||||
m_FilterModel->m_FilterRegexp.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
|
||||
m_FilterModel->refresh();
|
||||
}
|
||||
|
||||
void LogView::on_textFilterMeaning_currentIndexChanged(int index)
|
||||
{
|
||||
// 0 is Include, 1 is Exclude
|
||||
m_FilterModel->m_IncludeTextMatches = (index == 0);
|
||||
m_FilterModel->refresh();
|
||||
}
|
||||
|
||||
void LogView::on_regexpFilter_toggled()
|
||||
{
|
||||
m_FilterModel->m_UseRegexp = ui->regexpFilter->isChecked();
|
||||
m_FilterModel->refresh();
|
||||
}
|
||||
|
||||
void LogView::messages_keyPress(QKeyEvent *event)
|
||||
{
|
||||
if(event->matches(QKeySequence::Copy))
|
||||
{
|
||||
QModelIndexList items = ui->messages->selectionModel()->selectedIndexes();
|
||||
|
||||
QList<int> rows;
|
||||
|
||||
for(QModelIndex idx : items)
|
||||
{
|
||||
if(!rows.contains(idx.row()))
|
||||
rows.push_back(idx.row());
|
||||
}
|
||||
|
||||
qSort(rows);
|
||||
|
||||
int columns = m_ItemModel->columnCount();
|
||||
|
||||
QString clipboardText;
|
||||
for(int r : rows)
|
||||
{
|
||||
const LogMessage &msg = m_Messages[r];
|
||||
|
||||
clipboardText += QFormatStr("%1 PID %2: [%3] %4 - %5 - %6\n")
|
||||
.arg(msg.Source, -8)
|
||||
.arg(msg.PID, 6)
|
||||
.arg(msg.Timestamp.toString(lit("HH:mm:ss")))
|
||||
.arg(msg.Location, 26)
|
||||
.arg(ToQStr(msg.Type), -7)
|
||||
.arg(msg.Message);
|
||||
}
|
||||
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
clipboard->setText(clipboardText.trimmed());
|
||||
}
|
||||
}
|
||||
|
||||
void LogView::typeFilter_changed(QStandardItem *item)
|
||||
{
|
||||
uint32_t type = m_TypeModel->indexFromItem(item).row() - 1;
|
||||
|
||||
if(item->checkState() == Qt::Checked)
|
||||
m_FilterModel->m_HiddenTypes.remove(type);
|
||||
else
|
||||
m_FilterModel->m_HiddenTypes.insert(type);
|
||||
|
||||
m_FilterModel->refresh();
|
||||
|
||||
ui->typeFilter->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void LogView::pidFilter_changed(QStandardItem *item)
|
||||
{
|
||||
uint32_t PID = item->text().toUInt();
|
||||
|
||||
if(item->checkState() == Qt::Checked)
|
||||
m_FilterModel->m_HiddenPIDs.remove(PID);
|
||||
else
|
||||
m_FilterModel->m_HiddenPIDs.insert(PID);
|
||||
|
||||
m_FilterModel->refresh();
|
||||
|
||||
ui->pidFilter->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
void LogView::messages_refresh()
|
||||
{
|
||||
rdcstr contents;
|
||||
RENDERDOC_GetLogFileContents(contents);
|
||||
|
||||
if(prevOffset == contents.size())
|
||||
return;
|
||||
|
||||
// look at all new lines since the last one we saw
|
||||
QStringList lines = QString(contents.substr(prevOffset)).split(QRegularExpression(lit("[\r\n]")));
|
||||
prevOffset = contents.size();
|
||||
|
||||
QString r =
|
||||
lit("^" // start of the line
|
||||
"([A-Z][A-Z][A-Z][A-Z]) " // project
|
||||
"([0-9]+): " // PID
|
||||
"\\[([0-9][0-9]):([0-9][0-9]):([0-9][0-9])\\] " // timestamp
|
||||
"\\s*([^(]+)\\(\\s*([0-9]+)\\) - " // filename.ext( line)
|
||||
"([A-Za-z]+)\\s+- " // type
|
||||
"(.*)");
|
||||
|
||||
QRegularExpression logRegex(r);
|
||||
|
||||
for(const QString &line : lines)
|
||||
{
|
||||
QRegularExpressionMatch match = logRegex.match(line);
|
||||
|
||||
if(match.hasMatch())
|
||||
{
|
||||
LogMessage msg;
|
||||
msg.Source = match.captured(1);
|
||||
|
||||
if(msg.Source == lit("ADRD"))
|
||||
msg.Source = tr("Android");
|
||||
else if(msg.Source == lit("QTRD"))
|
||||
msg.Source = tr("UI");
|
||||
else if(msg.Source == lit("RDOC"))
|
||||
msg.Source = tr("Core");
|
||||
|
||||
msg.PID = match.captured(2).toUInt();
|
||||
msg.Timestamp =
|
||||
QTime(match.captured(3).toUInt(), match.captured(4).toUInt(), match.captured(5).toUInt());
|
||||
msg.Location = QFormatStr("%1(%2)").arg(match.captured(6)).arg(match.captured(7));
|
||||
msg.Type = (LogType)logTypeStrings.indexOf(match.captured(8));
|
||||
msg.Message = match.captured(9).trimmed();
|
||||
|
||||
m_Messages.push_back(msg);
|
||||
|
||||
if(!m_PIDs.contains(msg.PID))
|
||||
{
|
||||
m_PIDs.append(msg.PID);
|
||||
QStandardItem *item = new QStandardItem(QString::number(msg.PID));
|
||||
item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
||||
item->setData(Qt::Checked, Qt::CheckStateRole);
|
||||
m_PIDModel->appendRow(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!lines.isEmpty())
|
||||
m_ItemModel->refresh();
|
||||
|
||||
if(ui->followNew->isChecked())
|
||||
ui->messages->scrollToBottom();
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/******************************************************************************
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017-2019 Baldur Karlsson
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
#include <QTimer>
|
||||
#include "Code/Interface/QRDInterface.h"
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class LogView;
|
||||
}
|
||||
|
||||
class QStandardItem;
|
||||
class QStandardItemModel;
|
||||
class QAction;
|
||||
class QMenu;
|
||||
class LogItemModel;
|
||||
class LogFilterModel;
|
||||
|
||||
struct LogMessage
|
||||
{
|
||||
QString Source;
|
||||
uint32_t PID;
|
||||
QTime Timestamp;
|
||||
QString Location;
|
||||
LogType Type;
|
||||
QString Message;
|
||||
};
|
||||
|
||||
class LogView : public QFrame, public IDiagnosticLogView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit LogView(ICaptureContext &ctx, QWidget *parent = 0);
|
||||
~LogView();
|
||||
|
||||
// ILogView
|
||||
QWidget *Widget() override { return this; }
|
||||
private slots:
|
||||
// automatic slots
|
||||
void on_openExternal_clicked();
|
||||
void on_save_clicked();
|
||||
void on_textFilter_textChanged(const QString &text);
|
||||
void on_textFilterMeaning_currentIndexChanged(int index);
|
||||
void on_regexpFilter_toggled();
|
||||
|
||||
// manual slots
|
||||
void messages_refresh();
|
||||
void messages_keyPress(QKeyEvent *event);
|
||||
void pidFilter_changed(QStandardItem *item);
|
||||
void typeFilter_changed(QStandardItem *item);
|
||||
|
||||
private:
|
||||
Ui::LogView *ui;
|
||||
ICaptureContext &m_Ctx;
|
||||
|
||||
size_t prevOffset = 0;
|
||||
|
||||
QVector<LogMessage> m_Messages;
|
||||
|
||||
QList<uint32_t> m_PIDs;
|
||||
|
||||
LogItemModel *m_ItemModel = NULL;
|
||||
LogFilterModel *m_FilterModel = NULL;
|
||||
|
||||
friend class LogItemModel;
|
||||
friend class LogFilterModel;
|
||||
|
||||
QStandardItemModel *m_PIDModel = NULL;
|
||||
QStandardItemModel *m_TypeModel = NULL;
|
||||
|
||||
QTimer m_RefreshTimer;
|
||||
};
|
||||
@@ -0,0 +1,316 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>LogView</class>
|
||||
<widget class="QFrame" name="LogView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>581</width>
|
||||
<height>404</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Diagnostic Log</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="spacing">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="followNew">
|
||||
<property name="text">
|
||||
<string>Follow new messages</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
<normaloff>:/arrow_refresh.png</normaloff>:/arrow_refresh.png</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="openExternal">
|
||||
<property name="text">
|
||||
<string>Open in external editor</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
<normaloff>:/action_hover.png</normaloff>:/action_hover.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="save">
|
||||
<property name="text">
|
||||
<string>Save</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../Resources/resources.qrc">
|
||||
<normaloff>:/save.png</normaloff>:/save.png</iconset>
|
||||
</property>
|
||||
<property name="toolButtonStyle">
|
||||
<enum>Qt::ToolButtonTextBesideIcon</enum>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="toolTipDuration">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Filter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="pidFilter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="typeFilter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||
</property>
|
||||
<property name="minimumContentsLength">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Text:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="textFilterMeaning">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maxVisibleItems">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Include</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Exclude</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="regexpFilter">
|
||||
<property name="text">
|
||||
<string>Regex</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="textFilter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="RDTreeView" name="messages">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="verticalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollBarPolicy">
|
||||
<enum>Qt::ScrollBarAlwaysOn</enum>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ContiguousSelection</enum>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="verticalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="horizontalScrollMode">
|
||||
<enum>QAbstractItemView::ScrollPerPixel</enum>
|
||||
</property>
|
||||
<property name="indentation">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="uniformRowHeights">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="itemsExpandable">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RDTreeView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>Widgets/Extended/RDTreeView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="../Resources/resources.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -2580,13 +2580,6 @@ void MainWindow::on_action_View_Documentation_triggered()
|
||||
QDesktopServices::openUrl(QUrl::fromUserInput(lit("https://renderdoc.org/docs")));
|
||||
}
|
||||
|
||||
void MainWindow::on_action_View_Diagnostic_Log_File_triggered()
|
||||
{
|
||||
QString logPath = QString::fromUtf8(RENDERDOC_GetLogFile());
|
||||
if(QFileInfo::exists(logPath))
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(logPath));
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Source_on_GitHub_triggered()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl::fromUserInput(lit("https://github.com/baldurk/renderdoc")));
|
||||
@@ -2603,6 +2596,16 @@ void MainWindow::on_action_Show_Tips_triggered()
|
||||
RDDialog::show(&tipsDialog);
|
||||
}
|
||||
|
||||
void MainWindow::on_action_View_Diagnostic_Log_File_triggered()
|
||||
{
|
||||
QWidget *logView = m_Ctx.GetDiagnosticLogView()->Widget();
|
||||
|
||||
if(ui->toolWindowManager->toolWindows().contains(logView))
|
||||
ToolWindowManager::raiseToolWindow(logView);
|
||||
else
|
||||
ui->toolWindowManager->addToolWindow(logView, mainToolArea());
|
||||
}
|
||||
|
||||
void MainWindow::on_action_Counter_Viewer_triggered()
|
||||
{
|
||||
QWidget *performanceCounterViewer = m_Ctx.GetPerformanceCounterViewer()->Widget();
|
||||
|
||||
@@ -101,6 +101,7 @@ public:
|
||||
void showPipelineViewer() { on_action_Pipeline_State_triggered(); }
|
||||
void showCaptureDialog() { on_action_Launch_Application_triggered(); }
|
||||
void showDebugMessageView() { on_action_Errors_and_Warnings_triggered(); }
|
||||
void showDiagnosticLogView() { on_action_View_Diagnostic_Log_File_triggered(); }
|
||||
void showCommentView() { on_action_Comments_triggered(); }
|
||||
void showStatisticsViewer() { on_action_Statistics_Viewer_triggered(); }
|
||||
void showTimelineBar() { on_action_Timeline_triggered(); }
|
||||
@@ -142,6 +143,7 @@ private slots:
|
||||
void on_action_Settings_triggered();
|
||||
void on_action_View_Documentation_triggered();
|
||||
void on_action_View_Diagnostic_Log_File_triggered();
|
||||
void on_action_Diagnostic_Log_triggered() { on_action_View_Diagnostic_Log_File_triggered(); }
|
||||
void on_action_Source_on_GitHub_triggered();
|
||||
void on_action_Build_Release_Downloads_triggered();
|
||||
void on_action_Show_Tips_triggered();
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
<addaction name="action_Counter_Viewer"/>
|
||||
<addaction name="action_Resource_Inspector"/>
|
||||
<addaction name="action_Comments"/>
|
||||
<addaction name="action_Diagnostic_Log"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="extension_dummy_Window"/>
|
||||
</widget>
|
||||
@@ -500,6 +501,11 @@
|
||||
<string>Manage Extensions</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Diagnostic_Log">
|
||||
<property name="text">
|
||||
<string>Dia&gnostic Log</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<customwidgets>
|
||||
|
||||
@@ -263,6 +263,10 @@ struct CaptureContextInvoker : ICaptureContext
|
||||
{
|
||||
return InvokeRetFunction<IDebugMessageView *>(&ICaptureContext::GetDebugMessageView);
|
||||
}
|
||||
virtual IDiagnosticLogView *GetDiagnosticLogView() override
|
||||
{
|
||||
return InvokeRetFunction<IDiagnosticLogView *>(&ICaptureContext::GetDiagnosticLogView);
|
||||
}
|
||||
virtual ICommentView *GetCommentView() override
|
||||
{
|
||||
return InvokeRetFunction<ICommentView *>(&ICaptureContext::GetCommentView);
|
||||
@@ -316,6 +320,10 @@ struct CaptureContextInvoker : ICaptureContext
|
||||
{
|
||||
return InvokeRetFunction<bool>(&ICaptureContext::HasDebugMessageView);
|
||||
}
|
||||
virtual bool HasDiagnosticLogView() override
|
||||
{
|
||||
return InvokeRetFunction<bool>(&ICaptureContext::HasDiagnosticLogView);
|
||||
}
|
||||
virtual bool HasCommentView() override
|
||||
{
|
||||
return InvokeRetFunction<bool>(&ICaptureContext::HasCommentView);
|
||||
@@ -366,6 +374,10 @@ struct CaptureContextInvoker : ICaptureContext
|
||||
{
|
||||
InvokeVoidFunction(&ICaptureContext::ShowDebugMessageView);
|
||||
}
|
||||
virtual void ShowDiagnosticLogView() override
|
||||
{
|
||||
InvokeVoidFunction(&ICaptureContext::ShowDiagnosticLogView);
|
||||
}
|
||||
virtual void ShowCommentView() override { InvokeVoidFunction(&ICaptureContext::ShowCommentView); }
|
||||
virtual void ShowPerformanceCounterViewer() override
|
||||
{
|
||||
|
||||
@@ -211,6 +211,7 @@ SOURCES += Code/qrenderdoc.cpp \
|
||||
Windows/BufferViewer.cpp \
|
||||
Widgets/Extended/RDTableView.cpp \
|
||||
Windows/DebugMessageView.cpp \
|
||||
Windows/LogView.cpp \
|
||||
Windows/CommentView.cpp \
|
||||
Windows/StatisticsViewer.cpp \
|
||||
Windows/TimelineBar.cpp \
|
||||
@@ -287,6 +288,7 @@ HEADERS += Code/CaptureContext.h \
|
||||
Windows/BufferViewer.h \
|
||||
Widgets/Extended/RDTableView.h \
|
||||
Windows/DebugMessageView.h \
|
||||
Windows/LogView.h \
|
||||
Windows/CommentView.h \
|
||||
Windows/StatisticsViewer.h \
|
||||
Windows/TimelineBar.h \
|
||||
@@ -331,6 +333,7 @@ FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/BufferViewer.ui \
|
||||
Windows/ShaderViewer.ui \
|
||||
Windows/DebugMessageView.ui \
|
||||
Windows/LogView.ui \
|
||||
Windows/CommentView.ui \
|
||||
Windows/StatisticsViewer.ui \
|
||||
Windows/Dialogs/SettingsDialog.ui \
|
||||
|
||||
@@ -606,6 +606,7 @@
|
||||
<ClCompile Include="$(IntDir)generated\moc_D3D11PipelineStateViewer.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_D3D12PipelineStateViewer.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_DebugMessageView.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_LogView.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_CommentView.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_EventBrowser.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_GLPipelineStateViewer.cpp" />
|
||||
@@ -716,6 +717,7 @@
|
||||
<ClCompile Include="Windows\BufferViewer.cpp" />
|
||||
<ClCompile Include="Windows\ConstantBufferPreviewer.cpp" />
|
||||
<ClCompile Include="Windows\DebugMessageView.cpp" />
|
||||
<ClCompile Include="Windows\LogView.cpp" />
|
||||
<ClCompile Include="Windows\CommentView.cpp" />
|
||||
<ClCompile Include="Windows\Dialogs\AboutDialog.cpp" />
|
||||
<ClCompile Include="Windows\Dialogs\CrashDialog.cpp" />
|
||||
@@ -930,6 +932,7 @@
|
||||
<ClInclude Include="$(IntDir)generated\ui_D3D11PipelineStateViewer.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_D3D12PipelineStateViewer.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_DebugMessageView.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_LogView.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_CommentView.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_EventBrowser.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_GLPipelineStateViewer.h" />
|
||||
@@ -1152,6 +1155,12 @@
|
||||
<Message>MOC %(Filename).h</Message>
|
||||
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\LogView.h">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>"$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\include" -I"$(ProjectDir)3rdparty\qt\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\include\QtGui" -I"$(ProjectDir)3rdparty\qt\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp"</Command>
|
||||
<Message>MOC %(Filename).h</Message>
|
||||
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\CommentView.h">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>"$(ProjectDir)3rdparty\qt\$(Platform)\bin\moc.exe" -DUNICODE -DWIN32 -DWIN64 -D_WIN32 -D_WIN64 -DRENDERDOC_PLATFORM_WIN32 -DSCINTILLA_QT=1 -DSCI_LEXER=1 -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -D_MSC_VER=1900 -I"$(ProjectDir)." -I"$(SolutionDir)\renderdoc\api\replay" -I"$(ProjectDir)3rdparty\qt\$(Platform)\mkspecs/win32-msvc2015" -I"$(ProjectDir)3rdparty\qt\include" -I"$(ProjectDir)3rdparty\qt\include\QtWidgets" -I"$(ProjectDir)3rdparty\qt\include\QtGui" -I"$(ProjectDir)3rdparty\qt\include\QtCore" "%(Fullpath)" -o "$(IntDir)generated\moc_%(Filename).cpp"</Command>
|
||||
@@ -1404,6 +1413,12 @@
|
||||
<Message>UIC %(Filename).ui</Message>
|
||||
<Outputs>$(IntDir)generated\ui_%(Filename).h</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\LogView.ui">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>"$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h"</Command>
|
||||
<Message>UIC %(Filename).ui</Message>
|
||||
<Outputs>$(IntDir)generated\ui_%(Filename).h</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\CommentView.ui">
|
||||
<AdditionalInputs>%(Fullpath);$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command>"$(ProjectDir)3rdparty\qt\$(Platform)\bin\uic.exe" "%(Fullpath)" -o "$(IntDir)generated\ui_%(Filename).h"</Command>
|
||||
|
||||
@@ -717,6 +717,12 @@
|
||||
<ClCompile Include="Windows\Dialogs\ExtensionManager.cpp">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Windows\LogView.cpp">
|
||||
<Filter>Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)generated\moc_LogView.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
|
||||
@@ -1070,6 +1076,9 @@
|
||||
<ClInclude Include="Code\Interface\Extensions.h">
|
||||
<Filter>Code\Interface</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(IntDir)generated\ui_LogView.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Code\pyrenderdoc\pyconversion.h">
|
||||
@@ -1451,6 +1460,12 @@
|
||||
<CustomBuild Include="Windows\Dialogs\ExtensionManager.h">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\LogView.ui">
|
||||
<Filter>Windows</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Windows\LogView.h">
|
||||
<Filter>Windows</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="Resources\action.png">
|
||||
|
||||
@@ -564,7 +564,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(cons
|
||||
friendly = Android::GetFriendlyName(deviceID);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr *deviceList)
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr &deviceList)
|
||||
{
|
||||
std::string adbStdout = Android::adbExecCommand("", "devices", ".", true).strStdout;
|
||||
|
||||
@@ -592,7 +592,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdc
|
||||
}
|
||||
}
|
||||
|
||||
*deviceList = ret;
|
||||
deviceList = ret;
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_AndroidInitialise()
|
||||
|
||||
@@ -2293,6 +2293,9 @@ analysis program.
|
||||
)");
|
||||
extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetLogFile();
|
||||
|
||||
DOCUMENT("Internal function for fetching the contents of a log");
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetLogFileContents(rdcstr &logfile);
|
||||
|
||||
DOCUMENT("Internal function for logging text simply.");
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_LogText(const char *text);
|
||||
|
||||
@@ -2351,7 +2354,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetAndroidFriendlyName(cons
|
||||
rdcstr &friendly);
|
||||
|
||||
DOCUMENT("Internal function for enumerating android devices.");
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr *deviceList);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_EnumerateAndroidDevices(rdcstr &deviceList);
|
||||
|
||||
DOCUMENT("Internal function for initialising android use.");
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_AndroidInitialise();
|
||||
|
||||
@@ -182,6 +182,20 @@ rdcstr DoStringise(const EnvSep &el)
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const LogType &el)
|
||||
{
|
||||
BEGIN_ENUM_STRINGISE(LogType)
|
||||
{
|
||||
STRINGISE_ENUM_CLASS(Debug);
|
||||
STRINGISE_ENUM_CLASS_NAMED(Comment, "Log");
|
||||
STRINGISE_ENUM_CLASS(Warning);
|
||||
STRINGISE_ENUM_CLASS(Error);
|
||||
STRINGISE_ENUM_CLASS(Fatal);
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const Topology &el)
|
||||
{
|
||||
|
||||
@@ -3373,6 +3373,7 @@ DOCUMENT(R"(The type of a log message
|
||||
enum class LogType : int32_t
|
||||
{
|
||||
Debug,
|
||||
First = Debug,
|
||||
Comment,
|
||||
Warning,
|
||||
Error,
|
||||
@@ -3382,6 +3383,8 @@ enum class LogType : int32_t
|
||||
|
||||
DECLARE_REFLECTION_ENUM(LogType);
|
||||
|
||||
ITERABLE_OPERATORS(LogType);
|
||||
|
||||
#if defined(ENABLE_PYTHON_FLAG_ENUMS)
|
||||
|
||||
ENABLE_PYTHON_FLAG_ENUMS;
|
||||
|
||||
@@ -251,6 +251,11 @@ extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetLogFile()
|
||||
return RDCGETLOGFILE();
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_GetLogFileContents(rdcstr &logfile)
|
||||
{
|
||||
logfile = FileIO::logfile_readall(RDCGETLOGFILE());
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_InitGlobalEnv(GlobalEnvironment env,
|
||||
const rdcarray<rdcstr> &args)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user