From fb1dfbd184b3d3f381dc3f3d3faa7b75e425c1db Mon Sep 17 00:00:00 2001 From: baldurk Date: Mon, 6 Feb 2017 17:14:44 +0000 Subject: [PATCH] Add ordered list editor for configuring shader search paths in settings --- .../Windows/Dialogs/OrderedListEditor.cpp | 203 ++++++++++++++++++ .../Windows/Dialogs/OrderedListEditor.h | 69 ++++++ .../Windows/Dialogs/OrderedListEditor.ui | 102 +++++++++ qrenderdoc/Windows/Dialogs/SettingsDialog.cpp | 14 +- qrenderdoc/Windows/Dialogs/SettingsDialog.h | 2 +- qrenderdoc/qrenderdoc.pro | 5 +- qrenderdoc/qrenderdoc_local.vcxproj | 5 + qrenderdoc/qrenderdoc_local.vcxproj.filters | 15 ++ 8 files changed, 411 insertions(+), 4 deletions(-) create mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.cpp create mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.h create mode 100644 qrenderdoc/Windows/Dialogs/OrderedListEditor.ui diff --git a/qrenderdoc/Windows/Dialogs/OrderedListEditor.cpp b/qrenderdoc/Windows/Dialogs/OrderedListEditor.cpp new file mode 100644 index 000000000..c58a6142d --- /dev/null +++ b/qrenderdoc/Windows/Dialogs/OrderedListEditor.cpp @@ -0,0 +1,203 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 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 "OrderedListEditor.h" +#include +#include +#include "Code/QRDUtils.h" +#include "ui_OrderedListEditor.h" + +OrderedListEditor::OrderedListEditor(const QString &windowName, const QString &itemName, + BrowseMode browse, QWidget *parent) + : QDialog(parent), ui(new Ui::OrderedListEditor) +{ + ui->setupUi(this); + + m_BrowseMode = browse; + + setWindowTitle(windowName); + + if(m_BrowseMode == BrowseMode::None) + { + ui->list->setColumnCount(1); + ui->list->setHorizontalHeaderLabels({itemName}); + ui->list->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + } + else + { + QStringList labels; + labels << itemName << tr("Browse"); + ui->list->setColumnCount(2); + ui->list->setHorizontalHeaderLabels(labels); + + ui->list->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch); + ui->list->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents); + } + + QObject::connect(ui->list, &RDTableWidget::keyPress, this, &OrderedListEditor::list_keyPress); +} + +OrderedListEditor::~OrderedListEditor() +{ + delete ui; +} + +QToolButton *OrderedListEditor::makeBrowseButton() +{ + QToolButton *ret = new QToolButton(this); + + ret->setIcon(QIcon(QPixmap(QString::fromUtf8(":/Resources/folder_page.png")))); + ret->setAutoRaise(true); + + QObject::connect(ret, &QToolButton::clicked, this, &OrderedListEditor::browse_clicked); + + return ret; +} + +void OrderedListEditor::setItems(const QStringList &strings) +{ + ui->list->setUpdatesEnabled(false); + ui->list->clearContents(); + + ui->list->setRowCount(strings.count()); + + for(int i = 0; i < strings.count(); i++) + { + ui->list->setItem(i, 0, new QTableWidgetItem(strings[i])); + + if(m_BrowseMode != BrowseMode::None) + ui->list->setCellWidget(i, 1, makeBrowseButton()); + } + + // if we added any strings above the new item row was automatically + // appended. If not, add it explicitly here + if(strings.count() == 0) + addNewItemRow(); + + ui->list->resizeColumnToContents(0); + if(m_BrowseMode != BrowseMode::None) + ui->list->resizeColumnToContents(1); + + ui->list->setUpdatesEnabled(true); +} + +void OrderedListEditor::addNewItemRow() +{ + ui->list->insertRow(ui->list->rowCount()); + + QTableWidgetItem *item = new QTableWidgetItem(""); + item->setFlags(item->flags() & ~(Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled)); + ui->list->setItem(ui->list->rowCount() - 1, 0, item); + + if(m_BrowseMode != BrowseMode::None) + { + item = new QTableWidgetItem(""); + item->setFlags(item->flags() & ~(Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled)); + ui->list->setItem(ui->list->rowCount() - 1, 1, item); + + ui->list->setCellWidget(ui->list->rowCount() - 1, 1, makeBrowseButton()); + } +} + +QStringList OrderedListEditor::getItems() +{ + QStringList ret; + + // don't include the last 'new item' entry + for(int i = 0; i < ui->list->rowCount() - 1; i++) + ret << ui->list->item(i, 0)->text(); + + return ret; +} + +void OrderedListEditor::on_list_cellChanged(int row, int column) +{ + // hack :(. Assume this will only be hit on single UI thread. + static bool recurse = false; + + if(recurse) + return; + + recurse = true; + + // if the last row has something added to it, make a new final row + if(row == ui->list->rowCount() - 1) + { + if(!ui->list->item(row, column)->data(Qt::DisplayRole).toString().trimmed().isEmpty()) + { + // enable dragging + ui->list->item(row, 0)->setFlags(ui->list->item(row, 0)->flags() | + (Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled)); + if(m_BrowseMode != BrowseMode::None) + delete ui->list->takeItem(row, 1); + + addNewItemRow(); + } + } + + if(row > 0 && column == 0 && + ui->list->item(row, column)->data(Qt::DisplayRole).toString().trimmed().isEmpty()) + { + ui->list->removeRow(row); + } + + recurse = false; +} + +void OrderedListEditor::browse_clicked() +{ + QWidget *tool = qobject_cast(QObject::sender()); + + if(tool) + { + for(int i = 0; i < ui->list->rowCount(); i++) + { + QWidget *rowButton = ui->list->cellWidget(i, 1); + if(rowButton == tool) + { + QString sel; + if(m_BrowseMode == BrowseMode::Folder) + sel = RDDialog::getExistingDirectory(this, tr("Browse for a folder")); + else + sel = RDDialog::getOpenFileName(this, tr("Browse for a file")); + + if(sel != "") + ui->list->item(i, 0)->setText(sel); + } + } + } +} + +void OrderedListEditor::list_keyPress(QKeyEvent *event) +{ + if(event->key() == Qt::Key_Delete) + { + int row = -1; + if(ui->list->selectionModel()->selectedIndexes().count() > 0) + row = ui->list->selectionModel()->selectedIndexes()[0].row(); + + if(row >= 0) + ui->list->removeRow(row); + } +} diff --git a/qrenderdoc/Windows/Dialogs/OrderedListEditor.h b/qrenderdoc/Windows/Dialogs/OrderedListEditor.h new file mode 100644 index 000000000..6a961b494 --- /dev/null +++ b/qrenderdoc/Windows/Dialogs/OrderedListEditor.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2017 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 + +namespace Ui +{ +class OrderedListEditor; +} + +class QTreeWidgetItem; +class QToolButton; + +enum class BrowseMode +{ + None, + Folder, + File, +}; + +class OrderedListEditor : public QDialog +{ + Q_OBJECT + +public: + explicit OrderedListEditor(const QString &windowName, const QString &itemName, BrowseMode browse, + QWidget *parent = 0); + ~OrderedListEditor(); + + void setItems(const QStringList &strings); + QStringList getItems(); + +private slots: + // automatic slots + void on_list_cellChanged(int row, int column); + + // manual slots + void browse_clicked(); + void list_keyPress(QKeyEvent *event); + +private: + Ui::OrderedListEditor *ui; + + BrowseMode m_BrowseMode; + + void addNewItemRow(); + QToolButton *makeBrowseButton(); +}; diff --git a/qrenderdoc/Windows/Dialogs/OrderedListEditor.ui b/qrenderdoc/Windows/Dialogs/OrderedListEditor.ui new file mode 100644 index 000000000..6d7ed64b1 --- /dev/null +++ b/qrenderdoc/Windows/Dialogs/OrderedListEditor.ui @@ -0,0 +1,102 @@ + + + OrderedListEditor + + + + 0 + 0 + 400 + 300 + + + + + + + true + + + false + + + QAbstractItemView::InternalMove + + + Qt::MoveAction + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + false + + + 50 + + + false + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + RDTableWidget + QTableWidget +
Widgets/Extended/RDTableWidget.h
+
+
+ + + + buttonBox + accepted() + OrderedListEditor + accept() + + + 199 + 278 + + + 199 + 149 + + + + + buttonBox + rejected() + OrderedListEditor + reject() + + + 199 + 278 + + + 199 + 149 + + + + +
diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp index f0fb349c9..433317bc1 100644 --- a/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp +++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.cpp @@ -26,6 +26,7 @@ #include "Code/CaptureContext.h" #include "Code/PersistantConfig.h" #include "Code/QRDUtils.h" +#include "Windows/Dialogs/OrderedListEditor.h" #include "CaptureDialog.h" #include "ui_SettingsDialog.h" @@ -203,7 +204,16 @@ void SettingsDialog::on_AlwaysReplayLocally_toggled(bool checked) // core void SettingsDialog::on_chooseSearchPaths_clicked() { - // TODO ordered list editor + OrderedListEditor listEd(tr("Shader debug info search paths"), tr("Search Path"), + BrowseMode::Folder, this); + + listEd.setItems(m_Ctx->Config.GetConfigSetting("shader.debug.searchPaths") + .split(QChar(';'), QString::SkipEmptyParts)); + + int res = RDDialog::show(&listEd); + + if(res) + m_Ctx->Config.SetConfigSetting("shader.debug.searchPaths", listEd.getItems().join(QChar(';'))); } // texture viewer @@ -320,7 +330,7 @@ void SettingsDialog::on_browseAdbPath_clicked() m_Ctx->Config.Serialize(); } -void SettingsDialog::on_MaxConnectTimeout_valueChanged(double timeout) +void SettingsDialog::on_Android_MaxConnectTimeout_valueChanged(double timeout) { m_Ctx->Config.Android_MaxConnectTimeout = ui->Android_MaxConnectTimeout->value(); diff --git a/qrenderdoc/Windows/Dialogs/SettingsDialog.h b/qrenderdoc/Windows/Dialogs/SettingsDialog.h index f70ba50ec..9b281ba57 100644 --- a/qrenderdoc/Windows/Dialogs/SettingsDialog.h +++ b/qrenderdoc/Windows/Dialogs/SettingsDialog.h @@ -84,7 +84,7 @@ private slots: // android void on_browseTempCaptureDirectory_clicked(); void on_browseAdbPath_clicked(); - void on_MaxConnectTimeout_valueChanged(double timeout); + void on_Android_MaxConnectTimeout_valueChanged(double timeout); void on_Android_AdbExecutablePath_textEdited(const QString &path); // manual slots diff --git a/qrenderdoc/qrenderdoc.pro b/qrenderdoc/qrenderdoc.pro index 3b1161055..29b8dd7a5 100644 --- a/qrenderdoc/qrenderdoc.pro +++ b/qrenderdoc/qrenderdoc.pro @@ -135,6 +135,7 @@ SOURCES += Code/qrenderdoc.cpp \ Windows/DebugMessageView.cpp \ Windows/StatisticsViewer.cpp \ Windows/Dialogs/SettingsDialog.cpp \ + Windows/Dialogs/OrderedListEditor.cpp \ Widgets/Extended/RDTableWidget.cpp HEADERS += Code/CaptureContext.h \ @@ -175,6 +176,7 @@ HEADERS += Code/CaptureContext.h \ Windows/DebugMessageView.h \ Windows/StatisticsViewer.h \ Windows/Dialogs/SettingsDialog.h \ + Windows/Dialogs/OrderedListEditor.h \ Widgets/Extended/RDTableWidget.h FORMS += Windows/Dialogs/AboutDialog.ui \ @@ -198,7 +200,8 @@ FORMS += Windows/Dialogs/AboutDialog.ui \ Windows/ShaderViewer.ui \ Windows/DebugMessageView.ui \ Windows/StatisticsViewer.ui \ - Windows/Dialogs/SettingsDialog.ui + Windows/Dialogs/SettingsDialog.ui \ + Windows/Dialogs/OrderedListEditor.ui RESOURCES += resources.qrc diff --git a/qrenderdoc/qrenderdoc_local.vcxproj b/qrenderdoc/qrenderdoc_local.vcxproj index be66486fd..4c25f6205 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj +++ b/qrenderdoc/qrenderdoc_local.vcxproj @@ -503,6 +503,7 @@ + @@ -553,6 +554,7 @@ + @@ -663,6 +665,7 @@ + @@ -694,6 +697,7 @@ + @@ -724,6 +728,7 @@ + diff --git a/qrenderdoc/qrenderdoc_local.vcxproj.filters b/qrenderdoc/qrenderdoc_local.vcxproj.filters index c899cb68b..ec7779f3f 100644 --- a/qrenderdoc/qrenderdoc_local.vcxproj.filters +++ b/qrenderdoc/qrenderdoc_local.vcxproj.filters @@ -484,6 +484,12 @@ Generated Files + + Windows\Dialogs + + + Generated Files + Widgets\Extended @@ -867,6 +873,12 @@ Generated Files + + Windows\Dialogs + + + Generated Files + Widgets\Extended @@ -1111,6 +1123,9 @@ Windows\Dialogs + + Windows\Dialogs +