Salome HOME
Merge remote branch 'origin/V7_dev'
[modules/gui.git] / src / Qtx / QtxPopupMgr.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:      QtxPopupMgr.cxx
24 // Author:    Alexander SOLOVYOV, Sergey TELKOV
25 //
26 #include "QtxPopupMgr.h"
27 #include "QtxAction.h"
28 #include "QtxEvalExpr.h"
29 #include <QList>
30 #include <QMenu>
31 #include <QVariant>
32
33 #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
34  
35 /*!
36   \brief Used for comparing of two QVariant values.
37   \param v1 first argument for comparison
38   \param v2 second argument for comparison
39   \return \c true if \a v1 less than \a v2
40 */
41 bool operator<( const QVariant& v1, const QVariant& v2 )
42 {
43   QVariant::Type t1 = v1.type(), t2 = v2.type();
44   if ( t1 == t2 )
45   {
46     switch( t1 )
47     {
48     case QVariant::Int:
49       return v1.toInt() < v2.toInt();
50     case QVariant::Double:
51       return v1.toDouble() < v2.toDouble();
52     case QVariant::String:
53       return v1.toString() < v2.toString();
54     case QVariant::StringList:
55     case QVariant::List:
56     {
57       const QList<QVariant>& aList1 = v1.toList(), aList2 = v2.toList();
58       QList<QVariant>::const_iterator anIt1 = aList1.begin(), aLast1 = aList1.end(),
59         anIt2 = aList2.begin(), aLast2 = aList2.end();
60       for ( ; anIt1 != aLast1 && anIt2 != aLast2;  anIt1++, anIt2++ )
61       {
62         if ( (*anIt1) != (*anIt2) )
63           return (*anIt1) < (*anIt2);
64       }
65       return anIt1 == aLast1 && anIt2 != aLast2;
66     }
67     default:
68       return v1.toString() < v2.toString();
69     }
70   }
71   return t1 < t2;
72 }
73
74 #else
75
76 bool operator<( const QList<QVariant>& v1, const QList<QVariant>& v2 )
77 {
78   QList<QVariant>::const_iterator anIt1 = v1.begin(), aLast1 = v1.end(),
79     anIt2 = v2.begin(), aLast2 = v2.end();
80   for ( ; anIt1 != aLast1 && anIt2 != aLast2;  anIt1++, anIt2++ )
81   {
82     if ( (*anIt1) != (*anIt2) )
83       return (*anIt1) < (*anIt2);
84   }
85   return anIt1 == aLast1 && anIt2 != aLast2;
86 }
87
88 #endif // QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
89
90 /*!
91   \class QtxPopupMgr::PopupCreator
92   \internal
93   \brief Popup menu actions creator.
94
95   Used by Reader to create actions by reading descriptions from the file
96   and fill in the action manager with the actions.
97 */
98
99 class QtxPopupMgr::PopupCreator : public QtxActionMgr::Creator
100 {
101 public:
102   PopupCreator( QtxActionMgr::Reader*, QtxPopupMgr* );
103   virtual ~PopupCreator();
104
105   virtual int     append( const QString&, const bool,
106                           const ItemAttributes&, const int );
107
108   virtual QString rule( const ItemAttributes&, 
109                         const QtxPopupMgr::RuleType = VisibleRule ) const;
110
111 private:
112   QtxPopupMgr*    myMgr;
113 };
114
115 /*!
116   \brief Constructor.
117   \param r menu action reader
118   \param mgr popup menu manager
119 */
120 QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
121                                          QtxPopupMgr* mgr )
122 : QtxActionMgr::Creator( r ),
123   myMgr( mgr )
124 {
125 }
126
127 /*!
128   \brief Destructor.
129 */
130 QtxPopupMgr::PopupCreator::~PopupCreator()
131 {
132 }
133
134 /*!
135   \brief Create and append new action to the action manager.
136   \param tag item tag name
137   \param subMenu \c true if this item is submenu
138   \param attr attributes map
139   \param pId parent action ID
140   \return menu action ID
141 */
142 int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
143                                        const ItemAttributes& attr, const int pId )
144 {
145   if ( !myMgr || !reader() )
146     return -1;
147
148   QString label   = reader()->option( "label",     "label"     ),
149           id      = reader()->option( "id",        "id"        ),
150           pos     = reader()->option( "pos",       "pos"       ),
151           group   = reader()->option( "group",     "group"     ),
152           tooltip = reader()->option( "tooltip",   "tooltip"   ),
153           sep     = reader()->option( "separator", "separator" ),
154           accel   = reader()->option( "accel",     "accel"     ),
155           icon    = reader()->option( "icon",      "icon"      ),
156           toggle  = reader()->option( "toggle",    "toggle"    );
157
158   QtxActionMenuMgr* mgr = myMgr;
159
160   int res = -1, actId = intValue( attr, id, -1 );;
161   if ( subMenu )
162     res = mgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
163   else if ( tag == sep )
164     res = mgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
165   else
166   {
167     QIcon set;
168     QPixmap pix;
169     QString name = strValue( attr, icon );
170     if( !name.isEmpty() )
171     {
172       if ( loadPixmap( name, pix ) )
173         set = QIcon( pix );
174     }
175
176     QString actLabel = strValue( attr, label );
177     QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
178                                        QKeySequence( strValue( attr, accel ) ),
179                                        myMgr );
180     newAct->setToolTip( strValue( attr, tooltip ) );
181     QString toggleact = strValue( attr, toggle );
182     bool isToggle = !toggleact.isEmpty();
183     newAct->setCheckable( isToggle );
184     newAct->setChecked( toggleact.toLower() == "true" );
185         
186     connect( newAct );
187     int aid = mgr->registerAction( newAct, actId ); 
188     QString arule = rule( attr, QtxPopupMgr::VisibleRule );
189     if ( !arule.isEmpty() )
190       myMgr->setRule( newAct, arule, QtxPopupMgr::VisibleRule );
191     arule = rule( attr, QtxPopupMgr::EnableRule );
192     if ( !arule.isEmpty() )
193       myMgr->setRule( newAct, arule, QtxPopupMgr::EnableRule );
194     arule = rule( attr, QtxPopupMgr::ToggleRule );
195     if ( isToggle && !arule.isEmpty() )
196       myMgr->setRule( newAct, arule, QtxPopupMgr::ToggleRule );
197     res = mgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
198   }
199
200   return res;
201 }
202
203 /*!
204   \brief Get the rule for the menu item.
205
206   Default implementation returns empty rule.
207
208   \param attr attributes map
209   \param ruleType rule type (QtxPopupMgr::RuleType)
210   \return rule for the menu item corresponding to the rule type
211 */
212 QString QtxPopupMgr::PopupCreator::rule( const ItemAttributes& /*attr*/, 
213                                          const QtxPopupMgr::RuleType /*ruleType*/ ) const
214 {
215   return QString();
216 }
217
218 /*!
219   \class QtxPopupMgr
220   \brief Popup menu manager.
221
222   Menu manager allows using of set of action for automatic generating of
223   application context popup menu by reuquest and dynamic update of its
224   contents.
225
226   Use insert() methods to add menu items to the popup menu.
227
228   The visibility, enable and toggle state of the menu item is controlled
229   by the syntaxic rules, which can be set with setRule() methods.
230   The rules are parsed automatically with help of QtxEvalParser class.
231
232   QtxPopupSelection class is used as back-end for getting value of each
233   parameter found in the rule by the expression parser.
234   Use setSelection() and selection() to set/get the selection instance
235   for the popup menu manager.
236   
237   Popup menu manager automatically optimizes the menu by removing 
238   extra separators, hiding empty popup submenus etc.
239 */
240
241 /*!
242   \brief Constructor.
243   \param object parent object
244 */
245 QtxPopupMgr::QtxPopupMgr( QObject* parent )
246 : QtxActionMenuMgr( 0, parent ),
247   mySelection( 0 )
248 {
249 }
250
251 /*!
252   \brief Constructor.
253   \param popup popup menu
254   \param object parent object
255 */
256 QtxPopupMgr::QtxPopupMgr( QMenu* popup, QObject* parent )
257 : QtxActionMenuMgr( popup, parent ),
258   mySelection( 0 )
259 {
260 }
261
262 /*!
263   \brief Destructor.
264 */
265 QtxPopupMgr::~QtxPopupMgr()
266 {
267 }
268
269 /*!
270   \brief Get popup menu.
271   \return popup menu
272 */
273 QMenu* QtxPopupMgr::menu() const
274 {
275   return ::qobject_cast<QMenu*>( menuWidget() );
276 }
277
278 /*!
279   \brief Get popup menu.
280   \param menu popup menu
281 */
282 void QtxPopupMgr::setMenu( QMenu* menu )
283 {
284   setMenuWidget( menu );
285 }
286
287 /*!
288   \brief Get selection.
289   \return current selection object
290 */
291 QtxPopupSelection* QtxPopupMgr::selection() const
292 {
293   return mySelection;
294 }
295
296 /*!
297   \brief Set selection.
298   \param sel new selection object
299 */
300 void QtxPopupMgr::setSelection( QtxPopupSelection* sel )
301 {
302   if ( mySelection == sel )
303     return;
304
305   delete mySelection;
306
307   mySelection = sel;
308
309   if ( mySelection ) {
310     mySelection->setParent( this );
311     mySelection->setPopupMgr( this );
312   }
313
314   connect( mySelection, SIGNAL( destroyed( QObject* ) ), 
315            this,        SLOT( onSelectionDestroyed( QObject* ) ) );
316
317   QtxActionMgr::triggerUpdate();
318 }
319
320 /*!
321   \brief Register an action and return its identifier.
322
323   If \a id is less than 0, the identifier for the action is generated automatically.
324   If action with given \a id is already registered, it will be re-registered.
325   If required \a id is already in use, new identifier is generatied; in this case
326   returning value will different from required one.
327
328   \param act action to be registered
329   \param id action ID
330   \param rule syntax rule
331   \param ruleType rule type (QtxPopupMgr::RuleType)
332   \return action ID (the same as \a id or generated one)
333 */
334 int QtxPopupMgr::registerAction( QAction* act, const int id, const QString& rule, const QtxPopupMgr::RuleType ruleType )
335 {
336   int _id = QtxActionMenuMgr::registerAction( act, id );
337   setRule( act, rule, ruleType );
338   return _id;
339 }
340
341 /*!
342   \brief Unregister action from internal map.
343   \param id action ID
344 */
345 void QtxPopupMgr::unRegisterAction( const int id )
346 {
347   QAction* a = action( id );
348   if ( myRules.contains( a ) )
349   {
350     for ( ExprMap::iterator it = myRules[a].begin(); it != myRules[a].end(); ++it )
351       delete it.value();
352   }
353   myRules.remove( a );
354
355   remove( id );
356
357   QtxActionMenuMgr::unRegisterAction( id );
358 }
359
360 /*!
361   \brief Insert action to the popup menu manager.
362   \param id action ID
363   \param pId parent menu action ID
364   \param rule syntax rule
365   \param ruleType rule type (QtxPopupMgr::RuleType)
366   \return action ID
367 */
368 int QtxPopupMgr::insertAction( const int id, const int pId, const QString& rule, const RuleType ruleType )
369 {
370   int res = QtxActionMenuMgr::insert( id, pId, -1 );
371   setRule( action( id ), rule, ruleType );
372   return res;
373 }
374
375 /*!
376   \brief Insert action to the popup menu manager.
377   \param a action
378   \param pId parent menu action ID
379   \param rule syntax rule
380   \param ruleType rule type (QtxPopupMgr::RuleType)
381   \return action ID
382 */
383 int QtxPopupMgr::insertAction( QAction* a, const int pId, const QString& rule, const RuleType ruleType )
384 {
385   int res = QtxActionMenuMgr::insert( a, pId, -1 );
386   setRule( a, rule, ruleType );
387   return res;
388 }
389
390 /*!
391   \return true if action has rule of given type
392   \param a - action
393   \param t - rule type
394 */
395 bool QtxPopupMgr::hasRule( QAction* a, const RuleType t ) const
396 {
397   return a ? expression( a, t, false )!=0 : false;
398 }
399
400 /*!
401   \return true if action with given id has rule of given type
402   \param id - action id
403   \param t - rule type
404 */
405 bool QtxPopupMgr::hasRule( const int id, const RuleType t ) const
406 {
407   return hasRule( action( id ), t );
408 }
409
410 /*!
411   \brief Get rule of type \a type for the action \a a.
412   \param a action
413   \param ruleType rule type (QtxPopupMgr::RuleType)
414   \return rule of required type
415 */
416 QString QtxPopupMgr::rule( QAction* a, const RuleType ruleType ) const
417 {
418   QString rule;
419   QtxEvalExpr* expr = expression( a, ruleType );
420   if ( expr )
421     rule = expr->expression();
422   return rule;
423 }
424
425 /*!
426   \brief Get rule of type \a type for the action \a id.
427   \param id action ID
428   \param ruleType rule type (QtxPopupMgr::RuleType)
429   \return rule of required type
430 */
431 QString QtxPopupMgr::rule( const int id, const RuleType ruleType ) const
432 {
433   return rule( action( id ), ruleType );
434 }
435
436 /*!
437   \brief Set rule of type \a type for the action \a a.
438   \param a action
439   \param rule rule
440   \param ruleType rule type (QtxPopupMgr::RuleType)
441   \return rule of required type
442 */
443 void QtxPopupMgr::setRule( QAction* a, const QString& rule, const RuleType ruleType )
444 {
445   if ( !a )
446     return;
447
448   QtxEvalExpr* expr = expression( a, ruleType, true );
449
450   expr->setExpression( rule );
451 }
452
453 /*!
454   \brief Set rule of type \a type for the action \a id.
455   \param id action ID
456   \param rule rule
457   \param ruleType rule type (QtxPopupMgr::RuleType)
458   \return rule of required type
459 */
460 void QtxPopupMgr::setRule( const int id, const QString& rule, const RuleType ruleType )
461 {
462   setRule( action( id ), rule, ruleType );
463 }
464
465 /*!
466   \brief Calculate an expression.
467   \param p expression parser
468   \return \c true if parser has finished work without errors
469 */
470 bool QtxPopupMgr::result( QtxEvalParser* p ) const
471 {
472   bool res = false;
473   if ( p )
474   {
475     QVariant vv = p->calculate();
476     res = p->error() == QtxEvalExpr::OK &&
477           ( ( vv.type() == QVariant::Int && vv.toInt() != 0 ) ||
478             ( vv.type() == QVariant::Bool && vv.toBool() ) );
479   }
480   return res;
481 }
482
483 /*!
484   \brief Fill the parser with parameters of the expression.
485
486   The values of the parameters are given from the selection object
487   (QtxPopupSelection).
488   
489   \param p expression parser
490   \param returning list of parameters names which are not retrieved from the selection
491   \sa selection()
492 */
493 void QtxPopupMgr::setParameters( QtxEvalParser* p, QStringList& specific ) const
494 {
495   if ( !p || !mySelection )
496     return;
497
498   QStringList params = p->parameters();
499   for ( QStringList::const_iterator it = params.begin(); it != params.end(); ++it )
500   {
501     QVariant v = parameter( *it );
502     if ( v.isValid() )
503       p->setParameter( *it, v );
504     else
505       specific.append( *it );
506   }
507 }
508
509 /*!
510   \brief Check the rule for the action.
511   \param act action
512   \param ruleType rule type (QtxPopupMgr::RuleType)
513   \return \c true if current selection satisfies the action rule
514 */
515 bool QtxPopupMgr::isSatisfied( QAction* act, const RuleType ruleType ) const
516 {
517   if ( !act )
518     return false;
519
520   QtxEvalExpr* exp = expression( act, ruleType );
521   if ( !exp )
522     return true;
523
524   bool res = false;
525
526   QtxEvalParser* p = exp->parser();
527
528   QStringList specific;
529   p->clearParameters();
530   setParameters( p, specific );
531
532   QMap<QList<QVariant>, int> aCorteges;
533   if ( !specific.isEmpty() )
534   {
535     if ( mySelection )
536     {
537       res = false;
538       for ( int i = 0; i < mySelection->count() && !res; i++ )
539       {
540         QList<QVariant> c;
541         for ( QStringList::const_iterator anIt1 = specific.begin(); anIt1 != specific.end(); ++anIt1 )
542           c.append( parameter( *anIt1, i ) );
543         aCorteges.insert( c, 0 );
544       }
545       for ( QMap<QList<QVariant>, int>::const_iterator anIt = aCorteges.begin(); anIt  != aCorteges.end(); ++anIt )
546       {
547         const QList<QVariant>& aCortege = anIt.key();
548         QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
549         QList<QVariant>::const_iterator anIt2 = aCortege.begin();
550         for ( ; anIt1 != aLast1; anIt1++, anIt2++ )
551           p->setParameter( *anIt1, *anIt2 );
552         res = res || result( p );
553       }
554     }
555     else
556       res = false;
557   }
558   else
559     res = result( p );
560
561   return res;
562 }
563
564 /*!
565   \brief Check if the menu item is visible.
566   \param id action ID
567   \param place some parent action ID
568   \return \c true if the action is visible
569 */
570 bool QtxPopupMgr::isVisible( const int id, const int place ) const
571 {
572   return QtxActionMenuMgr::isVisible( id, place ) && ( !hasRule( id ) || isSatisfied( action( id ) ) );
573 }
574
575 /*!
576   \brief Perform internal update of the popup menu according 
577   to the current selection.
578 */
579 void QtxPopupMgr::internalUpdate()
580 {
581   myCache.clear();
582
583   for ( RuleMap::iterator it = myRules.begin(); it != myRules.end(); ++it )
584   {
585     ExprMap& map = it.value();
586     if ( it.key()->isCheckable() && map.contains( ToggleRule ) &&
587          !map[ToggleRule]->expression().isEmpty() )
588       it.key()->setChecked( isSatisfied( it.key(), ToggleRule ) );
589   }
590
591   QtxActionMenuMgr::internalUpdate();
592
593   myCache.clear();
594 }
595
596 /*!
597   \brief Update popup according to the current selection.
598 */
599 void QtxPopupMgr::updateMenu()
600 {
601   internalUpdate();
602 }
603
604 /*!
605   \brief Get an syntax expression for the action according to the specified rule type.
606   \param a action
607   \param ruleType rule type (QtxPopupMgr::RuleType)
608   \param create if \c true an expression does not exist, create it
609   \return syntax expression
610 */
611 QtxEvalExpr* QtxPopupMgr::expression( QAction* a, const RuleType ruleType, const bool create ) const
612 {
613   QtxEvalExpr* res = 0;
614
615   QtxPopupMgr* that = (QtxPopupMgr*)this;
616   RuleMap& ruleMap = that->myRules;
617   if ( !ruleMap.contains( a ) && create )
618     ruleMap.insert( a, ExprMap() );
619
620   if ( ruleMap.contains( a ) )
621   {
622     ExprMap& exprMap = ruleMap[a];
623     if ( exprMap.contains( ruleType ) )
624       res = exprMap[ruleType];
625     else if ( create )
626       exprMap.insert( ruleType, res = new QtxEvalExpr() );
627   }
628
629   return res;
630 }
631
632 /*!
633   \brief Load actions description from the file.
634   \param fname file name
635   \param r action reader
636   \return \c true on success and \c false on error
637 */
638 bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
639 {
640   PopupCreator cr( &r, this );
641   return r.read( fname, cr );
642 }
643
644 /*
645   \brief Get the specified parameter value.
646   \param name parameter name
647   \param idx additional index used when used parameters with same names 
648   \return parameter value
649   \sa selection()
650 */
651 QVariant QtxPopupMgr::parameter( const QString& name, const int idx ) const
652 {
653   QVariant val;
654   QString cacheName = name + ( idx >= 0 ? QString( "_%1" ).arg( idx ) : QString() );
655   if ( myCache.contains( cacheName ) )
656     val = myCache[cacheName];
657   else
658   {
659     if ( selection() )
660       val = idx < 0 ? selection()->parameter( name ) : 
661                       selection()->parameter( idx, name );
662     if ( val.isValid() )
663     {
664       QtxPopupMgr* that = (QtxPopupMgr*)this;
665       that->myCache.insert( cacheName, val );
666     }
667   }
668   return val;
669 }
670
671 /*!
672   \brief Called when selection is destroyed.
673   
674   Prevents crashes when the selection object is destroyed outside the
675   popup manager.
676
677   \param o selection object being destroyed
678 */
679 void QtxPopupMgr::onSelectionDestroyed( QObject* o )
680 {
681   if ( o == mySelection )
682     mySelection = 0;
683 }
684
685 /*!
686   \class QtxPopupSelection
687   \brief This class is a part of the popup menu management system. 
688
689   The QtxPopupSelection class is used as back-end for getting value
690   of each parameter found in the rule by the expression parser.
691   
692   For example, it can be used for the analyzing of the currently 
693   selected objects and defining the values of the parameters used
694   in the rules syntax expression. Rules, in their turn, define
695   each action state - visibility, enabled and toggled state.
696 */
697
698 /*!
699   \brief Constructor.
700 */
701 QtxPopupSelection::QtxPopupSelection()
702   : QObject( 0 ),
703     myPopupMgr( 0 )
704 {
705 }
706
707 /*!
708   \brief Destructor.
709 */
710 QtxPopupSelection::~QtxPopupSelection()
711 {
712 }
713
714 /*!
715   \brief Get an option value.
716   \param optName option name
717   \return option value or empty string if option is not found
718 */
719 QString QtxPopupSelection::option( const QString& optName ) const
720 {
721   QString opt;
722   if ( myOptions.contains( optName ) )
723     opt = myOptions[optName];
724   return opt;
725 }
726
727 /*!
728   \brief Set an option value.
729   \param optName option name
730   \param opt option value
731 */
732 void QtxPopupSelection::setOption( const QString& optName, const QString& opt )
733 {
734   myOptions.insert( optName, opt );
735 }
736
737 QtxPopupMgr* QtxPopupSelection::popupMgr() const
738 {
739   return myPopupMgr;
740 }
741
742 void QtxPopupSelection::setPopupMgr( QtxPopupMgr* pm )
743 {
744   myPopupMgr = pm;
745 }
746
747 /*!
748   \brief Get the parameter value.
749   \param str parameter name
750   \return parameter value
751 */
752 QVariant QtxPopupSelection::parameter( const QString& str ) const
753 {
754   if ( str == selCountParam() )
755     return count();
756   else if ( str.startsWith( equalityParam() ) )
757   {
758     QtxEvalSetSets::ValueSet set;
759     QString par = str.mid( equalityParam().length() );
760
761     QtxPopupMgr* pMgr = popupMgr();
762     for ( int i = 0; i < (int)count(); i++ )
763     {
764       QVariant v = pMgr ? pMgr->parameter( par, i ) : parameter( i, par );
765       if ( v.isValid() )
766         QtxEvalSetSets::add( set, v );
767       else
768         return QVariant();
769     }
770     return set;
771   }
772   else
773     return QVariant();
774 }
775
776 /*!
777   \brief Get symbol which detects the name of the parameter list.
778   \return equality symbol (by default, "$")
779 */
780 QString QtxPopupSelection::equalityParam() const
781 {
782   QString str = option( "equality" );
783   if ( str.isEmpty() )
784     str = "$";
785   return str;
786 }
787
788 /*!
789   \brief Get name of the parameter, specifing number of selected objects
790   \return parameter name (by default, "selcount")
791 */
792 QString QtxPopupSelection::selCountParam() const
793 {
794   QString str = option( "selcount" );
795   if ( str.isEmpty() )
796     str = "selcount";
797   return str;
798 }
799
800 /*!
801   \fn int QtxPopupSelection::count() const;
802   \brief Get number of the selected objects.
803   \return nb of selected objects
804 */
805
806 /*!
807   \fn QVariant QtxPopupSelection::parameter( const int idx, const QString& name ) const;
808   \brief Get value of the parameter which is of list type
809   \param idx parameter index
810   \param name parameter name
811   \return parameter value
812 */