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