1 // LIGHT : sample (no-corba-engine) SALOME module
3 // Copyright (C) 2003 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 // Author : Julia DOROVSKIKH
26 #include "LIGHTGUI_DataModel.h"
27 #include "LIGHTGUI_DataObject.h"
29 #include <SalomeApp_Study.h>
30 #include <SUIT_Tools.h>
31 #include <SUIT_DataObjectIterator.h>
36 //=================================================================================
37 // function : LIGHTGUI_DataModel()
38 // purpose : constructor
39 //=================================================================================
40 LIGHTGUI_DataModel::LIGHTGUI_DataModel ( CAM_Module* theModule )
41 : SalomeApp_DataModel( theModule ),
47 //=================================================================================
48 // function : ~LIGHTGUI_DataModel()
49 // purpose : destructor
50 //=================================================================================
51 LIGHTGUI_DataModel::~LIGHTGUI_DataModel()
55 //=================================================================================
57 // purpose : Open data model operation
58 //=================================================================================
59 bool LIGHTGUI_DataModel::open ( const QString& theURL, CAM_Study* study )
61 SalomeApp_Study* aDoc = dynamic_cast<SalomeApp_Study*>( study );
65 SalomeApp_DataModel::open( theURL, study );
67 // Get list of files, created for this module by SalomeApp_Engine_i::Load().
68 std::vector<std::string> aListOfFiles = GetListOfFiles();
70 // The first list item contains path to a temporary
71 // directory, where the persistent files was placed
72 if ( aListOfFiles.size() > 0 ) {
73 QString aTmpDir ( aListOfFiles[0] );
75 // This module operates with a single persistent file
76 if ( aListOfFiles.size() == 2 ) {
78 QString aFileName ( aListOfFiles[1] );
79 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + aFileName;
81 loadFile( aFullPath, study );
84 // Remove the files and temporary directory, created
85 // for this module by SalomeApp_Engine_i::Load()
86 bool isMultiFile = false; // TODO: decide, how to access this parameter
87 RemoveTemporaryFiles( isMultiFile );
93 //=================================================================================
95 // purpose : Save data model operation
96 //=================================================================================
97 bool LIGHTGUI_DataModel::save()
99 // 1. Save data to temporary files
100 bool isMultiFile = false; // TODO: decide, how to access this parameter
102 QString aTmpDir ( SalomeApp_DataModel::GetTmpDir( myStudyURL.latin1(), isMultiFile ) );
103 QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_LIGHTGUI.txt";
104 QString aFullPath = aTmpDir + aFileName;
105 dumpFile( aFullPath );
107 // 2. Set list of temporary files to Engine
108 std::vector<std::string> aListOfFiles ( 2 );
109 aListOfFiles[0] = aTmpDir.latin1();
110 aListOfFiles[1] = aFileName.latin1();
111 SetListOfFiles( aListOfFiles );
116 //=================================================================================
117 // function : saveAs()
118 // purpose : SaveAs data model operation
119 //=================================================================================
120 bool LIGHTGUI_DataModel::saveAs ( const QString& theURL, CAM_Study* )
126 //=================================================================================
127 // function : close()
128 // purpose : Close data model operation
129 //=================================================================================
130 bool LIGHTGUI_DataModel::close()
135 //=================================================================================
136 // function : create()
137 // purpose : Create data model operation
138 //=================================================================================
139 bool LIGHTGUI_DataModel::create( CAM_Study* study )
141 buildTree( study->root(), QStringList() );
145 //=================================================================================
146 // function : isModified()
147 // purpose : default implementation, always returns false so as not to mask study's isModified()
148 //=================================================================================
149 bool LIGHTGUI_DataModel::isModified() const
154 //=================================================================================
155 // function : isSaved()
156 // purpose : default implementation, always returns true so as not to mask study's isSaved()
157 //=================================================================================
158 bool LIGHTGUI_DataModel::isSaved() const
163 //=================================================================================
164 // function : update()
165 // purpose : updates data model
166 //=================================================================================
167 void LIGHTGUI_DataModel::update ( SalomeApp_DataObject*, SalomeApp_Study* )
169 // Nothing to do here: we always keep the data tree in the up-to-date state
170 // The only goal of this method is to hide default behavior from SalomApp_DataModel
174 //=================================================================================
175 // function : loadFile()
176 // purpose : loads text data from the file
177 //=================================================================================
178 bool LIGHTGUI_DataModel::loadFile ( const QString& theFileName, CAM_Study* study )
180 if ( theFileName.isEmpty() ) return false;
182 myFileName = theFileName;
185 QFile file ( myFileName );
186 if ( file.open( IO_ReadOnly ) ) {
187 QTextStream stream ( &file );
189 while ( !stream.eof() ) {
190 line = stream.readLine(); // line of text excluding '\n'
197 buildTree( study->root(), lines );
205 //=================================================================================
206 // function : dumpFile()
207 // purpose : saves text data to the file
208 //=================================================================================
209 bool LIGHTGUI_DataModel::dumpFile ( const QString& theFileName )
211 QString aFileName = theFileName;
212 if ( aFileName.isEmpty() )
213 aFileName = myFileName;
215 if ( aFileName.isEmpty() ) return false;
218 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
219 LIGHTGUI_DataObject* obj = dynamic_cast<LIGHTGUI_DataObject*>( it.current() );
220 if ( obj && obj->lineNb() > 0 )
221 lines.insert( lines.at( obj->lineNb()-1 ), obj->lineText() );
224 QFile file ( aFileName );
225 if ( file.open( IO_WriteOnly ) ) {
226 QTextStream stream ( &file );
227 QStringList::Iterator it = lines.begin();
228 for ( ; it != lines.end(); ++it ) {
229 stream << *it << "\n";
233 myFileName = aFileName;
240 //=================================================================================
241 // function : fileName()
242 // purpose : gets a name of text file previously loaded or saved
243 //=================================================================================
244 QString LIGHTGUI_DataModel::fileName () const
249 //=================================================================================
250 // function : getLineText()
251 // purpose : gets text from the given line
252 //=================================================================================
253 QString LIGHTGUI_DataModel::getLineText ( const int thePosition ) const
257 LIGHTGUI_DataObject* obj = findObject( thePosition );
259 aText = obj->lineText();
264 //=================================================================================
265 // function : setLineText()
266 // purpose : sets new text to the given line
267 //=================================================================================
268 bool LIGHTGUI_DataModel::setLineText ( const int thePosition, const QString& theText )
270 if ( thePosition <= 0 ) return false;
271 LIGHTGUI_DataObject* obj = findObject( thePosition );
273 if ( theText.stripWhiteSpace().isEmpty() && !obj->lineText().stripWhiteSpace().isEmpty() ||
274 !theText.stripWhiteSpace().isEmpty() && obj->lineText().stripWhiteSpace().isEmpty() ) {
275 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
276 // paragraph becomes a text line
277 SUIT_DataObject* newParent = obj->prevBrother();
279 obj->setParent( newParent );
280 while ( SUIT_DataObject* first = obj->firstChild() )
281 first->setParent( newParent );
285 // text line becomes a paragraph
286 SUIT_DataObject* parent = obj->parent();
287 SUIT_DataObject* modelRoot = parent ? parent->parent() : 0;
288 if ( modelRoot && parent ) {
289 int pos = parent->childPos( obj );
290 modelRoot->insertChild( obj, modelRoot->childPos( parent )+1 );
291 while ( SUIT_DataObject* next = parent->childObject( pos ) )
292 obj->appendChild( next );
296 obj->setLineText( theText );
302 //=================================================================================
303 // function : insertLineBefore()
304 // purpose : inserts the text line before the given one or appends a new line
305 //=================================================================================
306 bool LIGHTGUI_DataModel::insertLineBefore ( const int thePosition, const QString& theText )
308 // Insert new line before the item at thePosition in the list,
309 // or at the end() if thePosition is out of range
310 LIGHTGUI_ModuleObject* modelRoot = dynamic_cast<LIGHTGUI_ModuleObject*>( root() );
313 if ( thePosition > 0 ) {
314 LIGHTGUI_DataObject* obj = findObject( thePosition );
315 if ( !obj || !obj->parent() )
317 SUIT_DataObject* parent = obj->parent();
318 if ( theText.stripWhiteSpace().isEmpty() ) {
319 // insert new paragraph
320 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
321 int pos = modelRoot->childPos( obj );
322 modelRoot->insertChild( new LIGHTGUI_DataObject( theText, 0 ), pos );
325 int pos = parent->childPos( obj );
326 LIGHTGUI_DataObject* newObj = new LIGHTGUI_DataObject( theText, 0 );
327 modelRoot->insertChild( newObj, modelRoot->childPos( parent )+1 );
328 while ( SUIT_DataObject* next = parent->childObject( pos ) )
329 newObj->appendChild( next );
333 // insert new text line
334 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
335 SUIT_DataObject* prevParent = obj->prevBrother();
337 prevParent->appendChild( new LIGHTGUI_DataObject( theText, prevParent ) );
340 int pos = parent->childPos( obj );
341 parent->insertChild( new LIGHTGUI_DataObject( theText, 0 ), pos );
346 // append new paragraph/line
347 theText.stripWhiteSpace().isEmpty() ? new LIGHTGUI_DataObject( theText, modelRoot ) :
348 new LIGHTGUI_DataObject( theText, modelRoot->lastChild() );
353 //=================================================================================
354 // function : deleteTextLine()
355 // purpose : remove text line at the given position
356 //=================================================================================
357 bool LIGHTGUI_DataModel::deleteTextLine( const int thePosition )
359 LIGHTGUI_ModuleObject* modelRoot = dynamic_cast<LIGHTGUI_ModuleObject*>( root() );
362 if ( thePosition <= 0 )
364 LIGHTGUI_DataObject* obj = findObject( thePosition );
365 if ( !obj || !obj->parent() )
368 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
369 // if paragraph : put all child lines to the previous paragraph
370 SUIT_DataObject* newParent = obj->prevBrother();
372 while ( SUIT_DataObject* first = obj->firstChild() )
373 first->setParent( newParent );
376 obj->parent()->removeChild( obj );
380 //=================================================================================
381 // function : clearAll()
382 // purpose : removes all text lines
383 //=================================================================================
384 void LIGHTGUI_DataModel::clearAll()
386 buildTree( getStudy()->root(), QStringList() );
389 //=================================================================================
390 // function : buildTree()
391 // purpose : rebuilds data tree
392 //=================================================================================
393 void LIGHTGUI_DataModel::buildTree ( SUIT_DataObject* studyRoot, const QStringList& lines )
398 LIGHTGUI_ModuleObject* modelRoot = new LIGHTGUI_ModuleObject( this, studyRoot );
399 CAM_DataObject* aParaObject, aLineObject;
401 aParaObject = new LIGHTGUI_DataObject ( "", modelRoot );
403 QStringList::ConstIterator it1 = lines.begin(),
405 for ( ; it1 != it2; ++it1 ) {
406 if ( (*it1).stripWhiteSpace().isEmpty() ) {
407 aParaObject = new LIGHTGUI_DataObject ( *it1, modelRoot );
410 aLineObject = new LIGHTGUI_DataObject ( *it1, aParaObject );
414 modelRoot->setDataModel( this );
415 setRoot( modelRoot );
418 //=================================================================================
419 // function : findObject()
420 // purpose : finds a data object corresponding to the given line number
421 //=================================================================================
422 LIGHTGUI_DataObject* LIGHTGUI_DataModel::findObject( const int thePosition ) const
424 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
425 LIGHTGUI_DataObject* obj = dynamic_cast<LIGHTGUI_DataObject*>( it.current() );
426 if ( obj && obj->lineNb() == thePosition )