41#include <QSignalMapper>
57 : QWidget(parent), m_mantidDisplayModel(mdb), m_viewOnly(viewOnly), m_updateCount(0), m_treeUpdating(false),
59 m_sortDirection(
SortDirection::Ascending), m_mutex(QMutex::Recursive) {
60 setObjectName(
"exploreMantid");
73 static bool registered_addtional_types =
false;
74 if (!registered_addtional_types) {
75 registered_addtional_types =
true;
76 qRegisterMetaType<TopLevelItems>();
85 m_tree->setDragEnabled(
true);
87 auto presenter = std::make_shared<WorkspacePresenter>(
this);
88 m_presenter = std::dynamic_pointer_cast<ViewNotifiable>(presenter);
105 m_tree->setHeaderLabel(
"Workspaces");
111 m_saveButton->setToolTip(
"Save the selected workspaces");
117 m_groupButton->setToolTip(
"Group together two or more selected workspaces");
119 m_sortButton->setToolTip(
"Sort all workspaces by name, size, or the last time they were modified");
138 auto *layout =
new QVBoxLayout();
139 layout->setMargin(0);
140 layout->addLayout(buttonLayout);
142 layout->addWidget(
m_tree);
143 this->setLayout(layout);
149 QAction *loadFileAction =
new QAction(
"File",
this);
150 QAction *liveDataAction =
new QAction(
"Live Data",
this);
151 connect(loadFileAction, SIGNAL(triggered()),
this, SLOT(
onClickLoad()));
152 connect(liveDataAction, SIGNAL(triggered()),
this, SLOT(
onClickLiveData()));
163 connect(
m_tree, SIGNAL(itemClicked(QTreeWidgetItem *,
int)),
this, SLOT(
clickedWorkspace(QTreeWidgetItem *,
int)));
167 m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
168 connect(
m_tree, SIGNAL(customContextMenuRequested(
const QPoint &)),
this, SLOT(
popupMenu(
const QPoint &)));
170 Qt::QueuedConnection);
188 return std::dynamic_pointer_cast<WorkspacePresenter>(
m_presenter);
195 auto items =
m_tree->selectedItems();
197 names.reserve(
static_cast<size_t>(items.size()));
198 std::transform(items.cbegin(), items.cend(), std::back_inserter(names),
199 [](
auto const &item) { return item->text(0).toStdString(); });
205 auto items =
m_tree->selectedItems();
208 for (
auto &item : items) {
209 names.append(item->text(0));
218 auto items =
m_tree->selectedItems();
219 auto data = items[0]->data(0, Qt::UserRole).value<
Workspace_sptr>();
225 return QMessageBox::question(parentWidget(), QString::fromStdString(caption), QString::fromStdString(message),
226 QMessageBox::Yes, QMessageBox::No) == QMessageBox::Yes;
230 QMessageBox::critical(parentWidget(), QString::fromStdString(caption), QString::fromStdString(message));
234 QObject *sender = QObject::sender();
245 QMetaObject::invokeMethod(
dynamic_cast<QObject *
>(
m_mantidDisplayModel),
"showAlgorithmDialog", Qt::QueuedConnection,
246 Q_ARG(QString,
"Load"));
250 QMetaObject::invokeMethod(
dynamic_cast<QObject *
>(
m_mantidDisplayModel),
"showAlgorithmDialog", Qt::QueuedConnection,
251 Q_ARG(QString,
"StartLiveData"));
259 for (
auto &ws : wsNames)
260 names.append(QString::fromStdString(ws));
273 QString qs_oldName = QString::fromStdString(oldName);
274 QString qs_newName = QString::fromStdString(newName);
276 QMutexLocker renameMapLock(&
m_mutex);
280 if (!oldNames.isEmpty()) {
281 for (
auto &name : oldNames)
296 return askUserYesNo(
"Delete Workspaces",
"Are you sure you want to delete the selected Workspaces?\n\nThis prompt "
297 "can be disabled from:\nFile->Settings->General");
302 for (
auto &ws : wsNames)
303 names.append(QString::fromStdString(ws));
335 static int counter = 1;
374 QAction *sendingAction =
dynamic_cast<QAction *
>(sender());
377 QString actionName = sendingAction->text();
379 if (actionName.compare(
"Nexus") == 0)
381 else if (actionName.compare(
"ASCII") == 0)
392 if (!wsName.empty()) {
393 presets[
"InputWorkspace"] = QString::fromStdString(wsName);
396 std::string algorithmName;
400 algorithmName =
"SaveNexus";
403 algorithmName =
"SaveAscii";
412 if (items.size() < 2)
421 saveAlg->initialize();
423 if (res == QFileDialog::Accepted) {
424 for (
auto &wsName : wsNames) {
425 std::string filename = folder +
"/" + wsName +
".nxs";
427 saveAlg->setProperty(
"InputWorkspace", wsName);
428 saveAlg->setProperty(
"Filename", filename);
430 }
catch (std::exception &ex) {
431 docklog.error() <<
"Error saving workspace " << wsName <<
": " << ex.what() <<
'\n';
440 const QString text = QString::fromStdString(filterText).trimmed();
441 QRegExp filterRegEx(text, Qt::CaseInsensitive);
444 QTreeWidgetItemIterator unhideIter(
m_tree);
445 while (*unhideIter) {
446 (*unhideIter)->setHidden(
false);
452 if (!text.isEmpty()) {
455 QStringList expanded;
456 int n =
m_tree->topLevelItemCount();
457 for (
int i = 0; i <
n; ++i) {
458 auto item =
m_tree->topLevelItem(i);
459 if (item->isExpanded()) {
460 expanded << item->text(0);
464 item->setExpanded(
true);
469 QTreeWidgetItemIterator it(
m_tree, QTreeWidgetItemIterator::All);
471 QTreeWidgetItem *item = (*it);
472 QVariant userData = item->data(0, Qt::UserRole);
474 if (!userData.isNull()) {
478 if (item->text(0).contains(filterRegEx)) {
484 visibleGroups.append(item);
485 item->setHidden(
false);
488 if (item->parent() ==
nullptr) {
490 item->setHidden(
false);
494 item->setHidden(
false);
495 if (item->parent()->isHidden()) {
498 item->parent()->setHidden(
false);
499 expanded << item->parent()->text(0);
504 item->setHidden(
true);
513 for (
auto group : visibleGroups) {
514 for (
int i = 0; i < group->childCount(); i++) {
515 QTreeWidgetItem *child = group->child(i);
516 if (child->isHidden()) {
519 child->setHidden(
false);
525 for (
int i = 0; i <
n; ++i) {
526 auto item =
m_tree->topLevelItem(i);
527 item->setExpanded(expanded.contains(item->text(0)));
532 if (hiddenCount > 0) {
533 QString headerString = QString(
"Workspaces (%1 filtered)").arg(QString::number(hiddenCount));
534 m_tree->headerItem()->setText(0, headerString);
536 m_tree->headerItem()->setText(0,
"Workspaces");
547 item->setIcon(0, QIcon(WORKSPACE_ICONS.getIcon(wsID)));
548 }
catch (std::runtime_error &) {
549 docklog.warning() <<
"Cannot find icon for workspace ID '" << wsID <<
"'\n";
557 m_showData =
new QAction(tr(
"Show Data"),
this);
560 m_showInst =
new QAction(tr(
"Show Instrument"),
this);
563 m_plotSpec =
new QAction(tr(
"Plot Spectrum..."),
this);
566 m_plotSpecErr =
new QAction(tr(
"Plot Spectrum with Errors..."),
this);
572 m_colorFill =
new QAction(tr(
"Color Fill Plot"),
this);
578 m_showBoxData =
new QAction(tr(
"Show Box Data Table"),
this);
593 icon.addFile(QString::fromUtf8(
":/SliceViewer/icons/SliceViewerWindow_icon.png"), QSize(), QIcon::Normal,
599 m_showLogs =
new QAction(tr(
"Sample Logs..."),
this);
605 m_showHist =
new QAction(tr(
"Show History"),
this);
611 m_rename =
new QAction(tr(
"Rename"),
this);
614 m_delete =
new QAction(tr(
"Delete"),
this);
628 m_clearUB =
new QAction(tr(
"Clear UB Matrix"),
this);
643 QAction *m_byMemorySize =
new QAction(
"Size",
this);
651 QActionGroup *sortDirectionGroup =
new QActionGroup(
m_sortMenu);
654 sortDirectionGroup->setExclusive(
true);
663 m_byMemorySize->setCheckable(
true);
664 m_byMemorySize->setEnabled(
true);
679 m_sortMenu->addActions(sortDirectionGroup->actions());
690 QVariant userData = item->data(0, Qt::UserRole);
691 if (userData.isNull())
695 while (item->childCount() > 0) {
696 auto *widgetItem = item->takeChild(0);
702 if (
auto group = std::dynamic_pointer_cast<WorkspaceGroup>(
workspace)) {
703 auto members = group->getAllItems();
704 for (
const auto &ws : members) {
705 auto *node =
addTreeEntry(std::make_pair(ws->getName(), ws), item);
708 node->setSelected(
true);
714 }
catch (std::runtime_error &e) {
715 details = QString(
"Error: %1").arg(e.what());
717 QStringList rows = details.split(QLatin1Char(
'\n'), Qt::SkipEmptyParts);
718 rows.append(QString(
"Memory used: ") +
workspace->getMemorySizeAsStr().c_str());
720 auto iend = rows.constEnd();
721 for (
auto itr = rows.constBegin(); itr != iend; ++itr) {
723 data->setFlags(Qt::NoItemFlags);
725 item->addChild(data);
751 foreach (QTreeWidgetItem *item, selected) {
m_selectedNames << item->text(0); }
755 auto iend = topLevelItems.end();
756 for (
auto it = topLevelItems.begin(); it != iend; ++it) {
758 QString name = node->text(0);
759 if (expanded.contains(name))
760 node->setExpanded(
true);
763 node->setSelected(
true);
781 QTreeWidgetItem *parent) {
783 node->setData(0, Qt::UserRole, QVariant::fromValue(item.second));
787 const std::string wsID = item.second->id();
789 idNode->setFlags(Qt::NoItemFlags);
790 node->addChild(idNode);
794 parent->addChild(node);
796 m_tree->addTopLevelItem(node);
808 if (!renamed.isEmpty()) {
809 foreach (QString oldName, renamed) {
822 auto items =
m_tree->selectedItems();
825 if (items.size() == 1) {
827 auto wsSptr = items.first()->data(0, Qt::UserRole).value<
Workspace_sptr>();
828 auto grpSptr = std::dynamic_pointer_cast<WorkspaceGroup>(wsSptr);
836 }
else if (items.size() >= 2) {
839 m_groupButton->setToolTip(
"Group together two or more selected workspaces");
840 }
else if (items.size() == 0) {
843 m_groupButton->setToolTip(
"Group together two or more selected workspaces");
853 if (items.size() > 0) {
854 auto item = *(items.begin());
873 m_showInst->setEnabled(matrixWS->getInstrument() && !matrixWS->getInstrument()->getName().empty() &&
874 matrixWS->getAxis(1)->isSpectra());
875 menu->addSeparator();
881 bool multipleBins =
false;
883 multipleBins = (matrixWS->blocksize() > 1);
885 const size_t numHist = matrixWS->getNumberHistograms();
886 for (
size_t i = 0; i < numHist; ++i) {
887 if (matrixWS->y(i).size() > 1) {
901 m_colorFill->setEnabled((matrixWS->axes() > 1 && matrixWS->getNumberHistograms() > 1));
903 menu->addSeparator();
946 menu->addSeparator();
965 menu->addSeparator();
987 QMenu *clearMenu =
new QMenu(tr(
"Clear Options"),
this);
992 menu->addMenu(clearMenu);
1000 hasUB = wsIMD->hasOrientedLattice();
1014 if (menuEntryName.isEmpty())
1015 menuEntryName = algorithmString;
1018 QAction *saveAction =
new QAction(menuEntryName,
this);
1019 saveAction->setData(QVariant(algorithmString));
1047 return askUserYesNo(
"Clear Workspaces",
"This will delete all the workspaces, are you sure?");
1065 if (selectedNames.empty())
1069 if (selectedNames.size() > 1) {
1089 auto wsName = selectedNames[0];
1098 if (qButtonName ==
"Group") {
1100 }
else if (qButtonName ==
"Ungroup") {
1123 QStringList expanded;
1124 int n =
m_tree->topLevelItemCount();
1125 for (
int i = 0; i <
n; ++i) {
1126 auto item =
m_tree->topLevelItem(i);
1127 if (item->isExpanded()) {
1128 expanded << item->text(0);
1165 m_tree->selectionModel()->clear();
1167 QMenu *menu(
nullptr);
1174 menu =
new QMenu(
this);
1175 menu->setObjectName(
"WorkspaceContextMenu");
1180 if (
auto matrixWS = std::dynamic_pointer_cast<const Mantid::API::MatrixWorkspace>(ws)) {
1182 }
else if (
auto mdeventWS = std::dynamic_pointer_cast<const IMDEventWorkspace>(ws)) {
1184 }
else if (
auto mdWS = std::dynamic_pointer_cast<const IMDWorkspace>(ws)) {
1186 }
else if (
auto peaksWS = std::dynamic_pointer_cast<const IPeaksWorkspace>(ws)) {
1188 }
else if (
auto groupWS = std::dynamic_pointer_cast<const WorkspaceGroup>(ws)) {
1190 }
else if (std::dynamic_pointer_cast<const Mantid::API::ITableWorkspace>(ws)) {
1199 std::vector<std::string> programNames =
1201 bool firstPass(
true);
1203 for (
auto &programName : programNames) {
1204 std::string visible =
1206 std::string target =
1209 bool compatible(
true);
1210 std::string saveUsing(
1214 alg->setPropertyValue(
"InputWorkspace",
selectedWsName.toStdString());
1215 }
catch (std::exception &) {
1226 QString name = QString::fromStdString(programName);
1249 menu->addSeparator();
1254 menu->popup(QCursor::pos());
1277 std::map<std::string, std::string> programKeysAndDetails;
1278 programKeysAndDetails[
"name"] =
m_programName.toStdString();
1283 (
"workspace.sendto." + programKeysAndDetails.find(
"name")->second)));
1285 for (
const auto &programKey : programKeys) {
1288 (
"workspace.sendto." + programKeysAndDetails.find(
"name")->second +
"." + programKey)));
1292 if ((programKeysAndDetails.count(
"name") != 0) && (programKeysAndDetails.count(
"target") != 0) &&
1293 (programKeysAndDetails.count(
"saveusing") != 0)) {
1294 std::string expTarget = Poco::Path::expand(programKeysAndDetails.find(
"target")->second);
1296 QFileInfo target = QString::fromStdString(expTarget);
1297 if (target.exists()) {
1300 QString saveUsing = QString::fromStdString(programKeysAndDetails.find(
"saveusing")->second);
1306 Property *prop = alg->getProperty(
"Filename");
1314 alg->setPropertyValue(
"fileName",
"auto_save_" +
selectedWsName.toStdString() + ext);
1317 alg->setPropertyValue(
"InputWorkspace",
selectedWsName.toStdString());
1320 if (programKeysAndDetails.count(
"saveparameters") != 0) {
1321 QString saveParametersGrouped = QString::fromStdString(programKeysAndDetails.find(
"saveparameters")->second);
1322 QStringList saveParameters = saveParametersGrouped.split(
',');
1325 for (
int i = 0; i < saveParameters.size(); i++) {
1326 QStringList sPNameAndDetail = saveParameters[i].split(
'=');
1327 std::string saveParameterName = sPNameAndDetail[0].trimmed().toStdString();
1328 std::string saveParameterDetail = sPNameAndDetail[1].trimmed().toStdString();
1329 if (saveParameterDetail ==
"True")
1330 alg->setProperty(saveParameterName,
true);
1331 else if (saveParameterDetail ==
"False")
1332 alg->setProperty(saveParameterName,
false);
1335 alg->setPropertyValue(saveParameterName, saveParameterDetail);
1344 QString savedFile = QString::fromStdString(alg->getProperty(
"Filename"));
1345 QStringList arguments;
1348 if (programKeysAndDetails.count(
"arguments") != 0) {
1349 QString temp = QString::fromStdString(programKeysAndDetails.find(
"arguments")->second);
1350 temp.replace(QString(
"[file]"), savedFile);
1352 arguments = temp.split(
",");
1354 arguments.insert(0, savedFile);
1357 std::vector<std::string> argumentsV;
1359 for (
int i = 0; i < arguments.size(); i++) {
1360 argumentsV.assign(1, (arguments[i].toStdString()));
1366 }
catch (std::runtime_error &) {
1367 QMessageBox::information(
this,
"Error",
1368 "User tried to open program from: " + QString::fromStdString(expTarget) +
1369 " There was an error opening the program. "
1370 "Please check the target and arguments list "
1371 "to ensure that these are correct");
1373 }
catch (std::exception &) {
1374 QMessageBox::information(
this,
"Mantid - Send to Program",
1375 "A file property wasn't found. Please check that the correct" +
1376 QString(
"save algorithm was used.\n(View -> Preferences -> "
1377 "Mantid -> SendTo -> Edit -> SaveUsing)"));
1380 QMessageBox::information(
this,
"Target Path Error",
1381 "User tried to open program from: " + QString::fromStdString(expTarget) +
1382 " The target file path for the program "
1383 "can't be found. Please check that the full "
1402 const bool isAdvanced = type ==
"Advanced";
1406 if (userInput.plots.empty()) {
1409 bool showErrorBars = ((type ==
"Errors") || (type ==
"Advanced" && userInput.errors));
1412 if (userInput.tiled) {
1414 }
else if (userInput.simple || userInput.waterfall) {
1415 if (userInput.isAdvanced) {
1417 userInput.waterfall, userInput.advanced.logName, userInput.advanced.customLogValues);
1420 userInput.waterfall);
1423 }
else if (userInput.surface) {
1425 userInput.advanced.axisName, userInput.advanced.logName,
1426 userInput.advanced.customLogValues, userInput.advanced.workspaceNames);
1427 }
else if (userInput.contour) {
1429 userInput.advanced.axisName, userInput.advanced.logName,
1430 userInput.advanced.customLogValues, userInput.advanced.workspaceNames);
1445 auto items =
m_tree->selectedItems();
1451 QStringList allWsNames;
1453 for (
auto &item : items) {
1456 if (
auto wsGroup = std::dynamic_pointer_cast<WorkspaceGroup>(ws)) {
1457 for (
auto &name : wsGroup->getNames())
1458 allWsNames.append(QString::fromStdString(name));
1460 allWsNames.append(item->text(0));
1464 allWsNames.removeDuplicates();
1471 case Qt::Key_Delete:
1472 case Qt::Key_Backspace:
1487 QMessageBox::information(
this,
"Error", QString(
"Cannot create detectors tables for workspace ") + ws);
IPeaksWorkspace_sptr workspace
This class should be the basis for all customised algorithm dialogs.
Defines a mapping between a workspace ID and a pixmap to use for an icon.
A specialized class for dealing with file properties.
std::string getDefaultExt() const
Returns the main file extension that's used.
The Logger class is in charge of the publishing messages from the framework through various channels.
Base class for properties.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
EXPORT_OPT_MANTIDQT_COMMON QPixmap getQPixmap(const std::string &name)
Function that returns a QPixmap given a string name.
std::shared_ptr< const IMDEventWorkspace > IMDEventWorkspace_const_sptr
Shared pointer to Mantid::API::IMDEventWorkspace (const version)
std::shared_ptr< IAlgorithm > IAlgorithm_sptr
shared pointer to Mantid::API::IAlgorithm
std::shared_ptr< Workspace > Workspace_sptr
shared pointer to Mantid::API::Workspace
std::shared_ptr< const IMDWorkspace > IMDWorkspace_const_sptr
Shared pointer to the IMDWorkspace base class (const version)
std::shared_ptr< const MatrixWorkspace > MatrixWorkspace_const_sptr
shared pointer to the matrix workspace base class (const version)
std::shared_ptr< IMDWorkspace > IMDWorkspace_sptr
Shared pointer to the IMDWorkspace base class.
std::shared_ptr< const IPeaksWorkspace > IPeaksWorkspace_const_sptr
shared pointer to Mantid::API::IPeaksWorkspace (const version)