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 <LightApp_Study.h>
30 #include <SUIT_Tools.h>
31 #include <SUIT_DataObjectIterator.h>
32 #include <CAM_Module.h>
33 #include <CAM_Application.h>
41 //=================================================================================
42 // function : LIGHTGUI_DataModel()
43 // purpose : constructor
44 //=================================================================================
45 LIGHTGUI_DataModel::LIGHTGUI_DataModel ( CAM_Module* theModule )
46 : LightApp_DataModel( theModule ),
52 //=================================================================================
53 // function : ~LIGHTGUI_DataModel()
54 // purpose : destructor
55 //=================================================================================
56 LIGHTGUI_DataModel::~LIGHTGUI_DataModel()
60 //=================================================================================
62 // purpose : Open data model operation
63 //=================================================================================
64 bool LIGHTGUI_DataModel::open ( const QString& theURL, CAM_Study* study )
66 LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( study );
70 LightApp_DataModel::open( theURL, aDoc );
72 // Get list of files, created for this module by LightApp_Engine_i::Load().
73 std::vector<std::string> aListOfFiles = aDoc->GetListOfFiles();
75 // The first list item contains path to a temporary
76 // directory, where the persistent files was placed
77 if ( aListOfFiles.size() > 0 ) {
78 QString aTmpDir ( aListOfFiles[0] );
80 // This module operates with a single persistent file
81 if ( aListOfFiles.size() == 2 ) {
83 QString aFileName ( aListOfFiles[1] );
84 QString aFullPath = SUIT_Tools::addSlash( aTmpDir ) + aFileName;
86 loadFile( aFullPath, aDoc );
89 // Remove the files and temporary directory, created
90 // for this module by LightApp_Engine_i::Load()
91 bool isMultiFile = false; // TODO: decide, how to access this parameter
92 aDoc->RemoveTemporaryFiles( isMultiFile );
98 //=================================================================================
100 // purpose : Save data model operation
101 //=================================================================================
102 bool LIGHTGUI_DataModel::save()
104 // 1. Save data to temporary files
105 bool isMultiFile = false; // TODO: decide, how to access this parameter
107 LightApp_DataModel::save();
109 LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
111 QString aTmpDir = study->GetTmpDir( myStudyURL.latin1(), isMultiFile );
112 QString aFileName = SUIT_Tools::file( myStudyURL, false ) + "_LIGHTGUI.txt";
113 QString aFullPath = aTmpDir + aFileName;
114 dumpFile( aFullPath );
116 // 2. Set list of temporary files to Engine
117 std::vector<std::string> aListOfFiles ( 2 );
118 aListOfFiles[0] = aTmpDir.latin1();
119 aListOfFiles[1] = aFileName.latin1();
120 study->SetListOfFiles( aListOfFiles );
125 //=================================================================================
126 // function : saveAs()
127 // purpose : SaveAs data model operation
128 //=================================================================================
129 bool LIGHTGUI_DataModel::saveAs ( const QString& theURL, CAM_Study* )
135 //=================================================================================
136 // function : close()
137 // purpose : Close data model operation
138 //=================================================================================
139 bool LIGHTGUI_DataModel::close()
141 LightApp_DataModel::close();
145 //=================================================================================
146 // function : create()
147 // purpose : Create data model operation
148 //=================================================================================
149 bool LIGHTGUI_DataModel::create( CAM_Study* study )
151 buildTree( study->root(), QStringList() );
155 //=================================================================================
156 // function : isModified()
157 // purpose : default implementation, always returns false so as not to mask study's isModified()
158 //=================================================================================
159 bool LIGHTGUI_DataModel::isModified() const
164 //=================================================================================
165 // function : isSaved()
166 // purpose : default implementation, always returns true so as not to mask study's isSaved()
167 //=================================================================================
168 bool LIGHTGUI_DataModel::isSaved() const
173 //=================================================================================
174 // function : update()
175 // purpose : updates data model
176 //=================================================================================
177 void LIGHTGUI_DataModel::update ( LightApp_DataObject*, LightApp_Study* )
179 // Nothing to do here: we always keep the data tree in the up-to-date state
180 // The only goal of this method is to hide default behavior from LightApp_DataModel
184 //=================================================================================
185 // function : loadFile()
186 // purpose : loads text data from the file
187 //=================================================================================
188 bool LIGHTGUI_DataModel::loadFile ( const QString& theFileName, CAM_Study* study )
190 if ( theFileName.isEmpty() ) return false;
192 myFileName = theFileName;
195 QFile file ( myFileName );
196 if ( file.open( IO_ReadOnly ) ) {
197 QTextStream stream ( &file );
199 while ( !stream.eof() ) {
200 line = stream.readLine(); // line of text excluding '\n'
207 buildTree( study->root(), lines );
215 //=================================================================================
216 // function : dumpFile()
217 // purpose : saves text data to the file
218 //=================================================================================
219 bool LIGHTGUI_DataModel::dumpFile ( const QString& theFileName )
221 QString aFileName = theFileName;
222 if ( aFileName.isEmpty() )
223 aFileName = myFileName;
225 if ( aFileName.isEmpty() ) return false;
228 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
229 LIGHTGUI_DataObject* obj = dynamic_cast<LIGHTGUI_DataObject*>( it.current() );
230 if ( obj && obj->lineNb() > 0 )
231 lines.insert( lines.at( obj->lineNb()-1 ), obj->lineText() );
234 QFile file ( aFileName );
235 if ( file.open( IO_WriteOnly ) ) {
236 QTextStream stream ( &file );
237 QStringList::Iterator it = lines.begin();
238 for ( ; it != lines.end(); ++it ) {
239 stream << *it << "\n";
243 myFileName = aFileName;
250 //=================================================================================
251 // function : fileName()
252 // purpose : gets a name of text file previously loaded or saved
253 //=================================================================================
254 QString LIGHTGUI_DataModel::fileName () const
259 //=================================================================================
260 // function : getLineText()
261 // purpose : gets text from the given line
262 //=================================================================================
263 QString LIGHTGUI_DataModel::getLineText ( const int thePosition ) const
267 LIGHTGUI_DataObject* obj = findObject( thePosition );
269 aText = obj->lineText();
274 //=================================================================================
275 // function : setLineText()
276 // purpose : sets new text to the given line
277 //=================================================================================
278 bool LIGHTGUI_DataModel::setLineText ( const int thePosition, const QString& theText )
280 if ( thePosition <= 0 ) return false;
281 LIGHTGUI_DataObject* obj = findObject( thePosition );
283 if ( theText.stripWhiteSpace().isEmpty() && !obj->lineText().stripWhiteSpace().isEmpty() ||
284 !theText.stripWhiteSpace().isEmpty() && obj->lineText().stripWhiteSpace().isEmpty() ) {
285 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
286 // paragraph becomes a text line
287 SUIT_DataObject* newParent = obj->prevBrother();
289 obj->setParent( newParent );
290 while ( SUIT_DataObject* first = obj->firstChild() )
291 first->setParent( newParent );
295 // text line becomes a paragraph
296 SUIT_DataObject* parent = obj->parent();
297 SUIT_DataObject* modelRoot = parent ? parent->parent() : 0;
298 if ( modelRoot && parent ) {
299 int pos = parent->childPos( obj );
300 modelRoot->insertChild( obj, modelRoot->childPos( parent )+1 );
301 while ( SUIT_DataObject* next = parent->childObject( pos ) )
302 obj->appendChild( next );
306 obj->setLineText( theText );
312 //=================================================================================
313 // function : insertLineBefore()
314 // purpose : inserts the text line before the given one or appends a new line
315 //=================================================================================
316 bool LIGHTGUI_DataModel::insertLineBefore ( const int thePosition, const QString& theText )
318 // Insert new line before the item at thePosition in the list,
319 // or at the end() if thePosition is out of range
320 LIGHTGUI_ModuleObject* modelRoot = dynamic_cast<LIGHTGUI_ModuleObject*>( root() );
323 if ( thePosition > 0 ) {
324 LIGHTGUI_DataObject* obj = findObject( thePosition );
325 if ( !obj || !obj->parent() )
327 SUIT_DataObject* parent = obj->parent();
328 if ( theText.stripWhiteSpace().isEmpty() ) {
329 // insert new paragraph
330 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
331 int pos = modelRoot->childPos( obj );
332 modelRoot->insertChild( new LIGHTGUI_DataObject( theText, 0 ), pos );
335 int pos = parent->childPos( obj );
336 LIGHTGUI_DataObject* newObj = new LIGHTGUI_DataObject( theText, 0 );
337 modelRoot->insertChild( newObj, modelRoot->childPos( parent )+1 );
338 while ( SUIT_DataObject* next = parent->childObject( pos ) )
339 newObj->appendChild( next );
343 // insert new text line
344 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
345 SUIT_DataObject* prevParent = obj->prevBrother();
347 prevParent->appendChild( new LIGHTGUI_DataObject( theText, prevParent ) );
350 int pos = parent->childPos( obj );
351 parent->insertChild( new LIGHTGUI_DataObject( theText, 0 ), pos );
356 // append new paragraph/line
357 theText.stripWhiteSpace().isEmpty() ? new LIGHTGUI_DataObject( theText, modelRoot ) :
358 new LIGHTGUI_DataObject( theText, modelRoot->lastChild() );
363 //=================================================================================
364 // function : deleteTextLine()
365 // purpose : remove text line at the given position
366 //=================================================================================
367 bool LIGHTGUI_DataModel::deleteTextLine( const int thePosition )
369 LIGHTGUI_ModuleObject* modelRoot = dynamic_cast<LIGHTGUI_ModuleObject*>( root() );
372 if ( thePosition <= 0 )
374 LIGHTGUI_DataObject* obj = findObject( thePosition );
375 if ( !obj || !obj->parent() )
378 if ( obj->lineText().stripWhiteSpace().isEmpty() ) {
379 // if paragraph : put all child lines to the previous paragraph
380 SUIT_DataObject* newParent = obj->prevBrother();
382 while ( SUIT_DataObject* first = obj->firstChild() )
383 first->setParent( newParent );
386 obj->parent()->removeChild( obj );
390 //=================================================================================
391 // function : clearAll()
392 // purpose : removes all text lines
393 //=================================================================================
394 void LIGHTGUI_DataModel::clearAll()
396 buildTree( getStudy()->root(), QStringList() );
399 //=================================================================================
400 // function : buildTree()
401 // purpose : rebuilds data tree
402 //=================================================================================
403 void LIGHTGUI_DataModel::buildTree ( SUIT_DataObject* studyRoot, const QStringList& lines )
408 LIGHTGUI_ModuleObject* modelRoot = new LIGHTGUI_ModuleObject( this, studyRoot );
409 LIGHTGUI_DataObject* aParaObject;
410 LIGHTGUI_DataObject* aLineObject;
412 aParaObject = new LIGHTGUI_DataObject ( "", modelRoot );
414 QStringList::ConstIterator it1 = lines.begin(),
416 for ( ; it1 != it2; ++it1 ) {
417 if ( (*it1).stripWhiteSpace().isEmpty() ) {
418 aParaObject = new LIGHTGUI_DataObject ( *it1, modelRoot );
421 aLineObject = new LIGHTGUI_DataObject ( *it1, aParaObject );
425 modelRoot->setDataModel( this );
426 setRoot( modelRoot );
429 //=================================================================================
430 // function : findObject()
431 // purpose : finds a data object corresponding to the given line number
432 //=================================================================================
433 LIGHTGUI_DataObject* LIGHTGUI_DataModel::findObject( const int thePosition ) const
435 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
436 LIGHTGUI_DataObject* obj = dynamic_cast<LIGHTGUI_DataObject*>( it.current() );
437 if ( obj && obj->lineNb() == thePosition )