]> SALOME platform Git repositories - modules/gui.git/blob - src/Qtx/QtxActionMgr.cxx
Salome HOME
16ec7b5b1916cb71863ab55c566e8f6d38bcd35c
[modules/gui.git] / src / Qtx / QtxActionMgr.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 // File:      QtxActionMgr.cxx
20 // Author:    Alexander SOLOVYEV, Sergey TELKOV
21
22 #include "Qtx.h"
23 #include "QtxActionMgr.h"
24 #include "QtxAction.h"
25
26 #include <qwidget.h>
27 #include <qtoolbar.h>
28 #include <qpopupmenu.h>
29 #include <qwidgetlist.h>
30 #include <qobjectlist.h>
31 #include <qfile.h>
32 #include <qdom.h>
33
34 static QAction* qtx_separator_action = 0;
35
36 void qtxSeparatorActionCleanup()
37 {
38   delete qtx_separator_action;
39   qtx_separator_action = 0;
40 }
41
42 /*!
43         Class: QtxActionMenuMgr::SeparatorAction
44         Level: Internal
45 */
46
47 class QtxActionMgr::SeparatorAction : public QtxAction
48 {
49 public:
50   SeparatorAction( QObject* = 0 );
51   virtual ~SeparatorAction();
52
53   virtual bool addTo( QWidget* );
54   virtual bool removeFrom( QWidget* );
55
56 private:
57   QMap<QPopupMenu*, QIntList>  myMenus;
58   QMap<QToolBar*, QWidgetList> myTools;
59 };
60
61 QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent )
62 : QtxAction( parent )
63 {
64 }
65
66 QtxActionMgr::SeparatorAction::~SeparatorAction()
67 {
68 }
69
70 bool QtxActionMgr::SeparatorAction::addTo( QWidget* wid )
71 {
72   if ( !wid )
73     return false;
74
75   bool res = true;
76   if ( wid->inherits( "QPopupMenu" ) )
77   {
78     QPopupMenu* popup = (QPopupMenu*)wid;
79     myMenus[popup].append( popup->insertSeparator() );
80   }
81   else if ( wid->inherits( "QToolBar" ) )
82   {
83     QToolBar* tb = (QToolBar*)wid;
84     tb->addSeparator();
85     myTools[tb].append( (QWidget*)tb->children()->getLast() );
86   }
87   else
88     res = false;
89
90   return res;
91 }
92
93 bool QtxActionMgr::SeparatorAction::removeFrom( QWidget* wid )
94 {
95   if ( !wid )
96     return false;
97
98   bool res = true;
99   if ( wid->inherits( "QPopupMenu" ) )
100   {
101     QPopupMenu* popup = (QPopupMenu*)wid;
102     if ( myMenus.contains( popup ) )
103     {
104       const QIntList& list = myMenus[popup];
105       for ( QIntList::const_iterator it = list.begin(); it != list.end(); ++it )
106         popup->removeItem( *it );
107
108       myMenus.remove( popup );
109     }
110   }
111   else if ( wid->inherits( "QToolBar" ) )
112   {
113     QToolBar* tb = (QToolBar*)wid;
114     if ( myTools.contains( tb ) )
115     {
116       QMap<QObject*, int> childMap;
117       if ( tb->children() )
118       {
119         for ( QObjectListIt it( *tb->children() ); it.current(); ++it )
120           childMap.insert( it.current(), 0 );
121       }
122       const QWidgetList& list = myTools[tb];
123       for ( QWidgetListIt it( list ); it.current(); ++it )
124       {
125         if ( childMap.contains( it.current() ) )
126         delete it.current();
127       }
128
129       myTools.remove( tb );
130     }
131   }
132   else
133     res = false;
134
135   return res;
136 }
137
138 /*!
139         Class: QtxActionMgr
140         Level: Public
141 */
142
143 QtxActionMgr::QtxActionMgr( QObject* parent )
144 : QObject( parent ),
145 myUpdate( true )
146 {
147 }
148
149 QtxActionMgr::~QtxActionMgr()
150 {
151 }
152
153 int QtxActionMgr::registerAction( QAction* a, const int userId )
154 {
155   if ( !a )
156     return -1;
157
158   int theId = userId < 0 ? generateId() : userId;
159
160   if ( contains( theId ) )
161     unRegisterAction( theId );
162
163   int cur = actionId( a );
164   if ( cur != -1 )
165   {
166     if ( userId == -1 )
167       return cur;
168     else
169       unRegisterAction( cur );
170   }
171
172   myActions.insert( theId, a );
173
174   return theId;
175 }
176
177 void QtxActionMgr::unRegisterAction( const int id )
178 {
179   if( contains( id ) )
180     myActions.remove( id );
181 }
182
183 QAction* QtxActionMgr::action( const int id ) const
184 {
185   if ( contains( id ) )
186     return myActions[ id ];
187   else
188     return 0;
189 }
190
191 int QtxActionMgr::actionId( const QAction* a ) const
192 {
193   if ( !a )
194     return -1;
195
196   int theId = -1;
197   for ( ActionMap::ConstIterator it = myActions.begin(); it != myActions.end() && theId == -1; ++it )
198   {
199     if ( it.data() == a )
200       theId = it.key();
201   }
202
203   return theId;
204 }
205
206 bool QtxActionMgr::contains( const int id ) const
207 {
208   return myActions.contains( id );
209 }
210
211 int QtxActionMgr::count() const
212 {
213   return myActions.count();
214 }
215
216 bool QtxActionMgr::isEmpty() const
217 {
218   return myActions.isEmpty();
219 }
220
221 void QtxActionMgr::idList( QIntList& lst ) const
222 {
223   lst = myActions.keys();
224 }
225
226 bool QtxActionMgr::isUpdatesEnabled() const
227 {
228   return myUpdate;
229 }
230
231 void QtxActionMgr::setUpdatesEnabled( const bool upd )
232 {
233   myUpdate = upd;
234 }
235
236 bool QtxActionMgr::isVisible( const int, const int ) const
237 {
238   return true;
239 }
240
241 void QtxActionMgr::setVisible( const int, const int, const bool )
242 {
243 }
244
245 void QtxActionMgr::update()
246 {
247   if ( isUpdatesEnabled() )
248     internalUpdate();
249 }
250
251 void QtxActionMgr::internalUpdate()
252 {
253 }
254
255 int QtxActionMgr::generateId() const
256 {
257   static int id = -1;
258   return --id;
259 }
260
261 bool QtxActionMgr::isEnabled( const int id ) const
262 {
263   QAction* a = action( id );
264   if ( a )
265     return a->isEnabled();
266   else
267     return false;
268 }
269
270 void QtxActionMgr::setEnabled( const int id, const bool en )
271 {
272   QAction* a = action( id );
273   if ( a )
274     a->setEnabled( en );
275 }
276
277 QAction* QtxActionMgr::separator( const bool individual )
278 {
279   if ( individual )
280     return new SeparatorAction();
281
282   if ( !qtx_separator_action )
283   {
284     qtx_separator_action = new SeparatorAction();
285     qAddPostRoutine( qtxSeparatorActionCleanup );
286   }
287   return qtx_separator_action;
288 }
289
290 /*!
291         Class: QtxActionMgr::Reader
292         Level: Public
293 */
294
295 QtxActionMgr::Reader::Reader()
296 {
297 }
298
299 QtxActionMgr::Reader::~Reader()
300 {
301 }
302
303 QStringList QtxActionMgr::Reader::options() const
304 {
305   return myOptions.keys();
306 }
307
308 QString QtxActionMgr::Reader::option( const QString& name, const QString& def ) const
309 {
310   if( myOptions.contains( name ) )
311     return myOptions[ name ];
312   else
313     return def;
314 }
315
316 void QtxActionMgr::Reader::setOption( const QString& name, const QString& value )
317 {
318   myOptions[ name ] = value;
319 }
320
321
322 /*!
323         Class: QtxActionMgr::XMLReader
324         Level: Public
325 */
326 QtxActionMgr::XMLReader::XMLReader( const QString& root,
327                                     const QString& item,
328                                     const QString& dir )
329 : Reader()
330 {
331   setOption( QString( "root_tag" ),  root );
332   setOption( QString( "menu_item" ), item );
333   setOption( QString( "icons_dir" ), dir  );
334   setOption( QString( "id" ),        QString( "item-id" ) );
335   setOption( QString( "pos" ),       QString( "pos-id" ) );
336   setOption( QString( "group" ),     QString( "group-id" ) );
337   setOption( QString( "label" ),     QString( "label-id" ) );
338   setOption( QString( "tooltip" ),   QString( "tooltip-id" ) );
339   setOption( QString( "accel" ),     QString( "accel-id" ) );
340   setOption( QString( "separator" ), QString( "separator" ) );
341   setOption( QString( "icon" ),      QString( "icon-id" ) );
342   setOption( QString( "toggle" ),    QString( "toggle-id" ) );
343 }
344
345 QtxActionMgr::XMLReader::~XMLReader()
346 {
347 }
348
349 bool QtxActionMgr::XMLReader::read( const QString& fname, Creator& cr ) const
350 {
351   bool res = false;  
352
353 #ifndef QT_NO_DOM
354
355   QFile file( fname );
356   if ( !file.open( IO_ReadOnly ) )
357     return res;
358
359   QDomDocument doc;
360
361   res = doc.setContent( &file );
362   file.close();
363
364   if ( !res )
365     return res;
366
367   QString root = option( "root_tag" );
368   for( QDomNode cur = doc.documentElement(); !cur.isNull(); )
369   {
370     if( cur.isElement() && isNodeSimilar( cur, root ) )
371       read( cur, -1, cr );
372     else if( cur.hasChildNodes() )
373     {
374       cur = cur.firstChild();
375       continue;
376     }
377
378     while( !cur.isNull() && cur.nextSibling().isNull() )
379       cur = cur.parentNode();
380     if( !cur.isNull() )
381       cur = cur.nextSibling();
382   }
383
384 #endif
385
386   return res;
387 }
388
389 void QtxActionMgr::XMLReader::read( const QDomNode& parent_node,
390                                     const int parent_id,
391                                     Creator& cr ) const
392 {
393   if( parent_node.isNull() )
394     return;
395
396   QStringList items = QStringList::split( "|", option( QString( "menu_item" ) ) );
397
398   const QDomNodeList& children = parent_node.childNodes();
399   for( int i=0, n=children.count(); i<n; i++ )
400   {
401     QDomNode node = children.item( i );
402     //QString n = node.nodeName();
403     if( node.isElement() /*&& node.hasAttributes()*/ &&
404         ( items.contains( node.nodeName() ) || node.nodeName()==option( "separator" ) ) )
405     {
406       QDomNamedNodeMap map = node.attributes();
407       ItemAttributes attrs;
408
409       for( int i=0, n=map.count(); i<n; i++ )
410         if( map.item( i ).isAttr() )
411         {
412           QDomAttr a = map.item( i ).toAttr();
413           attrs.insert( a.name(), a.value() );
414         }
415
416       int newId = cr.append( node.nodeName(), node.hasChildNodes(), attrs, parent_id );
417       if( node.hasChildNodes() )
418         read( node, newId, cr );
419     }
420   }
421 }
422
423 bool QtxActionMgr::XMLReader::isNodeSimilar( const QDomNode& node,
424                                              const QString& pattern ) const
425 {
426   if( node.nodeName()==pattern )
427     return true;
428   
429   QDomDocument temp;
430   QString mes;
431   temp.setContent( pattern, true, &mes );
432
433   const QDomNamedNodeMap &temp_map = temp.documentElement().attributes(),
434                          &cur_map = node.attributes();
435   bool ok = temp_map.count()>0;
436   for( int i=0, n=temp_map.count(); i<n && ok; i++ )
437   {
438     QDomAttr a = temp_map.item( i ).toAttr(),
439              b = cur_map.namedItem( a.name() ).toAttr();
440     ok = !b.isNull() && a.name()==b.name() && a.value()==b.value();
441   }
442
443   return ok;
444 }
445
446
447 /*!
448         Class: QtxActionMgr::Creator
449         Level: Public
450 */
451 int QtxActionMgr::Creator::intValue( const ItemAttributes& attrs,
452                                      const QString& name, int def )
453 {
454   if( attrs.contains( name ) )
455   {
456     bool ok; 
457     int res = attrs[ name ].toInt( &ok );
458     if( ok )
459       return res;
460   }
461   return def;
462 }
463
464 QString QtxActionMgr::Creator::strValue( const ItemAttributes& attrs,
465                                          const QString& name,
466                                          const QString& def  )
467 {
468   if( attrs.contains( name ) )
469     return attrs[ name ];
470   else
471     return def;
472 }
473
474 QtxActionMgr::Creator::Creator( QtxActionMgr::Reader* r )
475 : myReader( r )
476 {
477 }
478
479 QtxActionMgr::Creator::~Creator()
480 {
481 }
482
483 QtxActionMgr::Reader* QtxActionMgr::Creator::reader() const
484 {
485   return myReader;
486 }
487
488 void QtxActionMgr::Creator::connect( QAction* ) const
489 {
490 }
491
492 bool QtxActionMgr::Creator::loadPixmap( const QString& fname, QPixmap& pix ) const
493 {
494   if( !reader() )
495     return false;
496
497   QStringList dirlist = QStringList::split( ";", reader()->option( "icons_dir", "." ) );
498   QStringList::const_iterator anIt = dirlist.begin(),
499                               aLast = dirlist.end();
500   bool res = false;
501   for( ; anIt!=aLast && !res; anIt++ )
502     res = pix.load( Qtx::addSlash( *anIt ) + fname );
503
504   return res;
505 }