mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-11-07 14:35:48 +00:00
Add support for saving and loading structure definitions
This commit is contained in:
17 files changed
+558
-96
No files matched your search
@@ -24,32 +24,89 @@
|
||||
|
||||
#include "BufferFormatSpecifier.h"
|
||||
#include <QFontDatabase>
|
||||
#include <QKeyEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QSignalBlocker>
|
||||
#include <QTextCursor>
|
||||
#include <QTextDocument>
|
||||
#include "Code/QRDUtils.h"
|
||||
#include "ui_BufferFormatSpecifier.h"
|
||||
|
||||
BufferFormatList *globalFormatList = NULL;
|
||||
|
||||
BufferFormatList::BufferFormatList(ICaptureContext &ctx, QObject *parent)
|
||||
: m_Ctx(ctx), QObject(parent)
|
||||
{
|
||||
rdcarray<rdcstr> saved = m_Ctx.Config().BufferFormatter_SavedFormats;
|
||||
|
||||
for(rdcstr f : saved)
|
||||
{
|
||||
int idx = f.indexOf('\n');
|
||||
|
||||
formats[QString(f.substr(0, idx))] = QString(f.substr(idx + 1)).trimmed();
|
||||
}
|
||||
}
|
||||
|
||||
void BufferFormatList::setFormat(QString name, QString format)
|
||||
{
|
||||
bool newFmt = !formats.contains(name);
|
||||
if(format.isEmpty())
|
||||
formats.remove(name);
|
||||
else
|
||||
formats[name] = format;
|
||||
if(newFmt || (!newFmt && format.isEmpty()))
|
||||
emit formatListUpdated();
|
||||
|
||||
QStringList keys = formats.keys();
|
||||
keys.sort(Qt::CaseInsensitive);
|
||||
rdcarray<rdcstr> saved;
|
||||
for(QString k : keys)
|
||||
saved.push_back(k + lit("\n") + formats[k]);
|
||||
m_Ctx.Config().BufferFormatter_SavedFormats = saved;
|
||||
}
|
||||
|
||||
BufferFormatSpecifier::BufferFormatSpecifier(QWidget *parent)
|
||||
: QWidget(parent), ui(new Ui::BufferFormatSpecifier)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QObject::connect(ui->toggleHelp, &QPushButton::clicked, this, &BufferFormatSpecifier::toggleHelp);
|
||||
|
||||
setErrors(QString());
|
||||
|
||||
on_showHelp_toggled(false);
|
||||
|
||||
ui->savedList->setItemDelegate(new FullEditorDelegate(ui->savedList));
|
||||
|
||||
ui->formatText->setFont(Formatter::FixedFont());
|
||||
ui->savedList->setFont(Formatter::PreferredFont());
|
||||
|
||||
ui->savedList->setColumns({tr("Saved formats")});
|
||||
}
|
||||
|
||||
BufferFormatSpecifier::~BufferFormatSpecifier()
|
||||
{
|
||||
if(m_Ctx)
|
||||
m_Ctx->Config().BufferFormatter_ShowHelp = ui->helpText->isVisible();
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::setAutoFormat(QString autoFormat)
|
||||
{
|
||||
m_AutoFormat = autoFormat;
|
||||
|
||||
updateFormatList();
|
||||
|
||||
setFormat(autoFormat);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::setContext(ICaptureContext *ctx)
|
||||
{
|
||||
m_Ctx = ctx;
|
||||
showHelp(m_Ctx->Config().BufferFormatter_ShowHelp);
|
||||
|
||||
if(!globalFormatList)
|
||||
globalFormatList = new BufferFormatList(*ctx, ctx->GetMainWindow()->Widget());
|
||||
|
||||
QObject::connect(globalFormatList, &BufferFormatList::formatListUpdated, this,
|
||||
&BufferFormatSpecifier::updateFormatList);
|
||||
|
||||
updateFormatList();
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::setTitle(QString title)
|
||||
@@ -57,16 +114,6 @@ void BufferFormatSpecifier::setTitle(QString title)
|
||||
ui->formatGroup->setTitle(title);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::toggleHelp()
|
||||
{
|
||||
ui->helpText->setVisible(!ui->helpText->isVisible());
|
||||
|
||||
if(ui->helpText->isVisible())
|
||||
showHelp(true);
|
||||
else
|
||||
showHelp(false);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::setFormat(const QString &format)
|
||||
{
|
||||
ui->formatText->setText(format);
|
||||
@@ -81,22 +128,224 @@ void BufferFormatSpecifier::setErrors(const QString &errors)
|
||||
ui->errors->setVisible(true);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::showHelp(bool help)
|
||||
void BufferFormatSpecifier::updateFormatList()
|
||||
{
|
||||
ui->helpText->setVisible(help);
|
||||
QString sel;
|
||||
|
||||
RDTreeWidgetItem *item = ui->savedList->selectedItem();
|
||||
if(item)
|
||||
sel = item->text(0);
|
||||
|
||||
if(help)
|
||||
{
|
||||
ui->gridLayout->removeWidget(ui->formatGroup);
|
||||
ui->gridLayout->addWidget(ui->formatGroup, 1, 0, 1, 3);
|
||||
QSignalBlocker block(ui->savedList);
|
||||
int vs = ui->savedList->verticalScrollBar()->value();
|
||||
ui->savedList->beginUpdate();
|
||||
|
||||
ui->savedList->clear();
|
||||
|
||||
int selidx = -1;
|
||||
|
||||
if(!m_AutoFormat.isEmpty())
|
||||
{
|
||||
item = new RDTreeWidgetItem({tr("<Auto-generated>")});
|
||||
item->setItalic(true);
|
||||
ui->savedList->addTopLevelItem(item);
|
||||
|
||||
if(item->text(0) == sel)
|
||||
selidx = 0;
|
||||
}
|
||||
|
||||
QStringList formats = globalFormatList->getFormats();
|
||||
|
||||
for(QString f : formats)
|
||||
{
|
||||
if(f == sel)
|
||||
selidx = ui->savedList->topLevelItemCount();
|
||||
|
||||
ui->savedList->addTopLevelItem(new RDTreeWidgetItem({f}));
|
||||
}
|
||||
|
||||
{
|
||||
item = new RDTreeWidgetItem({tr("New...")});
|
||||
if(item->text(0) == sel)
|
||||
selidx = ui->savedList->topLevelItemCount();
|
||||
item->setEditable(0, true);
|
||||
ui->savedList->addTopLevelItem(item);
|
||||
}
|
||||
|
||||
if(selidx >= 0)
|
||||
ui->savedList->setSelectedItem(ui->savedList->topLevelItem(selidx));
|
||||
|
||||
ui->savedList->resizeColumnToContents(0);
|
||||
|
||||
ui->savedList->endUpdate();
|
||||
ui->savedList->verticalScrollBar()->setValue(vs);
|
||||
}
|
||||
|
||||
on_savedList_itemSelectionChanged();
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_savedList_keyPress(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace)
|
||||
{
|
||||
on_delDef_clicked();
|
||||
}
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_savedList_itemChanged(RDTreeWidgetItem *item, int column)
|
||||
{
|
||||
// ignore updates for anything but the last one
|
||||
if(ui->savedList->indexOfTopLevelItem(item) != ui->savedList->topLevelItemCount() - 1)
|
||||
return;
|
||||
|
||||
QString name = item->text(0);
|
||||
|
||||
// prevent recursion
|
||||
{
|
||||
QSignalBlocker block(ui->savedList);
|
||||
|
||||
// if they didn't actually edit it, ignore
|
||||
if(name == tr("New..."))
|
||||
return;
|
||||
|
||||
if(globalFormatList->hasFormat(name))
|
||||
{
|
||||
RDDialog::critical(this, tr("Name already in use"),
|
||||
tr("The definition name '%1' is already in used.\n"
|
||||
"To update this definition, select it and click update."));
|
||||
item->setText(0, tr("New..."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
globalFormatList->setFormat(name, ui->formatText->toPlainText());
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_savedList_itemDoubleClicked(RDTreeWidgetItem *item, int column)
|
||||
{
|
||||
ui->savedList->setSelectedItem(item);
|
||||
|
||||
if(ui->loadDef->isEnabled())
|
||||
on_loadDef_clicked();
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_savedList_itemSelectionChanged()
|
||||
{
|
||||
RDTreeWidgetItem *item = ui->savedList->selectedItem();
|
||||
|
||||
ui->saveDef->setEnabled(item != NULL);
|
||||
ui->loadDef->setEnabled(item != NULL);
|
||||
ui->delDef->setEnabled(item != NULL);
|
||||
|
||||
// auto format is always the first, and can't be saved to or deleted
|
||||
if(!m_AutoFormat.isEmpty() && ui->savedList->indexOfTopLevelItem(item) == 0)
|
||||
{
|
||||
ui->saveDef->setEnabled(false);
|
||||
ui->delDef->setEnabled(false);
|
||||
}
|
||||
|
||||
// the 'new' format is always the last, and can't be loaded from or deleted
|
||||
if(ui->savedList->indexOfTopLevelItem(item) == ui->savedList->topLevelItemCount() - 1)
|
||||
{
|
||||
ui->loadDef->setEnabled(false);
|
||||
ui->delDef->setEnabled(false);
|
||||
|
||||
ui->saveDef->setToolTip(tr("Create new current structure definition"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->gridLayout->removeWidget(ui->formatGroup);
|
||||
ui->gridLayout->addWidget(ui->formatGroup, 0, 0, 2, 3);
|
||||
ui->saveDef->setToolTip(tr("Update selected with current structure definition"));
|
||||
}
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_showHelp_toggled(bool help)
|
||||
{
|
||||
ui->helpText->setVisible(help);
|
||||
ui->formatText->setVisible(!help);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_loadDef_clicked()
|
||||
{
|
||||
RDTreeWidgetItem *item = ui->savedList->selectedItem();
|
||||
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
QString name = item->text(0);
|
||||
|
||||
QString format;
|
||||
if(!m_AutoFormat.isEmpty() && ui->savedList->indexOfTopLevelItem(item) == 0)
|
||||
format = m_AutoFormat;
|
||||
else
|
||||
format = globalFormatList->getFormat(name);
|
||||
|
||||
{
|
||||
QSignalBlocker block(ui->formatText);
|
||||
|
||||
QTextDocument *doc = ui->formatText->document();
|
||||
QTextCursor cur(doc);
|
||||
cur.select(QTextCursor::Document);
|
||||
cur.insertText(format);
|
||||
}
|
||||
|
||||
emit processFormat(format);
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_saveDef_clicked()
|
||||
{
|
||||
RDTreeWidgetItem *item = ui->savedList->selectedItem();
|
||||
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
// for the 'new...' just trigger an edit and let the user do it that way. This reduces
|
||||
// duplication, avoids need for a prompt for the name, and educates the user that they can edit
|
||||
// directly
|
||||
if(ui->savedList->indexOfTopLevelItem(item) == ui->savedList->topLevelItemCount() - 1)
|
||||
{
|
||||
ui->savedList->editItem(item);
|
||||
return;
|
||||
}
|
||||
|
||||
QString name = item->text(0);
|
||||
|
||||
QMessageBox::StandardButton res = RDDialog::question(
|
||||
this, tr("Updating definition"),
|
||||
tr("Are you sure you wish to overwrite definition '%1'?").arg(name), RDDialog::YesNoCancel);
|
||||
|
||||
if(res != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
globalFormatList->setFormat(name, ui->formatText->toPlainText());
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_delDef_clicked()
|
||||
{
|
||||
RDTreeWidgetItem *item = ui->savedList->selectedItem();
|
||||
|
||||
if(!item)
|
||||
return;
|
||||
|
||||
QString name = item->text(0);
|
||||
|
||||
QMessageBox::StandardButton res = RDDialog::question(
|
||||
this, tr("Deleting definition"),
|
||||
tr("Are you sure you wish to delete definition '%1'?").arg(name), RDDialog::YesNoCancel);
|
||||
|
||||
if(res != QMessageBox::Yes)
|
||||
return;
|
||||
|
||||
ui->savedList->clearSelection();
|
||||
|
||||
globalFormatList->setFormat(name, QString());
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_formatText_textChanged()
|
||||
{
|
||||
ui->savedList->clearSelection();
|
||||
}
|
||||
|
||||
void BufferFormatSpecifier::on_apply_clicked()
|
||||
{
|
||||
setErrors(QString());
|
||||
|
||||
Reference in new issue
Block a user