From d739a2e41bd4724b76db9946124356b9771c9283 Mon Sep 17 00:00:00 2001 From: jriegel Date: Sun, 10 Feb 2013 20:02:21 +0100 Subject: [PATCH] Add all base system changes from the Assembly branch --- src/App/Application.cpp | 14 +- src/App/CMakeLists.txt | 2 + src/App/Document.cpp | 72 +++++--- src/App/Document.h | 20 +++ src/App/DocumentObjectPy.xml | 2 +- src/App/GeoFeature.cpp | 1 - src/App/GeoFeature.h | 1 - src/App/Placement.cpp | 3 +- src/App/Placement.h | 11 +- src/App/PropertyStandard.cpp | 281 +++++++++++++++++++++++++++++++ src/App/PropertyStandard.h | 100 +++++++++++ src/Base/Uuid.cpp | 66 +++----- src/Base/Uuid.h | 10 +- src/Gui/Application.cpp | 9 +- src/Gui/ApplicationPy.cpp | 12 +- src/Gui/CMakeLists.txt | 9 + src/Gui/CombiView.cpp | 7 +- src/Gui/CombiView.h | 3 +- src/Gui/Command.cpp | 34 ++++ src/Gui/Command.h | 5 + src/Gui/Control.cpp | 10 ++ src/Gui/Control.h | 4 + src/Gui/Document.cpp | 56 ++++++ src/Gui/Document.h | 22 ++- src/Gui/DocumentPy.xml | 65 +++---- src/Gui/DocumentPyImp.cpp | 28 +++ src/Gui/SoFCDB.cpp | 2 + src/Gui/SoFCUnifiedSelection.cpp | 7 +- src/Gui/SoFCUnifiedSelection.h | 2 + src/Gui/Tree.cpp | 120 ++++++++----- src/Gui/Tree.h | 32 +++- src/Gui/View3DInventor.cpp | 1 + src/Gui/View3DInventorViewer.cpp | 11 +- src/Gui/View3DInventorViewer.h | 5 + src/Gui/ViewProvider.cpp | 6 + src/Gui/ViewProvider.h | 15 ++ 36 files changed, 877 insertions(+), 171 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index a0f5a0685..655ef445e 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -91,6 +91,8 @@ #include "VRMLObject.h" #include "Annotation.h" #include "MeasureDistance.h" +#include "Placement.h" +#include "Plane.h" // If you stumble here, run the target "BuildExtractRevision" on Windows systems // or the Python script "SubWCRev.py" on Linux based systems which builds @@ -1042,6 +1044,8 @@ void Application::initTypes(void) App ::Annotation ::init(); App ::AnnotationLabel ::init(); App ::MeasureDistance ::init(); + App ::Placement ::init(); + App ::Plane ::init(); } void Application::initConfig(int argc, char ** argv) @@ -1204,10 +1208,12 @@ void Application::processCmdLineFiles(void) Base::Interpreter().runFile(File.filePath().c_str(), true); } else if (File.hasExtension("py")) { - //FIXME: Does this make any sense? I think we should do the ame as for - // fcmacro or fcscript. - //Base::Interpreter().loadModule(File.fileNamePure().c_str()); - Base::Interpreter().runFile(File.filePath().c_str(), true); + try{ + Base::Interpreter().loadModule(File.fileNamePure().c_str()); + }catch(PyException){ + // if module load not work, just try run the script (run in __main__) + Base::Interpreter().runFile(File.filePath().c_str(),true); + } } else { std::vector mods = App::GetApplication().getImportModules(Ext.c_str()); diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index 5d1c2137c..c55ade764 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -77,6 +77,7 @@ SET(Document_CPP_SRCS InventorObject.cpp MeasureDistance.cpp Placement.cpp + Plane.cpp Transactions.cpp VRMLObject.cpp ) @@ -95,6 +96,7 @@ SET(Document_HPP_SRCS InventorObject.h MeasureDistance.h Placement.h + Plane.h Transactions.h VRMLObject.h ) diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 8862341e7..083437bd9 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -143,6 +143,8 @@ struct DocumentP int iUndoMode; unsigned int UndoMemSize; unsigned int UndoMaxStackSize; + DependencyList DepList; + std::map VertexObjectList; DocumentP() { activeObject = 0; @@ -530,13 +532,20 @@ Document::Document(void) ADD_PROPERTY_TYPE(LastModifiedDate,("Unknown"),0,Prop_ReadOnly,"Date of last modification"); ADD_PROPERTY_TYPE(Company,(""),0,Prop_None,"Additional tag to save the the name of the company"); ADD_PROPERTY_TYPE(Comment,(""),0,Prop_None,"Additional tag to save a comment"); + ADD_PROPERTY_TYPE(Meta,(),0,Prop_None,"Map with additional meta information"); + ADD_PROPERTY_TYPE(Material,(),0,Prop_None,"Map with material properties"); // create the uuid for the document Base::Uuid id; - ADD_PROPERTY_TYPE(Id,(id.UuidStr),0,Prop_None,"UUID of the document"); + ADD_PROPERTY_TYPE(Id,(""),0,Prop_None,"ID of the document"); + ADD_PROPERTY_TYPE(Uid,(id),0,Prop_None,"UUID of the document"); + + // license stuff + ADD_PROPERTY_TYPE(License,("CC-BY 3.0"),0,Prop_None,"License string of the Item"); + ADD_PROPERTY_TYPE(LicenseURL,("http://creativecommons.org/licenses/by/3.0/"),0,Prop_None,"URL to the license text/contract"); // create transient directory std::string basePath = Base::FileInfo::getTempPath() + GetApplication().getExecutableName(); - Base::FileInfo TransDir(basePath + "_Doc_" + id.UuidStr); + Base::FileInfo TransDir(basePath + "_Doc_" + id.getValue()); if (!TransDir.exists()) TransDir.createDirectory(); ADD_PROPERTY_TYPE(TransientDir,(TransDir.filePath().c_str()),0,Prop_Transient, @@ -629,7 +638,7 @@ void Document::Restore(Base::XMLReader &reader) // create new transient directory std::string basePath = Base::FileInfo::getTempPath() + GetApplication().getExecutableName(); - Base::FileInfo TransDirNew(basePath + "_Doc_" + Id.getValue()); + Base::FileInfo TransDirNew(basePath + "_Doc_" + Uid.getValueStr()); if(!TransDirNew.exists()) TransDirNew.createDirectory(); TransientDir.setValue(TransDirNew.filePath()); @@ -859,7 +868,7 @@ bool Document::save (void) // make a tmp. file where to save the project data first and then rename to // the actual file name. This may be useful if overwriting an existing file // fails so that the data of the work up to now isn't lost. - std::string uuid = Base::Uuid::CreateUuid(); + std::string uuid = Base::Uuid::createUuid(); std::string fn = FileName.getValue(); fn += "."; fn += uuid; Base::FileInfo tmp(fn); @@ -1081,6 +1090,24 @@ std::vector Document::getInList(const DocumentObject* me) return result; } + +void Document::_rebuildDependencyList(void){ + + // Filling up the adjacency List + for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) + // add the object as Vertex and remember the index + d->VertexObjectList[It->second] = add_vertex(d->DepList); + // add the edges + for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { + std::vector OutList = It->second->getOutList(); + for (std::vector::const_iterator It2=OutList.begin();It2!=OutList.end();++It2) + if (*It2) + add_edge(d->VertexObjectList[It->second],d->VertexObjectList[*It2],d->DepList); + } + +} + + void Document::recompute() { // delete recompute log @@ -1088,27 +1115,30 @@ void Document::recompute() delete *it; _RecomputeLog.clear(); - DependencyList DepList; - std::map VertexObjectList; + // updates the depency graph + _rebuildDependencyList(); - // Filling up the adjacency List - for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) - // add the object as Vertex and remember the index - VertexObjectList[It->second] = add_vertex(DepList); - // add the edges - for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { - std::vector OutList = It->second->getOutList(); - for (std::vector::const_iterator It2=OutList.begin();It2!=OutList.end();++It2) - if (*It2) - add_edge(VertexObjectList[It->second],VertexObjectList[*It2],DepList); - } + //DependencyList DepList; + //std::map VertexObjectList; + + //// Filling up the adjacency List + //for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) + // // add the object as Vertex and remember the index + // VertexObjectList[It->second] = add_vertex(DepList); + //// add the edges + //for (std::map::const_iterator It = d->objectMap.begin(); It != d->objectMap.end();++It) { + // std::vector OutList = It->second->getOutList(); + // for (std::vector::const_iterator It2=OutList.begin();It2!=OutList.end();++It2) + // if (*It2) + // add_edge(VertexObjectList[It->second],VertexObjectList[*It2],DepList); + //} std::list make_order; DependencyList::out_edge_iterator j, jend; try { // this sort gives the execute - boost::topological_sort(DepList, std::front_inserter(make_order)); + boost::topological_sort(d->DepList, std::front_inserter(make_order)); } catch (const std::exception& e) { std::cerr << "Document::recompute: " << e.what() << std::endl; @@ -1116,7 +1146,7 @@ void Document::recompute() } // caching vertex to DocObject - for (std::map::const_iterator It1= VertexObjectList.begin();It1 != VertexObjectList.end(); ++It1) + for (std::map::const_iterator It1= d->VertexObjectList.begin();It1 != d->VertexObjectList.end(); ++It1) d->vertexMap[It1->second] = It1->first; #ifdef FC_LOGFEATUREUPDATE @@ -1136,8 +1166,8 @@ void Document::recompute() NeedUpdate = true; else {// if (Cur->mustExecute() == -1) // update if one of the dependencies is touched - for (boost::tie(j, jend) = out_edges(*i, DepList); j != jend; ++j) { - DocumentObject* Test = d->vertexMap[target(*j, DepList)]; + for (boost::tie(j, jend) = out_edges(*i, d->DepList); j != jend; ++j) { + DocumentObject* Test = d->vertexMap[target(*j, d->DepList)]; if (!Test) continue; #ifdef FC_LOGFEATUREUPDATE std::clog << Test->getNameInDocument() << ", " ; diff --git a/src/App/Document.h b/src/App/Document.h index ce662b588..5e2eedd89 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -71,11 +71,29 @@ public: /// creators name (utf-8) PropertyString CreatedBy; PropertyString CreationDate; + /// user last modified the document PropertyString LastModifiedBy; PropertyString LastModifiedDate; + /// company name UTF8(optional) PropertyString Company; + /// long comment or description (UTF8 with line breaks) PropertyString Comment; + /// Id e.g. Part number PropertyString Id; + /// unique identifier of the document + PropertyUUID Uid; + /** License string + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ + App::PropertyString License; + /// License descripton/contract URL + App::PropertyString LicenseURL; + /// Meta descriptons + App::PropertyMap Meta; + /// Meta descriptons + App::PropertyMap Material; + /// read-only name of the temp dir created wen the document is opened PropertyString TransientDir; //@} @@ -283,6 +301,8 @@ protected: /// helper which Recompute only this feature bool _recomputeFeature(DocumentObject* Feat); void _clearRedos(); + /// refresh the internal dependency graph + void _rebuildDependencyList(void); private: diff --git a/src/App/DocumentObjectPy.xml b/src/App/DocumentObjectPy.xml index 6ea7d0fd4..66d6b052f 100644 --- a/src/App/DocumentObjectPy.xml +++ b/src/App/DocumentObjectPy.xml @@ -31,7 +31,7 @@ - A list of all objects which link tobthis object. + A list of all objects which link to this object. diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index 5226b9e78..b85799cd8 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -40,7 +40,6 @@ PROPERTY_SOURCE(App::GeoFeature, App::DocumentObject) GeoFeature::GeoFeature(void) { - ADD_PROPERTY(Pos,(0)); ADD_PROPERTY(Placement,(Base::Placement())); } diff --git a/src/App/GeoFeature.h b/src/App/GeoFeature.h index c709e2c88..fa79bdeec 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -40,7 +40,6 @@ class AppExport GeoFeature : public App::DocumentObject PROPERTY_HEADER(App::GeoFeature); public: - PropertyPlacementLink Pos; PropertyPlacement Placement; /// Constructor diff --git a/src/App/Placement.cpp b/src/App/Placement.cpp index b54ad1ca0..75307d702 100644 --- a/src/App/Placement.cpp +++ b/src/App/Placement.cpp @@ -33,7 +33,7 @@ using namespace App; -PROPERTY_SOURCE_ABSTRACT(App::Placement, App::DocumentObject) +PROPERTY_SOURCE(App::Placement, App::DocumentObject) //=========================================================================== @@ -43,7 +43,6 @@ PROPERTY_SOURCE_ABSTRACT(App::Placement, App::DocumentObject) Placement::Placement(void) { - ADD_PROPERTY(Pos,(Base::Placement())); } Placement::~Placement(void) diff --git a/src/App/Placement.h b/src/App/Placement.h index 38802a8a9..af52c73c5 100644 --- a/src/App/Placement.h +++ b/src/App/Placement.h @@ -28,7 +28,7 @@ #include -#include "DocumentObject.h" +#include "GeoFeature.h" #include "PropertyGeo.h" @@ -48,18 +48,21 @@ namespace App /** Placement Object * Handles the repositioning of data. Also can do grouping */ -class AppExport Placement: public App::DocumentObject +class AppExport Placement: public App::GeoFeature { PROPERTY_HEADER(App::Placement); public: - PropertyPlacement Pos; - /// Constructor Placement(void); virtual ~Placement(); + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderPlacement"; + } }; diff --git a/src/App/PropertyStandard.cpp b/src/App/PropertyStandard.cpp index 3918d0c36..53f4e5bbd 100644 --- a/src/App/PropertyStandard.cpp +++ b/src/App/PropertyStandard.cpp @@ -1127,6 +1127,110 @@ unsigned int PropertyString::getMemSize (void) const return static_cast(_cValue.size()); } +//************************************************************************** +//************************************************************************** +// PropertyUUID +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TYPESYSTEM_SOURCE(App::PropertyUUID , App::Property); + +PropertyUUID::PropertyUUID() +{ + +} + +PropertyUUID::~PropertyUUID() +{ + +} + +void PropertyUUID::setValue(const Base::Uuid &id) +{ + aboutToSetValue(); + _uuid = id; + hasSetValue(); +} + +void PropertyUUID::setValue(const char* sString) +{ + if (sString) { + aboutToSetValue(); + _uuid.setValue(sString); + hasSetValue(); + } +} + +void PropertyUUID::setValue(const std::string &sString) +{ + aboutToSetValue(); + _uuid.setValue(sString); + hasSetValue(); +} + +const std::string& PropertyUUID::getValueStr(void) const +{ + return _uuid.getValue(); +} + +const Base::Uuid& PropertyUUID::getValue(void) const +{ + return _uuid; +} + +PyObject *PropertyUUID::getPyObject(void) +{ + PyObject *p = PyString_FromString(_uuid.getValue().c_str()); + return p; +} + +void PropertyUUID::setPyObject(PyObject *value) +{ + std::string string; + if (PyString_Check(value)) { + string = PyString_AsString(value); + } + else { + std::string error = std::string("type must be a str, not "); + error += value->ob_type->tp_name; + throw Py::TypeError(error); + } + + // assign the string + setValue(string); +} + +void PropertyUUID::Save (Base::Writer &writer) const +{ + writer.Stream() << writer.ind() << "" << std::endl; +} + +void PropertyUUID::Restore(Base::XMLReader &reader) +{ + // read my Element + reader.readElement("Uuid"); + // get the value of my Attribute + setValue(reader.getAttribute("value")); +} + +Property *PropertyUUID::Copy(void) const +{ + PropertyUUID *p= new PropertyUUID(); + p->_uuid = _uuid; + return p; +} + +void PropertyUUID::Paste(const Property &from) +{ + aboutToSetValue(); + _uuid = dynamic_cast(from)._uuid; + hasSetValue(); +} + +unsigned int PropertyUUID::getMemSize (void) const +{ + return static_cast(sizeof(_uuid)); +} + //************************************************************************** // PropertyFont //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1300,6 +1404,183 @@ void PropertyStringList::Paste(const Property &from) hasSetValue(); } + +//************************************************************************** +// PropertyMap +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TYPESYSTEM_SOURCE(App::PropertyMap , App::Property); + +PropertyMap::PropertyMap() +{ + +} + +PropertyMap::~PropertyMap() +{ + +} + +//************************************************************************** +// Base class implementer + + +int PropertyMap::getSize(void) const +{ + return static_cast(_lValueList.size()); +} + +void PropertyMap::setValue(const std::string& key,const std::string& value) +{ + aboutToSetValue(); + _lValueList[key] = value; + hasSetValue(); +} + +void PropertyMap::setValues(const std::map& map) +{ + aboutToSetValue(); + _lValueList=map; + hasSetValue(); +} + + + +const std::string& PropertyMap::operator[] (const std::string& key) const +{ + static std::string empty; + std::map::const_iterator it = _lValueList.find(key); + if(it!=_lValueList.end()) + return it->second; + else + return empty; +} + + +PyObject *PropertyMap::getPyObject(void) +{ + PyObject* dict = PyDict_New(); + + for (std::map::const_iterator it = _lValueList.begin();it!= _lValueList.end(); ++it) { + PyObject* item = PyUnicode_DecodeUTF8(it->second.c_str(), it->second.size(), 0); + if (!item) { + Py_DECREF(dict); + throw Base::Exception("UTF8 conversion failure at PropertyMap::getPyObject()"); + } + PyDict_SetItemString(dict,it->first.c_str(),item); + } + + return dict; +} + +void PropertyMap::setPyObject(PyObject *value) +{ + if (PyDict_Check(value)) { + + std::map values; + // get key and item list + PyObject* keyList = PyDict_Keys(value); + + PyObject* itemList = PyDict_Values(value); + Py_ssize_t nSize = PyList_Size(keyList); + + for (Py_ssize_t i=0; iob_type->tp_name; + throw Py::TypeError(error); + } + + // check on the item: + PyObject* item = PyList_GetItem(itemList, i); + if (PyUnicode_Check(item)) { + PyObject* unicode = PyUnicode_AsUTF8String(item); + values[keyStr] = PyString_AsString(unicode); + Py_DECREF(unicode); + } + else if (PyString_Check(item)) { + values[keyStr] = PyString_AsString(item); + } + else { + std::string error = std::string("type in list must be string or unicode, not "); + error += item->ob_type->tp_name; + throw Py::TypeError(error); + } + } + + setValues(values); + } + else { + std::string error = std::string("type must be a dict object"); + error += value->ob_type->tp_name; + throw Py::TypeError(error); + } +} + +unsigned int PropertyMap::getMemSize (void) const +{ + size_t size=0; + for (std::map::const_iterator it = _lValueList.begin();it!= _lValueList.end(); ++it) { + size += it->second.size(); + size += it->first.size(); + } + return size; +} + +void PropertyMap::Save (Base::Writer &writer) const +{ + writer.Stream() << writer.ind() << "" << endl; + writer.incInd(); + for (std::map::const_iterator it = _lValueList.begin();it!= _lValueList.end(); ++it) + writer.Stream() << writer.ind() << "first <<"\" value=\"" << encodeAttribute(it->second) <<"\"/>" << endl; + + writer.decInd(); + writer.Stream() << writer.ind() << "" << endl ; +} + +void PropertyMap::Restore(Base::XMLReader &reader) +{ + // read my Element + reader.readElement("Map"); + // get the value of my Attribute + int count = reader.getAttributeAsInteger("count"); + + std::map values; + for(int i = 0; i < count; i++) { + reader.readElement("Item"); + values[reader.getAttribute("key")] = reader.getAttribute("value"); + } + + reader.readEndElement("Map"); + + // assignment + setValues(values); +} + +Property *PropertyMap::Copy(void) const +{ + PropertyMap *p= new PropertyMap(); + p->_lValueList = _lValueList; + return p; +} + +void PropertyMap::Paste(const Property &from) +{ + aboutToSetValue(); + _lValueList = dynamic_cast(from)._lValueList; + hasSetValue(); +} + + + + //************************************************************************** //************************************************************************** // PropertyBool diff --git a/src/App/PropertyStandard.h b/src/App/PropertyStandard.h index fc2989379..9f6d07beb 100644 --- a/src/App/PropertyStandard.h +++ b/src/App/PropertyStandard.h @@ -32,6 +32,7 @@ #include #include +#include #include "Property.h" #include "Material.h" @@ -297,6 +298,61 @@ private: std::vector _lValueList; }; +/** implements a key/value list as property + * The key ought to be ASCII the Value should be treated as UTF8 to be save. + */ +class AppExport PropertyMap: public Property +{ + TYPESYSTEM_HEADER(); + +public: + + /** + * A constructor. + * A more elaborate description of the constructor. + */ + PropertyMap(); + + /** + * A destructor. + * A more elaborate description of the destructor. + */ + ~PropertyMap(); + + virtual int getSize(void) const; + + /** Sets the property + */ + void setValue(void){}; + void setValue(const std::string& key,const std::string& value); + void setValues(const std::map&); + + /// index operator + const std::string& operator[] (const std::string& key) const ; + + void set1Value (const std::string& key, const std::string& value){_lValueList.operator[] (key) = value;} + + const std::map &getValues(void) const{return _lValueList;} + + //virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyStringListItem"; } + + virtual PyObject *getPyObject(void); + virtual void setPyObject(PyObject *); + + virtual void Save (Base::Writer &writer) const; + virtual void Restore(Base::XMLReader &reader); + + virtual Property *Copy(void) const; + virtual void Paste(const Property &from); + + virtual unsigned int getMemSize (void) const; + + +private: + std::map _lValueList; +}; + + /** Float properties * This is the father of all properties handling floats. @@ -489,6 +545,50 @@ private: std::string _cValue; }; +/** UUID properties + * This property handles unique identifieers + */ +class AppExport PropertyUUID: public Property +{ + TYPESYSTEM_HEADER(); + +public: + + /** + * A constructor. + * A more elaborate description of the constructor. + */ + PropertyUUID(void); + + /** + * A destructor. + * A more elaborate description of the destructor. + */ + virtual ~PropertyUUID(); + + + void setValue(const Base::Uuid &); + void setValue(const char* sString); + void setValue(const std::string &sString); + const std::string& getValueStr(void) const; + const Base::Uuid& getValue(void) const; + + //virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyStringItem"; } + virtual PyObject *getPyObject(void); + virtual void setPyObject(PyObject *); + + virtual void Save (Base::Writer &writer) const; + virtual void Restore(Base::XMLReader &reader); + + virtual Property *Copy(void) const; + virtual void Paste(const Property &from); + virtual unsigned int getMemSize (void) const; + +private: + Base::Uuid _uuid; +}; + + /** Property handling with font names. */ class AppExport PropertyFont : public PropertyString diff --git a/src/Base/Uuid.cpp b/src/Base/Uuid.cpp index 9080d338f..eb0395a8c 100644 --- a/src/Base/Uuid.cpp +++ b/src/Base/Uuid.cpp @@ -24,11 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# ifdef FC_OS_WIN32 -# include -# else -# include -# endif +# include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... @@ -50,7 +46,7 @@ using namespace Base; */ Uuid::Uuid() { - UuidStr = CreateUuid(); + _uuid = createUuid(); } /** @@ -65,46 +61,36 @@ Uuid::~Uuid() //************************************************************************** // Get the UUID //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -std::string Uuid::CreateUuid(void) +std::string Uuid::createUuid(void) { -#ifdef FC_OS_WIN32 - RPC_STATUS rstat; - UUID uuid; - unsigned char *uuidStr; - - rstat = UuidCreate(&uuid); - if (rstat != RPC_S_OK) throw Base::Exception("Cannot convert a unique Windows UUID to a string"); - - rstat = UuidToString(&uuid, &uuidStr); - if (rstat != RPC_S_OK) throw Base::Exception("Cannot convert a unique Windows UUID to a string"); - - std::string Uuid((char *)uuidStr); - - /* convert it from rcp memory to our own */ - //container = nssUTF8_Duplicate(uuidStr, NULL); - RpcStringFree(&uuidStr); -#elif 1 std::string Uuid; QString uuid = QUuid::createUuid().toString(); uuid = uuid.mid(1); uuid.chop(1); Uuid = (const char*)uuid.toAscii(); -#else - // use Python's implemententation - std::string Uuid; - PyGILStateLocker lock; - try { - Py::Module module(PyImport_ImportModule("uuid"),true); - Py::Callable method(module.getAttr("uuid4")); - Py::Tuple arg; - Py::Object guid = method.apply(arg); - Uuid = guid.as_string(); - } - catch (Py::Exception& e) { - e.clear(); - throw Base::Exception("Creation of UUID failed"); - } -#endif return Uuid; } +void Uuid::setValue(const char* sString) +{ + if (sString) { + QUuid uuid(QString::fromAscii(sString)); + if (uuid.isNull()) + throw std::runtime_error("invalid uuid"); + // remove curly braces + QString id = uuid.toString(); + id = id.mid(1); + id.chop(1); + _uuid = (const char*)id.toAscii(); + } +} + +void Uuid::setValue(const std::string &sString) +{ + setValue(sString.c_str()); +} + +const std::string& Uuid::getValue(void) const +{ + return _uuid; +} \ No newline at end of file diff --git a/src/Base/Uuid.h b/src/Base/Uuid.h index 8da9b0266..414a613b5 100644 --- a/src/Base/Uuid.h +++ b/src/Base/Uuid.h @@ -31,7 +31,6 @@ namespace Base { - /** Creates a Uuid * \author Jürgen Riegel */ @@ -43,10 +42,13 @@ public: /// Destruction virtual ~Uuid(); - /// Uuid - std::string UuidStr; + void setValue(const char* sString); + void setValue(const std::string &sString); + const std::string& getValue(void) const; + static std::string createUuid(void); - static std::string CreateUuid(void); +private: + std::string _uuid; }; } //namespace Base diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index ccdc09180..bca7a619c 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -93,6 +93,8 @@ #include "ViewProviderVRMLObject.h" #include "ViewProviderAnnotation.h" #include "ViewProviderMeasureDistance.h" +#include "ViewProviderPlacement.h" +#include "ViewProviderPlane.h" #include "Language/Translator.h" #include "TaskView/TaskDialogPython.h" @@ -1443,6 +1445,8 @@ void Application::initTypes(void) Gui::ViewProviderMeasureDistance ::init(); Gui::ViewProviderPythonFeature ::init(); Gui::ViewProviderPythonGeometry ::init(); + Gui::ViewProviderPlacement ::init(); + Gui::ViewProviderPlane ::init(); // Workbench Gui::Workbench ::init(); @@ -1690,7 +1694,7 @@ void Application::runApplication(void) SetASCII("AutoloadModule", start.c_str()); } - app.activateWorkbench(start.c_str()); + //app.activateWorkbench(start.c_str()); // show the main window if (!hidden) { @@ -1706,6 +1710,9 @@ void Application::runApplication(void) SoQt::setFatalErrorHandler( messageHandlerSoQt, 0 ); #endif + app.activateWorkbench(start.c_str()); + + Instance->d->startingUp = false; #if 0 diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 6f0bfd5ba..a1e89811a 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -497,7 +497,17 @@ PyObject* Application::sActivateWorkbenchHandler(PyObject * /*self*/, PyObject * return NULL; } - Instance->activateWorkbench(psKey); + try { + Instance->activateWorkbench(psKey); + } + catch (const Base::Exception& e) { + PyErr_SetString(PyExc_Exception, e.what()); + return 0; + } + catch (...) { + PyErr_SetString(PyExc_Exception, "Unknown C++ exception raised in activateWorkbench"); + return 0; + } Py_INCREF(Py_None); return Py_None; diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 2e984d49d..9c3d1641a 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -164,6 +164,7 @@ set(Gui_MOC_HDRS Transform.h Tree.h TreeView.h + ProjectView.h View3DInventor.h WidgetFactory.h Widgets.h @@ -424,6 +425,7 @@ SET(Dock_Windows_CPP_SRCS ToolBox.cpp Tree.cpp TreeView.cpp + ProjectView.cpp ) SET(Dock_Windows_HPP_SRCS CombiView.h @@ -436,6 +438,7 @@ SET(Dock_Windows_HPP_SRCS ToolBox.h Tree.h TreeView.h + ProjectView.h ) SET(Dock_Windows_SRCS ${Dock_Windows_CPP_SRCS} @@ -617,6 +620,8 @@ SET(Viewprovider_CPP_SRCS ViewProviderPythonFeature.cpp ViewProviderVRMLObject.cpp ViewProviderBuilder.cpp + ViewProviderPlacement.cpp + ViewProviderPlane.cpp ) SET(Viewprovider_SRCS ${Viewprovider_CPP_SRCS} @@ -632,12 +637,15 @@ SET(Viewprovider_SRCS ViewProviderPythonFeature.h ViewProviderVRMLObject.h ViewProviderBuilder.h + ViewProviderPlacement.h + ViewProviderPlane.h ) SOURCE_GROUP("View3D\\Viewprovider" FILES ${Viewprovider_SRCS}) # The Inventor sources SET(Inventor_CPP_SRCS Inventor/SoDrawingGrid.cpp + Inventor/SoAutoZoomTranslation.cpp SoFCBackgroundGradient.cpp SoFCBoundingBox.cpp SoFCColorBar.cpp @@ -658,6 +666,7 @@ SET(Inventor_CPP_SRCS SET(Inventor_SRCS ${Inventor_CPP_SRCS} Inventor/SoDrawingGrid.h + Inventor/SoAutoZoomTranslation.h SoFCBackgroundGradient.h SoFCBoundingBox.h SoFCColorBar.h diff --git a/src/Gui/CombiView.cpp b/src/Gui/CombiView.cpp index b7cdb1f7f..cf2f5813a 100644 --- a/src/Gui/CombiView.cpp +++ b/src/Gui/CombiView.cpp @@ -29,6 +29,7 @@ #include "BitmapFactory.h" #include "iisTaskPanel/include/iisTaskPanel" #include "PropertyView.h" +#include "ProjectView.h" #include "Application.h" #include "Document.h" #include "Tree.h" @@ -72,11 +73,15 @@ CombiView::CombiView(Gui::Document* pcDocument, QWidget *parent) prop = new PropertyView(this); splitter->addWidget(prop); - tabs->addTab(splitter,trUtf8("Project")); + tabs->addTab(splitter,trUtf8("Model")); // task panel taskPanel = new Gui::TaskView::TaskView(this); tabs->addTab(taskPanel, trUtf8("Tasks")); + + // task panel + projectView = new Gui::ProjectWidget(this); + tabs->addTab(projectView, trUtf8("Project")); } CombiView::~CombiView() diff --git a/src/Gui/CombiView.h b/src/Gui/CombiView.h index a16c20f39..39db7938e 100644 --- a/src/Gui/CombiView.h +++ b/src/Gui/CombiView.h @@ -38,7 +38,7 @@ namespace App { namespace Gui { class TreeWidget; class PropertyView; - + class ProjectWidget; namespace PropertyEditor { class EditableListView; class EditableItem; @@ -98,6 +98,7 @@ private: Gui::PropertyView * prop; QTreeView * tree; Gui::TaskView::TaskView * taskPanel; + Gui::ProjectWidget * projectView; }; } // namespace DockWnd diff --git a/src/Gui/Command.cpp b/src/Gui/Command.cpp index 3412dd1f1..2fc6f8748 100644 --- a/src/Gui/Command.cpp +++ b/src/Gui/Command.cpp @@ -47,6 +47,8 @@ #include "Control.h" #include "View3DInventor.h" #include "View3DInventorViewer.h" +#include "WorkbenchManager.h" +#include "Workbench.h" #include #include @@ -119,6 +121,9 @@ using namespace Gui::DockWnd; * @see Gui::Command, Gui::CommandManager */ +// list of modules already loaded by a command (not issue again for macro cleanness) +std::set alreadyLoadedModule; + CommandBase::CommandBase( const char* sMenu, const char* sToolTip, const char* sWhat, const char* sStatus, const char* sPixmap, const char* sAcc) : sMenuText(sMenu), sToolTipText(sToolTip), sWhatsThis(sWhat?sWhat:sToolTip), @@ -443,6 +448,35 @@ void Command::runCommand(DoCmd_Type eType,const char* sCmd) Base::Interpreter().runString(sCmd); } +void Command::addModule(DoCmd_Type eType,const char* sModuleName) +{ + if(alreadyLoadedModule.find(sModuleName) == alreadyLoadedModule.end()) { + std::string sCmd("import "); + sCmd += sModuleName; + if (eType == Gui) + Gui::Application::Instance->macroManager()->addLine(MacroManager::Gui,sCmd.c_str()); + else + Gui::Application::Instance->macroManager()->addLine(MacroManager::App,sCmd.c_str()); + Base::Interpreter().runString(sCmd.c_str()); + alreadyLoadedModule.insert(sModuleName); + } +} + +std::string Command::assureWorkbench(const char * sName) +{ + // check if the WB is already open? + std::string actName = WorkbenchManager::instance()->active()->name(); + // if yes, do nothing + if(actName == sName) + return actName; + + // else - switch to new WB + doCommand(Gui,"Gui.activateWorkbench('%s')",sName); + + return actName; + +} + void Command::copyVisual(const char* to, const char* attr, const char* from) { doCommand(Gui,"Gui.ActiveDocument.%s.%s=Gui.ActiveDocument.%s.%s", to, attr, from, attr); diff --git a/src/Gui/Command.h b/src/Gui/Command.h index 5c5035bdd..255a7dd2f 100644 --- a/src/Gui/Command.h +++ b/src/Gui/Command.h @@ -237,6 +237,11 @@ public: /// Run a App level Action static void doCommand(DoCmd_Type eType,const char* sCmd,...); static void runCommand(DoCmd_Type eType,const char* sCmd); + /// import an external (or own) module only once + static void addModule(DoCmd_Type eType,const char* sModuleName); + /// assures the switch to a certain workbench, if already in the workbench, does nothing. + static std::string assureWorkbench(const char * sName); + static void copyVisual(const char* to, const char* attr, const char* from); static void copyVisual(const char* to, const char* attr_to, const char* from, const char* attr_from); /// Get Python tuple from object and sub-elements diff --git a/src/Gui/Control.cpp b/src/Gui/Control.cpp index adf0ff3f8..5fc93036c 100644 --- a/src/Gui/Control.cpp +++ b/src/Gui/Control.cpp @@ -81,6 +81,16 @@ void ControlSingleton::showTaskView() _taskPanel->raise(); } +void ControlSingleton::showModelView() +{ + Gui::DockWnd::CombiView* pcCombiView = qobject_cast + (Gui::DockWindowManager::instance()->getDockWindow("Combo View")); + if (pcCombiView) + pcCombiView->showTreeView(); + else if (_taskPanel) + _taskPanel->raise(); +} + void ControlSingleton::showDialog(Gui::TaskView::TaskDialog *dlg) { // only one dialog at a time diff --git a/src/Gui/Control.h b/src/Gui/Control.h index 639efd2b3..0c4931da0 100644 --- a/src/Gui/Control.h +++ b/src/Gui/Control.h @@ -64,12 +64,15 @@ public: /// This method start an Task dialog in the TaskView void showDialog(Gui::TaskView::TaskDialog *dlg); Gui::TaskView::TaskDialog* activeDialog() const; + //void closeDialog(); //@} /** @name task view handling */ //@{ Gui::TaskView::TaskView* taskPanel() const; + /// reisin the model view + void showModelView(); //@} bool isAllowedAlterDocument(void) const; @@ -78,6 +81,7 @@ public: public Q_SLOTS: void closeDialog(); + /// reises the task view pane void showTaskView(); private Q_SLOTS: diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index ef2e72793..f93aab1ee 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -31,6 +31,7 @@ # include # include # include +# include #endif #include @@ -188,6 +189,10 @@ bool Document::setEdit(Gui::ViewProvider* p, int ModNum) { if (d->_pcInEdit) resetEdit(); + // is it really a ViewProvider of this document? + if (d->_ViewProviderMap.find(dynamic_cast(p)->getObject()) == d->_ViewProviderMap.end()) + return false; + View3DInventor *activeView = dynamic_cast(getActiveView()); if (activeView && activeView->getViewer()->setEditingViewProvider(p,ModNum)) { d->_pcInEdit = p; @@ -388,6 +393,7 @@ void Document::slotNewObject(const App::DocumentObject& Obj) Base::Console().Error("App::Document::_RecomputeFeature(): Unknown exception in Feature \"%s\" thrown\n",Obj.getNameInDocument()); } #endif + std::list::iterator vIt; // cycling to all views of the document for (vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { @@ -450,6 +456,36 @@ void Document::slotChangedObject(const App::DocumentObject& Obj, const App::Prop Base::Console().Error("Cannot update representation for '%s'.\n", Obj.getNameInDocument()); } + // check for children + if(viewProvider->getChildRoot()) { + std::vector children = viewProvider->claimChildren3D(); + SoGroup* childGroup = viewProvider->getChildRoot(); + + // size not the same -> build up the list new + if(childGroup->getNumChildren() != children.size()){ + + childGroup->removeAllChildren(); + + for(std::vector::iterator it=children.begin();it!=children.end();++it){ + ViewProvider* ChildViewProvider = getViewProvider(*it); + if(ChildViewProvider) { + SoSeparator* childRootNode = ChildViewProvider->getRoot(); + childGroup->addChild(childRootNode); + + // cycling to all views of the document to remove the viewprovider from the viewer itself + for (std::list::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { + View3DInventor *activeView = dynamic_cast(*vIt); + if (activeView && viewProvider) { + if (d->_pcInEdit == ChildViewProvider) + resetEdit(); + activeView->getViewer()->removeViewProvider(ChildViewProvider); + } + } + } + } + } + } + if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) signalChangedObject(static_cast(*viewProvider), Prop); } @@ -489,6 +525,26 @@ bool Document::isModified() const return d->_isModified; } + +ViewProvider* Document::getViewProviderByPathFromTail(SoPath * path) const +{ + // Make sure I'm the lowest LocHL in the pick path! + for (int i = 0; i < path->getLength(); i++) { + SoNode *node = path->getNodeFromTail(i); + if (node->isOfType(SoSeparator::getClassTypeId())) { + std::map::const_iterator it = d->_ViewProviderMap.begin(); + for(;it!= d->_ViewProviderMap.end();++it) + if (node == it->second->getRoot()) + return it->second; + + } + } + + return 0; +} + + + App::Document* Document::getDocument(void) const { return d->_pcDocument; diff --git a/src/Gui/Document.h b/src/Gui/Document.h index a6b933f20..85736c6b9 100644 --- a/src/Gui/Document.h +++ b/src/Gui/Document.h @@ -33,6 +33,10 @@ #include #include +#include "Tree.h" + +class SoPath; + namespace Base { class Matrix4D; @@ -79,10 +83,10 @@ public: mutable boost::signal signalNewObject; /// signal on deleted Object mutable boost::signal signalDeletedObject; - /// signal on changed Object, the 2nd argument is the changed property - /// of the referenced document object, not of the view provider + /** signal on changed Object, the 2nd argument is the changed property + of the referenced document object, not of the view provider */ mutable boost::signal signalChangedObject; + const App::Property&)> signalChangedObject; /// signal on renamed Object mutable boost::signal signalRenamedObject; /// signal on activated Object @@ -91,6 +95,14 @@ public: mutable boost::signal signalInEdit; /// signal on leaving edit mode mutable boost::signal signalResetEdit; + /// signal on changed Object, the 2nd argument is the highlite mode to use + mutable boost::signal signalHighlightObject; + /// signal on changed Object, the 2nd argument is the highlite mode to use + mutable boost::signal signalExpandObject; + //@} /** @name I/O of the document */ @@ -134,7 +146,9 @@ public: /// Attach a view (get called by the MDIView constructor) void attachView(Gui::BaseView* pcView, bool bPassiv=false); /// Detach a view (get called by the MDIView destructor) - void detachView(Gui::BaseView* pcView, bool bPassiv=false); + void detachView(Gui::BaseView* pcView, bool bPassiv=false); + /// helper for selection + ViewProvider* getViewProviderByPathFromTail(SoPath * path) const; /// call update on all attached views void onUpdate(void); /// call relabel to all attached views diff --git a/src/Gui/DocumentPy.xml b/src/Gui/DocumentPy.xml index c76e101cf..da5795a6c 100644 --- a/src/Gui/DocumentPy.xml +++ b/src/Gui/DocumentPy.xml @@ -68,38 +68,43 @@ deprecated -- use ActiveView - - - Return a list if mdi views of a given type - - - - - Send a message to all views of the document - - - - - Merges this document with another project file - - - + + + Return a list if mdi views of a given type + + + + + Send a message to all views of the document + + + + + Merges this document with another project file + + + + + toggleTreeItem(DocObject,int=0) - change TreeItem of a document object 0:Toggle,1:Collaps,2:Expand + + + - The active object of the document + The active object of the document - - - The active view of the document - - - - - - The related App document to this Gui document - - - - + + + The active view of the document + + + + + + The related App document to this Gui document + + + + diff --git a/src/Gui/DocumentPyImp.cpp b/src/Gui/DocumentPyImp.cpp index 67b66f36a..535e58dd9 100644 --- a/src/Gui/DocumentPyImp.cpp +++ b/src/Gui/DocumentPyImp.cpp @@ -38,6 +38,10 @@ // inclusion of the generated files (generated out of DocumentPy.xml) #include "DocumentPy.h" #include "DocumentPy.cpp" +#include +#include "Tree.h" +#include "ViewProviderDocumentObject.h" + using namespace Gui; @@ -251,6 +255,30 @@ PyObject* DocumentPy::mergeProject(PyObject *args) } PY_CATCH; } +PyObject* DocumentPy::toggleTreeItem(PyObject *args) +{ + PyObject *object=0; + int mod = 0; + if (PyArg_ParseTuple(args,"O!|i",&(App::DocumentObjectPy::Type), &object,&mod)) { + App::DocumentObject* Object = static_cast(object)->getDocumentObjectPtr(); + // Should be set! + assert(Object); + + // get the gui document of the Assembly Item + //ActiveAppDoc = Item->getDocument(); + //ActiveGuiDoc = Gui::Application::Instance->getDocument(getDocumentPtr()); + Gui::ViewProviderDocumentObject* ActiveVp = dynamic_cast (getDocumentPtr()->getViewProvider(Object)) ; + switch(mod) { + case 0: getDocumentPtr()->signalExpandObject(*ActiveVp,Gui::Toggle); break; + case 1: getDocumentPtr()->signalExpandObject(*ActiveVp,Gui::Collaps); break; + case 2: getDocumentPtr()->signalExpandObject(*ActiveVp,Gui::Expand); break; + } + } + + Py_Return; +} + + Py::Object DocumentPy::getActiveObject(void) const { App::DocumentObject *object = getDocumentPtr()->getDocument()->getActiveObject(); diff --git a/src/Gui/SoFCDB.cpp b/src/Gui/SoFCDB.cpp index 5769248c4..9a5680ab1 100644 --- a/src/Gui/SoFCDB.cpp +++ b/src/Gui/SoFCDB.cpp @@ -43,6 +43,7 @@ #include "SoTextLabel.h" #include "SoNavigationDragger.h" #include "Inventor/SoDrawingGrid.h" +#include "Inventor/SoAutoZoomTranslation.h" #include "propertyeditor/PropertyItem.h" #include "NavigationStyle.h" @@ -97,6 +98,7 @@ void Gui::SoFCDB::init() SoAxisCrossKit ::initClass(); SoRegPoint ::initClass(); SoDrawingGrid ::initClass(); + SoAutoZoomTranslation ::initClass(); PropertyItem ::init(); PropertySeparatorItem ::init(); diff --git a/src/Gui/SoFCUnifiedSelection.cpp b/src/Gui/SoFCUnifiedSelection.cpp index f8f42764b..52cca94ce 100644 --- a/src/Gui/SoFCUnifiedSelection.cpp +++ b/src/Gui/SoFCUnifiedSelection.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include "SoFCUnifiedSelection.h" @@ -288,7 +289,7 @@ void SoFCUnifiedSelection::doAction(SoAction *action) } else if (selaction->SelChange.Type == SelectionChanges::ClrSelection || selaction->SelChange.Type == SelectionChanges::SetSelection) { - std::vector vps = this->viewer->getViewProvidersOfType + std::vector vps = this->pcDocument->getViewProvidersOfType (ViewProviderDocumentObject::getClassTypeId()); for (std::vector::iterator it = vps.begin(); it != vps.end(); ++it) { ViewProviderDocumentObject* vpd = static_cast(*it); @@ -350,7 +351,7 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) ViewProvider *vp = 0; ViewProviderDocumentObject* vpd = 0; if (pPath && pPath->containsPath(action->getCurPath())) - vp = viewer->getViewProviderByPathFromTail(pPath); + vp = pcDocument->getViewProviderByPathFromTail(pPath); if (vp && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) vpd = static_cast(vp); @@ -423,7 +424,7 @@ SoFCUnifiedSelection::handleEvent(SoHandleEventAction * action) ViewProvider *vp = 0; ViewProviderDocumentObject* vpd = 0; if (pPath && pPath->containsPath(action->getCurPath())) - vp = viewer->getViewProviderByPathFromTail(pPath); + vp = pcDocument->getViewProviderByPathFromTail(pPath); if (vp && vp->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) vpd = static_cast(vp); if (vpd && vpd->useNewSelectionModel() && vpd->isSelectable()) { diff --git a/src/Gui/SoFCUnifiedSelection.h b/src/Gui/SoFCUnifiedSelection.h index db6cf1183..380e778f4 100644 --- a/src/Gui/SoFCUnifiedSelection.h +++ b/src/Gui/SoFCUnifiedSelection.h @@ -48,6 +48,7 @@ class SoDetail; namespace Gui { +class Document; /** Unified Selection node * This is the new selection node for the 3D Viewer which will @@ -95,6 +96,7 @@ protected: //virtual SbBool readInstance(SoInput * in, unsigned short flags); View3DInventorViewer *viewer; + Gui::Document *pcDocument; private: //static void turnoffcurrent(SoAction * action); //void setOverride(SoGLRenderAction * action); diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index 32c58a4df..16ec6a607 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -573,6 +573,7 @@ void TreeWidget::slotActiveDocument(const Gui::Document& Doc) } } + void TreeWidget::onTestStatus(void) { if (isVisible()) { @@ -758,6 +759,8 @@ DocumentItem::DocumentItem(const Gui::Document* doc, QTreeWidgetItem * parent) doc->signalActivatedObject.connect(boost::bind(&DocumentItem::slotActiveObject, this, _1)); doc->signalInEdit.connect(boost::bind(&DocumentItem::slotInEdit, this, _1)); doc->signalResetEdit.connect(boost::bind(&DocumentItem::slotResetEdit, this, _1)); + doc->signalHighlightObject.connect(boost::bind(&DocumentItem::slotHighlightObject, this, _1,_2,_3)); + doc->signalExpandObject.connect(boost::bind(&DocumentItem::slotExpandObject, this, _1,_2)); setFlags(Qt::ItemIsEnabled/*|Qt::ItemIsEditable*/); } @@ -826,7 +829,6 @@ void DocumentItem::slotChangeObject(const Gui::ViewProviderDocumentObject& view) std::map::iterator it = ObjectMap.find(objectName); if (it != ObjectMap.end()) { // use new grouping style -# if 1 std::set children; std::vector group = view.claimChildren(); for (std::vector::iterator jt = group.begin(); jt != group.end(); ++jt) { @@ -866,49 +868,8 @@ void DocumentItem::slotChangeObject(const Gui::ViewProviderDocumentObject& view) this->addChild(child); } } - //this->treeWidget()->expandItem(it->second); - // old grouping style here -# else + this->treeWidget()->expandItem(it->second); - // is the object a group? - if (obj->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) { - std::set children; - std::vector group = static_cast(obj)->Group.getValues(); - for (std::vector::iterator jt = group.begin(); jt != group.end(); ++jt) { - const char* internalName = (*jt)->getNameInDocument(); - if (internalName) { - std::map::iterator kt = ObjectMap.find(internalName); - if (kt != ObjectMap.end()) { - children.insert(kt->second); - QTreeWidgetItem* parent = kt->second->parent(); - if (parent && parent != it->second) { - int index = parent->indexOfChild(kt->second); - parent->takeChild(index); - it->second->addChild(kt->second); - } - } - else { - Base::Console().Warning("DocumentItem::slotChangedObject: Cannot reparent unknown object.\n"); - } - } - else { - Base::Console().Warning("DocumentItem::slotChangedObject: Group references unknown object.\n"); - } - } - - // move all children which are not part of the group anymore to this item - int count = it->second->childCount(); - for (int i=0; i < count; i++) { - QTreeWidgetItem* child = it->second->child(i); - if (children.find(child) == children.end()) { - it->second->takeChild(i); - this->addChild(child); - } - } - this->treeWidget()->expandItem(it->second); - } - // end of grouping style switch -# endif // set the text label std::string displayName = obj->Label.getValue(); it->second->setText(0, QString::fromUtf8(displayName.c_str())); @@ -948,11 +909,84 @@ void DocumentItem::slotActiveObject(const Gui::ViewProviderDocumentObject& obj) } } +void DocumentItem::slotHighlightObject (const Gui::ViewProviderDocumentObject& obj,const Gui::HighlightMode& high,bool set) +{ + + std::string objectName = obj.getObject()->getNameInDocument(); + std::map::iterator jt = ObjectMap.find(objectName); + if (jt == ObjectMap.end()) + return; // signal is emitted before the item gets created + + QFont f = jt->second->font(0); + switch (high) { + case Gui::Bold: f.setBold(set); break; + case Gui::Italic: f.setItalic(set); break; + case Gui::Underlined: f.setUnderline(set); break; + case Gui::Overlined: f.setOverline(set); break; + case Gui::Blue: + if(set) + jt->second->setBackgroundColor(0,QColor(200,200,255)); + else + jt->second->setData(0, Qt::BackgroundColorRole,QVariant()); + break; + default: + // not defined enum + assert(0); + } + jt->second->setFont(0,f); + +} + +void DocumentItem::slotExpandObject (const Gui::ViewProviderDocumentObject& obj,const Gui::TreeItemMode& mode) +{ + + std::string objectName = obj.getObject()->getNameInDocument(); + std::map::iterator jt = ObjectMap.find(objectName); + if (jt == ObjectMap.end()) + return; // signal is emitted before the item gets created + + switch (mode) { + case Gui::Expand: + jt->second->setExpanded(true); + break; + case Gui::Collaps: + jt->second->setExpanded(false); + break; + case Gui::Toggle: + if(jt->second->isExpanded()) + jt->second->setExpanded(false); + else + jt->second->setExpanded(true); + break; + + default: + // not defined enum + assert(0); + } + +} + + const Gui::Document* DocumentItem::document() const { return this->pDocument; } +//void DocumentItem::markItem(const App::DocumentObject* Obj,bool mark) +//{ +// // never call without Object! +// assert(Obj); +// +// +// std::map::iterator pos; +// pos = ObjectMap.find(Obj->getNameInDocument()); +// if (pos != ObjectMap.end()) { +// QFont f = pos->second->font(0); +// f.setUnderline(mark); +// pos->second->setFont(0,f); +// } +//} + void DocumentItem::testStatus(void) { for (std::map::iterator pos = ObjectMap.begin();pos!=ObjectMap.end();++pos) { diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index 478208ac4..4e616daa5 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -32,12 +32,28 @@ #include #include + namespace Gui { class ViewProviderDocumentObject; class DocumentObjectItem; class DocumentItem; +/// highlight modes for the tree items +enum HighlightMode { Underlined, + Italic , + Overlined , + Bold , + Blue +}; + +/// highlight modes for the tree items +enum TreeItemMode { Expand, + Collaps, + Toggle +}; + + /** Tree view that allows drag & drop of document objects. * @author Werner Mayer */ @@ -55,6 +71,8 @@ public: static const int DocumentType; static const int ObjectType; + void markItem(const App::DocumentObject* Obj,bool mark); + protected: /// Observer message from the Selection void onSelectionChanged(const SelectionChanges& msg); @@ -130,12 +148,14 @@ protected: /** Removes a view provider from the document item. * If this view provider is not added nothing happens. */ - void slotDeleteObject(const Gui::ViewProviderDocumentObject&); - void slotChangeObject(const Gui::ViewProviderDocumentObject&); - void slotRenameObject(const Gui::ViewProviderDocumentObject&); - void slotActiveObject(const Gui::ViewProviderDocumentObject&); - void slotInEdit (const Gui::ViewProviderDocumentObject&); - void slotResetEdit (const Gui::ViewProviderDocumentObject&); + void slotDeleteObject (const Gui::ViewProviderDocumentObject&); + void slotChangeObject (const Gui::ViewProviderDocumentObject&); + void slotRenameObject (const Gui::ViewProviderDocumentObject&); + void slotActiveObject (const Gui::ViewProviderDocumentObject&); + void slotInEdit (const Gui::ViewProviderDocumentObject&); + void slotResetEdit (const Gui::ViewProviderDocumentObject&); + void slotHighlightObject (const Gui::ViewProviderDocumentObject&,const Gui::HighlightMode&,bool); + void slotExpandObject (const Gui::ViewProviderDocumentObject&,const Gui::TreeItemMode&); private: const Gui::Document* pDocument; diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 630a743c9..6c9c207f4 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -113,6 +113,7 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, Qt::W // create the inventor widget and set the defaults #if !defined (NO_USE_QT_MDI_AREA) _viewer = new View3DInventorViewer(0); + _viewer->setDocument(this->_pcDocument); stack->addWidget(_viewer->getWidget()); setCentralWidget(stack); #else diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 9cc832e60..c3623c5fc 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -215,7 +215,7 @@ View3DInventorViewer::View3DInventorViewer (QWidget *parent, const char *name, // NOTE: For every mouse click event the SoFCUnifiedSelection searches for the picked // point which causes a certain slow-down because for all objects the primitives // must be created. Using an SoSeparator avoids this drawback. - Gui::SoFCUnifiedSelection* selectionRoot = new Gui::SoFCUnifiedSelection(); + selectionRoot = new Gui::SoFCUnifiedSelection(); selectionRoot->applySettings(); selectionRoot->viewer = this; #endif @@ -292,6 +292,12 @@ View3DInventorViewer::~View3DInventorViewer() Gui::Selection().Detach(this); } +void View3DInventorViewer::setDocument(Gui::Document *pcDocument) +{ + // write the document the viewer belongs to to the selection node + selectionRoot->pcDocument = pcDocument; +} + void View3DInventorViewer::initialize() { navigation = new CADNavigationStyle(); @@ -355,10 +361,9 @@ void View3DInventorViewer::removeViewProvider(ViewProvider* pcProvider) } + SbBool View3DInventorViewer::setEditingViewProvider(Gui::ViewProvider* p, int ModNum) { - if (_ViewProviderSet.find(p) == _ViewProviderSet.end()) - return false; if (this->editViewProvider) return false; // only one view provider is editable at a time bool ok = p->startEditing(ModNum); diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index a7b1593c1..47cb11de9 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -52,6 +52,8 @@ class ViewProvider; class SoFCBackgroundGradient; class NavigationStyle; class SoFCUnifiedSelection; +class Document; +class SoFCUnifiedSelection; /** The Inventor viewer * @@ -266,6 +268,8 @@ public: void setNavigationType(Base::Type); NavigationStyle* navigationStyle() const; + void setDocument(Gui::Document *pcDocument); + protected: virtual void actualRedraw(void); virtual void setSeekMode(SbBool enable); @@ -301,6 +305,7 @@ private: SoSeparator * pcViewProviderRoot; SoEventCallback* pEventCallback; NavigationStyle* navigation; + SoFCUnifiedSelection* selectionRoot; void initialize(); SbBool axiscrossEnabled; diff --git a/src/Gui/ViewProvider.cpp b/src/Gui/ViewProvider.cpp index b670ef4c6..e7ec6e4d6 100644 --- a/src/Gui/ViewProvider.cpp +++ b/src/Gui/ViewProvider.cpp @@ -139,6 +139,12 @@ void ViewProvider::setUpdatesEnabled (bool enable) _updateData = enable; } +void highlight(const HighlightMode& high) +{ + + +} + void ViewProvider::eventCallback(void * ud, SoEventCallback * node) { const SoEvent * ev = node->getEvent(); diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 05b22dbc9..2ad3a0b8a 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -54,9 +54,12 @@ namespace App { class Color; } +class SoGroup; + #include #include + namespace Gui { namespace TaskView { class TaskContent; @@ -66,6 +69,7 @@ class ViewProviderPy; class ObjectItem; + /** General interface for all visual stuff in FreeCAD * This class is used to generate and handle all around * visualizing and presenting objects from the FreeCAD @@ -90,8 +94,18 @@ public: SoSeparator* getAnnotation(void); // returns the root node of the Provider (3D) virtual SoSeparator* getFrontRoot(void) const {return 0;} + // returns the root node where the children gets collected(3D) + virtual SoGroup* getChildRoot(void) const {return 0;} // returns the root node of the Provider (3D) virtual SoSeparator* getBackRoot(void) const {return 0;} + /** deliver the children belonging to this object + * this method is used to deliver the objects to + * the 3DView which should be grouped under its + * scene graph. This affects the visibility and the 3D + * position of the object. + */ + virtual std::vector claimChildren3D(void) const + { return std::vector(); } /** @name Selection handling * This group of methodes do the selection handling. @@ -179,6 +193,7 @@ public: bool isVisible() const; //@} + /** @name Edit methods * if the Viewprovider goes in edit mode * you can handle most of the events in the viewer by yourself