Add environment variable editor for capture dialog in Qt

This commit is contained in:
baldurk
2017-02-15 16:23:59 +00:00
parent a3e31489f8
commit 8b760ced92
7 changed files with 603 additions and 4 deletions
+10 -1
View File
@@ -29,6 +29,7 @@
#include "3rdparty/toolwindowmanager/ToolWindowManager.h"
#include "Code/QRDUtils.h"
#include "Code/qprocessinfo.h"
#include "Windows/Dialogs/EnvironmentEditor.h"
#include "Windows/Dialogs/VirtualFileDialog.h"
#include "LiveCapture.h"
#include "ui_CaptureDialog.h"
@@ -498,7 +499,15 @@ void CaptureDialog::on_workDirBrowse_clicked()
void CaptureDialog::on_envVarEdit_clicked()
{
// TODO Env Editor
EnvironmentEditor envEditor(this);
for(const EnvironmentModification &mod : m_EnvModifications)
envEditor.addModification(mod, true);
int res = RDDialog::show(&envEditor);
if(res)
setEnvironmentModifications(envEditor.modifications());
}
void CaptureDialog::on_toggleGlobal_clicked()
@@ -0,0 +1,260 @@
/******************************************************************************
* The MIT License (MIT)
*
* Copyright (c) 2016-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 "EnvironmentEditor.h"
#include <QCompleter>
#include <QFontDatabase>
#include <QKeyEvent>
#include "Code/QRDUtils.h"
#include "ui_EnvironmentEditor.h"
Q_DECLARE_METATYPE(EnvironmentModification);
EnvironmentEditor::EnvironmentEditor(QWidget *parent)
: QDialog(parent), ui(new Ui::EnvironmentEditor)
{
ui->setupUi(this);
auto commitLambda = [this](QKeyEvent *event) {
if(event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter)
on_addUpdate_clicked();
};
QObject::connect(ui->name, &RDLineEdit::keyPress, commitLambda);
QObject::connect(ui->value, &RDLineEdit::keyPress, commitLambda);
auto separatorLambda = [this]() { ui->separator->setEnabled(!ui->setValue->isChecked()); };
QObject::connect(ui->setValue, &QRadioButton::toggled, separatorLambda);
QObject::connect(ui->prependValue, &QRadioButton::toggled, separatorLambda);
QObject::connect(ui->appendValue, &QRadioButton::toggled, separatorLambda);
ui->separator->addItems({
ToQStr(eEnvSep_Platform), ToQStr(eEnvSep_SemiColon), ToQStr(eEnvSep_Colon), ToQStr(eEnvSep_None),
});
ui->separator->setCurrentIndex(0);
ui->setValue->setChecked(true);
ui->name->setFocus();
m_Completer = new QCompleter({}, this);
ui->name->setCompleter(m_Completer);
ui->variables->header()->setSectionResizeMode(0, QHeaderView::Interactive);
ui->variables->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
ui->variables->setClearSelectionOnFocusLoss(false);
ui->variables->sortByColumn(0, Qt::DescendingOrder);
ui->variables->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont));
}
EnvironmentEditor::~EnvironmentEditor()
{
delete ui;
}
void EnvironmentEditor::on_name_textChanged(const QString &text)
{
int idx = existingIndex();
if(idx >= 0)
{
ui->addUpdate->setText(tr("Update"));
ui->deleteButton->setEnabled(true);
ui->variables->clearSelection();
ui->variables->topLevelItem(idx)->setSelected(true);
}
else
{
ui->addUpdate->setText(tr("Add"));
ui->deleteButton->setEnabled(false);
ui->addUpdate->setEnabled(!text.trimmed().isEmpty());
}
}
void EnvironmentEditor::on_variables_keyPress(QKeyEvent *event)
{
if(event->key() == Qt::Key_Delete && ui->deleteButton->isEnabled())
on_deleteButton_clicked();
}
void EnvironmentEditor::on_variables_currentItemChanged(QTreeWidgetItem *current,
QTreeWidgetItem *previous)
{
QList<QTreeWidgetItem *> sel = ui->variables->selectedItems();
if(sel.isEmpty())
return;
EnvironmentModification mod = sel[0]->data(0, Qt::UserRole).value<EnvironmentModification>();
if(!mod.variable.isEmpty())
{
ui->name->setText(mod.variable);
ui->value->setText(mod.value);
ui->separator->setCurrentIndex((int)mod.separator);
if(mod.type == eEnvMod_Set)
ui->setValue->setChecked(true);
else if(mod.type == eEnvMod_Append)
ui->appendValue->setChecked(true);
else if(mod.type == eEnvMod_Prepend)
ui->prependValue->setChecked(true);
}
}
void EnvironmentEditor::on_addUpdate_clicked()
{
EnvironmentModification mod;
mod.variable = ui->name->text();
mod.value = ui->value->text();
mod.separator = (EnvironmentSeparator)ui->separator->currentIndex();
if(ui->appendValue->isChecked())
mod.type = eEnvMod_Append;
else if(ui->prependValue->isChecked())
mod.type = eEnvMod_Prepend;
else
mod.type = eEnvMod_Set;
addModification(mod, false);
on_name_textChanged(ui->name->text());
}
void EnvironmentEditor::on_deleteButton_clicked()
{
QList<QTreeWidgetItem *> sel = ui->variables->selectedItems();
if(sel.isEmpty())
return;
delete ui->variables->takeTopLevelItem(ui->variables->indexOfTopLevelItem(sel[0]));
on_name_textChanged(ui->name->text());
}
int EnvironmentEditor::existingIndex()
{
QString name = ui->name->text();
for(int i = 0; i < ui->variables->topLevelItemCount(); i++)
if(ui->variables->topLevelItem(i)->text(0) == name)
return i;
return -1;
}
void EnvironmentEditor::addModification(EnvironmentModification mod, bool silent)
{
if(mod.variable.trimmed() == "")
{
if(!silent)
RDDialog::critical(this, tr("Invalid variable"),
tr("Environment variable cannot be just whitespace"));
return;
}
QTreeWidgetItem *node = NULL;
int idx = existingIndex();
if(idx < 0)
{
node = makeTreeNode({mod.variable, mod.GetTypeString(), mod.value});
ui->variables->addTopLevelItem(node);
}
else
{
node = ui->variables->topLevelItem(idx);
node->setText(0, mod.variable);
node->setText(1, mod.GetTypeString());
node->setText(2, mod.value);
}
node->setData(0, Qt::UserRole, QVariant::fromValue(mod));
ui->variables->clearSelection();
node->setSelected(true);
delete m_Completer;
QStringList names;
for(int i = 0; i < ui->variables->topLevelItemCount(); i++)
names << ui->variables->topLevelItem(i)->text(0);
m_Completer = new QCompleter(names, this);
ui->name->setCompleter(m_Completer);
}
QList<EnvironmentModification> EnvironmentEditor::modifications()
{
QList<EnvironmentModification> ret;
for(int i = 0; i < ui->variables->topLevelItemCount(); i++)
{
EnvironmentModification mod =
ui->variables->topLevelItem(i)->data(0, Qt::UserRole).value<EnvironmentModification>();
if(!mod.variable.isEmpty())
ret.push_back(mod);
}
return ret;
}
void EnvironmentEditor::on_buttonBox_accepted()
{
int idx = existingIndex();
if(idx >= 0 || ui->name->text().isEmpty())
{
accept();
return;
}
QMessageBox::StandardButton res = RDDialog::question(
this, tr("Variable not added"),
tr("You did not add the variable modification you were editing. Add it now?"),
RDDialog::YesNoCancel, QMessageBox::Yes);
if(res == QMessageBox::Yes)
{
on_addUpdate_clicked();
}
else if(res == QMessageBox::Cancel)
{
// don't close
return;
}
accept();
}
@@ -0,0 +1,63 @@
/******************************************************************************
* 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 <QDialog>
#include "Code/RenderManager.h"
namespace Ui
{
class EnvironmentEditor;
}
class QTreeWidgetItem;
class QCompleter;
class EnvironmentEditor : public QDialog
{
Q_OBJECT
public:
explicit EnvironmentEditor(QWidget *parent = 0);
~EnvironmentEditor();
void addModification(EnvironmentModification mod, bool silent);
QList<EnvironmentModification> modifications();
public slots:
// automatic slots
void on_name_textChanged(const QString &text);
void on_addUpdate_clicked();
void on_deleteButton_clicked();
void on_variables_keyPress(QKeyEvent *event);
void on_variables_currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);
void on_buttonBox_accepted();
private:
Ui::EnvironmentEditor *ui;
QCompleter *m_Completer;
int existingIndex();
};
@@ -0,0 +1,237 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>EnvironmentEditor</class>
<widget class="QDialog" name="EnvironmentEditor">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>418</height>
</rect>
</property>
<property name="windowTitle">
<string>Environment Variables</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<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>
<property name="spacing">
<number>4</number>
</property>
<item row="0" column="0" colspan="2">
<widget class="RDTreeWidget" name="variables">
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="indentation">
<number>0</number>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Modification</string>
</property>
</column>
<column>
<property name="text">
<string>Value</string>
</property>
</column>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>100</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Environment Variable</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="nameLabel">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item>
<widget class="RDLineEdit" name="name"/>
</item>
<item>
<widget class="QLabel" name="valueLabel">
<property name="text">
<string>Value</string>
</property>
</widget>
</item>
<item>
<widget class="RDLineEdit" name="value"/>
</item>
</layout>
</widget>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Modification type</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="setValue">
<property name="text">
<string>Set Value</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="appendValue">
<property name="text">
<string>Append Value</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="prependValue">
<property name="text">
<string>Prepend Value</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="separator"/>
</item>
</layout>
</widget>
</item>
<item row="2" column="1">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>25</number>
</property>
<item>
<widget class="QFrame" name="frame">
<layout class="QHBoxLayout" name="horizontalLayout">
<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>
<widget class="QPushButton" name="addUpdate">
<property name="text">
<string>Add / Update</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="deleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>RDLineEdit</class>
<extends>QLineEdit</extends>
<header>Widgets/Extended/RDLineEdit.h</header>
</customwidget>
<customwidget>
<class>RDTreeWidget</class>
<extends>QTreeWidget</extends>
<header>Widgets/Extended/RDTreeWidget.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>EnvironmentEditor</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
+6 -3
View File
@@ -146,7 +146,8 @@ SOURCES += Code/qrenderdoc.cpp \
Windows/Dialogs/VirtualFileDialog.cpp \
Windows/Dialogs/RemoteManager.cpp \
Windows/PixelHistoryView.cpp \
Widgets/PipelineFlowChart.cpp
Widgets/PipelineFlowChart.cpp \
Windows/Dialogs/EnvironmentEditor.cpp
HEADERS += Code/CaptureContext.h \
Code/qprocessinfo.h \
@@ -195,7 +196,8 @@ HEADERS += Code/CaptureContext.h \
Windows/Dialogs/VirtualFileDialog.h \
Windows/Dialogs/RemoteManager.h \
Windows/PixelHistoryView.h \
Widgets/PipelineFlowChart.h
Widgets/PipelineFlowChart.h \
Windows/Dialogs/EnvironmentEditor.h
FORMS += Windows/Dialogs/AboutDialog.ui \
Windows/MainWindow.ui \
@@ -223,7 +225,8 @@ FORMS += Windows/Dialogs/AboutDialog.ui \
Windows/Dialogs/SuggestRemoteDialog.ui \
Windows/Dialogs/VirtualFileDialog.ui \
Windows/Dialogs/RemoteManager.ui \
Windows/PixelHistoryView.ui
Windows/PixelHistoryView.ui \
Windows/Dialogs/EnvironmentEditor.ui
RESOURCES += Resources/resources.qrc
+15
View File
@@ -641,6 +641,7 @@
<ClCompile Include="$(IntDir)generated\moc_EventBrowser.cpp" />
<ClCompile Include="$(IntDir)generated\moc_GLPipelineStateViewer.cpp" />
<ClCompile Include="$(IntDir)generated\moc_LiveCapture.cpp" />
<ClCompile Include="$(IntDir)generated\moc_EnvironmentEditor.cpp" />
<ClCompile Include="$(IntDir)generated\moc_OrderedListEditor.cpp" />
<ClCompile Include="$(IntDir)generated\moc_RemoteManager.cpp" />
<ClCompile Include="$(IntDir)generated\moc_PipelineStateViewer.cpp" />
@@ -708,6 +709,7 @@
<ClCompile Include="Windows\Dialogs\AboutDialog.cpp" />
<ClCompile Include="Windows\Dialogs\CaptureDialog.cpp" />
<ClCompile Include="Windows\Dialogs\LiveCapture.cpp" />
<ClCompile Include="Windows\Dialogs\EnvironmentEditor.cpp" />
<ClCompile Include="Windows\Dialogs\OrderedListEditor.cpp" />
<ClCompile Include="Windows\Dialogs\RemoteManager.cpp" />
<ClCompile Include="Windows\Dialogs\SettingsDialog.cpp" />
@@ -858,6 +860,7 @@
<ClInclude Include="$(IntDir)generated\ui_GLPipelineStateViewer.h" />
<ClInclude Include="$(IntDir)generated\ui_LiveCapture.h" />
<ClInclude Include="$(IntDir)generated\ui_MainWindow.h" />
<ClInclude Include="$(IntDir)generated\ui_EnvironmentEditor.h" />
<ClInclude Include="$(IntDir)generated\ui_OrderedListEditor.h" />
<ClInclude Include="$(IntDir)generated\ui_RemoteManager.h" />
<ClInclude Include="$(IntDir)generated\ui_PipelineStateViewer.h" />
@@ -1024,6 +1027,12 @@
<Message>MOC %(Filename).h</Message>
<Outputs>$(IntDir)generated\moc_%(Filename).cpp</Outputs>
</CustomBuild>
<CustomBuild Include="Windows\Dialogs\EnvironmentEditor.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="Windows\Dialogs\OrderedListEditor.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>
@@ -1189,6 +1198,12 @@
<Outputs>$(IntDir)generated\ui_%(Filename).h</Outputs>
<SubType>Designer</SubType>
</CustomBuild>
<CustomBuild Include="Windows\Dialogs\EnvironmentEditor.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\Dialogs\OrderedListEditor.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>
@@ -531,6 +531,12 @@
<ClCompile Include="$(IntDir)generated\qrc_resources.cpp">
<Filter>Generated Files</Filter>
</ClCompile>
<ClCompile Include="$(IntDir)generated\moc_EnvironmentEditor.cpp">
<Filter>Generated Files</Filter>
</ClCompile>
<ClCompile Include="Windows\Dialogs\EnvironmentEditor.cpp">
<Filter>Windows\Dialogs</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="3rdparty\flowlayout\FlowLayout.h">
@@ -1235,5 +1241,11 @@
<CustomBuild Include="Widgets\PipelineFlowChart.h">
<Filter>Widgets</Filter>
</CustomBuild>
<CustomBuild Include="Windows\Dialogs\EnvironmentEditor.ui">
<Filter>Windows\Dialogs</Filter>
</CustomBuild>
<CustomBuild Include="Windows\Dialogs\EnvironmentEditor.h">
<Filter>Windows\Dialogs</Filter>
</CustomBuild>
</ItemGroup>
</Project>