#include "LightApp_ModuleAction.h"
#include <QtxComboBox.h>
+#include <QtxActionSet.h>
+#include <QHBoxLayout>
+
+/*!
+ \class LightApp_ModuleAction::ActionSet
+ \brief Internal class to represent list of modules buttons.
+ \internal
+*/
+
+class LightApp_ModuleAction::ActionSet : public QtxActionSet
+{
+public:
+ ActionSet( QObject* );
+ QAction* moduleAction( const QString& ) const;
+ int moduleId( const QString& ) const;
+ int moduleId( QAction* ) const;
+ void setVisible( bool );
+};
+
+/*!
+ \brief Constructor.
+ \internal
+ \param parent parent object
+*/
+LightApp_ModuleAction::ActionSet::ActionSet( QObject* parent )
+: QtxActionSet( parent )
+{
+}
+
+/*!
+ \brief Get action corresponding to the specified module.
+ \internal
+ \param name module name
+ \return module action or 0 if \a name is invalid
+*/
+QAction* LightApp_ModuleAction::ActionSet::moduleAction( const QString& name ) const
+{
+ QAction* a = 0;
+
+ QList<QAction*> alist = actions();
+ for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && !a; ++it )
+ {
+ if ( (*it)->text() == name )
+ a = *it;
+ }
+
+ return a;
+}
+
+/*!
+ \brief Get module action identifier.
+ \internal
+ \param name module name
+ \return module action ID or -1 if \a name is invalid
+*/
+int LightApp_ModuleAction::ActionSet::moduleId( const QString& name ) const
+{
+ int id = -1;
+
+ QList<QAction*> alist = actions();
+ for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && id == -1; ++it )
+ {
+ if ( (*it)->text() == name )
+ id = actionId( *it );
+ }
+
+ return id;
+}
+
+/*!
+ \brief Get module action identifier.
+ \internal
+ \param a module action
+ \return module action ID or -1 if \a a is null or invalid
+*/
+int LightApp_ModuleAction::ActionSet::moduleId( QAction* a ) const
+{
+ return actionId( a );
+}
+
+/*!
+ \brief Show/hide modules actions.
+ \internal
+ \param on new visibility state
+*/
+void LightApp_ModuleAction::ActionSet::setVisible( bool on )
+{
+ QList<QAction*> alist = actions();
+ for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
+ (*it)->setVisible( on );
+
+ QtxActionSet::setVisible( on );
+}
+
+/*!
+ \class LightApp_ModuleAction::ComboAction
+ \brief Internal class to represent combo box with the list of modules in the toolbar.
+ \internal
+*/
+
+/*!
+ \brief Constructor.
+ \internal
+ \param parent parent object
+*/
+LightApp_ModuleAction::ComboAction::ComboAction( QObject* parent )
+: QtxAction( parent )
+{
+}
+
+/*!
+ \brief Get list of associated widgets.
+ \internal
+ \return list of created widgets (QtxComboBox)
+*/
+QList<QtxComboBox*> LightApp_ModuleAction::ComboAction::widgets() const
+{
+ QList<QtxComboBox*> lst;
+
+ QList<QWidget*> wlist = createdWidgets();
+ for ( QList<QWidget*>::const_iterator wit = wlist.begin(); wit != wlist.end(); ++wit )
+ lst += qFindChildren<QtxComboBox *>(*wit);
+
+ return lst;
+}
+
+/*!
+ \brief Create combo box widget by request from the toolbar.
+ \internal
+ \param parent parent widget (should be QToolBar or its successor)
+ \return new custom widget, containing combo box
+*/
+QWidget* LightApp_ModuleAction::ComboAction::createWidget( QWidget* parent )
+{
+ if ( !parent->inherits( "QToolBar" ) )
+ return 0;
+
+ QWidget* dumb = new QWidget( parent );
+ QHBoxLayout* l = new QHBoxLayout( dumb );l->setSpacing(0);l->setMargin(0);
+ QtxComboBox* cb = new QtxComboBox( dumb );
+ cb->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
+ cb->setFocusPolicy( Qt::NoFocus );
+ l->addWidget( cb );
+
+ connect( cb, SIGNAL( activatedId( int ) ), this, SIGNAL( activatedId( int ) ) );
+
+ return dumb;
+}
+
+/*!
+ \fn void LightApp_ModuleAction::ComboAction::activatedId( int id );
+ \internal
+ \brief Emitted when the combo box item is activated
+ \param item identifier
+*/
/*!
\class LightApp_ModuleAction
toolbar.
This action is represented in the toolbar as combo box and a set of buttons
- for each module. In addition, the combo box contains an item, corresponding
- to the "neutral point" of the application (where there is no active module).
+ for each module. In addition to the modules items, the combo box contains
+ an item corresponding to the "neutral point" of the application
+ (when there is no active module).
The action can be constructed with up to two parameters, defining the text
and icon to be displayed for the "neutral point".
When user activates/deactivates any module, the signal moduleActivated()
is emitted.
+
+ The action can be represented in the toolbar in different modes:
+ * as combo box only (Qtx::ComboItem)
+ * as set of modules buttons only (Qtx::Buttons)
+ * as combo box followed by the set of modules buttons (Qtx::All)
+ * as none (Qtx::None)
+ By default, both combo box and buttons set are shown. Use method
+ setMode() to change this behavior.
+
+ An action can be also added to the popup menu, but combo box is never shown
+ in this case, only modules buttons.
*/
/*!
\param parent parent object
*/
LightApp_ModuleAction::LightApp_ModuleAction( const QString& text, QObject* parent )
-: QtxActionSet( parent )
+: QtxAction( parent )
{
setText( text );
init();
\param parent parent object
*/
LightApp_ModuleAction::LightApp_ModuleAction( const QString& text, const QIcon& ico, QObject* parent )
-: QtxActionSet( parent )
+: QtxAction( parent )
{
setText( text );
setIcon( ico );
QStringList LightApp_ModuleAction::modules() const
{
QStringList lst;
- QList<QAction*> alist = actions();
+
+ QList<QAction*> alist = mySet->actions();
for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
lst.append( (*it)->text() );
+
return lst;
}
/*!
- \brief Get module icon
+ \brief Get module icon.
\param name module name
\return module icon
+ \sa setModuleIcon()
*/
QIcon LightApp_ModuleAction::moduleIcon( const QString& name ) const
{
- QAction* a = moduleAction( name );
+ QAction* a = mySet->moduleAction( name );
return a ? a->icon() : QIcon();
}
/*!
- \brief Set module icon
+ \brief Set module icon.
\param name module name
\param ico new module icon
+ \sa moduleIcon()
*/
void LightApp_ModuleAction::setModuleIcon( const QString& name, const QIcon& ico )
{
- QAction* a = moduleAction( name );
+ QAction* a = mySet->moduleAction( name );
if ( !a )
return;
\param name module name
\param ico module icon
\param idx position in the module list (if -1, the module is added to the end of list)
+ \sa removeModule()
*/
void LightApp_ModuleAction::insertModule( const QString& name, const QIcon& ico,
const int idx )
QtxAction* a = new QtxAction( name, ico, name, 0, this, true );
a->setStatusTip( tr( "Activate/deactivate %1 module" ).arg( name ) );
- int id = insertAction( a, -1, idx );
+ mySet->insertAction( a, -1, idx );
update();
}
/*!
\brief Remove module from the list.
\param name module name
+ \sa insertModule()
*/
void LightApp_ModuleAction::removeModule( const QString& name )
{
- int id = moduleId( name );
+ int id = mySet->moduleId( name );
if ( id == -1 )
return;
- removeAction( id );
+ mySet->removeAction( id );
update();
}
is returned.
\return active module name
+ \sa setActiveModule()
*/
QString LightApp_ModuleAction::activeModule() const
{
To turn to the "neutral point" (no active module), pass empty string.
\param name new active module name
+ \sa activeModule()
*/
void LightApp_ModuleAction::setActiveModule( const QString& name )
{
- int id = moduleId( name );
+ if ( name == activeModule() )
+ return;
+
+ int id = mySet->moduleId( name );
if ( name.isEmpty() || id != -1 )
activate( id, false );
}
/*!
- \brief Called when module button is triggered.
- \internal
- \param id module identifier
+ \brief Set action display mode.
+
+ Action can be represented in the toolbar as
+ * combo box only (Qtx::ComboItem)
+ * set of modules buttons only (Qtx::Buttons)
+ * combo box followed by the set of modules buttons (Qtx::All)
+ * none (Qtx::None)
+
+ \param mode action display mode
+ \sa mode()
*/
-void LightApp_ModuleAction::onTriggered( int id )
+void LightApp_ModuleAction::setMode( const int mode )
{
- activate( id );
+ myMode = mode;
+ update();
}
/*!
- \brief Activate a module item.
- \internal
- \param id module identifier
- \param fromAction \c true if function is called from the module button
+ \brief Get action display mode.
+ \param mode action display mode
+ \sa setMode()
*/
-void LightApp_ModuleAction::activate( int id, bool fromAction )
+int LightApp_ModuleAction::mode() const
{
- bool checked = false;
-
- QList<QAction*> alist = actions();
- for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
- {
- if ( actionId( *it ) != id ) {
- (*it)->setChecked( false );
- }
- else {
- if ( !fromAction )
- (*it)->setChecked( true );
- checked = (*it)->isChecked();
- }
- }
-
- QList<QWidget*> widgets = createdWidgets();
- for ( QList<QWidget*>::const_iterator wit = widgets.begin(); wit != widgets.end(); ++wit )
- {
- QtxComboBox* cb = ::qobject_cast<QtxComboBox*>( *wit );
- if ( cb ) {
- bool blocked = cb->signalsBlocked();
- cb->blockSignals( true );
- cb->setCurrentId( checked ? id : -1 );
- cb->blockSignals( blocked );
- }
- }
-
- emit moduleActivated( activeModule() );
+ return myMode;
}
/*!
- \brief Called when combo box item is activated.
- \param id module identifier
+ \brief Add action to the widget.
+ \param w widget (menu or toolbar)
+ \return \c true if the action is added successfully and \c false otherwise.
+ \sa removeFrom()
*/
-void LightApp_ModuleAction::onComboActivated( int id )
+bool LightApp_ModuleAction::addTo( QWidget* w )
{
- QList<QAction*> alist = actions();
- for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
- {
- (*it)->setChecked( actionId( *it ) == id );
- }
-
- emit moduleActivated( activeModule() );
+ bool ok = QtxAction::addTo( w );
+ if ( w->inherits( "QToolBar" ) )
+ ok = ok && myCombo->addTo( w );
+ return ok && mySet->addTo( w );
}
/*!
- \brief Create combo box widget by request from tool bar.
- \param parent parent widget (should be QToolBar or its successor)
- \return new combo box widget
+ \brief Remove action from widget.
+ \param w widget (menu or toolbar)
+ \return \c true if the action is removed successfully and \c false otherwise.
+ \sa addTo()
*/
-QWidget* LightApp_ModuleAction::createWidget( QWidget* parent )
+bool LightApp_ModuleAction::removeFrom( QWidget* w )
{
- if ( !parent->inherits( "QToolBar" ) )
- return 0;
-
- QtxComboBox* cb = new QtxComboBox( parent );
- cb->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
- cb->setFocusPolicy( Qt::NoFocus );
-
- update( cb );
- cb->blockSignals( true );
- cb->setCurrentId( actionId( active() ) );
- cb->blockSignals( false );
-
- connect( cb, SIGNAL( activatedId( int ) ), this, SLOT( onComboActivated( int ) ) );
-
- return cb;
+ bool ok = mySet->removeFrom( w );
+ if ( w->inherits( "QToolBar" ) )
+ ok = ok && myCombo->removeFrom( w );
+ return ok && QtxAction::removeFrom( w );
}
/*!
- \brief Return \c false if the action contains custom widgets.
- \return \c false (action provides combo box as custom widget)
+ \brief Called when the action is added to the widget.
+ \param w widget (not used)
*/
-bool LightApp_ModuleAction::isEmptyAction() const
+void LightApp_ModuleAction::addedTo( QWidget* /*w*/ )
{
- return false;
+ update();
}
/*!
- \brief Get an action corresponding to the active module.
+ \fn void LightApp_ModuleAction::moduleActivated( const QString& name );
+ \brief Emitted when the module is activated
+ \param name module name (empty string for neutral point)
+*/
+
+/*!
+ \brief Initialize an action,
\internal
- \return active module action or 0 if there is no active module
*/
-QAction* LightApp_ModuleAction::active() const
+void LightApp_ModuleAction::init()
{
- QAction* a = 0;
- QList<QAction*> alist = actions();
- for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && !a; ++it )
- {
- if ( (*it)->isChecked() )
- a = *it;
- }
- return a;
+ setVisible( false );
+
+ myMode = All;
+ myCombo = new ComboAction( this );
+ mySet = new ActionSet( this );
+
+ connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
+ connect( mySet, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) );
+ connect( myCombo, SIGNAL( activatedId( int ) ), this, SLOT( onComboActivated( int ) ) );
}
/*!
*/
void LightApp_ModuleAction::update()
{
- QList<QWidget*> lst = createdWidgets();
- for ( QList<QWidget*>::const_iterator itr = lst.begin(); itr != lst.end(); ++itr )
- update( ::qobject_cast<QtxComboBox*>( *itr ) );
+ QList<QtxComboBox*> lst = myCombo->widgets();
+ for ( QList<QtxComboBox*>::const_iterator it = lst.begin(); it != lst.end(); ++it )
+ update( *it );
+
+ myCombo->setVisible( myMode & ComboItem );
+ mySet->setVisible( myMode & Buttons );
}
/*!
if ( !cb )
return;
- int curId = cb->currentId();
-
- QList<QAction*> alist = actions();
+ int curId = mySet->moduleId( active() );
+ QList<QAction*> alist = mySet->actions();
cb->clear();
-
+
cb->addItem( icon(), text() );
cb->setId( 0, -1 );
for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
{
QAction* a = *it;
- int id = actionId( a );
+ int id = mySet->moduleId( a );
cb->addItem( a->icon(), a->text() );
cb->setId( cb->count() - 1, id );
}
}
/*!
- \brief Initialize an action,
- \internal
-*/
-void LightApp_ModuleAction::init()
-{
- setVisible( true );
- connect( this, SIGNAL( triggered( int ) ), this, SLOT( onTriggered( int ) ) );
-}
-
-/*!
- \brief Get action corresponding to the specified module.
+ \brief Get an action corresponding to the active module.
\internal
- \param name module name
- \return module action or 0 if \a name is invalid
+ \return active module action or 0 if there is no active module
*/
-QAction* LightApp_ModuleAction::moduleAction( const QString& name ) const
+QAction* LightApp_ModuleAction::active() const
{
QAction* a = 0;
- QList<QAction*> alist = actions();
+
+ QList<QAction*> alist = mySet->actions();
for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && !a; ++it )
{
- if ( (*it)->text() == name )
+ if ( (*it)->isChecked() )
a = *it;
}
+
return a;
}
/*!
- \brief Get module action identifier.
+ \brief Activate a module item.
\internal
- \param name module name
- \return module action ID or 0 if \a name is invalid
+ \param id module identifier
+ \param fromAction \c true if function is called from the module button
*/
-int LightApp_ModuleAction::moduleId( const QString& name ) const
+void LightApp_ModuleAction::activate( int id, bool fromAction )
{
- int id = -1;
- QList<QAction*> alist = actions();
- for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end() && id == -1; ++it )
+ bool checked = false;
+
+ QList<QAction*> alist = mySet->actions();
+ for ( QList<QAction*>::const_iterator it = alist.begin(); it != alist.end(); ++it )
{
- if ( (*it)->text() == name )
- id = actionId( *it );
+ if ( mySet->moduleId( *it ) != id ) {
+ (*it)->setChecked( false );
+ }
+ else {
+ if ( !fromAction )
+ (*it)->setChecked( true );
+ checked = (*it)->isChecked();
+ }
}
- return id;
+
+ QList<QtxComboBox*> widgets = myCombo->widgets();
+ for ( QList<QtxComboBox*>::const_iterator wit = widgets.begin(); wit != widgets.end(); ++wit )
+ {
+ QtxComboBox* cb = *wit;
+ bool blocked = cb->signalsBlocked();
+ cb->blockSignals( true );
+ cb->setCurrentId( checked ? id : -1 );
+ cb->blockSignals( blocked );
+ }
+
+ emit moduleActivated( activeModule() );
}
/*!
- \fn void LightApp_ModuleAction::moduleActivated( const QString& name );
- \brief Emitted when the module is activated
- \param name module name (empty string for neutral point)
+ \brief Called when module button is triggered.
+ \internal
+ \param id module identifier
+*/
+void LightApp_ModuleAction::onTriggered( int id )
+{
+ activate( id );
+}
+
+/*!
+ \brief Called when action state is changed.
+ \internal
+
+ This slot is used to prevent making the parent action visible.
+*/
+void LightApp_ModuleAction::onChanged()
+{
+ if ( !isVisible() )
+ return;
+
+ bool block = signalsBlocked();
+ blockSignals( true );
+ setVisible( false );
+ blockSignals( block );
+}
+
+/*!
+ \brief Called when combo box item is activated.
+ \param id module identifier
*/
+void LightApp_ModuleAction::onComboActivated( int id )
+{
+ activate( id, false );
+}