Mantid
Loading...
Searching...
No Matches
DataSelector.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
12#include "MantidAPI/Workspace.h"
15
16#include <QFileInfo>
17
18#include <QDebug>
19#include <QDropEvent>
20#include <QMimeData>
21#include <QUrl>
22
23using namespace Mantid::API;
24
25namespace {
26auto &ads = AnalysisDataService::Instance();
27
28std::string cutLastOf(const std::string &str, const std::string &delimiter) {
29 const auto cutIndex = str.rfind(delimiter);
30 if (cutIndex != std::string::npos)
31 return str.substr(0, cutIndex);
32 return str;
33}
34
35std::string extractLastOf(const std::string &str, const std::string &delimiter) {
36 const auto cutIndex = str.rfind(delimiter);
37 if (cutIndex != std::string::npos)
38 return str.substr(cutIndex + 1, str.size() - cutIndex);
39 return str;
40}
41
42bool fileFound(std::string const &file) { return !FileFinder::Instance().getFullPath(file).empty(); }
43
44std::string loadAlgName(const std::string &filePath) {
45 const auto suffix = extractLastOf(filePath, ".");
46 return suffix == "dave" ? "LoadDaveGrp" : "Load";
47}
48
49void makeGroup(std::string const &workspaceName) {
50 if (!ads.retrieveWS<WorkspaceGroup>(workspaceName)) {
51 const auto groupAlg = AlgorithmManager::Instance().createUnmanaged("GroupWorkspaces");
52 groupAlg->initialize();
53 groupAlg->setProperty("InputWorkspaces", workspaceName);
54 groupAlg->setProperty("OutputWorkspace", workspaceName);
55 groupAlg->execute();
56 }
57}
58
59} // namespace
60
62
64 : API::MantidWidget(parent), m_loadProperties(), m_algRunner(), m_showLoad(true), m_alwaysLoadAsGroup(false) {
65 m_uiForm.setupUi(this);
66 connect(m_uiForm.cbInputType, SIGNAL(currentIndexChanged(int)), this, SLOT(handleViewChanged(int)));
67 connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SIGNAL(loadClicked()));
68
69 // data selected changes
70 connect(m_uiForm.rfFileInput, SIGNAL(filesFoundChanged()), this, SLOT(handleFileInput()));
71 connect(m_uiForm.wsWorkspaceInput, SIGNAL(currentIndexChanged(int)), this, SLOT(handleWorkspaceInput()));
72 connect(m_uiForm.pbLoadFile, SIGNAL(clicked()), this, SLOT(handleFileInput()));
73
74 connect(&m_algRunner, SIGNAL(algorithmComplete(bool)), this, SLOT(handleAutoLoadComplete(bool)));
75 this->setAcceptDrops(true);
76 m_uiForm.rfFileInput->setAcceptDrops(false);
77}
78
80
85bool DataSelector::isOptional() const { return m_isOptional; }
86
91void DataSelector::isOptional(bool optional) {
93 m_uiForm.rfFileInput->isOptional(optional);
94 m_uiForm.wsWorkspaceInput->setOptional(optional);
95}
96
101 // Get filename and check it's not empty
102 QString filename = m_uiForm.rfFileInput->getUserInput().toString();
103
104 if (filename.isEmpty()) {
105 return;
106 }
107
108 emit filesAutoLoaded();
109 autoLoadFile(filename);
110}
111
115void DataSelector::setSelectorIndex(int index) { m_uiForm.cbInputType->setCurrentIndex(index); }
116
120void DataSelector::setTypeSelectorVisible(bool visible) { m_uiForm.cbInputType->setVisible(visible); }
121
128 int index = m_uiForm.stackedDataSelect->currentIndex();
129 return (index == 0);
130}
131
138
147bool DataSelector::isValid(bool const autoLoad) {
148 bool isValid = false;
149
150 if (isFileSelectorVisible()) {
151 isValid = m_uiForm.rfFileInput->isValid();
152
153 // check to make sure the user hasn't deleted the auto-loaded file
154 // since choosing it.
155 if (isValid && autoLoad) {
156 auto const wsName = getCurrentDataName().toStdString();
157
158 isValid = !wsName.empty();
159 if (isValid && !ads.doesExist(wsName)) {
160 // attempt to reload if we can
161 // don't use algorithm runner because we need to know instantly.
162 auto const filepath = m_uiForm.rfFileInput->getUserInput().toString().toStdString();
163 if (!filepath.empty())
164 executeLoadAlgorithm(filepath, wsName);
165
166 isValid = ads.doesExist(wsName);
167
168 if (!isValid) {
169 m_uiForm.rfFileInput->setFileProblem("The specified workspace is "
170 "missing from the analysis data "
171 "service");
172 }
173 } else {
174 if (!ads.doesExist(wsName)) {
175 return isValid;
176 }
177 auto const workspaceTypes = m_uiForm.wsWorkspaceInput->getWorkspaceTypes();
178 auto const workspace = ads.retrieveWS<Workspace>(wsName);
179 isValid = workspaceTypes.empty() || workspaceTypes.indexOf(QString::fromStdString(workspace->id())) != -1;
180 if (!isValid) {
181 m_uiForm.rfFileInput->setFileProblem("The specified workspace type (" +
182 QString::fromStdString(workspace->id()) +
183 ") is "
184 "not one of the allowed types: " +
185 workspaceTypes.join(", "));
186 }
187 }
188 }
189 } else {
190 isValid = m_uiForm.wsWorkspaceInput->isValid();
191 }
192
193 return isValid;
194}
195
201 QString problem = "";
202 if (isFileSelectorVisible()) {
203 problem = m_uiForm.rfFileInput->getFileProblem();
204 if (problem.compare("") == 0) {
205 problem = "Input field is empty";
206 }
207 } else {
208 problem = "A valid workspace has not been selected";
209 }
210
211 return problem;
212}
213
222void DataSelector::autoLoadFile(const QString &filepath) {
223 const auto baseName = getWsNameFromFiles().toStdString();
224 executeLoadAlgorithm(filepath.toStdString(), baseName);
225}
226
233void DataSelector::executeLoadAlgorithm(std::string const &filename, std::string const &outputWorkspace) {
234 const auto loadAlg = AlgorithmManager::Instance().createUnmanaged(loadAlgName(filename));
235 loadAlg->initialize();
236 loadAlg->setProperty("Filename", filename);
237 loadAlg->setProperty("OutputWorkspace", outputWorkspace);
238 loadAlg->updatePropertyValues(m_loadProperties);
239
241}
242
249void DataSelector::setLoadProperty(std::string const &propertyName, bool const value) {
251}
252
259 m_uiForm.rfFileInput->setFileProblem(error ? "Could not load file. See log for details." : "");
260
261 if (error) {
262 return;
263 }
265 makeGroup(getWsNameFromFiles().toStdString());
266 }
268}
269
274 if (m_uiForm.stackedDataSelect->currentIndex() > 0) {
275 // Get text of name of workspace to use
276 QString filename = m_uiForm.wsWorkspaceInput->currentText();
277 if (filename.isEmpty())
278 return;
279
280 // emit that we got a valid workspace/file to work with
281 emit dataReady(filename);
282 }
283}
284
291 // Index indicates which view is visible.
292 m_uiForm.stackedDataSelect->setCurrentIndex(index);
293
294 // 0 is always file view
295 switch (index) {
296 case 0:
297 emit fileViewVisible();
298 break;
299 case 1:
302 break;
303 }
304}
305
311QString DataSelector::getFullFilePath() const { return m_uiForm.rfFileInput->getUserInput().toString(); }
312
319 QString filepath = DataSelector::getFullFilePath();
320 QFileInfo qfio(filepath);
321 QString baseName = qfio.completeBaseName();
322
323 // make up a name for the group workspace, if multiple files are specified
324 if (m_uiForm.rfFileInput->allowMultipleFiles() && filepath.count(",") > 0) {
325 baseName += "_group";
326 }
327
328 return baseName;
329}
330
343QString DataSelector::getCurrentDataName(bool const autoLoad) const {
344 QString filename("");
345
346 int index = m_uiForm.stackedDataSelect->currentIndex();
347
348 switch (index) {
349 case 0:
350 // the file selector is visible
351 if (m_uiForm.rfFileInput->isValid()) {
352 if (m_uiForm.rfFileInput->allowMultipleFiles() && !autoLoad) {
353 // if multiple files are allowed, auto-loading is not on, return the
354 // full user input
355 filename = getFullFilePath();
356 } else {
357 filename = getWsNameFromFiles();
358 }
359 }
360 break;
361 case 1:
362 // the workspace selector is visible
363 filename = m_uiForm.wsWorkspaceInput->currentText();
364 break;
365 }
366
367 return filename;
368}
369
375QString DataSelector::getLoadBtnText() const { return m_uiForm.pbLoadFile->text(); }
376
382void DataSelector::setLoadBtnText(const QString &text) { m_uiForm.pbLoadFile->setText(text); }
383
390void DataSelector::setAlwaysLoadAsGroup(bool const loadAsGroup) { m_alwaysLoadAsGroup = loadAsGroup; }
391
396void DataSelector::readSettings(const QString &group) { m_uiForm.rfFileInput->readSettings(group); }
397
402void DataSelector::saveSettings(const QString &group) { m_uiForm.rfFileInput->saveSettings(group); }
403
410
418 m_uiForm.pbLoadFile->setEnabled(load);
419 m_uiForm.pbLoadFile->setVisible(load);
420 m_showLoad = load;
421}
422
427void DataSelector::dropEvent(QDropEvent *de) {
428 const QMimeData *mimeData = de->mimeData();
429 auto before_action = de->dropAction();
430
431 auto const dragData = mimeData->text().toStdString();
432
433 if (de->mimeData() && ads.doesExist(dragData)) {
434 m_uiForm.wsWorkspaceInput->dropEvent(de);
435 if (de->dropAction() == before_action) {
436 setWorkspaceSelectorIndex(mimeData->text());
437 m_uiForm.cbInputType->setCurrentIndex(1);
438 return;
439 }
440 de->setDropAction(before_action);
441 }
442
443 m_uiForm.rfFileInput->dropEvent(de);
444 if (de->dropAction() == before_action) {
445 m_uiForm.cbInputType->setCurrentIndex(0);
446 }
447
448 auto const filepath = m_uiForm.rfFileInput->getText().toStdString();
449 if (de->mimeData() && !ads.doesExist(dragData) && !filepath.empty()) {
450 auto const file = extractLastOf(filepath, "/");
451 if (fileFound(file)) {
452 auto const workspaceName = cutLastOf(file, ".");
453 executeLoadAlgorithm(filepath, workspaceName);
454
455 setWorkspaceSelectorIndex(QString::fromStdString(workspaceName));
456 m_uiForm.cbInputType->setCurrentIndex(1);
457 }
458 }
459}
460
466void DataSelector::setWorkspaceSelectorIndex(QString const &workspaceName) {
467 auto const index = m_uiForm.wsWorkspaceInput->findText(workspaceName);
468 m_uiForm.wsWorkspaceInput->setCurrentIndex(index != -1 ? index : 0);
469}
470
475void DataSelector::dragEnterEvent(QDragEnterEvent *de) {
476 const QMimeData *mimeData = de->mimeData();
477 if (mimeData->hasText() || mimeData->hasUrls())
478 de->acceptProposedAction();
479}
480
481} // namespace MantidQt::MantidWidgets
double value
The value of the point.
Definition FitMW.cpp:51
double error
IPeaksWorkspace_sptr workspace
std::map< DeltaEMode::Type, std::string > index
virtual void startAlgorithm(Mantid::API::IAlgorithm_sptr alg)
Begin asynchronous execution of an algorithm and observe its execution.
Mantid::API::AlgorithmRuntimeProps m_loadProperties
Extra load properties to set on the load algorithm before execution.
bool isWorkspaceSelectorVisible() const
Get whether the workspace selector is currently being shown.
void setLoadProperty(std::string const &propertyName, bool const value)
Set an extra property on the load algorithm before execution.
virtual bool isValid(bool const autoLoad=true)
Checks if widget is in a valid state.
void setShowLoad(bool load)
Set if the load button should be shown.
void setTypeSelectorVisible(bool visible)
Sets if the option to choose selector is visible.
bool m_alwaysLoadAsGroup
Flag to always load data, placing it inside a WorkspaceGroup, even if there is 1 entry.
Ui::DataSelector m_uiForm
Member containing the widgets child widgets.
void handleViewChanged(int index)
Slot called when the current view is changed.
void dropEvent(QDropEvent *) override
Called when an item is dropped.
void autoLoadFile(const QString &filenames)
Attempt to automatically load a file.
void saveSettings(const QString &)
Save settings in the given group.
void setWorkspaceSelectorIndex(QString const &workspaceName)
Set the index of the combobox containing the loaded workspace.
void fileViewVisible()
Signal emitted when file input is visible.
bool isFileSelectorVisible() const
Get whether the file selector is currently being shown.
void setLoadBtnText(const QString &)
Sets the load button text.
void filesAutoLoaded()
Signal emitted when files are found and autoloaded.
QString getWsNameFromFiles() const
Get the workspace name from the list of files.
virtual QString getCurrentDataName(bool const autoLoad=true) const
Get the currently available file or workspace name.
QString getFullFilePath() const
Get the current file path in the FileFinderWidget widget.
void dragEnterEvent(QDragEnterEvent *) override
Called when an item is dragged onto a control.
void setAlwaysLoadAsGroup(bool const loadAsGroup)
Sets the DataSelector to always load data inside a WorkspaceGroup.
bool willShowLoad()
Check if the widget will show the load button.
bool m_showLoad
Flag to show or hide the load button. By default this is set to true.
void readSettings(const QString &)
Read settings from the given group.
void handleAutoLoadComplete(bool error)
Slot called if the widget fails to auto load the file.
QString getProblem() const
Get file problem, empty string means no error.
bool isOptional() const
Gets if optional.
DataSelector(QWidget *parent=nullptr)
MantidQt::API::QtAlgorithmRunner m_algRunner
Algorithm Runner used to run the load algorithm.
void handleWorkspaceInput()
Slot called when workspace input is available.
void dataReady(const QString &wsname)
Signal emitted when data is ready from a workspace selector or file browser.
void executeLoadAlgorithm(std::string const &filename, std::string const &outputWorkspace)
Execute load algorithm.
QString getLoadBtnText() const
Gets the load button text.
void setSelectorIndex(int index)
Sets which selector (file or workspace) is visible.
void loadClicked()
Signal emitted when the load button is clicked.
void workspaceViewVisible()
Signal emitted when workspace selector is visible.
void handleFileInput()
Slot called when file input is available.
Class to hold a set of workspaces.
Base Workspace Abstract Class.
Definition Workspace.h:29
void MANTID_API_DLL update(std::string const &property, std::string const &value, IAlgorithmRuntimeProps &properties)