summaryrefslogtreecommitdiffstats
path: root/src/widgets/qaction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets/qaction.cpp')
-rw-r--r--src/widgets/qaction.cpp2144
1 files changed, 2144 insertions, 0 deletions
diff --git a/src/widgets/qaction.cpp b/src/widgets/qaction.cpp
new file mode 100644
index 0000000..1e68de0
--- /dev/null
+++ b/src/widgets/qaction.cpp
@@ -0,0 +1,2144 @@
+/****************************************************************************
+**
+** Implementation of QAction class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the Qt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free Qt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at [email protected].
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.QPL
+** included in the packaging of this file. Licensees holding valid Qt
+** Commercial licenses may use this file in accordance with the Qt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "qaction.h"
+
+#ifndef QT_NO_ACTION
+
+#include "qtoolbar.h"
+#include "qptrlist.h"
+#include "qpopupmenu.h"
+#include "qaccel.h"
+#include "qtoolbutton.h"
+#include "qcombobox.h"
+#include "qtooltip.h"
+#include "qwhatsthis.h"
+#include "qstatusbar.h"
+#include "qobjectlist.h"
+
+
+/*!
+ \class QAction qaction.h
+ \brief The QAction class provides an abstract user interface
+ action that can appear both in menus and tool bars.
+
+ \ingroup basic
+ \ingroup application
+ \mainclass
+
+ In GUI applications many commands can be invoked via a menu
+ option, a toolbar button and a keyboard accelerator. Since the
+ same action must be performed regardless of how the action was
+ invoked, and since the menu and toolbar should be kept in sync, it
+ is useful to represent a command as an \e action. An action can be
+ added to a menu and a toolbar and will automatically keep them in
+ sync. For example, if the user presses a Bold toolbar button the
+ Bold menu item will automatically be checked.
+
+ A QAction may contain an icon, a menu text, an accelerator, a
+ status text, a whats this text and a tool tip. Most of these can
+ be set in the constructor. They can also be set independently with
+ setIconSet(), setText(), setMenuText(), setToolTip(),
+ setStatusTip(), setWhatsThis() and setAccel().
+
+ An action may be a toggle action e.g. a Bold toolbar button, or a
+ command action, e.g. 'Open File' to invoke an open file dialog.
+ Toggle actions emit the toggled() signal when their state changes.
+ Both command and toggle actions emit the activated() signal when
+ they are invoked. Use setToggleAction() to set an action's toggled
+ status. To see if an action is a toggle action use
+ isToggleAction(). A toggle action may be "on", isOn() returns
+ TRUE, or "off", isOn() returns FALSE.
+
+ Actions are added to widgets (menus or toolbars) using addTo(),
+ and removed using removeFrom().
+
+ Once a QAction has been created it should be added to the relevant
+ menu and toolbar and then connected to the slot which will perform
+ the action. For example:
+
+ \quotefile action/application.cpp
+ \skipto QPixmap( fileopen
+ \printuntil connect
+
+ We create a "File Save" action with a menu text of "&Save" and
+ \e{Ctrl+S} as the keyboard accelerator. We connect the
+ fileSaveAction's activated() signal to our own save() slot. Note
+ that at this point there is no menu or toolbar action, we'll add
+ them next:
+
+ \skipto new QToolBar
+ \printline
+ \skipto fileSaveAction->addTo
+ \printline
+ \skipto new QPopupMenu
+ \printuntil insertItem
+ \skipto fileSaveAction->addTo
+ \printline
+
+ We create a toolbar and add our fileSaveAction to it. Similarly we
+ create a menu, add a top-level menu item, and add our
+ fileSaveAction.
+
+ We recommend that actions are created as children of the window
+ that they are used in. In most cases actions will be children of
+ the application's main window.
+
+ To prevent recursion, don't create an action as a child of a
+ widget that the action is later added to.
+*/
+
+class QActionPrivate
+{
+public:
+ QActionPrivate(QAction *act);
+ ~QActionPrivate();
+ QIconSet *iconset;
+ QString text;
+ QString menutext;
+ QString tooltip;
+ QString statustip;
+ QString whatsthis;
+#ifndef QT_NO_ACCEL
+ QKeySequence key;
+ QAccel* accel;
+ int accelid;
+#endif
+ uint enabled : 1;
+ uint visible : 1;
+ uint toggleaction : 1;
+ uint on : 1;
+ uint forceDisabled : 1;
+ uint forceInvisible : 1;
+#ifndef QT_NO_TOOLTIP
+ QToolTipGroup tipGroup;
+#endif
+ QActionGroupPrivate* d_group;
+ QAction *action;
+
+ struct MenuItem {
+ MenuItem():popup(0),id(0){}
+ QPopupMenu* popup;
+ int id;
+ };
+ // ComboItem is only necessary for actions that are
+ // in dropdown/exclusive actiongroups. The actiongroup
+ // will clean this up
+ struct ComboItem {
+ ComboItem():combo(0), id(0) {}
+ QComboBox *combo;
+ int id;
+ };
+ QPtrList<MenuItem> menuitems;
+ QPtrList<QToolButton> toolbuttons;
+ QPtrList<ComboItem> comboitems;
+
+ enum Update { Icons = 1, Visibility = 2, State = 4, EverythingElse = 8 };
+ void update( uint upd = EverythingElse );
+
+ QString menuText() const;
+ QString toolTip() const;
+ QString statusTip() const;
+};
+
+QActionPrivate::QActionPrivate(QAction *act)
+ : iconset( 0 ),
+#ifndef QT_NO_ACCEL
+ key( 0 ), accel( 0 ), accelid( 0 ),
+#endif
+ enabled( TRUE ), visible( TRUE ), toggleaction( FALSE ), on( FALSE ),
+ forceDisabled( FALSE ), forceInvisible( FALSE ),
+#ifndef QT_NO_TOOLTIP
+ tipGroup( 0 ),
+#endif
+ d_group( 0 ), action(act)
+{
+ menuitems.setAutoDelete( TRUE );
+ comboitems.setAutoDelete( TRUE );
+#ifndef QT_NO_TOOLTIP
+ tipGroup.setDelay( FALSE );
+#endif
+}
+
+QActionPrivate::~QActionPrivate()
+{
+ QPtrListIterator<QToolButton> ittb( toolbuttons );
+ QToolButton *tb;
+
+ while ( ( tb = ittb.current() ) ) {
+ ++ittb;
+ delete tb;
+ }
+
+ QPtrListIterator<QActionPrivate::MenuItem> itmi( menuitems);
+ QActionPrivate::MenuItem* mi;
+ while ( ( mi = itmi.current() ) ) {
+ ++itmi;
+ QPopupMenu* menu = mi->popup;
+ if ( menu->findItem( mi->id ) )
+ menu->removeItem( mi->id );
+ }
+
+ QPtrListIterator<QActionPrivate::ComboItem> itci(comboitems);
+ QActionPrivate::ComboItem* ci;
+ while ( ( ci = itci.current() ) ) {
+ ++itci;
+ QComboBox* combo = ci->combo;
+ combo->clear();
+ QActionGroup *group = ::qt_cast<QActionGroup*>(action->parent());
+ QObjectList *siblings = group ? group->queryList("QAction") : 0;
+ if (siblings) {
+ QObjectListIt it(*siblings);
+ while (it.current()) {
+ QAction *sib = ::qt_cast<QAction*>(it.current());
+ ++it;
+ sib->removeFrom(combo);
+ }
+ it = QObjectListIt(*siblings);
+ while (it.current()) {
+ QAction *sib = ::qt_cast<QAction*>(it.current());
+ ++it;
+ if (sib == action)
+ continue;
+ sib->addTo(combo);
+ }
+ }
+ delete siblings;
+ }
+
+#ifndef QT_NO_ACCEL
+ delete accel;
+#endif
+ delete iconset;
+}
+
+class QActionGroupPrivate
+{
+public:
+ uint exclusive: 1;
+ uint dropdown: 1;
+ QPtrList<QAction> actions;
+ QAction* selected;
+ QAction* separatorAction;
+
+ struct MenuItem {
+ MenuItem():popup(0),id(0){}
+ QPopupMenu* popup;
+ int id;
+ };
+
+ QPtrList<QComboBox> comboboxes;
+ QPtrList<QToolButton> menubuttons;
+ QPtrList<MenuItem> menuitems;
+ QPtrList<QPopupMenu> popupmenus;
+
+ void update( const QActionGroup * );
+};
+
+void QActionPrivate::update( uint upd )
+{
+ for ( QPtrListIterator<MenuItem> it( menuitems); it.current(); ++it ) {
+ MenuItem* mi = it.current();
+ QString t = menuText();
+#ifndef QT_NO_ACCEL
+ if ( key )
+ t += '\t' + QAccel::keyToString( key );
+#endif
+ if ( upd & State ) {
+ mi->popup->setItemEnabled( mi->id, enabled );
+ if ( toggleaction )
+ mi->popup->setItemChecked( mi->id, on );
+ }
+ if ( upd & Visibility )
+ mi->popup->setItemVisible( mi->id, visible );
+
+ if ( upd & Icons )
+ if ( iconset )
+ mi->popup->changeItem( mi->id, *iconset, t );
+ else
+ mi->popup->changeItem( mi->id, QIconSet(), t );
+ if ( upd & EverythingElse ) {
+ mi->popup->changeItem( mi->id, t );
+ if ( !whatsthis.isEmpty() )
+ mi->popup->setWhatsThis( mi->id, whatsthis );
+ if ( toggleaction ) {
+ mi->popup->setCheckable( TRUE );
+ mi->popup->setItemChecked( mi->id, on );
+ }
+ }
+ }
+ for ( QPtrListIterator<QToolButton> it2(toolbuttons); it2.current(); ++it2 ) {
+ QToolButton* btn = it2.current();
+ if ( upd & State ) {
+ btn->setEnabled( enabled );
+ if ( toggleaction )
+ btn->setOn( on );
+ }
+ if ( upd & Visibility )
+ visible ? btn->show() : btn->hide();
+ if ( upd & Icons ) {
+ if ( iconset )
+ btn->setIconSet( *iconset );
+ else
+ btn->setIconSet( QIconSet() );
+ }
+ if ( upd & EverythingElse ) {
+ btn->setToggleButton( toggleaction );
+ if ( !text.isEmpty() )
+ btn->setTextLabel( text, FALSE );
+#ifndef QT_NO_TOOLTIP
+ QToolTip::remove( btn );
+ QToolTip::add( btn, toolTip(), &tipGroup, statusTip() );
+#endif
+#ifndef QT_NO_WHATSTHIS
+ QWhatsThis::remove( btn );
+ if ( !whatsthis.isEmpty() )
+ QWhatsThis::add( btn, whatsthis );
+#endif
+ }
+ }
+#ifndef QT_NO_ACCEL
+ if ( accel ) {
+ accel->setEnabled( enabled && visible );
+ if ( !whatsthis.isEmpty() )
+ accel->setWhatsThis( accelid, whatsthis );
+ }
+#endif
+ // Only used by actiongroup
+ for ( QPtrListIterator<ComboItem> it3( comboitems ); it3.current(); ++it3 ) {
+ ComboItem *ci = it3.current();
+ if ( !ci->combo )
+ return;
+ if ( iconset )
+ ci->combo->changeItem( iconset->pixmap(), text, ci->id );
+ else
+ ci->combo->changeItem( text, ci->id );
+ }
+}
+
+QString QActionPrivate::menuText() const
+{
+ if ( menutext.isNull() ) {
+ QString t(text);
+ t.replace('&', "&&");
+ return t;
+ }
+ return menutext;
+}
+
+QString QActionPrivate::toolTip() const
+{
+ if ( tooltip.isNull() ) {
+#ifndef QT_NO_ACCEL
+ if ( accel )
+ return text + " (" + QAccel::keyToString( accel->key( accelid )) + ")";
+#endif
+ return text;
+ }
+ return tooltip;
+}
+
+QString QActionPrivate::statusTip() const
+{
+ if ( statustip.isNull() )
+ return toolTip();
+ return statustip;
+}
+
+/*
+ internal: guesses a descriptive text from a menu text
+ */
+static QString qt_stripMenuText( QString s )
+{
+ s.remove( QString::fromLatin1("...") );
+ s.remove( QChar('&' ) );
+ return s.stripWhiteSpace();
+}
+
+/*!
+ Constructs an action called \a name with parent \a parent.
+
+ If \a parent is a QActionGroup, the new action inserts itself into
+ \a parent.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+QAction::QAction( QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ init();
+}
+
+/*! \obsolete
+ Constructs an action called \a name with parent \a parent.
+
+ If \a toggle is TRUE the action will be a toggle action, otherwise
+ it will be a command action.
+
+ If \a parent is a QActionGroup, the new action inserts itself into
+ \a parent.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+*/
+QAction::QAction( QObject* parent, const char* name, bool toggle )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ d->toggleaction = toggle;
+ init();
+}
+
+
+#ifndef QT_NO_ACCEL
+
+/*!
+ This constructor creates an action with the following properties:
+ the icon or iconset \a icon, the menu text \a menuText and
+ keyboard accelerator \a accel. It is a child of \a parent and
+ called \a name.
+
+ If \a parent is a QActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+
+ The action uses a stripped version of \a menuText (e.g. "\&Menu
+ Option..." becomes "Menu Option") as descriptive text for
+ toolbuttons. You can override this by setting a specific
+ description with setText(). The same text and \a accel will be
+ used for tool tips and status tips unless you provide text for
+ these using setToolTip() and setStatusTip().
+
+ Call setToggleAction(TRUE) to make the action a toggle action.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+QAction::QAction( const QIconSet& icon, const QString& menuText, QKeySequence accel,
+ QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ if ( !icon.isNull() )
+ setIconSet( icon );
+ d->text = qt_stripMenuText( menuText );
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*!
+ This constructor results in an icon-less action with the the menu
+ text \a menuText and keyboard accelerator \a accel. It is a child
+ of \a parent and called \a name.
+
+ If \a parent is a QActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+
+ The action uses a stripped version of \a menuText (e.g. "\&Menu
+ Option..." becomes "Menu Option") as descriptive text for
+ toolbuttons. You can override this by setting a specific
+ description with setText(). The same text and \a accel will be
+ used for tool tips and status tips unless you provide text for
+ these using setToolTip() and setStatusTip().
+
+ Call setToggleAction(TRUE) to make the action a toggle action.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+QAction::QAction( const QString& menuText, QKeySequence accel,
+ QObject* parent, const char* name )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ d->text = qt_stripMenuText( menuText );
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*! \obsolete
+ This constructor creates an action with the following properties:
+ the description \a text, the icon or iconset \a icon, the menu
+ text \a menuText and keyboard accelerator \a accel. It is a child
+ of \a parent and called \a name. If \a toggle is TRUE the action
+ will be a toggle action, otherwise it will be a command action.
+
+ If \a parent is a QActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+
+ The \a text and \a accel will be used for tool tips and status
+ tips unless you provide specific text for these using setToolTip()
+ and setStatusTip().
+*/
+QAction::QAction( const QString& text, const QIconSet& icon, const QString& menuText, QKeySequence accel, QObject* parent, const char* name, bool toggle )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ d->toggleaction = toggle;
+ if ( !icon.isNull() )
+ setIconSet( icon );
+
+ d->text = text;
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*! \obsolete
+ This constructor results in an icon-less action with the
+ description \a text, the menu text \a menuText and the keyboard
+ accelerator \a accel. Its parent is \a parent and it is called \a
+ name. If \a toggle is TRUE the action will be a toggle action,
+ otherwise it will be a command action.
+
+ The action automatically becomes a member of \a parent if \a
+ parent is a QActionGroup.
+
+ For accelerators and status tips to work, \a parent must either be
+ a widget, or an action group whose parent is a widget.
+
+ The \a text and \a accel will be used for tool tips and status
+ tips unless you provide specific text for these using setToolTip()
+ and setStatusTip().
+*/
+QAction::QAction( const QString& text, const QString& menuText, QKeySequence accel, QObject* parent, const char* name, bool toggle )
+ : QObject( parent, name )
+{
+ d = new QActionPrivate(this);
+ d->toggleaction = toggle;
+ d->text = text;
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+#endif
+
+/*!
+ \internal
+*/
+void QAction::init()
+{
+ if ( ::qt_cast<QActionGroup*>(parent()) )
+ ((QActionGroup*) parent())->add( this ); // insert into action group
+}
+
+/*!
+ Destroys the object and frees allocated resources.
+*/
+
+QAction::~QAction()
+{
+ delete d;
+}
+
+/*!
+ \property QAction::iconSet
+ \brief the action's icon
+
+ The icon is used as the tool button icon and in the menu to the
+ left of the menu text. There is no default icon.
+
+ If a null icon (QIconSet::isNull() is passed into this function,
+ the icon of the action is cleared.
+
+ (See the action/toggleaction/toggleaction.cpp example.)
+
+*/
+void QAction::setIconSet( const QIconSet& icon )
+{
+ register QIconSet *i = d->iconset;
+ if ( !icon.isNull() )
+ d->iconset = new QIconSet( icon );
+ else
+ d->iconset = 0;
+ delete i;
+ d->update( QActionPrivate::Icons );
+}
+
+QIconSet QAction::iconSet() const
+{
+ if ( d->iconset )
+ return *d->iconset;
+ return QIconSet();
+}
+
+/*!
+ \property QAction::text
+ \brief the action's descriptive text
+
+ If \l QMainWindow::usesTextLabel is TRUE, the text appears as a
+ label in the relevant tool button. It also serves as the default
+ text in menus and tool tips if these have not been specifically
+ defined. There is no default text.
+
+ \sa setMenuText() setToolTip() setStatusTip()
+*/
+void QAction::setText( const QString& text )
+{
+ d->text = text;
+ d->update();
+}
+
+QString QAction::text() const
+{
+ return d->text;
+}
+
+
+/*!
+ \property QAction::menuText
+ \brief the action's menu text
+
+ If the action is added to a menu the menu option will consist of
+ the icon (if there is one), the menu text and the accelerator (if
+ there is one). If the menu text is not explicitly set in the
+ constructor or by using setMenuText() the action's description
+ text will be used as the menu text. There is no default menu text.
+
+ \sa text
+*/
+void QAction::setMenuText( const QString& text )
+{
+ if ( d->menutext == text )
+ return;
+
+ d->menutext = text;
+ d->update();
+}
+
+QString QAction::menuText() const
+{
+ return d->menuText();
+}
+
+/*!
+ \property QAction::toolTip
+ \brief the action's tool tip
+
+ This text is used for the tool tip. If no status tip has been set
+ the tool tip will be used for the status tip.
+
+ If no tool tip is specified the action's text is used, and if that
+ hasn't been specified the description text is used as the tool tip
+ text.
+
+ There is no default tool tip text.
+
+ \sa setStatusTip() setAccel()
+*/
+void QAction::setToolTip( const QString& tip )
+{
+ if ( d->tooltip == tip )
+ return;
+
+ d->tooltip = tip;
+ d->update();
+}
+
+QString QAction::toolTip() const
+{
+ return d->toolTip();
+}
+
+/*!
+ \property QAction::statusTip
+ \brief the action's status tip
+
+ The statusTip is displayed on all status bars that this action's
+ toplevel parent widget provides.
+
+ If no status tip is defined, the action uses the tool tip text.
+
+ There is no default statusTip text.
+
+ \sa setStatusTip() setToolTip()
+*/
+//#### Please reimp for QActionGroup!
+//#### For consistency reasons even action groups should show
+//#### status tips (as they already do with tool tips)
+//#### Please change QActionGroup class doc appropriately after
+//#### reimplementation.
+void QAction::setStatusTip( const QString& tip )
+{
+ if ( d->statustip == tip )
+ return;
+
+ d->statustip = tip;
+ d->update();
+}
+
+QString QAction::statusTip() const
+{
+ return d->statusTip();
+}
+
+/*!
+ \property QAction::whatsThis
+ \brief the action's "What's This?" help text
+
+ The whats this text is used to provide a brief description of the
+ action. The text may contain rich text (HTML-like tags -- see
+ QStyleSheet for the list of supported tags). There is no default
+ "What's This" text.
+
+ \sa QWhatsThis
+*/
+void QAction::setWhatsThis( const QString& whatsThis )
+{
+ if ( d->whatsthis == whatsThis )
+ return;
+ d->whatsthis = whatsThis;
+ d->update();
+}
+
+QString QAction::whatsThis() const
+{
+ return d->whatsthis;
+}
+
+
+#ifndef QT_NO_ACCEL
+/*!
+ \property QAction::accel
+ \brief the action's accelerator key
+
+ The keycodes can be found in \l Qt::Key and \l Qt::Modifier. There
+ is no default accelerator key.
+*/
+//#### Please reimp for QActionGroup!
+//#### For consistency reasons even QActionGroups should respond to
+//#### their accelerators and e.g. open the relevant submenu.
+//#### Please change appropriate QActionGroup class doc after
+//#### reimplementation.
+void QAction::setAccel( const QKeySequence& key )
+{
+ if ( d->key == key )
+ return;
+
+ d->key = key;
+ delete d->accel;
+ d->accel = 0;
+
+ if ( !(int)key ) {
+ d->update();
+ return;
+ }
+
+ QObject* p = parent();
+ while ( p && !p->isWidgetType() ) {
+ p = p->parent();
+ }
+ if ( p ) {
+ d->accel = new QAccel( (QWidget*)p, this, "qt_action_accel" );
+ d->accelid = d->accel->insertItem( d->key );
+ d->accel->connectItem( d->accelid, this, SLOT( internalActivation() ) );
+ }
+#if defined(QT_CHECK_STATE)
+ else
+ qWarning( "QAction::setAccel() (%s) requires widget in parent chain", name() );
+#endif
+ d->update();
+}
+
+
+QKeySequence QAction::accel() const
+{
+ return d->key;
+}
+#endif
+
+
+/*!
+ \property QAction::toggleAction
+ \brief whether the action is a toggle action
+
+ A toggle action is one which has an on/off state. For example a
+ Bold toolbar button is either on or off. An action which is not a
+ toggle action is a command action; a command action is simply
+ executed, e.g. file save. This property's default is FALSE.
+
+ In some situations, the state of one toggle action should depend
+ on the state of others. For example, "Left Align", "Center" and
+ "Right Align" toggle actions are mutually exclusive. To achieve
+ exclusive toggling, add the relevant toggle actions to a
+ QActionGroup with the \l QActionGroup::exclusive property set to
+ TRUE.
+*/
+void QAction::setToggleAction( bool enable )
+{
+ if ( enable == (bool)d->toggleaction )
+ return;
+
+ if ( !enable )
+ d->on = FALSE;
+
+ d->toggleaction = enable;
+ d->update();
+}
+
+bool QAction::isToggleAction() const
+{
+ return d->toggleaction;
+}
+
+/*!
+ Activates the action and executes all connected slots.
+ This only works for actions that are not toggle action.
+
+ \sa toggle()
+*/
+void QAction::activate()
+{
+ if ( isToggleAction() ) {
+#if defined(QT_CHECK_STATE)
+ qWarning( "QAction::%s() (%s) Toggle actions "
+ "can not be activated", "activate", name() );
+#endif
+ return;
+ }
+ emit activated();
+}
+
+/*!
+ Toggles the state of a toggle action.
+
+ \sa on, activate(), toggled(), isToggleAction()
+*/
+void QAction::toggle()
+{
+ if ( !isToggleAction() ) {
+#if defined(QT_CHECK_STATE)
+ qWarning( "QAction::%s() (%s) Only toggle actions "
+ "can be switched", "toggle", name() );
+#endif
+ return;
+ }
+ setOn( !isOn() );
+}
+
+/*!
+ \property QAction::on
+ \brief whether a toggle action is on
+
+ This property is always on (TRUE) for command actions and
+ \l{QActionGroup}s; setOn() has no effect on them. For action's
+ where isToggleAction() is TRUE, this property's default value is
+ off (FALSE).
+
+ \sa toggleAction
+*/
+void QAction::setOn( bool enable )
+{
+ if ( !isToggleAction() ) {
+#if defined(QT_CHECK_STATE)
+ if ( enable )
+ qWarning( "QAction::%s() (%s) Only toggle actions "
+ "can be switched", "setOn", name() );
+#endif
+ return;
+ }
+ if ( enable == (bool)d->on )
+ return;
+ d->on = enable;
+ d->update( QActionPrivate::State );
+ emit toggled( enable );
+}
+
+bool QAction::isOn() const
+{
+ return d->on;
+}
+
+/*!
+ \property QAction::enabled
+ \brief whether the action is enabled
+
+ Disabled actions can't be chosen by the user. They don't disappear
+ from the menu/tool bar but are displayed in a way which indicates
+ that they are unavailable, e.g. they might be displayed grayed
+ out.
+
+ What's this? help on disabled actions is still available provided
+ the \l QAction::whatsThis property is set.
+*/
+void QAction::setEnabled( bool enable )
+{
+ d->forceDisabled = !enable;
+
+ if ( (bool)d->enabled == enable )
+ return;
+
+ d->enabled = enable;
+ d->update( QActionPrivate::State );
+}
+
+bool QAction::isEnabled() const
+{
+ return d->enabled;
+}
+
+/*!
+ Disables the action if \a disable is TRUE; otherwise
+ enables the action.
+
+ See the \l enabled documentation for more information.
+*/
+void QAction::setDisabled( bool disable )
+{
+ setEnabled( !disable );
+}
+
+/*!
+ \property QAction::visible
+ \brief whether the action can be seen (e.g. in menus and toolbars)
+
+ If \e visible is TRUE the action can be seen (e.g. in menus and
+ toolbars) and chosen by the user; if \e visible is FALSE the
+ action cannot be seen or chosen by the user.
+
+ Actions which are not visible are \e not grayed out; they do not
+ appear at all.
+*/
+void QAction::setVisible( bool visible )
+{
+ d->forceInvisible = !visible;
+
+ if ( (bool)d->visible == visible )
+ return;
+ d->visible = visible;
+ d->update( QActionPrivate::Visibility );
+#if (QT_VERSION-0 >= 0x040000)
+#error "QAction::setVisible function wants to be virtual. Also add virtual change() function"
+#endif
+ if ( d->d_group ) //### this function wants to be virtual in 4.0
+ d->d_group->update( (QActionGroup*) this );
+}
+
+/*
+ Returns TRUE if the action is visible (e.g. in menus and
+ toolbars); otherwise returns FALSE.
+*/
+bool QAction::isVisible() const
+{
+ return d->visible;
+}
+
+/*! \internal
+*/
+void QAction::internalActivation()
+{
+ if ( isToggleAction() )
+ setOn( !isOn() );
+ emit activated();
+}
+
+/*! \internal
+*/
+void QAction::toolButtonToggled( bool on )
+{
+ if ( !isToggleAction() )
+ return;
+ setOn( on );
+}
+
+/*!
+ Adds this action to widget \a w.
+
+ Currently actions may be added to QToolBar and QPopupMenu widgets.
+
+ An action added to a tool bar is automatically displayed as a tool
+ button; an action added to a pop up menu appears as a menu option.
+
+ addTo() returns TRUE if the action was added successfully and
+ FALSE otherwise. (If \a w is not a QToolBar or QPopupMenu the
+ action will not be added and FALSE will be returned.)
+
+ \sa removeFrom()
+*/
+bool QAction::addTo( QWidget* w )
+{
+#ifndef QT_NO_TOOLBAR
+ if ( ::qt_cast<QToolBar*>(w) ) {
+ if ( !qstrcmp( name(), "qt_separator_action" ) ) {
+ ((QToolBar*)w)->addSeparator();
+ } else {
+ QCString bname = name() + QCString( "_action_button" );
+ QToolButton* btn = new QToolButton( (QToolBar*) w, bname );
+ addedTo( btn, w );
+ btn->setToggleButton( d->toggleaction );
+ d->toolbuttons.append( btn );
+ if ( d->iconset )
+ btn->setIconSet( *d->iconset );
+ d->update( QActionPrivate::State | QActionPrivate::Visibility | QActionPrivate::EverythingElse ) ;
+ connect( btn, SIGNAL( clicked() ), this, SIGNAL( activated() ) );
+ connect( btn, SIGNAL( toggled(bool) ), this, SLOT( toolButtonToggled(bool) ) );
+ connect( btn, SIGNAL( destroyed() ), this, SLOT( objectDestroyed() ) );
+#ifndef QT_NO_TOOLTIP
+ connect( &(d->tipGroup), SIGNAL(showTip(const QString&)), this, SLOT(showStatusText(const QString&)) );
+ connect( &(d->tipGroup), SIGNAL(removeTip()), this, SLOT(clearStatusText()) );
+#endif
+ }
+ } else
+#endif
+ if ( ::qt_cast<QPopupMenu*>(w) ) {
+ QActionPrivate::MenuItem* mi = new QActionPrivate::MenuItem;
+ mi->popup = (QPopupMenu*) w;
+ QIconSet* diconset = d->iconset;
+ if ( !qstrcmp( name(), "qt_separator_action" ) )
+ mi->id = ((QPopupMenu*)w)->insertSeparator();
+ else if ( diconset )
+ mi->id = mi->popup->insertItem( *diconset, QString::fromLatin1("") );
+ else
+ mi->id = mi->popup->insertItem( QString::fromLatin1("") );
+ addedTo( mi->popup->indexOf( mi->id ), mi->popup );
+ mi->popup->connectItem( mi->id, this, SLOT(internalActivation()) );
+ d->menuitems.append( mi );
+ d->update( QActionPrivate::State | QActionPrivate::Visibility | QActionPrivate::EverythingElse ) ;
+ w->topLevelWidget()->className();
+ connect( mi->popup, SIGNAL(highlighted(int)), this, SLOT(menuStatusText(int)) );
+ connect( mi->popup, SIGNAL(aboutToHide()), this, SLOT(clearStatusText()) );
+ connect( mi->popup, SIGNAL( destroyed() ), this, SLOT( objectDestroyed() ) );
+ // Makes only sense when called by QActionGroup::addTo
+ } else if ( ::qt_cast<QComboBox*>(w) ) {
+ QActionPrivate::ComboItem *ci = new QActionPrivate::ComboItem;
+ ci->combo = (QComboBox*)w;
+ connect( ci->combo, SIGNAL( destroyed() ), this, SLOT( objectDestroyed() ) );
+ ci->id = ci->combo->count();
+ if ( qstrcmp( name(), "qt_separator_action" ) ) {
+ if ( d->iconset )
+ ci->combo->insertItem( d->iconset->pixmap(), text() );
+ else
+ ci->combo->insertItem( text() );
+ } else {
+ ci->id = -1;
+ }
+ d->comboitems.append( ci );
+
+ d->update( QActionPrivate::State | QActionPrivate::EverythingElse );
+ } else {
+ qWarning( "QAction::addTo(), unknown object" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) for the action in the \a
+ container.
+*/
+
+void QAction::addedTo( QWidget *actionWidget, QWidget *container )
+{
+ Q_UNUSED( actionWidget );
+ Q_UNUSED( container );
+}
+
+/*!
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a menu item at the index position \a index in the popup
+ menu \a menu.
+*/
+
+void QAction::addedTo( int index, QPopupMenu *menu )
+{
+ Q_UNUSED( index );
+ Q_UNUSED( menu );
+}
+
+/*!
+ Sets the status message to \a text
+*/
+void QAction::showStatusText( const QString& text )
+{
+#ifndef QT_NO_STATUSBAR
+ // find out whether we are clearing the status bar by the popup that actually set the text
+ static QPopupMenu *lastmenu = 0;
+ QObject *s = (QObject*)sender();
+ if ( s ) {
+ QPopupMenu *menu = (QPopupMenu*)s->qt_cast( "QPopupMenu" );
+ if ( menu && !!text )
+ lastmenu = menu;
+ else if ( menu && text.isEmpty() ) {
+ if ( lastmenu && menu != lastmenu )
+ return;
+ lastmenu = 0;
+ }
+ }
+
+ QObject* par = parent();
+ QObject* lpar = 0;
+ QStatusBar *bar = 0;
+ while ( par && !bar ) {
+ lpar = par;
+ bar = (QStatusBar*)par->child( 0, "QStatusBar", FALSE );
+ par = par->parent();
+ }
+ if ( !bar && lpar ) {
+ QObjectList *l = lpar->queryList( "QStatusBar" );
+ if ( !l )
+ return;
+ // #### hopefully the last one is the one of the mainwindow...
+ bar = (QStatusBar*)l->last();
+ delete l;
+ }
+ if ( bar ) {
+ if ( text.isEmpty() )
+ bar->clear();
+ else
+ bar->message( text );
+ }
+#endif
+}
+
+/*!
+ Sets the status message to the menu item's status text, or to the
+ tooltip, if there is no status text.
+*/
+void QAction::menuStatusText( int id )
+{
+ static int lastId = 0;
+ QString text;
+ QPtrListIterator<QActionPrivate::MenuItem> it( d->menuitems);
+ QActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( mi->id == id ) {
+ text = statusTip();
+ break;
+ }
+ }
+
+ if ( !text.isEmpty() )
+ showStatusText( text );
+ else if ( id != lastId )
+ clearStatusText();
+ lastId = id;
+}
+
+/*!
+ Clears the status text.
+*/
+void QAction::clearStatusText()
+{
+ if (!statusTip().isEmpty())
+ showStatusText( QString::null );
+}
+
+/*!
+ Removes the action from widget \a w.
+
+ Returns TRUE if the action was removed successfully; otherwise
+ returns FALSE.
+
+ \sa addTo()
+*/
+bool QAction::removeFrom( QWidget* w )
+{
+#ifndef QT_NO_TOOLBAR
+ if ( ::qt_cast<QToolBar*>(w) ) {
+ QPtrListIterator<QToolButton> it( d->toolbuttons);
+ QToolButton* btn;
+ while ( ( btn = it.current() ) ) {
+ ++it;
+ if ( btn->parentWidget() == w ) {
+ d->toolbuttons.removeRef( btn );
+ disconnect( btn, SIGNAL( destroyed() ), this, SLOT( objectDestroyed() ) );
+ delete btn;
+ // no need to disconnect from statusbar
+ }
+ }
+ } else
+#endif
+ if ( ::qt_cast<QPopupMenu*>(w) ) {
+ QPtrListIterator<QActionPrivate::MenuItem> it( d->menuitems);
+ QActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( mi->popup == w ) {
+ disconnect( mi->popup, SIGNAL(highlighted(int)), this, SLOT(menuStatusText(int)) );
+ disconnect( mi->popup, SIGNAL(aboutToHide()), this, SLOT(clearStatusText()) );
+ disconnect( mi->popup, SIGNAL( destroyed() ), this, SLOT( objectDestroyed() ) );
+ mi->popup->removeItem( mi->id );
+ d->menuitems.removeRef( mi );
+ }
+ }
+ } else if ( ::qt_cast<QComboBox*>(w) ) {
+ QPtrListIterator<QActionPrivate::ComboItem> it( d->comboitems );
+ QActionPrivate::ComboItem *ci;
+ while ( ( ci = it.current() ) ) {
+ ++it;
+ if ( ci->combo == w ) {
+ disconnect( ci->combo, SIGNAL(destroyed()), this, SLOT(objectDestroyed()) );
+ d->comboitems.removeRef( ci );
+ }
+ }
+ } else {
+ qWarning( "QAction::removeFrom(), unknown object" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+void QAction::objectDestroyed()
+{
+ const QObject* obj = sender();
+ QPtrListIterator<QActionPrivate::MenuItem> it( d->menuitems );
+ QActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( mi->popup == obj )
+ d->menuitems.removeRef( mi );
+ }
+ QActionPrivate::ComboItem *ci;
+ QPtrListIterator<QActionPrivate::ComboItem> it2( d->comboitems );
+ while ( ( ci = it2.current() ) ) {
+ ++it2;
+ if ( ci->combo == obj )
+ d->comboitems.removeRef( ci );
+ }
+ d->toolbuttons.removeRef( (QToolButton*) obj );
+}
+
+/*!
+ \fn void QAction::activated()
+
+ This signal is emitted when an action is activated by the user,
+ e.g. when the user clicks a menu option or a toolbar button or
+ presses an action's accelerator key combination.
+
+ Connect to this signal for command actions. Connect to the
+ toggled() signal for toggle actions.
+*/
+
+/*!
+ \fn void QAction::toggled(bool on)
+
+ This signal is emitted when a toggle action changes state; command
+ actions and \l{QActionGroup}s don't emit toggled().
+
+ The \a on argument denotes the new state: If \a on is TRUE the
+ toggle action is switched on, and if \a on is FALSE the toggle
+ action is switched off.
+
+ To trigger a user command depending on whether a toggle action has
+ been switched on or off connect it to a slot that takes a bool to
+ indicate the state, e.g.
+
+ \quotefile action/toggleaction/toggleaction.cpp
+ \skipto QMainWindow * window
+ \printline QMainWindow * window
+ \skipto labelonoffaction
+ \printline labelonoffaction
+ \skipto connect
+ \printuntil setUsesTextLabel
+
+ \sa activated() setToggleAction() setOn()
+*/
+
+void QActionGroupPrivate::update( const QActionGroup* that )
+{
+ for ( QPtrListIterator<QAction> it( actions ); it.current(); ++it ) {
+ if ( that->isEnabled() && !it.current()->d->forceDisabled ) {
+ it.current()->setEnabled( TRUE );
+ } else if ( !that->isEnabled() && it.current()->isEnabled() ) {
+ it.current()->setEnabled( FALSE );
+ it.current()->d->forceDisabled = FALSE;
+ }
+ if ( that->isVisible() && !it.current()->d->forceInvisible ) {
+ it.current()->setVisible( TRUE );
+ } else if ( !that->isVisible() && it.current()->isVisible() ) {
+ it.current()->setVisible( FALSE );
+ it.current()->d->forceInvisible = FALSE;
+ }
+ }
+ for ( QPtrListIterator<QComboBox> cb( comboboxes ); cb.current(); ++cb ) {
+ QComboBox *combobox = cb.current();
+ combobox->setEnabled( that->isEnabled() );
+ combobox->setShown( that->isVisible() );
+
+#ifndef QT_NO_TOOLTIP
+ QToolTip::remove( combobox );
+ if ( !!that->toolTip() )
+ QToolTip::add( combobox, that->toolTip() );
+#endif
+#ifndef QT_NO_WHATSTHIS
+ QWhatsThis::remove( combobox );
+ if ( !!that->whatsThis() )
+ QWhatsThis::add( combobox, that->whatsThis() );
+#endif
+
+ }
+ for ( QPtrListIterator<QToolButton> mb( menubuttons ); mb.current(); ++mb ) {
+ QToolButton *button = mb.current();
+ button->setEnabled( that->isEnabled() );
+ button->setShown( that->isVisible() );
+
+ if ( !that->text().isNull() )
+ button->setTextLabel( that->text() );
+ if ( !that->iconSet().isNull() )
+ button->setIconSet( that->iconSet() );
+
+#ifndef QT_NO_TOOLTIP
+ QToolTip::remove( mb.current() );
+ if ( !!that->toolTip() )
+ QToolTip::add( button, that->toolTip() );
+#endif
+#ifndef QT_NO_WHATSTHIS
+ QWhatsThis::remove( button );
+ if ( !!that->whatsThis() )
+ QWhatsThis::add( button, that->whatsThis() );
+#endif
+ }
+ for ( QPtrListIterator<QActionGroupPrivate::MenuItem> pu( menuitems ); pu.current(); ++pu ) {
+ QWidget* parent = pu.current()->popup->parentWidget();
+ if ( ::qt_cast<QPopupMenu*>(parent) ) {
+ QPopupMenu* ppopup = (QPopupMenu*)parent;
+ ppopup->setItemEnabled( pu.current()->id, that->isEnabled() );
+ ppopup->setItemVisible( pu.current()->id, that->isVisible() );
+ } else {
+ pu.current()->popup->setEnabled( that->isEnabled() );
+ }
+ }
+ for ( QPtrListIterator<QPopupMenu> pm( popupmenus ); pm.current(); ++pm ) {
+ QPopupMenu *popup = pm.current();
+ QPopupMenu *parent = ::qt_cast<QPopupMenu*>(popup->parentWidget());
+ if ( !parent )
+ continue;
+
+ int index;
+ parent->findPopup( popup, &index );
+ int id = parent->idAt( index );
+ if ( !that->iconSet().isNull() )
+ parent->changeItem( id, that->iconSet(), that->menuText() );
+ else
+ parent->changeItem( id, that->menuText() );
+ parent->setItemEnabled( id, that->isEnabled() );
+#ifndef QT_NO_ACCEL
+ parent->setAccel( that->accel(), id );
+#endif
+ }
+}
+
+/*!
+ \class QActionGroup qaction.h
+ \brief The QActionGroup class groups actions together.
+
+ \ingroup basic
+ \ingroup application
+
+ In some situations it is useful to group actions together. For
+ example, if you have a left justify action, a right justify action
+ and a center action, only one of these actions should be active at
+ any one time, and one simple way of achieving this is to group the
+ actions together in an action group.
+
+ An action group can also be added to a menu or a toolbar as a
+ single unit, with all the actions within the action group
+ appearing as separate menu options and toolbar buttons.
+
+ Here's an example from examples/textedit:
+ \quotefile textedit/textedit.cpp
+ \skipto QActionGroup
+ \printuntil connect
+
+ Here we create a new action group. Since the action group is exclusive
+ by default, only one of the actions in the group is ever active at any
+ one time. We then connect the group's selected() signal to our
+ textAlign() slot.
+
+ \printuntil actionAlignLeft->setToggleAction
+
+ We create a left align action, add it to the toolbar and the menu
+ and make it a toggle action. We create center and right align
+ actions in exactly the same way.
+
+ \omit
+ A QActionGroup emits an activated() signal when one of its actions
+ is activated.
+ \endomit
+ The actions in an action group emit their activated() (and for
+ toggle actions, toggled()) signals as usual.
+
+ The setExclusive() function is used to ensure that only one action
+ is active at any one time: it should be used with actions which
+ have their \c toggleAction set to TRUE.
+
+ Action group actions appear as individual menu options and toolbar
+ buttons. For exclusive action groups use setUsesDropDown() to
+ display the actions in a subwidget of any widget the action group
+ is added to. For example, the actions would appear in a combobox
+ in a toolbar or as a submenu in a menu.
+
+ Actions can be added to an action group using add(), but normally
+ they are added by creating the action with the action group as
+ parent. Actions can have separators dividing them using
+ addSeparator(). Action groups are added to widgets with addTo().
+*/
+
+/*!
+ Constructs an action group called \a name, with parent \a parent.
+
+ The action group is exclusive by default. Call setExclusive(FALSE) to make
+ the action group non-exclusive.
+*/
+QActionGroup::QActionGroup( QObject* parent, const char* name )
+ : QAction( parent, name )
+{
+ d = new QActionGroupPrivate;
+ d->exclusive = TRUE;
+ d->dropdown = FALSE;
+ d->selected = 0;
+ d->separatorAction = 0;
+ QAction::d->d_group = d;
+
+ connect( this, SIGNAL(selected(QAction*)), SLOT(internalToggle(QAction*)) );
+}
+
+/*!
+ Constructs an action group called \a name, with parent \a parent.
+
+ If \a exclusive is TRUE only one toggle action in the group will
+ ever be active.
+
+ \sa exclusive
+*/
+QActionGroup::QActionGroup( QObject* parent, const char* name, bool exclusive )
+ : QAction( parent, name )
+{
+ d = new QActionGroupPrivate;
+ d->exclusive = exclusive;
+ d->dropdown = FALSE;
+ d->selected = 0;
+ d->separatorAction = 0;
+ QAction::d->d_group = d;
+
+ connect( this, SIGNAL(selected(QAction*)), SLOT(internalToggle(QAction*)) );
+}
+
+/*!
+ Destroys the object and frees allocated resources.
+*/
+
+QActionGroup::~QActionGroup()
+{
+ QPtrListIterator<QActionGroupPrivate::MenuItem> mit( d->menuitems );
+ while ( mit.current() ) {
+ QActionGroupPrivate::MenuItem *mi = mit.current();
+ ++mit;
+ if ( mi->popup )
+ mi->popup->disconnect( SIGNAL(destroyed()), this, SLOT(objectDestroyed()) );
+ }
+
+ QPtrListIterator<QComboBox> cbit( d->comboboxes );
+ while ( cbit.current() ) {
+ QComboBox *cb = cbit.current();
+ ++cbit;
+ cb->disconnect( SIGNAL(destroyed()), this, SLOT(objectDestroyed()) );
+ }
+ QPtrListIterator<QToolButton> mbit( d->menubuttons );
+ while ( mbit.current() ) {
+ QToolButton *mb = mbit.current();
+ ++mbit;
+ mb->disconnect( SIGNAL(destroyed()), this, SLOT(objectDestroyed()) );
+ }
+ QPtrListIterator<QPopupMenu> pmit( d->popupmenus );
+ while ( pmit.current() ) {
+ QPopupMenu *pm = pmit.current();
+ ++pmit;
+ pm->disconnect( SIGNAL(destroyed()), this, SLOT(objectDestroyed()) );
+ }
+
+ delete d->separatorAction;
+ d->menubuttons.setAutoDelete( TRUE );
+ d->comboboxes.setAutoDelete( TRUE );
+ d->menuitems.setAutoDelete( TRUE );
+ d->popupmenus.setAutoDelete( TRUE );
+ delete d;
+}
+
+/*!
+ \property QActionGroup::exclusive
+ \brief whether the action group does exclusive toggling
+
+ If exclusive is TRUE only one toggle action in the action group
+ can ever be active at any one time. If the user chooses another
+ toggle action in the group the one they chose becomes active and
+ the one that was active becomes inactive.
+
+ \sa QAction::toggleAction
+*/
+void QActionGroup::setExclusive( bool enable )
+{
+ d->exclusive = enable;
+}
+
+bool QActionGroup::isExclusive() const
+{
+ return d->exclusive;
+}
+
+/*!
+ \property QActionGroup::usesDropDown
+ \brief whether the group's actions are displayed in a subwidget of
+ the widgets the action group is added to
+
+ Exclusive action groups added to a toolbar display their actions
+ in a combobox with the action's \l QAction::text and \l
+ QAction::iconSet properties shown. Non-exclusive groups are
+ represented by a tool button showing their \l QAction::iconSet and
+ -- depending on \l QMainWindow::usesTextLabel() -- text()
+ property.
+
+ In a popup menu the member actions are displayed in a submenu.
+
+ Changing usesDropDown only affects \e subsequent calls to addTo().
+
+ Note that setting this property for actions in a combobox causes
+ calls to their \link QAction::setVisible()\endlink,
+ \link QAction::setEnabled()\endlink, and
+ \link QAction::setDisabled()\endlink functions to have no effect.
+
+ This property's default is FALSE.
+
+*/
+void QActionGroup::setUsesDropDown( bool enable )
+{
+ d->dropdown = enable;
+}
+
+bool QActionGroup::usesDropDown() const
+{
+ return d->dropdown;
+}
+
+/*!
+ Adds action \a action to this group.
+
+ Normally an action is added to a group by creating it with the
+ group as parent, so this function is not usually used.
+
+ \sa addTo()
+*/
+void QActionGroup::add( QAction* action )
+{
+ if ( d->actions.containsRef( action ) )
+ return;
+
+ d->actions.append( action );
+
+ if ( action->whatsThis().isNull() )
+ action->setWhatsThis( whatsThis() );
+ if ( action->toolTip().isNull() )
+ action->setToolTip( toolTip() );
+
+ if (!action->d->forceDisabled)
+ action->d->enabled = isEnabled();
+ if (!action->d->forceInvisible)
+ action->d->visible = isVisible();
+
+ connect( action, SIGNAL( destroyed() ), this, SLOT( childDestroyed() ) );
+ connect( action, SIGNAL( activated() ), this, SIGNAL( activated() ) );
+ connect( action, SIGNAL( toggled(bool) ), this, SLOT( childToggled(bool) ) );
+
+ for ( QPtrListIterator<QComboBox> cb( d->comboboxes ); cb.current(); ++cb ) {
+ action->addTo( cb.current() );
+ }
+ for ( QPtrListIterator<QToolButton> mb( d->menubuttons ); mb.current(); ++mb ) {
+ QPopupMenu* popup = mb.current()->popup();
+ if ( !popup )
+ continue;
+ action->addTo( popup );
+ }
+ for ( QPtrListIterator<QActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ QPopupMenu* popup = mi.current()->popup;
+ if ( !popup )
+ continue;
+ action->addTo( popup );
+ }
+}
+
+/*!
+ Adds a separator to the group.
+*/
+void QActionGroup::addSeparator()
+{
+ if ( !d->separatorAction )
+ d->separatorAction = new QAction( 0, "qt_separator_action" );
+ d->actions.append( d->separatorAction );
+}
+
+
+/*! \fn void QActionGroup::insert( QAction* a )
+
+ \obsolete
+
+ Use add() instead, or better still create the action with the action
+ group as its parent.
+ */
+
+/*!
+ Adds this action group to the widget \a w.
+
+ If isExclusive() is FALSE or usesDropDown() is FALSE, the actions within
+ the group are added to the widget individually. For example, if the widget
+ is a menu, the actions will appear as individual menu options, and
+ if the widget is a toolbar, the actions will appear as toolbar buttons.
+
+ If both isExclusive() and usesDropDown() are TRUE, the actions
+ are presented either in a combobox (if \a w is a toolbar) or in a
+ submenu (if \a w is a menu).
+
+ All actions should be added to the action group \e before the
+ action group is added to the widget. If actions are added to the
+ action group \e after the action group has been added to the
+ widget these later actions will \e not appear.
+
+ \sa setExclusive() setUsesDropDown() removeFrom()
+*/
+bool QActionGroup::addTo( QWidget* w )
+{
+#ifndef QT_NO_TOOLBAR
+ if ( ::qt_cast<QToolBar*>(w) ) {
+ if ( d->dropdown ) {
+ if ( !d->exclusive ) {
+ QPtrListIterator<QAction> it( d->actions);
+ if ( !it.current() )
+ return TRUE;
+
+ QAction *defAction = it.current();
+
+ QToolButton* btn = new QToolButton( (QToolBar*) w, "qt_actiongroup_btn" );
+ addedTo( btn, w );
+ connect( btn, SIGNAL(destroyed()), SLOT(objectDestroyed()) );
+ d->menubuttons.append( btn );
+
+ if ( !iconSet().isNull() )
+ btn->setIconSet( iconSet() );
+ else if ( !defAction->iconSet().isNull() )
+ btn->setIconSet( defAction->iconSet() );
+ if ( !!text() )
+ btn->setTextLabel( text() );
+ else if ( !!defAction->text() )
+ btn->setTextLabel( defAction->text() );
+#ifndef QT_NO_TOOLTIP
+ if ( !!toolTip() )
+ QToolTip::add( btn, toolTip() );
+ else if ( !!defAction->toolTip() )
+ QToolTip::add( btn, defAction->toolTip() );
+#endif
+#ifndef QT_NO_WHATSTHIS
+ if ( !!whatsThis() )
+ QWhatsThis::add( btn, whatsThis() );
+ else if ( !!defAction->whatsThis() )
+ QWhatsThis::add( btn, defAction->whatsThis() );
+#endif
+
+ connect( btn, SIGNAL( clicked() ), defAction, SIGNAL( activated() ) );
+ connect( btn, SIGNAL( toggled(bool) ), defAction, SLOT( toolButtonToggled(bool) ) );
+ connect( btn, SIGNAL( destroyed() ), defAction, SLOT( objectDestroyed() ) );
+
+ QPopupMenu *menu = new QPopupMenu( btn, "qt_actiongroup_menu" );
+ btn->setPopupDelay( 0 );
+ btn->setPopup( menu );
+
+ while( it.current() ) {
+ it.current()->addTo( menu );
+ ++it;
+ }
+ d->update( this );
+ return TRUE;
+ } else {
+ QComboBox *box = new QComboBox( FALSE, w, "qt_actiongroup_combo" );
+ addedTo( box, w );
+ connect( box, SIGNAL(destroyed()), SLOT(objectDestroyed()) );
+ d->comboboxes.append( box );
+#ifndef QT_NO_TOOLTIP
+ if ( !!toolTip() )
+ QToolTip::add( box, toolTip() );
+#endif
+#ifndef QT_NO_WHATSTHIS
+ if ( !!whatsThis() )
+ QWhatsThis::add( box, whatsThis() );
+#endif
+
+ int onIndex = 0;
+ bool foundOn = FALSE;
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ QAction *action = it.current();
+ if ( !foundOn )
+ foundOn = action->isOn();
+ if ( qstrcmp( action->name(), "qt_separator_action" ) && !foundOn )
+ onIndex++;
+ action->addTo( box );
+ }
+ if ( foundOn )
+ box->setCurrentItem( onIndex );
+ connect( box, SIGNAL(activated(int)), this, SLOT( internalComboBoxActivated(int)) );
+ connect( box, SIGNAL(highlighted(int)), this, SLOT( internalComboBoxHighlighted(int)) );
+ d->update( this );
+ return TRUE;
+ }
+ }
+ } else
+#endif
+ if ( ::qt_cast<QPopupMenu*>(w) ) {
+ QPopupMenu *popup;
+ if ( d->dropdown ) {
+ QPopupMenu *menu = (QPopupMenu*)w;
+ popup = new QPopupMenu( w, "qt_actiongroup_menu" );
+ d->popupmenus.append( popup );
+ connect( popup, SIGNAL(destroyed()), SLOT(objectDestroyed()) );
+
+ int id;
+ if ( !iconSet().isNull() ) {
+ if ( menuText().isEmpty() )
+ id = menu->insertItem( iconSet(), text(), popup );
+ else
+ id = menu->insertItem( iconSet(), menuText(), popup );
+ } else {
+ if ( menuText().isEmpty() )
+ id = menu->insertItem( text(), popup );
+ else
+ id = menu->insertItem( menuText(), popup );
+ }
+
+ addedTo( menu->indexOf( id ), menu );
+
+ QActionGroupPrivate::MenuItem *item = new QActionGroupPrivate::MenuItem;
+ item->id = id;
+ item->popup = popup;
+ d->menuitems.append( item );
+ } else {
+ popup = (QPopupMenu*)w;
+ }
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ // #### do an addedTo( index, popup, action), need to find out index
+ it.current()->addTo( popup );
+ }
+ return TRUE;
+ }
+
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ // #### do an addedTo( index, popup, action), need to find out index
+ it.current()->addTo( w );
+ }
+
+ return TRUE;
+}
+
+/*! \reimp
+*/
+bool QActionGroup::removeFrom( QWidget* w )
+{
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ it.current()->removeFrom( w );
+ }
+
+#ifndef QT_NO_TOOLBAR
+ if ( ::qt_cast<QToolBar*>(w) ) {
+ QPtrListIterator<QComboBox> cb( d->comboboxes );
+ while( cb.current() ) {
+ QComboBox *box = cb.current();
+ ++cb;
+ if ( box->parentWidget() == w )
+ delete box;
+ }
+ QPtrListIterator<QToolButton> mb( d->menubuttons );
+ while( mb.current() ) {
+ QToolButton *btn = mb.current();
+ ++mb;
+ if ( btn->parentWidget() == w )
+ delete btn;
+ }
+ } else
+#endif
+ if ( ::qt_cast<QPopupMenu*>(w) ) {
+ QPtrListIterator<QActionGroupPrivate::MenuItem> pu( d->menuitems );
+ while ( pu.current() ) {
+ QActionGroupPrivate::MenuItem *mi = pu.current();
+ ++pu;
+ if ( d->dropdown && mi->popup )
+ ( (QPopupMenu*)w )->removeItem( mi->id );
+ delete mi->popup;
+ }
+ }
+
+ return TRUE;
+}
+
+/*! \internal
+*/
+void QActionGroup::childToggled( bool b )
+{
+ if ( !isExclusive() )
+ return;
+ QAction* s = (QAction*) sender();
+ if ( b ) {
+ if ( s != d->selected ) {
+ d->selected = s;
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->isToggleAction() && it.current() != s )
+ it.current()->setOn( FALSE );
+ }
+ emit activated();
+ emit selected( s );
+ } else if ( !s->isToggleAction() ) {
+ emit activated();
+ }
+ } else {
+ if ( s == d->selected ) {
+ // at least one has to be selected
+ s->setOn( TRUE );
+ }
+ }
+}
+
+/*! \internal
+*/
+void QActionGroup::childDestroyed()
+{
+ d->actions.removeRef( (QAction*) sender() );
+ if ( d->selected == sender() )
+ d->selected = 0;
+}
+
+/*! \reimp
+*/
+void QActionGroup::setEnabled( bool enable )
+{
+ if ( enable == isEnabled() )
+ return;
+
+ QAction::setEnabled( enable );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setToggleAction( bool toggle )
+{
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it )
+ it.current()->setToggleAction( toggle );
+
+ QAction::setToggleAction( TRUE );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setOn( bool on )
+{
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ QAction *act = it.current();
+ if ( act->isToggleAction() )
+ act->setOn( on );
+ }
+
+ QAction::setOn( on );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setIconSet( const QIconSet& icon )
+{
+ QAction::setIconSet( icon );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setText( const QString& txt )
+{
+ if ( txt == text() )
+ return;
+
+ QAction::setText( txt );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setMenuText( const QString& text )
+{
+ if ( text == menuText() )
+ return;
+
+ QAction::setMenuText( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setToolTip( const QString& text )
+{
+ if ( text == toolTip() )
+ return;
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->toolTip().isNull() )
+ it.current()->setToolTip( text );
+ }
+ QAction::setToolTip( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::setWhatsThis( const QString& text )
+{
+ if ( text == whatsThis() )
+ return;
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->whatsThis().isNull() )
+ it.current()->setWhatsThis( text );
+ }
+ QAction::setWhatsThis( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void QActionGroup::childEvent( QChildEvent *e )
+{
+ if ( !e->removed() )
+ return;
+
+ QAction *action = ::qt_cast<QAction*>(e->child());
+ if ( !action )
+ return;
+
+ for ( QPtrListIterator<QComboBox> cb( d->comboboxes ); cb.current(); ++cb ) {
+ for ( int i = 0; i < cb.current()->count(); i++ ) {
+ if ( cb.current()->text( i ) == action->text() ) {
+ cb.current()->removeItem( i );
+ break;
+ }
+ }
+ }
+ for ( QPtrListIterator<QToolButton> mb( d->menubuttons ); mb.current(); ++mb ) {
+ QPopupMenu* popup = mb.current()->popup();
+ if ( !popup )
+ continue;
+ action->removeFrom( popup );
+ }
+ for ( QPtrListIterator<QActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ QPopupMenu* popup = mi.current()->popup;
+ if ( !popup )
+ continue;
+ action->removeFrom( popup );
+ }
+}
+
+/*!
+ \fn void QActionGroup::selected( QAction* )
+
+ This signal is emitted from exclusive groups when toggle actions
+ change state.
+
+ The argument is the action whose state changed to "on".
+
+ \sa setExclusive(), isOn() QAction::toggled()
+*/
+
+/*! \internal
+*/
+void QActionGroup::internalComboBoxActivated( int index )
+{
+ QAction *a = 0;
+ for ( int i = 0; i <= index && i < (int)d->actions.count(); ++i ) {
+ a = d->actions.at( i );
+ if ( a && !qstrcmp( a->name(), "qt_separator_action" ) )
+ index++;
+ }
+ a = d->actions.at( index );
+ if ( a ) {
+ if ( a != d->selected ) {
+ d->selected = a;
+ for ( QPtrListIterator<QAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->isToggleAction() && it.current() != a )
+ it.current()->setOn( FALSE );
+ }
+ if ( a->isToggleAction() )
+ a->setOn( TRUE );
+
+ emit activated();
+ if ( a->isToggleAction() )
+ emit selected( d->selected );
+ emit ((QActionGroup*)a)->activated();
+ } else if ( !a->isToggleAction() ) {
+ emit activated();
+ emit ((QActionGroup*)a)->activated();
+ }
+ a->clearStatusText();
+ }
+}
+
+/*! \internal
+*/
+void QActionGroup::internalComboBoxHighlighted( int index )
+{
+ QAction *a = 0;
+ for ( int i = 0; i <= index && i < (int)d->actions.count(); ++i ) {
+ a = d->actions.at( i );
+ if ( a && !qstrcmp( a->name(), "qt_separator_action" ) )
+ index++;
+ }
+ a = d->actions.at( index );
+ if ( a )
+ a->showStatusText(a->statusTip());
+ else
+ clearStatusText();
+}
+
+/*! \internal
+*/
+void QActionGroup::internalToggle( QAction *a )
+{
+ int index = d->actions.find( a );
+ if ( index == -1 )
+ return;
+
+ int lastItem = index;
+ for ( int i = 0; i < lastItem; i++ ) {
+ QAction *action = d->actions.at( i );
+ if ( !qstrcmp( action->name(), "qt_separator_action" ) )
+ index--;
+ }
+
+ for ( QPtrListIterator<QComboBox> it( d->comboboxes); it.current(); ++it )
+ it.current()->setCurrentItem( index );
+}
+
+/*! \internal
+*/
+void QActionGroup::objectDestroyed()
+{
+ const QObject* obj = sender();
+ d->menubuttons.removeRef( (QToolButton*)obj );
+ for ( QPtrListIterator<QActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ if ( mi.current()->popup == obj ) {
+ d->menuitems.removeRef( mi.current() );
+ break;
+ }
+ }
+ d->popupmenus.removeRef( (QPopupMenu*)obj );
+ d->comboboxes.removeRef( (QComboBox*)obj );
+}
+
+/*!
+ \internal
+
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) for the child action \a a in
+ the \a container.
+*/
+
+void QActionGroup::addedTo( QWidget *actionWidget, QWidget *container, QAction *a )
+{
+ Q_UNUSED( actionWidget );
+ Q_UNUSED( container );
+ Q_UNUSED( a );
+}
+
+/*!
+ \overload
+ \internal
+
+ This function is called from the addTo() function when it has
+ created a menu item for the child action at the index position \a
+ index in the popup menu \a menu.
+*/
+
+void QActionGroup::addedTo( int index, QPopupMenu *menu, QAction *a )
+{
+ Q_UNUSED( index );
+ Q_UNUSED( menu );
+ Q_UNUSED( a );
+}
+
+/*!
+ \reimp
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) in the \a container.
+*/
+
+void QActionGroup::addedTo( QWidget *actionWidget, QWidget *container )
+{
+ Q_UNUSED( actionWidget );
+ Q_UNUSED( container );
+}
+
+/*!
+ \reimp
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a menu item at the index position \a index in the popup
+ menu \a menu.
+*/
+
+void QActionGroup::addedTo( int index, QPopupMenu *menu )
+{
+ Q_UNUSED( index );
+ Q_UNUSED( menu );
+}
+
+#endif