Mantid
Loading...
Searching...
No Matches
MantidTreeWidget.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 +
9
14
15#include <QApplication>
16#include <QDrag>
17#include <QDragMoveEvent>
18#include <QFileInfo>
19#include <QList>
20#include <QMimeData>
21#include <QUrl>
22
23using namespace Mantid::API;
24
25namespace {
26Mantid::Kernel::Logger treelog("MantidTreeWidget");
27}
28
30
32 : QTreeWidget(parent), m_mantidUI(mui), m_ads(Mantid::API::AnalysisDataService::Instance()), m_sortScheme() {
33 setObjectName("WorkspaceTree");
34 setSelectionMode(QAbstractItemView::ExtendedSelection);
35 setSortOrder(Qt::AscendingOrder);
36 setAcceptDrops(true);
37
38 m_doubleClickAction = [&](const QString &wsName) { m_mantidUI->importWorkspace(wsName, false); };
39}
40
45void MantidTreeWidget::dragMoveEvent(QDragMoveEvent *de) {
46 // The event needs to be accepted here
47 if (de->mimeData()->hasUrls())
48 de->accept();
49}
50
55void MantidTreeWidget::dragEnterEvent(QDragEnterEvent *de) {
56 // Set the drop action to be the proposed action.
57 if (de->mimeData()->hasUrls())
58 de->acceptProposedAction();
59}
60
65void MantidTreeWidget::dropEvent(QDropEvent *de) {
66 const auto filenames = DropEventHelper::getFileNames(de);
67 de->acceptProposedAction();
68
69 for (int i = 0; i < filenames.size(); ++i) {
70 try {
71 QFileInfo fi(filenames[i]);
72 QString basename = fi.completeBaseName();
73 auto alg = m_mantidUI->createAlgorithm("Load");
74 alg->initialize();
75 alg->setProperty("Filename", filenames[i].toStdString());
76 alg->setProperty("OutputWorkspace", basename.toStdString());
78 } catch (std::runtime_error &error) {
79 treelog.error() << "Failed to Load the file " << filenames[i].toStdString()
80 << " . The reason for failure is: " << error.what() << '\n';
81 } catch (std::logic_error &error) {
82 treelog.error() << "Failed to Load the file " << filenames[i].toStdString()
83 << " . The reason for failure is: " << error.what() << '\n';
84 } catch (std::exception &error) {
85 treelog.error() << "Failed to Load the file " << filenames[i].toStdString()
86 << " . The reason for failure is: " << error.what() << '\n';
87 }
88 }
89}
90
92 if (e->button() == Qt::LeftButton) {
93 if (!itemAt(e->pos()))
94 selectionModel()->clear();
95 m_dragStartPosition = e->pos();
96 }
97
98 QTreeWidget::mousePressEvent(e);
99}
100
102 if (!(e->buttons() & Qt::LeftButton))
103 return;
104 if ((e->pos() - m_dragStartPosition).manhattanLength() < QApplication::startDragDistance())
105 return;
106
107 QStringList wsNames = getSelectedWorkspaceNames();
108 if (wsNames.isEmpty())
109 return;
110
111 // Start dragging - Qt docs say not to delete the QDrag object
112 // manually
113 QDrag *drag = new QDrag(this);
114 auto *mimeData = new QMimeData;
115 drag->setMimeData(mimeData);
116 mimeData->setObjectName("MantidWorkspace");
117 mimeData->setText(wsNames.join("\n"));
118 drag->exec(Qt::CopyAction | Qt::MoveAction);
119}
120
122 try {
123 auto wsNames = getSelectedWorkspaceNames();
124 if (wsNames.isEmpty()) {
125 return;
126 }
127 auto wsName = wsNames.front();
129 grpWSPstr = std::dynamic_pointer_cast<WorkspaceGroup>(m_ads.retrieve(wsName.toStdString()));
130 if (!grpWSPstr) {
131 if (!wsName.isEmpty()) {
132 m_doubleClickAction(wsName);
133 return;
134 }
135 }
137 return;
138 }
139 QTreeWidget::mouseDoubleClickEvent(e);
140}
141
148 QStringList names;
149
150 foreach (const auto selectedItem, this->selectedItems()) {
151 if (selectedItem)
152 names.append(selectedItem->text(0));
153 }
154
155 return names;
156}
157
166 // Check for any selected WorkspaceGroup names and replace with the names of
167 // their children.
168 // We preserve the order, but use a set to avoid adding duplicate workspaces.
169 std::set<QString> selectedWsNameSet;
170 std::vector<QString> selectedWsNameList;
171 foreach (const QString wsName, this->getSelectedWorkspaceNames()) {
172 const auto groupWs = std::dynamic_pointer_cast<const WorkspaceGroup>(m_ads.retrieve(wsName.toStdString()));
173 if (groupWs) {
174 const auto childWsNames = groupWs->getNames();
175 for (const auto &childWsName : childWsNames) {
176 if (selectedWsNameSet.find(QString::fromStdString(childWsName)) == selectedWsNameSet.end()) {
177 selectedWsNameSet.insert(QString::fromStdString(childWsName));
178 selectedWsNameList.emplace_back(QString::fromStdString(childWsName));
179 }
180 }
181 } else {
182 if (selectedWsNameSet.insert(wsName).second) {
183 selectedWsNameList.emplace_back(wsName);
184 }
185 }
186 }
187
188 // Get the names of, and pointers to, the MatrixWorkspaces only.
189 QList<MatrixWorkspace_const_sptr> selectedMatrixWsList;
190 QList<QString> selectedMatrixWsNameList;
191 foreach (const auto selectedWsName, selectedWsNameList) {
192 const auto matrixWs =
193 std::dynamic_pointer_cast<const MatrixWorkspace>(m_ads.retrieve(selectedWsName.toStdString()));
194 if (matrixWs) {
195 selectedMatrixWsList.append(matrixWs);
196 }
197 }
198 return selectedMatrixWsList;
199}
200
216 bool showTiledOpt, bool isAdvanced) const {
217 auto selectedMatrixWsList = getSelectedMatrixWorkspaces();
218 QList<QString> selectedMatrixWsNameList;
219 foreach (const auto matrixWs, selectedMatrixWsList) {
220 selectedMatrixWsNameList.append(QString::fromStdString(matrixWs->getName()));
221 }
222
223 // Check workspaces to see whether to plot immediately without dialog box
224 bool plotImmediately = true;
225 if (isAdvanced) {
226 plotImmediately = selectedMatrixWsList.size() == 1 && selectedMatrixWsList[0]->getNumberHistograms() == 1;
227 } else {
228 foreach (const auto selectedMatrixWs, selectedMatrixWsList) {
229 if (selectedMatrixWs->getNumberHistograms() != 1) {
230 plotImmediately = false;
231 break;
232 }
233 }
234 }
235
236 // ... and if so, just return all workspace names mapped to workspace index 0;
237 if (plotImmediately) {
238 const std::set<int> SINGLE_SPECTRUM = {0};
239 QMultiMap<QString, std::set<int>> spectrumToPlot;
240 foreach (const auto selectedMatrixWs, selectedMatrixWsList) {
241 spectrumToPlot.insert(QString::fromStdString(selectedMatrixWs->getName()), SINGLE_SPECTRUM);
242 }
243 // and get simple 1D plot done
245 selections.plots = spectrumToPlot;
246 selections.simple = true;
247 selections.waterfall = false;
248 selections.tiled = false;
249 selections.surface = false;
250 selections.contour = false;
251 return selections;
252 }
253
254 // Else, one or more workspaces
255 auto dio = m_mantidUI->createWorkspaceIndexDialog(0, selectedMatrixWsNameList, showWaterfallOpt, showPlotAll,
256 showTiledOpt, isAdvanced);
257 dio->exec();
258 return dio->getSelections();
259}
260
262
263void MantidTreeWidget::setSortOrder(Qt::SortOrder sortOrder) { m_sortOrder = sortOrder; }
264
265Qt::SortOrder MantidTreeWidget::getSortOrder() const { return m_sortOrder; }
266
268
272void MantidTreeWidget::sort() { sortItems(sortColumn(), m_sortOrder); }
273
278void MantidTreeWidget::logWarningMessage(const std::string &msg) { treelog.warning(msg); }
279} // namespace MantidQt::MantidWidgets
double error
Definition: IndexPeaks.cpp:133
virtual MantidWSIndexDialog * createWorkspaceIndexDialog(int flags, const QStringList &wsNames, bool showWaterfall, bool showPlotAll, bool showTiledOpt, bool isAdvanced=false)=0
virtual bool executeAlgorithmAsync(Mantid::API::IAlgorithm_sptr alg, const bool wait=false)=0
virtual Mantid::API::IAlgorithm_sptr createAlgorithm(const QString &algName, int version=-1)=0
void dragMoveEvent(QDragMoveEvent *de) override
Accept a drag move event and selects whether to accept the action.
MantidWSIndexWidget::UserInput chooseSpectrumFromSelected(bool showWaterfallOpt=true, bool showPlotAll=true, bool showTiledOpt=true, bool isAdvanced=false) const
Allows users to choose spectra from the selected workspaces by presenting them with a dialog box.
void dropEvent(QDropEvent *de) override
Accept a drag drop event and process the data appropriately.
void logWarningMessage(const std::string &)
Log a warning message.
void mouseDoubleClickEvent(QMouseEvent *e) override
void mouseMoveEvent(QMouseEvent *e) override
std::function< void(QString)> m_doubleClickAction
Action that is executed when a workspace in the tree is double clicked.
void dragEnterEvent(QDragEnterEvent *de) override
Accept a drag enter event and selects whether to accept the action.
void sort()
Sort the items according to the current sort scheme and order.
MantidTreeWidget(MantidDisplayBase *mui, QWidget *parent=nullptr)
QStringList getSelectedWorkspaceNames() const
Returns a list of all selected workspaces.
Mantid::API::AnalysisDataServiceImpl & m_ads
MantidItemSortScheme getSortScheme() const
QList< std::shared_ptr< const Mantid::API::MatrixWorkspace > > getSelectedMatrixWorkspaces() const
Filter the list of selected workspace names to account for any non-MatrixWorkspaces that may have bee...
void mousePressEvent(QMouseEvent *e) override
MantidWSIndexWidget::UserInput getSelections()
Returns a structure holding all of the selected options.
std::shared_ptr< T > retrieve(const std::string &name) const
Get a shared pointer to a stored data object.
Definition: DataService.h:350
Exception for when an item is not found in a collection.
Definition: Exception.h:145
The Logger class is in charge of the publishing messages from the framework through various channels.
Definition: Logger.h:52
Manage the lifetime of a class intended to be a singleton.
EXPORT_OPT_MANTIDQT_COMMON QStringList getFileNames(const QDropEvent *event)
Get all filenames from a QDropEvent.
std::shared_ptr< WorkspaceGroup > WorkspaceGroup_sptr
shared pointer to Mantid::API::WorkspaceGroup
Helper class which provides the Collimation Length for SANS instruments.