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