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