-
+// Copyright (C) 2007-2023 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, 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
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+// File: QtxPopupMgr.cxx
+// Author: Alexander SOLOVYOV, Sergey TELKOV
+//
#include "QtxPopupMgr.h"
-#include "QtxListOfOperations.h"
-#include "QtxStdOperations.h"
#include "QtxAction.h"
+#include "QtxEvalExpr.h"
+#include <QList>
+#include <QMenu>
+#include <QVariant>
-#include <qpopupmenu.h>
-
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxValue QtxPopupMgr::Selection::globalParam( const QString& str ) const
+bool operator<( const QList<QVariant>& v1, const QList<QVariant>& v2 )
{
- if( str==selCountParam() )
- return count();
-
- else if( str[0]==equality() )
+ QList<QVariant>::const_iterator anIt1 = v1.begin(), aLast1 = v1.end(),
+ anIt2 = v2.begin(), aLast2 = v2.end();
+ for ( ; anIt1 != aLast1 && anIt2 != aLast2; anIt1++, anIt2++ )
{
- QtxSets::ValueSet set;
- QString par = str.mid( 1 );
-
- for( int i=0, n=count(); i<n; i++ )
- {
- QtxValue v = param( i, par );
- if( v.isValid() )
- QtxSets::add( set, v );
- else
- return QtxValue();
- }
- return set;
+ if ( (*anIt1) != (*anIt2) )
+ return (*anIt1) < (*anIt2);
}
-
- else
- return QtxValue();
+ return anIt1 == aLast1 && anIt2 != aLast2;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QChar QtxPopupMgr::Selection::equality() const
+/*!
+ \class QtxPopupMgr::PopupCreator
+ \internal
+ \brief Popup menu actions creator.
+
+ Used by Reader to create actions by reading descriptions from the file
+ and fill in the action manager with the actions.
+*/
+
+class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator
{
- return defEquality();
-}
+public:
+ PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* );
+ virtual ~PopupCreator();
+
+ virtual int append( const QString&, const bool,
+ const ItemAttributes&, const int );
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QString QtxPopupMgr::Selection::selCountParam() const
+ virtual QString rule( const ItemAttributes&,
+ const QtxPopupMgr::RuleType = VisibleRule ) const;
+
+private:
+ QtxPopupMgr* myMgr;
+};
+
+/*!
+ \brief Constructor.
+ \param r menu action reader
+ \param mgr popup menu manager
+*/
+QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
+ QtxPopupMgr* mgr )
+: QtxActionMgr::Creator( r ),
+ myMgr( mgr )
{
- return defSelCountParam();
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QChar QtxPopupMgr::Selection::defEquality()
+/*!
+ \brief Destructor.
+*/
+QtxPopupMgr::PopupCreator::~PopupCreator()
{
- return '$';
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QString QtxPopupMgr::Selection::defSelCountParam()
+/*!
+ \brief Create and append new action to the action manager.
+ \param tag item tag name
+ \param subMenu \c true if this item is submenu
+ \param attr attributes map
+ \param pId parent action ID
+ \return menu action ID
+*/
+int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
+ const ItemAttributes& attr, const int pId )
{
- return "selcount";
-}
+ if ( !myMgr || !reader() )
+ return -1;
+ QString label = reader()->option( "label", "label" ),
+ id = reader()->option( "id", "id" ),
+ pos = reader()->option( "pos", "pos" ),
+ group = reader()->option( "group", "group" ),
+ tooltip = reader()->option( "tooltip", "tooltip" ),
+ sep = reader()->option( "separator", "separator" ),
+ accel = reader()->option( "accel", "accel" ),
+ icon = reader()->option( "icon", "icon" ),
+ toggle = reader()->option( "toggle", "toggle" );
+ QtxActionMenuMgr* mgr = myMgr;
+ int res = -1, actId = intValue( attr, id, -1 );;
+ if ( subMenu )
+ res = mgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ else if ( tag == sep )
+ res = mgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ else
+ {
+ QIcon set;
+ QPixmap pix;
+ QString name = strValue( attr, icon );
+ if( !name.isEmpty() )
+ {
+ if ( loadPixmap( name, pix ) )
+ set = QIcon( pix );
+ }
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::Operations::Operations( QtxPopupMgr* mgr )
-: QtxStrings(),
- myPopupMgr( mgr )
-{
- QStringList aList;
- aList.append( "every" );
- aList.append( "any" );
- aList.append( "onlyone" );
- addOperations( aList );
+ QString actLabel = strValue( attr, label );
+ QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
+ QKeySequence( strValue( attr, accel ) ),
+ myMgr );
+ newAct->setToolTip( strValue( attr, tooltip ) );
+ QString toggleact = strValue( attr, toggle );
+ bool isToggle = !toggleact.isEmpty();
+ newAct->setCheckable( isToggle );
+ newAct->setChecked( toggleact.toLower() == "true" );
+
+ connect( newAct );
+ int aid = mgr->registerAction( newAct, actId );
+ QString arule = rule( attr, QtxPopupMgr::VisibleRule );
+ if ( !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::VisibleRule );
+ arule = rule( attr, QtxPopupMgr::EnableRule );
+ if ( !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::EnableRule );
+ arule = rule( attr, QtxPopupMgr::ToggleRule );
+ if ( isToggle && !arule.isEmpty() )
+ myMgr->setRule( newAct, arule, QtxPopupMgr::ToggleRule );
+ res = mgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ }
- myParser = new QtxParser( mgr->myOperations );
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::Operations::~Operations()
+/*!
+ \brief Get the rule for the menu item.
+
+ Default implementation returns empty rule.
+
+ \param attr attributes map
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule for the menu item corresponding to the rule type
+*/
+QString QtxPopupMgr::PopupCreator::rule( const ItemAttributes& /*attr*/,
+ const QtxPopupMgr::RuleType /*ruleType*/ ) const
{
- delete myParser;
+ return QString();
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-int QtxPopupMgr::Operations::prior( const QString& op, bool isBin ) const
+/*!
+ \class QtxPopupMgr
+ \brief Popup menu manager.
+
+ Menu manager allows using of set of action for automatic generating of
+ application context popup menu by reuquest and dynamic update of its
+ contents.
+
+ Use insert() methods to add menu items to the popup menu.
+
+ The visibility, enable and toggle state of the menu item is controlled
+ by the syntaxic rules, which can be set with setRule() methods.
+ The rules are parsed automatically with help of QtxEvalParser class.
+
+ QtxPopupSelection class is used as back-end for getting value of each
+ parameter found in the rule by the expression parser.
+ Use setSelection() and selection() to set/get the selection instance
+ for the popup menu manager.
+
+ Popup menu manager automatically optimizes the menu by removing
+ extra separators, hiding empty popup submenus etc.
+*/
+
+/*!
+ \brief Constructor.
+ \param object parent object
+*/
+QtxPopupMgr::QtxPopupMgr( QObject* parent )
+: QtxActionMenuMgr( 0, parent ),
+ mySelection( 0 )
{
- if( !isBin && ( op=="every" || op=="any" || op=="onlyone" ) )
- return 1;
- else
- return QtxStrings::prior( op, isBin );
-
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxParser::Error QtxPopupMgr::Operations::calculate
- ( const QString& op, QtxValue& v1, QtxValue& v2 ) const
+/*!
+ \brief Constructor.
+ \param popup popup menu
+ \param object parent object
+*/
+QtxPopupMgr::QtxPopupMgr( QMenu* popup, QObject* parent )
+: QtxActionMenuMgr( popup, parent ),
+ mySelection( 0 )
{
- int ind = -1;
- if( op=="every" )
- ind = 0;
- else if( op=="any" )
- ind = 1;
- else if( op=="onlyone" )
- ind = 2;
+}
- if( ind>=0 && ind<=2 )
- {
- QString val_name = op + "(" + v2.toString() + ")";
- QtxParser::Error err = QtxParser::OK;
-
- if( !myValues.contains( val_name ) )
- {
- myParser->setExpr( v2.toString() );
- QStringList params, specific;
- myParser->paramsList( params );
-
- myParser->clear();
- myPopupMgr->setParams( myParser, specific );
-
- QtxPopupMgr::Selection* sel = myPopupMgr->myCurrentSelection;
-
- int global_result = 0;
- if( sel )
- for( int i=0, n=sel->count(); i<n; i++ )
- {
- QStringList::const_iterator anIt = specific.begin(),
- aLast = specific.end();
- for( ; anIt!=aLast; anIt++ )
- {
- QtxValue v = sel->param( i, *anIt );
- if( v.isValid() )
- myParser->set( *anIt, v );
- else
- return QtxParser::InvalidToken;
- }
-
- QtxValue res = myParser->calculate();
- err = myParser->lastError();
- if( err==QtxParser::OK )
- if( res.type()==QVariant::Bool )
- {
- if( res.toBool() )
- global_result++;
- if( ind==2 && global_result>1 )
- break;
- }
- else
- return QtxParser::InvalidResult;
- else
- return err;
- }
-
- QtxValue& vv = ( QtxValue& )myValues[ val_name ];
- vv = ( ind==0 && global_result==sel->count() ) ||
- ( ind==1 ) ||
- ( ind==2 && global_result==1 );
- }
-
- v2 = myValues[ val_name ];
-
- return err;
- }
- else
- return QtxStrings::calculate( op, v1, v2 );
+/*!
+ \brief Destructor.
+*/
+QtxPopupMgr::~QtxPopupMgr()
+{
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::Operations::clear()
+/*!
+ \brief Get popup menu.
+ \return popup menu
+*/
+QMenu* QtxPopupMgr::menu() const
{
- myValues.clear();
+ return ::qobject_cast<QMenu*>( menuWidget() );
}
+/*!
+ \brief Get popup menu.
+ \param menu popup menu
+*/
+void QtxPopupMgr::setMenu( QMenu* menu )
+{
+ setMenuWidget( menu );
+}
+/*!
+ \brief Get selection.
+ \return current selection object
+*/
+QtxPopupSelection* QtxPopupMgr::selection() const
+{
+ return mySelection;
+}
+/*!
+ \brief Set selection.
+ \param sel new selection object
+*/
+void QtxPopupMgr::setSelection( QtxPopupSelection* sel )
+{
+ if ( mySelection == sel )
+ return;
+ delete mySelection;
+ mySelection = sel;
+ if ( mySelection ) {
+ mySelection->setParent( this );
+ mySelection->setPopupMgr( this );
+ }
+ connect( mySelection, SIGNAL( destroyed( QObject* ) ),
+ this, SLOT( onSelectionDestroyed( QObject* ) ) );
+ QtxActionMgr::triggerUpdate();
+}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::QtxPopupMgr( QPopupMenu* popup, QObject* parent )
-: QtxActionMenuMgr( popup, parent )
+/*!
+ \brief Register an action and return its identifier.
+
+ If \a id is less than 0, the identifier for the action is generated automatically.
+ If action with given \a id is already registered, it will be re-registered.
+ If required \a id is already in use, new identifier is generatied; in this case
+ returning value will different from required one.
+
+ \param act action to be registered
+ \param id action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID (the same as \a id or generated one)
+*/
+int QtxPopupMgr::registerAction( QAction* act, const int id, const QString& rule, const QtxPopupMgr::RuleType ruleType )
{
- createOperations();
+ int _id = QtxActionMenuMgr::registerAction( act, id );
+ setRule( act, rule, ruleType );
+ return _id;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::~QtxPopupMgr()
+/*!
+ \brief Unregister action from internal map.
+ \param id action ID
+*/
+void QtxPopupMgr::unRegisterAction( const int id )
{
+ QAction* a = action( id );
+ if ( myRules.contains( a ) )
+ {
+ for ( ExprMap::iterator it = myRules[a].begin(); it != myRules[a].end(); ++it )
+ delete it.value();
+ }
+ myRules.remove( a );
+
+ remove( id );
+
+ QtxActionMenuMgr::unRegisterAction( id );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::createOperations()
+/*!
+ \brief Insert action to the popup menu manager.
+ \param id action ID
+ \param pId parent menu action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID
+*/
+int QtxPopupMgr::insertAction( const int id, const int pId, const QString& rule, const RuleType ruleType )
{
- myOperations = new QtxListOfOperations;
- myOperations->append( "logic", new QtxLogic(), 0 );
- myOperations->append( "arithm", new QtxArithmetics(), 50 );
- myOperations->append( "strings", new QtxStrings(), 100 );
- myOperations->append( "sets", new QtxSets(), 150 );
- myOperations->append( "custom", new Operations( this ), 200 );
+ int res = QtxActionMenuMgr::insert( id, pId, -1 );
+ setRule( action( id ), rule, ruleType );
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-int QtxPopupMgr::registerAction( QAction* act,
- const QString& visible,
- const QString& toggle,
- const int id )
+/*!
+ \brief Insert action to the popup menu manager.
+ \param a action
+ \param pId parent menu action ID
+ \param rule syntax rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return action ID
+*/
+int QtxPopupMgr::insertAction( QAction* a, const int pId, const QString& rule, const RuleType ruleType )
{
- int _id = QtxActionMenuMgr::registerAction( act, id );
- setRule( _id, visible, true );
- setRule( _id, toggle, false );
- return _id;
+ int res = QtxActionMenuMgr::insert( a, pId, -1 );
+ setRule( a, rule, ruleType );
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::unRegisterAction( const int id )
+/*!
+ \return true if action has rule of given type
+ \param a - action
+ \param t - rule type
+*/
+bool QtxPopupMgr::hasRule( QAction* a, const RuleType t ) const
{
- QAction* act = action( id );
-
- myVisibility.remove( act );
- myToggle.remove( act );
+ return a ? expression( a, t, false )!=0 : false;
+}
- remove( id );
- //QtxActionMenuMgr::unRegisterAction( id );
+/*!
+ \return true if action with given id has rule of given type
+ \param id - action id
+ \param t - rule type
+*/
+bool QtxPopupMgr::hasRule( const int id, const RuleType t ) const
+{
+ return hasRule( action( id ), t );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-bool QtxPopupMgr::hasRule( QAction* act, bool visibility ) const
+/*!
+ \brief Get rule of type \a type for the action \a a.
+ \param a action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+QString QtxPopupMgr::rule( QAction* a, const RuleType ruleType ) const
{
- return map( visibility ).contains( act );
+ QString rule;
+ QtxEvalExpr* expr = expression( a, ruleType );
+ if ( expr )
+ rule = expr->expression();
+ return rule;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-bool QtxPopupMgr::hasRule( const int id, bool visibility ) const
+/*!
+ \brief Get rule of type \a type for the action \a id.
+ \param id action ID
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+QString QtxPopupMgr::rule( const int id, const RuleType ruleType ) const
{
- return hasRule( action( id ), visibility );
+ return rule( action( id ), ruleType );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::setRule( QAction* act, const QString& rule, bool visibility )
+/*!
+ \brief Set rule of type \a type for the action \a a.
+ \param a action
+ \param rule rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+void QtxPopupMgr::setRule( QAction* a, const QString& rule, const RuleType ruleType )
{
- if( !act || rule.isEmpty() )
- return;
+ if ( !a )
+ return;
- if( !hasRule( act, visibility ) )
- {
- QtxParser* p = new QtxParser( myOperations, rule );
- if( p->lastError()==QtxParser::OK )
- map( visibility ).insert( act, p );
- else
- delete p;
- }
- else
- {
- QtxParser* p = map( visibility )[ act ];
- p->setExpr( rule );
- if( p->lastError()!=QtxParser::OK )
- p->setExpr( QString() );
- }
+ QtxEvalExpr* expr = expression( a, ruleType, true );
+
+ expr->setExpression( rule );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::setRule( const int id, const QString& rule, bool visibility )
+/*!
+ \brief Set rule of type \a type for the action \a id.
+ \param id action ID
+ \param rule rule
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return rule of required type
+*/
+void QtxPopupMgr::setRule( const int id, const QString& rule, const RuleType ruleType )
{
- setRule( action( id ), rule, visibility );
+ setRule( action( id ), rule, ruleType );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-bool result( QtxParser* p )
+/*!
+ \brief Calculate an expression.
+ \param p expression parser
+ \return \c true if parser has finished work without errors
+*/
+bool QtxPopupMgr::result( QtxEvalParser* p ) const
{
- bool res = false;
- if( p )
- {
- QtxValue vv = p->calculate();
- res = p->lastError()==QtxParser::OK &&
- ( ( vv.type()==QVariant::Int && vv.toInt()!=0 ) ||
- ( vv.type()==QVariant::Bool && vv.toBool() ) );
- }
- return res;
+ bool res = false;
+ if ( p )
+ {
+ QVariant vv = p->calculate();
+ res = p->error() == QtxEvalExpr::OK &&
+ ( ( vv.type() == QVariant::Int && vv.toInt() != 0 ) ||
+ ( vv.type() == QVariant::Bool && vv.toBool() ) );
+ }
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::setParams( QtxParser* p, QStringList& specific ) const
+/*!
+ \brief Fill the parser with parameters of the expression.
+
+ The values of the parameters are given from the selection object
+ (QtxPopupSelection).
+
+ \param p expression parser
+ \param returning list of parameters names which are not retrieved from the selection
+ \sa selection()
+*/
+void QtxPopupMgr::setParameters( QtxEvalParser* p, QStringList& specific ) const
{
- if( !p || !myCurrentSelection )
- return;
-
- QStringList params;
+ if ( !p || !mySelection )
+ return;
- p->paramsList( params );
- QStringList::const_iterator anIt = params.begin(),
- aLast = params.end();
- for( ; anIt!=aLast; anIt++ )
- {
- QtxValue v = myCurrentSelection->globalParam( *anIt );
- if( v.isValid() )
- p->set( *anIt, v );
- else
- specific.append( *anIt );
- }
+ QStringList params = p->parameters();
+ for ( QStringList::const_iterator it = params.begin(); it != params.end(); ++it )
+ {
+ QVariant v = parameter( *it );
+ if ( v.isValid() )
+ p->setParameter( *it, v );
+ else
+ specific.append( *it );
+ }
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-bool QtxPopupMgr::isSatisfied( QAction* act, bool visibility ) const
+/*!
+ \brief Check the rule for the action.
+ \param act action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \return \c true if current selection satisfies the action rule
+*/
+bool QtxPopupMgr::isSatisfied( QAction* act, const RuleType ruleType ) const
{
- QString menu = act->menuText();
- //const char* mmm = menu.latin1();
+ if ( !act )
+ return false;
+
+ QtxEvalExpr* exp = expression( act, ruleType );
+ if ( !exp )
+ return true;
+
+ bool res = false;
- bool res = false;
- if( !act )
- return res;
+ QtxEvalParser* p = exp->parser();
- if( hasRule( act, visibility ) )
+ QStringList specific;
+ p->clearParameters();
+ setParameters( p, specific );
+
+ QMap<QList<QVariant>, int> aCorteges;
+ if ( !specific.isEmpty() )
+ {
+ if ( mySelection )
{
- QtxParser* p = map( visibility )[ act ];
- //QString pdump = p->dump();
- //const char* pdd = pdump.latin1();
-
-
- QStringList specific;
- p->clear();
- ( ( Operations* )myOperations->operations( "custom" ) )->clear();
-
- setParams( p, specific );
-
- if( specific.count()>0 )
- if( myCurrentSelection )
- for( int i=0, n=myCurrentSelection->count(); i<n; i++ )
- {
- QStringList::const_iterator anIt1 = specific.begin(),
- aLast1 = specific.end();
- for( ; anIt1!=aLast1; anIt1++ )
- p->set( *anIt1, myCurrentSelection->param( i, *anIt1 ) );
-
- res = res || result( p );
- }
- else
- res = false;
- else
- res = result( p );
+ res = false;
+ for ( int i = 0; i < mySelection->count() && !res; i++ )
+ {
+ QList<QVariant> c;
+ for ( QStringList::const_iterator anIt1 = specific.begin(); anIt1 != specific.end(); ++anIt1 )
+ c.append( parameter( *anIt1, i ) );
+ aCorteges.insert( c, 0 );
+ }
+ for ( QMap<QList<QVariant>, int>::const_iterator anIt = aCorteges.begin(); anIt != aCorteges.end(); ++anIt )
+ {
+ const QList<QVariant>& aCortege = anIt.key();
+ QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
+ QList<QVariant>::const_iterator anIt2 = aCortege.begin();
+ for ( ; anIt1 != aLast1; anIt1++, anIt2++ )
+ p->setParameter( *anIt1, *anIt2 );
+ res = res || result( p );
+ }
}
+ else
+ res = false;
+ }
+ else
+ res = result( p );
- return res;
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-bool QtxPopupMgr::isVisible( const int actId, const int place ) const
+/*!
+ \brief Check if the menu item is visible.
+ \param id action ID
+ \param place some parent action ID
+ \return \c true if the action is visible
+*/
+bool QtxPopupMgr::isVisible( const int id, const int place ) const
{
- bool res = QtxActionMenuMgr::isVisible( actId, place );
- QAction* act = action( actId );
- if( hasRule( act, true ) )
- res = res && isSatisfied( act, true );
- return res;
+ return QtxActionMenuMgr::isVisible( id, place ) && ( !hasRule( id ) || isSatisfied( action( id ) ) );
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-void QtxPopupMgr::updatePopup( QPopupMenu* p, Selection* sel )
+/*!
+ \brief Perform internal update of the popup menu according
+ to the current selection.
+*/
+void QtxPopupMgr::internalUpdate()
{
- if( !p || !sel )
- return;
+ myCache.clear();
+
+ for ( RuleMap::iterator it = myRules.begin(); it != myRules.end(); ++it )
+ {
+ ExprMap& map = it.value();
+ if ( it.key()->isCheckable() && map.contains( ToggleRule ) &&
+ !map[ToggleRule]->expression().isEmpty() )
+ it.key()->setChecked( isSatisfied( it.key(), ToggleRule ) );
+ }
- myCurrentSelection = sel;
+ QtxActionMenuMgr::internalUpdate();
- RulesMap::iterator anIt = myToggle.begin(),
- aLast = myToggle.end();
- for( ; anIt!=aLast; anIt++ )
- if( anIt.key()->isToggleAction() && hasRule( anIt.key(), false ) )
- anIt.key()->setOn( isSatisfied( anIt.key(), false ) );
+ myCache.clear();
+}
- setWidget( ( QWidget* )p );
- updateMenu();
+/*!
+ \brief Update popup according to the current selection.
+*/
+void QtxPopupMgr::updateMenu()
+{
+ internalUpdate();
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::RulesMap& QtxPopupMgr::map( bool visibility ) const
+/*!
+ \brief Get an syntax expression for the action according to the specified rule type.
+ \param a action
+ \param ruleType rule type (QtxPopupMgr::RuleType)
+ \param create if \c true an expression does not exist, create it
+ \return syntax expression
+*/
+QtxEvalExpr* QtxPopupMgr::expression( QAction* a, const RuleType ruleType, const bool create ) const
{
- return ( RulesMap& )( visibility ? myVisibility : myToggle );
+ QtxEvalExpr* res = 0;
+
+ QtxPopupMgr* that = (QtxPopupMgr*)this;
+ RuleMap& ruleMap = that->myRules;
+ if ( !ruleMap.contains( a ) && create )
+ ruleMap.insert( a, ExprMap() );
+
+ if ( ruleMap.contains( a ) )
+ {
+ ExprMap& exprMap = ruleMap[a];
+ if ( exprMap.contains( ruleType ) )
+ res = exprMap[ruleType];
+ else if ( create )
+ exprMap.insert( ruleType, res = new QtxEvalExpr() );
+ }
+
+ return res;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
+/*!
+ \brief Load actions description from the file.
+ \param fname file name
+ \param r action reader
+ \return \c true on success and \c false on error
+*/
bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
{
PopupCreator cr( &r, this );
return r.read( fname, cr );
}
+/*
+ \brief Get the specified parameter value.
+ \param name parameter name
+ \param idx additional index used when used parameters with same names
+ \return parameter value
+ \sa selection()
+*/
+QVariant QtxPopupMgr::parameter( const QString& name, const int idx ) const
+{
+ QVariant val;
+ QString cacheName = name + ( idx >= 0 ? QString( "_%1" ).arg( idx ) : QString() );
+ if ( myCache.contains( cacheName ) )
+ val = myCache[cacheName];
+ else
+ {
+ if ( selection() )
+ val = idx < 0 ? selection()->parameter( name ) :
+ selection()->parameter( idx, name );
+ if ( val.isValid() )
+ {
+ QtxPopupMgr* that = (QtxPopupMgr*)this;
+ that->myCache.insert( cacheName, val );
+ }
+ }
+ return val;
+}
+/*!
+ \brief Called when selection is destroyed.
+
+ Prevents crashes when the selection object is destroyed outside the
+ popup manager.
+ \param o selection object being destroyed
+*/
+void QtxPopupMgr::onSelectionDestroyed( QObject* o )
+{
+ if ( o == mySelection )
+ mySelection = 0;
+}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
- QtxPopupMgr* mgr )
-: QtxActionMgr::Creator( r ),
- myMgr( mgr )
+/*!
+ \class QtxPopupSelection
+ \brief This class is a part of the popup menu management system.
+
+ The QtxPopupSelection class is used as back-end for getting value
+ of each parameter found in the rule by the expression parser.
+
+ For example, it can be used for the analyzing of the currently
+ selected objects and defining the values of the parameters used
+ in the rules syntax expression. Rules, in their turn, define
+ each action state - visibility, enabled and toggled state.
+*/
+
+/*!
+ \brief Constructor.
+*/
+QtxPopupSelection::QtxPopupSelection()
+ : QObject( 0 ),
+ myPopupMgr( 0 )
{
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QtxPopupMgr::PopupCreator::~PopupCreator()
+/*!
+ \brief Destructor.
+*/
+QtxPopupSelection::~QtxPopupSelection()
{
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
- const ItemAttributes& attr, const int pId )
+/*!
+ \brief Get an option value.
+ \param optName option name
+ \return option value or empty string if option is not found
+*/
+QString QtxPopupSelection::option( const QString& optName ) const
{
- if( !myMgr || !reader() )
- return -1;
+ QString opt;
+ if ( myOptions.contains( optName ) )
+ opt = myOptions[optName];
+ return opt;
+}
- QString label = reader()->option( "label", "label" ),
- id = reader()->option( "id", "id" ),
- pos = reader()->option( "pos", "pos" ),
- group = reader()->option( "group", "group" ),
- tooltip = reader()->option( "tooltip", "tooltip" ),
- sep = reader()->option( "separator", "separator" ),
- accel = reader()->option( "accel", "accel" ),
- icon = reader()->option( "icon", "icon" ),
- toggle = reader()->option( "toggle", "toggle" );
+/*!
+ \brief Set an option value.
+ \param optName option name
+ \param opt option value
+*/
+void QtxPopupSelection::setOption( const QString& optName, const QString& opt )
+{
+ myOptions.insert( optName, opt );
+}
- int res = -1, actId = intValue( attr, id, -1 );;
- if( subMenu )
- res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
- else if( tag==sep )
- res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
- else //if( !myMgr->contains( actId ) )
+QtxPopupMgr* QtxPopupSelection::popupMgr() const
+{
+ return myPopupMgr;
+}
+
+void QtxPopupSelection::setPopupMgr( QtxPopupMgr* pm )
+{
+ myPopupMgr = pm;
+}
+
+/*!
+ \brief Get the parameter value.
+ \param str parameter name
+ \return parameter value
+*/
+QVariant QtxPopupSelection::parameter( const QString& str ) const
+{
+ if ( str == selCountParam() )
+ return count();
+ else if ( str.startsWith( equalityParam() ) )
{
- QPixmap pix; QIconSet set;
- QString name = strValue( attr, icon );
- if( !name.isEmpty() )
+ QtxEvalSetSets::ValueSet set;
+ QString par = str.mid( equalityParam().length() );
+
+ QtxPopupMgr* pMgr = popupMgr();
+ for ( int i = 0; i < (int)count(); i++ )
{
- if( loadPixmap( name, pix ) )
- set = QIconSet( pix );
+ QVariant v = pMgr ? pMgr->parameter( par, i ) : parameter( i, par );
+ if ( v.isValid() )
+ QtxEvalSetSets::add( set, v );
+ else
+ return QVariant();
}
-
- QString actLabel = strValue( attr, label );
- QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
- QKeySequence( strValue( attr, accel ) ),
- myMgr );
- newAct->setToolTip( strValue( attr, tooltip ) );
- QString toggleact = strValue( attr, toggle );
- bool isToggle = !toggleact.isEmpty();
- newAct->setToggleAction( isToggle );
- newAct->setOn( toggleact.lower()=="true" );
-
- connect( newAct );
- int aid = myMgr->registerAction( newAct, visibleRule( attr ),
- isToggle ? toggleRule( attr ) : QString::null,
- actId );
- res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
+ return set;
}
-
- return res;
+ else
+ return QVariant();
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const
+/*!
+ \brief Get symbol which detects the name of the parameter list.
+ \return equality symbol (by default, "$")
+*/
+QString QtxPopupSelection::equalityParam() const
{
- return QString::null;
+ QString str = option( "equality" );
+ if ( str.isEmpty() )
+ str = "$";
+ return str;
}
-//================================================================
-// Function :
-// Purpose :
-//================================================================
-QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const
+/*!
+ \brief Get name of the parameter, specifing number of selected objects
+ \return parameter name (by default, "selcount")
+*/
+QString QtxPopupSelection::selCountParam() const
{
- return QString::null;
+ QString str = option( "selcount" );
+ if ( str.isEmpty() )
+ str = "selcount";
+ return str;
}
+
+/*!
+ \fn int QtxPopupSelection::count() const;
+ \brief Get number of the selected objects.
+ \return nb of selected objects
+*/
+
+/*!
+ \fn QVariant QtxPopupSelection::parameter( const int idx, const QString& name ) const;
+ \brief Get value of the parameter which is of list type
+ \param idx parameter index
+ \param name parameter name
+ \return parameter value
+*/