-// 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 <qpopupmenu.h>
-#include <qworkspace.h>
-#include <qwidgetlist.h>
-
-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 <QMenu>
+#include <QWidgetList>
+
+/*!
+ \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 )
}
}
+/*!
+ \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<QMenu*>( 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<QMenu*>( 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<QAction*> lst = actions();
+ for ( QList<QAction*>::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<QAction*> items;
+ QMap<QAction*, int> 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<QAction*, int>::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<QMenu*>( 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 );
}