Salome HOME
Improve multi-selector control to provide "Delete" key processing.
authornds <nds@opencascade.com>
Wed, 13 Jan 2016 05:36:42 +0000 (08:36 +0300)
committerdbv <dbv@opencascade.com>
Tue, 16 Feb 2016 14:03:02 +0000 (17:03 +0300)
Shortcut can not be used for it because there is a conflict in Qt which one should be performed.
So, OperationMgr processes it from property panel and application on the whole(qApp->installEventFilter(this)).

src/ModuleBase/ModuleBase_ModelWidget.cpp
src/ModuleBase/ModuleBase_ModelWidget.h
src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp
src/ModuleBase/ModuleBase_WidgetMultiSelector.h
src/PartSet/PartSet_OperationPrs.cpp
src/XGUI/XGUI_ContextMenuMgr.cpp
src/XGUI/XGUI_Displayer.cpp
src/XGUI/XGUI_OperationMgr.cpp
src/XGUI/XGUI_OperationMgr.h

index 86fe765daafc4e328d73f14677ec27471f799be4..939505967552215db2fd1982170c7efe27772e34 100644 (file)
@@ -279,6 +279,11 @@ bool ModuleBase_ModelWidget::processEnter()
   return false;
 }
 
+bool ModuleBase_ModelWidget::processDelete()
+{
+  return false;
+}
+
 bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
 {
   QWidget* aWidget = qobject_cast<QWidget*>(theObject);
index 9f7c999806a9882eefe0180a62e340ff42bdf275..79e4b1e1737a7b6831c881bdebbd3312ae3ef432 100644 (file)
@@ -183,9 +183,12 @@ Q_OBJECT
   /// \return Current Editing mode
   bool isEditingMode() const { return myIsEditing; }
 
-  /// Returns true if the event is processed.
+  /// Returns true if the event is processed. The default implementation is empty, returns false.
   virtual bool processEnter();
 
+  /// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processDelete();
+
   /// Sends Update and Redisplay for the given object
   /// \param theObj is updating object
   static void updateObject(ObjectPtr theObj);
index 714e4ef7f389c06ed7f6e55306d97cb619d0db98..6fa8eae78e5db813aebb9ae109790c2c3058f0b1 100755 (executable)
@@ -148,7 +148,6 @@ ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParen
   myListControl->addAction(myCopyAction);
 
   myDeleteAction = new QAction(QIcon(":pictures/delete.png"), tr("Delete"), this);
-  myDeleteAction->setShortcut(QKeySequence::Delete);
   myDeleteAction->setEnabled(false);
   connect(myDeleteAction, SIGNAL(triggered(bool)), SLOT(onDeleteItem()));
   myListControl->addAction(myDeleteAction);
@@ -329,6 +328,40 @@ bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_Vie
   return aValid;
 }
 
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::processDelete()
+{
+  // find attribute indices to delete
+  std::set<int> anAttributeIds;
+  getSelectedAttributeIndices(anAttributeIds);
+
+  // refill attribute by the items which indices are not in the list of ids
+  bool aDone = false;
+  AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
+  if (aSelectionListAttr.get()) {
+    aDone = !anAttributeIds.empty();
+    aSelectionListAttr->remove(anAttributeIds);
+  }
+  else {
+    AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID());
+    if (aRefListAttr.get()) {
+      aDone = !anAttributeIds.empty();
+      aRefListAttr->remove(anAttributeIds);
+    }
+  }
+  if (aDone) {
+    // update object is necessary to flush update signal. It leads to objects references map update
+    // and the operation presentation will not contain deleted items visualized as parameters of
+    // the feature.
+    updateObject(myFeature);
+
+    restoreValue();
+    myWorkshop->setSelected(getAttributeSelection());
+    myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeAllObjects, true);
+  }
+  return true; // if the delete should be processed outsize, the method should return isDone
+}
+
 //********************************************************************
 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
 {
@@ -475,30 +508,7 @@ void ModuleBase_WidgetMultiSelector::onCopyItem()
 //********************************************************************
 void ModuleBase_WidgetMultiSelector::onDeleteItem()
 {
-  // find attribute indices to delete
-  std::set<int> anAttributeIds;
-  getSelectedAttributeIndices(anAttributeIds);
-
-  // refill attribute by the items which indices are not in the list of ids
-  bool aDone = false;
-  AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID());
-  if (aSelectionListAttr.get()) {
-    aDone = !anAttributeIds.empty();
-    aSelectionListAttr->remove(anAttributeIds);
-  }
-  else {
-    AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID());
-    if (aRefListAttr.get()) {
-      aDone = !anAttributeIds.empty();
-      aRefListAttr->remove(anAttributeIds);
-    }
-  }
-  if (aDone) {
-    restoreValue();
-    myWorkshop->setSelected(getAttributeSelection());
-
-    myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeAllObjects, true);
-  }
+  processDelete();
 }
 
 //********************************************************************
index bebc59c91f0c40b8f878d8552cb626c85fda379f..591d842ad91156746ed3d07174e9a8891e69eb08 100755 (executable)
@@ -81,7 +81,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Widge
   /// \return a boolean value
   virtual bool isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs);
 
- public slots:
+  /// Returns true if the event is processed. The default implementation is empty, returns false.
+  virtual bool processDelete();
+
+public slots:
   /// Slot is called on selection type changed
   void onSelectionTypeChanged();
 
index 9b41b2effbdbaa48d2552f175bbc6c0bf0642d23..cbf29b38bb4f107303a24716daa4da3f32a7c489 100755 (executable)
@@ -13,6 +13,8 @@
 
 #include "ModuleBase_Tools.h"
 #include "ModuleBase_IModule.h"
+#include <ModuleBase_IPropertyPanel.h>
+#include <ModuleBase_ModelWidget.h>
 
 #include <ModelAPI_Result.h>
 #include <ModelAPI_Attribute.h>
@@ -79,8 +81,6 @@ bool PartSet_OperationPrs::hasShapes()
   return !myFeatureShapes.empty() || !myFeatureResults.empty();
 }
 
-#include <ModuleBase_IPropertyPanel.h>
-#include <ModuleBase_ModelWidget.h>
 void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
                                    const Handle(Prs3d_Presentation)& thePresentation, 
                                    const Standard_Integer theMode)
index 940901ce4be41b00ec8d30af48f49f3dcf884e64..ea453bb49f8e68805b9af437822054d6283c33e9 100644 (file)
@@ -62,7 +62,6 @@ void XGUI_ContextMenuMgr::createActions()
   aDesktop->addAction(aAction);
 
   addAction("DELETE_CMD", aAction);
-  aAction->setShortcut(Qt::Key_Delete);
   aAction->setShortcutContext(Qt::ApplicationShortcut);
 
   aAction = new QAction(QIcon(":pictures/rename_edit.png"), tr("Rename"), this);
index 2c24b774aac73afaf0a3bd47a1ae06e540e3084c..29b8b997bcf4b7c79b12c09b234f05de24c26ac3 100644 (file)
@@ -501,8 +501,8 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrs>& theValues,
   if (aContext.IsNull())
     return;
   if (aContext->HasOpenedContext()) {
-    aContext->UnhilightSelected();
-    aContext->ClearSelected();
+    aContext->UnhilightSelected(false);
+    aContext->ClearSelected(false);
     foreach (ModuleBase_ViewerPrs aPrs, theValues) {
       const TopoDS_Shape& aShape = aPrs.shape();
       if (!aShape.IsNull()) {
@@ -525,8 +525,8 @@ void XGUI_Displayer::setSelected(const  QList<ModuleBase_ViewerPrs>& theValues,
       }
     }
   } else {
-    aContext->UnhilightCurrents();
-    aContext->ClearCurrents();
+    aContext->UnhilightCurrents(false);
+    aContext->ClearCurrents(false);
     foreach (ModuleBase_ViewerPrs aPrs, theValues) {
       ObjectPtr anObject = aPrs.object();
       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(anObject);
index 15f90b947906cb81852dba24da26aa4b28173696..dff53bd91f513595f4a144976506108bd3d3d961 100644 (file)
@@ -35,6 +35,10 @@ XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,
                                      ModuleBase_IWorkshop* theWorkshop)
 : QObject(theParent), myWorkshop(theWorkshop)
 {
+  /// we need to install filter to the application in order to react to 'Delete' key button
+  /// this key can not be a short cut for a corresponded action because we need to set
+  /// the actions priority
+  qApp->installEventFilter(this);
 }
 
 XGUI_OperationMgr::~XGUI_OperationMgr()
@@ -108,13 +112,17 @@ ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation*
 
 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
 {
+  bool isAccepted = false;
   if (theEvent->type() == QEvent::KeyRelease) {
     QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
     if(aKeyEvent) {
-      return onKeyReleased(aKeyEvent);
+      isAccepted = onKeyReleased(aKeyEvent);
     }
   }
-  return QObject::eventFilter(theObject, theEvent);
+  if (!isAccepted)
+    isAccepted = QObject::eventFilter(theObject, theEvent);
+
+  return isAccepted;
 }
 
 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
@@ -499,11 +507,9 @@ void XGUI_OperationMgr::onOperationStopped()
 
 bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
 {
-  QObject* aSender = sender();
-
   // Let the manager decide what to do with the given key combination.
   ModuleBase_Operation* anOperation = currentOperation();
-  bool isAccepted = true;
+  bool isAccepted = false;
   switch (theEvent->key()) {
     case Qt::Key_Return:
     case Qt::Key_Enter: {
@@ -525,7 +531,10 @@ bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
         }
       }
     }
-
+    case Qt::Key_Delete: {
+      isAccepted = onProcessDelete();
+    }
+    break;
     break;
     default:
       isAccepted = false;
@@ -539,26 +548,32 @@ bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
 
 bool XGUI_OperationMgr::onProcessEnter()
 {
-  bool isAccepted = true;
+  bool isAccepted = false;
   ModuleBase_Operation* aOperation = currentOperation();
   ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
-  ModuleBase_ModelWidget* aActiveWgt = aPanel->activeWidget();
+  ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
   bool isAborted = false;
-  if (!aActiveWgt) {
+  if (!anActiveWgt) {
     QWidget* aFocusWidget = aPanel->focusWidget();
     QToolButton* aCancelBtn = aPanel->findChild<QToolButton*>(PROP_PANEL_CANCEL);
     if (aFocusWidget && aCancelBtn && aFocusWidget == aCancelBtn) {
       abortOperation(aOperation);
+      isAccepted = true;
       isAborted = true;
     }
   }
   if (!isAborted) {
-    if (!aActiveWgt || !aActiveWgt->processEnter()) {
-      if (!myWorkshop->module()->processEnter(aActiveWgt ? aActiveWgt->attributeID() : "")) {
+    isAccepted = anActiveWgt && anActiveWgt->processEnter();
+    if (!isAccepted) {
+      isAccepted = myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
+      if (!isAccepted) {
+        /// functionality is similar to Apply click
         ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
         if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {
+          // key released is emitted to apply the current value to the model if it was modified in PP
           emit keyEnterReleased();
           commitOperation();
+          isAccepted = true;
         }
         else
           isAccepted = false;
@@ -568,6 +583,26 @@ bool XGUI_OperationMgr::onProcessEnter()
   return isAccepted;
 }
 
+bool XGUI_OperationMgr::onProcessDelete()
+{
+  bool isAccepted = false;
+  ModuleBase_Operation* aOperation = currentOperation();
+  ModuleBase_ModelWidget* anActiveWgt = 0;
+  if (aOperation) {
+    ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
+    if (aPanel)
+      anActiveWgt = aPanel->activeWidget();
+  }
+  if (anActiveWgt)
+    isAccepted = anActiveWgt->processDelete();
+  if (!isAccepted) {
+    workshop()->deleteObjects();
+    isAccepted = true;
+  }
+
+  return isAccepted;
+}
+
 XGUI_Workshop* XGUI_OperationMgr::workshop() const
 {
   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
index e7e715128b6e7e07e20876cd28a589875a3ad2f9..b87501c4b8066d4a87c64619b1a95e463bb9d92a 100755 (executable)
@@ -162,12 +162,17 @@ protected: // TEMPORARY
   /// \param theEvent the mouse event
   bool onKeyReleased(QKeyEvent* theEvent);
 
+ protected slots:
   /// The functionaly, that should be done by enter click
-  /// Fistly the active widget processes it, then module. If no one do not
+  /// Fistly the active widget processes it, then module. If no one does not
   /// process it, the current operation is committed
   bool onProcessEnter();
 
-  protected slots:
+  /// The functionaly, that should be done by delete click
+  /// Fistly the active widget processes it, then workshop. If no one does not
+  /// process it, do nothing
+  bool onProcessDelete();
+
   /// Slot that is called by an operation stop. Removes the stopped operation form the stack.
   /// If there is a suspended operation, restart it.
   void onOperationStopped();