1 // File: QtxWorkspaceAction.cxx
2 // Author: Sergey TELKOV
4 #include "QtxWorkspaceAction.h"
6 #include <qpopupmenu.h>
7 #include <qworkspace.h>
8 #include <qwidgetlist.h>
10 QtxWorkspaceAction::QtxWorkspaceAction( QWorkspace* ws, QObject* parent, const char* name )
11 : QtxAction( tr( "Controls windows into workspace" ), tr( "Workspace management" ), 0, parent, name ),
15 myItem.insert( Cascade, new QtxAction( tr( "Arranges the windows as overlapping tiles" ),
16 tr( "Cascade" ), 0, this, 0, false ) );
17 myItem.insert( Tile, new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ),
18 tr( "Tile" ), 0, this, 0, false ) );
19 myItem.insert( HTile, new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ),
20 tr( "Tile horizontally" ), 0, this, 0, false ) );
21 myItem.insert( VTile, new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ),
22 tr( "Tile vertically" ), 0, this, 0, false ) );
24 connect( myItem[Tile], SIGNAL( activated() ), this, SLOT( tile() ) );
25 connect( myItem[Cascade], SIGNAL( activated() ), this, SLOT( cascade() ) );
26 connect( myItem[HTile], SIGNAL( activated() ), this, SLOT( tileVertical() ) );
27 connect( myItem[VTile], SIGNAL( activated() ), this, SLOT( tileHorizontal() ) );
30 QtxWorkspaceAction::~QtxWorkspaceAction()
34 QWorkspace* QtxWorkspaceAction::workspace() const
39 int QtxWorkspaceAction::items() const
44 void QtxWorkspaceAction::setItems( const int flags )
46 if ( !flags || flags == myFlags || !( flags & Operations ) )
52 bool QtxWorkspaceAction::hasItems( const int flags ) const
54 return ( myFlags & flags ) == flags;
57 int QtxWorkspaceAction::accel( const int id ) const
60 if ( myItem.contains( id ) )
61 a = myItem[id]->accel();
65 QIconSet QtxWorkspaceAction::iconSet( const int id ) const
68 if ( myItem.contains( id ) )
69 ico = myItem[id]->iconSet();
73 QString QtxWorkspaceAction::menuText( const int id ) const
76 if ( myItem.contains( id ) )
77 txt = myItem[id]->menuText();
81 QString QtxWorkspaceAction::statusTip( const int id ) const
84 if ( myItem.contains( id ) )
85 txt = myItem[id]->statusTip();
89 void QtxWorkspaceAction::setAccel( const int id, const int a )
91 if ( myItem.contains( id ) )
92 myItem[id]->setAccel( a );
95 void QtxWorkspaceAction::setIconSet( const int id, const QIconSet& ico )
97 if ( myItem.contains( id ) )
98 myItem[id]->setIconSet( ico );
101 void QtxWorkspaceAction::setMenuText( const int id, const QString& txt )
103 if ( myItem.contains( id ) )
104 myItem[id]->setMenuText( txt );
107 void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt )
109 if ( myItem.contains( id ) )
110 myItem[id]->setStatusTip( txt );
113 bool QtxWorkspaceAction::addTo( QWidget* wid )
115 return addTo( wid, -1 );
118 bool QtxWorkspaceAction::addTo( QWidget* wid, const int idx )
120 if ( !wid || !wid->inherits( "QPopupMenu" ) )
123 QPopupMenu* pm = (QPopupMenu*)wid;
126 if ( myMenu.contains( pm ) )
129 myMenu.insert( pm, QIntList() );
130 fillPopup( pm, idx );
132 connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
133 connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
138 bool QtxWorkspaceAction::removeFrom( QWidget* wid )
140 if ( !wid || !wid->inherits( "QPopupMenu" ) )
143 QPopupMenu* pm = (QPopupMenu*)wid;
144 if ( !myMenu.contains( pm ) )
149 disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
150 disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
157 void QtxWorkspaceAction::perform( const int type )
176 void QtxWorkspaceAction::tile()
178 QWorkspace* ws = workspace();
185 void QtxWorkspaceAction::cascade()
187 QWorkspace* ws = workspace();
194 int h = ws->height();
196 QWidgetList winList = ws->windowList();
197 for ( QWidgetListIt it( winList ); it.current(); ++it )
198 it.current()->resize( int( w * 0.8 ), int( h * 0.8 ) );
201 void QtxWorkspaceAction::tileVertical()
203 QWorkspace* wrkSpace = workspace();
207 QWidgetList winList = wrkSpace->windowList();
208 if ( winList.isEmpty() )
212 for ( QWidgetListIt itr( winList ); itr.current(); ++itr )
213 if ( !itr.current()->testWState( WState_Minimized ) )
221 int heightForEach = wrkSpace->height() / count;
222 for ( QWidgetListIt it( winList ); it.current(); ++it )
224 QWidget* win = it.current();
225 if ( win->testWState( WState_Minimized ) )
228 if ( win->testWState( WState_Maximized ) )
233 int prefH = win->minimumHeight() + win->parentWidget()->baseSize().height();
234 int actualH = QMAX( heightForEach, prefH );
236 win->parentWidget()->setGeometry( 0, y, wrkSpace->width(), actualH );
241 void QtxWorkspaceAction::tileHorizontal()
243 QWorkspace* wrkSpace = workspace();
247 QWidgetList winList = wrkSpace->windowList();
248 if ( winList.isEmpty() )
252 for ( QWidgetListIt itr( winList ); itr.current(); ++itr )
253 if ( !itr.current()->testWState( WState_Minimized ) )
260 int widthForEach = wrkSpace->width() / count;
261 for ( QWidgetListIt it( winList ); it.current(); ++it )
263 QWidget* win = it.current();
264 if ( win->testWState( WState_Minimized ) )
267 if ( win->testWState( WState_Maximized ) )
272 int prefW = win->minimumWidth();
273 int actualW = QMAX( widthForEach, prefW );
275 win->parentWidget()->setGeometry( x, 0, actualW, wrkSpace->height() );
280 void QtxWorkspaceAction::onAboutToShow()
282 const QObject* obj = sender();
283 if ( !obj || !obj->inherits( "QPopupMenu" ) )
286 updatePopup( (QPopupMenu*)obj );
289 void QtxWorkspaceAction::onPopupDestroyed( QObject* obj )
291 myMenu.remove( (QPopupMenu*)obj );
294 void QtxWorkspaceAction::checkPopup( QPopupMenu* pm )
296 if ( !myMenu.contains( pm ) )
300 for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it )
302 if ( pm->indexOf( *it ) != -1 )
303 updList.append( *it );
308 if ( !updList.isEmpty() )
309 myMenu.insert( pm, updList );
312 disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
313 disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
317 void QtxWorkspaceAction::updatePopup( QPopupMenu* pm )
319 if ( !myMenu.contains( pm ) )
322 fillPopup( pm, clearPopup( pm ) );
324 bool count = workspace() ? workspace()->windowList().count() : 0;
325 myItem[Cascade]->setEnabled( count );
326 myItem[Tile]->setEnabled( count );
327 myItem[HTile]->setEnabled( count );
328 myItem[VTile]->setEnabled( count );
331 int QtxWorkspaceAction::clearPopup( QPopupMenu* pm )
333 if ( !myMenu.contains( pm ) )
337 const QIntList& lst = myMenu[pm];
338 for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it )
339 idx = pm->indexOf( *it );
341 for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
342 mit.data()->removeFrom( pm );
344 for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
345 pm->removeItem( *itr );
350 void QtxWorkspaceAction::fillPopup( QPopupMenu* pm, const int idx )
355 int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx );
357 myMenu.insert( pm, QIntList() );
358 QIntList& lst = myMenu[pm];
360 for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
362 if ( !hasItems( mit.key() ) )
365 mit.data()->addTo( pm, index );
366 lst.append( pm->idAt( index++ ) );
369 QWorkspace* ws = workspace();
370 if ( !ws || !hasItems( Windows ) )
373 QWidgetList wList = ws->windowList();
374 if ( wList.isEmpty() )
377 lst.append( pm->insertSeparator( index++ ) );
380 pm->setCheckable( true );
381 for ( QWidgetListIt it( wList ); it.current(); ++it )
383 int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ );
384 pm->setItemParameter( id, param++ );
385 pm->setItemChecked( id, it.current() == ws->activeWindow() );
390 void QtxWorkspaceAction::onItemActivated( int idx )
392 QWorkspace* ws = workspace();
396 QWidgetList wList = ws->windowList();
397 if ( idx < 0 || idx >= (int)wList.count() )
400 wList.at( idx )->setFocus();