Salome HOME
770e0964b375526da25576b791f6bc0b8662b42b
[modules/gui.git] / src / Qtx / QtxListAction.cxx
1 // Copyright (C) 2007-2022  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // File:      QtxListAction.cxx
24 // Author:    Sergey TELKOV
25 //
26 #include "QtxListAction.h"
27
28 #include <QMenu>
29 #include <QLabel>
30 #include <QVBoxLayout>
31 #include <QMouseEvent>
32 #include <QListWidget>
33 #include <QToolButton>
34 #include <QApplication>
35
36 /*!
37   \class QtxListAction::ScrollEvent
38   \internal
39   \brief Event for the scrolling in the list of actions.
40 */
41
42 class QtxListAction::ScrollEvent : public QEvent
43 {
44 public:
45   enum { Scroll = User + 1 };
46
47   ScrollEvent( bool down ) : QEvent( (QEvent::Type)Scroll ), myDown( down ) {}
48   virtual ~ScrollEvent() {}
49
50   bool isDown() const { return myDown; }
51
52 private:
53   bool myDown;
54 };
55
56 /*!
57   \class QtxListAction::ListWidget
58   \internal
59   \brief List of actions.
60 */
61
62 class QtxListAction::ListWidget : public QListWidget
63 {
64 public:
65   ListWidget( QWidget* parent = 0 ) : QListWidget( parent ) {}
66   virtual ~ListWidget() {}
67
68 protected:
69   virtual void scrollContentsBy( int dx, int dy )
70   {
71     QListWidget::scrollContentsBy( dx, dy );
72     if ( dy != 0 )
73       QApplication::postEvent( viewport(), new ScrollEvent( dy <= 0 ) );
74   }
75 };
76
77 /*!
78   \class QtxListAction::ListFrame
79   \internal
80   \brief Expanding frame with action list and comment.
81 */
82
83 class QtxListAction::ListFrame: public QMenu
84 {
85 public:
86   ListFrame( QtxListAction*, QWidget* parent );
87   virtual ~ListFrame();
88
89   void                    clear();
90   const QStringList       names() const;
91   void                    addNames( const QStringList& );
92
93   void                    setSingleComment( const QString& );
94   void                    setMultipleComment( const QString& );
95
96   int                     selected() const;
97   void                    setSelected( const int );
98
99   int                     linesNumber() const;
100   int                     charsNumber() const;
101
102   void                    setLinesNumber( const int );
103   void                    setCharsNumber( const int );
104
105   virtual QSize           sizeHint() const;
106   virtual QSize           minimumSizeHint() const;
107
108   virtual bool            eventFilter( QObject*, QEvent* );
109
110   virtual void            setVisible( bool );
111
112 protected:
113   virtual void            keyPressEvent( QKeyEvent* );
114
115 private:
116   void                    accept();
117   void                    updateComment();
118   void                    setNames( const QStringList& );
119   void                    removePostedEvens( QObject*, int );
120
121 private:
122   QListWidget*            myList;
123   QStringList             myNames;
124   QtxListAction*          myAction;
125   QLabel*                 myComment;
126
127   int                     myLines;
128   int                     myChars;
129
130   QString                 mySingleComment;
131   QString                 myMultipleComment;
132 };
133
134 /*!
135   \brief Constructor.
136   \param a list action
137   \param parent parent widget
138 */
139 QtxListAction::ListFrame::ListFrame( QtxListAction* a, QWidget* parent )
140 : QMenu( parent ),
141   myList( 0 ),
142   myAction( a ),
143   myComment( 0 ),
144   myLines( 5 ),
145   myChars( 5 )
146 {
147   QVBoxLayout* top = new QVBoxLayout( this );
148   top->setMargin( 0 );
149   QFrame* main = new QFrame( this );
150   main->setFrameStyle( QFrame::Panel | QFrame::Raised );
151   top->addWidget( main );
152
153   QVBoxLayout* base = new QVBoxLayout( main );
154   base->setMargin( 3 );
155   base->setSpacing( 2 );
156
157   myList = new ListWidget( main );
158   myList->setSelectionMode( QListWidget::MultiSelection );
159   myList->setVerticalScrollMode( QListWidget::ScrollPerItem );
160   myList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
161   myList->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
162   myList->viewport()->installEventFilter( this );
163   myList->viewport()->setMouseTracking( true );
164   myList->setFocusPolicy( Qt::NoFocus );
165
166   myComment = new QLabel( main );
167   myComment->setFrameStyle( QFrame::Panel | QFrame::Sunken );
168   myComment->setAlignment( Qt::AlignCenter );
169   myMultipleComment = "%1";
170
171   base->addWidget( myList );
172   base->addWidget( myComment );
173 }
174
175 /*!
176   \brief Destructor.
177 */
178 QtxListAction::ListFrame::~ListFrame()
179 {
180 }
181
182 /*!
183   \brief Clear list of names.
184 */
185 void QtxListAction::ListFrame::clear()
186 {
187   myNames.clear();
188   setNames( myNames );
189 }
190
191 /*!
192   \brief Add names to the list.
193
194   Truncates each name to fit the frame width.
195   Method QtxListAction::setCharsNumber(int) can be used to change
196   the frame width (in characters).
197
198   \param names list of names to be added
199   \sa setNames(), QtxListAction::setCharsNumber(int)
200 */
201 void QtxListAction::ListFrame::addNames( const QStringList& names )
202 {
203   for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
204     myNames.append( *it );
205   setNames( myNames );
206 }
207
208 /*!
209   \brief Set names to the list.
210
211   Truncates each name to fit the frame width.
212   Method QtxListAction::setCharsNumber(int) can be used to change
213   the frame width (in characters).
214
215   \param names list of names to be set
216   \sa addNames(), QtxListAction::setCharsNumber(int)
217 */
218 void QtxListAction::ListFrame::setNames( const QStringList& names )
219 {
220   if ( !myList )
221     return;
222
223   myList->clear();
224   QStringList strList;
225   for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
226   {
227     QString s = *it;
228     QFontMetrics fm = myList->fontMetrics();
229     int maxW = charsNumber() * fm.maxWidth();
230     int w = fm.width( s );
231     if ( w > maxW )
232     {
233       QString extra( "..." );
234       int len = s.length();
235       int extraLen = fm.width( extra ) + 1;
236       while ( true )
237       {
238         w = fm.width( s, --len );
239         if ( w + extraLen < maxW )
240         {
241           s = s.left( len );
242           break;
243         }
244       }
245       s += extra;
246     }
247     strList.append( s );
248   }
249   myList->addItems( strList );
250 }
251
252 /*!
253   \brief Get list of names.
254   \return list of names
255 */
256 const QStringList QtxListAction::ListFrame::names() const
257 {
258   return myNames;
259 }
260
261 /*!
262   \brief Get maximum numer of lines shown without activation of vertical scroll bar.
263   \return number of lines
264   \sa setLinesNumber(), charsNumber(), setCharsNumber()
265 */
266 int QtxListAction::ListFrame::linesNumber() const
267 {
268   return myLines;
269 }
270
271 /*!
272   \brief Get maximum numer of characters in the line.
273
274   If the name length is greater than this value, it will be truncated.
275
276   \return number of characters
277   \sa setCharsNumber(), linesNumber(), setLinesNumber()
278 */
279 int QtxListAction::ListFrame::charsNumber() const
280 {
281   return myChars;
282 }
283
284 /*!
285   \brief Set maximum numer of lines shown without activation of vertical scroll bar.
286   \param maxLines number of lines
287   \sa linesNumber(), charsNumber(), setCharsNumber()
288 */
289 void QtxListAction::ListFrame::setLinesNumber( const int maxLines )
290 {
291   myLines = maxLines;
292 }
293
294 /*!
295   \brief Set maximum numer of characters in the line.
296
297   If the name length is greater than this value, it will be truncated.
298
299   \param maxChars number of characters
300   \sa charsNumber(), linesNumber(), setLinesNumber()
301 */
302 void QtxListAction::ListFrame::setCharsNumber( const int maxChars )
303 {
304   if ( myChars == maxChars )
305     return;
306
307   myChars = maxChars;
308   setNames( myNames );
309 }
310
311 /*!
312   \brief Set comment which is displayed when single name is selected.
313   \param comment comment format
314 */
315 void QtxListAction::ListFrame::setSingleComment( const QString& comment )
316 {
317   mySingleComment = comment;
318   setNames( myNames );
319   updateComment();
320 }
321
322 /*!
323   \brief Set comment which is displayed when multiple names are selected.
324   \param comment comment format
325 */
326 void QtxListAction::ListFrame::setMultipleComment( const QString& comment )
327 {
328   myMultipleComment = comment;
329   setNames( myNames );
330   updateComment();
331 }
332
333 /*!
334   \brief Update displayed comment.
335 */
336 void QtxListAction::ListFrame::updateComment()
337 {
338   QString com;
339   int selNum = selected();
340   if ( selNum > 1 )
341     com = myMultipleComment;
342   else if ( selNum > 0 && !mySingleComment.isEmpty() )
343     com = mySingleComment;
344   
345   if ( !com.isEmpty() )
346     com = com.arg( selNum );
347   
348   myComment->setText( com );
349 }
350
351 /*!
352   \brief Get preferable size for the list widget.
353   \return preferable size
354 */
355 QSize QtxListAction::ListFrame::sizeHint() const
356 {
357   return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
358                 qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
359                 myComment->sizeHint().height() );
360 }
361
362 /*!
363   \brief Get preferable minimum size for the list widget.
364   \return preferable minimum size
365 */
366 QSize QtxListAction::ListFrame::minimumSizeHint() const
367 {
368   return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
369                 qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
370                 myComment->sizeHint().height() );
371 }
372
373 /*!
374   \brief Validate the action.
375 */
376 void QtxListAction::ListFrame::accept()
377 {
378   int sel = selected();
379   if ( sel && myAction )
380     myAction->onMultiple( sel );
381 }
382
383 /*!
384   \brief Called when list widget is shown/hidden.
385   \param on if \c true, widget is shown, otherswise it is hidden
386 */
387 void QtxListAction::ListFrame::setVisible( bool on )
388 {
389   if ( on )
390   {
391     myList->setFocus();
392     myList->scrollToItem( myList->item( 0 ), QListWidget::PositionAtTop );
393     setSelected( 0 );
394     updateComment();
395   }
396
397   QMenu::setVisible( on );
398 }
399
400 /*!
401   \brief Process key press event.
402
403   The following keys are supported:
404   - Up/Down
405   - PageUp/PageDown
406   - Enter
407   - Escape
408
409   \param e key press event
410 */
411 void QtxListAction::ListFrame::keyPressEvent( QKeyEvent* e )
412 {
413   if ( e->type() == QEvent::KeyRelease )
414     return;
415
416   e->accept();
417
418   int selNum = selected();
419   switch( e->key() )
420   {
421   case Qt::Key_Up:
422     setSelected( qMax( 1, selNum - 1 ) );
423     break;
424   case Qt::Key_Down:
425     setSelected( qMax( 1, selNum + 1 ) );
426     break;
427   case Qt::Key_PageUp:
428     setSelected( qMax( 1, selNum - linesNumber() ) );
429     break;
430   case Qt::Key_PageDown:
431     setSelected( selNum += linesNumber() );
432     break;
433   case Qt::Key_Home:
434     setSelected( 1 );
435     break;
436   case Qt::Key_End:
437     setSelected( myList->count() );
438     break;
439   case Qt::Key_Return:
440     accept();
441     break;
442   case Qt::Key_Escape:
443     hide();
444     break;
445   }
446 }
447
448 /*!
449   \brief Process mouse events on the viewport of the list widget.
450   \param o object recieving event (viewport)
451   \param e event
452   \return \c true if further event processing should be stopped.
453 */
454 bool QtxListAction::ListFrame::eventFilter( QObject* o, QEvent* e )
455 {
456   bool res = true;
457
458   switch( (int)e->type() )
459   {
460   case QEvent::MouseMove:
461     {
462       QMouseEvent* me = (QMouseEvent*)e;
463       if ( !myList->viewport()->rect().contains( me->pos() ) )
464         setSelected( 0 );
465       else if ( myList->itemAt( me->pos() ) )
466         setSelected( myList->row( myList->itemAt( me->pos() ) ) + 1 );
467     }
468     break;
469   case QEvent::MouseButtonRelease:
470     accept();
471   case QEvent::MouseButtonPress:
472   case QEvent::MouseButtonDblClick:
473     break;
474   case ScrollEvent::Scroll:
475     {
476       ScrollEvent* se = (ScrollEvent*)e;
477       QPoint pos = myList->viewport()->mapFromGlobal( QCursor::pos() );
478       if ( myList->viewport()->rect().contains( pos ) )
479       {
480         if ( myList->itemAt( pos ) )
481           setSelected( myList->row( myList->itemAt( pos ) ) + 1 );
482       }
483       else if ( se->isDown() )
484         setSelected( myList->row( myList->itemAt( myList->viewport()->rect().bottomLeft() -
485                                                   QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
486       else
487         setSelected( myList->row( myList->itemAt( myList->viewport()->rect().topLeft() +
488                                                   QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
489     }
490     break;
491   default:
492     res = false;
493     break;
494   }
495
496   if ( res )
497     return true;
498   else
499     return QMenu::eventFilter( o, e );
500 }
501
502 /*!
503   \brief Get number of selected names.
504   \return number of selected items
505 */
506 int QtxListAction::ListFrame::selected() const
507 {
508   int sel = 0;
509   QModelIndexList indexes = myList->selectionModel()->selectedRows();
510   for ( QModelIndexList::const_iterator it = indexes.begin(); it != indexes.end(); ++it )
511     sel = qMax( sel, (*it).row() + 1 );
512   
513   return sel;
514 }
515
516 /*!
517   \brief Set number of selected names.
518   \param lastSel number of items to be selected
519 */
520 void QtxListAction::ListFrame::setSelected( const int lastSel )
521 {
522   int last = qMin( lastSel, (int)myList->count() );
523
524   QItemSelection selection;
525   QItemSelectionModel* selModel = myList->selectionModel();
526
527   for ( int i = 0; i < last; i++ )
528     selection.select( selModel->model()->index( i, 0 ), selModel->model()->index( i, 0 ) );
529
530   selModel->select( selection, QItemSelectionModel::ClearAndSelect );
531   
532   int item = last - 1;
533
534   myList->scrollToItem( myList->item( item ) );
535   myList->clearFocus();
536
537   removePostedEvens( myList->viewport(), ScrollEvent::Scroll );
538
539   updateComment();
540 }
541
542 /*!
543   \brief Filter all events of specified type sent to specified object.
544   \param o object
545   \param type event type to be filtered
546 */
547 void QtxListAction::ListFrame::removePostedEvens( QObject* o, int type )
548 {
549   class Filter : public QObject
550   {
551   public:
552     Filter() : QObject( 0 ) {}
553     virtual bool eventFilter( QObject*, QEvent* )
554     {
555       return true;
556     }
557   };
558
559   Filter f;
560   o->installEventFilter( &f );
561   QApplication::sendPostedEvents( o, type );
562 }
563
564 /*!
565   \class QtxListAction
566   \brief Action with associated list of items.
567   
568   This class can be helpuful, for example, for creation of Undo/Redo
569   toolbar items which show list of available commands in the popup list box.
570 */
571
572 /*!
573   \brief Constructor.
574   \param parent parent object
575 */
576 QtxListAction::QtxListAction( QObject* parent )
577 : QtxAction( parent ),
578   myFrame( 0 )
579 {
580   initialize();
581 }
582
583 /*!
584   \brief Constructor.
585   \param icon action icon
586   \param menuText menu text
587   \param accel key accelerator
588   \param parent parent object
589 */
590 QtxListAction::QtxListAction( const QIcon& icon, const QString& menuText, 
591                               int accel, QObject* parent )
592 : QtxAction( menuText, icon, menuText, accel, parent ),
593   myFrame( 0 )
594 {
595   initialize();
596 }
597
598 /*!
599   \brief Constructor.
600   \param menuText menu text
601   \param accel key accelerator
602   \param parent parent object
603 */
604 QtxListAction::QtxListAction( const QString& menuText, int accel, QObject* parent )
605 : QtxAction( menuText, menuText, accel, parent ),
606   myFrame( 0 )
607 {
608   initialize();
609 }
610
611 /*!
612   \brief Constructor.
613   \param text action description text (tooltip)
614   \param menuText menu text
615   \param accel key accelerator
616   \param parent parent object
617 */
618 QtxListAction::QtxListAction( const QString& text, const QString& menuText, 
619                               int accel, QObject* parent )
620 : QtxAction( text, menuText, accel, parent ),
621   myFrame( 0 )
622 {
623   initialize();
624 }
625
626 /*!
627   \brief Constructor.
628   \param text action description text (tooltip)
629   \param icon action icon
630   \param menuText menu text
631   \param accel key accelerator
632   \param parent parent object
633 */
634 QtxListAction::QtxListAction( const QString& text, const QIcon& icon, 
635                               const QString& menuText, int accel, QObject* parent )
636 : QtxAction( text, icon, menuText, accel, parent ),
637   myFrame( 0 )
638 {
639   initialize();
640 }
641
642 /*!
643   \brief Destructor.
644 */
645 QtxListAction::~QtxListAction()
646 {
647   delete myFrame;
648   myFrame = 0;
649 }
650
651 /*!
652   \brief Get popup mode.
653   \return current popup mode (QtxListAction::PopupMode)
654   \sa setPopupMode()
655 */
656 int QtxListAction::popupMode() const
657 {
658   return menu() ? SubMenu : Item;
659 }
660
661 /*!
662   \brief Set popup mode.
663   \param mode new popup mode (QtxListAction::PopupMode)
664   \sa popupMode()
665 */
666 void QtxListAction::setPopupMode( const int mode )
667 {
668   if ( mode == popupMode() )
669     return;
670
671   if ( mode == Item )
672   {
673     delete menu();
674     setMenu( 0 );
675   }
676   else
677     setMenu( new QMenu( 0 ) );
678
679   onChanged();
680 }
681
682 /*!
683   \brief Get current list of names.
684   \return list of names
685 */
686 QStringList QtxListAction::names() const
687 {
688   QStringList lst;
689   if ( myFrame )
690     lst = myFrame->names();
691   return lst;
692 }
693
694 /*!
695   \brief Add names to the list.
696
697   Truncates each name to fit the frame width.
698   Method setCharsNumber() can be used to change
699   the frame width (in characters).
700
701   \param names list of names to be added
702   \param clear if \c true, remove the old contents from the list
703   \sa setCharsNumber()
704 */
705 void QtxListAction::addNames( const QStringList& names, bool clear )
706 {
707   if ( !myFrame )
708     return;
709
710   if ( clear )
711     myFrame->clear();
712
713   myFrame->addNames( names );
714
715   onChanged();
716 }
717
718 /*!
719   \brief Get maximum numer of lines shown without activation of vertical scroll bar.
720   \return number of lines
721   \sa setLinesNumber(), charsNumber(), setCharsNumber()
722 */
723 int QtxListAction::linesNumber() const
724 {
725   return myFrame->linesNumber();
726 }
727
728 /*!
729   \brief Get maximum numer of characters in the line.
730
731   If the name length is greater than this value, it will be truncated.
732
733   \return number of characters
734   \sa setCharsNumber(), linesNumber(), setLinesNumber()
735 */
736 int QtxListAction::charsNumber() const
737 {
738   return myFrame->charsNumber();
739 }
740
741 /*!
742   \brief Set maximum numer of lines shown without activation of vertical scroll bar.
743   \param nlines number of lines (5 by default)
744   \sa linesNumber(), charsNumber(), setCharsNumber()
745 */
746 void QtxListAction::setLinesNumber( const int nlines )
747 {
748   myFrame->setLinesNumber( nlines );
749 }
750
751 /*!
752   \brief Set maximum numer of characters in the line.
753
754   If the name length is greater than this value, it will be truncated.
755
756   \param maxChars number of characters (5 by default)
757   \sa charsNumber(), linesNumber(), setLinesNumber()
758 */
759
760 void QtxListAction::setCharsNumber( const int nchars )
761 {
762   myFrame->setCharsNumber( nchars );
763 }
764
765 /*!
766   \brief Set the format Qt string for comments displayed under the list
767          of actions for one action and for several actions.
768
769   Example: "Undo %1 actions" format string will work as "Undo 3 actions"
770   when 3 actions are selected. The default format string is "%1".
771
772   \param c single action comment format
773   \param c multiple actions comment format
774 */
775 void QtxListAction::setComment( const QString& c, const QString& sc )
776 {
777   if ( !myFrame )
778     return;
779
780   myFrame->setSingleComment( sc.isEmpty() ? c : sc );
781   myFrame->setMultipleComment( c );
782 }
783
784 /*!
785   \brief Create action widget.
786
787   This function is called whenever the action is added 
788   to a container widget that supports custom widgets like menu or toolbar.
789   
790   \param parent container widget the action is added to
791   \return tool button for toolbar and 0 otherwise
792 */
793 QWidget* QtxListAction::createWidget( QWidget* parent )
794 {
795   if ( parent && parent->inherits( "QMenu" ) )
796     return 0;
797
798   QToolButton* tb = new QToolButton( parent );
799   tb->setText( text() );
800   tb->setIcon( icon() );
801   tb->setPopupMode( QToolButton::MenuButtonPopup );
802   tb->setMenu( myFrame );
803   tb->setEnabled( isEnabled() && !names().isEmpty() );
804   tb->setToolTip( toolTip() );
805   connect( tb, SIGNAL( clicked( bool ) ), this, SLOT( onSingle( bool ) ) );
806
807   return tb;
808 }
809
810 /*!
811   \brief Destroy action widget.
812
813   This function is called whenever the action is removed
814   from a container widget that supports custom widgets like menu or toolbar.
815   
816   \param widget container widget the action is removed from
817 */
818 void QtxListAction::deleteWidget( QWidget* widget )
819 {
820   delete widget;
821 }
822
823 /*!
824   \brief Initialize the action.
825 */
826 void QtxListAction::initialize()
827 {
828   setPopupMode( Item );
829   
830   myFrame = new QtxListAction::ListFrame( this, 0 );
831   myFrame->setLinesNumber( 7 );
832   myFrame->setCharsNumber( 5 );
833
834   myFrame->hide();
835
836   connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
837   connect( this, SIGNAL( triggered( bool ) ), this, SLOT( onSingle( bool ) ) );
838 }
839
840 /*!
841   \brief Called the action contents is changed.
842 */
843 void QtxListAction::onChanged()
844 {
845   QStringList lst = myFrame->names();
846
847   if ( menu() )
848   {
849     menu()->clear();
850     for ( QStringList::iterator iter = lst.begin(); iter != lst.end(); ++iter )
851     {
852       QAction* a = new QAction( *iter, menu() );
853       menu()->addAction( a );
854       connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTriggered( bool ) ) );
855     }
856   }
857
858   QList<QWidget*> widList = createdWidgets();
859   for ( QList<QWidget*>::iterator it = widList.begin(); it != widList.end(); ++it )
860   {
861     (*it)->setEnabled( isEnabled() && !lst.isEmpty() );
862     QToolButton* tb = ::qobject_cast<QToolButton*>( *it );
863     if ( tb )
864     {
865       tb->setText( text() );
866       tb->setIcon( icon() );
867       tb->setToolTip( toolTip() );
868     }
869   }
870 }
871
872 /*!
873   \brief Called when a user click action button.
874   \param on (not used)
875 */
876
877 void QtxListAction::onSingle( bool /*on*/ )
878 {
879   onMultiple( 1 );
880 }
881
882 /*!
883   \brief Called when multiple items are selected. 
884 */
885 void QtxListAction::onMultiple( const int numActions )
886 {
887   if ( myFrame )
888     myFrame->hide();
889
890   if ( numActions > 0 )
891     emit triggered( numActions );
892 }
893
894 /*!
895   \brief Called when user activates an items in the popup sub menu. 
896   \param on (not used)
897 */
898 void QtxListAction::onTriggered( bool /*on*/ )
899 {
900   if ( !menu() )
901     return;
902
903   QList<QAction*> actionList = menu()->actions();
904   int idx = actionList.indexOf( ::qobject_cast<QAction*>( sender() ) );
905   if ( idx < 0 )
906     return;
907
908   emit triggered( idx + 1 );
909 }
910
911 /*!
912   \fn QtxListAction::activated(int numItems );
913   \brief This signal is emitted when an action is activated.
914   \param numItems number of items being selected in the action list.
915 */