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