Salome HOME
e46877afa762f5a37717520d80b0f871cd5d812b
[modules/shaper.git] / src / XGUI / XGUI_OperationMgr.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        XGUI_OperationMgr.cpp
4 // Created:     20 Apr 2014
5 // Author:      Natalia ERMOLAEVA
6
7 #include "XGUI_OperationMgr.h"
8 #include "XGUI_ModuleConnector.h"
9 #include "XGUI_Workshop.h"
10 #include "XGUI_ErrorMgr.h"
11
12 #include <ModuleBase_IPropertyPanel.h>
13 #include <ModuleBase_ModelWidget.h>
14 #include "ModuleBase_Operation.h"
15 #include "ModuleBase_IWorkshop.h"
16 #include "ModuleBase_IModule.h"
17 #include <ModuleBase_IViewer.h>
18 #include "ModuleBase_OperationDescription.h"
19 #include "ModuleBase_OperationFeature.h"
20 #include "ModuleBase_Tools.h"
21
22 #include "ModelAPI_CompositeFeature.h"
23 #include "ModelAPI_Session.h"
24
25 #include <XGUI_PropertyPanel.h>
26 #include <QToolButton>
27
28 #include <QMessageBox>
29 #include <QApplication>
30 #include <QKeyEvent>
31
32 //#define DEBUG_CURRENT_FEATURE
33
34 /// Processes "Delete" key event of application. This key is used by several application actions.
35 /// There is a logical order of the actions processing. So the key can not be set for actions
36 /// as a shortcut. The class listens the key event and call operation manager processor.
37 class XGUI_ShortCutListener : public QObject
38 {
39 public:
40   /// Constructor
41   /// \param theParent the parent to be deleted when the parent is deleted
42   /// \param theOperationMgr the class to perform deletion
43   XGUI_ShortCutListener(QObject* theParent, XGUI_OperationMgr* theOperationMgr)
44     : QObject(theParent), myOperationMgr(theOperationMgr)
45   {
46     qApp->installEventFilter(this);
47   }
48   ~XGUI_ShortCutListener() {}
49
50   /// Redefinition of virtual function to process Delete key release
51   virtual bool eventFilter(QObject *theObject, QEvent *theEvent)
52   {
53     bool isAccepted = false;
54     if (theEvent->type() == QEvent::KeyRelease) {
55       QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
56       if(aKeyEvent) {
57         switch (aKeyEvent->key()) {
58           case Qt::Key_Delete: {
59             isAccepted = myOperationMgr->onProcessDelete();
60           }
61         }
62       }
63     }
64     if (!isAccepted)
65       isAccepted = QObject::eventFilter(theObject, theEvent);
66     return isAccepted;
67   }
68
69 private:
70   XGUI_OperationMgr* myOperationMgr; /// processor for key event
71 };
72
73 XGUI_OperationMgr::XGUI_OperationMgr(QObject* theParent,
74                                      ModuleBase_IWorkshop* theWorkshop)
75 : QObject(theParent), myWorkshop(theWorkshop)
76 {
77   /// we need to install filter to the application in order to react to 'Delete' key button
78   /// this key can not be a short cut for a corresponded action because we need to set
79   /// the actions priority
80   XGUI_ShortCutListener* aShortCutListener = new XGUI_ShortCutListener(theParent, this);
81 }
82
83 XGUI_OperationMgr::~XGUI_OperationMgr()
84 {
85 }
86
87 ModuleBase_Operation* XGUI_OperationMgr::currentOperation() const
88 {
89   return myOperations.count() > 0 ? myOperations.last() : 0;
90 }
91
92 bool XGUI_OperationMgr::isCurrentOperation(ModuleBase_Operation* theOperation)
93 {
94   if(!hasOperation())
95     return false;
96   return currentOperation() == theOperation;
97 }
98
99 bool XGUI_OperationMgr::hasOperation() const
100 {
101   return !myOperations.isEmpty() && (myOperations.last() != NULL);
102 }
103
104 bool XGUI_OperationMgr::hasOperation(const QString& theId) const
105 {
106   foreach(ModuleBase_Operation* aOp, myOperations) {
107     if (aOp->id() == theId)
108       return true;
109   }
110   return false;
111 }
112
113 ModuleBase_Operation* XGUI_OperationMgr::findOperation(const QString& theId) const
114 {
115   foreach(ModuleBase_Operation* aOp, myOperations) {
116     if (aOp->id() == theId)
117       return aOp;
118   }
119   return 0;
120 }
121
122
123 int XGUI_OperationMgr::operationsCount() const
124 {
125   return myOperations.count();
126 }
127
128 QStringList XGUI_OperationMgr::operationList() const
129 {
130   QStringList result;
131   foreach(ModuleBase_Operation* eachOperation, myOperations) {
132     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(eachOperation);
133     if (aFOperation) {
134       FeaturePtr aFeature = aFOperation->feature();
135       if(aFeature) {
136         result << QString::fromStdString(aFeature->getKind());
137       }
138     }
139   }
140   return result;
141 }
142
143 ModuleBase_Operation* XGUI_OperationMgr::previousOperation(ModuleBase_Operation* theOperation) const
144 {
145   int idx = myOperations.lastIndexOf(theOperation);
146   if(idx == -1 || idx == 0) {
147     return NULL;
148   }
149   return myOperations.at(idx - 1);
150 }
151
152 bool XGUI_OperationMgr::eventFilter(QObject *theObject, QEvent *theEvent)
153 {
154   bool isAccepted = false;
155   if (theEvent->type() == QEvent::KeyRelease) {
156     QKeyEvent* aKeyEvent = dynamic_cast<QKeyEvent*>(theEvent);
157     if(aKeyEvent) {
158       isAccepted = onKeyReleased(aKeyEvent);
159     }
160   }
161   if (!isAccepted)
162     isAccepted = QObject::eventFilter(theObject, theEvent);
163
164   return isAccepted;
165 }
166
167 bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
168 {
169   if (hasOperation())
170     currentOperation()->postpone();
171   myOperations.append(theOperation);
172
173   connect(theOperation, SIGNAL(beforeStarted()), SLOT(onBeforeOperationStarted()));
174   connect(theOperation, SIGNAL(beforeAborted()), SLOT(onBeforeOperationAborted()));
175   connect(theOperation, SIGNAL(beforeCommitted()), SLOT(onBeforeOperationCommitted()));
176
177   connect(theOperation, SIGNAL(started()), SLOT(onOperationStarted()));
178   connect(theOperation, SIGNAL(aborted()), SLOT(onOperationAborted()));
179   connect(theOperation, SIGNAL(committed()), SLOT(onOperationCommitted()));
180
181   connect(theOperation, SIGNAL(stopped()), SLOT(onOperationStopped()));
182   connect(theOperation, SIGNAL(resumed()), SLOT(onOperationResumed()));
183   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
184                                                                         (theOperation);
185   if (aFOperation)
186     connect(aFOperation, SIGNAL(activatedByPreselection()),
187             SIGNAL(operationActivatedByPreselection()));
188
189   bool isStarted = theOperation->start();
190   if (isStarted)
191     onValidateOperation();
192   return isStarted;
193 }
194
195 bool XGUI_OperationMgr::abortAllOperations()
196 {
197   bool aResult = true;
198   if(!hasOperation())
199     return aResult;
200
201   if (operationsCount() == 1) {
202     ModuleBase_Operation* aCurrentOperation = currentOperation();
203     if (canStopOperation(aCurrentOperation)) {
204       abortOperation(aCurrentOperation);
205     }
206     else
207       aResult = false;
208   }
209   else {
210     aResult = QMessageBox::question(qApp->activeWindow(),
211                                     tr("Abort operation"),
212                                     tr("All active operations will be aborted."),
213                                     QMessageBox::Ok | QMessageBox::Cancel,
214                                     QMessageBox::Cancel) == QMessageBox::Ok;
215     while(aResult && hasOperation()) {
216       abortOperation(currentOperation());
217     }
218   }
219   return aResult;
220 }
221
222 bool XGUI_OperationMgr::commitAllOperations()
223 {
224   bool isCompositeCommitted = false;
225   while (hasOperation()) {
226     ModuleBase_Operation* anOperation = currentOperation();
227     if (workshop()->errorMgr()->isApplyEnabled()) {
228       onCommitOperation();
229     } else {
230       abortOperation(anOperation);
231     }
232     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
233                                                                             (anOperation);
234     if (aFOperation) {
235       FeaturePtr aFeature = aFOperation->feature();
236       CompositeFeaturePtr aComposite = 
237           std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aFeature);
238       isCompositeCommitted = aComposite.get();
239       if (isCompositeCommitted)
240         break;
241     }
242   }
243   return true;
244 }
245
246 void XGUI_OperationMgr::onValidateOperation()
247 {
248   if (!hasOperation())
249     return;
250   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
251                                                                           (currentOperation());
252   if(aFOperation && aFOperation->feature().get())
253     workshop()->errorMgr()->updateActions(aFOperation->feature());
254 }
255
256 void XGUI_OperationMgr::updateApplyOfOperations(ModuleBase_Operation* theOperation)
257 {
258   XGUI_ErrorMgr* anErrorMgr = workshop()->errorMgr();
259   if (theOperation) {
260     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(theOperation);
261     if (aFOperation)
262       anErrorMgr->updateAcceptAllAction(aFOperation->feature());
263   }
264   else {
265     foreach(ModuleBase_Operation* anOperation, myOperations) {
266       if (anOperation)
267         updateApplyOfOperations(anOperation);
268     }
269   }
270 }
271
272 bool XGUI_OperationMgr::canStopOperation(ModuleBase_Operation* theOperation)
273 {
274   //in case of nested (sketch) operation no confirmation needed
275   if (isGrantedOperation(theOperation->id()))
276     return true;
277   if (theOperation && theOperation->isModified()) {
278     QString aMessage = tr("%1 operation will be aborted.").arg(theOperation->id());
279     int anAnswer = QMessageBox::question(qApp->activeWindow(),
280                                          tr("Abort operation"),
281                                          aMessage,
282                                          QMessageBox::Ok | QMessageBox::Cancel,
283                                          QMessageBox::Cancel);
284     return anAnswer == QMessageBox::Ok;
285   }
286   return true;
287 }
288
289 bool XGUI_OperationMgr::commitOperation()
290 {
291   if (hasOperation() && currentOperation()->isValid()) {
292     onCommitOperation();
293     return true;
294   }
295   return false;
296 }
297
298 void XGUI_OperationMgr::resumeOperation(ModuleBase_Operation* theOperation)
299 {
300   theOperation->resume();
301 }
302
303 bool XGUI_OperationMgr::isGrantedOperation(const QString& theId)
304 {
305   bool isGranted = false;
306
307   QListIterator<ModuleBase_Operation*> anIt(myOperations);
308   anIt.toBack();
309   ModuleBase_Operation* aPreviousOperation = 0;
310   while (anIt.hasPrevious() && !isGranted) {
311     ModuleBase_Operation* anOp = anIt.previous();
312     if (anOp)
313       isGranted = anOp->isGranted(theId);
314   }
315   return isGranted;
316 }
317
318 void XGUI_OperationMgr::setCurrentFeature(const FeaturePtr& theFeature)
319 {
320   SessionPtr aMgr = ModelAPI_Session::get();
321   DocumentPtr aDoc = aMgr->activeDocument();
322   bool aIsOp = aMgr->isOperation();
323   if (!aIsOp)
324     aMgr->startOperation();
325   aDoc->setCurrentFeature(theFeature, false);
326   if (!aIsOp)
327     aMgr->finishOperation();
328 }
329
330 bool XGUI_OperationMgr::canStartOperation(const QString& theId)
331 {
332   bool aCanStart = true;
333   ModuleBase_Operation* aCurrentOp = currentOperation();
334   if (aCurrentOp) {
335     bool aGranted = aCurrentOp->isGranted(theId);
336     // the started operation is granted for the current one,
337     // e.g. current - Sketch, started - Line
338     if (aGranted) {
339       aCanStart = true;
340     }
341     else {
342       if (!isGrantedOperation(theId)) {
343         // the operation is not granted in the current list of operations
344         // e.g. Edit Parameter when Sketch, Line in Sketch is active.
345         aCanStart = abortAllOperations();
346       }
347       else if (canStopOperation(aCurrentOp)) {
348         // the started operation is granted in the parrent operation,
349         // e.g. current - Line in Sketch, started Circle 
350         if (workshop()->errorMgr()->isApplyEnabled() && aCurrentOp->isModified())
351           aCurrentOp->commit();
352         else
353           abortOperation(aCurrentOp);
354       } else {
355         aCanStart = false;
356       }
357     }
358   }
359   return aCanStart;
360 }
361
362 void XGUI_OperationMgr::abortOperation(ModuleBase_Operation* theOperation)
363 {
364   ModuleBase_Operation* aCurrentOperation = currentOperation();
365   if (theOperation == aCurrentOperation)
366     theOperation->abort();
367   else {
368     // it is possible to trigger upper operation(e.g. sketch, current is sketch line)
369     // all operation from the current to triggered should also be aborted
370     // operations over the parameter one are not aborted(e.g. extrusion cut, sketch abort)
371     while(hasOperation()) {
372       ModuleBase_Operation* aCurrentOperation = currentOperation();
373       aCurrentOperation->abort();
374       if(theOperation == aCurrentOperation)
375         break;
376     }
377   }
378 }
379
380 void XGUI_OperationMgr::onCommitOperation()
381 {
382   ModuleBase_Operation* anOperation = currentOperation();
383   if (anOperation)
384     anOperation->commit();
385 }
386
387 void XGUI_OperationMgr::onAbortOperation()
388 {
389   ModuleBase_Operation* aCurrentOperation = currentOperation();
390   if (aCurrentOperation && canStopOperation(aCurrentOperation)) {
391     abortOperation(aCurrentOperation);
392   }
393 }
394
395 void XGUI_OperationMgr::onBeforeOperationStarted()
396 {
397   ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
398   if (!aCurrentOperation)
399     return;
400
401   /// Set current feature and remeber old current feature
402   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
403   if (aFOperation) {
404     SessionPtr aMgr = ModelAPI_Session::get();
405     DocumentPtr aDoc = aMgr->activeDocument();
406     // the parameter of current feature should be false, we should use all feature, not only visible
407     // in order to correctly save the previous feature of the nested operation, where the
408     // features can be not visible in the tree. The problem case is Edit sketch entitity(line)
409     // in the Sketch, created in ExtrusionCut operation. The entity disappears by commit.
410     // When sketch entity operation started, the sketch should be cashed here as the current.
411     // Otherwise(the flag is true), the ExtrusionCut is cashed, when commit happens, the sketch
412     // is disabled, sketch entity is disabled as extrusion cut is created earliest then sketch.
413     // As a result the sketch disappears from the viewer. However after commit it is displayed back.
414     aFOperation->setPreviousCurrentFeature(aDoc->currentFeature(false));
415
416 #ifdef DEBUG_CURRENT_FEATURE
417     FeaturePtr aFeature = aFOperation->feature();
418     QString aKind = aFeature ? aFeature->getKind().c_str() : "";
419     qDebug(QString("onBeforeOperationStarted(), edit operation = %1, feature = %2")
420             .arg(aFOperation->isEditOperation())
421             .arg(ModuleBase_Tools::objectInfo(aFeature)).toStdString().c_str());
422
423     qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
424             ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
425 #endif
426
427     if (aFOperation->isEditOperation()) // it should be performed by the feature edit only
428       // in create operation, the current feature is changed by addFeature()
429       aDoc->setCurrentFeature(aFOperation->feature(), false);
430
431 #ifdef DEBUG_CURRENT_FEATURE
432     qDebug("\tdocument->setCurrentFeature");
433     qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
434             ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
435 #endif
436   ModuleBase_IModule* aModule = myWorkshop->module();
437   if (aModule)
438     aModule->beforeOperationStarted(aFOperation);
439   }
440 }
441
442 void XGUI_OperationMgr::onOperationStarted()
443 {
444   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
445   updateApplyOfOperations(aSenderOperation);
446   emit operationStarted(aSenderOperation);
447 }
448
449 void XGUI_OperationMgr::onBeforeOperationAborted()
450 {
451   onBeforeOperationCommitted();
452 }
453
454 void XGUI_OperationMgr::onOperationAborted()
455 {
456   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
457   emit operationAborted(aSenderOperation);
458 }
459
460 void XGUI_OperationMgr::onBeforeOperationCommitted()
461 {
462   ModuleBase_Operation* aCurrentOperation = dynamic_cast<ModuleBase_Operation*>(sender());
463   if (!aCurrentOperation)
464     return;
465
466   /// Restore the previous current feature
467   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(aCurrentOperation);
468   if (aFOperation) {
469 #ifdef DEBUG_CURRENT_FEATURE
470     QString aKind = aFOperation->feature()->getKind().c_str();
471     qDebug(QString("onBeforeOperationCommitted(), edit operation = %1, feature = %2")
472             .arg(aFOperation->isEditOperation())
473             .arg(ModuleBase_Tools::objectInfo(aFOperation->feature())).toStdString().c_str());
474
475     qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
476             ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
477 #endif
478
479     if (aFOperation->isEditOperation()) {
480       /// Restore the previous current feature
481       setCurrentFeature(aFOperation->previousCurrentFeature());
482     }
483     else { // create operation
484       // the Top created feature should stays the current. In nested operations, like Line in the Sketch or
485       // Sketch in ExtrusionCut, a previous feature should be restored on commit. It is performed here
486       // in order to perform it in the current transaction without opening a new one.
487       if (myOperations.front() != aFOperation)
488         setCurrentFeature(aFOperation->previousCurrentFeature());
489     }
490 #ifdef DEBUG_CURRENT_FEATURE
491     qDebug("\tdocument->setCurrentFeature");
492     qDebug(QString("\tdocument->currentFeature(false) = %1").arg(
493             ModuleBase_Tools::objectInfo(ModelAPI_Session::get()->activeDocument()->currentFeature(false))).toStdString().c_str());
494 #endif
495     ModuleBase_IModule* aModule = myWorkshop->module();
496     if (aModule)
497       aModule->beforeOperationStopped(aFOperation);
498   }
499 }
500
501 void XGUI_OperationMgr::onOperationCommitted()
502 {
503   // apply state for all features from the stack of operations should be updated
504   updateApplyOfOperations();
505
506   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
507   emit operationCommitted(aSenderOperation);
508 }
509
510 void XGUI_OperationMgr::onOperationResumed()
511 {
512   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
513   emit operationResumed(aSenderOperation);
514 }
515
516 void XGUI_OperationMgr::onOperationStopped()
517 {
518   ModuleBase_Operation* aSenderOperation = dynamic_cast<ModuleBase_Operation*>(sender());
519   ModuleBase_Operation* aCurrentOperation = currentOperation();
520   if (!aSenderOperation || !aCurrentOperation || aSenderOperation != aCurrentOperation)
521     return;
522
523   myOperations.removeAll(aCurrentOperation);
524   aCurrentOperation->deleteLater();
525
526   emit operationStopped(aCurrentOperation);
527
528   // get last operation which can be resumed
529   ModuleBase_Operation* aResultOp = 0;
530   QListIterator<ModuleBase_Operation*> anIt(myOperations);
531   anIt.toBack();
532   while (anIt.hasPrevious()) {
533     ModuleBase_Operation* anOp = anIt.previous();
534     if (anOp) {
535       aResultOp = anOp;
536       break;
537     }
538   }
539   if (aResultOp) {
540     bool isModified = aCurrentOperation->isModified();
541     aResultOp->setIsModified(aResultOp->isModified() || isModified);
542     resumeOperation(aResultOp);
543     onValidateOperation();
544   }
545 }
546
547 bool XGUI_OperationMgr::onKeyReleased(QKeyEvent* theEvent)
548 {
549   // Let the manager decide what to do with the given key combination.
550   ModuleBase_Operation* anOperation = currentOperation();
551   bool isAccepted = false;
552   switch (theEvent->key()) {
553     case Qt::Key_Return:
554     case Qt::Key_Enter: {
555       isAccepted = onProcessEnter();
556     }
557     break;
558     case Qt::Key_N:
559     case Qt::Key_P: {
560       bool noModifiers = (theEvent->modifiers() == Qt::NoModifier);
561       if (noModifiers) {
562         ModuleBase_IViewer* aViewer = myWorkshop->viewer();
563         Handle(AIS_InteractiveContext) aContext = aViewer->AISContext();
564         if (!aContext.IsNull()) {
565           Handle(V3d_View) aView = aViewer->activeView();
566           if ((theEvent->key() == Qt::Key_N))
567             aContext->HilightNextDetected(aView);
568           else if ((theEvent->key() == Qt::Key_P))
569             aContext->HilightPreviousDetected(aView);
570         }
571       }
572     }
573     break;
574     break;
575     default:
576       isAccepted = false;
577       break;
578   }
579   //if(anOperation) {
580   //  anOperation->keyReleased(theEvent->key());
581   //}
582   return isAccepted;
583 }
584
585 bool XGUI_OperationMgr::onProcessEnter()
586 {
587   bool isAccepted = false;
588   ModuleBase_Operation* aOperation = currentOperation();
589   ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
590   ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
591   bool isAborted = false;
592   if (!anActiveWgt) {
593     QWidget* aFocusWidget = aPanel->focusWidget();
594     QToolButton* aCancelBtn = aPanel->findChild<QToolButton*>(PROP_PANEL_CANCEL);
595     if (aFocusWidget && aCancelBtn && aFocusWidget == aCancelBtn) {
596       abortOperation(aOperation);
597       isAccepted = true;
598       isAborted = true;
599     }
600   }
601   if (!isAborted) {
602     isAccepted = anActiveWgt && anActiveWgt->processEnter();
603     if (!isAccepted) {
604       isAccepted = myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
605       if (!isAccepted) {
606         /// functionality is similar to Apply click
607         ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>(currentOperation());
608         if (!aFOperation || myWorkshop->module()->getFeatureError(aFOperation->feature()).isEmpty()) {
609           // key released is emitted to apply the current value to the model if it was modified in PP
610           emit keyEnterReleased();
611           commitOperation();
612           isAccepted = true;
613         }
614         else
615           isAccepted = false;
616       }
617     }
618   }
619   return isAccepted;
620 }
621
622 bool XGUI_OperationMgr::onProcessDelete()
623 {
624   bool isAccepted = false;
625   ModuleBase_Operation* aOperation = currentOperation();
626   ModuleBase_ModelWidget* anActiveWgt = 0;
627   if (aOperation) {
628     ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
629     if (aPanel)
630       anActiveWgt = aPanel->activeWidget();
631   }
632   if (anActiveWgt)
633     isAccepted = anActiveWgt->processDelete();
634   if (!isAccepted) {
635     workshop()->deleteObjects();
636     isAccepted = true;
637   }
638
639   return isAccepted;
640 }
641
642 XGUI_Workshop* XGUI_OperationMgr::workshop() const
643 {
644   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myWorkshop);
645   return aConnector->workshop();
646 }
647