]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxWorkstackAction.cxx
Salome HOME
3bc06761a33849f9d7b0c9521e9392a65f186806
[modules/gui.git] / src / Qtx / QtxWorkstackAction.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 // File:      QtxWorkstackAction.cxx
20 // Author:    Sergey TELKOV
21
22 #include "QtxWorkstackAction.h"
23
24 #include "QtxWorkstack.h"
25
26 #include <qpopupmenu.h>
27 #include <qwidgetlist.h>
28
29 /*!
30   Constructor
31 */
32 QtxWorkstackAction::QtxWorkstackAction( QtxWorkstack* ws, QObject* parent, const char* name )
33 : QtxAction( tr( "Controls windows into workstack" ), tr( "Workstack management" ), 0, parent, name ),
34 myFlags( Standard ),
35 myWorkstack( ws )
36 {
37   myItem.insert( VSplit, new QtxAction( tr( "Split the active window on two vertical parts" ),
38                                         tr( "Split vertically" ), 0, this, 0, false ) );
39   myItem.insert( HSplit, new QtxAction( tr( "Split the active window on two horizontal parts" ),
40                                         tr( "Split horizontally" ), 0, this, 0, false ) );
41
42   connect( myItem[VSplit], SIGNAL( activated() ), ws, SLOT( splitVertical() ) );
43   connect( myItem[HSplit], SIGNAL( activated() ), ws, SLOT( splitHorizontal() ) );
44 }
45
46 /*!
47   Destructor
48 */
49 QtxWorkstackAction::~QtxWorkstackAction()
50 {
51 }
52
53 /*!
54   \return corresponding workstack
55 */
56 QtxWorkstack* QtxWorkstackAction::workstack() const
57 {
58   return myWorkstack;
59 }
60
61 /*!
62   \return set of action flags
63 */
64 int QtxWorkstackAction::items() const
65 {
66   return myFlags;
67 }
68
69 /*!
70   Sets action flags
71   \param flags - new set of flags
72 */
73 void QtxWorkstackAction::setItems( const int flags )
74 {
75   if ( !flags || flags == myFlags || !( flags & Split ) )
76     return;
77
78   myFlags = flags;
79 }
80
81 /*!
82   \return true if action contains all flags
83   \param flags - new set of flags
84 */
85 bool QtxWorkstackAction::hasItems( const int flags ) const
86 {
87   return ( myFlags & flags ) == flags;
88 }
89
90 /*!
91   \return accelerator of item
92   \param id - item id
93 */
94 int QtxWorkstackAction::accel( const int id ) const
95 {
96   int a = 0;
97   if ( myItem.contains( id ) )
98     a = myItem[id]->accel();
99   return a;
100 }
101
102 /*!
103   \return icons of item
104   \param id - item id
105 */
106 QIconSet QtxWorkstackAction::iconSet( const int id ) const
107 {
108   QIconSet ico;
109   if ( myItem.contains( id ) )
110     ico = myItem[id]->iconSet();
111   return ico;
112 }
113
114 /*!
115   \return menu text of item
116   \param id - item id
117 */
118 QString QtxWorkstackAction::menuText( const int id ) const
119 {
120   QString txt;
121   if ( myItem.contains( id ) )
122     txt = myItem[id]->menuText();
123   return txt;
124 }
125
126 /*!
127   \return status tip of item
128   \param id - item id
129 */
130 QString QtxWorkstackAction::statusTip( const int id ) const
131 {
132   QString txt;
133   if ( myItem.contains( id ) )
134     txt = myItem[id]->statusTip();
135   return txt;
136 }
137
138 /*!
139   Changes accelerator of item
140   \param id - item id
141   \param a - new accelerator
142 */
143 void QtxWorkstackAction::setAccel( const int id, const int a )
144 {
145   if ( myItem.contains( id ) )
146     myItem[id]->setAccel( a );
147 }
148
149 /*!
150   Changes icons of item
151   \param id - item id
152   \param ico - new icons
153 */
154 void QtxWorkstackAction::setIconSet( const int id, const QIconSet& ico )
155 {
156   if ( myItem.contains( id ) )
157     myItem[id]->setIconSet( ico );
158 }
159
160 /*!
161   Changes menu text of item
162   \param id - item id
163   \param txt - new menu text
164 */
165 void QtxWorkstackAction::setMenuText( const int id, const QString& txt )
166 {
167   if ( myItem.contains( id ) )
168     myItem[id]->setMenuText( txt );
169 }
170
171 /*!
172   Changes status tip of item
173   \param id - item id
174   \param txt - new status tip
175 */
176 void QtxWorkstackAction::setStatusTip( const int id, const QString& txt )
177 {
178   if ( myItem.contains( id ) )
179     myItem[id]->setStatusTip( txt );
180 }
181
182 /*!
183   Adds action to widget
184   \param wid - widget
185 */
186 bool QtxWorkstackAction::addTo( QWidget* wid )
187 {
188   return addTo( wid, -1 );
189 }
190
191 /*!
192   Adds action to widget
193   \param wid - widget
194   \param idx - position
195 */
196 bool QtxWorkstackAction::addTo( QWidget* wid, const int idx )
197 {
198   if ( !wid || !wid->inherits( "QPopupMenu" ) )
199     return false;
200
201   QPopupMenu* pm = (QPopupMenu*)wid;
202   checkPopup( pm );
203
204   if ( myMenu.contains( pm ) )
205     return false;
206
207   myMenu.insert( pm, QIntList() );
208   fillPopup( pm, idx );
209
210   connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
211   connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
212
213   return true;
214 }
215
216 /*!
217   Removes action from widget
218   \param wid - widget
219 */
220 bool QtxWorkstackAction::removeFrom( QWidget* wid )
221 {
222   if ( !wid || !wid->inherits( "QPopupMenu" ) )
223     return false;
224
225   QPopupMenu* pm = (QPopupMenu*)wid;
226   if ( !myMenu.contains( pm ) )
227     return false;
228
229   clearPopup( pm );
230
231   disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
232   disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
233
234   myMenu.remove( pm );
235
236   return true;
237 }
238
239 /*!
240   Performs action
241   \param type - action type
242 */
243 void QtxWorkstackAction::perform( const int type )
244 {
245   switch ( type )
246   {
247   case VSplit:
248     workstack()->splitVertical();
249     break;
250   case HSplit:
251     workstack()->splitHorizontal();
252     break;
253   }
254 }
255
256 /*!
257   SLOT: called just before the popup menu is displayed, updates popup
258 */
259 void QtxWorkstackAction::onAboutToShow()
260 {
261   const QObject* obj = sender();
262   if ( !obj || !obj->inherits( "QPopupMenu" ) )
263     return;
264
265   QtxWorkstack* ws = workstack();
266   if ( ws && myItem.contains( VSplit ) )
267     myItem[VSplit]->setAccel( ws->accel( QtxWorkstack::SplitVertical ) );
268   if ( ws && myItem.contains( HSplit ) )
269     myItem[HSplit]->setAccel( ws->accel( QtxWorkstack::SplitHorizontal ) );
270
271   updatePopup( (QPopupMenu*)obj );
272 }
273
274 /*!
275   SLOT: called when popup menu is destroyed, removes it from menu
276 */
277 void QtxWorkstackAction::onPopupDestroyed( QObject* obj )
278 {
279   myMenu.remove( (QPopupMenu*)obj );
280 }
281
282 /*!
283   Updates popup
284   \param pm - popup menu
285 */
286 void QtxWorkstackAction::checkPopup( QPopupMenu* pm )
287 {
288   if ( !myMenu.contains( pm ) )
289     return;
290
291   QIntList updList;
292   for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it )
293   {
294     if ( pm->indexOf( *it ) != -1 )
295       updList.append( *it );
296   }
297
298   myMenu.remove( pm );
299
300   if ( !updList.isEmpty() )
301     myMenu.insert( pm, updList );
302   else
303   {
304     disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
305     disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
306   }
307 }
308
309 /*!
310   Clears and refills popup and updates state of actions
311   \param pm - popup menu
312 */
313 void QtxWorkstackAction::updatePopup( QPopupMenu* pm )
314 {
315   if ( !myMenu.contains( pm ) )
316     return;
317
318   fillPopup( pm, clearPopup( pm ) );
319
320   int count = workstack() ? workstack()->splitWindowList().count() : 0;
321   myItem[VSplit]->setEnabled( count > 1 );
322   myItem[HSplit]->setEnabled( count > 1 );
323 }
324
325 /*!
326   Clears popup
327   \param pm - popup menu
328 */
329 int QtxWorkstackAction::clearPopup( QPopupMenu* pm )
330 {
331   if ( !myMenu.contains( pm ) )
332     return -1;
333
334   int idx = -1;
335   const QIntList& lst = myMenu[pm];
336   for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it )
337     idx = pm->indexOf( *it );
338
339   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
340     mit.data()->removeFrom( pm );
341
342   for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
343     pm->removeItem( *itr );
344
345   return idx;
346 }
347
348 /*!
349   Fills popup with items
350   \param pm - popup menu
351   \param idx - position
352 */
353 void QtxWorkstackAction::fillPopup( QPopupMenu* pm, const int idx )
354 {
355   if ( !pm )
356     return;
357
358   int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx );
359
360   myMenu.insert( pm, QIntList() );
361   QIntList& lst = myMenu[pm];
362
363   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
364   {
365     if ( !hasItems( mit.key() ) )
366       continue;
367
368     mit.data()->addTo( pm, index );
369     lst.append( pm->idAt( index++ ) );
370   }
371
372   QtxWorkstack* ws = workstack();
373   if ( !ws || !hasItems( Windows ) )
374     return;
375
376   QWidgetList wList = ws->windowList();
377   if ( wList.isEmpty() )
378     return;
379
380   lst.append( pm->insertSeparator( index++ ) );
381
382   int param = 0;
383   pm->setCheckable( true );
384   for ( QWidgetListIt it( wList ); it.current(); ++it )
385   {
386     int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ );
387     pm->setItemParameter( id, param++ );
388     pm->setItemChecked( id, it.current() == ws->activeWindow() );
389     lst.append( id );
390   }
391 }
392
393 /*!
394   SLOT: called when popup item corresponding to window is activated, activates window
395 */
396 void QtxWorkstackAction::onItemActivated( int idx )
397 {
398   QtxWorkstack* ws = workstack();
399   if ( !ws )
400     return;
401
402   QWidgetList wList = ws->windowList();
403   if ( idx < 0 || idx >= (int)wList.count() )
404     return;
405
406   wList.at( idx )->setFocus();
407 }