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
259void DataSelector::setLoadProperty(std::string const &propertyName, std::string const &value) {
261}
262
269 m_uiForm.rfFileInput->setFileProblem(error ? "Could not load file. See log for details." : "");
270
271 if (error) {
272 return;
273 }
275 makeGroup(getWsNameFromFiles().toStdString());
276 }
278}
279
284 if (m_uiForm.stackedDataSelect->currentIndex() > 0) {
285 // Get text of name of workspace to use
286 QString filename = m_uiForm.wsWorkspaceInput->currentText();
287 if (filename.isEmpty())
288 return;
289
290 // emit that we got a valid workspace/file to work with
291 emit dataReady(filename);
292 }
293}
294
301 // Index indicates which view is visible.
302 m_uiForm.stackedDataSelect->setCurrentIndex(index);
303
304 // 0 is always file view
305 switch (index) {
306 case 0:
307 emit fileViewVisible();
308 break;
309 case 1:
312 break;
313 }
314}
315
321QString DataSelector::getFullFilePath() const { return m_uiForm.rfFileInput->getUserInput().toString(); }
322
329 QString filepath = DataSelector::getFullFilePath();
330 QFileInfo qfio(filepath);
331 QString baseName = qfio.completeBaseName();
332
333 // make up a name for the group workspace, if multiple files are specified
334 if (m_uiForm.rfFileInput->allowMultipleFiles() && filepath.count(",") > 0) {
335 baseName += "_group";
336 }
337
338 return baseName;
339}
340
353QString DataSelector::getCurrentDataName(bool const autoLoad) const {
354 QString filename("");
355
356 int index = m_uiForm.stackedDataSelect->currentIndex();
357
358 switch (index) {
359 case 0:
360 // the file selector is visible
361 if (m_uiForm.rfFileInput->isValid()) {
362 if (m_uiForm.rfFileInput->allowMultipleFiles() && !autoLoad) {
363 // if multiple files are allowed, auto-loading is not on, return the
364 // full user input
365 filename = getFullFilePath();
366 } else {
367 filename = getWsNameFromFiles();
368 }
369 }
370 break;
371 case 1:
372 // the workspace selector is visible
373 filename = m_uiForm.wsWorkspaceInput->currentText();
374 break;
375 }
376
377 return filename;
378}
379
385QString DataSelector::getLoadBtnText() const { return m_uiForm.pbLoadFile->text(); }
386
392void DataSelector::setLoadBtnText(const QString &text) { m_uiForm.pbLoadFile->setText(text); }
393
400void DataSelector::setAlwaysLoadAsGroup(bool const loadAsGroup) { m_alwaysLoadAsGroup = loadAsGroup; }
401
404}
405
407 m_uiForm.rfFileInput->restoreSettings(settings);
408}
409
410API::FileFinderSettings DataSelector::captureSettings() const { return m_uiForm.rfFileInput->captureSettings(); }
411
412void DataSelector::saveSettings(QSettings &settings, const API::FileFinderSettings &values) const {
413 m_uiForm.rfFileInput->saveSettings(settings, values);
414}
415
422
430 m_uiForm.pbLoadFile->setEnabled(load);
431 m_uiForm.pbLoadFile->setVisible(load);
432 m_showLoad = load;
433}
434
439void DataSelector::dropEvent(QDropEvent *de) {
440 const QMimeData *mimeData = de->mimeData();
441 auto before_action = de->dropAction();
442
443 auto const dragData = mimeData->text().toStdString();
444
445 if (de->mimeData() && ads.doesExist(dragData)) {
446 m_uiForm.wsWorkspaceInput->dropEvent(de);
447 if (de->dropAction() == before_action) {
448 setWorkspaceSelectorIndex(mimeData->text());
449 m_uiForm.cbInputType->setCurrentIndex(1);
450 return;
451 }
452 de->setDropAction(before_action);
453 }
454
455 m_uiForm.rfFileInput->dropEvent(de);
456 if (de->dropAction() == before_action) {
457 m_uiForm.cbInputType->setCurrentIndex(0);
458 }
459
460 auto const filepath = m_uiForm.rfFileInput->getText().toStdString();
461 if (de->mimeData() && !ads.doesExist(dragData) && !filepath.empty()) {
462 auto const file = extractLastOf(filepath, "/");
463 if (fileFound(file)) {
464 auto const workspaceName = cutLastOf(file, ".");
465 executeLoadAlgorithm(filepath, workspaceName);
466
467 setWorkspaceSelectorIndex(QString::fromStdString(workspaceName));
468 m_uiForm.cbInputType->setCurrentIndex(1);
469 }
470 }
471}
472
478void DataSelector::setWorkspaceSelectorIndex(QString const &workspaceName) {
479 auto const index = m_uiForm.wsWorkspaceInput->findText(workspaceName);
480 m_uiForm.wsWorkspaceInput->setCurrentIndex(index != -1 ? index : 0);
481}
482
487void DataSelector::dragEnterEvent(QDragEnterEvent *de) {
488 const QMimeData *mimeData = de->mimeData();
489 if (mimeData->hasText() || mimeData->hasUrls())
490 de->acceptProposedAction();
491}
492
493} // 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
Immutable snapshot of the persistent state used by FileFinderWidget.
static FileFinderSettings readSettings(const QSettings &settings)
Query last_directory from const storage without changing this widget or writing settings.
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(QSettings &settings, const API::FileFinderSettings &values) const
Persist the supplied snapshot to mutable storage positioned at the target 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.
API::FileFinderSettings captureSettings() const
Capture the current state of the child file finder without persistent I/O.
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.
static API::FileFinderSettings readSettings(const QSettings &settings)
Query file-finder settings from const storage without changing this widget or writing settings.
bool m_showLoad
Flag to show or hide the load button. By default this is set to true.
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 restoreSettings(const API::FileFinderSettings &settings)
Restore the child file finder from an in-memory snapshot without persistent I/O.
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)