From 332d688f635be40597406f7f8979fa4ebe43242a Mon Sep 17 00:00:00 2001 From: stv Date: Mon, 28 May 2007 11:25:08 +0000 Subject: [PATCH] no message --- src/Qtx/QtxActionMenuMgr.cxx | 27 +- src/Qtx/QtxActionMenuMgr.h | 7 +- src/Qtx/QtxPopupMgr.cxx | 880 ++++++++++++++++------------------- src/Qtx/QtxPopupMgr.h | 131 +++--- 4 files changed, 468 insertions(+), 577 deletions(-) diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index 5e9dc0188..6a6a5fe12 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -146,18 +146,11 @@ QtxActionMenuMgr::QtxActionMenuMgr( QWidget* mw, QObject* p ) */ QtxActionMenuMgr::~QtxActionMenuMgr() { - for ( NodeList::iterator it = myRoot->children.begin(); it != myRoot->children.end() && myMenu; ++it ) - { - QAction* a = itemAction( (*it)->id ); - if ( !a ) - a = menuAction( (*it)->id ); - -// if ( a ) -// a->removeFrom( myMenu ); - } - for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) + { + delete itr.value()->menu(); delete itr.value(); + } delete myRoot; } @@ -342,7 +335,7 @@ int QtxActionMenuMgr::insert( const QString& title, const int pId, const int gro int gid = (id == -1 || eNode ) ? generateId() : id; QAction* ma = new QAction( title, this ); - ma->setMenu( new QMenu( myMenu ) ); + ma->setMenu( new QMenu( 0 ) ); connect( ma->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); connect( ma->menu(), SIGNAL( aboutToHide() ), this, SLOT( onAboutToHide() ) ); @@ -638,11 +631,19 @@ void QtxActionMenuMgr::onHighlighted( int id ) } } +/*! + \brief Returns the menu widget. +*/ +QWidget* QtxActionMenuMgr::menuWidget() const +{ + return myMenu; +} + /*! \brief Assign new menu widget to the menu manager. \param mw new menu widget */ -void QtxActionMenuMgr::setWidget( QWidget* mw ) +void QtxActionMenuMgr::setMenuWidget( QWidget* mw ) { if ( myMenu == mw ) return; @@ -654,6 +655,8 @@ void QtxActionMenuMgr::setWidget( QWidget* mw ) if ( myMenu ) connect( myMenu, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) ); + + triggerUpdate( -1, true ); } /*! diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index 4ba7214f2..c475de410 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -51,6 +51,8 @@ public: QtxActionMenuMgr( QWidget*, QObject* ); virtual ~QtxActionMenuMgr(); + QWidget* menuWidget() const; + virtual bool isVisible( const int, const int ) const; virtual void setVisible( const int, const int, const bool ); @@ -104,7 +106,8 @@ signals: void menuHighlighted( int, int ); protected: - void setWidget( QWidget* ); + void setMenuWidget( QWidget* ); + MenuNode* find( const int, const int, const bool = true ) const; MenuNode* find( const int, MenuNode* = 0, const bool = true ) const; bool find( const int, NodeList&, MenuNode* = 0 ) const; @@ -119,7 +122,7 @@ protected: QAction* menuAction( const int ) const; void updateMenu( MenuNode* = 0, const bool = true, const bool = true ); - virtual void internalUpdate(); + virtual void internalUpdate(); virtual void updateContent(); private: diff --git a/src/Qtx/QtxPopupMgr.cxx b/src/Qtx/QtxPopupMgr.cxx index 5f0df3de8..9f85263e4 100644 --- a/src/Qtx/QtxPopupMgr.cxx +++ b/src/Qtx/QtxPopupMgr.cxx @@ -18,337 +18,179 @@ // #include "QtxPopupMgr.h" -#include "QtxListOfOperations.h" -#include "QtxStdOperations.h" #include "QtxAction.h" -#include -#include - +#include /*! - \return value of global parameter (depending on whole selection, but not dependending on one object of selection) - \param str - name of parameter - - By default, it returns count of selected objects ("selcount") and list of parameters ("$") + \class QtxPopupMgr::PopupCreator */ -QtxValue QtxPopupMgr::Selection::globalParam( const QString& str ) const +class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator { - if( str==selCountParam() ) - return count(); +public: + PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* ); + virtual ~PopupCreator(); - else if( str[0]==equality() ) - { - QtxSets::ValueSet set; - QString par = str.mid( 1 ); + virtual int append( const QString&, const bool, + const ItemAttributes&, const int ); - for( int i=0, n=count(); ioption( "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" ); - virtual int count() const; - virtual QtxValue param( const int, const QString& ) const; - virtual QtxValue globalParam( const QString& ) const; + QtxActionMenuMgr* mgr = myMgr; -private: - typedef QMap< QString, QtxValue > CacheMap; + 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 ); + } - QtxPopupMgr::Selection* mySel; - CacheMap myParamCache; -}; + 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 ); + myMgr->setRule( newAct, visibleRule( attr ), QtxPopupMgr::VisibleRule ); + myMgr->setRule( newAct, isToggle ? toggleRule( attr ) : QString(), QtxPopupMgr::ToggleRule ); + res = mgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) ); + } -/*! - Constructor - \param sel - base selection used for parameter calculation -*/ -QtxCacheSelection::QtxCacheSelection( QtxPopupMgr::Selection* sel ) -: mySel( sel ) -{ + return res; } /*! - Destructor + \return visibility rule by attributes + Default implementation is empty */ -QtxCacheSelection::~QtxCacheSelection() +QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const { + return QString::null; } /*! - \return count of selected objects + \return toggle rule by attributes + Default implementation is empty */ -int QtxCacheSelection::count() const +QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const { - return mySel ? mySel->count() : 0; + return QString::null; } /*! - Calculates and caches parameters. - Already calculated parameters are returned without calculation - \return parameter value - \param i - index of selected object - \param name - name of parameter + \class QPopupMgr */ -QtxValue QtxCacheSelection::param( const int i, const QString& name ) const -{ - QString param_name = name + "#####" + QString::number( i ); - if( myParamCache.contains( param_name ) ) - return myParamCache[ param_name ]; - else - { - QtxValue v; - if( mySel ) - v = mySel->param( i, name ); - if( v.isValid() ) - ( ( CacheMap& )myParamCache ).insert( param_name, v ); - return v; - } -} /*! - Calculates and caches global parameters. - Already calculated parameters are returned without calculation - \return parameter value - \param name - name of parameter + Constructor */ -QtxValue QtxCacheSelection::globalParam( const QString& name ) const +QtxPopupMgr::QtxPopupMgr( QObject* parent ) +: QtxActionMenuMgr( 0, parent ), + mySelection( 0 ) { - if( myParamCache.contains( name ) ) - return myParamCache[ name ]; - else - { - QtxValue v; - if( mySel ) - v = mySel->globalParam( name ); - if( v.isValid() ) - ( ( CacheMap& )myParamCache ).insert( name, v ); - return v; - } } - - - /*! Constructor - \param mgr - popup manager */ -QtxPopupMgr::Operations::Operations( QtxPopupMgr* mgr ) -: QtxStrings(), - myPopupMgr( mgr ) +QtxPopupMgr::QtxPopupMgr( QMenu* popup, QObject* parent ) +: QtxActionMenuMgr( popup, parent ), + mySelection( 0 ) { - QStringList aList; - aList.append( "every" ); - aList.append( "any" ); - aList.append( "onlyone" ); - addOperations( aList ); - - myParser = new QtxParser( mgr->myOperations ); } /*! Destructor - Deletes internal parser */ -QtxPopupMgr::Operations::~Operations() +QtxPopupMgr::~QtxPopupMgr() { - delete myParser; } -/*! - \return priority of popup operation 'op'. - \param isBin indicate whether the operation is binary -*/ -int QtxPopupMgr::Operations::prior( const QString& op, bool isBin ) const +QMenu* QtxPopupMgr::menu() const { - if( !isBin && ( op=="every" || op=="any" || op=="onlyone" ) ) - return 1; - else - return QtxStrings::prior( op, isBin ); - + return ::qobject_cast( menuWidget() ); } -/*! - Calculates result of operation - \return one of error states - \param op - name of operation - \param v1 - first operation argument (must be used also to store result) - \param v2 - second operation argument -*/ -QtxParser::Error QtxPopupMgr::Operations::calculate - ( const QString& op, QtxValue& v1, QtxValue& v2 ) const -{ - 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(); iparam( 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 ); -} - -/*! - Clears internal map of values -*/ -void QtxPopupMgr::Operations::clear() +void QtxPopupMgr::setMenu( QMenu* menu ) { - myValues.clear(); + setMenuWidget( menu ); } - - - - - - - -/*! - Constructor -*/ -QtxPopupMgr::QtxPopupMgr( QPopupMenu* popup, QObject* parent ) -: QtxActionMenuMgr( popup, parent ), - myCurrentSelection( 0 ) +QtxPopupSelection* QtxPopupMgr::selection() const { - createOperations(); + return mySelection; } -/*! - Destructor -*/ -QtxPopupMgr::~QtxPopupMgr() +void QtxPopupMgr::setSelection( QtxPopupSelection* sel ) { -} + if ( mySelection == sel ) + return; -/*! - Creates popup operations instance -*/ -void QtxPopupMgr::createOperations() -{ - myOperations = new QtxListOfOperations; - myOperations->prepend( "logic", new QtxLogic(), 0 ); - myOperations->prepend( "arithm", new QtxArithmetics(), 50 ); - myOperations->append( "strings", new QtxStrings(), 100 ); - myOperations->append( "sets", new QtxSets(), 150 ); - myOperations->append( "custom", new Operations( this ), 200 ); + mySelection = sel; + + QtxActionMgr::triggerUpdate(); } /*! @@ -358,15 +200,11 @@ void QtxPopupMgr::createOperations() \param toggle - rule for toggle on state \param id - proposed id (if it is less than 0, then id will be generated automatically) */ -int QtxPopupMgr::registerAction( QAction* act, - const QString& visible, - const QString& toggle, - const int id ) +int QtxPopupMgr::registerAction( QAction* act, const int id, const QString& rule, const QtxPopupMgr::RuleType type ) { - int _id = QtxActionMenuMgr::registerAction( act, id ); - setRule( _id, visible, true ); - setRule( _id, toggle, false ); - return _id; + int _id = QtxActionMenuMgr::registerAction( act, id ); + setRule( act, rule, type ); + return _id; } /*! @@ -375,13 +213,17 @@ int QtxPopupMgr::registerAction( QAction* act, */ void QtxPopupMgr::unRegisterAction( const int id ) { - QAction* act = action( 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 ); - myVisibility.remove( act ); - myToggle.remove( act ); + remove( id ); - remove( id ); - //QtxActionMenuMgr::unRegisterAction( id ); + QtxActionMenuMgr::unRegisterAction( id ); } /*! @@ -389,75 +231,87 @@ void QtxPopupMgr::unRegisterAction( const int id ) \param act - action \param visibility - if it is true, then rule for "visibility" is checked, otherwise - for "toggle" */ -bool QtxPopupMgr::hasRule( QAction* act, bool visibility ) const +int QtxPopupMgr::insert( const int id, const int pId, const QString& rule, const RuleType ruleType ) +{ + int res = QtxActionMenuMgr::insert( id, pId, -1 ); + setRule( action( id ), rule, ruleType ); + return res; +} + +int QtxPopupMgr::insert( QAction* a, const int pId, const QString& rule, const RuleType ruleType ) +{ + int res = QtxActionMenuMgr::insert( a, pId, -1 ); + setRule( a, rule, ruleType ); + return res; +} + +/*! + \return Rule of a specified action + \param a - action + \param type - type of rule +*/ +QString QtxPopupMgr::rule( QAction* a, const RuleType type ) const { - return map( visibility ).contains( act ); + QString rule; + QtxEvalExpr* expr = expression( a, type ); + if ( expr ) + rule = expr->expression(); + return rule; } /*! - \return true if manager has rule for action + \return Rule of action with a specified id \param id - action id - \param visibility - if it is true, then rule for "visibility" is checked, otherwise - for "toggle" + \param type - type of rule */ -bool QtxPopupMgr::hasRule( const int id, bool visibility ) const +QString QtxPopupMgr::rule( const int id, const RuleType type ) const { - return hasRule( action( id ), visibility ); + return rule( action( id ), type ); } /*! Sets new rule for action \param act - action \param rule - string expression of rule - \param visibility - if it is true, then rule for "visibility" will be set, otherwise - for "toggle" + \param type - type of rule */ -void QtxPopupMgr::setRule( QAction* act, const QString& rule, bool visibility ) +void QtxPopupMgr::setRule( QAction* act, const QString& rule, const RuleType type ) { - if( !act || rule.isEmpty() ) - return; + if ( !act ) + 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( act, type, true ); + + expr->setExpression( rule ); } /*! Sets new rule for action \param id - action id \param rule - string expression of rule - \param visibility - if it is true, then rule for "visibility" will be set, otherwise - for "toggle" + \param type - type of rule */ -void QtxPopupMgr::setRule( const int id, const QString& rule, bool visibility ) +void QtxPopupMgr::setRule( const int id, const QString& rule, const RuleType type ) { - setRule( action( id ), rule, visibility ); + setRule( action( id ), rule, type ); } /*! \return true if parser has finished work without errors \param p - parser */ -bool result( QtxParser* p ) + +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; } /*! @@ -465,67 +319,63 @@ bool result( QtxParser* p ) \param p - parser \param specific - list will be filled with names of parameters depending on selection objects (not global) */ -void QtxPopupMgr::setParams( QtxParser* p, QStringList& specific ) const +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 ); + } } /*! \return true if 'v1'<'v2' This function can work with many types of values */ -bool operator<( const QtxValue& v1, const QtxValue& v2 ) +bool operator<( const QVariant& v1, const QVariant& v2 ) { QVariant::Type t1 = v1.type(), t2 = v2.type(); - if( t1==t2 ) + if ( t1 == t2 ) { switch( t1 ) { case QVariant::Int: return v1.toInt() < v2.toInt(); - + break; case QVariant::Double: return v1.toDouble() < v2.toDouble(); - - case QVariant::CString: + break; case QVariant::String: return v1.toString() < v2.toString(); - + break; case QVariant::StringList: case QVariant::List: { - const QValueList& aList1 = v1.toList(), aList2 = v2.toList(); - QValueList::const_iterator - anIt1 = aList1.begin(), aLast1 = aList1.end(), - anIt2 = aList2.begin(), aLast2 = aList2.end(); - for( ; anIt1!=aLast1 && anIt2!=aLast2; anIt1++, anIt2++ ) - if( (*anIt1)!=(*anIt2) ) - return (*anIt1)<(*anIt2); - - return anIt1==aLast1 && anIt2!=aLast2; + const QList& aList1 = v1.toList(), aList2 = v2.toList(); + QList::const_iterator anIt1 = aList1.begin(), aLast1 = aList1.end(), + anIt2 = aList2.begin(), aLast2 = aList2.end(); + for ( ; anIt1 != aLast1 && anIt2 != aLast2; anIt1++, anIt2++ ) + { + if ( (*anIt1) != (*anIt2) ) + return (*anIt1)<(*anIt2); + } + return anIt1 == aLast1 && anIt2 != aLast2; + break; } - default: - return v1.toString()menuText(); + if ( !act ) + return false; - bool res = false; - if( !act ) - return res; + QtxEvalExpr* exp = expression( act, type ); + if ( !exp ) + return true; - if( hasRule( act, visibility ) ) - { - QtxParser* p = map( visibility )[ act ]; - QStringList specific; - p->clear(); - ( ( Operations* )myOperations->operations( "custom" ) )->clear(); + bool res = false; - setParams( p, specific ); + QtxEvalParser* p = exp->parser(); - QMap,int> aCorteges; - QValueList c; + QStringList specific; + p->clearParameters(); + setParameters( p, specific ); - if( specific.count()>0 ) - if( myCurrentSelection ) + QMap, int> aCorteges; + if ( !specific.isEmpty() ) + { + if ( mySelection ) + { + res = false; + for ( int i = 0; i < mySelection->count() && !res; i++ ) { - res = false; - - for( int i=0, n=myCurrentSelection->count(); iparam( i, *anIt1 ) ); - aCorteges.insert( c, 0 ); - } - - //qDebug( QString( "%1 corteges" ).arg( aCorteges.count() ) ); - QMap,int>::const_iterator anIt = aCorteges.begin(), aLast = aCorteges.end(); - for( ; anIt!=aLast; anIt++ ) - { - QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end(); - const QValueList& aCortege = anIt.key(); - QValueList::const_iterator anIt2 = aCortege.begin(); - for( ; anIt1!=aLast1; anIt1++, anIt2++ ) - p->set( *anIt1, *anIt2 ); - res = res || result( p ); - } - - /* - for( int i=0, n=myCurrentSelection->count(); iset( *anIt1, myCurrentSelection->param( i, *anIt1 ) ); - res = res || result( p ); - }*/ - } - else - res = false; + QList c; + for ( QStringList::const_iterator anIt1 = specific.begin(); anIt1 != specific.end(); ++anIt1 ) + c.append( parameter( *anIt1, i ) ); + aCorteges.insert( c, 0 ); + } + for ( QMap, int>::const_iterator anIt = aCorteges.begin(); anIt != aCorteges.end(); ++anIt ) + { + const QList& aCortege = anIt.key(); + QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end(); + QList::const_iterator anIt2 = aCortege.begin(); + for ( ; anIt1 != aLast1; anIt1++, anIt2++ ) + p->setParameter( *anIt1, *anIt2 ); + res = res || result( p ); + } + } else - res = result( p ); + res = false; } + else + res = result( p ); return res; } @@ -604,11 +439,7 @@ bool QtxPopupMgr::isSatisfied( QAction* act, bool visibility ) const */ bool QtxPopupMgr::isVisible( const int actId, 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( actId, place ) && isSatisfied( action( actId ) ); } /*! @@ -616,36 +447,56 @@ bool QtxPopupMgr::isVisible( const int actId, const int place ) const \param p - popup menu \param sel - selection */ -void QtxPopupMgr::updatePopup( QPopupMenu* p, Selection* sel ) +void QtxPopupMgr::internalUpdate() { - QTime t1 = QTime::currentTime(); - - if( !p || !sel ) - return; + myCache.clear(); - myCurrentSelection = new QtxCacheSelection( sel ); - 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 ) ); + 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 ) ); + } - setWidget( ( QWidget* )p ); - updateMenu(); - QTime t2 = QTime::currentTime(); - qDebug( QString( "update popup time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) ); - qDebug( QString( "number of objects = %1" ).arg( myCurrentSelection->count() ) ); + QtxActionMenuMgr::internalUpdate(); +} - delete myCurrentSelection; +/*! + Updates popup according to selection + \param p - popup menu + \param sel - selection +*/ +void QtxPopupMgr::updateMenu() +{ + internalUpdate(); } /*! - \return reference to map of rules - \param visibility - type of map: visibility of toggle + \return reference to eval expression + \param a - action + \param type - rule type + \param create - create eval expression if it doesn't exist */ -QtxPopupMgr::RulesMap& QtxPopupMgr::map( bool visibility ) const +QtxEvalExpr* QtxPopupMgr::expression( QAction* a, const RuleType type, 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( type ) ) + res = exprMap[type]; + else if ( create ) + exprMap.insert( type, res = new QtxEvalExpr() ); + } + + return res; } /*! @@ -659,101 +510,150 @@ bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r ) PopupCreator cr( &r, this ); return r.read( fname, cr ); } + +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; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + /*! - Constructor - \param r - menu reader - \param mgr - menu manager + \class QtxPopupSelection */ -QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r, - QtxPopupMgr* mgr ) -: QtxActionMgr::Creator( r ), - myMgr( mgr ) + +QString QtxPopupSelection::option( const QString& optName ) const { + QString opt; + if ( myOptions.contains( optName ) ) + opt = myOptions[optName]; + return opt; } -/*! - Destructor -*/QtxPopupMgr::PopupCreator::~PopupCreator() +void QtxPopupSelection::setOption( const QString& optName, const QString& opt ) { + myOptions.insert( optName, opt ); } - /*! - Appends new menu items - \param tag - tag of item - \param subMenu - it has submenu - \param attr - list of attributes - \param pId - id of action corresponding to parent item + \return value of global parameter (depending on whole selection, but not + dependending on one object of selection) + \param str - name of parameter + + By default, it returns count of selected objects ("selcount") and list of parameters ("$") */ -int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu, - const ItemAttributes& attr, const int pId ) +QVariant QtxPopupSelection::parameter( const QString& str ) const { - 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" ); - - 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 ) ) + 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() ); + for ( int i = 0; i < (int)count(); i++ ) { - if( loadPixmap( name, pix ) ) - set = QIconSet( pix ); + QVariant v = 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(); } /*! - \return visibility rule by attributes - Default implementation is empty + \return symbole to detect name of parameter list */ -QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const +QString QtxPopupSelection::equalityParam() const { - return QString::null; + QString str = option( "equality" ); + if ( str.isEmpty() ) + str = "$"; + return str; } /*! - \return toggle rule by attributes - Default implementation is empty + \return name of parameter for count of selected objects */ -QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const +QString QtxPopupSelection::selCountParam() const { - return QString::null; + QString str = option( "equality" ); + if ( str.isEmpty() ) + str = "selcount"; + return str; } diff --git a/src/Qtx/QtxPopupMgr.h b/src/Qtx/QtxPopupMgr.h index 7bc260b3b..2ae7f5a28 100644 --- a/src/Qtx/QtxPopupMgr.h +++ b/src/Qtx/QtxPopupMgr.h @@ -17,116 +17,101 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef __QTX_POPUP_MGR_HEADER__ -#define __QTX_POPUP_MGR_HEADER__ +#ifndef QTXPOPUPMGR_H +#define QTXPOPUPMGR_H -#include "Qtx.h" +#include "QtxEvalExpr.h" #include "QtxActionMenuMgr.h" -#include "QtxParser.h" -#include "QtxStdOperations.h" -#include +#include -class QtxListOfOperations; +class QtxPopupSelection; + +/*! + \class QPopupMgr +*/ class QTX_EXPORT QtxPopupMgr : public QtxActionMenuMgr { Q_OBJECT public: - class QTX_EXPORT Selection - { - public: - virtual int count() const = 0; - virtual QtxValue param( const int, const QString& ) const = 0; - virtual QtxValue globalParam( const QString& ) const; - - virtual QChar equality() const; - virtual QString selCountParam() const; - - static QChar defEquality(); - static QString defSelCountParam(); - }; + typedef enum { VisibleRule, EnableRule, ToggleRule } RuleType; protected: - class Operations : public QtxStrings - { - public: - Operations( QtxPopupMgr* ); - virtual ~Operations(); + class PopupCreator; - virtual int prior( const QString&, bool isBin ) const; - virtual QtxParser::Error calculate( const QString&, QtxValue&, QtxValue& ) const; +public: + QtxPopupMgr( QObject* = 0 ); + QtxPopupMgr( QMenu*, QObject* = 0 ); + virtual ~QtxPopupMgr(); - void clear(); + int insert( const int, const int, const QString&, const RuleType = VisibleRule ); + int insert( QAction*, const int, const QString&, const RuleType = VisibleRule ); - private: - QtxPopupMgr* myPopupMgr; - QtxParser* myParser; - QMap< QString, QtxValue > myValues; - }; + virtual int registerAction( QAction*, const int, const QString& rule, + const RuleType = VisibleRule ); + virtual void unRegisterAction( const int ); - friend class Operations; + virtual bool isVisible( const int actId, const int place ) const; -protected: - class PopupCreator; + QString rule( QAction*, const RuleType = VisibleRule ) const; + QString rule( const int, const RuleType = VisibleRule ) const; -public: - QtxPopupMgr( QPopupMenu*, QObject* = 0 ); - virtual ~QtxPopupMgr(); + void setRule( QAction*, const QString&, const RuleType = VisibleRule ); + void setRule( const int, const QString&, const RuleType = VisibleRule ); - virtual int registerAction( QAction*, - const QString& visible, - const QString& toggle = QString::null, - const int = -1 ); - virtual void unRegisterAction( const int ); + QtxPopupSelection* selection() const; + void setSelection( QtxPopupSelection* ); - virtual bool isVisible( const int actId, const int place ) const; + QMenu* menu() const; + void setMenu( QMenu* ); - bool hasRule( QAction*, bool visibility ) const; - bool hasRule( const int, bool visibility ) const; - void setRule( QAction*, const QString&, bool visibility ); - void setRule( const int, const QString&, bool visibility ); - void updatePopup( QPopupMenu*, Selection* ); + void updateMenu(); - //return name of parameter corresponding to selected objects count - //it will be set automatically - - virtual bool load( const QString&, QtxActionMgr::Reader& ); + virtual bool load( const QString&, QtxActionMgr::Reader& ); protected: - typedef QMap< QAction*, QtxParser* > RulesMap; + virtual void internalUpdate(); + void setParameters( QtxEvalParser*, QStringList& ) const; + virtual bool isSatisfied( QAction*, const RuleType = VisibleRule ) const; + QtxEvalExpr* expression( QAction*, const RuleType = VisibleRule, const bool = false ) const; -protected: - virtual bool isSatisfied( QAction*, bool visibility ) const; - void setParams( QtxParser*, QStringList& ) const; - RulesMap& map( bool visibility ) const; +private: + bool result( QtxEvalParser* p ) const; + QVariant parameter( const QString&, const int = -1 ) const; - void createOperations(); +private: + typedef QMap ExprMap; + typedef QMap RuleMap; + typedef QMap CacheMap; private: - RulesMap myVisibility, myToggle; - Selection* myCurrentSelection; - QtxListOfOperations* myOperations; + RuleMap myRules; + CacheMap myCache; + QtxPopupSelection* mySelection; }; +/*! + \class QtxPopupSelection +*/ - -class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator +class QTX_EXPORT QtxPopupSelection { public: - PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* ); - virtual ~PopupCreator(); + virtual int count() const = 0; + virtual QVariant parameter( const QString& ) const; + virtual QVariant parameter( const int, const QString& ) const = 0; - virtual int append( const QString&, const bool, - const ItemAttributes&, const int ); + QString option( const QString& ) const; + void setOption( const QString&, const QString& ); - virtual QString visibleRule( const ItemAttributes& ) const; - virtual QString toggleRule( const ItemAttributes& ) const; +private: + QString equalityParam() const; + QString selCountParam() const; private: - QtxPopupMgr* myMgr; + QMap myOptions; }; - #endif -- 2.39.2