Back to index

salome-gui  6.5.0
QtxActionMgr.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:      QtxActionMgr.cxx
00024 // Author:    Alexander SOLOVYOV, Sergey TELKOV
00025 //
00026 #include "Qtx.h"
00027 #include "QtxActionMgr.h"
00028 #include "QtxAction.h"
00029 #include <QFile>
00030 #include <QTimer>
00031 #ifndef QT_NO_DOM
00032 #include <QDomDocument>
00033 #include <QDomNode>
00034 #include <QCoreApplication>
00035 #endif
00036 
00037 typedef QList< QPointer<QAction> > qtx_actionlist;
00038 static qtx_actionlist qtx_separator_actions;
00039 
00044 void qtxSeparatorActionCleanup()
00045 {
00046   for ( qtx_actionlist::iterator it = qtx_separator_actions.begin(); it != qtx_separator_actions.end(); ++it )
00047   {
00048     QAction* a = *it;
00049     delete a;
00050   }
00051 }
00052 
00059 class QtxActionMgr::SeparatorAction : public QAction
00060 {
00061 public:
00062   SeparatorAction( QObject* = 0 );
00063   virtual ~SeparatorAction();
00064 };
00065 
00071 QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent )
00072 : QAction( parent )
00073 {
00074   setSeparator( true );
00075 }
00076 
00080 QtxActionMgr::SeparatorAction::~SeparatorAction()
00081 {
00082 }
00083 
00112 QtxActionMgr::QtxActionMgr( QObject* parent )
00113 : QObject( parent ),
00114   myUpdate( true ),
00115   myUpdTimer( 0 )
00116 {
00117 }
00118 
00122 QtxActionMgr::~QtxActionMgr()
00123 {
00124 }
00125 
00138 int QtxActionMgr::registerAction( QAction* a, const int userId )
00139 {
00140   if ( !a )
00141     return -1;
00142 
00143   int theId = userId < 0 ? generateId() : userId;
00144 
00145   if ( contains( theId ) )
00146     unRegisterAction( theId );
00147 
00148   int cur = actionId( a );
00149   if ( cur != -1 )
00150   {
00151     if ( userId == -1 )
00152       return cur;
00153     else
00154       unRegisterAction( cur );
00155   }
00156 
00157   myActions.insert( theId, a );
00158 
00159   return theId;
00160 }
00161 
00167 void QtxActionMgr::unRegisterAction( const int id )
00168 {
00169   if( contains( id ) )
00170     myActions.remove( id );
00171 }
00172 
00179 QAction* QtxActionMgr::action( const int id ) const
00180 {
00181   if ( contains( id ) )
00182     return myActions[ id ];
00183   else
00184     return 0;
00185 }
00186 
00193 int QtxActionMgr::actionId( const QAction* a ) const
00194 {
00195   if ( !a )
00196     return -1;
00197 
00198   int theId = -1;
00199   for ( ActionMap::ConstIterator it = myActions.begin(); it != myActions.end() && theId == -1; ++it )
00200   {
00201     if ( it.value() == a )
00202       theId = it.key();
00203   }
00204 
00205   return theId;
00206 }
00207 
00213 bool QtxActionMgr::contains( const int id ) const
00214 {
00215   return myActions.contains( id );
00216 }
00217 
00223 int QtxActionMgr::count() const
00224 {
00225   return myActions.count();
00226 }
00227 
00233 bool QtxActionMgr::isEmpty() const
00234 {
00235   return myActions.isEmpty();
00236 }
00237 
00242 QIntList QtxActionMgr::idList() const
00243 {
00244   return myActions.keys();
00245 }
00246 
00252 bool QtxActionMgr::isUpdatesEnabled() const
00253 {
00254   return myUpdate;
00255 }
00256 
00262 void QtxActionMgr::setUpdatesEnabled( const bool upd )
00263 {
00264   myUpdate = upd;
00265 }
00266 
00279 bool QtxActionMgr::isVisible( const int /*actId*/, const int /*place*/ ) const
00280 {
00281   return true;
00282 }
00283 
00295 void QtxActionMgr::setVisible( const int /*actId*/, const int /*place*/, const bool /*v*/ )
00296 {
00297 }
00298 
00307 void QtxActionMgr::update()
00308 {
00309   if ( !isUpdatesEnabled() )
00310     return;
00311 
00312   internalUpdate();
00313   if ( myUpdTimer )
00314     myUpdTimer->stop();
00315 }
00316 
00324 void QtxActionMgr::internalUpdate()
00325 {
00326 }
00327 
00332 int QtxActionMgr::generateId() const
00333 {
00334   static int id = -1;
00335   return --id;
00336 }
00337 
00343 bool QtxActionMgr::isEnabled( const int id ) const
00344 {
00345   QAction* a = action( id );
00346   if ( a )
00347     return a->isEnabled();
00348   else
00349     return false;
00350 }
00351 
00357 void QtxActionMgr::setEnabled( const int id, const bool enable )
00358 {
00359   QAction* a = action( id );
00360   if ( a )
00361     a->setEnabled( enable );
00362 }
00363 
00374 QAction* QtxActionMgr::separator( const bool own )
00375 {
00376   if ( own )
00377     return new SeparatorAction();
00378 
00379   if ( qtx_separator_actions.isEmpty() )
00380     qAddPostRoutine( qtxSeparatorActionCleanup );
00381 
00382   SeparatorAction* a = new SeparatorAction();
00383   qtx_separator_actions.append( a );
00384 
00385   return a;
00386 }
00387 
00394 void QtxActionMgr::triggerUpdate()
00395 {
00396   if ( !isUpdatesEnabled() )
00397     return;
00398 
00399   if ( !myUpdTimer )
00400   {
00401     myUpdTimer = new QTimer( this );
00402     myUpdTimer->setSingleShot( true );
00403     connect( myUpdTimer, SIGNAL( timeout() ), this, SLOT( onUpdateContent() ) );
00404   }
00405   myUpdTimer->stop();
00406   // add timer event to event list
00407   myUpdTimer->start( 0 );
00408 }
00409 
00418 void QtxActionMgr::updateContent()
00419 {
00420 }
00421 
00428 void QtxActionMgr::onUpdateContent()
00429 {
00430   updateContent();
00431 }
00432 
00444 QtxActionMgr::Reader::Reader()
00445 {
00446 }
00447 
00451 QtxActionMgr::Reader::~Reader()
00452 {
00453 }
00454 
00459 QStringList QtxActionMgr::Reader::options() const
00460 {
00461   return myOptions.keys();
00462 }
00463 
00473 QString QtxActionMgr::Reader::option( const QString& name, const QString& def ) const
00474 {
00475   if( myOptions.contains( name ) )
00476     return myOptions[ name ];
00477   else
00478     return def;
00479 }
00480 
00486 void QtxActionMgr::Reader::setOption( const QString& name, const QString& value )
00487 {
00488   myOptions[ name ] = value;
00489 }
00490 
00517 QtxActionMgr::XMLReader::XMLReader( const QString& root,
00518                                     const QString& item,
00519                                     const QString& dir )
00520 : Reader()
00521 {
00522   setOption( QString( "root_tag" ),  root );
00523   setOption( QString( "menu_item" ), item );
00524   setOption( QString( "icons_dir" ), dir  );
00525   setOption( QString( "id" ),        QString( "item-id" ) );
00526   setOption( QString( "pos" ),       QString( "pos-id" ) );
00527   setOption( QString( "group" ),     QString( "group-id" ) );
00528   setOption( QString( "label" ),     QString( "label-id" ) );
00529   setOption( QString( "tooltip" ),   QString( "tooltip-id" ) );
00530   setOption( QString( "accel" ),     QString( "accel-id" ) );
00531   setOption( QString( "separator" ), QString( "separator" ) );
00532   setOption( QString( "icon" ),      QString( "icon-id" ) );
00533   setOption( QString( "toggle" ),    QString( "toggle-id" ) );
00534 }
00535 
00539 QtxActionMgr::XMLReader::~XMLReader()
00540 {
00541 }
00542 
00550 bool QtxActionMgr::XMLReader::read( const QString& fname, Creator& cr ) const
00551 {
00552   bool res = false;
00553 
00554 #ifndef QT_NO_DOM
00555 
00556   QFile file( fname );
00557   if ( !file.open( QFile::ReadOnly ) )
00558     return res;
00559 
00560   QDomDocument doc;
00561 
00562   res = doc.setContent( &file );
00563   file.close();
00564 
00565   if ( !res )
00566     return res;
00567 
00568   QString root = option( "root_tag" );
00569   for( QDomNode cur = doc.documentElement(); !cur.isNull(); )
00570   {
00571     if( cur.isElement() && isNodeSimilar( cur, root ) )
00572       read( cur, -1, cr );
00573     else if( cur.hasChildNodes() )
00574     {
00575       cur = cur.firstChild();
00576       continue;
00577     }
00578 
00579     while( !cur.isNull() && cur.nextSibling().isNull() )
00580       cur = cur.parentNode();
00581     if( !cur.isNull() )
00582       cur = cur.nextSibling();
00583   }
00584 
00585 #endif
00586 
00587   return res;
00588 }
00589 
00596 void QtxActionMgr::XMLReader::read( const QDomNode& parent_node,
00597                                     const int parent_id,
00598                                     Creator& cr ) const
00599 {
00600   if( parent_node.isNull() )
00601     return;
00602 
00603   QStringList items = option( "menu_item" ).split( "|", QString::SkipEmptyParts );
00604 
00605   const QDomNodeList& children = parent_node.childNodes();
00606   for( int i=0, n=children.count(); i<n; i++ )
00607   {
00608     QDomNode node = children.item( i );
00609     //QString n = node.nodeName();
00610     if( node.isElement() /*&& node.hasAttributes()*/ &&
00611         ( items.contains( node.nodeName() ) || node.nodeName()==option( "separator" ) ) )
00612     {
00613       QDomNamedNodeMap map = node.attributes();
00614       ItemAttributes attrs;
00615 
00616       for( int i=0, n=map.count(); i<n; i++ )
00617         if( map.item( i ).isAttr() )
00618         {
00619           QDomAttr a = map.item( i ).toAttr();
00620           attrs.insert( a.name(), a.value() );
00621         }
00622 
00623       int newId = cr.append( node.nodeName(), node.hasChildNodes(), attrs, parent_id );
00624       if( node.hasChildNodes() )
00625         read( node, newId, cr );
00626     }
00627   }
00628 }
00629 
00636 bool QtxActionMgr::XMLReader::isNodeSimilar( const QDomNode& node,
00637                                              const QString& pattern ) const
00638 {
00639   if( node.nodeName()==pattern )
00640     return true;
00641 
00642   QDomDocument temp;
00643   QString mes;
00644   temp.setContent( pattern, true, &mes );
00645 
00646   const QDomNamedNodeMap &temp_map = temp.documentElement().attributes(),
00647                          &cur_map = node.attributes();
00648   bool ok = temp_map.count()>0;
00649   for( int i=0, n=temp_map.count(); i<n && ok; i++ )
00650   {
00651     QDomAttr a = temp_map.item( i ).toAttr(),
00652              b = cur_map.namedItem( a.name() ).toAttr();
00653     ok = !b.isNull() && a.name()==b.name() && a.value()==b.value();
00654   }
00655 
00656   return ok;
00657 }
00658 
00677 int QtxActionMgr::Creator::intValue( const ItemAttributes& attrs,
00678                                      const QString& name, int def )
00679 {
00680   if( attrs.contains( name ) )
00681   {
00682     bool ok;
00683     int res = attrs[ name ].toInt( &ok );
00684     if( ok )
00685       return res;
00686   }
00687   return def;
00688 }
00689 
00700 QString QtxActionMgr::Creator::strValue( const ItemAttributes& attrs,
00701                                          const QString& name,
00702                                          const QString& def  )
00703 {
00704   if( attrs.contains( name ) )
00705     return attrs[ name ];
00706   else
00707     return def;
00708 }
00709 
00714 QtxActionMgr::Creator::Creator( QtxActionMgr::Reader* r )
00715 : myReader( r )
00716 {
00717 }
00718 
00722 QtxActionMgr::Creator::~Creator()
00723 {
00724 }
00725 
00730 QtxActionMgr::Reader* QtxActionMgr::Creator::reader() const
00731 {
00732   return myReader;
00733 }
00734 
00743 void QtxActionMgr::Creator::connect( QAction* /*a*/ ) const
00744 {
00745 }
00746 
00753 bool QtxActionMgr::Creator::loadPixmap( const QString& fname, QPixmap& pix ) const
00754 {
00755   if( !reader() )
00756     return false;
00757 
00758   QStringList dirlist = reader()->option( "icons_dir", "." ).split( ";", QString::SkipEmptyParts );
00759   QStringList::const_iterator anIt = dirlist.begin(),
00760                               aLast = dirlist.end();
00761   bool res = false;
00762   for( ; anIt!=aLast && !res; anIt++ )
00763     res = pix.load( Qtx::addSlash( *anIt ) + fname );
00764 
00765   return res;
00766 }
00767