-// 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: QtxAction.cxx
// Author: Sergey TELKOV
-
+//
#include "QtxAction.h"
-#include <qpopupmenu.h>
-#include <qmenubar.h>
+#include <QEvent>
+#include <QPointer>
+#include <QActionEvent>
+#include <QApplication>
/*!
- Name: QtxAction [public]
- Desc: Constructs an action with given parent and name. If toggle is true the
- action will be a toggle action, otherwise it will be a command action.
+ \class QtxAction::ActionNotify
+ \brief Notify event used to signalize about event adding/removing.
+ \internal
*/
-QtxAction::QtxAction( QObject* parent, const char* name, bool toggle )
- : QAction( parent, name, toggle )
+class QtxAction::ActionNotify : public QEvent
{
-}
+public:
+ ActionNotify( bool add, QWidget* wid ) : QEvent( QEvent::User ), myAdd( add ), myWidget( wid ) {};
+ ~ActionNotify() {};
+
+ bool isAdded() const { return myAdd; }
+ QWidget* widget() const { return myWidget; }
+
+private:
+ bool myAdd;
+ QPointer<QWidget> myWidget;
+};
/*!
- Name: QtxAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the icon or iconset icon, the menu text and keyboard
- accelerator. It is a child of given parent and named specified name.
- If toggle is true the action will be a toggle action, otherwise it will
- be a command action.
+ \class QtxAction
+ \brief Generic action class.
+
+ The class QtxAction inherits QWidgetAction class and can be used
+ as base class when implementing any custom menu/toolbar actions.
+ It is necessary to subclass from QtxAction and redefine virtual
+ callback methods addedTo(), removedFrom() (which are called automatically
+ when the action is added to the widget and removed from it) to customize
+ the action behavior.
*/
-QtxAction::QtxAction( const QString& text, const QIconSet& icon,
- const QString& menuText, int accel,
- QObject* parent, const char* name, bool toggle )
- : QAction( text, icon, menuText, accel, parent, name, toggle )
+/*!
+ \brief Constructor.
+
+ Creates an action owned by \a parent.
+ Parameter \a toggle can be used to make the action checkable.
+ Parameter \a shortcutAction can be used to assign the shortcut from
+ preferences. This parameter value corresponds to shortcut action identifier
+ in shortcut preferences.
+
+ \param parent parent object
+ \param toggle if \c true the action will be a toggle action
+ \param shortcutAction shortcut action identifier
+*/
+QtxAction::QtxAction( QObject* parent, bool toggle, const QString& shortcutAction )
+: QWidgetAction( parent )
{
+ setCheckable( toggle );
+ setShortcutActionName(shortcutAction);
+
+ QApplication::instance()->installEventFilter( this );
}
/*!
- Name: QtxAction [public]
- Desc: This constructor creates an action with the following properties: the
- description text, the menu text and keyboard accelerator. It is a child
- of given parent and named specified name. If toggle is true the action
- will be a toggle action, otherwise it will be a command action.
+ \brief Constructor.
+
+ Creates an action owned by \a parent. Parameters \a text,
+ \a icon, \a menuText and \a accel specify the action's attributes.
+ Parameter \a toggle can be used to make the action checkable.
+ Parameter \a shortcutAction can be used to assign the shortcut from
+ preferences. This parameter value corresponds to shortcut action identifier
+ in shortcut preferences.
+
+ \param text tooltip text
+ \param icon iconset
+ \param menuText menu text
+ \param accel shortcut key sequence
+ \param parent parent object
+ \param toggle if \c true the action will be a toggle action
+ \param shortcutAction shortcut action identifier
*/
-
-QtxAction::QtxAction( const QString& text, const QString& menuText, int accel,
- QObject* parent, const char* name, bool toggle )
- : QAction( text, menuText, accel, parent, name, toggle )
+QtxAction::QtxAction( const QString& text, const QIcon& icon, const QString& menuText,
+ int accel, QObject* parent, bool toggle, const QString& shortcutAction )
+: QWidgetAction( parent )
{
+ setIcon( icon );
+ setText( menuText );
+ setToolTip( text );
+ setShortcut( accel );
+ setCheckable( toggle );
+ setShortcutActionName(shortcutAction);
+
+ QApplication::instance()->installEventFilter( this );
}
/*!
- Name: ~QtxAction [virtual public]
- Desc: Destructor.
+ \brief Constructor.
+
+ Creates an action owned by \a parent. Parameters \a text,
+ \a menuText and \a accel specify the action's attributes.
+ Parameter \a toggle can be used to make the action checkable.
+ Parameter \a shortcutAction can be used to assign the shortcut from
+ preferences. This parameter value corresponds to shortcut action identifier
+ in shortcut preferences.
+
+ \param text tooltip text
+ \param menuText menu text
+ \param accel shortcut key sequence
+ \param parent parent object
+ \param toggle if \c true the action is a toggle action
+ \param shortcutAction shortcut action identifier
*/
+QtxAction::QtxAction( const QString& text, const QString& menuText,
+ int accel, QObject* parent, bool toggle, const QString& shortcutAction )
+: QWidgetAction( parent )
+{
+ setText( menuText );
+ setToolTip( text );
+ setShortcut( accel );
+ setCheckable( toggle );
+ setShortcutActionName(shortcutAction);
+
+ QApplication::instance()->installEventFilter( this );
+}
+/*!
+ \brief Destructor.
+*/
QtxAction::~QtxAction()
{
}
/*!
- Name: addTo [virtual public]
- Desc: Adds this action to widget. Returns true if the action was added
- successfully and false otherwise.
-*/
+ \brief Customize action events.
+
+ Sends a notification event to the action when it is added to
+ the widget or removed from it in order to perform custom processing.
-bool QtxAction::addTo( QWidget* w )
+ \param o object
+ \param e event
+ \return \c true if further event processing should be stopped
+ \sa customEvent(), addedTo(), removedFrom()
+*/
+bool QtxAction::eventFilter( QObject* o, QEvent* e )
{
- if ( w->inherits( "QMenuBar" ) ) {
- // --- Add action to the QMenuBar ---
- // n.b. currently for the actions inserted to the menu bar
- // the following properties are not supported:
- // * tooltips
- // * what's this info
- // * toggle mode
- QMenuBar* mb = (QMenuBar*)w;
- if ( myMenuIds.find( w ) != myMenuIds.end() )
- return false; // already added
- if ( name() == "qt_separator_action" ) // separator
- myMenuIds[ w ] = mb->insertSeparator();
- else if ( iconSet().isNull() ) // has no icon
- myMenuIds[ w ] = mb->insertItem( menuText(), this, SIGNAL( activated() ), accel() );
- else // has icon
- myMenuIds[ w ] = mb->insertItem( iconSet(), menuText(), this, SIGNAL( activated() ), accel() );
- mb->setItemEnabled( myMenuIds[ w ], isEnabled() );
- mb->setItemVisible( myMenuIds[ w ], isVisible() );
- return true;
+ if ( o && o->isWidgetType() )
+ {
+ if ( e->type() == QEvent::ActionAdded && ((QActionEvent*)e)->action() == this )
+ QApplication::postEvent( this, new ActionNotify( true, (QWidget*)o ) );
+ if ( e->type() == QEvent::ActionRemoved && ((QActionEvent*)e)->action() == this )
+ QApplication::postEvent( this, new ActionNotify( false, (QWidget*)o ) );
}
- return QAction::addTo( w );
+ return QWidgetAction::eventFilter( o, e );
}
/*!
- Name: addTo [virtual public]
- Desc: Adds this action to widget. If widget is QPopupMenu given index will
- be used for menu item inserting. Returns true if the action was added
- successfully and false otherwise.
-*/
+ \brief Called when the action is added to the widget.
-bool QtxAction::addTo( QWidget* w, int index )
+ This method can be redefined in the subclasses to customize
+ the action behavior. Base implementation does nothing.
+
+ \param w widget (should be menu or toolbar)
+ \sa removedFrom()
+*/
+void QtxAction::addedTo( QWidget* /*w*/ )
{
- if ( !addTo( w ) )
- return false;
-
- if ( w->inherits( "QPopupMenu" ) ) {
- // --- Add action to the QPopupMenu ---
- QPopupMenu* popup = (QPopupMenu*)w;
- if ( index >= 0 && index < (int)popup->count() - 1 ) {
- int id = popup->idAt( popup->count() - 1 );
- if ( id != -1 ) {
- QMenuItem* item = popup->findItem( id );
- if ( item && item->isSeparator() ) {
- popup->removeItem( id );
- popup->insertSeparator( index );
- }
- else {
- QPopupMenu* p = item ? item->popup() : 0;
- int accel = popup->accel( id );
- bool isOn = popup->isItemEnabled( id );
- bool isVisible = popup->isItemVisible( id );
- bool isChecked = popup->isItemChecked( id );
- QString text = popup->text( id );
- QIconSet icon;
- if ( popup->iconSet( id ) )
- icon = *popup->iconSet( id );
- popup->removeItem( id );
- int pos;
- if ( icon.isNull() )
- if ( p )
- pos = popup->indexOf( popup->insertItem( text, p, id, index ) );
- else
- pos = popup->indexOf( popup->insertItem( text, id, index ) );
- else
- if ( p )
- pos = popup->indexOf( popup->insertItem( icon, text, p, id, index ) );
- else
- pos = popup->indexOf( popup->insertItem( icon, text, p, id, index ) );
- popup->setId( pos, id );
- popup->setAccel( accel, id );
- popup->setItemEnabled( id, isOn );
- popup->setItemVisible( id, isVisible );
- popup->setItemChecked( id, isChecked );
- if ( !whatsThis().isEmpty() )
- popup->setWhatsThis( id, whatsThis() );
- if ( !p )
- popup->connectItem( id, this, SLOT( internalActivation() ) );
- }
- }
- }
- }
- else if ( w->inherits( "QMenuBar" ) ) {
- // --- Add action to the QMenuBar ---
- QMenuBar* mb = (QMenuBar*)w;
- if ( index >= 0 && index < (int)mb->count() - 1 ) {
- int id = mb->idAt( mb->count() - 1 );
- if ( id != -1 ) {
- QMenuItem* item = mb->findItem( id );
- if ( item && item->isSeparator() ) {
- mb->removeItem( id );
- mb->insertSeparator( index );
- }
- else {
- QPopupMenu* p = item ? item->popup() : 0;
- int accel = mb->accel( id );
- bool isOn = mb->isItemEnabled( id );
- bool isVisible = mb->isItemVisible( id );
- QString text = mb->text( id );
- QIconSet icon;
- if ( mb->iconSet( id ) )
- icon = *mb->iconSet( id );
- mb->removeItem( id );
- int pos;
- if ( icon.isNull() )
- if ( p )
- pos = mb->indexOf( mb->insertItem( text, p, id, index ) );
- else
- pos = mb->indexOf( mb->insertItem( text, id, index ) );
- else
- if ( p )
- pos = mb->indexOf( mb->insertItem( icon, text, p, id, index ) );
- else
- pos = mb->indexOf( mb->insertItem( icon, text, p, id, index ) );
- mb->setId( pos, id );
- mb->setAccel( accel, id );
- mb->setItemEnabled( id, isOn );
- mb->setItemVisible( id, isVisible );
- if ( !p )
- mb->connectItem( id, this, SIGNAL( activated() ) );
- }
- }
- }
- }
- return true;
}
/*!
- Name: removeFrom [virtual public]
- Desc: Removes this action from widget. Returns true if the action was removed
- successfully and false otherwise.
-*/
+ \brief Called when the action is removed from the widget.
+
+ This method can be redefined in the subclasses to customize
+ the action behavior. Base implementation does nothing.
-bool QtxAction::removeFrom( QWidget* w )
+ \param w widget (should be menu or toolbar)
+ \sa addedTo()
+*/
+void QtxAction::removedFrom( QWidget* /*w*/ )
{
- // check if widget is QMenuBar
- if ( w->inherits( "QMenuBar" ) ) {
- QMenuBar* mb = (QMenuBar*)w;
- if ( myMenuIds.find( w ) == myMenuIds.end() )
- return false; // not yet added
- mb->removeItem( myMenuIds[ w ] );
- myMenuIds.remove( w );
- return true;
- }
- return QAction::removeFrom( w );
}
/*!
- Name: setPopup [virtual public]
- Desc: Set or unset the sub popup menu for item with specified id in the given popup.
-*/
+ \brief Process notification events.
+
+ Calls addedTo() method when the action is added to the widget
+ and removedFrom() when it is removed from the widget
+ in order to perform custom processing.
-void QtxAction::setPopup( QWidget* w, const int id, QPopupMenu* subPopup ) const
+ \param e noification event
+ \sa eventFilter(), addedTo(), removedFrom()
+*/
+void QtxAction::customEvent( QEvent* e )
{
- if ( !w )
+ ActionNotify* ae = (ActionNotify*)e;
+ if ( !ae->widget() )
return;
- if ( !w->inherits( "QPopupMenu" ) && !w->inherits( "QMenuBar" ) )
- return; // unsupported widget type
+ if ( ae->isAdded() )
+ addedTo( ae->widget() );
+ else
+ removedFrom( ae->widget() );
+}
- QMenuData* md = 0;
- QMenuData* pmd = dynamic_cast<QMenuData*>( w );
- if ( !pmd )
- return; // bad widget
+/*!
+ \brief Return shortcut action name for the action.
- QMenuItem* item = pmd->findItem( id, &md );
- if ( !item || md != pmd )
- return; // item is not found
-
- QPopupMenu* oldPopup = item->popup();
- if ( oldPopup == subPopup )
- return; // popup is not changed
-
- // get properties
- int accel = pmd->accel( id );
- bool isOn = pmd->isItemEnabled( id );
- bool isVisible = pmd->isItemVisible( id );
- int pos = pmd->indexOf( id );
- QString text = pmd->text( id );
- QIconSet icon;
- if ( pmd->iconSet( id ) )
- icon = *pmd->iconSet( id );
-
- // remove previous item
- pmd->removeItem( id );
-
- // add new item
- if ( w->inherits( "QPopupMenu" ) ) {
- // --- QPopupMenu ---
- QPopupMenu* popup = (QPopupMenu*)w;
- if ( icon.isNull() )
- pos = popup->indexOf( subPopup ? popup->insertItem( text, subPopup, id, pos ) :
- popup->insertItem( text, id, pos ) );
- else
- pos = popup->indexOf( subPopup ? popup->insertItem( icon, text, subPopup, id, pos ) :
- popup->insertItem( icon, text, id, pos ) );
- }
- else {
- // --- QMenuBar ---
- QMenuBar* mb = (QMenuBar*)w;
- if ( icon.isNull() )
- pos = mb->indexOf( subPopup ? mb->insertItem( text, subPopup, id, pos ) :
- mb->insertItem( text, id, pos ) );
- else
- pos = mb->indexOf( subPopup ? mb->insertItem( icon, text, subPopup, id, pos ) :
- mb->insertItem( icon, text, id, pos ) );
- }
+ \return shortcut action name
+ \sa setShortcutActionName()
+*/
+QString QtxAction::shortcutActionName() const
+{
+ return myShortcutActionName;
+}
- // restore properties
- pmd->setId( pos, id ); // for sure (if id < 0)
- pmd->setAccel( accel, id );
- pmd->setItemEnabled( id, isOn );
- pmd->setItemVisible( id, isVisible );
+/*!
+ \brief Set shortcut action name to the action.
- // delete old popup
- delete oldPopup;
-}
+ Shortcut action name is used for shortcuts customization.
+ \param shortcutAction shortcut action name
+ \sa shortcutActionName()
+*/
+void QtxAction::setShortcutActionName( const QString& shortcutAction )
+{
+ myShortcutActionName = shortcutAction;
+}