SET(PROJECT_HEADERS
ModuleBase.h
ModuleBase_ActionInfo.h
+ ModuleBase_ActionType.h
ModuleBase_Definitions.h
ModuleBase_DoubleSpinBox.h
ModuleBase_Events.h
--- /dev/null
+// Copyright (C) 2014-2017 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or
+// email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
+//
+
+#ifndef ModuleBase_ActionType_H_
+#define ModuleBase_ActionType_H_
+
+#include <ModuleBase.h>
+
+/*!
+ * Structure to describe widget processed types of actions.
+ */
+enum MODULEBASE_EXPORT ModuleBase_ActionType
+{
+ ActionEnter,
+ ActionEscape,
+ ActionDelete,
+ ActionUndo,
+ ActionRedo
+};
+
+#endif /* ModuleBase_ActionType_H_ */
}
}
+bool ModuleBase_ModelWidget::canProcessAction(ModuleBase_ActionType theActionType,
+ bool& isActionEnabled)
+{
+ isActionEnabled = false;
+ switch (theActionType) {
+ case ActionEnter: return false;
+ case ActionEscape: return false;
+ case ActionDelete: return true;
+ case ActionUndo:
+ case ActionRedo:
+ default:
+ return false;
+ }
+}
+
+bool ModuleBase_ModelWidget::processAction(ModuleBase_ActionType theActionType)
+{
+ switch (theActionType) {
+ case ActionEnter:
+ return processEnter();
+ case ActionEscape:
+ return processEscape();
+ case ActionDelete:
+ return processDelete();
+ case ActionUndo:
+ case ActionRedo:
+ default:
+ return false;
+ }
+}
+
bool ModuleBase_ModelWidget::processEnter()
{
return false;
#define MODULEBASE_MODELWIDGET_H
#include <ModuleBase.h>
+#include <ModuleBase_ActionType.h>
#include <ModuleBase_OperationFeature.h>
#include <ModelAPI_Feature.h>
/// \return Current Editing mode
bool isEditingMode() const { return myIsEditing; }
- /// 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 processEscape();
+ /// Returns true if the action can be processed. The default implementation is empty, returns false.
+ /// \param theActionType an action type
+ /// \param isActionEnabled if true, the enable state of the action
+ virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
/// Returns true if the event is processed. The default implementation is empty, returns false.
- virtual bool processDelete();
+ virtual bool processAction(ModuleBase_ActionType theActionType);
/// Sends Update and Redisplay for the given object
/// \param theObj is updating object
/// The method called when widget is activated
virtual void activateCustom() {};
+ //// 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 processEscape();
+
+ //// Returns true if the event is processed. The default implementation is empty, returns false.
+ virtual bool processDelete();
+
protected slots:
/// Processing of values changed in model widget by store the current value to the feature
void onWidgetValuesChanged();
/// \return a control list
virtual QList<QWidget*> getControls() const;
- /// Returns true if the event is processed.
- virtual bool processEnter();
-
public slots:
// Delayed value chnged: when user starts typing something,
// it gives him a 0,5 second to finish typing, when sends valueChnaged() signal
// void onValueChanged();
protected:
+ /// Returns true if the event is processed.
+ virtual bool processEnter();
+
/// Saves the internal parameters to the given feature
/// \return True in success
virtual bool storeValueCustom();
/// \param theY the Y coordinate
void setCursorPosition(const int theX, const int theY);
+protected:
/// Returns true if the event is processed.
virtual bool processEnter();
/// Redefinition of virtual method
virtual QList<QWidget*> getControls() const;
- /// Returns true if the event is processed.
- virtual bool processEnter();
-
protected slots:
/// A slot for processing text changed event
void onTextChanged();
protected:
+ /// Returns true if the event is processed.
+ virtual bool processEnter();
+
/// Do not initialize value on the widget activation
virtual void initializeValueByActivate();
/// exists and has supported format
bool isCurrentPathValid();
- /// Reject the current editor dialog if it is shown and returns true.
- virtual bool processEscape();
-
public slots:
/// Processing of path selection button press
void onPathSelectionBtn();
void onPathChanged();
protected:
+ /// Reject the current editor dialog if it is shown and returns true.
+ virtual bool processEscape();
+
/// Saves the internal parameters to the given feature
/// \return True in success
virtual bool storeValueCustom();
/// \return a control list
virtual QList<QWidget*> getControls() const;
+protected:
/// Returns true if the event is processed.
virtual bool processEnter();
-protected:
/// Saves the internal parameters to the given feature
/// \return True in success
virtual bool storeValueCustom();
/// Redefinition of virtual method
virtual QList<QWidget*> getControls() const;
+protected:
/// Returns true if the event is processed.
virtual bool processEnter();
-protected:
/// Saves the internal parameters to the given feature
/// \return True in success
virtual bool storeValueCustom();
const int ATTRIBUTE_SELECTION_INDEX_ROLE = Qt::UserRole + 1;
+//#define DEBUG_UNDO_REDO
+
/**
* Customization of a List Widget to make it to be placed on full width of container
*/
#endif
};
+#ifdef DEBUG_UNDO_REDO
+void printHistoryInfo(const QString& theMethodName, int theCurrentHistoryIndex,
+ QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > theSelectedHistoryValues)
+{
+ QStringList aSizes;
+ for (int i = 0; i < theSelectedHistoryValues.size(); i++)
+ aSizes.append(QString::number(theSelectedHistoryValues[i].size()));
+
+ std::cout << theMethodName.toStdString()
+ << " current = " << theCurrentHistoryIndex
+ << " size(history) = " << theSelectedHistoryValues.size()
+ << " (" << aSizes.join(", ").toStdString() << ")"
+ << std::endl;
+}
+#endif
+
ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
ModuleBase_IWorkshop* theWorkshop,
const Config_WidgetAPI* theData)
: ModuleBase_WidgetSelector(theParent, theWorkshop, theData),
- myIsSetSelectionBlocked(false)
+ myIsSetSelectionBlocked(false), myCurrentHistoryIndex(-1)
{
QGridLayout* aMainLay = new QGridLayout(this);
ModuleBase_Tools::adjustMargins(aMainLay);
myWorkshop->module()->activateCustomPrs(myFeature,
ModuleBase_IModule::CustomizeHighlightedObjects, true);
+ clearSelectedHistory();
+ myWorkshop->updateCommandStatus();
}
//********************************************************************
ModuleBase_WidgetSelector::deactivate();
myWorkshop->module()->deactivateCustomPrs(ModuleBase_IModule::CustomizeHighlightedObjects, true);
+ clearSelectedHistory();
+ myWorkshop->updateCommandStatus();
}
//********************************************************************
convertIndicesToViewerSelection(anAttributeIds, theValues);
}
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::canProcessAction(ModuleBase_ActionType theActionType,
+ bool& isActionEnabled)
+{
+ isActionEnabled = false;
+ bool aCanProcess = false;
+ switch (theActionType) {
+ case ActionUndo:
+ case ActionRedo: {
+ aCanProcess = true;
+ isActionEnabled = theActionType == ActionUndo ? myCurrentHistoryIndex > 0
+ : (mySelectedHistoryValues.size() > 0 &&
+ myCurrentHistoryIndex < mySelectedHistoryValues.size() - 1);
+ }
+ break;
+ default:
+ break;
+ }
+ return aCanProcess;
+}
+
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::processAction(ModuleBase_ActionType theActionType)
+{
+ switch (theActionType) {
+ case ActionUndo:
+ case ActionRedo: {
+ if (theActionType == ActionUndo)
+ myCurrentHistoryIndex--;
+ else
+ myCurrentHistoryIndex++;
+ QList<ModuleBase_ViewerPrsPtr> aSelected = mySelectedHistoryValues[myCurrentHistoryIndex];
+ // equal vertices should not be used here
+ ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected);
+ bool isDone = setSelection(aSelected,
+ false /*need not validate because values already was in list*/);
+ updateOnSelectionChanged(isDone);
+
+ myWorkshop->updateCommandStatus();
+#ifdef DEBUG_UNDO_REDO
+ printHistoryInfo(QString("processAction %1").arg(theActionType == ActionUndo ? "Undo" : "Redo"),
+ myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+ return true;
+ }
+ default:
+ return ModuleBase_ModelWidget::processAction(theActionType);
+ }
+}
+
+//********************************************************************
+bool ModuleBase_WidgetMultiSelector::activateSelectionAndFilters(bool toActivate)
+{
+ myWorkshop->updateCommandStatus(); // update enable state of Undo/Redo application actions
+ return ModuleBase_WidgetSelector::activateSelectionAndFilters(toActivate);
+}
+
//********************************************************************
bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs)
{
//********************************************************************
bool ModuleBase_WidgetMultiSelector::processDelete()
{
+ appendFirstSelectionInHistory();
+
// find attribute indices to delete
std::set<int> anAttributeIds;
getSelectedAttributeIndices(anAttributeIds);
}
}
}
+ appendSelectionInHistory();
return aDone;
}
// may be the feature's result is not displayed, but attributes should be
myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeArguments,
true); /// hope that something is redisplayed by object updated
+ // clear history should follow after set selected to do not increase history by setSelected
+ clearSelectedHistory();
}
//********************************************************************
}
}
}
+ appendFirstSelectionInHistory();
ModuleBase_WidgetSelector::onSelectionChanged();
+ appendSelectionInHistory();
+}
+
+void ModuleBase_WidgetMultiSelector::appendFirstSelectionInHistory()
+{
+ if (mySelectedHistoryValues.empty()) {
+ myCurrentHistoryIndex++;
+ mySelectedHistoryValues.append(getAttributeSelection());
+
+#ifdef DEBUG_UNDO_REDO
+ printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+ }
+}
+
+void ModuleBase_WidgetMultiSelector::appendSelectionInHistory()
+{
+ while (myCurrentHistoryIndex != mySelectedHistoryValues.count() - 1)
+ mySelectedHistoryValues.removeLast();
+
+ QList<ModuleBase_ViewerPrsPtr> aSelected = getFilteredSelected();
+ myCurrentHistoryIndex++;
+ mySelectedHistoryValues.append(aSelected);
+ myWorkshop->updateCommandStatus();
+
+#ifdef DEBUG_UNDO_REDO
+ printHistoryInfo("appendSelectionInHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
+}
+
+void ModuleBase_WidgetMultiSelector::clearSelectedHistory()
+{
+ mySelectedHistoryValues.clear();
+ myCurrentHistoryIndex = -1;
+ myWorkshop->updateCommandStatus();
+
+#ifdef DEBUG_UNDO_REDO
+ printHistoryInfo("clearSelectedHistory", myCurrentHistoryIndex, mySelectedHistoryValues);
+#endif
}
void ModuleBase_WidgetMultiSelector::updateFocus()
/// \param theValues a list of presentations
virtual void getHighlighted(QList<std::shared_ptr<ModuleBase_ViewerPrs>>& theValues);
+ /// Returns true if the action can be processed. The default implementation is empty, returns false.
+ /// \param theActionType an action type
+ /// \param isActionEnabled if true, the enable state of the action
+ virtual bool canProcessAction(ModuleBase_ActionType theActionType, bool& isActionEnabled);
+
+ /// Returns true if the event is processed. The default implementation is empty, returns false.
+ virtual bool processAction(ModuleBase_ActionType theActionType);
+
+ /// Activate or deactivate selection and selection filters
+ /// \return true if the selection filter of the widget is activated in viewer context
+ virtual bool activateSelectionAndFilters(bool toActivate);
+
/// Checks the widget validity. By default, it returns true.
/// \param thePrs a selected presentation in the view
/// \return a boolean value
virtual bool isValidSelectionCustom(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs);
- /// 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();
void onListSelection();
protected:
+ /// Returns true if the event is processed. The default implementation is empty, returns false.
+ virtual bool processDelete();
+
/// The methiod called when widget is activated
virtual void activateCustom();
/// \return True in success
virtual bool storeValueCustom();
+ /// restire type of selection by feature attribute
virtual bool restoreValueCustom();
+ /// Creates an element of the attribute current selection if history is empty
+ virtual void appendFirstSelectionInHistory();
+
+ /// Create an element in the history that stores the current selection,
+ /// position in the history is incremented
+ void appendSelectionInHistory();
+
+ /// Clear list of stored selected items, reset current position into '-1'
+ void clearSelectedHistory();
+
/// Set the focus on the last item in the list
virtual void updateFocus();
/// A flag to block set selection perform if the method is in process
bool myIsSetSelectionBlocked;
+
+ /// A container of selected objects
+ QList<QList<std::shared_ptr<ModuleBase_ViewerPrs> > > mySelectedHistoryValues;
+ /// Position in a container of selected values
+ int myCurrentHistoryIndex;
};
#endif /* MODULEBASE_WIDGETFILESELECTOR_H_ */
return myOperations.at(idx - 1);
}
+ModuleBase_ModelWidget* XGUI_OperationMgr::activeWidget() const
+{
+ ModuleBase_ModelWidget* anActiveWidget = 0;
+ ModuleBase_Operation* anOperation = currentOperation();
+ if (anOperation) {
+ ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+ if (aPanel)
+ anActiveWidget = aPanel->activeWidget();
+ }
+ return anActiveWidget;
+}
+
bool XGUI_OperationMgr::startOperation(ModuleBase_Operation* theOperation)
{
if (hasOperation())
ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel();
ModuleBase_ModelWidget* anActiveWgt = aPanel->activeWidget();
if (anActiveWgt)
- isAccepted = anActiveWgt && anActiveWgt->processEscape();
+ isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEscape);
}
// default Escape button functionality
if (!isAccepted && aOperation) {
}
}
if (!isAborted) {
- isAccepted = anActiveWgt && anActiveWgt->processEnter();
+ isAccepted = anActiveWgt && anActiveWgt->processAction(ActionEnter);
if (!isAccepted) {
isAccepted =
myWorkshop->module()->processEnter(anActiveWgt ? anActiveWgt->attributeID() : "");
if (isPPChildObject) {
anActiveWgt = aPanel->activeWidget();
if (anActiveWgt) {
- isAccepted = anActiveWgt->processDelete();
+ isAccepted = anActiveWgt->processAction(ActionDelete);
}
}
}
/// else, or if there is no parent - returns NULL
ModuleBase_Operation* previousOperation(ModuleBase_Operation* theOperation) const;
+ /// Returns an active widget of the current operation.
+ /// \return widget or NULL
+ ModuleBase_ModelWidget* activeWidget() const;
+
/// Start the operation and append it to the stack of operations
/// \param theOperation the started operation
/// \return the state whether the current operation is started
#ifdef _DEBUG
bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
if (aNewPart) {
- module()->launchOperation("Part", false);
+ module()->launchOperation("Part", false); // PartSetPlugin_Part::ID()
}
#endif
}
#ifndef HAVE_SALOME
myMainWindow->setCurrentDir(myCurrentDir, true);
#endif
+
+#ifdef _DEBUG
+ bool aNewPart = Config_PropManager::boolean("Plugins", "create_part_by_start");
+ if (aNewPart) {
+
+ DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument();
+ int aSize = aRootDoc->size(ModelAPI_ResultPart::group());
+ if (aSize > 0 ) {
+ ObjectPtr aObject = aRootDoc->object(ModelAPI_ResultPart::group(), 0);
+ ResultPartPtr aPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aObject);
+ if (aPart.get())
+ aPart->activate();
+ }
+ }
+#endif
+
QApplication::restoreOverrideCursor();
}
//******************************************************
void XGUI_Workshop::onUndo(int theTimes)
{
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ if (anActiveWidget && anActiveWidget->processAction(ActionUndo))
+ return;
+
objectBrowser()->treeView()->setCurrentIndex(QModelIndex());
SessionPtr aMgr = ModelAPI_Session::get();
std::list<std::string> aUndoList = aMgr->undoList();
//******************************************************
void XGUI_Workshop::onRedo(int theTimes)
{
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ if (anActiveWidget && anActiveWidget->processAction(ActionRedo))
+ return;
+
// the viewer update should be blocked in order to avoid the features blinking. For the created
// feature a results are created, the flush of the created signal caused the viewer redisplay for
// each created result. After a redisplay signal is flushed. So, the viewer update is blocked
//******************************************************
void XGUI_Workshop::onWidgetStateChanged(int thePreviousState)
{
- ModuleBase_ModelWidget* anActiveWidget = 0;
- ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
- if (anOperation) {
- ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
- if (aPanel)
- anActiveWidget = aPanel->activeWidget();
- }
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ //ModuleBase_Operation* anOperation = myOperationMgr->currentOperation();
+ //if (anOperation) {
+ // ModuleBase_IPropertyPanel* aPanel = anOperation->propertyPanel();
+ // if (aPanel)
+ // anActiveWidget = aPanel->activeWidget();
+ //}
if (anActiveWidget)
operationMgr()->onValidateOperation();
if (aMgr->hasModuleDocument()) {
foreach(QAction* aCmd, aCommands) {
QString aId = aCmd->data().toString();
- if (aId == "UNDO_CMD")
- aCmd->setEnabled(myModule->canUndo());
- else if (aId == "REDO_CMD")
- aCmd->setEnabled(myModule->canRedo());
+ if (aId == "UNDO_CMD") {
+ bool isActionEnabled = false;
+ // if ultimate is true -> using result of operation only, or using OR combination
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ if (anActiveWidget && anActiveWidget->canProcessAction(ActionUndo, isActionEnabled))
+ aCmd->setEnabled(isActionEnabled);
+ else
+ aCmd->setEnabled(myModule->canUndo());
+ }
+ else if (aId == "REDO_CMD") {
+ bool isActionEnabled = false;
+ // if ultimate is true -> using result of operation only, or using OR combination
+ ModuleBase_ModelWidget* anActiveWidget = myOperationMgr->activeWidget();
+ if (anActiveWidget && anActiveWidget->canProcessAction(ActionRedo, isActionEnabled))
+ aCmd->setEnabled(isActionEnabled);
+ else
+ aCmd->setEnabled(myModule->canRedo());
+ }
else
// Enable all commands
aCmd->setEnabled(true);