/*************************************************************************** * Copyright (c) 2013 Jan Rheinlaender * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 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 Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #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 # include # include # include # include #endif #include "ViewProviderDatum.h" #include "TaskDatumParameters.h" #include "Workbench.h" #include #include #include #include #include #include #include #include using namespace PartDesignGui; PROPERTY_SOURCE(PartDesignGui::ViewProviderDatum,Gui::ViewProviderGeometryObject) ViewProviderDatum::ViewProviderDatum() { pShapeSep = new SoSeparator(); pShapeSep->ref(); oldWb = ""; oldTip = NULL; } ViewProviderDatum::~ViewProviderDatum() { pShapeSep->unref(); } void ViewProviderDatum::attach(App::DocumentObject *obj) { ViewProviderGeometryObject::attach(obj); App::DocumentObject* o = getObject(); if (o->getTypeId() == PartDesign::Plane::getClassTypeId()) datumType = QObject::tr("Plane"); else if (o->getTypeId() == PartDesign::Line::getClassTypeId()) datumType = QObject::tr("Line"); else if (o->getTypeId() == PartDesign::Point::getClassTypeId()) datumType = QObject::tr("Point"); SoShapeHints* hints = new SoShapeHints(); hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE); SoMaterialBinding* bind = new SoMaterialBinding(); SoDrawStyle* fstyle = new SoDrawStyle(); fstyle->style = SoDrawStyle::FILLED; SoBaseColor* color = new SoBaseColor(); color->rgb.setValue(0.9f, 0.9f, 0.3f); SoSeparator* sep = new SoSeparator(); SoPickStyle* ps = new SoPickStyle(); ps->style = SoPickStyle::SHAPE; sep->addChild(hints); sep->addChild(bind); sep->addChild(fstyle); sep->addChild(color); sep->addChild(ps); sep->addChild(pShapeSep); addDisplayMaskMode(sep, "Base"); } bool ViewProviderDatum::onDelete(const std::vector &) { // Body feature housekeeping Part::BodyBase* body = Part::BodyBase::findBodyOf(getObject()); if (body != NULL) { body->removeFeature(getObject()); // Make the new Tip and the previous solid feature visible again App::DocumentObject* tip = body->Tip.getValue(); App::DocumentObject* prev = body->getPrevSolidFeature(); if (tip != NULL) { Gui::Application::Instance->getViewProvider(tip)->show(); if ((tip != prev) && (prev != NULL)) Gui::Application::Instance->getViewProvider(prev)->show(); } } // TODO: Ask user what to do about dependent objects, e.g. Sketches that have this feature as their support // 1. Delete // 2. Suppress // 3. Re-route return true; } std::vector ViewProviderDatum::getDisplayModes(void) const { // add modes std::vector StrList; StrList.push_back("Base"); return StrList; } void ViewProviderDatum::setDisplayMode(const char* ModeName) { if (strcmp(ModeName, "Base") == 0) setDisplayMaskMode("Base"); ViewProviderGeometryObject::setDisplayMode(ModeName); } void ViewProviderDatum::onChanged(const App::Property* prop) { /*if (prop == &Shape) { updateData(prop); } else {*/ ViewProviderGeometryObject::onChanged(prop); //} } std::string ViewProviderDatum::getElement(const SoDetail* detail) const { if (detail) { int element; if (detail->getTypeId() == SoLineDetail::getClassTypeId()) { const SoLineDetail* line_detail = static_cast(detail); element = line_detail->getLineIndex(); } else if (detail->getTypeId() == SoFaceDetail::getClassTypeId()) { const SoFaceDetail* face_detail = static_cast(detail); element = face_detail->getFaceIndex(); } else if (detail->getTypeId() == SoPointDetail::getClassTypeId()) { const SoPointDetail* point_detail = static_cast(detail); element = point_detail->getCoordinateIndex(); } if (element == 0) return datumType.toStdString(); } return std::string(""); } SoDetail* ViewProviderDatum::getDetail(const char* subelement) const { QString subelem = QString::fromAscii(subelement); if (subelem == QObject::tr("Line")) { SoLineDetail* detail = new SoLineDetail(); detail->setPartIndex(0); return detail; } else if (subelem == QObject::tr("Plane")) { SoFaceDetail* detail = new SoFaceDetail(); detail->setPartIndex(0); return detail; } else if (subelem == QObject::tr("Point")) { SoPointDetail* detail = new SoPointDetail(); detail->setCoordinateIndex(0); return detail; } return NULL; } bool ViewProviderDatum::isSelectable(void) const { return true; } void ViewProviderDatum::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) { QAction* act; act = menu->addAction(QObject::tr("Edit datum ") + datumType, receiver, member); act->setData(QVariant((int)ViewProvider::Default)); Gui::ViewProviderGeometryObject::setupContextMenu(menu, receiver, member); } bool ViewProviderDatum::setEdit(int ModNum) { if (!ViewProvider::setEdit(ModNum)) return false; if (ModNum == ViewProvider::Default ) { // When double-clicking on the item for this datum feature the // object unsets and sets its edit mode without closing // the task panel Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); TaskDlgDatumParameters *datumDlg = qobject_cast(dlg); if (datumDlg && datumDlg->getDatumView() != this) datumDlg = 0; // another datum feature left open its task panel if (dlg && !datumDlg) { QMessageBox msgBox; msgBox.setText(QObject::tr("A dialog is already open in the task panel")); msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::Yes); int ret = msgBox.exec(); if (ret == QMessageBox::Yes) Gui::Control().closeDialog(); else return false; } // clear the selection (convenience) Gui::Selection().clearSelection(); // always change to PartDesign WB, remember where we come from oldWb = Gui::Command::assureWorkbench("PartDesignWorkbench"); // start the edit dialog if (datumDlg) Gui::Control().showDialog(datumDlg); else Gui::Control().showDialog(new TaskDlgDatumParameters(this)); return true; } else { return ViewProvider::setEdit(ModNum); } } bool ViewProviderDatum::doubleClicked(void) { std::string Msg("Edit "); Msg += this->pcObject->Label.getValue(); Gui::Command::openCommand(Msg.c_str()); PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); if (activeBody != NULL) { // Drop into insert mode so that the user doesn't see all the geometry that comes later in the tree // Also, this way the user won't be tempted to use future geometry as external references for the sketch oldTip = activeBody->Tip.getValue(); if (oldTip != this->pcObject) Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); else oldTip = NULL; } else { oldTip = NULL; } Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().setEdit('%s',0)",this->pcObject->getNameInDocument()); return true; } void ViewProviderDatum::unsetEdit(int ModNum) { // return to the WB we were in before editing the PartDesign feature Gui::Command::assureWorkbench(oldWb.c_str()); if (ModNum == ViewProvider::Default) { // when pressing ESC make sure to close the dialog Gui::Control().closeDialog(); PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); if ((activeBody != NULL) && (oldTip != NULL)) { Gui::Selection().clearSelection(); Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument()); Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); oldTip = NULL; } else { oldTip = NULL; } } else { Gui::ViewProviderGeometryObject::unsetEdit(ModNum); } }