1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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.
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.
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
17 // See http://www.salome-platform.org/
20 #include "QtxPopupMgr.h"
21 #include "QtxListOfOperations.h"
22 #include "QtxStdOperations.h"
23 #include "QtxAction.h"
25 #include <qpopupmenu.h>
26 #include <qdatetime.h>
28 //================================================================
31 //================================================================
32 QtxValue QtxPopupMgr::Selection::globalParam( const QString& str ) const
34 if( str==selCountParam() )
37 else if( str[0]==equality() )
39 QtxSets::ValueSet set;
40 QString par = str.mid( 1 );
42 for( int i=0, n=count(); i<n; i++ )
44 QtxValue v = param( i, par );
46 QtxSets::add( set, v );
57 //================================================================
60 //================================================================
61 QChar QtxPopupMgr::Selection::equality() const
66 //================================================================
69 //================================================================
70 QString QtxPopupMgr::Selection::selCountParam() const
72 return defSelCountParam();
75 //================================================================
78 //================================================================
79 QChar QtxPopupMgr::Selection::defEquality()
84 //================================================================
87 //================================================================
88 QString QtxPopupMgr::Selection::defSelCountParam()
97 //================================================================
100 //================================================================
101 class QtxCacheSelection : public QtxPopupMgr::Selection
104 QtxCacheSelection( QtxPopupMgr::Selection* );
105 virtual ~QtxCacheSelection();
107 virtual int count() const;
108 virtual QtxValue param( const int, const QString& ) const;
109 virtual QtxValue globalParam( const QString& ) const;
112 typedef QMap< QString, QtxValue > CacheMap;
114 QtxPopupMgr::Selection* mySel;
115 CacheMap myParamCache;
118 //================================================================
121 //================================================================
122 QtxCacheSelection::QtxCacheSelection( QtxPopupMgr::Selection* sel )
127 //================================================================
130 //================================================================
131 QtxCacheSelection::~QtxCacheSelection()
135 //================================================================
138 //================================================================
139 int QtxCacheSelection::count() const
141 return mySel ? mySel->count() : 0;
144 //================================================================
147 //================================================================
148 QtxValue QtxCacheSelection::param( const int i, const QString& name ) const
150 QString param_name = name + "#####" + QString::number( i );
151 if( myParamCache.contains( param_name ) )
152 return myParamCache[ param_name ];
157 v = mySel->param( i, name );
159 ( ( CacheMap& )myParamCache ).insert( param_name, v );
164 //================================================================
167 //================================================================
168 QtxValue QtxCacheSelection::globalParam( const QString& name ) const
170 if( myParamCache.contains( name ) )
171 return myParamCache[ name ];
176 v = mySel->globalParam( name );
178 ( ( CacheMap& )myParamCache ).insert( name, v );
187 //================================================================
190 //================================================================
191 QtxPopupMgr::Operations::Operations( QtxPopupMgr* mgr )
196 aList.append( "every" );
197 aList.append( "any" );
198 aList.append( "onlyone" );
199 addOperations( aList );
201 myParser = new QtxParser( mgr->myOperations );
204 //================================================================
207 //================================================================
208 QtxPopupMgr::Operations::~Operations()
213 //================================================================
216 //================================================================
217 int QtxPopupMgr::Operations::prior( const QString& op, bool isBin ) const
219 if( !isBin && ( op=="every" || op=="any" || op=="onlyone" ) )
222 return QtxStrings::prior( op, isBin );
226 //================================================================
229 //================================================================
230 QtxParser::Error QtxPopupMgr::Operations::calculate
231 ( const QString& op, QtxValue& v1, QtxValue& v2 ) const
238 else if( op=="onlyone" )
241 if( ind>=0 && ind<=2 )
243 QString val_name = op + "(" + v2.toString() + ")";
244 QtxParser::Error err = QtxParser::OK;
246 if( !myValues.contains( val_name ) )
248 myParser->setExpr( v2.toString() );
249 QStringList params, specific;
250 myParser->paramsList( params );
253 myPopupMgr->setParams( myParser, specific );
255 QtxPopupMgr::Selection* sel = myPopupMgr->myCurrentSelection;
257 int global_result = 0;
259 for( int i=0, n=sel->count(); i<n; i++ )
261 QStringList::const_iterator anIt = specific.begin(),
262 aLast = specific.end();
263 for( ; anIt!=aLast; anIt++ )
265 QtxValue v = sel->param( i, *anIt );
267 myParser->set( *anIt, v );
269 return QtxParser::InvalidToken;
272 QtxValue res = myParser->calculate();
273 err = myParser->lastError();
274 if( err==QtxParser::OK )
275 if( res.type()==QVariant::Bool )
279 if( ind==2 && global_result>1 )
283 return QtxParser::InvalidResult;
288 QtxValue& vv = ( QtxValue& )myValues[ val_name ];
289 vv = ( ind==0 && global_result==sel->count() ) ||
291 ( ind==2 && global_result==1 );
294 v2 = myValues[ val_name ];
299 return QtxStrings::calculate( op, v1, v2 );
302 //================================================================
305 //================================================================
306 void QtxPopupMgr::Operations::clear()
319 //================================================================
322 //================================================================
323 QtxPopupMgr::QtxPopupMgr( QPopupMenu* popup, QObject* parent )
324 : QtxActionMenuMgr( popup, parent ),
325 myCurrentSelection( 0 )
330 //================================================================
333 //================================================================
334 QtxPopupMgr::~QtxPopupMgr()
338 //================================================================
341 //================================================================
342 void QtxPopupMgr::createOperations()
344 myOperations = new QtxListOfOperations;
345 myOperations->prepend( "logic", new QtxLogic(), 0 );
346 myOperations->prepend( "arithm", new QtxArithmetics(), 50 );
347 myOperations->append( "strings", new QtxStrings(), 100 );
348 myOperations->append( "sets", new QtxSets(), 150 );
349 myOperations->append( "custom", new Operations( this ), 200 );
352 //================================================================
355 //================================================================
356 int QtxPopupMgr::registerAction( QAction* act,
357 const QString& visible,
358 const QString& toggle,
361 int _id = QtxActionMenuMgr::registerAction( act, id );
362 setRule( _id, visible, true );
363 setRule( _id, toggle, false );
367 //================================================================
370 //================================================================
371 void QtxPopupMgr::unRegisterAction( const int id )
373 QAction* act = action( id );
375 myVisibility.remove( act );
376 myToggle.remove( act );
379 //QtxActionMenuMgr::unRegisterAction( id );
382 //================================================================
385 //================================================================
386 bool QtxPopupMgr::hasRule( QAction* act, bool visibility ) const
388 return map( visibility ).contains( act );
391 //================================================================
394 //================================================================
395 bool QtxPopupMgr::hasRule( const int id, bool visibility ) const
397 return hasRule( action( id ), visibility );
400 //================================================================
403 //================================================================
404 void QtxPopupMgr::setRule( QAction* act, const QString& rule, bool visibility )
406 if( !act || rule.isEmpty() )
409 if( !hasRule( act, visibility ) )
411 QtxParser* p = new QtxParser( myOperations, rule );
412 if( p->lastError()==QtxParser::OK )
413 map( visibility ).insert( act, p );
419 QtxParser* p = map( visibility )[ act ];
421 if( p->lastError()!=QtxParser::OK )
422 p->setExpr( QString() );
426 //================================================================
429 //================================================================
430 void QtxPopupMgr::setRule( const int id, const QString& rule, bool visibility )
432 setRule( action( id ), rule, visibility );
435 //================================================================
438 //================================================================
439 bool result( QtxParser* p )
444 QtxValue vv = p->calculate();
445 res = p->lastError()==QtxParser::OK &&
446 ( ( vv.type()==QVariant::Int && vv.toInt()!=0 ) ||
447 ( vv.type()==QVariant::Bool && vv.toBool() ) );
452 //================================================================
455 //================================================================
456 void QtxPopupMgr::setParams( QtxParser* p, QStringList& specific ) const
458 if( !p || !myCurrentSelection )
463 p->paramsList( params );
464 QStringList::const_iterator anIt = params.begin(),
465 aLast = params.end();
466 for( ; anIt!=aLast; anIt++ )
468 QtxValue v = myCurrentSelection->globalParam( *anIt );
472 specific.append( *anIt );
476 bool operator<( const QtxValue& v1, const QtxValue& v2 )
478 QVariant::Type t1 = v1.type(), t2 = v2.type();
484 return v1.toInt() < v2.toInt();
486 case QVariant::Double:
487 return v1.toDouble() < v2.toDouble();
489 case QVariant::CString:
490 case QVariant::String:
491 return v1.toString() < v2.toString();
493 case QVariant::StringList:
496 const QValueList<QtxValue>& aList1 = v1.toList(), aList2 = v2.toList();
497 QValueList<QtxValue>::const_iterator
498 anIt1 = aList1.begin(), aLast1 = aList1.end(),
499 anIt2 = aList2.begin(), aLast2 = aList2.end();
500 for( ; anIt1!=aLast1 && anIt2!=aLast2; anIt1++, anIt2++ )
501 if( (*anIt1)!=(*anIt2) )
502 return (*anIt1)<(*anIt2);
504 return anIt1==aLast1 && anIt2!=aLast2;
508 return v1.toString()<v2.toString();
515 //================================================================
518 //================================================================
519 bool QtxPopupMgr::isSatisfied( QAction* act, bool visibility ) const
521 QString menu = act->menuText();
527 if( hasRule( act, visibility ) )
529 QtxParser* p = map( visibility )[ act ];
530 QStringList specific;
532 ( ( Operations* )myOperations->operations( "custom" ) )->clear();
534 setParams( p, specific );
536 QMap<QValueList<QtxValue>,int> aCorteges;
537 QValueList<QtxValue> c;
539 if( specific.count()>0 )
540 if( myCurrentSelection )
544 for( int i=0, n=myCurrentSelection->count(); i<n && !res; i++ )
546 QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
548 for( ; anIt1!=aLast1; anIt1++ )
549 c.append( myCurrentSelection->param( i, *anIt1 ) );
550 aCorteges.insert( c, 0 );
553 //qDebug( QString( "%1 corteges" ).arg( aCorteges.count() ) );
554 QMap<QValueList<QtxValue>,int>::const_iterator anIt = aCorteges.begin(), aLast = aCorteges.end();
555 for( ; anIt!=aLast; anIt++ )
557 QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
558 const QValueList<QtxValue>& aCortege = anIt.key();
559 QValueList<QtxValue>::const_iterator anIt2 = aCortege.begin();
560 for( ; anIt1!=aLast1; anIt1++, anIt2++ )
561 p->set( *anIt1, *anIt2 );
562 res = res || result( p );
566 for( int i=0, n=myCurrentSelection->count(); i<n && !res; i++ )
568 QStringList::const_iterator anIt1 = specific.begin(), aLast1 = specific.end();
569 for( ; anIt1!=aLast1; anIt1++ )
570 p->set( *anIt1, myCurrentSelection->param( i, *anIt1 ) );
571 res = res || result( p );
583 //================================================================
586 //================================================================
587 bool QtxPopupMgr::isVisible( const int actId, const int place ) const
589 bool res = QtxActionMenuMgr::isVisible( actId, place );
590 QAction* act = action( actId );
591 if( hasRule( act, true ) )
592 res = res && isSatisfied( act, true );
596 //================================================================
599 //================================================================
600 void QtxPopupMgr::updatePopup( QPopupMenu* p, Selection* sel )
602 QTime t1 = QTime::currentTime();
607 myCurrentSelection = new QtxCacheSelection( sel );
608 RulesMap::iterator anIt = myToggle.begin(),
609 aLast = myToggle.end();
610 for( ; anIt!=aLast; anIt++ )
611 if( anIt.key()->isToggleAction() && hasRule( anIt.key(), false ) )
612 anIt.key()->setOn( isSatisfied( anIt.key(), false ) );
614 setWidget( ( QWidget* )p );
616 QTime t2 = QTime::currentTime();
617 qDebug( QString( "update popup time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
618 qDebug( QString( "number of objects = %1" ).arg( myCurrentSelection->count() ) );
620 delete myCurrentSelection;
623 //================================================================
626 //================================================================
627 QtxPopupMgr::RulesMap& QtxPopupMgr::map( bool visibility ) const
629 return ( RulesMap& )( visibility ? myVisibility : myToggle );
632 //================================================================
635 //================================================================
636 bool QtxPopupMgr::load( const QString& fname, QtxActionMgr::Reader& r )
638 PopupCreator cr( &r, this );
639 return r.read( fname, cr );
645 //================================================================
648 //================================================================
649 QtxPopupMgr::PopupCreator::PopupCreator( QtxActionMgr::Reader* r,
651 : QtxActionMgr::Creator( r ),
656 //================================================================
659 //================================================================
660 QtxPopupMgr::PopupCreator::~PopupCreator()
664 //================================================================
667 //================================================================
668 int QtxPopupMgr::PopupCreator::append( const QString& tag, const bool subMenu,
669 const ItemAttributes& attr, const int pId )
671 if( !myMgr || !reader() )
674 QString label = reader()->option( "label", "label" ),
675 id = reader()->option( "id", "id" ),
676 pos = reader()->option( "pos", "pos" ),
677 group = reader()->option( "group", "group" ),
678 tooltip = reader()->option( "tooltip", "tooltip" ),
679 sep = reader()->option( "separator", "separator" ),
680 accel = reader()->option( "accel", "accel" ),
681 icon = reader()->option( "icon", "icon" ),
682 toggle = reader()->option( "toggle", "toggle" );
684 int res = -1, actId = intValue( attr, id, -1 );;
686 res = myMgr->insert( strValue( attr, label ), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
688 res = myMgr->insert( separator(), pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
689 else //if( !myMgr->contains( actId ) )
691 QPixmap pix; QIconSet set;
692 QString name = strValue( attr, icon );
693 if( !name.isEmpty() )
695 if( loadPixmap( name, pix ) )
696 set = QIconSet( pix );
699 QString actLabel = strValue( attr, label );
700 QtxAction* newAct = new QtxAction( strValue( attr, tooltip ), set, actLabel,
701 QKeySequence( strValue( attr, accel ) ),
703 newAct->setToolTip( strValue( attr, tooltip ) );
704 QString toggleact = strValue( attr, toggle );
705 bool isToggle = !toggleact.isEmpty();
706 newAct->setToggleAction( isToggle );
707 newAct->setOn( toggleact.lower()=="true" );
710 int aid = myMgr->registerAction( newAct, visibleRule( attr ),
711 isToggle ? toggleRule( attr ) : QString::null,
713 res = myMgr->insert( aid, pId, intValue( attr, group, 0 ), intValue( attr, pos, -1 ) );
719 //================================================================
722 //================================================================
723 QString QtxPopupMgr::PopupCreator::visibleRule( const ItemAttributes& ) const
725 return QString::null;
728 //================================================================
731 //================================================================
732 QString QtxPopupMgr::PopupCreator::toggleRule( const ItemAttributes& ) const
734 return QString::null;