Salome HOME
Initial version
[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   updatePopup( (QPopupMenu*)obj );
172 }
173
174 void QtxWorkstackAction::onPopupDestroyed( QObject* obj )
175 {
176   myMenu.remove( (QPopupMenu*)obj );
177 }
178
179 void QtxWorkstackAction::checkPopup( QPopupMenu* pm )
180 {
181   if ( !myMenu.contains( pm ) )
182     return;
183
184   QIntList updList;
185   for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it )
186   {
187     if ( pm->indexOf( *it ) != -1 )
188       updList.append( *it );
189   }
190
191   myMenu.remove( pm );
192
193   if ( !updList.isEmpty() )
194     myMenu.insert( pm, updList );
195   else
196   {
197     disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
198     disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
199   }
200 }
201
202 void QtxWorkstackAction::updatePopup( QPopupMenu* pm )
203 {
204   if ( !myMenu.contains( pm ) )
205     return;
206
207   fillPopup( pm, clearPopup( pm ) );
208
209   int count = workstack() ? workstack()->splitWindowList().count() : 0;
210   myItem[VSplit]->setEnabled( count > 1 );
211   myItem[HSplit]->setEnabled( count > 1 );
212 }
213
214 int QtxWorkstackAction::clearPopup( QPopupMenu* pm )
215 {
216   if ( !myMenu.contains( pm ) )
217     return -1;
218
219   int idx = -1;
220   const QIntList& lst = myMenu[pm];
221   for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it )
222     idx = pm->indexOf( *it );
223
224   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
225     mit.data()->removeFrom( pm );
226
227   for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
228     pm->removeItem( *itr );
229
230   return idx;
231 }
232
233 void QtxWorkstackAction::fillPopup( QPopupMenu* pm, const int idx )
234 {
235   if ( !pm )
236     return;
237
238   int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx );
239
240   myMenu.insert( pm, QIntList() );
241   QIntList& lst = myMenu[pm];
242
243   for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
244   {
245     if ( !hasItems( mit.key() ) )
246       continue;
247
248     mit.data()->addTo( pm, index );
249     lst.append( pm->idAt( index++ ) );
250   }
251
252   QtxWorkstack* ws = workstack();
253   if ( !ws || !hasItems( Windows ) )
254     return;
255
256   QWidgetList wList = ws->windowList();
257   if ( wList.isEmpty() )
258     return;
259
260   lst.append( pm->insertSeparator( index++ ) );
261
262   int param = 0;
263   pm->setCheckable( true );
264   for ( QWidgetListIt it( wList ); it.current(); ++it )
265   {
266     int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ );
267     pm->setItemParameter( id, param++ );
268     pm->setItemChecked( id, it.current() == ws->activeWindow() );
269     lst.append( id );
270   }
271 }
272
273 void QtxWorkstackAction::onItemActivated( int idx )
274 {
275   QtxWorkstack* ws = workstack();
276   if ( !ws )
277     return;
278
279   QWidgetList wList = ws->windowList();
280   if ( idx < 0 || idx >= (int)wList.count() )
281     return;
282
283   wList.at( idx )->setFocus();
284 }