Salome HOME
Merge from V6_main 01/04/2013
[modules/gui.git] / src / CAF / CAF_Application.cxx
1 // Copyright (C) 2007-2013  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.
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_SequenceOfExtendedString.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() const
110 {
111   if ( stdApp().IsNull() )
112     return QString();
113
114   TColStd_SequenceOfExtendedString formats;
115   stdApp()->Formats( formats );
116
117   QStringList allWC;
118   QMap<QString, QStringList> wildCards;
119   Handle(Resource_Manager) resMgr = new Resource_Manager( stdApp()->ResourcesName() );
120   for ( int i = 1; i <= formats.Length(); i++ )
121   {
122     QString extension;
123     QString extResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".FileExtension" );
124     if ( resMgr->Find( extResStr.toLatin1().data() ) )
125       extension = QString( resMgr->Value( extResStr.toLatin1().data() ) );
126
127     QString descr;
128     QString descrResStr = CAF_Tools::toQString( formats.Value( i ) ) + QString( ".Description" );
129     if ( resMgr->Find( (char*)descrResStr.toLatin1().data() ) )
130       descr = QString( resMgr->Value( (char*)descrResStr.toLatin1().data() ) );
131
132     if ( !descr.isEmpty() && !extension.isEmpty() )
133     {
134       if ( !wildCards.contains( descr ) )
135         wildCards.insert( descr, QStringList() );
136       wildCards[descr].append( QString( "*.%1" ).arg( extension ) );
137       allWC.append( QString( "*.%1" ).arg( extension ) );
138     }
139   }
140
141   if ( wildCards.isEmpty() )
142     return QString();
143
144   QStringList filters;
145   for ( QMap<QString, QStringList>::ConstIterator it = wildCards.begin(); it != wildCards.end(); ++it )
146     filters.append( QString( "%1 (%2)" ).arg( it.key() ).arg( it.value().join( "; " ) ) );
147
148   if ( wildCards.count() > 1 )
149     filters.prepend( QString( "%1 (%2)" ).arg( tr( "INF_ALL_DOCUMENTS_FILTER" ) ).arg( allWC.join( "; " ) ) );
150
151   if ( !filters.isEmpty() )
152     filters.append( tr( "INF_ALL_FILTER" ) );
153
154   return filters.join( ";;" );
155 }
156
157 /*!
158   \brief Create menu and toolbars actions.
159 */
160 void CAF_Application::createActions()
161 {
162   STD_Application::createActions();
163
164   SUIT_Desktop* desk = desktop();
165   SUIT_ResourceMgr* resMgr = resourceMgr();
166
167   QtxListAction* editUndo = 
168     new QtxListAction( tr( "TOT_APP_EDIT_UNDO" ), 
169                        resMgr->loadPixmap( "STD", tr( "ICON_EDIT_UNDO" ) ),
170                        tr( "MEN_APP_EDIT_UNDO" ), Qt::CTRL+Qt::Key_Z, desk );
171   editUndo->setStatusTip( tr( "PRP_APP_EDIT_UNDO" ) );
172   registerAction( EditUndoId, editUndo );
173
174   QtxListAction* editRedo =
175     new QtxListAction( tr( "TOT_APP_EDIT_REDO" ), 
176                        resMgr->loadPixmap( "STD", tr( "ICON_EDIT_REDO" ) ),
177                        tr( "MEN_APP_EDIT_REDO" ), Qt::CTRL+Qt::Key_Y, desk );
178   editRedo->setStatusTip( tr( "PRP_APP_EDIT_REDO" ) );
179   registerAction( EditRedoId, editRedo );
180
181   editUndo->setComment( tr( "INF_APP_UNDOACTIONS" ) );
182   editRedo->setComment( tr( "INF_APP_REDOACTIONS" ) );
183
184   connect( editUndo, SIGNAL( triggered( int ) ), this, SLOT( onUndo( int ) ) );
185   connect( editRedo, SIGNAL( triggered( int ) ), this, SLOT( onRedo( int ) ) );
186
187   int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
188
189   createMenu( EditUndoId, editMenu, 0 );
190   createMenu( EditRedoId, editMenu, 0 );
191   createMenu( separator(), editMenu, -1, 0 );
192
193   int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
194
195   createTool( separator(), stdTBar );
196   createTool( EditUndoId, stdTBar );
197   createTool( EditRedoId, stdTBar );
198   createTool( separator(), stdTBar );
199 }
200
201 /*!
202   \brief Undo latest command operation for specified document.
203   \param doc OCAF document
204   \return \c true on success
205 */
206 bool CAF_Application::undo( CAF_Study* doc )
207 {
208   bool success = false;
209   if ( doc )
210   {
211     success = doc->undo();
212     if ( success )
213       doc->update();
214   }
215   return success;
216 }
217
218 /*!
219   \brief Redo latest command operation undo for specified document.
220   \param doc OCAF document
221   \return \c true on success
222 */
223 bool CAF_Application::redo(CAF_Study* doc)
224 {
225   bool success = false;
226   if ( doc )
227   {
228     success = doc->redo();
229     if ( success )
230       doc->update();
231   }
232   return success;
233 }
234
235 /*!
236   \brief Called when user activates "Undo" menu action.
237   
238   Undo operation on the active document.
239
240   \param numActions undo depth (number of commands)
241   \return \c true on success
242 */
243 bool CAF_Application::onUndo( int numActions )
244 {
245   bool ok = true;
246   while ( numActions > 0 )
247   {
248     CAF_Study* cafStudy = dynamic_cast<CAF_Study*>( activeStudy() );
249     if ( cafStudy )
250     {
251       if ( !undo( cafStudy ) )
252       {
253         ok = false;
254         break;
255       }
256       numActions--;
257     }
258   }
259   updateCommandsStatus();     /* enable/disable undo/redo */
260   return ok;
261 }
262
263 /*!
264   \brief Called when user activates "Redo" menu action.
265   
266   Redo latest undo commands on the active document.
267
268   \param numActions redo depth (number of commands)
269   \return \c true on success
270 */
271 bool CAF_Application::onRedo( int numActions )
272 {
273   bool ok = true;
274   while ( numActions > 0 )
275   {
276     CAF_Study* cafStudy = dynamic_cast<CAF_Study*>( activeStudy() );
277     if ( cafStudy )
278     {
279       if ( !redo( cafStudy ) )
280       {
281         ok = false;
282         break;
283       }
284       numActions--;
285     }
286   }
287   updateCommandsStatus();     /* enable/disable undo/redo */
288   return ok;
289 }
290
291 /*!
292   \brief Update actions state (Undo/Redo).
293 */
294 void CAF_Application::updateCommandsStatus()
295 {
296   STD_Application::updateCommandsStatus();
297
298   CAF_Study* cafStudy = 0;
299   if ( activeStudy() && activeStudy()->inherits( "CAF_Study" ) )
300     cafStudy = (CAF_Study*)activeStudy();
301
302   QtxListAction* undo = qobject_cast<QtxListAction*>( action( EditUndoId ) );
303   if ( cafStudy && undo )
304     undo->addNames( cafStudy->undoNames() );
305
306   QtxListAction* redo = qobject_cast<QtxListAction*>( action( EditRedoId ) );
307   if ( cafStudy && redo )
308     redo->addNames( cafStudy->redoNames() );
309
310   if ( undo )
311     undo->setEnabled( cafStudy && cafStudy->canUndo() );
312   if ( redo )
313     redo->setEnabled( cafStudy && cafStudy->canRedo() );
314 }
315
316 /*!
317   \brief Called when user activatees Help->About main menu command.
318 */
319 void CAF_Application::onHelpAbout()
320 {
321   SUIT_MessageBox::information( desktop(), tr( "About" ), tr( "ABOUT_INFO" ) );
322 }
323
324 /*!
325   \brief Create new empty study.
326   \return new study
327 */
328 SUIT_Study* CAF_Application::createNewStudy()
329 {
330   return new CAF_Study( this );
331 }
332
333 /*!
334   \brief Set OCAF application.
335   \param app new OCAF application
336 */
337 void CAF_Application::setStdApp( const Handle(TDocStd_Application)& app )
338 {
339   myStdApp = app;
340 }