mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-23 23:16:31 +00:00
Add a find/replace tool for use with Scintilla
This commit is contained in:
@@ -0,0 +1,194 @@
|
||||
/******************************************************************************
|
||||
* 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 "FindReplace.h"
|
||||
#include <QKeyEvent>
|
||||
#include <QLineEdit>
|
||||
#include "ui_FindReplace.h"
|
||||
|
||||
FindReplace::FindReplace(QWidget *parent) : QFrame(parent), ui(new Ui::FindReplace)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
ui->searchContext->setCurrentIndex(FindReplace::File);
|
||||
|
||||
// default to just find
|
||||
setReplaceMode(false);
|
||||
setDirection(FindReplace::Down);
|
||||
|
||||
QObject::connect(ui->findText->lineEdit(), &QLineEdit::returnPressed, this,
|
||||
&FindReplace::on_find_clicked);
|
||||
QObject::connect(ui->replaceText->lineEdit(), &QLineEdit::returnPressed, this,
|
||||
&FindReplace::on_replace_clicked);
|
||||
}
|
||||
|
||||
FindReplace::~FindReplace()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool FindReplace::replaceMode()
|
||||
{
|
||||
return ui->replaceMode->isChecked();
|
||||
}
|
||||
|
||||
FindReplace::SearchContext FindReplace::context()
|
||||
{
|
||||
return (FindReplace::SearchContext)ui->searchContext->currentIndex();
|
||||
}
|
||||
|
||||
FindReplace::SearchDirection FindReplace::direction()
|
||||
{
|
||||
return ui->searchUp->isChecked() ? FindReplace::Up : FindReplace::Down;
|
||||
}
|
||||
|
||||
bool FindReplace::matchCase()
|
||||
{
|
||||
return ui->matchCase->isChecked();
|
||||
}
|
||||
|
||||
bool FindReplace::matchWord()
|
||||
{
|
||||
return ui->matchWord->isChecked();
|
||||
}
|
||||
|
||||
bool FindReplace::regexp()
|
||||
{
|
||||
return ui->regexp->isChecked();
|
||||
}
|
||||
|
||||
QString FindReplace::findText()
|
||||
{
|
||||
return ui->findText->currentText();
|
||||
}
|
||||
|
||||
QString FindReplace::replaceText()
|
||||
{
|
||||
return ui->replaceText->currentText();
|
||||
}
|
||||
|
||||
void FindReplace::allowUserModeChange(bool allow)
|
||||
{
|
||||
ui->modeChangeFrame->setVisible(allow);
|
||||
}
|
||||
|
||||
void FindReplace::setReplaceMode(bool replacing)
|
||||
{
|
||||
ui->replaceLabel->setVisible(replacing);
|
||||
ui->replaceText->setVisible(replacing);
|
||||
ui->replace->setVisible(replacing);
|
||||
ui->replaceAll->setVisible(replacing);
|
||||
|
||||
ui->findMode->setChecked(!replacing);
|
||||
ui->replaceMode->setChecked(replacing);
|
||||
|
||||
setWindowTitle(replacing ? tr("Find && Replace") : tr("Find"));
|
||||
}
|
||||
|
||||
void FindReplace::setDirection(SearchDirection dir)
|
||||
{
|
||||
if(dir == FindReplace::Up)
|
||||
ui->searchUp->setChecked(true);
|
||||
else
|
||||
ui->searchDown->setChecked(true);
|
||||
}
|
||||
|
||||
void FindReplace::takeFocus()
|
||||
{
|
||||
ui->findText->setFocus();
|
||||
}
|
||||
|
||||
void FindReplace::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if(event->key() == Qt::Key_F3)
|
||||
{
|
||||
SearchDirection dir = direction();
|
||||
|
||||
if(event->modifiers() & Qt::ShiftModifier)
|
||||
ui->searchUp->setChecked(true);
|
||||
else
|
||||
ui->searchDown->setChecked(true);
|
||||
|
||||
emit performFind();
|
||||
|
||||
if(dir == FindReplace::Up)
|
||||
ui->searchUp->setChecked(true);
|
||||
else
|
||||
ui->searchDown->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void FindReplace::addHistory(QComboBox *combo)
|
||||
{
|
||||
QString text = combo->currentText();
|
||||
|
||||
for(int i = 0; i < combo->count(); i++)
|
||||
{
|
||||
if(combo->itemText(i) == text)
|
||||
{
|
||||
// remove the item so we can bump it up to the top of the list
|
||||
combo->removeItem(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
combo->insertItem(0, text);
|
||||
combo->setCurrentText(text);
|
||||
}
|
||||
|
||||
void FindReplace::on_find_clicked()
|
||||
{
|
||||
addHistory(ui->findText);
|
||||
emit performFind();
|
||||
}
|
||||
|
||||
void FindReplace::on_findAll_clicked()
|
||||
{
|
||||
addHistory(ui->findText);
|
||||
emit performFindAll();
|
||||
}
|
||||
|
||||
void FindReplace::on_replace_clicked()
|
||||
{
|
||||
addHistory(ui->findText);
|
||||
addHistory(ui->replaceText);
|
||||
emit performReplace();
|
||||
}
|
||||
|
||||
void FindReplace::on_replaceAll_clicked()
|
||||
{
|
||||
addHistory(ui->findText);
|
||||
addHistory(ui->replaceText);
|
||||
emit performReplaceAll();
|
||||
}
|
||||
|
||||
void FindReplace::on_findMode_clicked()
|
||||
{
|
||||
setReplaceMode(false);
|
||||
}
|
||||
|
||||
void FindReplace::on_replaceMode_clicked()
|
||||
{
|
||||
setReplaceMode(true);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/******************************************************************************
|
||||
* 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.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QFrame>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class FindReplace;
|
||||
}
|
||||
|
||||
class QComboBox;
|
||||
|
||||
class FindReplace : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit FindReplace(QWidget *parent = 0);
|
||||
~FindReplace();
|
||||
|
||||
enum SearchContext
|
||||
{
|
||||
File,
|
||||
AllFiles,
|
||||
};
|
||||
|
||||
enum SearchDirection
|
||||
{
|
||||
Up,
|
||||
Down,
|
||||
};
|
||||
|
||||
bool replaceMode();
|
||||
|
||||
SearchContext context();
|
||||
SearchDirection direction();
|
||||
bool matchCase();
|
||||
bool matchWord();
|
||||
bool regexp();
|
||||
|
||||
QString findText();
|
||||
QString replaceText();
|
||||
|
||||
public slots:
|
||||
void allowUserModeChange(bool allow);
|
||||
void setReplaceMode(bool replacing);
|
||||
void setDirection(SearchDirection dir);
|
||||
void takeFocus();
|
||||
|
||||
signals:
|
||||
void performFind();
|
||||
void performFindAll();
|
||||
void performReplace();
|
||||
void performReplaceAll();
|
||||
|
||||
private slots:
|
||||
// automatic slots
|
||||
void on_find_clicked();
|
||||
void on_findAll_clicked();
|
||||
void on_replace_clicked();
|
||||
void on_replaceAll_clicked();
|
||||
void on_findMode_clicked();
|
||||
void on_replaceMode_clicked();
|
||||
|
||||
private:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
Ui::FindReplace *ui;
|
||||
|
||||
void addHistory(QComboBox *combo);
|
||||
};
|
||||
@@ -0,0 +1,335 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>FindReplace</class>
|
||||
<widget class="QFrame" name="FindReplace">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>321</width>
|
||||
<height>352</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Context</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="searchContextLabel">
|
||||
<property name="text">
|
||||
<string>Search in:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="matchCase">
|
||||
<property name="text">
|
||||
<string>Match case</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QComboBox" name="searchContext">
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::NoInsert</enum>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Current File</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>All Files</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="regexp">
|
||||
<property name="text">
|
||||
<string>Use Regular Expressions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="matchWord">
|
||||
<property name="text">
|
||||
<string>Match whole word</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QFrame" name="frame">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="1">
|
||||
<widget class="QPushButton" name="replaceAll">
|
||||
<property name="text">
|
||||
<string>Replace All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QPushButton" name="replace">
|
||||
<property name="text">
|
||||
<string>Replace</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QPushButton" name="find">
|
||||
<property name="text">
|
||||
<string>Find Next</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QPushButton" name="findAll">
|
||||
<property name="text">
|
||||
<string>Find All</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QFrame" name="modeChangeFrame">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Panel</enum>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="findMode">
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="replaceMode">
|
||||
<property name="text">
|
||||
<string>Replace</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="autoRaise">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Direction</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="searchUp">
|
||||
<property name="text">
|
||||
<string>Up</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="searchDown">
|
||||
<property name="text">
|
||||
<string>Down</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QFrame" name="frame_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::StyledPanel</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="findLabel">
|
||||
<property name="text">
|
||||
<string>Find</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="replaceLabel">
|
||||
<property name="text">
|
||||
<string>Replace with</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="findText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAtTop</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="replaceText">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="insertPolicy">
|
||||
<enum>QComboBox::InsertAtTop</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -29,7 +29,9 @@
|
||||
#include "3rdparty/scintilla/include/SciLexer.h"
|
||||
#include "3rdparty/scintilla/include/qt/ScintillaEdit.h"
|
||||
#include "3rdparty/toolwindowmanager/ToolWindowManager.h"
|
||||
#include "3rdparty/toolwindowmanager/ToolWindowManagerArea.h"
|
||||
#include "Code/ScintillaSyntax.h"
|
||||
#include "Widgets/FindReplace.h"
|
||||
#include "Windows/PipelineState/PipelineStateViewer.h"
|
||||
#include "ui_ShaderViewer.h"
|
||||
|
||||
@@ -57,9 +59,34 @@ ShaderViewer::ShaderViewer(CaptureContext &ctx, QWidget *parent)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
// we create this up front so its state stays persistent as much as possible.
|
||||
m_FindReplace = new FindReplace(this);
|
||||
|
||||
m_FindResults = MakeEditor("findresults", "", SCLEX_NULL);
|
||||
m_FindResults->setReadOnly(true);
|
||||
m_FindResults->setWindowTitle("Find Results");
|
||||
|
||||
// remove margins
|
||||
m_FindResults->setMarginWidthN(0, 0);
|
||||
m_FindResults->setMarginWidthN(1, 0);
|
||||
m_FindResults->setMarginWidthN(2, 0);
|
||||
|
||||
QObject::connect(m_FindReplace, &FindReplace::performFind, this, &ShaderViewer::performFind);
|
||||
QObject::connect(m_FindReplace, &FindReplace::performFindAll, this, &ShaderViewer::performFindAll);
|
||||
QObject::connect(m_FindReplace, &FindReplace::performReplace, this, &ShaderViewer::performReplace);
|
||||
QObject::connect(m_FindReplace, &FindReplace::performReplaceAll, this,
|
||||
&ShaderViewer::performReplaceAll);
|
||||
|
||||
ui->docking->addToolWindow(m_FindReplace, ToolWindowManager::NoArea);
|
||||
ui->docking->setToolWindowProperties(m_FindReplace, ToolWindowManager::HideOnClose);
|
||||
|
||||
ui->docking->addToolWindow(m_FindResults, ToolWindowManager::NoArea);
|
||||
ui->docking->setToolWindowProperties(m_FindResults, ToolWindowManager::HideOnClose);
|
||||
|
||||
{
|
||||
m_DisassemblyView =
|
||||
MakeEditor("scintillaDisassem", "", m_Ctx.APIProps().pipelineType == eGraphicsAPI_Vulkan);
|
||||
MakeEditor("scintillaDisassem", "",
|
||||
m_Ctx.APIProps().pipelineType == eGraphicsAPI_Vulkan ? SCLEX_GLSL : SCLEX_HLSL);
|
||||
m_DisassemblyView->setReadOnly(true);
|
||||
m_DisassemblyView->setWindowTitle(tr("Disassembly"));
|
||||
|
||||
@@ -89,10 +116,11 @@ ShaderViewer::ShaderViewer(CaptureContext &ctx, QWidget *parent)
|
||||
m_Scintillas.push_back(m_DisassemblyView);
|
||||
|
||||
ui->docking->addToolWindow(m_DisassemblyView, ToolWindowManager::EmptySpace);
|
||||
ui->docking->setToolWindowProperties(m_DisassemblyView, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
m_DisassemblyView,
|
||||
ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
}
|
||||
|
||||
ui->docking->setAllowFloatingWindow(false);
|
||||
ui->docking->setRubberBandLineWidth(50);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
@@ -139,8 +167,13 @@ void ShaderViewer::editShader(bool customShader, const QString &entryPoint, cons
|
||||
ScintillaEdit *scintilla = AddFileScintilla(name, text);
|
||||
|
||||
scintilla->setReadOnly(false);
|
||||
QObject::connect(m_DisassemblyView, &ScintillaEdit::keyPressed, this,
|
||||
&ShaderViewer::editable_keyPressed);
|
||||
QObject::connect(scintilla, &ScintillaEdit::keyPressed, this, &ShaderViewer::editable_keyPressed);
|
||||
|
||||
QObject::connect(scintilla, &ScintillaEdit::modified, [this](int type, int, int, int,
|
||||
const QByteArray &, int, int, int) {
|
||||
if(type & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT | SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE))
|
||||
m_FindState = FindState();
|
||||
});
|
||||
|
||||
// TODO - shortcuts
|
||||
QObject::connect(new QShortcut(QKeySequence(Qt::Key_S | Qt::ControlModifier), scintilla),
|
||||
@@ -164,7 +197,7 @@ void ShaderViewer::editShader(bool customShader, const QString &entryPoint, cons
|
||||
if(files.count() > 2)
|
||||
addFileList();
|
||||
|
||||
m_Errors = MakeEditor("errors", "", false);
|
||||
m_Errors = MakeEditor("errors", "", SCLEX_NULL);
|
||||
m_Errors->setReadOnly(true);
|
||||
m_Errors->setWindowTitle("Errors");
|
||||
|
||||
@@ -178,7 +211,8 @@ void ShaderViewer::editShader(bool customShader, const QString &entryPoint, cons
|
||||
ui->docking->addToolWindow(
|
||||
m_Errors, ToolWindowManager::AreaReference(ToolWindowManager::BottomOf,
|
||||
ui->docking->areaOf(m_Scintillas.front()), 0.2f));
|
||||
ui->docking->setToolWindowProperties(m_Errors, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
m_Errors, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
}
|
||||
|
||||
void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderReflection *shader,
|
||||
@@ -190,6 +224,9 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
m_Trace = trace;
|
||||
m_Stage = stage;
|
||||
|
||||
// no replacing allowed, stay in find mode
|
||||
m_FindReplace->allowUserModeChange(false);
|
||||
|
||||
if(!shader || !bind)
|
||||
m_Trace = NULL;
|
||||
|
||||
@@ -272,19 +309,22 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
ui->docking->addToolWindow(
|
||||
ui->watch, ToolWindowManager::AreaReference(ToolWindowManager::BottomOf,
|
||||
ui->docking->areaOf(m_DisassemblyView), 0.25f));
|
||||
ui->docking->setToolWindowProperties(ui->watch, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->watch, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
|
||||
ui->variables->setWindowTitle(tr("Variables"));
|
||||
ui->docking->addToolWindow(
|
||||
ui->variables,
|
||||
ToolWindowManager::AreaReference(ToolWindowManager::AddTo, ui->docking->areaOf(ui->watch)));
|
||||
ui->docking->setToolWindowProperties(ui->variables, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->variables, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
|
||||
ui->constants->setWindowTitle(tr("Constants && Resources"));
|
||||
ui->docking->addToolWindow(
|
||||
ui->constants, ToolWindowManager::AreaReference(ToolWindowManager::LeftOf,
|
||||
ui->docking->areaOf(ui->variables), 0.5f));
|
||||
ui->docking->setToolWindowProperties(ui->constants, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->constants, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
|
||||
m_DisassemblyView->setMarginWidthN(1, 20);
|
||||
|
||||
@@ -390,13 +430,15 @@ void ShaderViewer::debugShader(const ShaderBindpointMapping *bind, const ShaderR
|
||||
ui->docking->addToolWindow(ui->inputSig, ToolWindowManager::AreaReference(
|
||||
ToolWindowManager::BottomOf,
|
||||
ui->docking->areaOf(m_DisassemblyView), 0.2f));
|
||||
ui->docking->setToolWindowProperties(ui->inputSig, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->inputSig, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
|
||||
ui->outputSig->setWindowTitle(tr("Output Signature"));
|
||||
ui->docking->addToolWindow(
|
||||
ui->outputSig, ToolWindowManager::AreaReference(ToolWindowManager::RightOf,
|
||||
ui->docking->areaOf(ui->inputSig), 0.5f));
|
||||
ui->docking->setToolWindowProperties(ui->outputSig, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
ui->outputSig, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -426,7 +468,9 @@ void ShaderViewer::OnEventChanged(uint32_t eventID)
|
||||
|
||||
ScintillaEdit *ShaderViewer::AddFileScintilla(const QString &name, const QString &text)
|
||||
{
|
||||
ScintillaEdit *scintilla = MakeEditor("scintilla" + name, text, true);
|
||||
ScintillaEdit *scintilla =
|
||||
MakeEditor("scintilla" + name, text,
|
||||
m_Ctx.APIProps().localRenderer == eGraphicsAPI_OpenGL ? SCLEX_GLSL : SCLEX_HLSL);
|
||||
scintilla->setReadOnly(true);
|
||||
scintilla->setWindowTitle(name);
|
||||
((QWidget *)scintilla)->setProperty("name", name);
|
||||
@@ -440,14 +484,15 @@ ScintillaEdit *ShaderViewer::AddFileScintilla(const QString &name, const QString
|
||||
ui->docking->areaOf(m_Scintillas[0]));
|
||||
|
||||
ui->docking->addToolWindow(scintilla, ref);
|
||||
ui->docking->setToolWindowProperties(scintilla, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
scintilla, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
|
||||
m_Scintillas.push_back(scintilla);
|
||||
|
||||
return scintilla;
|
||||
}
|
||||
|
||||
ScintillaEdit *ShaderViewer::MakeEditor(const QString &name, const QString &text, bool src)
|
||||
ScintillaEdit *ShaderViewer::MakeEditor(const QString &name, const QString &text, int lang)
|
||||
{
|
||||
ScintillaEdit *ret = new ScintillaEdit(this);
|
||||
|
||||
@@ -468,11 +513,16 @@ ScintillaEdit *ShaderViewer::MakeEditor(const QString &name, const QString &text
|
||||
ret->setObjectName(name);
|
||||
|
||||
// C# DarkGreen
|
||||
ret->indicSetFore(4, SCINTILLA_COLOUR(0, 100, 0));
|
||||
ret->indicSetStyle(4, INDIC_ROUNDBOX);
|
||||
ret->indicSetFore(INDICATOR_REGHIGHLIGHT, SCINTILLA_COLOUR(0, 100, 0));
|
||||
ret->indicSetStyle(INDICATOR_REGHIGHLIGHT, INDIC_ROUNDBOX);
|
||||
|
||||
ConfigureSyntax(ret,
|
||||
m_Ctx.APIProps().localRenderer == eGraphicsAPI_OpenGL ? SCLEX_GLSL : SCLEX_HLSL);
|
||||
// set up find result highlight style
|
||||
ret->indicSetFore(INDICATOR_FINDRESULT, SCINTILLA_COLOUR(200, 200, 127));
|
||||
ret->indicSetStyle(INDICATOR_FINDRESULT, INDIC_FULLBOX);
|
||||
ret->indicSetAlpha(INDICATOR_FINDRESULT, 50);
|
||||
ret->indicSetOutlineAlpha(INDICATOR_FINDRESULT, 80);
|
||||
|
||||
ConfigureSyntax(ret, lang);
|
||||
|
||||
ret->setTabWidth(4);
|
||||
|
||||
@@ -488,12 +538,25 @@ ScintillaEdit *ShaderViewer::MakeEditor(const QString &name, const QString &text
|
||||
|
||||
void ShaderViewer::readonly_keyPressed(QKeyEvent *event)
|
||||
{
|
||||
// TODO find
|
||||
if(event->key() == Qt::Key_F && (event->modifiers() & Qt::ControlModifier))
|
||||
{
|
||||
m_FindReplace->setReplaceMode(false);
|
||||
on_findReplace_clicked();
|
||||
}
|
||||
|
||||
if(event->key() == Qt::Key_F3)
|
||||
{
|
||||
find((event->modifiers() & Qt::ShiftModifier) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::editable_keyPressed(QKeyEvent *event)
|
||||
{
|
||||
// TODO replace
|
||||
if(event->key() == Qt::Key_H && (event->modifiers() & Qt::ControlModifier))
|
||||
{
|
||||
m_FindReplace->setReplaceMode(true);
|
||||
on_findReplace_clicked();
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::disassembly_buttonReleased(QMouseEvent *event)
|
||||
@@ -697,7 +760,8 @@ void ShaderViewer::addFileList()
|
||||
ui->docking->addToolWindow(
|
||||
list, ToolWindowManager::AreaReference(ToolWindowManager::LeftOf,
|
||||
ui->docking->areaOf(m_Scintillas.front()), 0.2f));
|
||||
ui->docking->setToolWindowProperties(list, ToolWindowManager::HideCloseButton);
|
||||
ui->docking->setToolWindowProperties(
|
||||
list, ToolWindowManager::HideCloseButton | ToolWindowManager::DisallowFloatWindow);
|
||||
}
|
||||
|
||||
void ShaderViewer::updateDebugging()
|
||||
@@ -733,12 +797,7 @@ void ShaderViewer::updateDebugging()
|
||||
int pos = m_DisassemblyView->positionFromLine(i);
|
||||
m_DisassemblyView->setSelection(pos, pos);
|
||||
|
||||
int firstLine = m_DisassemblyView->firstVisibleLine();
|
||||
int linesVisible = m_DisassemblyView->linesOnScreen();
|
||||
|
||||
if(m_DisassemblyView->isVisible() && (i < firstLine || i > (firstLine + linesVisible)))
|
||||
m_DisassemblyView->scrollCaret();
|
||||
|
||||
ensureLineScrolled(m_DisassemblyView, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -907,6 +966,15 @@ void ShaderViewer::updateDebugging()
|
||||
// TODO watch registers
|
||||
}
|
||||
|
||||
void ShaderViewer::ensureLineScrolled(ScintillaEdit *s, int line)
|
||||
{
|
||||
int firstLine = s->firstVisibleLine();
|
||||
int linesVisible = s->linesOnScreen();
|
||||
|
||||
if(s->isVisible() && (line < firstLine || line > (firstLine + linesVisible)))
|
||||
s->scrollCaret();
|
||||
}
|
||||
|
||||
int ShaderViewer::currentStep()
|
||||
{
|
||||
return m_CurrentStep;
|
||||
@@ -990,6 +1058,18 @@ void ShaderViewer::showErrors(const QString &errors)
|
||||
|
||||
void ShaderViewer::on_findReplace_clicked()
|
||||
{
|
||||
if(m_FindReplace->isVisible())
|
||||
{
|
||||
ToolWindowManager::raiseToolWindow(m_FindReplace);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->docking->moveToolWindow(
|
||||
m_FindReplace, ToolWindowManager::AreaReference(ToolWindowManager::NewFloatingArea));
|
||||
ui->docking->setToolWindowProperties(m_FindReplace, ToolWindowManager::HideOnClose);
|
||||
}
|
||||
ui->docking->areaOf(m_FindReplace)->parentWidget()->activateWindow();
|
||||
m_FindReplace->takeFocus();
|
||||
}
|
||||
|
||||
void ShaderViewer::on_save_clicked()
|
||||
@@ -1027,3 +1107,381 @@ void ShaderViewer::on_floatView_clicked()
|
||||
|
||||
updateDebugging();
|
||||
}
|
||||
|
||||
ScintillaEdit *ShaderViewer::currentScintilla()
|
||||
{
|
||||
ScintillaEdit *cur = qobject_cast<ScintillaEdit *>(QApplication::focusWidget());
|
||||
|
||||
if(cur == NULL)
|
||||
{
|
||||
for(ScintillaEdit *s : m_Scintillas)
|
||||
{
|
||||
if(s->isVisible())
|
||||
{
|
||||
cur = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cur;
|
||||
}
|
||||
|
||||
ScintillaEdit *ShaderViewer::nextScintilla(ScintillaEdit *cur)
|
||||
{
|
||||
for(int i = 0; i < m_Scintillas.count(); i++)
|
||||
{
|
||||
if(m_Scintillas[i] == cur)
|
||||
{
|
||||
if(i + 1 < m_Scintillas.count())
|
||||
return m_Scintillas[i + 1];
|
||||
|
||||
return m_Scintillas[0];
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_Scintillas.isEmpty())
|
||||
return m_Scintillas[0];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ShaderViewer::find(bool down)
|
||||
{
|
||||
ScintillaEdit *cur = currentScintilla();
|
||||
|
||||
if(!cur)
|
||||
return;
|
||||
|
||||
QString find = m_FindReplace->findText();
|
||||
|
||||
sptr_t flags = 0;
|
||||
|
||||
if(m_FindReplace->matchCase())
|
||||
flags |= SCFIND_MATCHCASE;
|
||||
if(m_FindReplace->matchWord())
|
||||
flags |= SCFIND_WHOLEWORD;
|
||||
if(m_FindReplace->regexp())
|
||||
flags |= SCFIND_REGEXP | SCFIND_POSIX;
|
||||
|
||||
FindReplace::SearchContext context = m_FindReplace->context();
|
||||
|
||||
QString findHash = QString("%1%2%3").arg(find).arg(flags).arg((int)context);
|
||||
|
||||
if(findHash != m_FindState.hash)
|
||||
{
|
||||
m_FindState.hash = findHash;
|
||||
m_FindState.start = 0;
|
||||
m_FindState.end = cur->length();
|
||||
m_FindState.offset = cur->currentPos();
|
||||
}
|
||||
|
||||
int start = m_FindState.start + m_FindState.offset;
|
||||
int end = m_FindState.end;
|
||||
|
||||
if(!down)
|
||||
end = m_FindState.start;
|
||||
|
||||
QPair<int, int> result = cur->findText(flags, find.toUtf8().data(), start, end);
|
||||
|
||||
m_FindState.prevResult = result;
|
||||
|
||||
if(result.first == -1)
|
||||
{
|
||||
sptr_t maxOffset = down ? 0 : m_FindState.end;
|
||||
|
||||
// if we're at offset 0 searching down, there are no results. Same for offset max and searching
|
||||
// up
|
||||
if(m_FindState.offset == maxOffset)
|
||||
return;
|
||||
|
||||
// otherwise, we can wrap the search around
|
||||
|
||||
if(context == FindReplace::AllFiles)
|
||||
{
|
||||
cur = nextScintilla(cur);
|
||||
ToolWindowManager::raiseToolWindow(cur);
|
||||
cur->activateWindow();
|
||||
cur->QWidget::setFocus();
|
||||
}
|
||||
|
||||
m_FindState.offset = maxOffset;
|
||||
|
||||
start = m_FindState.start + m_FindState.offset;
|
||||
end = m_FindState.end;
|
||||
|
||||
if(!down)
|
||||
end = m_FindState.start;
|
||||
|
||||
result = cur->findText(flags, find.toUtf8().data(), start, end);
|
||||
|
||||
m_FindState.prevResult = result;
|
||||
|
||||
if(result.first == -1)
|
||||
return;
|
||||
}
|
||||
|
||||
cur->setSelection(result.first, result.second);
|
||||
|
||||
ensureLineScrolled(cur, cur->lineFromPosition(result.first));
|
||||
|
||||
if(down)
|
||||
m_FindState.offset = result.second - m_FindState.start;
|
||||
else
|
||||
m_FindState.offset = result.first - m_FindState.start;
|
||||
}
|
||||
|
||||
void ShaderViewer::performFind()
|
||||
{
|
||||
find(m_FindReplace->direction() == FindReplace::Down);
|
||||
}
|
||||
|
||||
void ShaderViewer::performFindAll()
|
||||
{
|
||||
ScintillaEdit *cur = currentScintilla();
|
||||
|
||||
if(!cur)
|
||||
return;
|
||||
|
||||
QString find = m_FindReplace->findText();
|
||||
|
||||
sptr_t flags = 0;
|
||||
|
||||
QString results = tr("Find all \"%1\"").arg(find);
|
||||
|
||||
if(m_FindReplace->matchCase())
|
||||
{
|
||||
flags |= SCFIND_MATCHCASE;
|
||||
results += tr(", Match case");
|
||||
}
|
||||
|
||||
if(m_FindReplace->matchWord())
|
||||
{
|
||||
flags |= SCFIND_WHOLEWORD;
|
||||
results += tr(", Match whole word");
|
||||
}
|
||||
|
||||
if(m_FindReplace->regexp())
|
||||
{
|
||||
flags |= SCFIND_REGEXP | SCFIND_POSIX;
|
||||
results += tr(", with Regular Expressions");
|
||||
}
|
||||
|
||||
FindReplace::SearchContext context = m_FindReplace->context();
|
||||
|
||||
if(context == FindReplace::File)
|
||||
results += tr(", in current file\n");
|
||||
else
|
||||
results += tr(", in all files\n");
|
||||
|
||||
// trash the find state for any incremental finds
|
||||
m_FindState = FindState();
|
||||
|
||||
QList<ScintillaEdit *> scintillas = m_Scintillas;
|
||||
|
||||
if(context == FindReplace::File)
|
||||
scintillas = {cur};
|
||||
|
||||
QList<QPair<int, int>> resultList;
|
||||
|
||||
QByteArray findUtf8 = find.toUtf8();
|
||||
|
||||
for(ScintillaEdit *s : scintillas)
|
||||
{
|
||||
sptr_t start = 0;
|
||||
sptr_t end = s->length();
|
||||
|
||||
s->setIndicatorCurrent(INDICATOR_FINDRESULT);
|
||||
s->indicatorClearRange(start, end);
|
||||
|
||||
if(findUtf8.isEmpty())
|
||||
continue;
|
||||
|
||||
QPair<int, int> result;
|
||||
|
||||
do
|
||||
{
|
||||
result = s->findText(flags, findUtf8.data(), start, end);
|
||||
|
||||
if(result.first >= 0)
|
||||
{
|
||||
int line = s->lineFromPosition(result.first);
|
||||
sptr_t lineStart = s->positionFromLine(line);
|
||||
sptr_t lineEnd = s->lineEndPosition(line);
|
||||
|
||||
s->indicatorFillRange(result.first, result.second - result.first);
|
||||
|
||||
QString lineText = QString::fromUtf8(s->textRange(lineStart, lineEnd));
|
||||
|
||||
results += QString(" %1(%2): ").arg(s->windowTitle()).arg(line, 4);
|
||||
int startPos = results.length();
|
||||
|
||||
results += lineText;
|
||||
results += "\n";
|
||||
|
||||
resultList.push_back(
|
||||
qMakePair(result.first - lineStart + startPos, result.second - lineStart + startPos));
|
||||
}
|
||||
|
||||
start = result.second;
|
||||
|
||||
} while(result.first >= 0);
|
||||
}
|
||||
|
||||
if(findUtf8.isEmpty())
|
||||
return;
|
||||
|
||||
results += tr("Matching lines: %1").arg(resultList.count());
|
||||
|
||||
m_FindResults->setReadOnly(false);
|
||||
m_FindResults->setText(results.toUtf8().data());
|
||||
|
||||
m_FindResults->setIndicatorCurrent(INDICATOR_FINDRESULT);
|
||||
|
||||
for(QPair<int, int> r : resultList)
|
||||
m_FindResults->indicatorFillRange(r.first, r.second - r.first);
|
||||
|
||||
m_FindResults->setReadOnly(true);
|
||||
|
||||
if(m_FindResults->isVisible())
|
||||
{
|
||||
ToolWindowManager::raiseToolWindow(m_FindResults);
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->docking->moveToolWindow(m_FindResults,
|
||||
ToolWindowManager::AreaReference(ToolWindowManager::BottomOf,
|
||||
ui->docking->areaOf(cur), 0.2f));
|
||||
ui->docking->setToolWindowProperties(m_FindResults, ToolWindowManager::HideOnClose);
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderViewer::performReplace()
|
||||
{
|
||||
ScintillaEdit *cur = currentScintilla();
|
||||
|
||||
if(!cur)
|
||||
return;
|
||||
|
||||
QString find = m_FindReplace->findText();
|
||||
|
||||
if(find.isEmpty())
|
||||
return;
|
||||
|
||||
sptr_t flags = 0;
|
||||
|
||||
if(m_FindReplace->matchCase())
|
||||
flags |= SCFIND_MATCHCASE;
|
||||
if(m_FindReplace->matchWord())
|
||||
flags |= SCFIND_WHOLEWORD;
|
||||
if(m_FindReplace->regexp())
|
||||
flags |= SCFIND_REGEXP | SCFIND_POSIX;
|
||||
|
||||
FindReplace::SearchContext context = m_FindReplace->context();
|
||||
|
||||
QString findHash = QString("%1%2%3").arg(find).arg(flags).arg((int)context);
|
||||
|
||||
// if we didn't have a valid previous find, just do a find and bail
|
||||
if(findHash != m_FindState.hash)
|
||||
{
|
||||
performFind();
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_FindState.prevResult.first == -1)
|
||||
return;
|
||||
|
||||
cur->setTargetRange(m_FindState.prevResult.first, m_FindState.prevResult.second);
|
||||
|
||||
FindState save = m_FindState;
|
||||
|
||||
QString replaceText = m_FindReplace->replaceText();
|
||||
|
||||
// otherwise we have a valid previous find. Do the replace now
|
||||
// note this will invalidate the find state (as most user operations would), so we save/restore
|
||||
// the state
|
||||
if(m_FindReplace->regexp())
|
||||
cur->replaceTargetRE(-1, replaceText.toUtf8().data());
|
||||
else
|
||||
cur->replaceTarget(-1, replaceText.toUtf8().data());
|
||||
|
||||
m_FindState = save;
|
||||
|
||||
// adjust the offset if we replaced text and it went up or down in size
|
||||
m_FindState.offset += (replaceText.count() - find.count());
|
||||
|
||||
// move to the next result
|
||||
performFind();
|
||||
}
|
||||
|
||||
void ShaderViewer::performReplaceAll()
|
||||
{
|
||||
ScintillaEdit *cur = currentScintilla();
|
||||
|
||||
if(!cur)
|
||||
return;
|
||||
|
||||
QString find = m_FindReplace->findText();
|
||||
QString replace = m_FindReplace->replaceText();
|
||||
|
||||
if(find.isEmpty())
|
||||
return;
|
||||
|
||||
sptr_t flags = 0;
|
||||
|
||||
if(m_FindReplace->matchCase())
|
||||
flags |= SCFIND_MATCHCASE;
|
||||
if(m_FindReplace->matchWord())
|
||||
flags |= SCFIND_WHOLEWORD;
|
||||
if(m_FindReplace->regexp())
|
||||
flags |= SCFIND_REGEXP | SCFIND_POSIX;
|
||||
|
||||
FindReplace::SearchContext context = m_FindReplace->context();
|
||||
|
||||
(void)context;
|
||||
|
||||
// trash the find state for any incremental finds
|
||||
m_FindState = FindState();
|
||||
|
||||
QList<ScintillaEdit *> scintillas = m_Scintillas;
|
||||
|
||||
if(context == FindReplace::File)
|
||||
scintillas = {cur};
|
||||
|
||||
int numReplacements = 1;
|
||||
|
||||
for(ScintillaEdit *s : scintillas)
|
||||
{
|
||||
sptr_t start = 0;
|
||||
sptr_t end = s->length();
|
||||
|
||||
QPair<int, int> result;
|
||||
|
||||
QByteArray findUtf8 = find.toUtf8();
|
||||
QByteArray replaceUtf8 = replace.toUtf8();
|
||||
|
||||
do
|
||||
{
|
||||
result = s->findText(flags, findUtf8.data(), start, end);
|
||||
|
||||
if(result.first >= 0)
|
||||
{
|
||||
s->setTargetRange(result.first, result.second);
|
||||
|
||||
if(m_FindReplace->regexp())
|
||||
s->replaceTargetRE(-1, replaceUtf8.data());
|
||||
else
|
||||
s->replaceTarget(-1, replaceUtf8.data());
|
||||
|
||||
numReplacements++;
|
||||
}
|
||||
|
||||
start = result.second + (replaceUtf8.count() - findUtf8.count());
|
||||
|
||||
} while(result.first >= 0);
|
||||
}
|
||||
|
||||
RDDialog::information(
|
||||
this, tr("Replace all"),
|
||||
tr("%1 replacements made in %2 files").arg(numReplacements).arg(scintillas.count()));
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ class ShaderViewer;
|
||||
struct ShaderDebugTrace;
|
||||
struct ShaderReflection;
|
||||
class ScintillaEdit;
|
||||
class FindReplace;
|
||||
|
||||
// from Scintilla
|
||||
typedef intptr_t sptr_t;
|
||||
@@ -101,6 +102,10 @@ private slots:
|
||||
void readonly_keyPressed(QKeyEvent *event);
|
||||
void editable_keyPressed(QKeyEvent *event);
|
||||
void disassembly_buttonReleased(QMouseEvent *event);
|
||||
void performFind();
|
||||
void performFindAll();
|
||||
void performReplace();
|
||||
void performReplaceAll();
|
||||
|
||||
public slots:
|
||||
bool stepBack();
|
||||
@@ -124,8 +129,27 @@ private:
|
||||
ShaderStageType m_Stage;
|
||||
ScintillaEdit *m_DisassemblyView = NULL;
|
||||
ScintillaEdit *m_Errors = NULL;
|
||||
ScintillaEdit *m_FindResults = NULL;
|
||||
QList<ScintillaEdit *> m_Scintillas;
|
||||
|
||||
FindReplace *m_FindReplace;
|
||||
|
||||
struct FindState
|
||||
{
|
||||
// hash identifies when the search has changed
|
||||
QString hash;
|
||||
|
||||
// the range identified when the search first occurred (for incremental find/replace)
|
||||
sptr_t start = 0;
|
||||
sptr_t end = 0;
|
||||
|
||||
// the current offset where to search from next time, relative to above range
|
||||
sptr_t offset = 0;
|
||||
|
||||
// the last result
|
||||
QPair<int, int> prevResult;
|
||||
} m_FindState;
|
||||
|
||||
SaveMethod m_SaveCallback;
|
||||
CloseMethod m_CloseCallback;
|
||||
|
||||
@@ -137,14 +161,25 @@ private:
|
||||
static const int BREAKPOINT_MARKER = 2;
|
||||
static const int FINISHED_MARKER = 4;
|
||||
|
||||
static const int INDICATOR_FINDRESULT = 0;
|
||||
static const int INDICATOR_REGHIGHLIGHT = 1;
|
||||
|
||||
void addFileList();
|
||||
|
||||
ScintillaEdit *MakeEditor(const QString &name, const QString &text, bool src);
|
||||
ScintillaEdit *MakeEditor(const QString &name, const QString &text, int lang);
|
||||
ScintillaEdit *AddFileScintilla(const QString &name, const QString &text);
|
||||
|
||||
ScintillaEdit *currentScintilla();
|
||||
ScintillaEdit *nextScintilla(ScintillaEdit *cur);
|
||||
|
||||
int instructionForLine(sptr_t line);
|
||||
|
||||
void updateDebugging();
|
||||
|
||||
void ensureLineScrolled(ScintillaEdit *s, int i);
|
||||
|
||||
void find(bool down);
|
||||
|
||||
void runTo(int runToInstruction, bool forward, ShaderDebugStateFlags condition = eShaderDbg_None);
|
||||
|
||||
QString stringRep(const ShaderVariable &var, bool useType);
|
||||
|
||||
@@ -147,7 +147,8 @@ SOURCES += Code/qrenderdoc.cpp \
|
||||
Windows/Dialogs/RemoteManager.cpp \
|
||||
Windows/PixelHistoryView.cpp \
|
||||
Widgets/PipelineFlowChart.cpp \
|
||||
Windows/Dialogs/EnvironmentEditor.cpp
|
||||
Windows/Dialogs/EnvironmentEditor.cpp \
|
||||
Widgets/FindReplace.cpp
|
||||
|
||||
HEADERS += Code/CaptureContext.h \
|
||||
Code/qprocessinfo.h \
|
||||
@@ -197,7 +198,8 @@ HEADERS += Code/CaptureContext.h \
|
||||
Windows/Dialogs/RemoteManager.h \
|
||||
Windows/PixelHistoryView.h \
|
||||
Widgets/PipelineFlowChart.h \
|
||||
Windows/Dialogs/EnvironmentEditor.h
|
||||
Windows/Dialogs/EnvironmentEditor.h \
|
||||
Widgets/FindReplace.h
|
||||
|
||||
FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/MainWindow.ui \
|
||||
@@ -226,7 +228,8 @@ FORMS += Windows/Dialogs/AboutDialog.ui \
|
||||
Windows/Dialogs/VirtualFileDialog.ui \
|
||||
Windows/Dialogs/RemoteManager.ui \
|
||||
Windows/PixelHistoryView.ui \
|
||||
Windows/Dialogs/EnvironmentEditor.ui
|
||||
Windows/Dialogs/EnvironmentEditor.ui \
|
||||
Widgets/FindReplace.ui
|
||||
|
||||
RESOURCES += Resources/resources.qrc
|
||||
|
||||
|
||||
@@ -631,6 +631,7 @@
|
||||
<ClCompile Include="$(IntDir)generated\moc_AboutDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_APIInspector.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_BufferFormatSpecifier.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_FindReplace.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_BufferViewer.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_CaptureDialog.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\moc_ConstantBufferPreviewer.cpp" />
|
||||
@@ -687,6 +688,7 @@
|
||||
<ClCompile Include="$(IntDir)generated\moc_VulkanPipelineStateViewer.cpp" />
|
||||
<ClCompile Include="$(IntDir)generated\qrc_resources.cpp" />
|
||||
<ClCompile Include="Widgets\BufferFormatSpecifier.cpp" />
|
||||
<ClCompile Include="Widgets\FindReplace.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDListWidget.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTableView.cpp" />
|
||||
<ClCompile Include="Widgets\Extended\RDTableWidget.cpp" />
|
||||
@@ -850,6 +852,7 @@
|
||||
<ClInclude Include="$(IntDir)generated\ui_AboutDialog.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_APIInspector.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_BufferFormatSpecifier.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_FindReplace.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_BufferViewer.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_CaptureDialog.h" />
|
||||
<ClInclude Include="$(IntDir)generated\ui_ConstantBufferPreviewer.h" />
|
||||
@@ -895,6 +898,12 @@
|
||||
<Message>MOC %(Filename).h</Message>
|
||||
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\FindReplace.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\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\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="Widgets\CustomPaintWidget.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\$(Platform)\include -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtWidgets -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtGui -I$(ProjectDir)3rdparty\qt\$(Platform)\include\QtCore %(Fullpath) -o $(IntDir)generated\moc_%(Filename).cpp</Command>
|
||||
@@ -1143,6 +1152,12 @@
|
||||
<Message>UIC %(Filename).ui</Message>
|
||||
<Outputs>$(IntDir)generated\ui_%(Filename).h</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\FindReplace.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="Widgets\ResourcePreview.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>
|
||||
|
||||
@@ -537,6 +537,12 @@
|
||||
<ClCompile Include="Windows\Dialogs\EnvironmentEditor.cpp">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Widgets\FindReplace.cpp">
|
||||
<Filter>Widgets</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(IntDir)generated\moc_FindReplace.cpp">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
|
||||
@@ -830,6 +836,9 @@
|
||||
<ClInclude Include="$(IntDir)generated\ui_VulkanPipelineStateViewer.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(IntDir)generated\ui_FindReplace.h">
|
||||
<Filter>Generated Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources\128.png">
|
||||
@@ -1247,5 +1256,11 @@
|
||||
<CustomBuild Include="Windows\Dialogs\EnvironmentEditor.h">
|
||||
<Filter>Windows\Dialogs</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\FindReplace.ui">
|
||||
<Filter>Widgets</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="Widgets\FindReplace.h">
|
||||
<Filter>Widgets</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user