From 3998e2433babc55d97a8be0367192031acf2b07b Mon Sep 17 00:00:00 2001 From: vdwalts Date: Mon, 1 Aug 2016 21:58:23 +0100 Subject: [PATCH] FEM: constraint fixed: some changes in core implementation --- src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp | 332 ++++++++++++--------- src/Mod/Fem/Gui/TaskFemConstraintFixed.h | 38 ++- src/Mod/Fem/Gui/TaskFemConstraintFixed.ui | 37 ++- 3 files changed, 237 insertions(+), 170 deletions(-) diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp index 1fa025485..a82a588d8 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp @@ -20,41 +20,35 @@ * * ***************************************************************************/ - #include "PreCompiled.h" #ifndef _PreComp_ -# include +# include +# include +# include +# include +# include +# include # include # include -# include -# include # include -# include -# include -# include # include -# include -# include # include +# include +# include #endif -#include "ui_TaskFemConstraintFixed.h" +#include "Mod/Fem/App/FemConstraintFixed.h" #include "TaskFemConstraintFixed.h" +#include "ui_TaskFemConstraintFixed.h" #include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include + + +#include +#include + using namespace FemGui; using namespace Gui; @@ -62,126 +56,45 @@ using namespace Gui; /* TRANSLATOR FemGui::TaskFemConstraintFixed */ TaskFemConstraintFixed::TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent) - : TaskFemConstraint(ConstraintView, parent, "fem-constraint-fixed") -{ - // we need a separate container widget to add all controls to + : TaskFemConstraint(ConstraintView, parent, "fem-constraint-fixed") +{ //Note change "Fixed" in line above to new constraint name proxy = new QWidget(this); ui = new Ui_TaskFemConstraintFixed(); ui->setupUi(proxy); QMetaObject::connectSlotsByName(this); - // Create a context menu for the listview of the references - QAction* action = new QAction(tr("Delete"), ui->listReferences); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onReferenceDeleted())); - ui->listReferences->addAction(action); - ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->buttonReference, SIGNAL(pressed()), - this, SLOT(onButtonReference())); - + QAction* action = new QAction(tr("Delete"), ui->lw_references); + action->connect(action, SIGNAL(triggered()), this, SLOT(onReferenceDeleted())); + ui->lw_references->addAction(action); + ui->lw_references->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->lw_references, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + this->groupLayout()->addWidget(proxy); - // Temporarily prevent unnecessary feature recomputes - ui->listReferences->blockSignals(true); - ui->buttonReference->blockSignals(true); - +/* Note: */ // Get the feature data Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); std::vector SubElements = pcConstraint->References.getSubValues(); - + // Fill data into dialog elements - ui->listReferences->clear(); - for (std::size_t i = 0; i < Objects.size(); i++) - ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); - if (Objects.size() > 0) - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - - ui->listReferences->blockSignals(false); - ui->buttonReference->blockSignals(false); - - // Selection mode can be always on since there is nothing else in the UI - onButtonReference(true); -} - -void TaskFemConstraintFixed::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - std::vector references(1,subName); - Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == selref) { - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - // Ensure we don't have mixed reference types - if (SubElements.size() > 0) { - if (subName.substr(0,4) != SubElements.front().substr(0,4)) { - QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); - return; - } - } else { - if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); - return; - } - } - - // Avoid duplicates - std::size_t pos = 0; - for (; pos < Objects.size(); pos++) { - if (obj == Objects[pos]) { - break; - } - } - - if (pos != Objects.size()) { - if (subName == SubElements[pos]) { - return; - } - } - - // add the new reference - Objects.push_back(obj); - SubElements.push_back(subName); - pcConstraint->References.setValues(Objects,SubElements); - ui->listReferences->addItem(makeRefText(obj, subName)); - } - - Gui::Selection().clearSelection(); + + ui->lw_references->clear(); + for (std::size_t i = 0; i < Objects.size(); i++) { + ui->lw_references->addItem(makeRefText(Objects[i], SubElements[i])); } -} + if (Objects.size() > 0) { + ui->lw_references->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + } + + //Selection buttons + connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addToSelection())); + connect(ui->btnRemove, SIGNAL(clicked()), this, SLOT(removeFromSelection())); -void TaskFemConstraintFixed::onReferenceDeleted() { - int row = ui->listReferences->currentIndex().row(); - TaskFemConstraint::onReferenceDeleted(row); - ui->listReferences->model()->removeRow(row); - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); -} - -const std::string TaskFemConstraintFixed::getReferences() const -{ - int rows = ui->listReferences->model()->rowCount(); - - std::vector items; - for (int r = 0; r < rows; r++) - items.push_back(ui->listReferences->item(r)->text().toStdString()); - return TaskFemConstraint::getReferences(items); + updateUI(); } TaskFemConstraintFixed::~TaskFemConstraintFixed() @@ -189,15 +102,157 @@ TaskFemConstraintFixed::~TaskFemConstraintFixed() delete ui; } -void TaskFemConstraintFixed::changeEvent(QEvent *e) +void TaskFemConstraintFixed::updateUI() { - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->retranslateUi(proxy); + if (ui->lw_references->model()->rowCount() == 0) { + // Go into reference selection mode if no reference has been selected yet + onButtonReference(true); + return; } } -//************************************************************************** +void TaskFemConstraintFixed::addToSelection() +{ + std::vector selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document + if (selection.size()==0){ + QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!")); + return; + } + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + for (std::vector::iterator it = selection.begin(); it != selection.end(); ++it){//for every selected object + if (static_cast(it->getTypeName()).substr(0,4).compare(std::string("Part"))!=0){ + QMessageBox::warning(this, tr("Selection error"),tr("Selected object is not a part!")); + return; + } + + std::vector subNames=it->getSubNames(); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName()); + + if (subNames.size()>0){ + for (unsigned int subIt=0;subIt<(subNames.size());++subIt){// for every selected sub element + bool addMe=true; + if ((subNames[subIt].substr(0,4) != "Face") && (subNames[subIt].substr(0,4) != "Edge") && (subNames[subIt].substr(0,6) != "Vertex")) { + QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); + return; + } + for (std::vector::iterator itr=std::find(SubElements.begin(),SubElements.end(),subNames[subIt]); + itr!= SubElements.end(); + itr = std::find(++itr,SubElements.end(),subNames[subIt])) + {// for every sub element in selection that matches one in old list + if (obj==Objects[std::distance(SubElements.begin(),itr)]){//if selected sub element's object equals the one in old list then it was added before so don't add + addMe=false; + } + } + if (addMe){ + disconnect(ui->lw_references, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + Objects.push_back(obj); + SubElements.push_back(subNames[subIt]); + ui->lw_references->addItem(makeRefText(obj, subNames[subIt])); + connect(ui->lw_references, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + } + } + } + //Update UI + pcConstraint->References.setValues(Objects,SubElements); + updateUI(); + } +} + +void TaskFemConstraintFixed::removeFromSelection() +{ + std::vector selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document + if (selection.size()==0){ + QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!")); + return; + } + + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector itemsToDel; + for (std::vector::iterator it = selection.begin(); it != selection.end(); ++it){//for every selected object + if (static_cast(it->getTypeName()).substr(0,4).compare(std::string("Part"))!=0){ + QMessageBox::warning(this, tr("Selection error"),tr("Selected object is not a part!")); + return; + } + + std::vector subNames=it->getSubNames(); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName()); + + for (unsigned int subIt=0;subIt<(subNames.size());++subIt){// for every selected sub element + for (std::vector::iterator itr=std::find(SubElements.begin(),SubElements.end(),subNames[subIt]); + itr!= SubElements.end(); + itr = std::find(++itr,SubElements.end(),subNames[subIt])) + {// for every sub element in selection that matches one in old list + if (obj==Objects[std::distance(SubElements.begin(),itr)]){//if selected sub element's object equals the one in old list then it was added before so mark for deletion + itemsToDel.push_back(std::distance(SubElements.begin(),itr)); + } + } + } + } + + std::sort(itemsToDel.begin(),itemsToDel.end()); + while (itemsToDel.size()>0){ + Objects.erase(Objects.begin()+itemsToDel.back()); + SubElements.erase(SubElements.begin()+itemsToDel.back()); + itemsToDel.pop_back(); + } + //Update UI + disconnect(ui->lw_references, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + + ui->lw_references->clear(); + for (unsigned int j=0;jlw_references->addItem(makeRefText(Objects[j], SubElements[j])); + } + connect(ui->lw_references, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + + pcConstraint->References.setValues(Objects,SubElements); + updateUI(); +} + +void TaskFemConstraintFixed::setSelection(QListWidgetItem* item){ + std::string docName=ConstraintView->getObject()->getDocument()->getName(); + + std::string s = item->text().toStdString(); + std::string delimiter = ":"; + + size_t pos = 0; + std::string objName; + std::string subName; + pos = s.find(delimiter); + objName = s.substr(0, pos); + s.erase(0, pos + delimiter.length()); + subName=s; + + Gui::Selection().clearSelection(); + Gui::Selection().addSelection(docName.c_str(),objName.c_str(),subName.c_str(),0,0,0); +} + +void TaskFemConstraintFixed::onReferenceDeleted() { + TaskFemConstraintFixed::removeFromSelection(); +} + +const std::string TaskFemConstraintFixed::getReferences() const +{ + int rows = ui->lw_references->model()->rowCount(); + std::vector items; + for (int r = 0; r < rows; r++) { + items.push_back(ui->lw_references->item(r)->text().toStdString()); + } + return TaskFemConstraint::getReferences(items); +} + + +void TaskFemConstraintFixed::changeEvent(QEvent *e){ +} + //************************************************************************** // TaskDialog //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -227,10 +282,19 @@ void TaskDlgFemConstraintFixed::open() bool TaskDlgFemConstraintFixed::accept() { std::string name = ConstraintView->getObject()->getNameInDocument(); - const TaskFemConstraintFixed* parameterFixed = static_cast(parameter); - std::string scale = parameterFixed->getScale(); //OvG: determine modified scale + const TaskFemConstraintFixed* parameters = static_cast(parameter); + std::string scale = parameters->getScale(); //OvG: determine modified scale Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale return TaskDlgFemConstraint::accept(); } +bool TaskDlgFemConstraintFixed::reject() +{ + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::updateActive(); + + return true; +} + #include "moc_TaskFemConstraintFixed.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.h b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h index c4ebcf92c..029b76870 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.h +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h @@ -27,56 +27,54 @@ #include #include #include +#include #include "TaskFemConstraint.h" #include "ViewProviderFemConstraintFixed.h" +#include +#include +#include +#include + class Ui_TaskFemConstraintFixed; -namespace App { -class Property; -} - -namespace Gui { -class ViewProvider; -} - namespace FemGui { - class TaskFemConstraintFixed : public TaskFemConstraint { Q_OBJECT public: TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent = 0); - virtual ~TaskFemConstraintFixed(); - - virtual const std::string getReferences() const; + ~TaskFemConstraintFixed(); + const std::string getReferences() const; private Q_SLOTS: void onReferenceDeleted(void); + + void addToSelection(); + void removeFromSelection(); + void setSelection(QListWidgetItem* item); protected: - virtual void changeEvent(QEvent *e); - -private: - virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + void changeEvent(QEvent *e); private: + //void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); Ui_TaskFemConstraintFixed* ui; + }; -/// simulation dialog for the TaskView class TaskDlgFemConstraintFixed : public TaskDlgFemConstraint { Q_OBJECT public: TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView); - - /// is called by the framework if the dialog is accepted (Ok) - virtual bool accept(); void open(); + bool accept(); + bool reject(); }; } //namespace FemGui diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui b/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui index 799fe1bb1..27162f141 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui @@ -6,8 +6,8 @@ 0 0 - 257 - 233 + 309 + 207 @@ -15,27 +15,32 @@ - + - Add reference + Select multiple face(s), click Add or Remove - + + + + + Add + + + + + + + Remove + + + + - - - Qt::Vertical - - - - 17 - 56 - - - +