00001 /*************************************************************************** 00002 * Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> * 00003 * * 00004 * This file is part of the FreeCAD CAx development system. * 00005 * * 00006 * This library is free software; you can redistribute it and/or * 00007 * modify it under the terms of the GNU Library General Public * 00008 * License as published by the Free Software Foundation; either * 00009 * version 2 of the License, or (at your option) any later version. * 00010 * * 00011 * This library is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU Library General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Library General Public * 00017 * License along with this library; see the file COPYING.LIB. If not, * 00018 * write to the Free Software Foundation, Inc., 59 Temple Place, * 00019 * Suite 330, Boston, MA 02111-1307, USA * 00020 * * 00021 ***************************************************************************/ 00022 00023 00024 #include "PreCompiled.h" 00025 00026 #ifndef _PreComp_ 00027 # include <qpixmap.h> 00028 # include <Inventor/actions/SoSearchAction.h> 00029 # include <Inventor/nodes/SoDrawStyle.h> 00030 # include <Inventor/nodes/SoMaterial.h> 00031 # include <Inventor/nodes/SoSeparator.h> 00032 #endif 00033 00035 #include <Base/Console.h> 00036 #include <App/Material.h> 00037 #include <App/DocumentObject.h> 00038 #include "Application.h" 00039 #include "Document.h" 00040 #include "Selection.h" 00041 #include "MDIView.h" 00042 #include "TaskView/TaskAppearance.h" 00043 #include "ViewProviderDocumentObject.h" 00044 #include "ViewProviderDocumentObjectPy.h" 00045 00046 00047 using namespace Gui; 00048 00049 00050 PROPERTY_SOURCE(Gui::ViewProviderDocumentObject, Gui::ViewProvider) 00051 00052 ViewProviderDocumentObject::ViewProviderDocumentObject() 00053 : pcObject(0) 00054 { 00055 ADD_PROPERTY(DisplayMode,((long)0)); 00056 ADD_PROPERTY(Visibility,(true)); 00057 00058 sPixmap = "Feature"; 00059 } 00060 00061 00062 ViewProviderDocumentObject::~ViewProviderDocumentObject() 00063 { 00064 // Make sure that the property class does not destruct our string list 00065 DisplayMode.setEnums(0); 00066 } 00067 00068 void ViewProviderDocumentObject::getTaskViewContent(std::vector<Gui::TaskView::TaskContent*>& vec) const 00069 { 00070 vec.push_back(new Gui::TaskView::TaskAppearance()); 00071 } 00072 00073 void ViewProviderDocumentObject::startRestoring() 00074 { 00075 } 00076 00077 void ViewProviderDocumentObject::finishRestoring() 00078 { 00079 } 00080 00081 void ViewProviderDocumentObject::onChanged(const App::Property* prop) 00082 { 00083 if (prop == &DisplayMode) { 00084 setActiveMode(); 00085 } 00086 else if (prop == &Visibility) { 00087 // use this bit to check whether show() or hide() must be called 00088 if (Visibility.StatusBits.test(8) == false) { 00089 Visibility.StatusBits.set(8); 00090 Visibility.getValue() ? show() : hide(); 00091 Visibility.StatusBits.reset(8); 00092 } 00093 } 00094 00095 ViewProvider::onChanged(prop); 00096 } 00097 00098 void ViewProviderDocumentObject::hide(void) 00099 { 00100 // use this bit to check whether 'Visibility' must be adjusted 00101 if (Visibility.StatusBits.test(8) == false) { 00102 Visibility.StatusBits.set(8); 00103 Visibility.setValue(false); 00104 Visibility.StatusBits.reset(8); 00105 } 00106 ViewProvider::hide(); 00107 } 00108 00109 void ViewProviderDocumentObject::show(void) 00110 { 00111 // use this bit to check whether 'Visibility' must be adjusted 00112 if (Visibility.StatusBits.test(8) == false) { 00113 Visibility.StatusBits.set(8); 00114 Visibility.setValue(true); 00115 Visibility.StatusBits.reset(8); 00116 } 00117 ViewProvider::show(); 00118 } 00119 00120 void ViewProviderDocumentObject::updateView() 00121 { 00122 std::map<std::string, App::Property*> Map; 00123 pcObject->getPropertyMap(Map); 00124 00125 // Hide the object temporarily to speed up the update 00126 bool vis = ViewProvider::isShow(); 00127 if (vis) ViewProvider::hide(); 00128 for (std::map<std::string, App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it) { 00129 updateData(it->second); 00130 } 00131 if (vis) ViewProvider::show(); 00132 } 00133 00134 void ViewProviderDocumentObject::attach(App::DocumentObject *pcObj) 00135 { 00136 // save Object pointer 00137 pcObject = pcObj; 00138 00139 // Retrieve the supported display modes of the view provider 00140 aDisplayModesArray = this->getDisplayModes(); 00141 00142 if( aDisplayModesArray.empty() ) 00143 aDisplayModesArray.push_back(""); 00144 00145 // We must collect the const char* of the strings and give it to PropertyEnumeration, 00146 // but we are still responsible for them, i.e. the property class must not delete the literals. 00147 for ( std::vector<std::string>::iterator it = aDisplayModesArray.begin(); it != aDisplayModesArray.end(); ++it ) { 00148 aDisplayEnumsArray.push_back( it->c_str() ); 00149 } 00150 aDisplayEnumsArray.push_back(0); // null termination 00151 DisplayMode.setEnums(&(aDisplayEnumsArray[0])); 00152 00153 // set the active mode 00154 const char* defmode = this->getDefaultDisplayMode(); 00155 if (defmode) 00156 DisplayMode.setValue(defmode); 00157 } 00158 00159 Gui::MDIView* ViewProviderDocumentObject::getActiveView() const 00160 { 00161 App::Document* pAppDoc = pcObject->getDocument(); 00162 Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); 00163 return pGuiDoc->getActiveView(); 00164 } 00165 00166 SoNode* ViewProviderDocumentObject::findFrontRootOfType(const SoType& type) const 00167 { 00168 // first get the document this object is part of and get its GUI counterpart 00169 App::Document* pAppDoc = pcObject->getDocument(); 00170 Gui::Document* pGuiDoc = Gui::Application::Instance->getDocument(pAppDoc); 00171 00172 SoSearchAction searchAction; 00173 searchAction.setType(type); 00174 searchAction.setInterest(SoSearchAction::FIRST); 00175 00176 // search in all view providers for the node type 00177 std::vector<App::DocumentObject*> obj = pAppDoc->getObjects(); 00178 for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) { 00179 const ViewProvider* vp = pGuiDoc->getViewProvider(*it); 00180 // Ignore 'this' view provider. It could also happen that vp is 0, e.g. when 00181 // several objects have been added to the App::Document before notifying the 00182 // Gui::Document 00183 if (!vp || vp == this) 00184 continue; 00185 SoSeparator* front = vp->getFrontRoot(); 00186 //if (front && front->getTypeId() == type) 00187 // return front; 00188 if (front) { 00189 searchAction.apply(front); 00190 SoPath* path = searchAction.getPath(); 00191 if (path) 00192 return path->getTail(); 00193 } 00194 } 00195 00196 return 0; 00197 } 00198 00199 void ViewProviderDocumentObject::setActiveMode() 00200 { 00201 if (DisplayMode.getEnums()) { 00202 const char* mode = DisplayMode.getValueAsString(); 00203 if (mode) 00204 setDisplayMode(mode); 00205 } 00206 if (!Visibility.getValue()) 00207 ViewProvider::hide(); 00208 } 00209 00210 const char* ViewProviderDocumentObject::getDefaultDisplayMode() const 00211 { 00212 // We use the first item then 00213 return 0; 00214 } 00215 00216 std::vector<std::string> ViewProviderDocumentObject::getDisplayModes(void) const 00217 { 00218 // empty 00219 return std::vector<std::string>(); 00220 } 00221 00222 PyObject* ViewProviderDocumentObject::getPyObject() 00223 { 00224 if (!pyViewObject) 00225 pyViewObject = new ViewProviderDocumentObjectPy(this); 00226 pyViewObject->IncRef(); 00227 return pyViewObject; 00228 }