Salome HOME
Merge master branch into V9_dev
[modules/gui.git] / src / CAM / CAM_Study.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "CAM_Study.h"
24
25 #include "CAM_DataModel.h"
26 #include "CAM_DataObject.h"
27 #include "CAM_Module.h"
28
29 /*!
30   \class CAM_Study
31   \brief Represents document object in the CAM application architecture.
32
33   For each loaded module study contains the data model instance reference.
34   Provides all necessary functionality for data models management.
35 */
36
37 /*!
38   \brief Constructor.
39   \param app parent application
40 */
41 CAM_Study::CAM_Study( SUIT_Application* app )
42 : SUIT_Study( app )
43 {
44 }
45
46 /*!
47   \brief Destructor.
48 */
49 CAM_Study::~CAM_Study()
50 {
51 }
52
53 /*!
54   \brief Called when study is closed.
55
56   Closes all data models.
57   
58   \param permanently if \c true close study permanently (not used in the base implemetation)
59 */
60 void CAM_Study::closeDocument( bool permanently )
61 {
62   for( QList<CAM_DataModel*>::const_iterator it = myDataModels.begin(); 
63        it != myDataModels.end(); ++it )
64     (*it)->close();
65
66   SUIT_Study::closeDocument( permanently );
67 }
68
69 /*!
70   \brief Append data model to the study.
71   \param dm data model being added
72   \return \c true on success and \c false on error
73 */
74 bool CAM_Study::appendDataModel( const CAM_DataModel* dm )
75 {
76   return insertDataModel( dm, myDataModels.count() );
77 }
78
79 /*!
80   \brief Insert data model \a dm after data model \a other
81   
82   If \a other is 0, the data model is added to the end of list.
83
84   \param dm data model being added
85   \param other data model to be previous in the list
86   \return \c true on success and \c false on error
87 */
88 bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const CAM_DataModel* other )
89 {
90   int idx = myDataModels.indexOf( (CAM_DataModel*)other );
91   return insertDataModel( dm, idx < 0 ? idx : idx + 1 );
92 }
93
94 /*!
95   \brief Insert data model \a dm with index \a idx.
96   
97   \param dm data model being added
98   \param idx data model required index
99   \return \c true on success and \c false on error
100 */
101 bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const int idx )
102 {
103   if ( !dm || myDataModels.indexOf( (CAM_DataModel*)dm ) != -1 )
104     return false;
105
106   int pos = idx < 0 ? myDataModels.count() : idx;
107   myDataModels.insert( qMin( pos, (int)myDataModels.count() ), (CAM_DataModel*)dm );
108
109   connect( dm, SIGNAL( rootChanged( const CAM_DataModel* ) ), SLOT( updateModelRoot( const CAM_DataModel* ) ) );
110
111   dataModelInserted( dm );
112
113   return true;
114 }
115
116 /*!
117   \brief Remove data model from the study.
118   \param dm data model being removed
119   \return \c true on success and \c false on error
120 */
121 bool CAM_Study::removeDataModel( const CAM_DataModel* dm )
122 {
123   if ( !dm )
124     return true;
125
126   CAM_ModuleObject* aModelRoot = dynamic_cast<CAM_ModuleObject*>( dm->root() );
127   if ( aModelRoot )
128     aModelRoot->setDataModel( 0 );
129
130   return myDataModels.removeAll( (CAM_DataModel*)dm );
131 }
132
133 /*!
134   \brief Check if data model is contained in the list.
135   \param dm data model
136   \return \c true if data model is in the list and \c false otherwise.
137 */
138 bool CAM_Study::containsDataModel( const CAM_DataModel* dm ) const
139 {
140   return myDataModels.contains( (CAM_DataModel*)dm );
141 }
142
143 /*!
144   \brief Get all data models.
145   \param lst returning list of data model.
146 */
147 void CAM_Study::dataModels( ModelList& lst ) const
148 {
149   lst.clear();
150   for( QList<CAM_DataModel*>::const_iterator it = myDataModels.begin(); 
151        it != myDataModels.end(); ++it )
152     lst.append( *it );
153 }
154
155 /*!
156   \brief Called when data model is inserted in the study.
157   
158   Open data model \a dModel, if it is saved and update data tree.
159
160   \param dModel data model
161 */
162 void CAM_Study::dataModelInserted( const CAM_DataModel* dModel )
163 {
164   CAM_DataModel* dm = (CAM_DataModel*)dModel;
165
166   if ( isSaved() ) // need to load data model from an existing file?
167     openDataModel( studyName(), dm );
168   else // no, just need to update data model's connection to study tree 
169        //(some application may want to show model's root in a study tree even if a model is empty)
170     dm->create( this );
171   updateModelRoot( dm );
172 }
173
174 /*!
175   \brief Called when data model is opened.
176
177   Base implementation does nothing and returns \c false.
178   
179   \return \c true on success and \c false on error
180 */
181 bool CAM_Study::openDataModel( const QString&, CAM_DataModel* )
182 {
183   return false;
184 }
185
186 /*!
187   \brief Called when data model is saved.
188
189   Base implementation does nothing and returns \c false.
190   
191   \return \c true on success and \c false on error
192 */
193 bool CAM_Study::saveDataModel( const QString&, CAM_DataModel* )
194 {
195   return false;
196 }
197
198 /*!
199   \brief Update data model root object.
200   \param dm data model being updated.
201 */
202 void CAM_Study::updateModelRoot( const CAM_DataModel* dm )
203 {
204   if ( !root() )
205     return;
206
207   DataObjectList childList;
208   root()->children( childList );
209   CAM_DataObject* curRoot = 0;
210   QString aName = dm->root() ? dm->root()->name() : dm->module()->moduleName();
211   int i = 0;
212   for ( int n = childList.count(); i < n; i++ ) {
213     if ( childList.at( i )->name() == aName ) {
214       curRoot = dynamic_cast<CAM_DataObject*>( childList.at( i ) );
215       break;
216     }
217   }
218
219   if ( curRoot == dm->root() )
220     return;
221
222   // replacing old data model root with a new one - old root deleted here !
223   if ( curRoot )
224     root()->replaceChild( curRoot, dm->root(), true );
225   else {
226     int idx = myDataModels.indexOf( (CAM_DataModel*)dm );
227     if ( idx != -1 )
228       root()->insertChild( dm->root(), idx );
229   }
230 }