Skip to content

Commit 6027455

Browse files
committed
Fix #262 #263 - Handle Path Arguments
1 parent 20695ee commit 6027455

File tree

6 files changed

+159
-13
lines changed

6 files changed

+159
-13
lines changed

src/shared_gui_components/EditController.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "EditView.hpp"
88
#include "OSViewSwitcher.hpp"
99
#include "WorkflowController.hpp"
10+
#include "../model_editor/Utilities.hpp"
1011

1112
#include <openstudio/utilities/bcl/BCLMeasure.hpp>
1213
#include <openstudio/utilities/core/Assert.hpp>
@@ -251,6 +252,22 @@ InputController::InputController(EditController* editController, measure::OSArgu
251252
static_cast<void (InputController::*)(const QString&)>(&InputController::setValue));
252253

253254
inputView = stringInputView;
255+
} else if (m_argument.type() == measure::OSArgumentType::Path) {
256+
auto* pathInputView = new PathInputView(m_argument.extension(), m_argument.isRead());
257+
258+
pathInputView->setName(m_argument.displayName(), m_argument.units(), m_argument.description());
259+
260+
if (m_argument.hasValue()) {
261+
pathInputView->lineEdit->setText(QString::fromStdString(m_argument.valueAsString()));
262+
} else if (m_argument.hasDefaultValue()) {
263+
pathInputView->lineEdit->setText(QString::fromStdString(m_argument.defaultValueAsString()));
264+
}
265+
266+
connect(pathInputView, &PathInputView::selectedPathChanged, this,
267+
static_cast<void (InputController::*)(const openstudio::path&)>(&InputController::setValue));
268+
connect(pathInputView->lineEdit, &QLineEdit::textEdited, [this](const QString& v) { this->setValue(toPath(v)); });
269+
270+
inputView = pathInputView;
254271
} else {
255272
inputView = new InputView();
256273
}
@@ -302,6 +319,20 @@ void InputController::setValueForIndex(int index) {
302319
}
303320
}
304321

322+
void InputController::setValue(const openstudio::path& p) {
323+
if (isItOKToClearResults()) {
324+
if (p.empty()) {
325+
m_argument.clearValue();
326+
} else {
327+
m_argument.setValue(p);
328+
}
329+
330+
m_editController->measureStepItem()->setArgument(m_argument);
331+
332+
inputView->setIncomplete(isArgumentIncomplete());
333+
}
334+
}
335+
305336
bool InputController::isArgumentIncomplete() const {
306337
bool result = false;
307338
std::vector<measure::OSArgument> incompleteArguments = m_editController->measureStepItem()->incompleteArguments();

src/shared_gui_components/EditController.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ class InputController : public QObject
8181

8282
void setValue(bool value);
8383

84+
void setValue(const openstudio::path& p);
85+
8486
void setValueForIndex(int index);
8587

8688
private:

src/shared_gui_components/EditView.cpp

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
***********************************************************************************************************************/
55

66
#include "EditView.hpp"
7+
#include "../model_editor/Utilities.hpp"
8+
79
#include <QVBoxLayout>
810
#include <QHBoxLayout>
911
#include <QLabel>
@@ -18,6 +20,8 @@
1820
#include <QCheckBox>
1921
#include <QWheelEvent>
2022
#include <QApplication>
23+
#include <QPushButton>
24+
#include <QFileDialog>
2125

2226
#include <openstudio/utilities/core/Assert.hpp>
2327

@@ -369,8 +373,6 @@ InputCheckBox::InputCheckBox() : QAbstractButton() {
369373
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
370374
}
371375

372-
InputCheckBox::~InputCheckBox() = default;
373-
374376
void InputCheckBox::setText(const QString& text) {
375377
m_label->setText(text);
376378

@@ -400,4 +402,80 @@ void InputCheckBox::setIncomplete(bool incomplete) {
400402
}
401403
}
402404

405+
PathInputView::PathInputView(const std::string& extension, bool isRead)
406+
: InputView(), lineEdit(new QLineEdit()), nameLabel(new QLabel()), m_isRead(isRead) {
407+
auto* vLayout = new QVBoxLayout();
408+
vLayout->setContentsMargins(0, 0, 0, 0);
409+
vLayout->setSpacing(5);
410+
setLayout(vLayout);
411+
412+
nameLabel->setOpenExternalLinks(true);
413+
nameLabel->setWordWrap(true);
414+
vLayout->addWidget(nameLabel);
415+
416+
auto* hLayout = new QHBoxLayout();
417+
hLayout->addWidget(lineEdit);
418+
419+
selectPathButton = new QPushButton("...");
420+
selectPathButton->setFlat(true);
421+
selectPathButton->setFixedSize(30, 20);
422+
selectPathButton->setObjectName("StandardGrayButton");
423+
424+
connect(selectPathButton, &QPushButton::clicked, this, &PathInputView::onSelectPathButtonClicked);
425+
hLayout->addWidget(selectPathButton);
426+
427+
vLayout->addLayout(hLayout);
428+
429+
// TODO: sanitize the input?
430+
m_extension = toQString(extension);
431+
}
432+
433+
void PathInputView::setName(const std::string& name, const boost::optional<std::string>& units, const boost::optional<std::string>& description) {
434+
QString text;
435+
text += QString::fromStdString(name);
436+
if (units) {
437+
text += QString::fromStdString(" (" + units.get() + ")");
438+
}
439+
if (description) {
440+
text += QString::fromStdString("<div style=\"font-size:small;margin-top:2px;\">" + description.get() + "</div>");
441+
}
442+
443+
nameLabel->setText(text);
444+
}
445+
446+
void PathInputView::setIncomplete(bool incomplete) {
447+
if (incomplete) {
448+
nameLabel->setStyleSheet("QLabel { color: #DD0A05;}");
449+
} else {
450+
nameLabel->setStyleSheet("QLabel { color: black;}");
451+
}
452+
}
453+
454+
void PathInputView::setDisplayValue(const QVariant& value) {
455+
lineEdit->setText(value.toString());
456+
}
457+
458+
void PathInputView::onSelectPathButtonClicked() {
459+
QString lastPath = lineEdit->text();
460+
461+
QString selectedPath;
462+
463+
if (m_extension.isEmpty()) {
464+
// Assume this is a directory
465+
selectedPath =
466+
QFileDialog::getExistingDirectory(nullptr, tr("Open Directory"), lastPath, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
467+
} else {
468+
if (m_isRead) {
469+
selectedPath = QFileDialog::getOpenFileName(nullptr, tr("Open Read File"), lastPath, m_extension);
470+
} else {
471+
selectedPath = QFileDialog::getSaveFileName(nullptr, tr("Select Save File"), lastPath, m_extension);
472+
}
473+
}
474+
475+
if (!selectedPath.isEmpty()) {
476+
lineEdit->setText(selectedPath); // QFileInfo(selectedPath).absoluteFilePath()
477+
emit selectedPathChanged(toPath(selectedPath));
478+
}
479+
}
480+
403481
} // namespace openstudio

src/shared_gui_components/EditView.hpp

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,16 @@
66
#ifndef SHAREDGUICOMPONENTS_EDITVIEW_HPP
77
#define SHAREDGUICOMPONENTS_EDITVIEW_HPP
88

9-
#include <QWidget>
10-
#include <QComboBox>
119
#include <QAbstractButton>
10+
#include <QComboBox>
1211
#include <QLabel>
12+
#include <QWidget>
1313

1414
#include <boost/optional.hpp>
15+
#include <openstudio/utilities/core/Filesystem.hpp>
1516

1617
class QLineEdit;
18+
class QPushButton;
1719
class QTextEdit;
1820
class QVBoxLayout;
1921

@@ -27,7 +29,7 @@ class EditNullView : public QWidget
2729

2830
public:
2931
explicit EditNullView(const QString& text = "Select a Measure to Edit");
30-
virtual ~EditNullView() {}
32+
virtual ~EditNullView() = default;
3133

3234
protected:
3335
void paintEvent(QPaintEvent*) override;
@@ -39,7 +41,7 @@ class EditRubyMeasureView : public QWidget
3941

4042
public:
4143
explicit EditRubyMeasureView(bool applyMeasureNow);
42-
virtual ~EditRubyMeasureView() {}
44+
virtual ~EditRubyMeasureView() = default;
4345

4446
QLineEdit* nameLineEdit;
4547

@@ -77,7 +79,7 @@ class DoubleInputView : public InputView
7779

7880
public:
7981
DoubleInputView();
80-
virtual ~DoubleInputView() {}
82+
virtual ~DoubleInputView() = default;
8183

8284
QLineEdit* lineEdit;
8385

@@ -97,7 +99,7 @@ class ChoiceInputView : public InputView
9799

98100
public:
99101
ChoiceInputView();
100-
virtual ~ChoiceInputView() {}
102+
virtual ~ChoiceInputView() = default;
101103

102104
QComboBox* comboBox;
103105

@@ -117,7 +119,7 @@ class BoolInputView : public InputView
117119

118120
public:
119121
BoolInputView();
120-
virtual ~BoolInputView() {}
122+
virtual ~BoolInputView() = default;
121123

122124
InputCheckBox* checkBox;
123125

@@ -134,7 +136,7 @@ class IntegerInputView : public InputView
134136

135137
public:
136138
IntegerInputView();
137-
virtual ~IntegerInputView() {}
139+
virtual ~IntegerInputView() = default;
138140

139141
QLineEdit* lineEdit;
140142

@@ -154,7 +156,7 @@ class StringInputView : public InputView
154156

155157
public:
156158
StringInputView();
157-
virtual ~StringInputView() {}
159+
virtual ~StringInputView() = default;
158160

159161
QLineEdit* lineEdit;
160162

@@ -183,7 +185,7 @@ class InputCheckBox : public QAbstractButton
183185
public:
184186
InputCheckBox();
185187

186-
virtual ~InputCheckBox();
188+
virtual ~InputCheckBox() = default;
187189

188190
void setText(const QString& text);
189191

@@ -196,6 +198,35 @@ class InputCheckBox : public QAbstractButton
196198
QLabel* m_label;
197199
};
198200

201+
class PathInputView : public InputView
202+
{
203+
Q_OBJECT
204+
205+
public:
206+
PathInputView(const std::string& extension, bool isRead);
207+
virtual ~PathInputView() = default;
208+
209+
QLineEdit* lineEdit;
210+
QPushButton* selectPathButton;
211+
212+
void setName(const std::string& name, const boost::optional<std::string>& units, const boost::optional<std::string>& description);
213+
214+
void setIncomplete(bool incomplete) override;
215+
216+
void setDisplayValue(const QVariant& value) override;
217+
218+
signals:
219+
void selectedPathChanged(const openstudio::path& p);
220+
221+
private slots:
222+
void onSelectPathButtonClicked();
223+
224+
private:
225+
QLabel* nameLabel;
226+
QString m_extension;
227+
bool m_isRead;
228+
};
229+
199230
} // namespace openstudio
200231

201232
#endif // SHAREDGUICOMPONENTS_EDITVIEW_HPP

src/shared_gui_components/MeasureManager.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,8 +607,10 @@ boost::optional<measure::OSArgument> MeasureManager::getArgument(const measure::
607607

608608
} else if (type.value() == measure::OSArgumentType::Path) {
609609

610+
// TODO: aside from the fact that these arguments are weird / incorrectly named, neither the BCL-gem schema nor OS SDK actually handle them so
611+
// they are not even inside the measure.xml
610612
bool isRead = argument.get("is_read", Json::Value(false)).asBool();
611-
std::string extension = argument.get("extension", Json::Value("*")).asString();
613+
std::string extension = argument.get("extension", Json::Value("All files (*)")).asString();
612614

613615
result = measure::OSArgument::makePathArgument(name, isRead, extension, required, modelDependent);
614616

src/shared_gui_components/WorkflowController.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,8 @@ void MeasureStepItem::setArgument(const measure::OSArgument& argument) {
501501
m_step.setArgument(argument.name(), argument.valueAsDouble());
502502
} else if (argument.type() == measure::OSArgumentType::Integer) {
503503
m_step.setArgument(argument.name(), argument.valueAsInteger());
504+
} else if (argument.type() == measure::OSArgumentType::Path) {
505+
m_step.setArgument(argument.name(), openstudio::toString(argument.valueAsPath()));
504506
} else {
505507
m_step.setArgument(argument.name(), argument.valueAsString());
506508
}

0 commit comments

Comments
 (0)