Salome HOME
d2d517977ff91341659cb330944400bcaf73a98a
[modules/gui.git] / src / Qtx / QtxWorkspaceAction.cxx
1 //  Copyright (C) 2007-2008  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 // File:      QtxWorkspaceAction.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxWorkspaceAction.h"
26
27 #include "QtxWorkspace.h"
28
29 #include <QMenu>
30 #include <QWidgetList>
31
32 /*!
33   \class QtxWorkspaceAction
34   \brief Implements actions group for menu Windows with standard operations, like
35          "Cascade", "Tile", "Tile Horizontally", etc.
36 */
37
38 /*!
39   \brief Constructor.
40   \param ws parent workspace
41   \param parent parent object (owner of the action)
42 */
43 QtxWorkspaceAction::QtxWorkspaceAction( QtxWorkspace* ws, QObject* parent )
44 : QtxActionSet( parent ),
45   myWorkspace( ws ),
46   myWindowsFlag( true )
47 {
48   insertAction( new QtxAction( tr( "Arranges the windows as overlapping tiles" ),
49                                tr( "Cascade" ), 0, this ), Cascade );
50   insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ),
51                                tr( "Tile" ), 0, this ), Tile );
52   insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ),
53                                tr( "Tile horizontally" ), 0, this ), HTile );
54   insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ),
55                                tr( "Tile vertically" ), 0, this ), VTile );
56
57   connect( this, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) );
58
59   setMenuActions( Standard );
60 }
61
62 /*!
63   \brief Destructor.
64 */
65 QtxWorkspaceAction::~QtxWorkspaceAction()
66 {
67 }
68
69 /*!
70   \brief Get workspace.
71   \return parent workspace
72 */
73 QtxWorkspace* QtxWorkspaceAction::workspace() const
74 {
75   return myWorkspace;
76 }
77
78 /*!
79   \brief Set actions to be visible in the menu.
80   
81   Actions, which IDs are set in \a flags parameter, will be shown in the 
82   menu bar. Other actions will not be shown.
83
84   \param flags ORed together actions flags
85 */
86 void QtxWorkspaceAction::setMenuActions( const int flags )
87 {
88   action( Cascade )->setVisible( flags & Cascade );
89   action( Tile )->setVisible( flags & Tile );
90   action( VTile )->setVisible( flags & VTile );
91   action( HTile )->setVisible( flags & HTile );
92   myWindowsFlag = flags & Windows;
93 }
94
95 /*!
96   \brief Get menu actions which are currently visible in the menu bar.
97   \return ORed together actions flags
98   \sa setMenuActions()
99 */
100 int QtxWorkspaceAction::menuActions() const
101 {
102   int ret = 0;
103   ret = ret | ( action( Cascade )->isVisible() ? Cascade : 0 );
104   ret = ret | ( action( Tile )->isVisible() ? Tile : 0 );
105   ret = ret | ( action( VTile )->isVisible() ? VTile : 0 );
106   ret = ret | ( action( HTile )->isVisible() ? HTile : 0 );
107   ret = ret | ( myWindowsFlag ? Windows : 0 );
108   return ret;
109 }
110
111 /*!
112   \brief Get keyboard accelerator for the specified action.
113   \param id menu action ID
114   \return keyboard accelerator of menu item or 0 if there is no such action
115 */
116 int QtxWorkspaceAction::accel( const int id ) const
117 {
118   int a = 0;
119   if ( action( id ) )
120     a = action( id )->shortcut();
121   return a;
122 }
123
124 /*!
125   \brief Get icon for the specified action.
126
127   If \a id is invalid, null icon is returned.
128
129   \param id menu action ID
130   \return menu item icon
131 */
132 QIcon QtxWorkspaceAction::icon( const int id ) const
133 {
134   QIcon ico;
135   if ( action( id ) )
136     ico = action( id )->icon();
137   return ico;
138 }
139
140 /*!
141   \brief Get menu item text for the specified action.
142   \param id menu action ID
143   \return menu item text or null QString if there is no such action
144 */
145 QString QtxWorkspaceAction::text( const int id ) const
146 {
147   QString txt;
148   if ( action( id ) )
149     txt = action( id )->text();
150   return txt;
151 }
152
153 /*!
154   \brief Get status bar tip for the specified action.
155   \param id menu action ID
156   \return status bar tip menu item or null QString if there is no such action
157 */
158 QString QtxWorkspaceAction::statusTip( const int id ) const
159 {
160   QString txt;
161   if ( action( id ) )
162     txt = action( id )->statusTip();
163   return txt;
164 }
165
166 /*!
167   \brief Set keyboard accelerator for the specified action.
168   \param id menu action ID
169   \param a new keyboard accelerator
170 */
171 void QtxWorkspaceAction::setAccel( const int id, const int a )
172 {
173   if ( action( id ) )
174     action( id )->setShortcut( a );
175 }
176
177 /*!
178   \brief Set menu item icon for the specified action.
179   \param id menu action ID
180   \param ico new menu item icon
181 */
182 void QtxWorkspaceAction::setIcon( const int id, const QIcon& icon )
183 {
184   if ( action( id ) )
185     action( id )->setIcon( icon );
186 }
187
188 /*!
189   \brief Set menu item text for the specified action.
190   \param id menu action ID
191   \param txt new menu item text
192 */
193 void QtxWorkspaceAction::setText( const int id, const QString& txt )
194 {
195   if ( action( id ) )
196     action( id )->setText( txt );
197 }
198
199 /*!
200   \brief Set menu item status bar tip for the specified action.
201   \param id menu action ID
202   \param txt new menu item status bar tip
203 */
204 void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt )
205 {
206   if ( action( id ) )
207     action( id )->setStatusTip( txt );
208 }
209
210 /*!
211   \brief Process action activated by the user.
212   \param type action ID
213 */
214 void QtxWorkspaceAction::perform( const int type )
215 {
216   switch ( type )
217   {
218   case Cascade:
219     cascade();
220     break;
221   case Tile:
222     tile();
223     break;
224   case VTile:
225     tileVertical();
226     break;
227   case HTile:
228     tileHorizontal();
229     break;
230   }
231 }
232
233 /*!
234   \brief Tile child windows in the workspace.
235 */
236 void QtxWorkspaceAction::tile()
237 {
238   QtxWorkspace* ws = workspace();
239   if ( ws )
240     ws->tile();
241 }
242
243 /*!
244   \brief Cascade child windows in the workspace.
245 */
246 void QtxWorkspaceAction::cascade()
247 {
248   QtxWorkspace* ws = workspace();
249   if ( !ws )
250     return;
251
252   ws->cascade();
253
254         int w = ws->width();
255         int h = ws->height();
256
257         QWidgetList winList = ws->windowList();
258   for ( QWidgetList::iterator it = winList.begin(); it != winList.end(); ++it )
259                 (*it)->resize( int( w * 0.8 ), int( h * 0.8 ) );
260 }
261
262 /*!
263   \brief Tile child windows in the workspace in the vertical direction.
264 */
265 void QtxWorkspaceAction::tileVertical()
266 {
267   QtxWorkspace* ws = workspace();
268   if ( ws )
269     ws->tileVertical();
270 }
271
272 /*!
273   \brief Tile child windows in the workspace in the horizontal direction.
274 */
275 void QtxWorkspaceAction::tileHorizontal()
276 {
277   QtxWorkspace* ws = workspace();
278   if ( ws )
279     ws->tileHorizontal();
280 }
281
282 /*!
283   \brief Called when action is added to the menu bar.
284   \param w menu bar widget this action is being added to
285 */
286 void QtxWorkspaceAction::addedTo( QWidget* w )
287 {
288   QtxActionSet::addedTo( w );
289
290   QMenu* pm = ::qobject_cast<QMenu*>( w );
291   if ( pm )
292     connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
293 }
294
295 /*!
296   \brief Called when action is removed from the menu bar.
297   \param w menu bar widget this action is being removed from
298 */
299 void QtxWorkspaceAction::removedFrom( QWidget* w )
300 {
301   QtxActionSet::removedFrom( w );
302
303   QMenu* pm = ::qobject_cast<QMenu*>( w );
304   if ( pm )
305     disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
306 }
307
308 /*!
309   \brief Update all menu action state.
310 */
311 void QtxWorkspaceAction::updateContent()
312 {
313   bool count = workspace() ? workspace()->windowList().count() : 0;
314   action( Cascade )->setEnabled( count );
315   action( Tile )->setEnabled( count );
316   action( HTile )->setEnabled( count );
317   action( VTile )->setEnabled( count );
318
319   updateWindows();
320 }
321
322 /*!
323   \brief Update actions which refer to the opened child windows.
324 */
325 void QtxWorkspaceAction::updateWindows()
326 {
327   QtxWorkspace* ws = workspace();
328   if ( !ws )
329     return;
330
331   QList<QAction*> lst = actions();
332   for ( QList<QAction*>::iterator it = lst.begin(); it != lst.end(); ++it )
333   {
334     int id = actionId( *it );
335     if ( id >= Windows )
336       removeAction( *it );
337   }
338
339   bool base = action( Cascade )->isVisible() || action( Tile )->isVisible() ||
340               action( HTile )->isVisible() || action( VTile )->isVisible();
341
342   QList<QAction*> items;
343   QMap<QAction*, int> map;
344   if ( menuActions() & Windows )
345   {
346     int index = 1;
347     QWidgetList wList = ws->windowList();
348     for ( QWidgetList::iterator it = wList.begin(); it != wList.end(); ++it, index++ )
349     {
350       QWidget* wid = *it;
351       QAction* a = new QtxAction( wid->windowTitle(), wid->windowTitle(), 0, this, true );
352       a->setChecked( wid == ws->activeWindow() );
353       items.append( a );
354       map.insert( a, Windows + index );
355     }
356
357     if ( base && !items.isEmpty() )
358     {
359       QAction* sep = new QtxAction( this );
360       sep->setSeparator( true );
361       items.prepend( sep );
362       map.insert( sep, Windows );
363     }
364   }
365
366   if ( !items.isEmpty() )
367     insertActions( items );
368
369   for ( QMap<QAction*, int>::const_iterator itr = map.begin(); itr != map.end(); ++itr )
370     setActionId( itr.key(), itr.value() );
371 }
372
373 /*!
374   \brief Called when parent menu is about to show.
375
376   Updates all menu items.
377 */
378 void QtxWorkspaceAction::onAboutToShow()
379 {
380   QMenu* pm = ::qobject_cast<QMenu*>( sender() );
381   if ( pm )
382     updateContent();
383 }
384
385 /*!
386   \brief Called when menu item corresponding to some child window is activated.
387
388   Activates correposponding child window.
389
390   \param idx menu item index
391 */
392 void QtxWorkspaceAction::activateItem( const int idx )
393 {
394   QtxWorkspace* ws = workspace();
395   if ( !ws )
396     return;
397
398   QWidgetList wList = ws->windowList();
399   if ( idx >= 0 && idx < (int)wList.count() )
400     wList.at( idx )->setFocus();
401 }
402
403 /*!
404   \brief Called when menu item is activated by the user.
405   
406   Perform the corresponding action.
407
408   \param id menu item identifier
409 */
410 void QtxWorkspaceAction::onTriggered( int id )
411 {
412   if ( id < Windows )
413     perform( id );
414   else
415     activateItem( id - Windows - 1 );
416 }