X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_Module.cpp;h=9291d3fe4515663da4788b9facead2b2ad5c7787;hb=ac63def3eb29ba78d5e285c5edb026fb083f302b;hp=d3058ab2bf63bd86a83ad8898517260b10365a00;hpb=61da4e89d2ec63daa429d304f928482a0e6fa0b7;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index d3058ab2b..9291d3fe4 100644 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -1,61 +1,63 @@ -#include +#include "PartSet_Module.h" #include -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include + #include #include #include #include +#include #include #include #include -#include #include -#include #include #include -#include -#include -#include -#include #include #include #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include -#include -#include -#include #include -//#include -//#include - -#include -#include -#include -#include #include +#include +#include +#include +#include #include #include #include +#include +#include #include #include @@ -64,6 +66,23 @@ #include #endif + +/// Returns list of unique objects by sum of objects from List1 and List2 +QList getSumList(const QList& theList1, + const QList& theList2) +{ + QList aRes; + foreach (ModuleBase_ViewerPrs aPrs, theList1) { + if (!aRes.contains(aPrs.object())) + aRes.append(aPrs.object()); + } + foreach (ModuleBase_ViewerPrs aPrs, theList2) { + if (!aRes.contains(aPrs.object())) + aRes.append(aPrs.object()); + } + return aRes; +} + /*!Create and return new instance of XGUI_Module*/ extern "C" PARTSET_EXPORT ModuleBase_IModule* createModule(ModuleBase_IWorkshop* theWshop) { @@ -71,29 +90,44 @@ extern "C" PARTSET_EXPORT ModuleBase_IModule* createModule(ModuleBase_IWorkshop* } PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) - : ModuleBase_IModule(theWshop) + : ModuleBase_IModule(theWshop), + myIsDragging(false), myRestartingMode(RM_None), myDragDone(false) { - //myWorkshop = theWshop; - myListener = new PartSet_Listener(this); + //myWorkshop = dynamic_cast(theWshop); + ModuleBase_IViewer* aViewer = aViewer = theWshop->viewer(); + connect(aViewer, SIGNAL(mousePress(ModuleBase_IViewWindow*, QMouseEvent*)), + this, SLOT(onMousePressed(ModuleBase_IViewWindow*, QMouseEvent*))); + + connect(aViewer, SIGNAL(mouseRelease(ModuleBase_IViewWindow*, QMouseEvent*)), + this, SLOT(onMouseReleased(ModuleBase_IViewWindow*, QMouseEvent*))); - connect(myWorkshop, SIGNAL(operationStarted(ModuleBase_Operation*)), - this, SLOT(onOperationStarted(ModuleBase_Operation*))); + connect(aViewer, SIGNAL(mouseMove(ModuleBase_IViewWindow*, QMouseEvent*)), + this, SLOT(onMouseMoved(ModuleBase_IViewWindow*, QMouseEvent*))); - connect(myWorkshop, SIGNAL(operationStopped(ModuleBase_Operation*)), this, - SLOT(onOperationStopped(ModuleBase_Operation*))); + connect(aViewer, SIGNAL(mouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*)), + this, SLOT(onMouseDoubleClick(ModuleBase_IViewWindow*, QMouseEvent*))); - XGUI_Workshop* aXWshop = xWorkshop(); - XGUI_ContextMenuMgr* aContextMenuMgr = aXWshop->contextMenuMgr(); - connect(aContextMenuMgr, SIGNAL(actionTriggered(const QString&, bool)), this, - SLOT(onContextMenuCommand(const QString&, bool))); + XGUI_ModuleConnector* aConnector = dynamic_cast(theWshop); + XGUI_Workshop* aWorkshop = aConnector->workshop(); + XGUI_OperationMgr* anOpMgr = aWorkshop->operationMgr(); + connect(anOpMgr, SIGNAL(keyEnterReleased()), this, SLOT(onEnterReleased())); + connect(anOpMgr, SIGNAL(operationActivatedByPreselection()), + this, SLOT(onOperationActivatedByPreselection())); + + connect(aViewer, SIGNAL(keyRelease(ModuleBase_IViewWindow*, QKeyEvent*)), + this, SLOT(onKeyRelease(ModuleBase_IViewWindow*, QKeyEvent*))); } PartSet_Module::~PartSet_Module() { + if (!myDocumentShapeFilter.IsNull()) + myDocumentShapeFilter.Nullify(); + if (!myPlaneFilter.IsNull()) + myPlaneFilter.Nullify(); } -void PartSet_Module::createFeatures() +void PartSet_Module::registerValidators() { //Registering of validators SessionPtr aMgr = ModelAPI_Session::get(); @@ -103,523 +137,554 @@ void PartSet_Module::createFeatures() aFactory->registerValidator("PartSet_PerpendicularValidator", new PartSet_PerpendicularValidator); aFactory->registerValidator("PartSet_ParallelValidator", new PartSet_ParallelValidator); aFactory->registerValidator("PartSet_RadiusValidator", new PartSet_RadiusValidator); - - Config_ModuleReader aXMLReader = Config_ModuleReader(); - aXMLReader.readAll(); - myFeaturesInFiles = aXMLReader.featuresInFiles(); + aFactory->registerValidator("PartSet_DifferentObjects", new PartSet_DifferentObjectsValidator); } -void PartSet_Module::featureCreated(QAction* theFeature) +void PartSet_Module::registerFilters() { - connect(theFeature, SIGNAL(triggered(bool)), this, SLOT(onFeatureTriggered())); + //Registering of selection filters + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + ModuleBase_FilterFactory* aFactory = aConnector->selectionFilters(); + + aFactory->registerFilter("LinearEdgeFilter", new ModuleBase_FilterLinearEdge); } -std::string PartSet_Module::featureFile(const std::string& theFeatureId) +void PartSet_Module::operationCommitted(ModuleBase_Operation* theOperation) { - return myFeaturesInFiles[theFeatureId]; + if (theOperation->isEditOperation()) + return; + /// Restart sketcher operations automatically + FeaturePtr aFeature = theOperation->feature(); + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature && (myRestartingMode == RM_LastFeatureUsed || + myRestartingMode == RM_EmptyFeatureUsed)) { + myLastOperationId = theOperation->id(); + myLastFeature = myRestartingMode == RM_LastFeatureUsed ? theOperation->feature() : FeaturePtr(); + launchOperation(myLastOperationId); + } + breakOperationSequence(); } -/* - * - */ -void PartSet_Module::onFeatureTriggered() +void PartSet_Module::breakOperationSequence() { - QAction* aCmd = dynamic_cast(sender()); - //Do nothing on uncheck - if (aCmd->isCheckable() && !aCmd->isChecked()) - return; - launchOperation(aCmd->data().toString()); + myLastOperationId = ""; + myLastFeature = FeaturePtr(); + myRestartingMode = RM_None; } +void PartSet_Module::operationAborted(ModuleBase_Operation* theOperation) +{ + breakOperationSequence(); +} -void PartSet_Module::onOperationStarted(ModuleBase_Operation* theOperation) +void PartSet_Module::operationStarted(ModuleBase_Operation* theOperation) { - XGUI_Workshop* aXWshp = xWorkshop(); - XGUI_Displayer* aDisplayer = aXWshp->displayer(); - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(theOperation); - if (aPreviewOp) { - XGUI_PropertyPanel* aPropPanel = aXWshp->propertyPanel(); - connect(aPropPanel, SIGNAL(storedPoint2D(ObjectPtr, const std::string&)), this, - SLOT(onStorePoint2D(ObjectPtr, const std::string&)), Qt::UniqueConnection); - - //aDisplayer->deactivateObjectsOutOfContext(); - PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); - if (aSketchOp) { - if (aSketchOp->isEditOperation()) { - setSketchingMode(getSketchPlane(aSketchOp->feature())); - } else { - aDisplayer->openLocalContext(); - aDisplayer->activateObjectsOutOfContext(QIntList()); - myPlaneFilter = new StdSelect_FaceFilter(StdSelect_Plane); - aDisplayer->addSelectionFilter(myPlaneFilter); - QIntList aModes = sketchSelectionModes(aPreviewOp->feature()); - aDisplayer->setSelectionModes(aModes); - } + if (theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) { + // Display all sketcher sub-Objects + myCurrentSketch = std::dynamic_pointer_cast(theOperation->feature()); + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + + for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aDisplayer->display((*aIt), false); + } + aDisplayer->display(aFeature); + } + // Hide sketcher result + std::list aResults = myCurrentSketch->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aDisplayer->erase((*aIt), false); + } + aDisplayer->erase(myCurrentSketch); + + + if (myPlaneFilter.IsNull()) + myPlaneFilter = new ModuleBase_ShapeInPlaneFilter(); + myWorkshop->viewer()->addSelectionFilter(myPlaneFilter); + if (theOperation->isEditOperation()) { + // If it is editing of sketch then it means that plane is already defined + std::shared_ptr aPln = PartSet_Tools::sketchPlane(myCurrentSketch); + myPlaneFilter->setPlane(aPln->impl()); } } + if (myDocumentShapeFilter.IsNull()) + myDocumentShapeFilter = new PartSet_GlobalFilter(myWorkshop); + myWorkshop->viewer()->addSelectionFilter(myDocumentShapeFilter); } -void PartSet_Module::onOperationStopped(ModuleBase_Operation* theOperation) +void PartSet_Module::operationStopped(ModuleBase_Operation* theOperation) { - if (!theOperation) - return; - XGUI_Workshop* aXWshp = xWorkshop(); - XGUI_Displayer* aDisplayer = aXWshp->displayer(); - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(theOperation); - if (aPreviewOp) { - XGUI_PropertyPanel* aPropPanel = aXWshp->propertyPanel(); - - PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); - if (aSketchOp) { - aDisplayer->closeLocalContexts(); - } else { - PartSet_OperationFeatureCreate* aCreationOp = - dynamic_cast(aPreviewOp); - if (aCreationOp) { - // Activate just created object for selection - FeaturePtr aFeature = aCreationOp->feature(); - QIntList aModes = sketchSelectionModes(aFeature); - const std::list& aResults = aFeature->results(); - std::list::const_iterator anIt, aLast = aResults.end(); - for (anIt = aResults.begin(); anIt != aLast; anIt++) { - aDisplayer->activate(*anIt, aModes); - } - aDisplayer->activate(aFeature, aModes); + if (theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) { + DataPtr aData = myCurrentSketch->data(); + if ((!aData) || (!aData->isValid())) { + // The sketch was aborted + myCurrentSketch = CompositeFeaturePtr(); + return; + } + // Hide all sketcher sub-Objects + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_Displayer* aDisplayer = aConnector->workshop()->displayer(); + for (int i = 0; i < myCurrentSketch->numberOfSubs(); i++) { + FeaturePtr aFeature = myCurrentSketch->subFeature(i); + std::list aResults = aFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aDisplayer->erase((*aIt), false); } + aDisplayer->erase(aFeature, false); + } + // Display sketcher result + std::list aResults = myCurrentSketch->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + aDisplayer->display((*aIt), false); } - }// else { - // Activate results of current feature for selection - //FeaturePtr aFeature = theOperation->feature(); - //XGUI_Displayer* aDisplayer = aXWshp->displayer(); - //std::list aResults = aFeature->results(); - //std::list::const_iterator aIt; - //for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - // aDisplayer->activate(*aIt); - //} - //} + aDisplayer->display(myCurrentSketch); + + myCurrentSketch = CompositeFeaturePtr(); + myWorkshop->viewer()->removeSelectionFilter(myPlaneFilter); + } + myWorkshop->viewer()->removeSelectionFilter(myDocumentShapeFilter); } -void PartSet_Module::onContextMenuCommand(const QString& theId, bool isChecked) +void PartSet_Module::onPlaneSelected(const std::shared_ptr& thePln) { - QList aFeatures = workshop()->selection()->selectedObjects(); - if (theId == "EDIT_CMD" && (aFeatures.size() > 0)) { - FeaturePtr aFeature = boost::dynamic_pointer_cast(aFeatures.first()); - if (aFeature) - editFeature(aFeature); - } + myPlaneFilter->setPlane(thePln->impl()); } -void PartSet_Module::onMousePressed(QMouseEvent* theEvent) + +void PartSet_Module::propertyPanelDefined(ModuleBase_Operation* theOperation) { - XGUI_Workshop* aXWshp = xWorkshop(); - PartSet_OperationSketchBase* aPreviewOp = - dynamic_cast(workshop()->currentOperation()); - if (aPreviewOp) { - ModuleBase_ISelection* aSelection = workshop()->selection(); - // Initialise operation with preliminary selection - //QList aSelected = aSelection->getSelected(); - //QList aHighlighted = aSelection->getHighlighted(); - //QList aObjList; - //bool aHasShift = (theEvent->modifiers() & Qt::ShiftModifier); - //if (aHasShift) { - // foreach(ModuleBase_ViewerPrs aPrs, aSelected) - // aObjList.append(aPrs.object()); - - // foreach (ModuleBase_ViewerPrs aPrs, aHighlighted) { - // if (!aObjList.contains(aPrs.object())) - // aObjList.append(aPrs.object()); - // } - //} else { - // foreach(ModuleBase_ViewerPrs aPrs, aHighlighted) - // aObjList.append(aPrs.object()); - //} - //onSetSelection(aObjList); - aPreviewOp->mousePressed(theEvent, myWorkshop->viewer(), aSelection); + ModuleBase_IPropertyPanel* aPanel = theOperation->propertyPanel(); + if ((theOperation->id().toStdString() == SketchPlugin_Sketch::ID()) && + (theOperation->isEditOperation())) { + // we have to manually activate the sketch label in edit mode + aPanel->activateWidget(aPanel->modelWidgets().first()); + return; } -} -void PartSet_Module::onMouseReleased(QMouseEvent* theEvent) -{ - PartSet_OperationSketchBase* aPreviewOp = - dynamic_cast(myWorkshop->currentOperation()); - if (aPreviewOp) { - ModuleBase_ISelection* aSelection = workshop()->selection(); - // Initialise operation with preliminary selection - aPreviewOp->mouseReleased(theEvent, myWorkshop->viewer(), aSelection); + // Restart last operation type + if ((theOperation->id() == myLastOperationId) && myLastFeature) { + ModuleBase_ModelWidget* aWgt = aPanel->activeWidget(); + if (theOperation->id().toStdString() == SketchPlugin_Line::ID()) { + // Initialise new line with first point equal to end of previous + PartSet_WidgetPoint2D* aPnt2dWgt = dynamic_cast(aWgt); + if (aPnt2dWgt) { + std::shared_ptr aData = myLastFeature->data(); + std::shared_ptr aPoint = + std::dynamic_pointer_cast(aData->attribute(SketchPlugin_Line::END_ID())); + if (aPoint) { + aPnt2dWgt->setPoint(aPoint->x(), aPoint->y()); + PartSet_Tools::setConstraints(myCurrentSketch, theOperation->feature(), + aWgt->attributeID(), aPoint->x(), aPoint->y()); + theOperation->propertyPanel()->activateNextWidget(aPnt2dWgt); + } + } + } + } else { + // Start editing constraint + if (theOperation->isEditOperation()) { + std::string aId = theOperation->id().toStdString(); + if (sketchOperationIdList().contains(QString(aId.c_str()))) { + if ((aId == SketchPlugin_ConstraintRadius::ID()) || + (aId == SketchPlugin_ConstraintLength::ID()) || + (aId == SketchPlugin_ConstraintDistance::ID())) { + // Find and activate widget for management of point for dimension line position + QList aWidgets = aPanel->modelWidgets(); + foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { + PartSet_WidgetPoint2D* aPntWgt = dynamic_cast(aWgt); + if (aPntWgt) { + aPanel->activateWidget(aPntWgt); + return; + } + } + } + } + } } } -void PartSet_Module::onMouseMoved(QMouseEvent* theEvent) -{ - PartSet_OperationSketchBase* aPreviewOp = - dynamic_cast(myWorkshop->currentOperation()); - if (aPreviewOp) - aPreviewOp->mouseMoved(theEvent, myWorkshop->viewer()); -} -void PartSet_Module::onKeyRelease(QKeyEvent* theEvent) +void PartSet_Module::onSelectionChanged() { - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); - if (aPreviewOp) { - aPreviewOp->keyReleased(theEvent->key()); + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + bool isSketcherOp = false; + // An edit operation is enable only if the current opeation is the sketch operation + if (aOperation && myCurrentSketch) { + if (PartSet_Tools::sketchPlane(myCurrentSketch)) + isSketcherOp = (aOperation->id().toStdString() == SketchPlugin_Sketch::ID()); } -} + if (!isSketcherOp) + return; -void PartSet_Module::onMouseDoubleClick(QMouseEvent* theEvent) -{ - PartSet_OperationSketchBase* aPreviewOp = - dynamic_cast(myWorkshop->currentOperation()); - Handle(V3d_View) aView = myWorkshop->viewer()->activeView(); - if (aPreviewOp && (!aView.IsNull())) { - ModuleBase_ISelection* aSelection = workshop()->selection(); - // Initialise operation with preliminary selection - aPreviewOp->mouseDoubleClick(theEvent, aView, aSelection); + // Editing of constraints can be done on selection + ModuleBase_ISelection* aSelect = myWorkshop->selection(); + QList aSelected = aSelect->getSelected(); + if (aSelected.size() == 1) { + ModuleBase_ViewerPrs aPrs = aSelected.first(); + ObjectPtr aObject = aPrs.object(); + FeaturePtr aFeature = ModelAPI_Feature::feature(aObject); + if (aFeature) { + std::string aId = aFeature->getKind(); + if ((aId == SketchPlugin_ConstraintRadius::ID()) || + (aId == SketchPlugin_ConstraintLength::ID()) || + (aId == SketchPlugin_ConstraintDistance::ID())) { + editFeature(aFeature); + } + } } } -void PartSet_Module::onPlaneSelected(double theX, double theY, double theZ) +void PartSet_Module::onMousePressed(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - myWorkshop->viewer()->setViewProjection(theX, theY, theZ); - xWorkshop()->actionsMgr()->update(); - // Set working plane - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - FeaturePtr aSketch = anOperation->feature(); - setSketchingMode(getSketchPlane(aSketch)); -} + if (!(theEvent->buttons() & Qt::LeftButton)) + return; -void PartSet_Module::onFitAllView() -{ - myWorkshop->viewer()->fitAll(); -} + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + // Use only for sketch operations + if (aOperation && myCurrentSketch) { + if (!PartSet_Tools::sketchPlane(myCurrentSketch)) + return; -void PartSet_Module::onRestartOperation(std::string theName, ObjectPtr theObject) -{ - FeaturePtr aFeature = ModelAPI_Feature::feature(theObject); - - std::string aKind = aFeature ? aFeature->getKind() : ""; - ModuleBase_Operation* anOperation = createOperation(theName, aKind); - - PartSet_OperationSketchBase* aSketchOp = dynamic_cast(anOperation); - if (aSketchOp) { - PartSet_OperationFeatureCreate* aCreateOp = dynamic_cast(anOperation); - if (aCreateOp) - aCreateOp->initFeature(aFeature); - else { - anOperation->setFeature(aFeature); + bool isSketcher = (aOperation->id().toStdString() == SketchPlugin_Sketch::ID()); + bool isSketchOpe = sketchOperationIdList().contains(aOperation->id()); + + // Avoid non-sketch operations + if ((!isSketchOpe) && (!isSketcher)) + return; + + bool isEditing = aOperation->isEditOperation(); + + // Ignore creation sketch operation + if ((!isSketcher) && (!isEditing)) + return; + + if (theEvent->modifiers()) { + // If user performs multiselection + if (isSketchOpe && (!isSketcher)) + if (!aOperation->commit()) + aOperation->abort(); + return; + } + // Remember highlighted objects for editing + ModuleBase_ISelection* aSelect = myWorkshop->selection(); + QList aHighlighted = aSelect->getHighlighted(); + QList aSelected = aSelect->getSelected(); + myEditingFeatures.clear(); + myEditingAttr.clear(); + if ((aHighlighted.size() == 0) && (aSelected.size() == 0)) { + if (isSketchOpe && (!isSketcher)) + // commit previous operation + if (!aOperation->commit()) + aOperation->abort(); + return; } - ModuleBase_ISelection* aSelection = workshop()->selection(); - // Initialise operation with preliminary selection - QList aSelected = aSelection->getSelected(); - QList aHighlighted = aSelection->getHighlighted(); - aSketchOp->initSelection(aSelected, aHighlighted); - } //else if (aFeature) { - //anOperation->setFeature(aFeature); - ////Deactivate result of current feature in order to avoid its selection - //XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - //std::list aResults = aFeature->results(); - //std::list::const_iterator aIt; - //for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) { - // aDisplayer->deactivate(*aIt); - //} - //} - sendOperation(anOperation); - xWorkshop()->actionsMgr()->updateCheckState(); -} -void PartSet_Module::onMultiSelectionEnabled(bool theEnabled) -{ - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - aViewer->enableMultiselection(theEnabled); -} + QObjectPtrList aSelObjects = getSumList(aHighlighted, aSelected); + if ((aHighlighted.size() == 1) && (aSelected.size() == 0)) { + // Move by selected shape (vertex). Can be used only for single selection + foreach(ModuleBase_ViewerPrs aPrs, aHighlighted) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aHighlighted.first().object()); + if (aFeature) { + myEditingFeatures.append(aFeature); + TopoDS_Shape aShape = aPrs.shape(); + if (!aShape.IsNull()) { + if (aShape.ShapeType() == TopAbs_VERTEX) { + AttributePtr aAttr = PartSet_Tools::findAttributeBy2dPoint(myEditingFeatures.first(), + aShape, myCurrentSketch); + if (aAttr) + myEditingAttr.append(aAttr); + } + } + } + } + } else { + // Provide multi-selection. Can be used only for features + foreach (ObjectPtr aObj, aSelObjects) { + FeaturePtr aFeature = ModelAPI_Feature::feature(aObj); + if (aFeature && (!myEditingFeatures.contains(aFeature))) + myEditingFeatures.append(aFeature); + } -void PartSet_Module::onStopSelection(const QList& theFeatures, const bool isStop) -{ - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - //if (!isStop) { - // foreach(ObjectPtr aObject, theFeatures) { - // activateFeature(aObject); - // } - //} - aDisplayer->stopSelection(theFeatures, isStop, false); - - ModuleBase_IViewer* aViewer = myWorkshop->viewer(); - aViewer->enableSelection(!isStop); - - aDisplayer->updateViewer(); + } + // If nothing highlighted - return + if (myEditingFeatures.size() == 0) + return; + + if (isSketcher) { + myIsDragging = true; + get2dPoint(theWnd, theEvent, myCurX, myCurY); + myDragDone = false; + myWorkshop->viewer()->enableSelection(false); + launchEditing(); + + } else if (isSketchOpe && isEditing) { + // If selected another object + aOperation->abort(); + + myIsDragging = true; + get2dPoint(theWnd, theEvent, myCurX, myCurY); + myDragDone = false; + myWorkshop->viewer()->enableSelection(false); + + // This is necessary in order to finalize previous operation + QApplication::processEvents(); + launchEditing(); + } + } } -void PartSet_Module::onSetSelection(const QList& theFeatures) + +void PartSet_Module::get2dPoint(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent, + double& theX, double& theY) { - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - aDisplayer->setSelected(theFeatures, false); - aDisplayer->updateViewer(); + Handle(V3d_View) aView = theWnd->v3dView(); + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); + PartSet_Tools::convertTo2D(aPoint, myCurrentSketch, aView, theX, theY); } -void PartSet_Module::setSketchingMode(const gp_Pln& thePln) + +void PartSet_Module::launchEditing() { - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - if (!myPlaneFilter.IsNull()) { - aDisplayer->removeSelectionFilter(myPlaneFilter); - myPlaneFilter.Nullify(); + if (myEditingFeatures.size() > 0) { + FeaturePtr aFeature = myEditingFeatures.first(); + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature) { + editFeature(aSPFeature); + } } - QIntList aModes; - // Clear standard selection modes - aDisplayer->setSelectionModes(aModes); - aDisplayer->openLocalContext(); - // Get default selection modes - aModes = sketchSelectionModes(ObjectPtr()); - aDisplayer->activateObjectsOutOfContext(aModes); - - // Set filter - mySketchFilter = new ModuleBase_ShapeInPlaneFilter(thePln); - aDisplayer->addSelectionFilter(mySketchFilter); } -void PartSet_Module::onFeatureConstructed(ObjectPtr theFeature, int theMode) +/// Returns new instance of operation object (used in createOperation for customization) +ModuleBase_Operation* PartSet_Module::getNewOperation(const std::string& theFeatureId) { - bool isDisplay = theMode != PartSet_OperationSketchBase::FM_Hide; - ModuleBase_Operation* aCurOperation = myWorkshop->currentOperation(); - PartSet_OperationSketchBase* aPrevOp = dynamic_cast(aCurOperation); - if (aPrevOp) { - std::list aList = aPrevOp->subFeatures(); - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - QIntList aModes = sketchSelectionModes(aPrevOp->feature()); - std::list::iterator aSFIt; - for (aSFIt = aList.begin(); aSFIt != aList.end(); ++aSFIt) { - std::list aResults = (*aSFIt)->results(); - std::list::iterator aIt; - for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { - if (!isDisplay) - aDisplayer->erase((*aIt), false); - } - if (!isDisplay) - aDisplayer->erase((*aSFIt), false); - } - //aDisplayer->deactivateObjectsOutOfContext(); + if (theFeatureId == PartSet_OperationSketch::Type()) { + return new PartSet_OperationSketch(theFeatureId.c_str(), this); } - if (isDisplay) - ModelAPI_EventCreator::get()->sendUpdated( - theFeature, Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + return ModuleBase_IModule::getNewOperation(theFeatureId); } -ModuleBase_Operation* PartSet_Module::createOperation(const std::string& theCmdId, - const std::string& theFeatureKind) + +void PartSet_Module::onMouseReleased(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) { - // create the operation - ModuleBase_Operation* anOperation = 0; - if (theCmdId == PartSet_OperationSketch::Type()) { - anOperation = new PartSet_OperationSketch(theCmdId.c_str(), this); - } else { - ModuleBase_Operation* aCurOperation = myWorkshop->currentOperation(); - CompositeFeaturePtr aSketch; - PartSet_OperationSketchBase* aPrevOp = dynamic_cast(aCurOperation); - if (aPrevOp) { - aSketch = aPrevOp->sketch(); - } - if (PartSet_OperationFeatureCreate::canProcessKind(theCmdId)) { - anOperation = new PartSet_OperationFeatureCreate(theCmdId.c_str(), this, aSketch); - } else if (theCmdId == PartSet_OperationFeatureEditMulti::Type()) { - anOperation = new PartSet_OperationFeatureEditMulti(theCmdId.c_str(), this, aSketch); - } else if (theCmdId == PartSet_OperationFeatureEdit::Type()) { - anOperation = new PartSet_OperationFeatureEdit(theCmdId.c_str(), this, aSketch); + myWorkshop->viewer()->enableSelection(true); + if (myIsDragging) { + myIsDragging = false; + if (myDragDone) { + myWorkshop->currentOperation()->commit(); + myEditingFeatures.clear(); + myEditingAttr.clear(); } } +} + - if (!anOperation) { - anOperation = new ModuleBase_Operation(theCmdId.c_str(), this); +void PartSet_Module::onMouseMoved(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) +{ + if (myIsDragging) { + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation->id().toStdString() == SketchPlugin_Sketch::ID()) + return; // No edit operation activated + + static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED); + Handle(V3d_View) aView = theWnd->v3dView(); + gp_Pnt aPoint = PartSet_Tools::convertClickToPoint(theEvent->pos(), aView); + double aX, aY; + PartSet_Tools::convertTo2D(aPoint, myCurrentSketch, aView, aX, aY); + double dX = aX - myCurX; + double dY = aY - myCurY; + + if ((aOperation->id().toStdString() == SketchPlugin_Line::ID()) && + (myEditingAttr.size() == 1) && + myEditingAttr.first()) { + // probably we have prehighlighted point + AttributePtr aAttr = myEditingAttr.first(); + std::string aAttrId = aAttr->id(); + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + QList aWidgets = aPanel->modelWidgets(); + // Find corresponded widget to provide dragging + foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { + if (aWgt->attributeID() == aAttrId) { + PartSet_WidgetPoint2D* aWgt2d = dynamic_cast(aWgt); + if (aWgt2d) { + aWgt2d->setPoint(aWgt2d->x() + dX, aWgt2d->y() + dY); + break; + } + } + } + } else { + foreach(FeaturePtr aFeature, myEditingFeatures) { + std::shared_ptr aSketchFeature = + std::dynamic_pointer_cast(aFeature); + if (aSketchFeature) { + aSketchFeature->move(dX, dY); + ModelAPI_EventCreator::get()->sendUpdated(aSketchFeature, anEvent); + } + } + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_MOVED)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + } + myDragDone = true; + myCurX = aX; + myCurY = aY; } +} - // set operation description and list of widgets corresponding to the feature xml definition - std::string aFeatureKind = theFeatureKind.empty() ? theCmdId : theFeatureKind; - - std::string aPluginFileName = featureFile(aFeatureKind); - Config_WidgetReader aWdgReader = Config_WidgetReader(aPluginFileName); - aWdgReader.readAll(); - std::string aXmlCfg = aWdgReader.featureWidgetCfg(aFeatureKind); - std::string aDescription = aWdgReader.featureDescription(aFeatureKind); - - anOperation->getDescription()->setDescription(QString::fromStdString(aDescription)); - anOperation->getDescription()->setXmlRepresentation(QString::fromStdString(aXmlCfg)); - - // connect the operation - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); - if (aPreviewOp) { - connect(aPreviewOp, SIGNAL(featureConstructed(ObjectPtr, int)), this, - SLOT(onFeatureConstructed(ObjectPtr, int))); - connect(aPreviewOp, SIGNAL(restartRequired(std::string, ObjectPtr)), this, - SLOT(onRestartOperation(std::string, ObjectPtr))); - // If manage multi selection the it will be impossible to select more then one - // object under operation Edit -// connect(aPreviewOp, SIGNAL(multiSelectionEnabled(bool)), this, -// SLOT(onMultiSelectionEnabled(bool))); - - connect(aPreviewOp, SIGNAL(stopSelection(const QList&, const bool)), this, - SLOT(onStopSelection(const QList&, const bool))); - connect(aPreviewOp, SIGNAL(setSelection(const QList&)), this, - SLOT(onSetSelection(const QList&))); - - PartSet_OperationSketch* aSketchOp = dynamic_cast(aPreviewOp); - if (aSketchOp) { - connect(aSketchOp, SIGNAL(planeSelected(double, double, double)), this, - SLOT(onPlaneSelected(double, double, double))); - connect(aSketchOp, SIGNAL(fitAllView()), this, SLOT(onFitAllView())); +void PartSet_Module::onMouseDoubleClick(ModuleBase_IViewWindow* theWnd, QMouseEvent* theEvent) +{ + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation->isEditOperation()) { + std::string aId = aOperation->id().toStdString(); + if ((aId == SketchPlugin_ConstraintLength::ID()) || + (aId == SketchPlugin_ConstraintDistance::ID()) || + (aId == SketchPlugin_ConstraintRadius::ID())) + { + // Activate dimension value editing on double click + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + QList aWidgets = aPanel->modelWidgets(); + // Find corresponded widget to activate value editing + foreach (ModuleBase_ModelWidget* aWgt, aWidgets) { + if (aWgt->attributeID() == "ConstraintValue") { + aWgt->focusTo(); + return; + } + } } } +} - return anOperation; +void PartSet_Module::onKeyRelease(ModuleBase_IViewWindow* theWnd, QKeyEvent* theEvent) +{ + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_OperationMgr* anOpMgr = aConnector->workshop()->operationMgr(); + anOpMgr->onKeyReleased(theEvent); } +void PartSet_Module::onEnterReleased() +{ + myRestartingMode = RM_EmptyFeatureUsed; +} -void PartSet_Module::updateCurrentPreview(const std::string& theCmdId) +void PartSet_Module::onOperationActivatedByPreselection() { - ModuleBase_Operation* anOperation = myWorkshop->currentOperation(); - if (!anOperation) + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (!aOperation) return; - PartSet_OperationSketchBase* aPreviewOp = dynamic_cast(anOperation); - if (!aPreviewOp) - return; + // Set final definitions if they are necessary + //propertyPanelDefined(aOperation); - FeaturePtr aFeature = aPreviewOp->feature(); - if (!aFeature || aFeature->getKind() != theCmdId) - return; + /// Commit sketcher operations automatically + FeaturePtr aFeature = aOperation->feature(); + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature) { + aOperation->commit(); + } +} - XGUI_Displayer* aDisplayer = xWorkshop()->displayer(); - // Hide result of sketch - std::list aResults = aFeature->results(); - std::list::const_iterator aIt; - for (aIt = aResults.cbegin(); aIt != aResults.cend(); ++aIt) - aDisplayer->erase(*aIt, false); - - std::list aList = aPreviewOp->subFeatures(); - - std::list::const_iterator anIt = aList.begin(), aLast = aList.end(); - for (; anIt != aLast; anIt++) { - boost::shared_ptr aSPFeature = boost::dynamic_pointer_cast< - SketchPlugin_Feature>(*anIt); - if (!aSPFeature) - continue; - std::list aResults = aSPFeature->results(); - std::list::const_iterator aRIt; - for (aRIt = aResults.cbegin(); aRIt != aResults.cend(); ++aRIt) { - aDisplayer->display((*aRIt), false); - aDisplayer->activate((*aRIt), sketchSelectionModes((*aRIt))); +void PartSet_Module::onNoMoreWidgets() +{ + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation) { + /// Restart sketcher operations automatically + FeaturePtr aFeature = aOperation->feature(); + std::shared_ptr aSPFeature = + std::dynamic_pointer_cast(aFeature); + if (aSPFeature) { + if (myRestartingMode != RM_Forbided) + myRestartingMode = RM_LastFeatureUsed; + aOperation->commit(); } - aDisplayer->display(aSPFeature, false); - aDisplayer->activate(aSPFeature, sketchSelectionModes(aSPFeature)); } - aDisplayer->updateViewer(); } -void PartSet_Module::editFeature(FeaturePtr theFeature) +QStringList PartSet_Module::sketchOperationIdList() const { - if (!theFeature) - return; - -// if (theFeature->getKind() == SKETCH_KIND) { - //FeaturePtr aFeature = theFeature; - //if (XGUI_Tools::isModelObject(aFeature)) { - // ObjectPtr aObject = boost::dynamic_pointer_cast(aFeature); - // aFeature = aObject->featureRef(); - //} - - //if (aFeature) { - onRestartOperation(theFeature->getKind(), theFeature); - updateCurrentPreview(theFeature->getKind()); - //} -// } + QStringList aIds; + aIds << SketchPlugin_Line::ID().c_str(); + aIds << SketchPlugin_Point::ID().c_str(); + aIds << SketchPlugin_Arc::ID().c_str(); + aIds << SketchPlugin_Circle::ID().c_str(); + aIds << SketchPlugin_ConstraintLength::ID().c_str(); + aIds << SketchPlugin_ConstraintDistance::ID().c_str(); + aIds << SketchPlugin_ConstraintRigid::ID().c_str(); + aIds << SketchPlugin_ConstraintRadius::ID().c_str(); + aIds << SketchPlugin_ConstraintPerpendicular::ID().c_str(); + aIds << SketchPlugin_ConstraintParallel::ID().c_str(); + return aIds; } -void PartSet_Module::onStorePoint2D(ObjectPtr theFeature, const std::string& theAttribute) +void PartSet_Module::onVertexSelected(ObjectPtr theObject, const TopoDS_Shape& theShape) { - FeaturePtr aFeature = boost::dynamic_pointer_cast(theFeature); - - PartSet_OperationSketchBase* aPreviewOp = - dynamic_cast(myWorkshop->currentOperation()); - if (!aPreviewOp) - return; - - boost::shared_ptr aPoint = boost::dynamic_pointer_cast( - aFeature->data()->attribute(theAttribute)); - - PartSet_Tools::setConstraints(aPreviewOp->sketch(), aFeature, theAttribute, aPoint->x(), - aPoint->y()); + ModuleBase_Operation* aOperation = myWorkshop->currentOperation(); + if (aOperation->id().toStdString() == SketchPlugin_Line::ID()) { + /// If last line finished on vertex the lines creation sequence has to be break + ModuleBase_IPropertyPanel* aPanel = aOperation->propertyPanel(); + const QList& aWidgets = aPanel->modelWidgets(); + if (aWidgets.last() == aPanel->activeWidget()) { + myRestartingMode = RM_Forbided; + } + } } QWidget* PartSet_Module::createWidgetByType(const std::string& theType, QWidget* theParent, - Config_WidgetAPI* theWidgetApi, + Config_WidgetAPI* theWidgetApi, std::string theParentId, QList& theModelWidgets) { + XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); + XGUI_Workshop* aWorkshop = aConnector->workshop(); if (theType == "sketch-start-label") { - PartSet_WidgetSketchLabel* aWgt = new PartSet_WidgetSketchLabel(theParent, theWidgetApi, ""); - aWgt->setOperationsMgr(xWorkshop()->operationMgr()); + PartSet_WidgetSketchLabel* aWgt = new PartSet_WidgetSketchLabel(theParent, theWidgetApi, theParentId); + aWgt->setWorkshop(aWorkshop); + connect(aWgt, SIGNAL(planeSelected(const std::shared_ptr&)), + this, SLOT(onPlaneSelected(const std::shared_ptr&))); theModelWidgets.append(aWgt); return aWgt->getControl(); - } else - return 0; -} + } else if (theType == "sketch-2dpoint_selector") { + PartSet_WidgetPoint2D* aWgt = new PartSet_WidgetPoint2D(theParent, theWidgetApi, theParentId); + aWgt->setWorkshop(aWorkshop); + aWgt->setSketch(myCurrentSketch); -XGUI_Workshop* PartSet_Module::xWorkshop() const -{ - XGUI_ModuleConnector* aConnector = dynamic_cast(workshop()); - if (aConnector) { - return aConnector->workshop(); - } - return 0; -} + connect(aWgt, SIGNAL(vertexSelected(ObjectPtr, const TopoDS_Shape&)), + this, SLOT(onVertexSelected(ObjectPtr, const TopoDS_Shape&))); + theModelWidgets.append(aWgt); + return aWgt->getControl(); -QIntList PartSet_Module::sketchSelectionModes(ObjectPtr theFeature) -{ - QIntList aModes; - FeaturePtr aFeature = boost::dynamic_pointer_cast(theFeature); - if (aFeature) { - if (aFeature->getKind() == SketchPlugin_Sketch::ID()) { - aModes.append(TopAbs_FACE); - return aModes; - } else if (PartSet_Tools::isConstraintFeature(aFeature->getKind())) { - aModes.append(AIS_DSM_Text); - aModes.append(AIS_DSM_Line); - return aModes; - } - } - aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_VERTEX)); - aModes.append(AIS_Shape::SelectionMode((TopAbs_ShapeEnum) TopAbs_EDGE)); - return aModes; -} + } if (theType == "point2ddistance") { + PartSet_WidgetPoint2dDistance* aWgt = new PartSet_WidgetPoint2dDistance(theParent, theWidgetApi, theParentId); + aWgt->setWorkshop(aWorkshop); + aWgt->setSketch(myCurrentSketch); + + theModelWidgets.append(aWgt); + return aWgt->getControl(); + } if (theType == "sketch_shape_selector") { + PartSet_WidgetShapeSelector* aWgt = + new PartSet_WidgetShapeSelector(theParent, workshop(), theWidgetApi, theParentId); + aWgt->setSketcher(myCurrentSketch); -gp_Pln PartSet_Module::getSketchPlane(FeaturePtr theSketch) const -{ - DataPtr aData = theSketch->data(); - boost::shared_ptr anOrigin = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::ORIGIN_ID())); - boost::shared_ptr aNorm = boost::dynamic_pointer_cast( - aData->attribute(SketchPlugin_Sketch::NORM_ID())); - gp_Pnt aOrig(anOrigin->x(), anOrigin->y(), anOrigin->z()); - gp_Dir aDir(aNorm->x(), aNorm->y(), aNorm->z()); - return gp_Pln(aOrig, aDir); -} + theModelWidgets.append(aWgt); + return aWgt->getControl(); + } if (theType == "sketch_constraint_shape_selector") { + PartSet_WidgetConstraintShapeSelector* aWgt = + new PartSet_WidgetConstraintShapeSelector(theParent, workshop(), theWidgetApi, theParentId); + aWgt->setSketcher(myCurrentSketch); -void PartSet_Module::onSelectionChanged() -{ - ModuleBase_ISelection* aSelect = myWorkshop->selection(); - QList aSelected = aSelect->getSelected(); - // We need to stop edit operation if selection is cleared - if (aSelected.size() == 0) { - PartSet_OperationFeatureEdit* anEditOp = - dynamic_cast(myWorkshop->currentOperation()); - if (!anEditOp) - return; - anEditOp->commit(); - } else { - PartSet_OperationSketchBase* aSketchOp = - dynamic_cast(myWorkshop->currentOperation()); - if (aSketchOp) { - aSketchOp->selectionChanged(aSelect); - } - } + theModelWidgets.append(aWgt); + return aWgt->getControl(); + + }else + return 0; } +