1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File: QtxWorkspaceAction.cxx
20 // Author: Sergey TELKOV
22 #include "QtxWorkspaceAction.h"
24 #include <qpopupmenu.h>
25 #include <qworkspace.h>
26 #include <qwidgetlist.h>
31 QtxWorkspaceAction::QtxWorkspaceAction( QWorkspace* ws, QObject* parent, const char* name )
32 : QtxAction( tr( "Controls windows into workspace" ), tr( "Workspace management" ), 0, parent, name ),
36 myItem.insert( Cascade, new QtxAction( tr( "Arranges the windows as overlapping tiles" ),
37 tr( "Cascade" ), 0, this, 0, false ) );
38 myItem.insert( Tile, new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ),
39 tr( "Tile" ), 0, this, 0, false ) );
40 myItem.insert( HTile, new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ),
41 tr( "Tile horizontally" ), 0, this, 0, false ) );
42 myItem.insert( VTile, new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ),
43 tr( "Tile vertically" ), 0, this, 0, false ) );
45 connect( myItem[Tile], SIGNAL( activated() ), this, SLOT( tile() ) );
46 connect( myItem[Cascade], SIGNAL( activated() ), this, SLOT( cascade() ) );
47 connect( myItem[HTile], SIGNAL( activated() ), this, SLOT( tileVertical() ) );
48 connect( myItem[VTile], SIGNAL( activated() ), this, SLOT( tileHorizontal() ) );
54 QtxWorkspaceAction::~QtxWorkspaceAction()
59 \return corresponding workspace
61 QWorkspace* QtxWorkspaceAction::workspace() const
67 \return set of action flags
69 int QtxWorkspaceAction::items() const
76 \param flags - new set of flags
78 void QtxWorkspaceAction::setItems( const int flags )
80 if ( !flags || flags == myFlags || !( flags & Operations ) )
87 \return true if action contains all flags
88 \param flags - new set of flags
90 bool QtxWorkspaceAction::hasItems( const int flags ) const
92 return ( myFlags & flags ) == flags;
96 \return accelerator of item
99 int QtxWorkspaceAction::accel( const int id ) const
102 if ( myItem.contains( id ) )
103 a = myItem[id]->accel();
108 \return icons of item
111 QIconSet QtxWorkspaceAction::iconSet( const int id ) const
114 if ( myItem.contains( id ) )
115 ico = myItem[id]->iconSet();
120 \return menu text of item
123 QString QtxWorkspaceAction::menuText( const int id ) const
126 if ( myItem.contains( id ) )
127 txt = myItem[id]->menuText();
132 \return status tip of item
135 QString QtxWorkspaceAction::statusTip( const int id ) const
138 if ( myItem.contains( id ) )
139 txt = myItem[id]->statusTip();
144 Changes accelerator of item
146 \param a - new accelerator
148 void QtxWorkspaceAction::setAccel( const int id, const int a )
150 if ( myItem.contains( id ) )
151 myItem[id]->setAccel( a );
155 Changes icons of item
157 \param ico - new icons
159 void QtxWorkspaceAction::setIconSet( const int id, const QIconSet& ico )
161 if ( myItem.contains( id ) )
162 myItem[id]->setIconSet( ico );
166 Changes menu text of item
168 \param txt - new menu text
170 void QtxWorkspaceAction::setMenuText( const int id, const QString& txt )
172 if ( myItem.contains( id ) )
173 myItem[id]->setMenuText( txt );
177 Changes status tip of item
179 \param txt - new status tip
181 void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt )
183 if ( myItem.contains( id ) )
184 myItem[id]->setStatusTip( txt );
188 Adds action to widget
191 bool QtxWorkspaceAction::addTo( QWidget* wid )
193 return addTo( wid, -1 );
197 Adds action to widget
199 \param idx - position
201 bool QtxWorkspaceAction::addTo( QWidget* wid, const int idx )
203 if ( !wid || !wid->inherits( "QPopupMenu" ) )
206 QPopupMenu* pm = (QPopupMenu*)wid;
209 if ( myMenu.contains( pm ) )
212 myMenu.insert( pm, QIntList() );
213 fillPopup( pm, idx );
215 connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
216 connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
222 Removes action from widget
225 bool QtxWorkspaceAction::removeFrom( QWidget* wid )
227 if ( !wid || !wid->inherits( "QPopupMenu" ) )
230 QPopupMenu* pm = (QPopupMenu*)wid;
231 if ( !myMenu.contains( pm ) )
236 disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
237 disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
246 \param type - action type
248 void QtxWorkspaceAction::perform( const int type )
270 void QtxWorkspaceAction::tile()
272 QWorkspace* ws = workspace();
280 Performs cascade action
282 void QtxWorkspaceAction::cascade()
284 QWorkspace* ws = workspace();
291 int h = ws->height();
293 QWidgetList winList = ws->windowList();
294 for ( QWidgetListIt it( winList ); it.current(); ++it )
295 it.current()->resize( int( w * 0.8 ), int( h * 0.8 ) );
299 Performs tile vertical action
301 void QtxWorkspaceAction::tileVertical()
303 QWorkspace* wrkSpace = workspace();
307 QWidgetList winList = wrkSpace->windowList();
308 if ( winList.isEmpty() )
312 for ( QWidgetListIt itr( winList ); itr.current(); ++itr )
313 if ( !itr.current()->testWState( WState_Minimized ) )
321 int heightForEach = wrkSpace->height() / count;
322 for ( QWidgetListIt it( winList ); it.current(); ++it )
324 QWidget* win = it.current();
325 if ( win->testWState( WState_Minimized ) )
328 if ( win->testWState( WState_Maximized ) )
333 int prefH = win->minimumHeight() + win->parentWidget()->baseSize().height();
334 int actualH = QMAX( heightForEach, prefH );
336 win->parentWidget()->setGeometry( 0, y, wrkSpace->width(), actualH );
342 Performs tile horizontal action
344 void QtxWorkspaceAction::tileHorizontal()
346 QWorkspace* wrkSpace = workspace();
350 QWidgetList winList = wrkSpace->windowList();
351 if ( winList.isEmpty() )
355 for ( QWidgetListIt itr( winList ); itr.current(); ++itr )
356 if ( !itr.current()->testWState( WState_Minimized ) )
363 int widthForEach = wrkSpace->width() / count;
364 for ( QWidgetListIt it( winList ); it.current(); ++it )
366 QWidget* win = it.current();
367 if ( win->testWState( WState_Minimized ) )
370 if ( win->testWState( WState_Maximized ) )
375 int prefW = win->minimumWidth();
376 int actualW = QMAX( widthForEach, prefW );
378 win->parentWidget()->setGeometry( x, 0, actualW, wrkSpace->height() );
384 SLOT: called just before the popup menu is displayed, updates popup
386 void QtxWorkspaceAction::onAboutToShow()
388 const QObject* obj = sender();
389 if ( !obj || !obj->inherits( "QPopupMenu" ) )
392 updatePopup( (QPopupMenu*)obj );
396 SLOT: called when popup menu is destroyed, removes it from menu
398 void QtxWorkspaceAction::onPopupDestroyed( QObject* obj )
400 myMenu.remove( (QPopupMenu*)obj );
405 \param pm - popup menu
407 void QtxWorkspaceAction::checkPopup( QPopupMenu* pm )
409 if ( !myMenu.contains( pm ) )
413 for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it )
415 if ( pm->indexOf( *it ) != -1 )
416 updList.append( *it );
421 if ( !updList.isEmpty() )
422 myMenu.insert( pm, updList );
425 disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) );
426 disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) );
431 Clears and refills popup and updates state of actions
432 \param pm - popup menu
434 void QtxWorkspaceAction::updatePopup( QPopupMenu* pm )
436 if ( !myMenu.contains( pm ) )
439 fillPopup( pm, clearPopup( pm ) );
441 bool count = workspace() ? workspace()->windowList().count() : 0;
442 myItem[Cascade]->setEnabled( count );
443 myItem[Tile]->setEnabled( count );
444 myItem[HTile]->setEnabled( count );
445 myItem[VTile]->setEnabled( count );
450 \param pm - popup menu
452 int QtxWorkspaceAction::clearPopup( QPopupMenu* pm )
454 if ( !myMenu.contains( pm ) )
458 const QIntList& lst = myMenu[pm];
459 for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it )
460 idx = pm->indexOf( *it );
462 for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
463 mit.data()->removeFrom( pm );
465 for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
466 pm->removeItem( *itr );
472 Fills popup with items
473 \param pm - popup menu
474 \param idx - position
476 void QtxWorkspaceAction::fillPopup( QPopupMenu* pm, const int idx )
481 int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx );
483 myMenu.insert( pm, QIntList() );
484 QIntList& lst = myMenu[pm];
486 for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit )
488 if ( !hasItems( mit.key() ) )
491 mit.data()->addTo( pm, index );
492 lst.append( pm->idAt( index++ ) );
495 QWorkspace* ws = workspace();
496 if ( !ws || !hasItems( Windows ) )
499 QWidgetList wList = ws->windowList();
500 if ( wList.isEmpty() )
503 lst.append( pm->insertSeparator( index++ ) );
506 pm->setCheckable( true );
507 for ( QWidgetListIt it( wList ); it.current(); ++it )
509 int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ );
510 pm->setItemParameter( id, param++ );
511 pm->setItemChecked( id, it.current() == ws->activeWindow() );
517 SLOT: called when popup item corresponding to window is activated, activates window
519 void QtxWorkspaceAction::onItemActivated( int idx )
521 QWorkspace* ws = workspace();
525 QWidgetList wList = ws->windowList();
526 if ( idx < 0 || idx >= (int)wList.count() )
529 wList.at( idx )->setFocus();