Salome HOME
6773afdc242887b03999f1ccb475b248bab643cb
[modules/gui.git] / src / Qtx / QtxWorkstackAction.cxx
1 // File:      QtxWorkstackAction.cxx
2 // Author:    Sergey TELKOV
3
4 #include "QtxWorkstackAction.h"
5
6 #include "QtxWorkstack.h"
7
8 #include <qpopupmenu.h>
9 #include <qwidgetlist.h>
10
11 QtxWorkstackAction::QtxWorkstackAction( QtxWorkstack* ws, QObject* parent, const char* name )
12 : QtxAction( tr( "Controls windows into workstack" ), tr( "Workstack management" ), 0, parent, name ),
13 myFlags( Standard ),
14 myWorkstack( ws )
15 {
16   myItem.insert( VSplit, new QtxAction( tr( "Split the active window on two vertical parts" ),
17                                         tr( "Split vertically" ), 0, this, 0, false ) );
18   myItem.insert( HSplit, new QtxAction( tr( "Split the active window on two horizontal parts" ),
19                                         tr( "Split horizontally" ), 0, this, 0, false ) );
20
21   connect( myItem[VSplit], SIGNAL( activated() ), ws, SLOT( splitVertical() ) );
22   connect( myItem[HSplit], SIGNAL( activated() ), ws, SLOT( splitHorizontal() ) );
23 }
24
25 QtxWorkstackAction::~QtxWorkstackAction()
26 {
27 }
28
29 QtxWorkstack* QtxWorkstackAction::workstack() const
30 {
31   return myWorkstack;
32 }
33
34 int QtxWorkstackAction::items() const
35 {
36   return myFlags;
37 }
38
39 void QtxWorkstackAction::setItems( const int flags )
40 {
41   if ( !flags || flags == myFlags || !( flags & Split ) )
42     return;
43
44   myFlags = flags;
45 }
46
47 bool QtxWorkstackAction::hasItems( const int flags ) const
48 {
49   return ( myFlags & flags ) == flags;
50 }
51
52 int QtxWorkstackAction::accel( const int id ) const
53 {
54   int a = 0;
55   if ( myItem.contains( id ) )
56     a = myItem[id]->accel();
57   return a;
58 }
59
60 QIconSet QtxWorkstackAction::iconSet( const int id ) const
61 {
62   QIconSet ico;
63   if ( myItem.contains( id ) )
64     ico = myItem[id]->iconSet();
65   return ico;
66 }
67
68 QString QtxWorkstackAction::menuText( const int id ) const
69 {
70   QString txt;
71   if ( myItem.contains( id ) )
72     txt = myItem[id]->menuText();
73   return txt;
74 }
75
76 QString QtxWorkstackAction::statusTip( const int id ) const
77 {
78   QString txt;
79   if ( myItem.contains( id ) )
80     txt = myItem[id]->statusTip();
81   return txt;
82 }
83
84 void QtxWorkstackAction::setAccel( const int id, const int a )
85 {
86   if ( myItem.contains( id ) )
87     myItem[id]->setAccel( a );
88 }
89
90 void QtxWorkstackAction::setIconSet( const int id, const QIconSet& ico )
91 {
92   if ( myItem.contains( id ) )
93     myItem[id]->setIconSet( ico );
94 }
95
96 void QtxWorkstackAction::setMenuText( const int id, const QString& txt )
97 {
98   if ( myItem.contains( id ) )
99     myItem[id]->setMenuText( txt );
100 }
101
102 void QtxWorkstackAction::setStatusTip( const int id, const QString& txt )
103 {
104   if ( myItem.contains( id ) )
105     myItem[id]->setStatusTip( txt );
106 }
107
108 bool QtxWorkstackAction::addTo( QWidget* wid )
109 {
110   return addTo( wid, -1 );
111 }
112
113 bool QtxWorkstackAction::addTo( QWidget* wid, const int idx )
114 {
115   if ( !wid || !wid->inherits( "QPopupMenu" ) )
116     return false;
117
118   QPopupMenu* pm = (QPopupMenu*)wid;
119   checkPopup( pm );
120
121   if ( myMenu.contains( pm ) )
122     return false;
123
124   myMenu.insert( pm, QIntList() );
125   fillPopup( pm, idx );
126
127   connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
128   connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
129
130   return true;
131 }
132
133 bool QtxWorkstackAction::removeFrom( QWidget* wid )
134 {
135   if ( !wid || !wid->inherits( "QPopupMenu" ) )
136     return false;
137
138   QPopupMenu* pm = (QPopupMenu*)wid;
139   if ( !myMenu.contains( pm ) )
140     return false;
141
142   clearPopup( pm );
143
144   disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
145   disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
146
147   myMenu.remove( pm );
148
149   return true;
150 }
151
152 void QtxWorkstackAction::perform( const int type )
153 {
154   switch ( type )
155   {
156   case VSplit:
157     workstack()->splitVertical();
158     break;
159   case HSplit:
160     workstack()->splitHorizontal();
161     break;
162   }
163 }
164
165 void QtxWorkstackAction::onAboutToShow()
166 {
167   const QObject* obj = sender();
168   if ( !obj || !obj->inherits( "QPopupMenu" ) )
169     return;
170
171   QtxWorkstack* ws = workstack();
172   if ( ws && myItem.contains( VSplit ) )
173     myItem[VSplit]->setAccel( ws->accel( QtxWorkstack::SplitVertical ) );
174   if ( ws && myItem.contains( HSplit ) )
175     myItem[HSplit]->setAccel( ws->accel( QtxWorkstack::SplitHorizontal ) );
176
177   updatePopup( (QPopupMenu*)obj );
178 }
179
180 void QtxWorkstackAction::onPopupDestroyed( QObject* obj )
181 {
182   myMenu.remove( (QPopupMenu*)obj );
183 }
184
185 void QtxWorkstackAction::checkPopup( QPopupMenu* pm )
186 {
187   if ( !myMenu.contains( pm ) )
188     return;
189
190   QIntList updList;
191   for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it )
192   {
193     if ( pm->indexOf( *it ) != -1 )
194       updList.append( *it );
195   }
196
197   myMenu.remove( pm );
198
199   if ( !updList.isEmpty() )
200     myMenu.insert( pm, updList );
201   else
202   {
203     disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
204     disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
205   }
206 }
207
208 void QtxWorkstackAction::updatePopup( QPopupMenu* pm )
209 {
210   if ( !myMenu.contains( pm ) )
211     return;
212
213   fillPopup( pm, clearPopup( pm ) );
214
215   int count = workstack() ? workstack()->splitWindowList().count() : 0;
216   myItem[VSplit]->setEnabled( count > 1 );
217   myItem[HSplit]->setEnabled( count > 1 );
218 }
219
220 int QtxWorkstackAction::clearPopup( QPopupMenu* pm )
221 {
222   if ( !myMenu.contains( pm ) )
223     return -1;
224
225   int idx = -1;
226   const QIntList& lst = myMenu[pm];
227   for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it )
228     idx = pm->indexOf( *it );
229
230   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
231     mit.data()->removeFrom( pm );
232
233   for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
234     pm->removeItem( *itr );
235
236   return idx;
237 }
238
239 void QtxWorkstackAction::fillPopup( QPopupMenu* pm, const int idx )
240 {
241   if ( !pm )
242     return;
243
244   int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx );
245
246   myMenu.insert( pm, QIntList() );
247   QIntList& lst = myMenu[pm];
248
249   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
250   {
251     if ( !hasItems( mit.key() ) )
252       continue;
253
254     mit.data()->addTo( pm, index );
255     lst.append( pm->idAt( index++ ) );
256   }
257
258   QtxWorkstack* ws = workstack();
259   if ( !ws || !hasItems( Windows ) )
260     return;
261
262   QWidgetList wList = ws->windowList();
263   if ( wList.isEmpty() )
264     return;
265
266   lst.append( pm->insertSeparator( index++ ) );
267
268   int param = 0;
269   pm->setCheckable( true );
270   for ( QWidgetListIt it( wList ); it.current(); ++it )
271   {
272     int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ );
273     pm->setItemParameter( id, param++ );
274     pm->setItemChecked( id, it.current() == ws->activeWindow() );
275     lst.append( id );
276   }
277 }
278
279 void QtxWorkstackAction::onItemActivated( int idx )
280 {
281   QtxWorkstack* ws = workstack();
282   if ( !ws )
283     return;
284
285   QWidgetList wList = ws->windowList();
286   if ( idx < 0 || idx >= (int)wList.count() )
287     return;
288
289   wList.at( idx )->setFocus();
290 }