From c01c2b67b29c3a72d2ad698ed74763447b7374c0 Mon Sep 17 00:00:00 2001 From: Walter Van Herck <w.van.herck@fz-juelich.de> Date: Wed, 19 Feb 2014 14:09:19 +0100 Subject: [PATCH] Implemented deleting from context menu --- GUI/coregui/Models/LayerItem.cpp | 2 +- GUI/coregui/Models/MultiLayerItem.cpp | 1 + GUI/coregui/Models/ParameterizedItem.cpp | 13 +- GUI/coregui/Models/ParameterizedItem.h | 16 +-- GUI/coregui/Models/ParticleDecorationItem.cpp | 2 +- GUI/coregui/Models/SessionModel.cpp | 13 +- GUI/coregui/Views/SampleView.cpp | 116 ++++++++++++++---- GUI/coregui/Views/SampleView.h | 36 ++++-- GUI/coregui/Views/SampleViewComponents.cpp | 1 + GUI/coregui/utils/GUIHelpers.cpp | 98 +++++++++++++++ GUI/coregui/utils/GUIHelpers.h | 37 ++++++ 11 files changed, 281 insertions(+), 54 deletions(-) create mode 100644 GUI/coregui/utils/GUIHelpers.cpp create mode 100644 GUI/coregui/utils/GUIHelpers.h diff --git a/GUI/coregui/Models/LayerItem.cpp b/GUI/coregui/Models/LayerItem.cpp index 1a2372396b1..373fe206f04 100644 --- a/GUI/coregui/Models/LayerItem.cpp +++ b/GUI/coregui/Models/LayerItem.cpp @@ -19,7 +19,7 @@ LayerItem::LayerItem() : ParameterizedItem(QString("Layer")) { m_parameters[QString("Thickness")] = 0.0; - m_valid_parents.append(QString("MultiLayer")); + m_valid_children.append(QString("ParticleDecoration")); } LayerItem::~LayerItem() diff --git a/GUI/coregui/Models/MultiLayerItem.cpp b/GUI/coregui/Models/MultiLayerItem.cpp index 9ce4a44008a..4963c953a70 100644 --- a/GUI/coregui/Models/MultiLayerItem.cpp +++ b/GUI/coregui/Models/MultiLayerItem.cpp @@ -20,6 +20,7 @@ MultiLayerItem::MultiLayerItem() : ParameterizedItem(QString("MultiLayer")) { m_parameters[QString("Cross Correlation Length")] = 0.0; + m_valid_children.append(QString("Layer")); } MultiLayerItem::~MultiLayerItem() diff --git a/GUI/coregui/Models/ParameterizedItem.cpp b/GUI/coregui/Models/ParameterizedItem.cpp index 236da75bc77..fd71ec61d02 100644 --- a/GUI/coregui/Models/ParameterizedItem.cpp +++ b/GUI/coregui/Models/ParameterizedItem.cpp @@ -27,7 +27,7 @@ ParameterizedItem::~ParameterizedItem() { } -double ParameterizedItem::getParameterValue(QString name) +double ParameterizedItem::getParameterValue(const QString &name) const { if (!m_parameters.contains(name)) { throw Exceptions::RuntimeErrorException("ParameterizedItem::getParameterValue: " @@ -36,7 +36,7 @@ double ParameterizedItem::getParameterValue(QString name) return m_parameters[name]; } -void ParameterizedItem::setParameter(QString name, double value) +void ParameterizedItem::setParameter(const QString &name, double value) { if (!m_parameters.contains(name)) { throw Exceptions::RuntimeErrorException("ParameterizedItem::getParameterValue: " @@ -45,13 +45,8 @@ void ParameterizedItem::setParameter(QString name, double value) m_parameters[name] = value; } -bool ParameterizedItem::acceptsAsChild(ParameterizedItem *child) +bool ParameterizedItem::acceptsAsChild(const QString &child_name) const { - return child->isValidParent(this->text()); -} - -bool ParameterizedItem::isValidParent(QString parentName) -{ - return m_valid_parents.contains(parentName); + return m_valid_children.contains(child_name); } diff --git a/GUI/coregui/Models/ParameterizedItem.h b/GUI/coregui/Models/ParameterizedItem.h index 89d39e15994..563be4172bb 100644 --- a/GUI/coregui/Models/ParameterizedItem.h +++ b/GUI/coregui/Models/ParameterizedItem.h @@ -27,10 +27,10 @@ public: ~ParameterizedItem(); //! retrieves the parameter's value - double getParameterValue(QString name); + double getParameterValue(const QString &name) const; //! sets the parameter's value, if it exists - void setParameter(QString name, double value); + void setParameter(const QString &name, double value); //! retrieves the whole list of paramaters QMap<QString, double> &getParameters() { @@ -39,14 +39,16 @@ public: //! indicates if the passed item can be set as //! a child item - bool acceptsAsChild(ParameterizedItem *child); + bool acceptsAsChild(const QString &child_name) const; + + //! get list of acceptable child object names + QList<QString> getAcceptableChildren() const { + return m_valid_children; + } protected: - QList<QString> m_valid_parents; + QList<QString> m_valid_children; QMap<QString, double> m_parameters; private: - //! indicates if the item name, passed as argument - //! can be the current item's parent - bool isValidParent(QString parentName); }; diff --git a/GUI/coregui/Models/ParticleDecorationItem.cpp b/GUI/coregui/Models/ParticleDecorationItem.cpp index 2a103755b7e..387d7a6d406 100644 --- a/GUI/coregui/Models/ParticleDecorationItem.cpp +++ b/GUI/coregui/Models/ParticleDecorationItem.cpp @@ -18,7 +18,7 @@ ParticleDecorationItem::ParticleDecorationItem() : ParameterizedItem(QString("ParticleDecoration")) { - m_valid_parents.append(QString("Layer")); +// m_valid_children.append(QString("")); } diff --git a/GUI/coregui/Models/SessionModel.cpp b/GUI/coregui/Models/SessionModel.cpp index 3dcbdf8d4c0..b3b109bc923 100644 --- a/GUI/coregui/Models/SessionModel.cpp +++ b/GUI/coregui/Models/SessionModel.cpp @@ -48,21 +48,20 @@ void SessionModel::initialize() QStandardItem *SessionModel::createNewItem(QStandardItem *parent, QString model_type) { - ParameterizedItem *new_item = ItemFactory::createItem(model_type); - if (!new_item) { - return 0; - } - // Check if child is allowed to be added to parent if (parent!=invisibleRootItem()) { ParameterizedItem *p_par_parent = dynamic_cast<ParameterizedItem *>(parent); - if (!p_par_parent || !p_par_parent->acceptsAsChild(new_item)) { - delete new_item; + if (!p_par_parent || !p_par_parent->acceptsAsChild(model_type)) { return 0; } } + ParameterizedItem *new_item = ItemFactory::createItem(model_type); + if (!new_item) { + return 0; + } + parent->appendRow(new_item); return new_item; } diff --git a/GUI/coregui/Views/SampleView.cpp b/GUI/coregui/Views/SampleView.cpp index 591136ce970..5dd348be528 100644 --- a/GUI/coregui/Views/SampleView.cpp +++ b/GUI/coregui/Views/SampleView.cpp @@ -3,7 +3,7 @@ #include "SampleDesigner.h" #include "SampleToolBar.h" #include "MaterialBrowser.h" -#include "SessionModel.h" +#include "GUIHelpers.h" #include <QDockWidget> @@ -13,6 +13,7 @@ #include <QToolBar> #include <QAction> #include <QToolButton> +#include <QMenu> #include <iostream> @@ -28,7 +29,7 @@ SampleView::SampleView(QWidget *parent) , m_sampleDesigner(new SampleDesigner(this)) , m_toolBar(0) { - setObjectName(QLatin1String("SampleView")); + setObjectName(tr("SampleView")); setCentralWidget(m_sampleDesigner->getCentralWidget()); @@ -53,7 +54,11 @@ SampleView::SampleView(QWidget *parent) } resetToDefaultLayout(); - initActions(); + createActions(); + + + + connectSignals(); } @@ -76,38 +81,35 @@ void SampleView::initSubWindows() m_subWindows[WidgetBoxSubWindow] = SampleViewComponents::createWidgetBox(m_sampleDesigner, this); - SessionModel *session_model = new SessionModel(); + m_session = new SessionModel(); // Temporary for testing - QStandardItem *multilayer = session_model->insertNewItem("MultiLayer", QModelIndex()); - QStandardItem *layer = session_model->insertNewItem("Layer", multilayer->index()); - session_model->insertNewItem("ParticleDecoration", layer->index()); - session_model->insertNewItem("Layer", QModelIndex()); + QStandardItem *multilayer = m_session->insertNewItem("MultiLayer", QModelIndex()); + QStandardItem *layer = m_session->insertNewItem("Layer", multilayer->index()); + m_session->insertNewItem("ParticleDecoration", layer->index()); + m_session->insertNewItem("Layer", QModelIndex()); // END temporary - m_subWindows[SampleTreeView] = SampleViewComponents::createTreeView(session_model, this); + m_tree_view = SampleViewComponents::createTreeView(m_session, this); + m_subWindows[SampleTreeView] = m_tree_view; m_subWindows[PropertyEditorSubWindow] = SampleViewComponents::createPropertyEditor(m_sampleDesigner, this); SampleInfoStreamInterface *ae = SampleViewComponents::createInfoStream(this); ae->setWindowTitle(tr("Info Stream")); - ae->setObjectName(QLatin1String("InfoStream")); + ae->setObjectName(tr("InfoStream")); m_subWindows[InfoSubWindow] = ae; } - -void SampleView::initActions() +void SampleView::createActions() { - // toolBar should be initialized after MaterialBrowser - m_toolBar = new SampleToolBar(this); - connect(m_toolBar, SIGNAL(zoomOut()), m_sampleDesigner->getView(), SLOT(zoomOut())); - connect(m_toolBar, SIGNAL(zoomIn()), m_sampleDesigner->getView(), SLOT(zoomIn())); - connect(m_toolBar, SIGNAL(zoomFit()), m_sampleDesigner->getView(), SLOT(zoomFit())); - connect(m_toolBar, SIGNAL(clearAll()), m_sampleDesigner->getView(), SLOT(clearAll())); - connect(m_toolBar, SIGNAL(sceneToISample()), m_sampleDesigner, SLOT(sceneToISample())); + addAct = new QAction(tr("Add"), this); + addAct->setStatusTip(tr("Add a new object")); + connect(addAct, SIGNAL(triggered()), this, SLOT(addItem())); - addToolBar(m_toolBar); + delAct = new QAction(tr("Delete"), this); + delAct->setStatusTip(tr("Delete current object")); + connect(delAct, SIGNAL(triggered()), this, SLOT(deleteItem())); } - void SampleView::resetToDefaultLayout() { setTrackingEnabled(false); @@ -131,3 +133,75 @@ void SampleView::resetToDefaultLayout() setTrackingEnabled(true); } +void SampleView::addItem() +{ +} + +void SampleView::deleteItem() +{ + QModelIndex currentIndex = getTreeView()->currentIndex(); + if (currentIndex.isValid()) { + QStandardItem *item = getSessionModel()->itemFromIndex(currentIndex); + QString name = item->text(); + int rows = item->rowCount(); + QString message; + if (rows == 0) + message = tr("<p>Delete '%1'").arg(name); + else if (rows == 1) + message = tr("<p>Delete '%1' and its child (and " + "grandchildren etc.)").arg(name); + else if (rows > 1) + message = tr("<p>Delete '%1' and its %2 children (and " + "grandchildren etc.)").arg(name).arg(rows); + if (!GUIHelpers::okToDelete(this, tr("Delete"), message)) return; + getSessionModel()->removeRow(currentIndex.row(), currentIndex.parent()); + setDirty(); + updateUi(); + } +} + +void SampleView::showContextMenu(const QPoint &pnt) +{ + QList<QAction *> actions; + if (getTreeView()->indexAt(pnt).isValid()) { + actions.append(delAct); + } + if (actions.count() > 0) { + QMenu::exec(actions, getTreeView()->mapToGlobal(pnt)); + } +} + +void SampleView::updateUi() +{ +} + + +void SampleView::connectSignals() +{ + // toolBar should be initialized after MaterialBrowser + m_toolBar = new SampleToolBar(this); + connect(m_toolBar, SIGNAL(zoomOut()), m_sampleDesigner->getView(), SLOT(zoomOut())); + connect(m_toolBar, SIGNAL(zoomIn()), m_sampleDesigner->getView(), SLOT(zoomIn())); + connect(m_toolBar, SIGNAL(zoomFit()), m_sampleDesigner->getView(), SLOT(zoomFit())); + connect(m_toolBar, SIGNAL(clearAll()), m_sampleDesigner->getView(), SLOT(clearAll())); + connect(m_toolBar, SIGNAL(sceneToISample()), m_sampleDesigner, SLOT(sceneToISample())); + + // connect context menu for tree view + QTreeView *tree_view = static_cast<QTreeView *>(m_subWindows[SampleTreeView]); + connect(tree_view, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(showContextMenu(const QPoint &))); + + addToolBar(m_toolBar); +} + +SessionModel *SampleView::getSessionModel() +{ + return m_session; +} + +QTreeView *SampleView::getTreeView() +{ + return m_tree_view; +} + + diff --git a/GUI/coregui/Views/SampleView.h b/GUI/coregui/Views/SampleView.h index 20487d1caf7..70500a309d9 100644 --- a/GUI/coregui/Views/SampleView.h +++ b/GUI/coregui/Views/SampleView.h @@ -6,6 +6,9 @@ #include <QMainWindow> #include <QDockWidget> #include <QTreeView> +#include <QAction> + +#include "SessionModel.h" class SampleDesignerInterface; @@ -22,10 +25,10 @@ public: enum SubWindows { - WidgetBoxSubWindow, - SampleTreeView, - PropertyEditorSubWindow, - InfoSubWindow, + WidgetBoxSubWindow, // drag & drop items + SampleTreeView, // a tree view + PropertyEditorSubWindow, // property editor + InfoSubWindow, // status/info display NumberOfSubWindows }; @@ -35,17 +38,34 @@ public: public slots: void resetToDefaultLayout(); + void addItem(); + void deleteItem(); // void materialEditorCall(); +protected slots: + void showContextMenu(const QPoint &pnt); + void setDirty(bool dirty=true) { setWindowModified(dirty); } + void updateUi(); + private: void initSubWindows(); - void initActions(); + void createActions(); + void connectSignals(); + + SessionModel *getSessionModel(); + QTreeView *getTreeView(); - MaterialBrowser *m_materialBrowser; - SampleDesigner *m_sampleDesigner; - SampleToolBar *m_toolBar; + MaterialBrowser *m_materialBrowser; // material editor + SampleDesigner *m_sampleDesigner; // main sample view + SampleToolBar *m_toolBar; // toolbar QWidget *m_subWindows[NumberOfSubWindows]; QDockWidget *m_dockWidgets[NumberOfSubWindows]; + + QAction *addAct; + QAction *delAct; + + SessionModel *m_session; + QTreeView *m_tree_view; }; diff --git a/GUI/coregui/Views/SampleViewComponents.cpp b/GUI/coregui/Views/SampleViewComponents.cpp index e7dcbf2fb16..0c7e0481e1e 100644 --- a/GUI/coregui/Views/SampleViewComponents.cpp +++ b/GUI/coregui/Views/SampleViewComponents.cpp @@ -46,6 +46,7 @@ QTreeView *SampleViewComponents::createTreeView(SessionModel *session_model, QWi tree_view->setAllColumnsShowFocus(true); tree_view->setWindowTitle(QString("Object Tree View")); tree_view->setObjectName(QString("ObjectTree")); + tree_view->setContextMenuPolicy(Qt::CustomContextMenu); return tree_view; } diff --git a/GUI/coregui/utils/GUIHelpers.cpp b/GUI/coregui/utils/GUIHelpers.cpp new file mode 100644 index 00000000000..55d06bb4101 --- /dev/null +++ b/GUI/coregui/utils/GUIHelpers.cpp @@ -0,0 +1,98 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file utils/GUIHelpers.cpp +//! @brief Implements GUI helper functions. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#include "GUIHelpers.h" + +#include <QApplication> +#include <QMessageBox> +#include <QPushButton> + +namespace GUIHelpers { + +void information(QWidget *parent, const QString &title, const QString &text, const QString &detailedText) +{ + QScopedPointer<QMessageBox> messageBox(new QMessageBox(parent)); + if (parent) + messageBox->setWindowModality(Qt::WindowModal); + messageBox->setWindowTitle(QString("%1 - %2") + .arg(QApplication::applicationName()).arg(title)); + messageBox->setText(text); + if (!detailedText.isEmpty()) + messageBox->setInformativeText(detailedText); + messageBox->setIcon(QMessageBox::Information); + messageBox->addButton(QMessageBox::Ok); + messageBox->exec(); +} + + +void warning(QWidget *parent, const QString &title, const QString &text, const QString &detailedText) +{ + QScopedPointer<QMessageBox> messageBox(new QMessageBox(parent)); + if (parent) + messageBox->setWindowModality(Qt::WindowModal); + messageBox->setWindowTitle(QString("%1 - %2") + .arg(QApplication::applicationName()).arg(title)); + messageBox->setText(text); + if (!detailedText.isEmpty()) + messageBox->setInformativeText(detailedText); + messageBox->setIcon(QMessageBox::Warning); + messageBox->addButton(QMessageBox::Ok); + messageBox->exec(); +} + + +bool question(QWidget *parent, const QString &title, const QString &text, const QString &detailedText, const QString &yesText, const QString &noText) +{ + QScopedPointer<QMessageBox> messageBox(new QMessageBox(parent)); + if (parent) + messageBox->setWindowModality(Qt::WindowModal); + messageBox->setWindowTitle(QString("%1 - %2") + .arg(QApplication::applicationName()).arg(title)); + messageBox->setText(text); + if (!detailedText.isEmpty()) + messageBox->setInformativeText(detailedText); + messageBox->setIcon(QMessageBox::Question); + QAbstractButton *yesButton = messageBox->addButton(yesText, + QMessageBox::AcceptRole); + messageBox->addButton(noText, QMessageBox::RejectRole); + messageBox->setDefaultButton( + qobject_cast<QPushButton*>(yesButton)); + messageBox->exec(); + return messageBox->clickedButton() == yesButton; +} + + +bool okToDelete(QWidget *parent, const QString &title, const QString &text, const QString &detailedText) +{ + QScopedPointer<QMessageBox> messageBox(new QMessageBox(parent)); + if (parent) + messageBox->setWindowModality(Qt::WindowModal); + messageBox->setIcon(QMessageBox::Question); + messageBox->setWindowTitle(QString("%1 - %2") + .arg(QApplication::applicationName()).arg(title)); + messageBox->setText(text); + if (!detailedText.isEmpty()) + messageBox->setInformativeText(detailedText); + QAbstractButton *deleteButton = messageBox->addButton( + QObject::tr("&Delete"), QMessageBox::AcceptRole); + messageBox->addButton(QObject::tr("Do &Not Delete"), + QMessageBox::RejectRole); + messageBox->setDefaultButton( + qobject_cast<QPushButton*>(deleteButton)); + messageBox->exec(); + return messageBox->clickedButton() == deleteButton; +} + +} // namespace GUIHelpers diff --git a/GUI/coregui/utils/GUIHelpers.h b/GUI/coregui/utils/GUIHelpers.h new file mode 100644 index 00000000000..2ed035c90df --- /dev/null +++ b/GUI/coregui/utils/GUIHelpers.h @@ -0,0 +1,37 @@ +// ************************************************************************** // +// +// BornAgain: simulate and fit scattering at grazing incidence +// +//! @file utils/GUIHelpers.h +//! @brief Defines GUI helper functions. +//! +//! @homepage http://apps.jcns.fz-juelich.de/BornAgain +//! @license GNU General Public License v3 or higher (see COPYING) +//! @copyright Forschungszentrum Jülich GmbH 2013 +//! @authors Scientific Computing Group at MLZ Garching +//! @authors C. Durniak, G. Pospelov, W. Van Herck, J. Wuttke +// +// ************************************************************************** // + +#ifndef GUIHELPERS_H +#define GUIHELPERS_H + +#include <QWidget> +#include <QString> + +namespace GUIHelpers +{ +void information(QWidget *parent, const QString &title, + const QString &text, const QString &detailedText=QString()); +void warning(QWidget *parent, const QString &title, + const QString &text, const QString &detailedText=QString()); +bool question(QWidget *parent, const QString &title, + const QString &text, const QString &detailedText=QString(), + const QString &yesText=QObject::tr("&Yes"), + const QString &noText=QObject::tr("&No")); +bool okToDelete(QWidget *parent, const QString &title, + const QString &text, const QString &detailedText=QString()); +}; + +#endif // GUIHELPERS_H + -- GitLab