Salome HOME
PAL10212
[modules/gui.git] / src / Qtx / QtxPopupMgr.cxx
1
2 #include "QtxPopupMgr.h"
3 #include "QtxListOfOperations.h"
4 #include "QtxStdOperations.h"
5 #include "QtxAction.h"
6
7 #include <qpopupmenu.h>
8
9 //================================================================
10 // Function : 
11 // Purpose  : 
12 //================================================================
13 QtxValue QtxPopupMgr::Selection::globalParam( const QString& str ) const
14 {
15   if( str==selCountParam() )
16     return count();
17
18   else if( str[0]==equality() )
19   {
20     QtxSets::ValueSet set;
21     QString par = str.mid( 1 );
22
23     for( int i=0, n=count(); i<n; i++ )
24     {
25       QtxValue v = param( i, par );
26       if( v.isValid() )
27         QtxSets::add( set, v );
28       else
29         return QtxValue();      
30     }
31     return set;
32   }
33
34   else
35     return QtxValue();
36 }
37
38 //================================================================
39 // Function : 
40 // Purpose  : 
41 //================================================================
42 QChar QtxPopupMgr::Selection::equality() const
43 {
44   return defEquality();
45 }
46
47 //================================================================
48 // Function : 
49 // Purpose  : 
50 //================================================================
51 QString QtxPopupMgr::Selection::selCountParam() const
52 {
53   return defSelCountParam();
54 }
55
56 //================================================================
57 // Function : 
58 // Purpose  : 
59 //================================================================
60 QChar QtxPopupMgr::Selection::defEquality()
61 {
62     return '$';
63 }
64
65 //================================================================
66 // Function : 
67 // Purpose  : 
68 //================================================================
69 QString QtxPopupMgr::Selection::defSelCountParam()
70 {
71     return "selcount";
72 }
73
74
75
76
77 //================================================================
78 // Function : 
79 // Purpose  : 
80 //================================================================
81 QtxPopupMgr::Operations::Operations( QtxPopupMgr* mgr )
82 : QtxStrings(),
83   myPopupMgr( mgr )
84 {
85     QStringList aList;
86     aList.append( "every" );
87     aList.append( "any" );
88     aList.append( "onlyone" );
89     addOperations( aList );
90
91     myParser = new QtxParser( mgr->myOperations );
92 }
93
94 //================================================================
95 // Function : 
96 // Purpose  : 
97 //================================================================
98 QtxPopupMgr::Operations::~Operations()
99 {
100     delete myParser;
101 }
102
103 //================================================================
104 // Function : 
105 // Purpose  : 
106 //================================================================
107 int QtxPopupMgr::Operations::prior( const QString& op, bool isBin ) const
108 {
109     if( !isBin && ( op=="every" || op=="any" || op=="onlyone" ) )
110         return 1;
111     else
112         return QtxStrings::prior( op, isBin );
113
114 }
115
116 //================================================================
117 // Function : 
118 // Purpose  : 
119 //================================================================
120 QtxParser::Error QtxPopupMgr::Operations::calculate
121     ( const QString& op, QtxValue& v1, QtxValue& v2 ) const
122 {
123     int ind = -1;
124     if( op=="every" )
125         ind = 0;
126     else if( op=="any" )
127         ind = 1;
128     else if( op=="onlyone" )
129         ind = 2;
130
131     if( ind>=0 && ind<=2 )
132     {
133         QString val_name = op + "(" + v2.toString() + ")";
134         QtxParser::Error err = QtxParser::OK;
135
136         if( !myValues.contains( val_name ) )
137         {
138             myParser->setExpr( v2.toString() );
139             QStringList params, specific;
140             myParser->paramsList( params );
141
142             myParser->clear();
143             myPopupMgr->setParams( myParser, specific );
144
145             QtxPopupMgr::Selection* sel = myPopupMgr->myCurrentSelection;
146
147             int global_result = 0;
148             if( sel )
149                 for( int i=0, n=sel->count(); i<n; i++ )
150                 {
151                     QStringList::const_iterator anIt = specific.begin(),
152                                                 aLast = specific.end();
153                     for( ; anIt!=aLast; anIt++ )
154                     {
155                         QtxValue v = sel->param( i, *anIt );
156                         if( v.isValid() )
157                             myParser->set( *anIt, v );
158                         else
159                             return QtxParser::InvalidToken;
160                     }
161
162                     QtxValue res = myParser->calculate();
163                     err = myParser->lastError();
164                     if( err==QtxParser::OK )
165                         if( res.type()==QVariant::Bool )
166                         {
167                             if( res.toBool() )
168                                 global_result++;
169                             if( ind==2 && global_result>1 )
170                                 break;
171                         }
172                         else
173                             return QtxParser::InvalidResult;
174                     else
175                         return err;
176                 }
177
178             QtxValue& vv = ( QtxValue&  )myValues[ val_name ];
179             vv = ( ind==0 && global_result==sel->count() ) ||
180                  ( ind==1 ) ||
181                  ( ind==2 && global_result==1 );
182         }
183
184         v2 = myValues[ val_name ];
185
186         return err;
187     }
188     else
189         return QtxStrings::calculate( op, v1, v2 );
190 }
191
192 //================================================================
193 // Function : 
194 // Purpose  : 
195 //================================================================
196 void QtxPopupMgr::Operations::clear()
197 {
198     myValues.clear();
199 }
200
201
202
203
204
205
206
207
208
209 //================================================================
210 // Function : 
211 // Purpose  : 
212 //================================================================
213 QtxPopupMgr::QtxPopupMgr( QPopupMenu* popup, QObject* parent )
214 : QtxActionMenuMgr( popup, parent ),
215   myCurrentSelection( 0 )
216 {
217     createOperations();
218 }
219
220 //================================================================
221 // Function : 
222 // Purpose  : 
223 //================================================================
224 QtxPopupMgr::~QtxPopupMgr()
225 {
226 }
227
228 //================================================================
229 // Function : 
230 // Purpose  : 
231 //================================================================
232 void QtxPopupMgr::createOperations()
233 {
234     myOperations = new QtxListOfOperations;
235     myOperations->prepend( "logic",   new QtxLogic(),           0 );
236     myOperations->prepend( "arithm",  new QtxArithmetics(),    50 );
237     myOperations->prepend( "strings", new QtxStrings(),       100 );
238     myOperations->prepend( "sets",    new QtxSets(),          150 );
239     myOperations->prepend( "custom",  new Operations( this ), 200 );
240 }
241
242 //================================================================
243 // Function : 
244 // Purpose  : 
245 //================================================================
246 int QtxPopupMgr::registerAction( QAction* act,
247                                  const QString& visible,
248                                  const QString& toggle,
249                                  const int id )
250 {
251     int _id = QtxActionMenuMgr::registerAction( act, id );
252     setRule( _id, visible, true );
253     setRule( _id, toggle, false );
254     return _id;
255 }
256
257 //================================================================
258 // Function : 
259 // Purpose  : 
260 //================================================================
261 void QtxPopupMgr::unRegisterAction( const int id )
262 {
263     QAction* act = action( id );
264
265     myVisibility.remove( act );
266     myToggle.remove( act );
267
268     remove( id );
269     //QtxActionMenuMgr::unRegisterAction( id );
270 }
271
272 //================================================================
273 // Function : 
274 // Purpose  : 
275 //================================================================
276 bool QtxPopupMgr::hasRule( QAction* act, bool visibility ) const
277 {
278     return map( visibility ).contains( act );
279 }
280
281 //================================================================
282 // Function : 
283 // Purpose  : 
284 //================================================================
285 bool QtxPopupMgr::hasRule( const int id, bool visibility ) const
286 {
287     return hasRule( action( id ), visibility );
288 }
289
290 //================================================================
291 // Function : 
292 // Purpose  : 
293 //================================================================
294 void QtxPopupMgr::setRule( QAction* act, const QString& rule, bool visibility )
295 {
296     if( !act || rule.isEmpty() )
297         return;
298
299     if( !hasRule( act, visibility ) )
300     {
301         QtxParser* p = new QtxParser( myOperations, rule );
302         if( p->lastError()==QtxParser::OK )
303             map( visibility ).insert( act, p );
304         else
305             delete p;
306     }
307     else
308     {
309         QtxParser* p = map( visibility )[ act ];
310         p->setExpr( rule );
311         if( p->lastError()!=QtxParser::OK )
312             p->setExpr( QString() );
313     }
314 }
315
316 //================================================================
317 // Function : 
318 // Purpose  : 
319 //================================================================
320 void QtxPopupMgr::setRule( const int id, const QString& rule, bool visibility )
321 {
322     setRule( action( id ), rule, visibility );
323 }
324
325 //================================================================
326 // Function : 
327 // Purpose  : 
328 //================================================================
329 bool result( QtxParser* p )
330 {
331     bool res = false;
332     if( p )
333     {
334         QtxValue vv = p->calculate();
335         res = p->lastError()==QtxParser::OK &&
336             ( ( vv.type()==QVariant::Int && vv.toInt()!=0 ) ||
337               ( vv.type()==QVariant::Bool && vv.toBool() ) );
338     }
339     return res;
340 }
341
342 //================================================================
343 // Function : 
344 // Purpose  : 
345 //================================================================
346 void QtxPopupMgr::setParams( QtxParser* p, QStringList& specific ) const
347 {
348     if( !p || !myCurrentSelection )
349         return;
350
351     QStringList params;
352
353     p->paramsList( params );
354     QStringList::const_iterator anIt = params.begin(),
355                                 aLast = params.end();
356     for( ; anIt!=aLast; anIt++ )
357     {
358       QtxValue v = myCurrentSelection->globalParam( *anIt );
359       if( v.isValid() )
360         p->set( *anIt, v );
361       else
362         specific.append( *anIt );
363     }
364 }
365
366 //================================================================
367 // Function : 
368 // Purpose  : 
369 //================================================================
370 bool QtxPopupMgr::isSatisfied( QAction* act, bool visibility ) const
371 {
372     QString menu = act->menuText();
373     //const char* mmm = menu.latin1();
374
375     bool res = false;
376     if( !act )
377         return res;
378
379     if( hasRule( act, visibility ) )
380     {
381         QtxParser* p = map( visibility )[ act ];
382         //QString pdump = p->dump();
383             //const char* pdd = pdump.latin1();
384
385
386         QStringList specific;
387         p->clear();
388         ( ( Operations* )myOperations->operations( "custom" ) )->clear();
389
390         setParams( p, specific );
391
392         if( specific.count()>0 )
393             if( myCurrentSelection )
394                 for( int i=0, n=myCurrentSelection->count(); i<n; i++ )
395                 {
396                     QStringList::const_iterator anIt1 = specific.begin(),
397                                                 aLast1 = specific.end();
398                     for( ; anIt1!=aLast1; anIt1++ )
399                         p->set( *anIt1, myCurrentSelection->param( i, *anIt1 ) );
400
401                     res = res || result( p );
402                 }
403             else
404                 res = false;
405         else
406             res = result( p );
407     }
408
409     return res;
410 }
411
412 //================================================================
413 // Function : 
414 // Purpose  : 
415 //================================================================
416 bool QtxPopupMgr::isVisible( const int actId, const int place ) const
417 {
418     bool res = QtxActionMenuMgr::isVisible( actId, place );
419     QAction* act = action( actId );
420     if( hasRule( act, true ) )
421         res = res && isSatisfied( act, true );
422     return res;
423 }
424
425 //================================================================
426 // Function : 
427 // Purpose  : 
428 //================================================================
429 void QtxPopupMgr::updatePopup( QPopupMenu* p, Selection* sel )
430 {
431     if( !p || !sel )
432         return;
433
434     myCurrentSelection = sel;
435
436     RulesMap::iterator anIt = myToggle.begin(),
437                        aLast = myToggle.end();
438     for( ; anIt!=aLast; anIt++ )
439         if( anIt.key()->isToggleAction() && hasRule( anIt.key(), false ) )
440             anIt.key()->setOn( isSatisfied( anIt.key(), false ) );
441
442     setWidget( ( QWidget* )p );
443     updateMenu();
444 }
445
446 //================================================================
447 // Function : 
448 // Purpose  : 
449 //================================================================
450 QtxPopupMgr::RulesMap& QtxPopupMgr::map( bool visibility ) const
451 {
452     return ( RulesMap& )( visibility ? myVisibility : myToggle );
453 }
454
455 //================================================================
456 // Function : 
457 // Purpose  : 
458 //================================================================
459 bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
460 {
461   PopupCreator cr( &r, this );
462   return r.read( fname, cr );
463 }
464
465
466
467
468 //================================================================
469 // Function : 
470 // Purpose  : 
471 //================================================================
472 QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
473                                          QtxPopupMgr* mgr )
474 : QtxActionMgr::Creator( r ),
475   myMgr( mgr )
476 {
477 }
478
479 //================================================================
480 // Function : 
481 // Purpose  : 
482 //================================================================
483 QtxPopupMgr::PopupCreator::~PopupCreator()
484 {
485 }
486
487 //================================================================
488 // Function : 
489 // Purpose  : 
490 //================================================================
491 int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
492                                        const ItemAttributes& attr, const int pId )
493 {
494   if( !myMgr || !reader() )
495     return -1;
496
497   QString label   = reader()->option( "label",     "label"     ),
498           id      = reader()->option( "id",        "id"        ),
499           pos     = reader()->option( "pos",       "pos"       ),
500           group   = reader()->option( "group",     "group"     ),
501           tooltip = reader()->option( "tooltip",   "tooltip"   ),
502           sep     = reader()->option( "separator", "separator" ),
503           accel   = reader()->option( "accel",     "accel"     ),
504           icon    = reader()->option( "icon",      "icon"      ),
505           toggle  = reader()->option( "toggle",    "toggle"    );
506
507   int res = -1, actId = intValue( attr, id, -1 );;
508   if( subMenu )
509     res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
510   else if( tag==sep )
511     res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
512   else //if( !myMgr->contains( actId ) )
513   {
514     QPixmap pix; QIconSet set;
515     QString name = strValue( attr, icon );
516     if( !name.isEmpty() )
517     {
518       if( loadPixmap( name, pix ) )
519         set = QIconSet( pix );
520     }
521
522     QString actLabel = strValue( attr, label );
523     QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
524                                        QKeySequence( strValue( attr, accel ) ),
525                                        myMgr );
526     newAct->setToolTip( strValue( attr, tooltip ) );
527     QString toggleact = strValue( attr, toggle );
528     bool isToggle = !toggleact.isEmpty();
529     newAct->setToggleAction( isToggle );
530     newAct->setOn( toggleact.lower()=="true" );
531         
532     connect( newAct );
533     int aid = myMgr->registerAction( newAct, visibleRule( attr ), 
534                                      isToggle ? toggleRule( attr ) : QString::null,
535                                      actId );
536     res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
537   }
538
539   return res;
540 }
541
542 //================================================================
543 // Function : 
544 // Purpose  : 
545 //================================================================
546 QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const
547 {
548   return QString::null;
549 }
550
551 //================================================================
552 // Function : 
553 // Purpose  : 
554 //================================================================
555 QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const
556 {
557   return QString::null;
558 }