Salome HOME
Updated copyright comment
[modules/gui.git] / src / CAF / CAF_Application.cxx
1 // Copyright (C) 2007-2024  CEA, EDF, 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 "CAF_Application.h"
24
25 #include "CAF_Tools.h"
26 #include "CAF_Study.h"
27
28 #include <SUIT_Desktop.h>
29 #include <SUIT_MessageBox.h>
30 #include <SUIT_ResourceMgr.h>
31
32 #include <QtxAction.h>
33 #include <QtxListAction.h>
34
35 #include <QMap>
36 #include <QStringList>
37
38 #include <Resource_Manager.hxx>
39 #include <TColStd_SequenceOfAsciiString.hxx>
40
41 /*!
42   \brief Create new instance of CAF_Application.
43   \return new instance of CAF_Application class
44 */
45 extern "C" CAF_EXPORT SUIT_Application* createApplication()
46 {
47   return new CAF_Application();
48 }
49
50 /*!
51   \class CAF_Application
52   \brief OCC OCAF-based application.
53
54   Defines application configuration and behaviour for application using 
55   standard OCC OCAF data model. Allows using OCC OCAF serives
56   (for example, undo/redo mechanizm).
57 */
58
59 /*!
60   \brief Default constructor.
61 */
62 CAF_Application::CAF_Application()
63 : STD_Application()
64 {
65 }
66
67 /*!
68   \brief Constructor.
69   \param app OCAF application
70 */
71 CAF_Application::CAF_Application( const Handle( TDocStd_Application )& app )
72 : STD_Application(),
73   myStdApp( app )
74 {
75 }
76
77 /*!
78   \brief Destructor.
79 */
80 CAF_Application::~CAF_Application()
81 {
82 }
83
84 /*!
85   \brief Get application name.
86   \return application name
87 */
88 QString CAF_Application::applicationName() const
89 {
90   return QString( "CAFApplication" );
91 }
92
93 /*!
94   \brief Get OCAF application.
95   \return handle to OCAF application object
96 */
97 Handle( TDocStd_Application ) CAF_Application::stdApp() const
98 {
99   return myStdApp;
100 }
101
102 /*!
103   \brief Get file extension filter.
104
105   The file extension filter is used in Open/Save dialog boxes.
106
107   \return file filters for open/save document dialog box
108 */
109 QString CAF_Application::getFileFilter( bool open ) const
110 {
111   if ( stdApp().IsNull() )
112     return QString();
113
114   TColStd_SequenceOfAsciiString formats;
115   if ( open )
116     stdApp()->ReadingFormats( formats );
117   else
118     stdApp()->WritingFormats( formats );
119
120   QStringList allWC;
121   QMap<QString, QStringList> wildCards;
122   Handle(Resource_Manager) resMgr = new Resource_Manager( stdApp()->ResourcesName() );
123   for ( int i = 1; i <= formats.Length(); i++ )
124   {
125     QString extension;
126     QString extResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".FileExtension" );
127     if ( resMgr->Find( extResStr.toLatin1().data() ) )
128       extension = QString( resMgr->Value( extResStr.toLatin1().data() ) );
129
130     QString descr;
131     QString descrResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".Description" );
132     if ( resMgr->Find( (char*)descrResStr.toLatin1().data() ) )
133       descr = QString( resMgr->Value( (char*)descrResStr.toLatin1().data() ) );
134
135     if ( !descr.isEmpty() && !extension.isEmpty() )
136     {
137       if ( !wildCards.contains( descr ) )
138         wildCards.insert( descr, QStringList() );
139       wildCards[descr].append( QString( "*.%1" ).arg( extension ) );
140       allWC.append( QString( "*.%1" ).arg( extension ) );
141     }
142   }
143
144   if ( wildCards.isEmpty() )
145     return QString();
146
147   QStringList filters;
148   for ( QMap<QString, QStringList>::ConstIterator it = wildCards.begin(); it != wildCards.end(); ++it )
149     filters.append( QString( "%1 (%2)" ).arg( it.key() ).arg( it.value().join( "; " ) ) );
150
151   if ( wildCards.count() > 1 )
152     filters.prepend( QString( "%1 (%2)" ).arg( tr( "INF_ALL_DOCUMENTS_FILTER" ) ).arg( allWC.join( "; " ) ) );
153
154   if ( !filters.isEmpty() )
155     filters.append( tr( "INF_ALL_FILTER" ) );
156
157   return filters.join( ";;" );
158 }
159
160 /*!
161   \brief Create menu and toolbars actions.
162 */
163 void CAF_Application::createActions()
164 {
165   STD_Application::createActions();
166
167   SUIT_Desktop* desk = desktop();
168   SUIT_ResourceMgr* resMgr = resourceMgr();
169
170   QtxListAction* editUndo = 
171     new QtxListAction( tr( "TOT_APP_EDIT_UNDO" ), 
172                        resMgr->loadPixmap( "STD", tr( "ICON_EDIT_UNDO" ) ),
173                        tr( "MEN_APP_EDIT_UNDO" ), Qt::CTRL+Qt::Key_Z, desk );
174   editUndo->setStatusTip( tr( "PRP_APP_EDIT_UNDO" ) );
175   registerAction( EditUndoId, editUndo );
176
177   QtxListAction* editRedo =
178     new QtxListAction( tr( "TOT_APP_EDIT_REDO" ), 
179                        resMgr->loadPixmap( "STD", tr( "ICON_EDIT_REDO" ) ),
180                        tr( "MEN_APP_EDIT_REDO" ), Qt::CTRL+Qt::Key_Y, desk );
181   editRedo->setStatusTip( tr( "PRP_APP_EDIT_REDO" ) );
182   registerAction( EditRedoId, editRedo );
183
184   editUndo->setComment( tr( "INF_APP_UNDOACTIONS" ) );
185   editRedo->setComment( tr( "INF_APP_REDOACTIONS" ) );
186
187   connect( editUndo, SIGNAL( triggered( int ) ), this, SLOT( onUndo( int ) ) );
188   connect( editRedo, SIGNAL( triggered( int ) ), this, SLOT( onRedo( int ) ) );
189
190   int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
191
192   createMenu( EditUndoId, editMenu, 0 );
193   createMenu( EditRedoId, editMenu, 0 );
194   createMenu( separator(), editMenu, -1, 0 );
195
196   int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ),   // title (language-dependant)
197                             QString( "SalomeStandard" ) );       // name (language-independant)
198
199   createTool( separator(), stdTBar );
200   createTool( EditUndoId, stdTBar );
201   createTool( EditRedoId, stdTBar );
202   createTool( separator(), stdTBar );
203 }
204
205 /*!
206   \brief Undo latest command operation for specified document.
207   \param doc OCAF document
208   \return \c true on success
209 */
210 bool CAF_Application::undo( CAF_Study* doc )
211 {
212   bool success = false;
213   if ( doc )
214   {
215     success = doc->undo();
216     if ( success )
217       doc->update();
218   }
219   return success;
220 }
221
222 /*!
223   \brief Redo latest command operation undo for specified document.
224   \param doc OCAF document
225   \return \c true on success
226 */
227 bool CAF_Application::redo(CAF_Study* doc)
228 {
229   bool success = false;
230   if ( doc )
231   {
232     success = doc->redo();
233     if ( success )
234       doc->update();
235   }
236   return success;
237 }
238
239 /*!
240   \brief Called when user activates "Undo" menu action.
241   
242   Undo operation on the active document.
243
244   \param numActions undo depth (number of commands)
245   \return \c true on success
246 */
247 bool CAF_Application::onUndo( int numActions )
248 {
249   bool ok = true;
250   while ( numActions > 0 )
251   {
252     CAF_Study* cafStudy = dynamic_cast<CAF_Study*>( activeStudy() );
253     if ( cafStudy )
254     {
255       if ( !undo( cafStudy ) )
256       {
257         ok = false;
258         break;
259       }
260       numActions--;
261     }
262   }
263   updateCommandsStatus();     /* enable/disable undo/redo */
264   return ok;
265 }
266
267 /*!
268   \brief Called when user activates "Redo" menu action.
269   
270   Redo latest undo commands on the active document.
271
272   \param numActions redo depth (number of commands)
273   \return \c true on success
274 */
275 bool CAF_Application::onRedo( int numActions )
276 {
277   bool ok = true;
278   while ( numActions > 0 )
279   {
280     CAF_Study* cafStudy = dynamic_cast<CAF_Study*>( activeStudy() );
281     if ( cafStudy )
282     {
283       if ( !redo( cafStudy ) )
284       {
285         ok = false;
286         break;
287       }
288       numActions--;
289     }
290   }
291   updateCommandsStatus();     /* enable/disable undo/redo */
292   return ok;
293 }
294
295 /*!
296   \brief Update actions state (Undo/Redo).
297 */
298 void CAF_Application::updateCommandsStatus()
299 {
300   STD_Application::updateCommandsStatus();
301
302   CAF_Study* cafStudy = 0;
303   if ( activeStudy() && activeStudy()->inherits( "CAF_Study" ) )
304     cafStudy = (CAF_Study*)activeStudy();
305
306   QtxListAction* undo = qobject_cast<QtxListAction*>( action( EditUndoId ) );
307   if ( cafStudy && undo )
308     undo->addNames( cafStudy->undoNames() );
309
310   QtxListAction* redo = qobject_cast<QtxListAction*>( action( EditRedoId ) );
311   if ( cafStudy && redo )
312     redo->addNames( cafStudy->redoNames() );
313
314   if ( undo )
315     undo->setEnabled( cafStudy && cafStudy->canUndo() );
316   if ( redo )
317     redo->setEnabled( cafStudy && cafStudy->canRedo() );
318 }
319
320 /*!
321   \brief Called when user activatees Help->About main menu command.
322 */
323 void CAF_Application::onHelpAbout()
324 {
325   SUIT_MessageBox::information( desktop(), tr( "About" ), tr( "ABOUT_INFO" ) );
326 }
327
328 /*!
329   \brief Create new empty study.
330   \return new study
331 */
332 SUIT_Study* CAF_Application::createNewStudy()
333 {
334   return new CAF_Study( this );
335 }
336
337 /*!
338   \brief Set OCAF application.
339   \param app new OCAF application
340 */
341 void CAF_Application::setStdApp( const Handle(TDocStd_Application)& app )
342 {
343   myStdApp = app;
344 }