first take on enhanced feature pick task

This commit is contained in:
Stefan Tröger
2015-07-15 22:04:58 +02:00
parent 28bb00d9e2
commit a2dba9be6e
5 changed files with 228 additions and 113 deletions

View File

@@ -34,10 +34,14 @@
#include <Gui/Document.h>
#include <Gui/ViewProviderOrigin.h>
#include <App/Document.h>
#include <App/Part.h>
#include <Base/Tools.h>
#include <Base/Reader.h>
#include "ui_TaskFeaturePick.h"
#include "TaskFeaturePick.h"
#include "Workbench.h"
#include <Mod/PartDesign/App/Body.h>
using namespace PartDesignGui;
@@ -48,9 +52,10 @@ const QString TaskFeaturePick::getFeatureStatusString(const featureStatus st)
case invalidShape: return tr("Invalid shape");
case noWire: return tr("No wire in sketch");
case isUsed: return tr("Sketch already used by other feature");
case otherBody: return tr("Sketch belongs to another Body feature");
case otherBody: return tr("Belongs to another body");
case otherPart: return tr("Belongs to another part");
case basePlane: return tr("Base plane");
case afterTip: return tr("Feature is located after the Tip feature");
case afterTip: return tr("Feature is located after the tip feature");
}
return tr("");
@@ -66,23 +71,13 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
proxy = new QWidget(this);
ui->setupUi(proxy);
connect(ui->checkReverse, SIGNAL(toggled(bool)), this, SLOT(onCheckReverse(bool)));
connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherBody(bool)));
connect(ui->checkOtherFeature, SIGNAL(toggled(bool)), this, SLOT(onCheckOtherFeature(bool)));
connect(ui->radioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->radioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->radioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
ui->checkReverse->setChecked(false);
ui->checkOtherBody->setChecked(true);
ui->checkOtherBody->setEnabled(false); // TODO: implement
ui->checkOtherFeature->setChecked(false);
ui->checkOtherFeature->setEnabled(false); // TODO: implement
ui->radioIndependent->setChecked(true);
ui->radioIndependent->setEnabled(false);
// These are not implemented yet
ui->radioDependent->setEnabled(false);
ui->radioXRef->setEnabled(false);
connect(ui->checkOtherBody, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->bodyRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->bodyRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->checkOtherPart, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->partRadioIndependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->partRadioDependent, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
connect(ui->partRadioXRef, SIGNAL(toggled(bool)), this, SLOT(onUpdate(bool)));
auto guidoc = Gui::Application::Instance->activeDocument();
auto origin_obj = App::GetApplication().getActiveDocument()->getObjectsOfType<App::Origin>();
@@ -93,11 +88,10 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
QListWidgetItem* item = new QListWidgetItem(QString::fromAscii((*o)->getNameInDocument()) +
QString::fromAscii(" (") + getFeatureStatusString(*st) + QString::fromAscii(")"));
ui->listWidget->addItem(item);
st++;
//check if we need to set any origin in temporary visibility mode
for(App::Origin* obj : origin_obj) {
if(obj->hasObject(*o)) {
if(obj->hasObject(*o) && (*st != invalidShape)) {
Gui::ViewProviderOrigin* vpo = static_cast<Gui::ViewProviderOrigin*>(guidoc->getViewProvider(obj));
if(!vpo->isTemporaryVisibilityMode())
vpo->setTemporaryVisibilityMode(true, guidoc);
@@ -107,6 +101,8 @@ TaskFeaturePick::TaskFeaturePick(std::vector<App::DocumentObject*>& objects,
break;
}
}
st++;
}
groupLayout()->addWidget(proxy);
@@ -132,59 +128,35 @@ void TaskFeaturePick::updateList()
QListWidgetItem* item = ui->listWidget->item(index);
switch (*st) {
case validFeature: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
case invalidShape: item->setFlags(Qt::NoItemFlags); break;
case noWire: item->setFlags(Qt::NoItemFlags); break;
case isUsed: item->setFlags(ui->checkOtherFeature->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
case otherBody: item->setFlags(ui->checkOtherBody->isChecked() ? Qt::ItemIsSelectable | Qt::ItemIsEnabled : Qt::NoItemFlags); break;
case basePlane: item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); break;
case afterTip: item->setFlags(Qt::NoItemFlags); break;
case validFeature: item->setHidden(false); break;
case invalidShape: item->setHidden(true); break;
case noWire: item->setHidden(true); break;
case otherBody: item->setHidden(ui->checkOtherBody->isChecked() ? false : true); break;
case otherPart: item->setHidden(ui->checkOtherPart->isChecked() ? false : true); break;
case basePlane: item->setHidden(false); break;
case afterTip: item->setHidden(true); break;
}
index++;
}
}
void TaskFeaturePick::onCheckReverse(bool checked)
{
}
void TaskFeaturePick::onCheckOtherFeature(bool checked)
{
ui->radioIndependent->setEnabled(checked);
// TODO: Not implemented yet
//ui->radioDependent->setEnabled(checked);
//ui->radioXRef->setEnabled(checked);
updateList();
}
void TaskFeaturePick::onCheckOtherBody(bool checked)
{
ui->radioIndependent->setEnabled(checked);
// TODO: Not implemented yet
//ui->radioDependent->setEnabled(checked);
//ui->radioXRef->setEnabled(checked);
updateList();
}
void TaskFeaturePick::onUpdate(bool)
{
updateList();
}
bool TaskFeaturePick::getReverse()
{
return ui->checkReverse->isChecked();
}
std::vector<App::DocumentObject*> TaskFeaturePick::getFeatures() {
features.clear();
QListIterator<QListWidgetItem*> i(ui->listWidget->selectedItems());
while (i.hasNext()) {
QString t = i.next()->text();
auto item = i.next();
if(item->isHidden())
continue;
QString t = item->text();
t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
features.push_back(t);
}
@@ -197,6 +169,117 @@ std::vector<App::DocumentObject*> TaskFeaturePick::getFeatures() {
return result;
}
std::vector<App::DocumentObject*> TaskFeaturePick::buildFeatures() {
int index = 0;
std::vector<App::DocumentObject*> result;
auto activeBody = PartDesignGui::getBody(false);
auto activePart = PartDesignGui::getPartFor(activeBody, false);
for (std::vector<featureStatus>::const_iterator st = statuses.begin(); st != statuses.end(); st++) {
QListWidgetItem* item = ui->listWidget->item(index);
if(item->isSelected() && !item->isHidden()) {
QString t = item->text();
t = t.left(t.indexOf(QString::fromAscii("(")) - 1);
auto obj = App::GetApplication().getActiveDocument()->getObject(t.toAscii().data());
//build the dependend copy if wanted by the user
if(*st == otherBody) {
if(ui->bodyRadioIndependent->isChecked()) {
auto copy = makeCopy(obj, true);
activeBody->addFeature(copy);
result.push_back(copy);
}
else
result.push_back(obj);
}
else if(*st == otherPart) {
if(!ui->partRadioXRef->isChecked()) {
auto copy = makeCopy(obj, ui->partRadioIndependent->isChecked());
auto oBody = PartDesignGui::getBodyFor(obj, false);
if(oBody)
activeBody->addFeature(copy);
else
activePart->addObject(copy);
result.push_back(copy);
}
else
result.push_back(obj);
}
else
result.push_back(obj);
break;
}
index++;
}
return result;
}
App::DocumentObject* TaskFeaturePick::makeCopy(App::DocumentObject* obj, bool independent) {
//we do know that the created instance is a document object, as obj is one. But we do not know which
//exact type
auto name = App::GetApplication().getActiveDocument()->getUniqueObjectName(obj->getNameInDocument());
auto copy = App::GetApplication().getActiveDocument()->addObject(obj->getTypeId().getName(), name.c_str());
if(copy) {
//copy over all properties
std::vector<App::Property*> props;
std::vector<App::Property*> cprops;
obj->getPropertyList(props);
obj->getPropertyList(cprops);
try{
auto it = cprops.begin();
for( App::Property* prop : props ) {
//independent copys dont have links and are not attached
if(independent && (
prop->getTypeId() == App::PropertyLink::getClassTypeId() ||
prop->getTypeId() == App::PropertyLinkList::getClassTypeId() ||
prop->getTypeId() == App::PropertyLinkSub::getClassTypeId() ||
prop->getTypeId() == App::PropertyLinkSubList::getClassTypeId()||
( prop->getGroup() && strcmp(prop->getGroup(),"Attachment")==0) )) {
++it;
continue;
}
Base::StringWriter writer;
//the properties xml tag is often not correctly cosed and only has "</>". This leads
//to a end of document exception. To prevent this we add a dummy tag arround.
writer.Stream() << writer.ind() << "<Prop>" << std::endl;
writer.ind();
prop->Save(writer);
writer.decInd();
writer.Stream() << writer.ind() << "</Prop>" << std::endl;
std::stringstream stream(writer.getString());
Base::XMLReader reader("test", stream);
reader.readElement("Prop");
App::Property* cprop = *it++;
cprop->Restore(reader);
}
}
catch(const Base::Exception& e) {
Base::Console().Message("Exception: %s\n", e.what());
}
}
return copy;
}
void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg)
{
ui->listWidget->clearSelection();
@@ -211,8 +294,7 @@ void TaskFeaturePick::onSelectionChanged(const Gui::SelectionChanges& msg)
ui->listWidget->setItemSelected(item, true);
}
}
}
}
}
//**************************************************************************
@@ -236,9 +318,9 @@ TaskDlgFeaturePick::TaskDlgFeaturePick(std::vector<App::DocumentObject*> &object
TaskDlgFeaturePick::~TaskDlgFeaturePick()
{
//do the work now as before in accept() the dialog is still open, hence the work
//function could not open annother dialog
//function could not open annother dialog
if(accepted)
workFunction(pick->getFeatures());
workFunction(pick->buildFeatures());
}
//==== calls from the TaskView ===============================================================