X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FQtx%2FQtxWorkspaceAction.cxx;h=5bac837df3e87f8504936e52d15af368f7535ebb;hb=389efae83b99d654509671e60af3eecf11b8278e;hp=c630ff47d099c2d85769408f497475d4af2f883a;hpb=232b55569765049c7d1cceb5096a45f8584c9369;p=modules%2Fgui.git diff --git a/src/Qtx/QtxWorkspaceAction.cxx b/src/Qtx/QtxWorkspaceAction.cxx index c630ff47d..5bac837df 100644 --- a/src/Qtx/QtxWorkspaceAction.cxx +++ b/src/Qtx/QtxWorkspaceAction.cxx @@ -1,177 +1,217 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + // File: QtxWorkspaceAction.cxx // Author: Sergey TELKOV - +// #include "QtxWorkspaceAction.h" -#include -#include -#include - -QtxWorkspaceAction::QtxWorkspaceAction( QWorkspace* ws, QObject* parent, const char* name ) -: QtxAction( tr( "Controls windows into workspace" ), tr( "Workspace management" ), 0, parent, name ), -myFlags( Standard ), -myWorkspace( ws ) +#include "QtxWorkspace.h" + +#include +#include + +/*! + \class QtxWorkspaceAction + \brief Implements actions group for menu Windows with standard operations, like + "Cascade", "Tile", "Tile Horizontally", etc. +*/ + +/*! + \brief Constructor. + \param ws parent workspace + \param parent parent object (owner of the action) +*/ +QtxWorkspaceAction::QtxWorkspaceAction( QtxWorkspace* ws, QObject* parent ) +: QtxActionSet( parent ), + myWorkspace( ws ), + myWindowsFlag( true ) { - myItem.insert( Cascade, new QtxAction( tr( "Arranges the windows as overlapping tiles" ), - tr( "Cascade" ), 0, this, 0, false ) ); - myItem.insert( Tile, new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ), - tr( "Tile" ), 0, this, 0, false ) ); - myItem.insert( HTile, new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ), - tr( "Tile horizontally" ), 0, this, 0, false ) ); - myItem.insert( VTile, new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ), - tr( "Tile vertically" ), 0, this, 0, false ) ); - - connect( myItem[Tile], SIGNAL( activated() ), this, SLOT( tile() ) ); - connect( myItem[Cascade], SIGNAL( activated() ), this, SLOT( cascade() ) ); - connect( myItem[HTile], SIGNAL( activated() ), this, SLOT( tileVertical() ) ); - connect( myItem[VTile], SIGNAL( activated() ), this, SLOT( tileHorizontal() ) ); + insertAction( new QtxAction( tr( "Arranges the windows as overlapping tiles" ), + tr( "Cascade" ), 0, this ), Cascade ); + insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping tiles" ), + tr( "Tile" ), 0, this ), Tile ); + insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping horizontal tiles" ), + tr( "Tile horizontally" ), 0, this ), HTile ); + insertAction( new QtxAction( tr( "Arranges the windows as nonoverlapping vertical tiles" ), + tr( "Tile vertically" ), 0, this ), VTile ); + + connect( this, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) ); + + setMenuActions( Standard ); } +/*! + \brief Destructor. +*/ QtxWorkspaceAction::~QtxWorkspaceAction() { } -QWorkspace* QtxWorkspaceAction::workspace() const +/*! + \brief Get workspace. + \return parent workspace +*/ +QtxWorkspace* QtxWorkspaceAction::workspace() const { return myWorkspace; } -int QtxWorkspaceAction::items() const -{ - return myFlags; -} +/*! + \brief Set actions to be visible in the menu. + + Actions, which IDs are set in \a flags parameter, will be shown in the + menu bar. Other actions will not be shown. -void QtxWorkspaceAction::setItems( const int flags ) + \param flags ORed together actions flags +*/ +void QtxWorkspaceAction::setMenuActions( const int flags ) { - if ( !flags || flags == myFlags || !( flags & Operations ) ) - return; - - myFlags = flags; + action( Cascade )->setVisible( flags & Cascade ); + action( Tile )->setVisible( flags & Tile ); + action( VTile )->setVisible( flags & VTile ); + action( HTile )->setVisible( flags & HTile ); + myWindowsFlag = flags & Windows; } -bool QtxWorkspaceAction::hasItems( const int flags ) const +/*! + \brief Get menu actions which are currently visible in the menu bar. + \return ORed together actions flags + \sa setMenuActions() +*/ +int QtxWorkspaceAction::menuActions() const { - return ( myFlags & flags ) == flags; + int ret = 0; + ret = ret | ( action( Cascade )->isVisible() ? Cascade : 0 ); + ret = ret | ( action( Tile )->isVisible() ? Tile : 0 ); + ret = ret | ( action( VTile )->isVisible() ? VTile : 0 ); + ret = ret | ( action( HTile )->isVisible() ? HTile : 0 ); + ret = ret | ( myWindowsFlag ? Windows : 0 ); + return ret; } +/*! + \brief Get keyboard accelerator for the specified action. + \param id menu action ID + \return keyboard accelerator of menu item or 0 if there is no such action +*/ int QtxWorkspaceAction::accel( const int id ) const { int a = 0; - if ( myItem.contains( id ) ) - a = myItem[id]->accel(); + if ( action( id ) ) + a = action( id )->shortcut(); return a; } -QIconSet QtxWorkspaceAction::iconSet( const int id ) const +/*! + \brief Get icon for the specified action. + + If \a id is invalid, null icon is returned. + + \param id menu action ID + \return menu item icon +*/ +QIcon QtxWorkspaceAction::icon( const int id ) const { - QIconSet ico; - if ( myItem.contains( id ) ) - ico = myItem[id]->iconSet(); + QIcon ico; + if ( action( id ) ) + ico = action( id )->icon(); return ico; } -QString QtxWorkspaceAction::menuText( const int id ) const +/*! + \brief Get menu item text for the specified action. + \param id menu action ID + \return menu item text or null QString if there is no such action +*/ +QString QtxWorkspaceAction::text( const int id ) const { QString txt; - if ( myItem.contains( id ) ) - txt = myItem[id]->menuText(); + if ( action( id ) ) + txt = action( id )->text(); return txt; } +/*! + \brief Get status bar tip for the specified action. + \param id menu action ID + \return status bar tip menu item or null QString if there is no such action +*/ QString QtxWorkspaceAction::statusTip( const int id ) const { QString txt; - if ( myItem.contains( id ) ) - txt = myItem[id]->statusTip(); + if ( action( id ) ) + txt = action( id )->statusTip(); return txt; } +/*! + \brief Set keyboard accelerator for the specified action. + \param id menu action ID + \param a new keyboard accelerator +*/ void QtxWorkspaceAction::setAccel( const int id, const int a ) { - if ( myItem.contains( id ) ) - myItem[id]->setAccel( a ); + if ( action( id ) ) + action( id )->setShortcut( a ); } -void QtxWorkspaceAction::setIconSet( const int id, const QIconSet& ico ) +/*! + \brief Set menu item icon for the specified action. + \param id menu action ID + \param ico new menu item icon +*/ +void QtxWorkspaceAction::setIcon( const int id, const QIcon& icon ) { - if ( myItem.contains( id ) ) - myItem[id]->setIconSet( ico ); + if ( action( id ) ) + action( id )->setIcon( icon ); } -void QtxWorkspaceAction::setMenuText( const int id, const QString& txt ) +/*! + \brief Set menu item text for the specified action. + \param id menu action ID + \param txt new menu item text +*/ +void QtxWorkspaceAction::setText( const int id, const QString& txt ) { - if ( myItem.contains( id ) ) - myItem[id]->setMenuText( txt ); + if ( action( id ) ) + action( id )->setText( txt ); } +/*! + \brief Set menu item status bar tip for the specified action. + \param id menu action ID + \param txt new menu item status bar tip +*/ void QtxWorkspaceAction::setStatusTip( const int id, const QString& txt ) { - if ( myItem.contains( id ) ) - myItem[id]->setStatusTip( txt ); -} - -bool QtxWorkspaceAction::addTo( QWidget* wid ) -{ - return addTo( wid, -1 ); -} - -bool QtxWorkspaceAction::addTo( QWidget* wid, const int idx ) -{ - if ( !wid || !wid->inherits( "QPopupMenu" ) ) - return false; - - QPopupMenu* pm = (QPopupMenu*)wid; - checkPopup( pm ); - - if ( myMenu.contains( pm ) ) - return false; - - myMenu.insert( pm, QIntList() ); - fillPopup( pm, idx ); - - connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); - connect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); - - return true; -} - -bool QtxWorkspaceAction::removeFrom( QWidget* wid ) -{ - if ( !wid || !wid->inherits( "QPopupMenu" ) ) - return false; - - QPopupMenu* pm = (QPopupMenu*)wid; - if ( !myMenu.contains( pm ) ) - return false; - - clearPopup( pm ); - - disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); - disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); - - myMenu.remove( pm ); - - return true; + if ( action( id ) ) + action( id )->setStatusTip( txt ); } +/*! + \brief Process action activated by the user. + \param type action ID +*/ void QtxWorkspaceAction::perform( const int type ) { switch ( type ) @@ -191,229 +231,187 @@ void QtxWorkspaceAction::perform( const int type ) } } +/*! + \brief Tile child windows in the workspace. +*/ void QtxWorkspaceAction::tile() { - QWorkspace* ws = workspace(); - if ( !ws ) - return; - - ws->tile(); + QtxWorkspace* ws = workspace(); + if ( ws ) + ws->tile(); } +/*! + \brief Cascade child windows in the workspace. +*/ void QtxWorkspaceAction::cascade() { - QWorkspace* ws = workspace(); + QtxWorkspace* ws = workspace(); if ( !ws ) return; ws->cascade(); - int w = ws->width(); - int h = ws->height(); + int w = ws->width(); + int h = ws->height(); - QWidgetList winList = ws->windowList(); - for ( QWidgetListIt it( winList ); it.current(); ++it ) - it.current()->resize( int( w * 0.8 ), int( h * 0.8 ) ); + QWidgetList winList = ws->windowList(); + for ( QWidgetList::iterator it = winList.begin(); it != winList.end(); ++it ) + (*it)->resize( int( w * 0.8 ), int( h * 0.8 ) ); } +/*! + \brief Tile child windows in the workspace in the vertical direction. +*/ void QtxWorkspaceAction::tileVertical() { - QWorkspace* wrkSpace = workspace(); - if ( !wrkSpace ) - return; - - QWidgetList winList = wrkSpace->windowList(); - if ( winList.isEmpty() ) - return; - - int count = 0; - for ( QWidgetListIt itr( winList ); itr.current(); ++itr ) - if ( !itr.current()->testWState( WState_Minimized ) ) - count++; - - if ( !count ) - return; - - int y = 0; - - int heightForEach = wrkSpace->height() / count; - for ( QWidgetListIt it( winList ); it.current(); ++it ) - { - QWidget* win = it.current(); - if ( win->testWState( WState_Minimized ) ) - continue; - - if ( win->testWState( WState_Maximized ) ) - { - win->hide(); - win->showNormal(); - } - int prefH = win->minimumHeight() + win->parentWidget()->baseSize().height(); - int actualH = QMAX( heightForEach, prefH ); - - win->parentWidget()->setGeometry( 0, y, wrkSpace->width(), actualH ); - y += actualH; - } + QtxWorkspace* ws = workspace(); + if ( ws ) + ws->tileVertical(); } +/*! + \brief Tile child windows in the workspace in the horizontal direction. +*/ void QtxWorkspaceAction::tileHorizontal() { - QWorkspace* wrkSpace = workspace(); - if ( !wrkSpace ) - return; - - QWidgetList winList = wrkSpace->windowList(); - if ( winList.isEmpty() ) - return; - - int count = 0; - for ( QWidgetListIt itr( winList ); itr.current(); ++itr ) - if ( !itr.current()->testWState( WState_Minimized ) ) - count++; - - if ( !count ) - return; - - int x = 0; - int widthForEach = wrkSpace->width() / count; - for ( QWidgetListIt it( winList ); it.current(); ++it ) - { - QWidget* win = it.current(); - if ( win->testWState( WState_Minimized ) ) - continue; - - if ( win->testWState( WState_Maximized ) ) - { - win->hide(); - win->showNormal(); - } - int prefW = win->minimumWidth(); - int actualW = QMAX( widthForEach, prefW ); - - win->parentWidget()->setGeometry( x, 0, actualW, wrkSpace->height() ); - x += actualW; - } + QtxWorkspace* ws = workspace(); + if ( ws ) + ws->tileHorizontal(); } -void QtxWorkspaceAction::onAboutToShow() +/*! + \brief Called when action is added to the menu bar. + \param w menu bar widget this action is being added to +*/ +void QtxWorkspaceAction::addedTo( QWidget* w ) { - const QObject* obj = sender(); - if ( !obj || !obj->inherits( "QPopupMenu" ) ) - return; + QtxActionSet::addedTo( w ); - updatePopup( (QPopupMenu*)obj ); + QMenu* pm = ::qobject_cast( w ); + if ( pm ) + connect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); } -void QtxWorkspaceAction::onPopupDestroyed( QObject* obj ) +/*! + \brief Called when action is removed from the menu bar. + \param w menu bar widget this action is being removed from +*/ +void QtxWorkspaceAction::removedFrom( QWidget* w ) { - myMenu.remove( (QPopupMenu*)obj ); -} - -void QtxWorkspaceAction::checkPopup( QPopupMenu* pm ) -{ - if ( !myMenu.contains( pm ) ) - return; + QtxActionSet::removedFrom( w ); - QIntList updList; - for ( QIntList::const_iterator it = myMenu[pm].begin(); it != myMenu[pm].end(); ++it ) - { - if ( pm->indexOf( *it ) != -1 ) - updList.append( *it ); - } - - myMenu.remove( pm ); - - if ( !updList.isEmpty() ) - myMenu.insert( pm, updList ); - else - { + QMenu* pm = ::qobject_cast( w ); + if ( pm ) disconnect( pm, SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); - disconnect( pm, SIGNAL( destroyed( QObject* ) ), this, SLOT( onPopupDestroyed( QObject* ) ) ); - } } -void QtxWorkspaceAction::updatePopup( QPopupMenu* pm ) +/*! + \brief Update all menu action state. +*/ +void QtxWorkspaceAction::updateContent() { - if ( !myMenu.contains( pm ) ) - return; - - fillPopup( pm, clearPopup( pm ) ); - bool count = workspace() ? workspace()->windowList().count() : 0; - myItem[Cascade]->setEnabled( count ); - myItem[Tile]->setEnabled( count ); - myItem[HTile]->setEnabled( count ); - myItem[VTile]->setEnabled( count ); -} - -int QtxWorkspaceAction::clearPopup( QPopupMenu* pm ) -{ - if ( !myMenu.contains( pm ) ) - return -1; + action( Cascade )->setEnabled( count ); + action( Tile )->setEnabled( count ); + action( HTile )->setEnabled( count ); + action( VTile )->setEnabled( count ); - int idx = -1; - const QIntList& lst = myMenu[pm]; - for ( QIntList::const_iterator it = lst.begin(); it != lst.end() && idx == -1; ++it ) - idx = pm->indexOf( *it ); - - for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) - mit.data()->removeFrom( pm ); - - for ( QIntList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) - pm->removeItem( *itr ); - - return idx; + updateWindows(); } -void QtxWorkspaceAction::fillPopup( QPopupMenu* pm, const int idx ) +/*! + \brief Update actions which refer to the opened child windows. +*/ +void QtxWorkspaceAction::updateWindows() { - if ( !pm ) + QtxWorkspace* ws = workspace(); + if ( !ws ) return; - int index = idx < 0 ? pm->count() : QMIN( (int)pm->count(), idx ); + QList lst = actions(); + for ( QList::iterator it = lst.begin(); it != lst.end(); ++it ) + { + int id = actionId( *it ); + if ( id >= Windows ) + removeAction( *it ); + } - myMenu.insert( pm, QIntList() ); - QIntList& lst = myMenu[pm]; + bool base = action( Cascade )->isVisible() || action( Tile )->isVisible() || + action( HTile )->isVisible() || action( VTile )->isVisible(); - for ( ItemMap::ConstIterator mit = myItem.begin(); mit != myItem.end(); ++mit ) + QList items; + QMap map; + if ( menuActions() & Windows ) { - if ( !hasItems( mit.key() ) ) - continue; + int index = 1; + QWidgetList wList = ws->windowList(); + for ( QWidgetList::iterator it = wList.begin(); it != wList.end(); ++it, index++ ) + { + QWidget* wid = *it; + QAction* a = new QtxAction( wid->windowTitle(), wid->windowTitle(), 0, this, true ); + a->setChecked( wid == ws->activeWindow() ); + items.append( a ); + map.insert( a, Windows + index ); + } - mit.data()->addTo( pm, index ); - lst.append( pm->idAt( index++ ) ); + if ( base && !items.isEmpty() ) + { + QAction* sep = new QtxAction( this ); + sep->setSeparator( true ); + items.prepend( sep ); + map.insert( sep, Windows ); + } } - QWorkspace* ws = workspace(); - if ( !ws || !hasItems( Windows ) ) - return; + if ( !items.isEmpty() ) + insertActions( items ); - QWidgetList wList = ws->windowList(); - if ( wList.isEmpty() ) - return; + for ( QMap::const_iterator itr = map.begin(); itr != map.end(); ++itr ) + setActionId( itr.key(), itr.value() ); +} - lst.append( pm->insertSeparator( index++ ) ); +/*! + \brief Called when parent menu is about to show. - int param = 0; - pm->setCheckable( true ); - for ( QWidgetListIt it( wList ); it.current(); ++it ) - { - int id = pm->insertItem( it.current()->caption(), this, SLOT( onItemActivated( int ) ), 0, -1, index++ ); - pm->setItemParameter( id, param++ ); - pm->setItemChecked( id, it.current() == ws->activeWindow() ); - lst.append( id ); - } + Updates all menu items. +*/ +void QtxWorkspaceAction::onAboutToShow() +{ + QMenu* pm = ::qobject_cast( sender() ); + if ( pm ) + updateContent(); } -void QtxWorkspaceAction::onItemActivated( int idx ) +/*! + \brief Called when menu item corresponding to some child window is activated. + + Activates correposponding child window. + + \param idx menu item index +*/ +void QtxWorkspaceAction::activateItem( const int idx ) { - QWorkspace* ws = workspace(); + QtxWorkspace* ws = workspace(); if ( !ws ) return; QWidgetList wList = ws->windowList(); - if ( idx < 0 || idx >= (int)wList.count() ) - return; + if ( idx >= 0 && idx < (int)wList.count() ) + wList.at( idx )->setFocus(); +} + +/*! + \brief Called when menu item is activated by the user. + + Perform the corresponding action. - wList.at( idx )->setFocus(); + \param id menu item identifier +*/ +void QtxWorkspaceAction::onTriggered( int id ) +{ + if ( id < Windows ) + perform( id ); + else + activateItem( id - Windows - 1 ); }