1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 #include "ATOMICGUI_DataModel.h"
23 #include "ATOMICGUI_DataObject.h"
25 #include <LightApp_Study.h>
26 #include <SUIT_Tools.h>
27 #include <SUIT_DataObjectIterator.h>
28 #include <CAM_Module.h>
29 #include <CAM_Application.h>
31 #include <CAM_Module.h>
32 #include <CAM_Application.h>
43 const QString doc_name = "Atomic";
44 const QString doc_tag = "document";
45 const QString molecule_tag = "molecule";
46 const QString atom_tag = "atom";
47 const QString name_attr = "name";
48 const QString x_attr = "x";
49 const QString y_attr = "y";
50 const QString z_attr = "z";
53 ATOMICGUI_DataModel::ATOMICGUI_DataModel( CAM_Module* module )
54 : LightApp_DataModel( module ),
60 ATOMICGUI_DataModel::~ATOMICGUI_DataModel()
64 /*! Open Data Model. Build data structure from the given list of files. */
65 bool ATOMICGUI_DataModel::open( const QString& URL, CAM_Study* study, QStringList listOfFiles )
67 LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( study );
71 LightApp_DataModel::open( URL, aDoc, listOfFiles );
73 // The first list item contains path to a temporary
74 // directory, where the persistent files was placed
75 if ( listOfFiles.count() > 0 ) {
76 QString aTmpDir ( listOfFiles[0] );
78 // This module operates with a single persistent file
79 if ( listOfFiles.size() == 2 ) {
81 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + listOfFiles[1];
82 return importFile( aFullPath, aDoc );
89 /*! Save Data Model. Export data structure to temprorary files and return the list of files. */
90 bool ATOMICGUI_DataModel::save( QStringList& listOfFiles )
92 bool isMultiFile = false; // TODO: decide, how to access this parameter
94 LightApp_DataModel::save( listOfFiles );
96 LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
98 QString aTmpDir(study->GetTmpDir( myStudyURL.toLatin1(), isMultiFile ).c_str());
100 QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_ATOMICGUI.xml";
101 QString aFullPath = aTmpDir + aFileName;
102 bool ok = exportFile( aFullPath );
104 listOfFiles.append( aTmpDir );
105 listOfFiles.append( aFileName );
107 printf( " \n saved to %s\n ", aFullPath.toLatin1().data() );
112 /*! Save Data Model under given name. Export data structure to temprorary files and return the list of files. */
113 bool ATOMICGUI_DataModel::saveAs ( const QString& URL, CAM_Study* study, QStringList& listOfFiles )
116 return save( listOfFiles );
119 /*! Called on Study closure */
120 bool ATOMICGUI_DataModel::close()
124 return LightApp_DataModel::close();
127 /*! Called on Study creation */
128 bool ATOMICGUI_DataModel::create( CAM_Study* study )
133 /*! Default implementation, always returns false so as not to mask study's isModified() */
134 bool ATOMICGUI_DataModel::isModified() const
139 /*! Default implementation, always returns true so as not to mask study's isSaved() */
140 bool ATOMICGUI_DataModel::isSaved() const
145 /*! Called on update of the structure of Data Objects */
146 void ATOMICGUI_DataModel::build()
148 ATOMICGUI_ModuleObject* modelRoot = dynamic_cast<ATOMICGUI_ModuleObject*>( root() );
149 if( !modelRoot ) { // root is not set yet
150 modelRoot = new ATOMICGUI_ModuleObject( this, 0 );
151 setRoot( modelRoot );
154 // create 'molecule' objects under model root object and 'atom' objects under 'molecule'-s
155 for ( int i = 0; i < myMolecules.count(); i++ ) {
156 ATOMICGUI_DataObject* molObj = new ATOMICGUI_DataObject ( modelRoot, &myMolecules[i] );
157 for ( int j = 0; j < myMolecules[ i ].count(); j++ ) {
158 /*ATOMICGUI_DataObject* atomObj = */new ATOMICGUI_DataObject ( molObj, &myMolecules[i], j );
165 /*! Loads data from the XML file. */
166 bool ATOMICGUI_DataModel::importFile( const QString& fileName, CAM_Study* study )
172 QFile file( fileName );
173 if ( !file.open( QIODevice::ReadOnly ) )
178 res = doc.setContent( &file );
184 QDomElement root = doc.documentElement();
185 if ( root.isNull() || root.tagName() != doc_tag )
188 QDomNode molNode = root.firstChild();
189 while ( res && !molNode.isNull() ) {
190 res = molNode.isElement();
192 QDomElement molElem = molNode.toElement();
193 if ( molElem.tagName() == molecule_tag && molElem.hasAttribute( name_attr ) ) {
194 ATOMICGUI_AtomicMolecule aMol( molElem.attribute( name_attr ) );
195 QDomNode atomNode = molNode.firstChild();
196 while ( res && !atomNode.isNull() ) {
197 res = atomNode.isElement();
199 QDomElement atomElem = atomNode.toElement();
200 if ( atomElem.tagName() == atom_tag &&
201 atomElem.hasAttribute( name_attr ) &&
202 atomElem.hasAttribute( x_attr ) &&
203 atomElem.hasAttribute( y_attr ) &&
204 atomElem.hasAttribute( z_attr ) ) {
205 aMol.addAtom( atomElem.attribute( name_attr ),
206 atomElem.attribute( x_attr ).toDouble(),
207 atomElem.attribute( y_attr ).toDouble(),
208 atomElem.attribute( z_attr ).toDouble() );
214 res = atomNode.isComment();
216 atomNode = atomNode.nextSibling();
218 myMolecules.append( aMol );
224 res = molNode.isComment();
226 molNode = molNode.nextSibling();
234 /*! Saves data to the XML file */
235 bool ATOMICGUI_DataModel::exportFile( const QString& fileName )
241 QFile file( fileName );
242 if ( !file.open( QIODevice::WriteOnly ) )
245 QDomDocument doc( doc_name );
246 QDomElement root = doc.createElement( doc_tag );
247 doc.appendChild( root );
249 for ( int i = 0; i < myMolecules.count(); i++ ) {
250 QDomElement molecule = doc.createElement( molecule_tag );
251 molecule.setAttribute( name_attr, myMolecules[ i ].name() );
252 root.appendChild( molecule );
253 for ( int j = 0; j < myMolecules[ i ].count(); j++ ) {
254 QDomElement atom = doc.createElement( atom_tag );
255 atom.setAttribute( name_attr, myMolecules[ i ].atomName( j ) );
256 atom.setAttribute( x_attr, myMolecules[ i ].atomX( j ) );
257 atom.setAttribute( y_attr, myMolecules[ i ].atomY( j ) );
258 atom.setAttribute( z_attr, myMolecules[ i ].atomZ( j ) );
259 molecule.appendChild( atom );
263 QString docStr = doc.toString();
264 res = file.write( docStr.toLatin1(), docStr.length() ) == (int)docStr.length();
272 /*! Adds a new molecule to the data structure */
273 bool ATOMICGUI_DataModel::createMolecule ()
275 ATOMICGUI_AtomicMolecule mol;
277 // temporary code to add a few atoms to a molecule..
278 mol.addAtom( "atom_1", 0, 0, 0 );
279 mol.addAtom( "atom_2", 0, 0, 0 );
280 mol.addAtom( "atom_3", 0, 0, 0 );
281 // end of temporary code
283 myMolecules.append( mol );
290 /*! Adds a new atom to the given molecule */
291 bool ATOMICGUI_DataModel::addAtom( const QString& entry, const QString& atom,
292 const double x, const double y, const double z )
294 ATOMICGUI_DataObject* obj = findMolecule( entry );
295 if ( obj && obj->isMolecule() ) {
296 obj->molecule()->addAtom( atom, x, y, z );
301 /*! Rename the given (by entry) object */
302 bool ATOMICGUI_DataModel::renameObj( const QString& entry, const QString& name )
304 ATOMICGUI_DataObject* obj = findObject( entry );
306 if ( obj->isMolecule() || obj->isAtom() ) {
307 obj->molecule()->setName( name, obj->atomIndex() );
314 /*! Delete the given objects (list of entries) */
315 bool ATOMICGUI_DataModel::deleteObjs( const QStringList& entries )
317 QMap<QString, ATOMICGUI_DataObject*> cmap;
318 // first find all molecules
319 for ( int i = 0; i < entries.count(); i++ ) {
320 ATOMICGUI_DataObject* o = findObject( entries[i] );
321 if ( o && o->isMolecule() )
322 cmap[ entries[i] ] = o;
324 // then find all atoms
325 typedef QList<int> IntList;
326 QMap<ATOMICGUI_DataObject*, IntList> amap;
327 for ( int i = 0; i < entries.count(); i++ ) {
328 ATOMICGUI_DataObject* o = findObject( entries[i] );
329 if ( o && o->isAtom() ) {
330 ATOMICGUI_DataObject* c = dynamic_cast<ATOMICGUI_DataObject*>( o->parent() );
331 if ( !c || cmap.find( c->entry() ) == cmap.end() )
332 amap[ c ].append( o->atomIndex() );
335 // now perform deleting
337 QMap<QString, ATOMICGUI_DataObject*>::Iterator it;
338 for ( it = cmap.begin(); it != cmap.end(); ++it ) {
339 for ( int i = 0; i < myMolecules.count(); i++ ) {
340 if ( &myMolecules[ i ] == it.value()->molecule() ) {
341 myMolecules.removeAt( i );
347 QMap<ATOMICGUI_DataObject*, IntList>::Iterator it1;
348 for ( it1 = amap.begin(); it1 != amap.end(); ++it1 ) {
349 IntList indices = it1.value();
351 for ( int i = indices.count() - 1; i >= 0; i-- ) {
352 it1.key()->molecule()->deleteAtom( indices[i] );
359 /*! Returns the Data Object by entry */
360 ATOMICGUI_DataObject* ATOMICGUI_DataModel::findObject( const QString& entry )
362 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
363 ATOMICGUI_DataObject* obj = dynamic_cast<ATOMICGUI_DataObject*>( it.current() );
364 if ( obj && obj->entry() == entry )
370 /*! Returns the Data Object by entry. If object is an Atom, its parent Molecule is returned. */
371 ATOMICGUI_DataObject* ATOMICGUI_DataModel::findMolecule( const QString& entry )
373 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
374 ATOMICGUI_DataObject* obj = dynamic_cast<ATOMICGUI_DataObject*>( it.current() );
375 if ( obj && obj->entry() == entry ) {
376 if ( obj->isMolecule() )
378 else if ( obj->isAtom() )
379 return dynamic_cast<ATOMICGUI_DataObject*>( obj->parent() );