From f45a25bfc82b500871efacddf8d06ae3e3e81cb8 Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Sat, 12 Oct 2019 08:24:42 +0100 Subject: [PATCH] Remove custom dialog for CreateSampleShape Refs #23620 --- docs/source/release/v4.2.0/ui.rst | 9 +- .../plugins/algorithm_dialogs/CMakeLists.txt | 100 ++- .../CreateSampleShapeDialog.h | 186 ----- .../CreateSampleShapeDialog.ui | 195 ----- .../src/CreateSampleShapeDialog.cpp | 706 ------------------ 5 files changed, 55 insertions(+), 1141 deletions(-) delete mode 100644 qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h delete mode 100644 qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.ui delete mode 100644 qt/widgets/plugins/algorithm_dialogs/src/CreateSampleShapeDialog.cpp diff --git a/docs/source/release/v4.2.0/ui.rst b/docs/source/release/v4.2.0/ui.rst index 5f2d4ccc47a..1b3fd7e2f57 100644 --- a/docs/source/release/v4.2.0/ui.rst +++ b/docs/source/release/v4.2.0/ui.rst @@ -25,9 +25,12 @@ See :doc:`mantidworkbench`. SliceViewer and Vates Simple Interface -------------------------------------- -:ref:`Release 4.2.0 <v4.2.0>` - Miscellaneous ------------- -- Error Reporter text entry and information made more user friendly. \ No newline at end of file +- Error Reporter text entry and information made more user friendly. +- The custom dialog for :ref:`CreateSampleShape <algm-CreateSampleShape>` + has been removed. It will now fall back to the generic one. + + +:ref:`Release 4.2.0 <v4.2.0>` diff --git a/qt/widgets/plugins/algorithm_dialogs/CMakeLists.txt b/qt/widgets/plugins/algorithm_dialogs/CMakeLists.txt index edf5f032831..2e24f45f2cb 100644 --- a/qt/widgets/plugins/algorithm_dialogs/CMakeLists.txt +++ b/qt/widgets/plugins/algorithm_dialogs/CMakeLists.txt @@ -1,23 +1,24 @@ -set(SRC_FILES - src/CatalogPublishDialog.cpp - src/CreateSampleShapeDialog.cpp - src/ConvertTableToMatrixWorkspaceDialog.cpp - src/StartLiveDataDialog.cpp - src/FitDialog.cpp - src/LoadDialog.cpp - src/LoadDAEDialog.cpp - src/LoadRawDialog.cpp - src/LOQScriptInputDialog.cpp - src/MantidGLWidget.cpp - src/PeriodicTableWidget.cpp - src/PlotAsymmetryByLogValueDialog.cpp - src/SampleShapeHelpers.cpp - src/SmoothNeighboursDialog.cpp - src/SortTableWorkspaceDialog.cpp) +set( + SRC_FILES + src/CatalogPublishDialog.cpp + src/ConvertTableToMatrixWorkspaceDialog.cpp + src/StartLiveDataDialog.cpp + src/FitDialog.cpp + src/LoadDialog.cpp + src/LoadDAEDialog.cpp + src/LoadRawDialog.cpp + src/LOQScriptInputDialog.cpp + src/MantidGLWidget.cpp + src/PeriodicTableWidget.cpp + src/PlotAsymmetryByLogValueDialog.cpp + src/SampleShapeHelpers.cpp + src/SmoothNeighboursDialog.cpp + src/SortTableWorkspaceDialog.cpp +) -set(MOC_FILES +set( + MOC_FILES inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CatalogPublishDialog.h - inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h inc/MantidQtWidgets/Plugins/AlgorithmDialogs/ConvertTableToMatrixWorkspaceDialog.h inc/MantidQtWidgets/Plugins/AlgorithmDialogs/StartLiveDataDialog.h inc/MantidQtWidgets/Plugins/AlgorithmDialogs/FitDialog.h @@ -30,15 +31,15 @@ set(MOC_FILES inc/MantidQtWidgets/Plugins/AlgorithmDialogs/PlotAsymmetryByLogValueDialog.h inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SampleShapeHelpers.h inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SmoothNeighboursDialog.h - inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SortTableWorkspaceDialog.h) + inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SortTableWorkspaceDialog.h +) # Include files aren't required, but this makes them appear in Visual Studio -set(INC_FILES - ${MOC_FILES}) +set(INC_FILES ${MOC_FILES}) -set(UI_FILES +set( + UI_FILES inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CatalogPublishDialog.ui - inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.ui inc/MantidQtWidgets/Plugins/AlgorithmDialogs/ConvertTableToMatrixWorkspaceDialog.ui inc/MantidQtWidgets/Plugins/AlgorithmDialogs/DiagScriptInputDialog.ui inc/MantidQtWidgets/Plugins/AlgorithmDialogs/LOQScriptInputDialog.ui @@ -47,9 +48,13 @@ set(UI_FILES inc/MantidQtWidgets/Plugins/AlgorithmDialogs/LoadDialog.ui inc/MantidQtWidgets/Plugins/AlgorithmDialogs/StartLiveDataDialog.ui inc/MantidQtWidgets/Plugins/AlgorithmDialogs/FitDialog.ui - inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SortTableWorkspaceDialog.ui) + inc/MantidQtWidgets/Plugins/AlgorithmDialogs/SortTableWorkspaceDialog.ui +) -include_directories(inc inc/MantidQtWidgets/Plugins/AlgorithmDialogs) +include_directories( + inc + inc/MantidQtWidgets/Plugins/AlgorithmDialogs +) mtd_add_qt_library( TARGET_NAME MantidQtWidgetsPluginsAlgorithmDialogs @@ -57,11 +62,11 @@ mtd_add_qt_library( SRC ${SRC_FILES} MOC ${MOC_FILES} NOMOC ${INC_FILES} - UI ${UI_FILES} - PRECOMPILED + UI + ${UI_FILES} + PRECOMPILED inc/MantidQtWidgets/Plugins/AlgorithmDialogs/PrecompiledHeader.h - SYSTEM_INCLUDE_DIRS - ${Boost_INCLUDE_DIRS} + SYSTEM_INCLUDE_DIRS ${Boost_INCLUDE_DIRS} LINK_LIBS ${TCMALLOC_LIBRARIES_LINKTIME} ${CORE_MANTIDLIBS} @@ -69,16 +74,12 @@ mtd_add_qt_library( ${Boost_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARIES} - QT4_LINK_LIBS - Qt4::QtOpenGL - MTD_QT_LINK_LIBS - MantidQtWidgetsCommon - OSX_INSTALL_RPATH - @loader_path/../../Contents/MacOS - LINUX_INSTALL_RPATH - "\$ORIGIN/../../${LIB_DIR}" - INSTALL_DIR_BASE - ${PLUGINS_DIR}) + QT4_LINK_LIBS Qt4::QtOpenGL + MTD_QT_LINK_LIBS MantidQtWidgetsCommon + OSX_INSTALL_RPATH @loader_path/../../Contents/MacOS + LINUX_INSTALL_RPATH "\$ORIGIN/../../${LIB_DIR}" + INSTALL_DIR_BASE ${PLUGINS_DIR} +) mtd_add_qt_library( TARGET_NAME MantidQtWidgetsPluginsAlgorithmDialogs @@ -86,8 +87,9 @@ mtd_add_qt_library( SRC ${SRC_FILES} MOC ${MOC_FILES} NOMOC ${INC_FILES} - UI ${UI_FILES} - PRECOMPILED + UI + ${UI_FILES} + PRECOMPILED inc/MantidQtWidgets/Plugins/AlgorithmDialogs/PrecompiledHeader.h LINK_LIBS ${TCMALLOC_LIBRARIES_LINKTIME} @@ -96,13 +98,9 @@ mtd_add_qt_library( ${Boost_LIBRARIES} ${QT_LIBRARIES} ${OPENGL_LIBRARIES} - QT5_LINK_LIBS - Qt5::OpenGL - MTD_QT_LINK_LIBS - MantidQtWidgetsCommon - OSX_INSTALL_RPATH - @loader_path/../../Contents/MacOS - LINUX_INSTALL_RPATH - "\$ORIGIN/../../${LIB_DIR}" - INSTALL_DIR_BASE - ${WORKBENCH_PLUGINS_DIR}) + QT5_LINK_LIBS Qt5::OpenGL + MTD_QT_LINK_LIBS MantidQtWidgetsCommon + OSX_INSTALL_RPATH @loader_path/../../Contents/MacOS + LINUX_INSTALL_RPATH "\$ORIGIN/../../${LIB_DIR}" + INSTALL_DIR_BASE ${WORKBENCH_PLUGINS_DIR} +) diff --git a/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h b/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h deleted file mode 100644 index 7de7582e204..00000000000 --- a/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h +++ /dev/null @@ -1,186 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2009 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source -// & Institut Laue - Langevin -// SPDX - License - Identifier: GPL - 3.0 + -#ifndef MANTIDQT_CUSTOMDIALOGS_CREATESAMPLESHAPEDIALOG_H_ -#define MANTIDQT_CUSTOMDIALOGS_CREATESAMPLESHAPEDIALOG_H_ - -//--------------------------- -// Includes -//-------------------------- -#include "MantidQtWidgets/Common/AlgorithmDialog.h" -#include "ui_CreateSampleShapeDialog.h" - -#include <QHash> -#include <QItemDelegate> -#include <QMap> -#include <QPoint> -#include <QTreeWidget> -#include <QVector> - -//----------------------------------- -// Qt Forward declarations -//--------------------------------- -class QCloseEvent; - -namespace MantidQt { -namespace CustomDialogs { - -class BinaryTreeWidget; -class BinaryTreeWidgetItem; -class ShapeDetails; -struct BaseInstantiator; -struct Operation; -class MantidGLWidget; - -/** - This class gives specialised dialog for the sample shape definition - algorithm - - @author Martyn Gigg, Tessella Support Services plc - @date 13/03/2009 -*/ -class CreateSampleShapeDialog : public MantidQt::API::AlgorithmDialog { - Q_OBJECT - -public: - /// Default constructor - CreateSampleShapeDialog(QWidget *parent = nullptr); - - /// Destructor - ~CreateSampleShapeDialog() override; - -private slots: - /// Context menu request - void handleTreeContextMenuRequest(const QPoint &pos); - /// Toggle the flag on - void toggleShapeComplement(bool state); - /// Add a new shape - void addShape(QAction *shape); - /// Add operation node based on menu action - void addOperation(QAction *shape); - /// Connects to the delete slot - void handleDeleteRequest(); - /// Remove an item from the tree (recursive) - void removeItem(BinaryTreeWidgetItem *item); - /// Setup the details box based currently selected item - void setupDetailsBox(); - /// Change item data - void changeTreeData(BinaryTreeWidgetItem *item, int data); - /// Update the object within the 3D widget - void update3DView(); - -private: - /// Initialize the layout - void initLayout() override; - /// Get the input out of the dialog - void parseInput() override; - /// Find the parent - BinaryTreeWidgetItem *getSelectedItem(); - /// Create a details widget based upon the shape name given - ShapeDetails *createDetailsWidget(const QString &shapename) const; - /// Construct the XML from the current tree - QString constructShapeXML() const; - -private: - /// The form generated with Qt Designer - Ui::CreateSampleShapeDialog m_uiForm; - /// A pointer to the model for the shape tree - BinaryTreeWidget *m_shapeTree; - /// A map of shape names to instantiator objects - QHash<QString, BaseInstantiator *> m_setup_map; - /// A map of QTreeWidgetItem objects to their details objects - QMap<BinaryTreeWidgetItem *, ShapeDetails *> m_details_map; - /// A map of QTreeWidgetItem objects to their operation objects - QMap<BinaryTreeWidgetItem *, Operation *> m_ops_map; - /// The 3D object viewer - MantidGLWidget *m_object_viewer; -}; - -/** - * A custom item to use in the BinaryTree widget - */ -class BinaryTreeWidgetItem : public QTreeWidgetItem { - -public: - /// Default Constructor - BinaryTreeWidgetItem(int type = QTreeWidgetItem::UserType); - - /// Constructor taking a string list and an optional type - BinaryTreeWidgetItem(const QStringList &strings, - int type = QTreeWidgetItem::UserType); - - /// Add a child item - bool addChildItem(BinaryTreeWidgetItem *child); - - /// A pointer to the left child - BinaryTreeWidgetItem *leftChild() const; - - /// A pointer to the right child - BinaryTreeWidgetItem *rightChild() const; - -private: - /// The index of the left child (0 or 1) - int m_left_index; - /// The index of the right child (0 or 1) - int m_right_index; -}; - -/** - * A widget to implement a binary tree display. - */ -class BinaryTreeWidget : public QTreeWidget { - Q_OBJECT - -public: - /// Default constructor - BinaryTreeWidget(QWidget *parent = nullptr); - - // Return the root of the binary tree - BinaryTreeWidgetItem *root() const; - - /// Recurse through the tree in a post-order - void traverseInPostOrder(BinaryTreeWidgetItem *node, - QList<BinaryTreeWidgetItem *> &expression); - -/// Called when the data in the model is changed -#if QT_VERSION < 0x050000 - void dataChanged(const QModelIndex &topLeft, - const QModelIndex &bottomRight) override; -#else - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, - const QVector<int> &roles = QVector<int>()) override; -#endif - -signals: - /// Emitted when data has changed - void treeDataChange(BinaryTreeWidgetItem *item, int data); -}; - -/** - * A custom delegate class used for item editing - */ -class ComboBoxDelegate : public QItemDelegate { - Q_OBJECT - -public: - /// Default constructor - ComboBoxDelegate(QWidget *parent = nullptr); - /// Create an editor for the item - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; - /// Set the data for the editor when it has been created - void setEditorData(QWidget *editor, const QModelIndex &index) const override; - /// Set the data for the model when editing has finished - void setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const override; - /// Ensure that the editor has the correct geometry when it is created - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, - const QModelIndex &index) const override; -}; -} // namespace CustomDialogs -} // namespace MantidQt - -#endif // MANTIDQT_CUSTOMDIALOGS_CREATESAMPLESHAPE_H_ diff --git a/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.ui b/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.ui deleted file mode 100644 index 532cce06bd5..00000000000 --- a/qt/widgets/plugins/algorithm_dialogs/inc/MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.ui +++ /dev/null @@ -1,195 +0,0 @@ -<ui version="4.0" > - <class>CreateSampleShapeDialog</class> - <widget class="QDialog" name="CreateSampleShapeDialog" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>796</width> - <height>354</height> - </rect> - </property> - <property name="windowTitle" > - <string>Sample Shape Definition</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout" > - <item> - <layout class="QHBoxLayout" name="horizontalLayout" > - <item> - <widget class="QGroupBox" name="shape_box" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title" > - <string>Object Tree</string> - </property> - </widget> - </item> - <item> - <widget class="QGroupBox" name="details_box" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title" > - <string>Details</string> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2" > - <item> - <widget class="QScrollArea" name="details_scroll" > - <property name="frameShape" > - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> - </property> - <property name="widgetResizable" > - <bool>true</bool> - </property> - <widget class="QWidget" name="scrollAreaWidgetContents" > - <property name="geometry" > - <rect> - <x>0</x> - <y>0</y> - <width>232</width> - <height>258</height> - </rect> - </property> - </widget> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="view_box" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Expanding" hsizetype="Expanding" > - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title" > - <string>3D View</string> - </property> - </widget> - </item> - </layout> - </item> - <item> - <layout class="QHBoxLayout" name="bottomlayout" > - <item> - <widget class="QLabel" name="label" > - <property name="text" > - <string>Workspace</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="wksp_opt" /> - </item> - <item> - <spacer name="horizontalSpacer" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="helpButton" > - <property name="maximumSize" > - <size> - <width>25</width> - <height>16777215</height> - </size> - </property> - <property name="text" > - <string>?</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="createBtn" > - <property name="text" > - <string>Create Shape</string> - </property> - <property name="default" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="cancelBtn" > - <property name="text" > - <string>Cancel</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - <resources/> - <connections> - <connection> - <sender>createBtn</sender> - <signal>clicked()</signal> - <receiver>CreateSampleShapeDialog</receiver> - <slot>accept()</slot> - <hints> - <hint type="sourcelabel" > - <x>741</x> - <y>379</y> - </hint> - <hint type="destinationlabel" > - <x>438</x> - <y>201</y> - </hint> - </hints> - </connection> - <connection> - <sender>cancelBtn</sender> - <signal>clicked()</signal> - <receiver>CreateSampleShapeDialog</receiver> - <slot>reject()</slot> - <hints> - <hint type="sourcelabel" > - <x>827</x> - <y>379</y> - </hint> - <hint type="destinationlabel" > - <x>438</x> - <y>201</y> - </hint> - </hints> - </connection> - </connections> - <designerdata> - <property name="gridDeltaX" > - <number>10</number> - </property> - <property name="gridDeltaY" > - <number>10</number> - </property> - <property name="gridSnapX" > - <bool>false</bool> - </property> - <property name="gridSnapY" > - <bool>false</bool> - </property> - <property name="gridVisible" > - <bool>true</bool> - </property> - </designerdata> -</ui> diff --git a/qt/widgets/plugins/algorithm_dialogs/src/CreateSampleShapeDialog.cpp b/qt/widgets/plugins/algorithm_dialogs/src/CreateSampleShapeDialog.cpp deleted file mode 100644 index e905858306e..00000000000 --- a/qt/widgets/plugins/algorithm_dialogs/src/CreateSampleShapeDialog.cpp +++ /dev/null @@ -1,706 +0,0 @@ -// Mantid Repository : https://github.com/mantidproject/mantid -// -// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI, -// NScD Oak Ridge National Laboratory, European Spallation Source -// & Institut Laue - Langevin -// SPDX - License - Identifier: GPL - 3.0 + -//--------------------------- -// Includes -//-------------------------- -#include "MantidQtWidgets/Plugins/AlgorithmDialogs/CreateSampleShapeDialog.h" -#include "MantidQtWidgets/Common/AlgorithmInputHistory.h" -#include "MantidQtWidgets/Plugins/AlgorithmDialogs/MantidGLWidget.h" -#include "MantidQtWidgets/Plugins/AlgorithmDialogs/SampleShapeHelpers.h" - -#include "MantidGeometry/Objects/CSGObject.h" -#include "MantidGeometry/Objects/ShapeFactory.h" - -#include <QCloseEvent> -#include <QComboBox> -#include <QLabel> -#include <QLineEdit> -#include <QMenu> -#include <QMessageBox> -#include <QShortcut> - -// Add this class to the list of specialised dialogs in this namespace -namespace MantidQt { -namespace CustomDialogs { -DECLARE_DIALOG(CreateSampleShapeDialog) -} -} // namespace MantidQt - -// Just to save writing this everywhere -using namespace MantidQt::CustomDialogs; - -//--------------------------------------- -// Public member functions -//--------------------------------------- -/** - * Constructor - */ -CreateSampleShapeDialog::CreateSampleShapeDialog(QWidget *parent) - : AlgorithmDialog(parent), m_shapeTree(nullptr), m_setup_map(), - m_details_map(), m_ops_map() { - m_object_viewer = new MantidGLWidget; -} - -/** - * Destructor - */ -CreateSampleShapeDialog::~CreateSampleShapeDialog() { - // Delete the objects created. The shape details static counter is decremented - // when - // its destructor is called - QMutableMapIterator<BinaryTreeWidgetItem *, ShapeDetails *> itr( - m_details_map); - while (itr.hasNext()) { - itr.next(); - ShapeDetails *obj = itr.value(); - itr.remove(); - delete obj; - } - QMutableMapIterator<BinaryTreeWidgetItem *, Operation *> itrb(m_ops_map); - while (itrb.hasNext()) { - itrb.next(); - Operation *obj = itrb.value(); - itrb.remove(); - delete obj; - } -} - -/** - * Set up the dialog - */ -void CreateSampleShapeDialog::initLayout() { - // The main setup function - m_uiForm.setupUi(this); - - // Create the map of instantiators. The keys defined here are used to generate - // the shape - // menu items - m_setup_map.clear(); - m_setup_map["sphere"] = new ShapeDetailsInstantiator<SphereDetails>; - m_setup_map["cylinder"] = new ShapeDetailsInstantiator<CylinderDetails>; - m_setup_map["infinite cylinder"] = - new ShapeDetailsInstantiator<InfiniteCylinderDetails>(); - m_setup_map["cylinder ring slice"] = - new ShapeDetailsInstantiator<SliceOfCylinderRingDetails>(); - // m_setup_map["cone"] = new ShapeDetailsInstantiator<ConeDetails>(); - // m_setup_map["infinite cone"] = new - // ShapeDetailsInstantiator<InfiniteConeDetails>(); - m_setup_map["infinite plane"] = - new ShapeDetailsInstantiator<InfinitePlaneDetails>(); - m_setup_map["cuboid"] = new ShapeDetailsInstantiator<CuboidDetails>(); - m_setup_map["hexahedron"] = new ShapeDetailsInstantiator<HexahedronDetails>(); - // m_setup_map["torus"] = new ShapeDetailsInstantiator<TorusDetails>(); - - // The binary tree - m_shapeTree = new BinaryTreeWidget(this); - m_shapeTree->setColumnCount(1); - m_shapeTree->setHeaderLabel(""); - m_shapeTree->setContextMenuPolicy(Qt::CustomContextMenu); - m_shapeTree->setSelectionBehavior(QAbstractItemView::SelectItems); - m_shapeTree->setSelectionMode(QAbstractItemView::SingleSelection); - connect(m_shapeTree, SIGNAL(customContextMenuRequested(const QPoint &)), this, - SLOT(handleTreeContextMenuRequest(const QPoint &))); - connect(m_shapeTree, SIGNAL(itemSelectionChanged()), this, - SLOT(setupDetailsBox())); - connect(m_shapeTree, SIGNAL(treeDataChange(BinaryTreeWidgetItem *, int)), - this, SLOT(changeTreeData(BinaryTreeWidgetItem *, int))); - - QPushButton *view_shape_btn = new QPushButton("Update 3D view"); - connect(view_shape_btn, SIGNAL(clicked()), this, SLOT(update3DView())); - QHBoxLayout *bottom = new QHBoxLayout; - bottom->addWidget(view_shape_btn); - bottom->addStretch(); - - // Shape box layout - QVBoxLayout *shape_box_layout = new QVBoxLayout; - shape_box_layout->addWidget(m_shapeTree); - shape_box_layout->addLayout(bottom); - m_uiForm.shape_box->setLayout(shape_box_layout); - - QShortcut *delete_key = new QShortcut(QKeySequence(Qt::Key_Delete), this); - connect(delete_key, SIGNAL(activated()), this, SLOT(handleDeleteRequest())); - - QVBoxLayout *view_box_layout = new QVBoxLayout; - view_box_layout->addWidget(m_object_viewer); - m_uiForm.view_box->setLayout(view_box_layout); - - // Check input workspace property. If there are available workspaces then - // these have been set as allowed values - std::vector<std::string> workspaces = - getAlgorithmProperty("InputWorkspace")->allowedValues(); - for (std::vector<std::string>::const_iterator itr = workspaces.begin(); - itr != workspaces.end(); ++itr) { - m_uiForm.wksp_opt->addItem(QString::fromStdString(*itr)); - } - tie(m_uiForm.wksp_opt, "InputWorkspace", m_uiForm.bottomlayout); - - // Connect the help button - connect(m_uiForm.helpButton, SIGNAL(clicked()), this, SLOT(helpClicked())); -} - -/** - * Retrieve the input from the dialog - */ -void CreateSampleShapeDialog::parseInput() { - QString xml = constructShapeXML(); - if (m_shapeTree->topLevelItemCount() > 0 && xml.isEmpty()) { - QMessageBox::information(this, "CreateSampleShapeDialog", - "An error occurred while parsing the shape tree.\n" - "Please check that each node has two children and " - "the lowest elements are primitive shapes."); - return; - } - - storePropertyValue("ShapeXML", xml); - - // Get workspace value - storePropertyValue("InputWorkspace", m_uiForm.wksp_opt->currentText()); -} - -/** - * Update the 3D widget with a new object - */ -void CreateSampleShapeDialog::update3DView() { - std::string shapexml = constructShapeXML().toStdString(); - if (m_shapeTree->topLevelItemCount() > 0 && shapexml.empty()) { - QMessageBox::information(this, "CreateSampleShapeDialog", - "An error occurred while parsing the shape tree.\n" - "Please check that each node has two children and " - "the lowest elements are primitive shapes."); - return; - } - - // Testing a predefined complex shape PLEASE LEAVE FOR THE MOMENT - // std::string shapexml = "<cuboid id=\"cuboid_1\" >\n" - // "<left-front-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.0\" />\n" - // "<left-front-top-point x=\"-0.02\" y=\"0.05\" z= \"0.0\" />\n" - // "<left-back-bottom-point x=\"-0.02\" y=\"-0.02\" z= \"0.07\" />\n" - // "<right-front-bottom-point x=\"0.05\" y=\"-0.02\" z= \"0.0\" />\n" - // "</cuboid>\n" - // "<infinite-cylinder id=\"infcyl_1\" >" - // "<radius val=\"0.025\" />" - // "<centre x=\"0.015\" y=\"0.015\" z= \"0.07\" />" - // "<axis x=\"0.0\" y=\"0.0\" z= \"-0.001\" />" - // "</infinite-cylinder>\n" - // "<sphere id=\"sphere_1\">" - // "<centre x=\"0.015\" y=\"0.015\" z= \"0.035\" />" - // "<radius val=\"0.04\" />" - // "</sphere>\n" - // "<infinite-cylinder id=\"infcyl_3\" >" - // "<radius val=\"0.025\" />" - // "<centre x=\"0.015\" y=\"-0.02\" z= \"0.035\" />" - // "<axis x=\"0.0\" y=\"0.001\" z= \"0.0\" />" - // "</infinite-cylinder>\n" - // "<infinite-cylinder id=\"infcyl_2\" >" - // "<radius val=\"0.025\" />" - // "<centre x=\"-0.02\" y=\"0.015\" z= \"0.035\" />" - // "<axis x=\"0.001\" y=\"0.0\" z= \"0.0\" />" - // "</infinite-cylinder>\n" - // "<algebra val=\"((cuboid_1 sphere_1) (# - // (infcyl_1:(infcyl_2:infcyl_3))))\" />\n"; - - Mantid::Geometry::ShapeFactory sFactory; - auto shape_sptr = sFactory.createShape(shapexml); - // std::cerr << "\n--------- XML String -----------\n" << shapexml << - // "\n---------------------\n"; - if (shape_sptr == boost::shared_ptr<Mantid::Geometry::CSGObject>()) - return; - try { - shape_sptr->initDraw(); - } catch (...) { - QMessageBox::information( - this, "Create sample shape", - QString( - "An error occurred while attempting to initialize the shape.\n") + - "Please check that all objects intersect each other."); - return; - } - - m_object_viewer->setDisplayObject(shape_sptr); -} - -/** - * This slot is called when a context menu is requested inside the tree widget - * @param pos :: The position of the mouse pointer when the menu was requested - */ -void CreateSampleShapeDialog::handleTreeContextMenuRequest(const QPoint &pos) { - QMenu *context_menu = new QMenu(m_shapeTree); - - QTreeWidgetItem *item = m_shapeTree->itemAt(pos); - QString op_text = "Insert child operation"; - bool is_shape(false); - if (item) { - QString displayText = item->text(0); - if (!displayText.startsWith("inter") && !displayText.startsWith("uni") && - !displayText.startsWith("diff")) { - is_shape = true; - // For a shape we need the option to mark it as a complement shape - QAction *complement = new QAction("Complement", context_menu); - complement->setCheckable(true); - bool isChecked = - m_details_map.value(getSelectedItem())->getComplementFlag(); - complement->setChecked(isChecked); - connect(complement, SIGNAL(toggled(bool)), this, - SLOT(toggleShapeComplement(bool))); - context_menu->addAction(complement); - context_menu->addSeparator(); - - op_text = "Insert operation above"; - } - } - - QMenu *add_op = new QMenu(op_text); - add_op->addAction(new QAction("intersection", add_op)); - add_op->addAction(new QAction("union", add_op)); - add_op->addAction(new QAction("difference", add_op)); - connect(add_op, SIGNAL(triggered(QAction *)), this, - SLOT(addOperation(QAction *))); - context_menu->addMenu(add_op); - - if (!is_shape || m_shapeTree->topLevelItemCount() == 0) { - QMenu *submenu = new QMenu("Insert child shape"); - QStringList shapes = m_setup_map.keys(); - QStringListIterator itr(shapes); - while (itr.hasNext()) { - submenu->addAction(new QAction(itr.next(), submenu)); - } - connect(submenu, SIGNAL(triggered(QAction *)), this, - SLOT(addShape(QAction *))); - context_menu->addMenu(submenu); - } - - context_menu->addSeparator(); - QAction *remove = new QAction("Delete", context_menu); - connect(remove, SIGNAL(triggered()), this, SLOT(handleDeleteRequest())); - context_menu->addAction(remove); - - context_menu->popup(QCursor::pos()); -} - -void CreateSampleShapeDialog::toggleShapeComplement(bool state) { - BinaryTreeWidgetItem *selected = getSelectedItem(); - if (m_details_map.contains(selected)) { - m_details_map.value(selected)->setComplementFlag(state); - } - if (state) { - selected->setText(0, QString("# ") + selected->text(0)); - } else { - selected->setText(0, selected->text(0).section('#', 1).trimmed()); - } -} - -void CreateSampleShapeDialog::changeTreeData(BinaryTreeWidgetItem *item, - int data) { - if (m_ops_map.contains(item)) { - m_ops_map.value(item)->binaryop = data; - } -} - -BinaryTreeWidgetItem *CreateSampleShapeDialog::getSelectedItem() { - if (!m_shapeTree->selectedItems().isEmpty()) { - /// Single selections are the only ones allowed - return dynamic_cast<BinaryTreeWidgetItem *>( - m_shapeTree->selectedItems()[0]); - } - - // Check if tree is empty - if (m_shapeTree->topLevelItemCount() == 0) { - // Give back the invisible root item - return m_shapeTree->root(); - } else { - QMessageBox::information(this, "CreateSampleShape", - "Please select an item in the list as a parent."); - } - return nullptr; -} - -/** - * Add a new child shape - * @param shape :: The action that emitted the signal - */ -void CreateSampleShapeDialog::addShape(QAction *shape) { - // Get the selected item - BinaryTreeWidgetItem *parent = getSelectedItem(); - if (parent && parent->childCount() == 2) - return; - - BinaryTreeWidgetItem *child = - new BinaryTreeWidgetItem(QStringList(shape->text())); - child->setFlags(child->flags() & ~Qt::ItemIsEditable); - - if (m_shapeTree->topLevelItemCount() == 0) { - m_shapeTree->insertTopLevelItem(0, child); - } else if (parent) { - parent->addChildItem(child); - } else { - return; - } - - // This calls setupDetails - m_shapeTree->setCurrentItem(child); - m_shapeTree->expandAll(); -} - -/** - * Add operation node based on menu action - */ -void CreateSampleShapeDialog::addOperation(QAction *opt) { - // Get the selected item - BinaryTreeWidgetItem *selected = getSelectedItem(); - if (!selected) - return; - if (selected && selected->childCount() == 2) - return; - - BinaryTreeWidgetItem *operation = new BinaryTreeWidgetItem; - QFont font = operation->font(0); - font.setBold(true); - operation->setFont(0, font); - operation->setData(0, Qt::DisplayRole, opt->text()); - int opcode(0); - if (opt->text().startsWith("u")) - opcode = 1; - else if (opt->text().startsWith("d")) - opcode = 2; - else - opcode = 0; - - operation->setData(0, Qt::UserRole, opcode); - operation->setFlags(operation->flags() | Qt::ItemIsEditable); - - if (m_shapeTree->topLevelItemCount() == 0) { - m_shapeTree->insertTopLevelItem(0, operation); - } else { - if (m_ops_map.contains(selected)) { - selected->addChildItem(operation); - } else if (selected->parent()) { - int index = selected->parent()->indexOfChild(selected); - selected->parent()->insertChild(index, operation); - selected->parent()->removeChild(selected); - operation->addChildItem(selected); - } else { - m_shapeTree->takeTopLevelItem(m_shapeTree->indexOfTopLevelItem(selected)); - m_shapeTree->insertTopLevelItem(0, operation); - operation->addChildItem(selected); - } - } - - m_ops_map.insert(operation, new Operation(opcode)); - // This calls setupDetails if necessary - m_shapeTree->setCurrentItem(operation); - m_shapeTree->expandAll(); -} - -/** - * Handle a delete signal - */ -void CreateSampleShapeDialog::handleDeleteRequest() { - BinaryTreeWidgetItem *item = getSelectedItem(); - if (!item) - return; - removeItem(item); -} - -/** - * Remove an item and all children from the tree - */ -void CreateSampleShapeDialog::removeItem(BinaryTreeWidgetItem *item) { - if (!item) - return; - - // Recursively remove children - if (item->childCount() > 0) { - while (item->childCount() > 0) { - if (item->leftChild()) - removeItem(item->leftChild()); - if (item->rightChild()) - removeItem(item->rightChild()); - } - } - - if (m_details_map.contains(item)) { - ShapeDetails *obj = m_details_map.take(item); - delete obj; - } else if (m_ops_map.contains(item)) { - Operation *obj = m_ops_map.take(item); - delete obj; - } else - return; - - if (item->parent()) { - item->parent()->removeChild(item); - } else { - m_shapeTree->takeTopLevelItem(m_shapeTree->indexOfTopLevelItem(item)); - } -} - -/** - * Setup the layout for the details box based upon the item given - */ -void CreateSampleShapeDialog::setupDetailsBox() { - QList<QTreeWidgetItem *> selection = m_shapeTree->selectedItems(); - if (selection.isEmpty()) - return; - - // Remove the current widget if one exists in the scroll area - if (m_uiForm.details_scroll->widget()) - m_uiForm.details_scroll->takeWidget(); - - BinaryTreeWidgetItem *item = - dynamic_cast<BinaryTreeWidgetItem *>(selection[0]); - if (!item) - return; - QString shapename = item->text(0); - if (m_setup_map.contains(shapename)) { - ShapeDetails *obj = nullptr; - if (m_details_map.contains(item)) { - obj = m_details_map.value(item); - } else { - obj = createDetailsWidget(shapename); - m_details_map.insert(item, obj); - } - // Set it as the currently displayed widget - m_uiForm.details_scroll->setWidget(obj); - } -} - -/** - * Create the correct type of details box for the shape - * @param shapename :: The name of the shape for which to create a widget - * @return A pointer to the details object - */ -ShapeDetails * -CreateSampleShapeDialog::createDetailsWidget(const QString &shapename) const { - if (m_setup_map.contains(shapename)) { - return m_setup_map.value(shapename)->createInstance(); - } - return nullptr; -} - -/** - * Construct the XML from the current tree - */ -QString CreateSampleShapeDialog::constructShapeXML() const { - if (m_shapeTree->topLevelItemCount() == 0 || m_details_map.isEmpty()) - return QString(); - - QString shapexml; - // First construct the XML that builds each separately defined shape - QMapIterator<BinaryTreeWidgetItem *, ShapeDetails *> detitr(m_details_map); - while (detitr.hasNext()) { - detitr.next(); - shapexml += detitr.value()->writeXML() + "\n"; - } - - QList<BinaryTreeWidgetItem *> postfix_exp; - // Build expression list - m_shapeTree->traverseInPostOrder(m_shapeTree->root(), postfix_exp); - - QListIterator<BinaryTreeWidgetItem *> expitr(postfix_exp); - QStringList inter_results; - while (expitr.hasNext()) { - BinaryTreeWidgetItem *item = expitr.next(); - if (m_details_map.contains(item)) { - ShapeDetails *shape = m_details_map.value(item); - QString shapeID = shape->getShapeID(); - if (shape->getComplementFlag()) { - shapeID = QString("#(") + shapeID + QString(")"); - } - inter_results.append(shapeID); - } else if (m_ops_map.contains(item)) { - int rcount = inter_results.count(); - if (inter_results.count() < 2) { - shapexml = ""; - break; - } - QString left = inter_results.at(rcount - 2); - QString right = inter_results.at(rcount - 1); - QString result = m_ops_map.value(item)->toString(left, right); - // Remove left result and replace the right with the result - inter_results.removeAt(rcount - 2); - // List has now been reduced in size by 1 - inter_results.replace(rcount - 2, result); - } else { - shapexml = ""; - break; - } - } - - // Something went wrong if the list hasn't compacted down to one entry - if (inter_results.size() != 1 || shapexml.isEmpty()) { - return QString(); - } - - shapexml += "<algebra val=\"" + inter_results.at(0) + "\" />"; - return shapexml; -} - -//================================================================= -//================================================================= - -//------------------------------------------------ -// BinaryTreeWidgetItem -//------------------------------------------------ -/** - * Default constructor - * @param type :: The type of the item - */ -BinaryTreeWidgetItem::BinaryTreeWidgetItem(int type) - : QTreeWidgetItem(type), m_left_index(0), m_right_index(1) {} - -/** - * Construct an item with a string list of column texts to add - * @param strings :: A list of strings to appear as the column texts - * @param type :: Qt or User defined - */ -BinaryTreeWidgetItem::BinaryTreeWidgetItem(const QStringList &strings, int type) - : QTreeWidgetItem(strings, type), m_left_index(0), m_right_index(1) {} - -/** - * Add a child item. This will only succeed if there are fewer than 2 children - * currently - */ -bool BinaryTreeWidgetItem::addChildItem(BinaryTreeWidgetItem *child) { - bool tooManyChildren = childCount() >= 2; - if (!tooManyChildren) - this->addChild(child); - - // Call sub-class function - return !tooManyChildren; -} - -/** - * A pointer to the left child. It can be NULL - */ -BinaryTreeWidgetItem *BinaryTreeWidgetItem::leftChild() const { - return dynamic_cast<BinaryTreeWidgetItem *>(this->child(m_left_index)); -} - -/** - * A pointer to the right child. It can be NULL - */ -BinaryTreeWidgetItem *BinaryTreeWidgetItem::rightChild() const { - return dynamic_cast<BinaryTreeWidgetItem *>(this->child(m_right_index)); -} - -//------------------------------------------------ -// BinaryTreeWidget -//------------------------------------------------ - -/** - * Default constructor - */ -BinaryTreeWidget::BinaryTreeWidget(QWidget *parent) : QTreeWidget(parent) { - ComboBoxDelegate *delegate = new ComboBoxDelegate(this); - setItemDelegate(delegate); -} - -/** - * Gets the root item for the tree - */ -BinaryTreeWidgetItem *BinaryTreeWidget::root() const { - return dynamic_cast<BinaryTreeWidgetItem *>(invisibleRootItem()->child(0)); -} - -/** - * A recursive function that builds an expression from the binary tree by - * traversing it in a post order fashion - * @param node :: The parent node - * @param expression :: The expression list to build - */ -void BinaryTreeWidget::traverseInPostOrder( - BinaryTreeWidgetItem *node, QList<BinaryTreeWidgetItem *> &expression) { - if (!node) - return; - // For the time begin just print the string that we get - if (node->leftChild()) - traverseInPostOrder(node->leftChild(), expression); - if (node->rightChild()) - traverseInPostOrder(node->rightChild(), expression); - - // Append this to the list - expression.append(node); -} - -#if QT_VERSION < 0x050000 -void BinaryTreeWidget::dataChanged(const QModelIndex &topLeft, - const QModelIndex & /*bottomRight*/) { -#else -void BinaryTreeWidget::dataChanged(const QModelIndex &topLeft, - const QModelIndex & /*bottomRight*/, - const QVector<int> & /*roles*/) { -#endif - emit treeDataChange( - dynamic_cast<BinaryTreeWidgetItem *>(itemFromIndex(topLeft)), - topLeft.data(Qt::UserRole).toInt()); -} - -//------------------------------------------------ -// ComboBoxDelegate -//------------------------------------------------ -/** - * Default constructor - */ -ComboBoxDelegate::ComboBoxDelegate(QWidget *parent) : QItemDelegate(parent) {} - -/** - * Create an editor for a tree item - * @param parent :: The parent widget - * @param index :: unused argument - * @param option :: unused argument - */ -QWidget *ComboBoxDelegate::createEditor(QWidget *parent, - const QStyleOptionViewItem & /*option*/, - const QModelIndex & /*index*/) const { - QComboBox *editor = new QComboBox(parent); - editor->addItem("intersection"); - editor->addItem("union"); - editor->addItem("difference"); - - return editor; -} - -/** - * Set the data for the editor when it has been created - * @param editor :: The editor in question - * @param index :: The model item in question - */ -void ComboBoxDelegate::setEditorData(QWidget *editor, - const QModelIndex &index) const { - int value = index.model()->data(index, Qt::UserRole).toInt(); - - QComboBox *combo_box = qobject_cast<QComboBox *>(editor); - combo_box->setCurrentIndex(value); -} - -/** - * Set the data for the model when editing is finished - * @param editor :: The editor in question - * @param model :: The model in question - * @param index :: The index for the model given - */ -void ComboBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, - const QModelIndex &index) const { - QComboBox *combo_box = static_cast<QComboBox *>(editor); - int boxitem = combo_box->currentIndex(); - QString value = combo_box->itemText(boxitem); - - model->setData(index, boxitem, Qt::UserRole); - model->setData(index, value, Qt::DisplayRole); -} - -/** - * Set the appropriate geometry for the widget - * @param editor :: The editor in question - * @param option :: The style option - * @param index :: The index for the model given - */ -void ComboBoxDelegate::updateEditorGeometry( - QWidget *editor, const QStyleOptionViewItem &option, - const QModelIndex & /*index*/) const { - editor->setGeometry(option.rect); -} -- GitLab