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