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