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/
19 // File: QtxListAction.cxx
20 // Author: Sergey TELKOV (Based on code by Eugene AKSENOV)
22 #include "QtxListAction.h"
31 #include <qpopupmenu.h>
32 #include <qtoolbutton.h>
33 #include <qobjectlist.h>
34 #include <qapplication.h>
36 static const char* list_arrow_icon[] = {
49 \class QtxListAction::ToolButton
52 class QtxListAction::ToolButton : public QToolButton
55 ToolButton( QtxListAction*, QWidget* = 0, const char* = 0 );
56 virtual ~ToolButton();
58 virtual QSize sizeHint() const;
61 QtxListAction* myAction;
67 QtxListAction::ToolButton::ToolButton( QtxListAction* a, QWidget* parent, const char* name )
68 : QToolButton( parent, name ),
71 setIconSet( QPixmap( list_arrow_icon ) );
77 QtxListAction::ToolButton::~ToolButton()
80 myAction->controlDeleted( this );
84 \return the recommended size for the widget
86 QSize QtxListAction::ToolButton::sizeHint() const
88 QSize sz = iconSet().pixmap().size();
89 return QSize( sz.width() + 2, sz.height() + 2 );
93 Constructs an list action with given parent and name. If toggle is true the
94 action will be a toggle action, otherwise it will be a command action.
96 QtxListAction::QtxListAction( QObject* parent, const char* name, bool toggle )
97 : QtxAction( parent, name, toggle ),
106 This constructor creates an action with the following properties: the
107 description text, the icon or iconset icon, the menu text and keyboard
108 accelerator. It is a child of given parent and named specified name.
109 If toggle is true the action will be a toggle action, otherwise it will
113 QtxListAction::QtxListAction( const QString& text, const QIconSet& icon,
114 const QString& menuText, int accel,
115 QObject* parent, const char* name, bool toggle )
116 : QtxAction( text, icon, menuText, accel, parent, name, toggle ),
125 This constructor creates an action with the following properties: the
126 description text, the menu text and keyboard accelerator. It is a child
127 of given parent and named specified name. If toggle is true the action
128 will be a toggle action, otherwise it will be a command action.
131 QtxListAction::QtxListAction( const QString& text, const QString& menuText,
132 int accel, QObject* parent, const char* name, bool toggle )
133 : QtxAction( text, menuText, accel, parent, name, toggle ),
145 QtxListAction::~QtxListAction()
148 myFrame->myAction = 0;
152 Name: popupMode [public]
153 Desc: Returns popup mode. If popup mode "Item" (default) then action will
154 be added into popup menu as menu item. If popup mode "SubMenu" then
155 action will be added into popup menu as sub menu with list of items.
158 int QtxListAction::popupMode() const
164 Name: setPopupMode [public]
165 Desc: Set the popup mode. Popup mode define way in this action will be
166 added into popup menu. This function should be used before addTo.
169 void QtxListAction::setPopupMode( const int mode )
175 \return list of names
177 QStringList QtxListAction::names() const
181 lst = myFrame->names();
186 Name: addNames [public]
187 Desc: Fills the list of actions. Removes the old contents from
188 the list if 'clear' is true.
191 void QtxListAction::addNames( const QStringList& names, bool clear )
199 myFrame->addNames( names );
201 QStringList lst = myFrame->names();
202 for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
205 QPopupMenu* pm = (QPopupMenu*)pit.key();
206 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
207 pit.data().popup->insertItem( *it, i++ );
208 pm->setItemEnabled( pit.data().id, isEnabled() && pit.data().popup->count() );
211 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
213 bit.data().drop->setEnabled( isEnabled() && !lst.isEmpty() );
214 bit.data().main->setEnabled( isEnabled() && !lst.isEmpty() );
219 Name: addTo [virtual public]
220 Desc: Adds this control to 'popup' or 'toolbar'.
223 bool QtxListAction::addTo( QWidget* w )
225 if ( myButtons.contains( w ) || myPopups.contains( w ) )
228 if ( !w->inherits( "QPopupMenu" ) || popupMode() != SubMenu )
229 if ( !QtxAction::addTo( w ) )
234 addedTo( (QWidget*)w->children()->getLast(), w );
237 if ( w->inherits( "QToolBar" ) )
239 Buttons& entry = myButtons[w];
240 QHBox* dropWrap = new QHBox( w );
241 entry.drop = new ToolButton( this, dropWrap, "qt_dockwidget_internal" );
243 entry.drop->setTextLabel( text() );
244 entry.drop->setToggleButton( true );
245 entry.drop->setAutoRaise( entry.main->autoRaise() );
247 entry.main->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
248 entry.drop->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
250 entry.main->installEventFilter( this );
251 entry.drop->installEventFilter( this );
253 QToolTip::add( entry.drop, toolTip(), myTipGroup, statusTip() );
255 connect( entry.drop, SIGNAL( toggled( bool ) ), this, SLOT( onExpand( bool ) ) );
257 else if ( w->inherits( "QPopupMenu" ) && popupMode() == SubMenu )
260 QPopupMenu* pm = (QPopupMenu*)w;
262 entry.popup = new QPopupMenu( pm );
263 entry.id = pm->insertItem( text(), entry.popup );
266 QStringList lst = myFrame->names();
267 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
269 int id = entry.popup->insertItem( *it );
270 entry.popup->setItemParameter( id, i++ );
272 pm->setItemEnabled( entry.id, isEnabled() && entry.popup->count() );
273 myPopups.insert( w, entry );
275 connect( entry.popup, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
279 connect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
286 Name: addTo [virtual public]
287 Desc: Adds this control to 'popup' or 'toolbar'. Allow to specify index
288 for adding into 'popup'.
291 bool QtxListAction::addTo( QWidget* w, const int idx )
293 return QtxAction::addTo( w, idx );
297 Name: removeFrom [virtual public]
298 Desc: Removes this control from 'popup' or 'toolbar'.
301 bool QtxListAction::removeFrom( QWidget* w )
303 if ( !QtxAction::removeFrom( w ) )
306 if ( w->inherits( "QToolBar" ) )
311 if ( myButtons.contains( w ) )
313 Buttons& entry = myButtons[w];
315 if ( entry.drop->parent() && entry.drop->parent()->parent() == w )
316 delete entry.drop->parent();
320 myButtons.remove( w );
322 else if ( w->inherits( "QPopupMenu" ) )
323 myPopups.remove( w );
326 disconnect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
333 Name: setEnabled [virtual public slot]
334 Desc: Enables/disables this control.
337 void QtxListAction::setEnabled( bool enable )
339 QtxAction::setEnabled( enable );
341 bool isOn = enable && !myFrame->names().isEmpty();
343 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
345 bit.data().drop->setEnabled( isOn );
346 bit.data().main->setEnabled( isOn );
349 for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
351 QPopupMenu* cont = (QPopupMenu*)pit.key();
352 cont->setItemEnabled( pit.data().id, isOn );
357 Name: setMaxLines [public]
358 Desc: Sets max number of lines that list frame shows
359 without vertical scroll bar. Default value is 5.
362 void QtxListAction::setMaxLines( int nlines )
364 myFrame->setMaxLines( nlines );
368 Name: setMaxLineChars [public]
369 Desc: Sets max number of characters in a line which list frame shows
370 without truncation. Default value is 12 (the widest char size is used).
373 void QtxListAction::setMaxLineChars( int nchars )
375 myFrame->setMaxLineChars( nchars );
379 Name: setComment [public]
380 Desc: Sets the format Qt string for comments displayed under the list
381 of actions for one action and for several actions.
382 Ex. "Undo %1 actions" format string will work as "Undo 3 actions"
383 when 3 actions are selected. The default format string is "%1".
386 void QtxListAction::setComment( const QString& c, const QString& sc )
391 myFrame->setSingleComment( sc.isEmpty() ? c : sc );
392 myFrame->setMultipleComment( c );
396 Name: eventFilter [virtual public]
397 Desc: Reimplemented to paint the tool buttons in 2D/3D.
400 bool QtxListAction::eventFilter( QObject* o, QEvent* e )
402 if ( !myRaise && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) )
405 QWidget* wid = widget( (QWidget*)o );
406 if ( o == mainButton( wid ) )
407 obj = dropButton( wid );
408 else if ( o == dropButton( wid ) )
409 obj = mainButton( wid );
414 QApplication::sendEvent( obj, e );
419 return QObject::eventFilter( o, e );
423 Name: addedTo [protected]
424 Desc: Reimplemented for internal reasons.
427 void QtxListAction::addedTo( QWidget* actionWidget, QWidget* container )
430 QtxAction::addedTo( actionWidget, container );
433 if ( !container->inherits( "QToolBar" ) )
437 entry.main = (QToolButton*)actionWidget;
439 myButtons.insert( container, entry );
443 Name: initialize [private]
444 Desc: Initialization of object QtxListAction.
447 void QtxListAction::initialize()
449 myTipGroup = new QToolTipGroup( this );
451 myFrame = new QtxListFrame( this, qApp->mainWidget() );
452 myFrame->setMaxLines( 5 );
453 myFrame->setMaxLineChars( 7 );
457 connect( myFrame, SIGNAL( hided() ), this, SLOT( onHided() ) );
458 connect( this, SIGNAL( activated() ), this, SLOT( onSingle() ) );
459 connect( myFrame, SIGNAL( selected( int ) ), this, SLOT( onMultiple( int ) ) );
461 connect( myTipGroup, SIGNAL( removeTip() ), this, SLOT( clearStatusText() ) );
462 connect( myTipGroup, SIGNAL( showTip( const QString& ) ), this, SLOT( showStatusText( const QString& ) ) );
466 Name: onSingle [private slot]
467 Desc: Called when a single action is selected.
470 void QtxListAction::onSingle()
476 Name: onMultiple [private slot]
477 Desc: Called when multiple actions are selected.
480 void QtxListAction::onMultiple( int numActions )
485 if ( numActions > 0 )
486 emit activated( numActions );
490 Name: onExpand [private slot]
491 Desc: Activates the list of actions.
494 void QtxListAction::onExpand( bool on )
496 const QObject* obj = sender();
499 QWidget* wid = widget( (QToolButton*)obj );
500 QToolButton* main = mainButton( wid );
501 myFrame->setOwner( main );
510 SLOT: called when frame is hidden
512 void QtxListAction::onHided()
514 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
516 bool block = bit.data().drop->signalsBlocked();
517 bit.data().drop->blockSignals( true );
518 bit.data().drop->setOn( false );
519 bit.data().drop->blockSignals( block );
524 Name: onActivated [private slot]
525 Desc: Called when a sub menu item is activated.
528 void QtxListAction::onActivated( int id )
530 QPopupMenu* pm = (QPopupMenu*)sender();
531 int num = pm->itemParameter( id );
533 emit activated( num );
537 Name: onDestroyed [private slot]
538 Desc: Called when a container widget is destroyed.
541 void QtxListAction::onDestroyed( QObject* obj )
543 if ( !obj->isWidgetType() )
546 myPopups.remove( (QWidget*)obj );
547 myButtons.remove( (QWidget*)obj );
551 Name: widget [private]
552 Desc: Returns container widget for specified control.
555 QWidget* QtxListAction::widget( QWidget* obj ) const
558 for ( PopupsMap::ConstIterator pit = myPopups.begin(); pit != myPopups.end() && !wid; ++pit )
559 if ( pit.data().popup == obj )
562 for ( ButtonsMap::ConstIterator bit = myButtons.begin(); bit != myButtons.end() && !wid; ++bit )
563 if ( bit.data().main == obj || bit.data().drop == obj )
570 Name: listPopup [private]
571 Desc: Returns sub popup menu widget for specified container.
574 QPopupMenu* QtxListAction::listPopup( QWidget* wid ) const
577 if ( myPopups.contains( wid ) )
578 p = myPopups[wid].popup;
583 Name: mainButton [private]
584 Desc: Returns main tool button for specified container.
587 QToolButton* QtxListAction::mainButton( QWidget* wid ) const
590 if ( myButtons.contains( wid ) )
591 mb = myButtons[wid].main;
596 Name: dropButton [private]
597 Desc: Returns drop tool button for specified container.
600 QToolButton* QtxListAction::dropButton( QWidget* wid ) const
603 if ( myButtons.contains( wid ) )
604 db = myButtons[wid].drop;
609 Name: controlDeleted [private]
610 Desc: Called when action child controls deleted.
613 void QtxListAction::controlDeleted( QWidget* wid )
616 for ( ButtonsMap::Iterator it = myButtons.begin(); it != myButtons.end() && !w; ++it )
618 if ( it.data().main == wid || it.data().drop == wid )
627 myButtons.remove( w );
633 Frame for the list of actions
635 class QtxListFrame::ScrollEvent : public QCustomEvent
638 enum { Scroll = User + 1 };
640 ScrollEvent( bool down ) : QCustomEvent( Scroll ), myDown( down ) {};
641 virtual ~ScrollEvent() {};
643 bool isDown() const { return myDown; };
657 QtxListFrame::QtxListFrame( QtxListAction* a, QWidget* parent, WFlags f )
658 : QFrame( parent, 0, WStyle_Customize | WStyle_NoBorderEx | WType_Popup | WStyle_Tool | WStyle_StaysOnTop ),
664 myMaxLineChars( 10 ),
666 myScrollBlock( false )
668 QVBoxLayout* theLayout = new QVBoxLayout( this, 3 );
669 theLayout->setResizeMode( QLayout::FreeResize );
671 myList = new QListBox( this );
672 myList->setSelectionMode( QListBox::Multi );
673 myList->setHScrollBarMode( QScrollView::AlwaysOff );
674 myList->setFocusPolicy( NoFocus );
676 QPalette p = myList->palette();
677 p.setColor( QPalette::Inactive, QColorGroup::Highlight,
678 p.color( QPalette::Active, QColorGroup::Highlight ) );
679 p.setColor( QPalette::Inactive, QColorGroup::HighlightedText,
680 p.color( QPalette::Active, QColorGroup::HighlightedText ) );
681 myList->setPalette( p );
683 /* We'll have the vertical scroll bar only and
684 truncate the names which are too wide */
685 connect( myList, SIGNAL( contentsMoving( int, int ) ), this, SLOT( onScroll( int, int ) ) );
687 myComment = new QLabel( this );
688 myComment->setFrameStyle( Panel | Sunken );
689 myComment->setAlignment( AlignCenter );
690 myMultipleComment = "%1";
692 theLayout->addWidget( myList );
693 theLayout->addWidget( myComment );
695 setFrameStyle( Panel | Raised );
701 QtxListFrame::~QtxListFrame()
704 myAction->myFrame = 0;
708 Clears list of names [ public ]
711 void QtxListFrame::clear()
718 Adds a names to the list. Truncates the name to fit to the frame width.
719 Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
722 void QtxListFrame::addNames( const QStringList& names )
724 for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
725 myNames.append( *it );
730 Sets a names to the list. Truncates the name to fit to the frame width.
731 Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
734 void QtxListFrame::setNames( const QStringList& names )
741 for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
744 QFontMetrics fm = myList->fontMetrics();
745 int maxW = myMaxLineChars * fm.maxWidth();
746 int w = fm.width( s );
749 QString extra( "..." );
750 int len = s.length();
751 int extraLen = fm.width( extra ) + 1;
754 w = fm.width( s, --len );
755 if ( w + extraLen < maxW )
763 myList->insertItem( s );
768 \return list of names
770 const QStringList QtxListFrame::names() const
776 Sets max number of lines shown without activation of vertical scroll bar. [ public ]
779 void QtxListFrame::setMaxLines( int maxLines )
781 myMaxLines = maxLines;
785 Sets max number of chars in line ( the rest will be truncated ). [ public ]
788 void QtxListFrame::setMaxLineChars( int maxChars )
790 if ( myMaxLineChars == maxChars )
793 myMaxLineChars = maxChars;
798 Sets the format of single comment. [ public ]
801 void QtxListFrame::setSingleComment( const QString& comment )
803 mySingleComment = comment;
809 Sets the format of multiple comment. [ public ]
812 void QtxListFrame::setMultipleComment( const QString& comment )
814 myMultipleComment = comment;
820 Updates comment display. [ public ]
823 void QtxListFrame::updateComment()
826 int selNum = selected();
828 com = myMultipleComment;
829 else if ( selNum > 0 && !mySingleComment.isEmpty() )
830 com = mySingleComment;
832 if ( !com.isEmpty() )
833 com = com.arg( selNum );
835 myComment->setText( com );
840 \param wo - new owner
842 void QtxListFrame::setOwner( QWidget* wo )
848 if ( myOwner->parentWidget() && myOwner->parentWidget()->inherits( "QToolBar" ) &&
849 ((QToolBar*)myOwner->parentWidget())->orientation() == Qt::Vertical )
850 lpos = QPoint( myOwner->x() + myOwner->width() + 2, myOwner->y() );
852 lpos = QPoint( myOwner->x(), myOwner->y() + myOwner->height() + 2 );
853 QPoint gpos = myOwner->parentWidget() ? myOwner->parentWidget()->mapToGlobal( lpos )
854 : myOwner->mapToGlobal( lpos );
855 if ( parentWidget() )
856 move( parentWidget()->mapFromGlobal( gpos ) );
863 Validates the action. [ private slot ]
866 void QtxListFrame::accept()
868 emit selected( selected() );
872 Cancels the action. [ private slot ]
875 void QtxListFrame::reject()
881 Initializes / shows the frame. [ virtual public slot ]
884 void QtxListFrame::show()
886 int cnt = (int)myList->count();
890 myList->setTopItem( 0 );
891 myList->clearSelection();
892 myList->setMinimumSize( 0, ( QMIN( cnt + 1, myMaxLines ) ) * myList->itemHeight() + 1 );
895 int linstep = myList->itemHeight();
896 myList->verticalScrollBar()->setLineStep( linstep );
897 myList->verticalScrollBar()->setPageStep( myMaxLines * linstep );
899 QFontMetrics fm = myList->fontMetrics();
900 layout()->invalidate();
901 int maxHeight = layout()->minimumSize().height() + layout()->margin();
902 int maxWidth = myMaxLineChars * fm.maxWidth();
903 for ( uint i = 0; i <= myList->count(); i++ )
904 maxWidth = QMAX( maxWidth, fm.width( myList->text( i ) ) );
906 resize( width(), maxHeight );
908 myList->updateGeometry();
910 QApplication::sendPostedEvents();
912 myList->resizeContents( myList->contentsWidth(),
913 myList->itemHeight() * cnt );
914 if ( myList->contentsHeight() > myList->visibleHeight() )
915 maxWidth += myList->verticalScrollBar()->width();
917 QString single = mySingleComment.arg( cnt );
918 QString multi = myMultipleComment.arg( cnt );
919 int comWidth = QMAX( myComment->fontMetrics().width( single ), myComment->fontMetrics().width( multi ) );
920 if ( myComment->frameWidth() )
921 comWidth += myComment->fontMetrics().width( "x" );
923 maxWidth = QMAX( maxWidth, comWidth );
925 resize( maxWidth, maxHeight );
928 qApp->installEventFilter( this );
935 Cleanup. [ virtual public slot ]
938 void QtxListFrame::hide()
940 qApp->removeEventFilter( this );
946 Processes KeyUp/KeyDown, PageUp/PageDown, CR and Esc keys.
947 Returns 'true' if event is eaten, 'false' otherwise. [ private ]
950 bool QtxListFrame::handleKeyEvent( QObject* , QKeyEvent* e )
952 if ( e->type() == QEvent::KeyRelease )
955 int selNum = selected();
959 setSelected( QMAX( 1, selNum - 1 ) );
962 setSelected( QMAX( 1, selNum + 1 ) );
965 setSelected( QMAX( 1, selNum - myMaxLines ) );
968 setSelected( selNum += myMaxLines );
974 setSelected( myList->count() );
987 Selects items on move, validates on button release. If object 'o' is not our name list,
988 we close the frame. Returns 'true' if event is eaten, 'false' otherwise. [ private ]
991 bool QtxListFrame::handleMouseEvent( QObject* o, QMouseEvent* e )
995 case QEvent::MouseButtonPress:
997 if ( o != myList->viewport() && !isPopup() )
1001 case QEvent::MouseMove:
1003 if ( o == myList->viewport() )
1005 QListBoxItem* lbi = myList->itemAt( e->pos() );
1007 setSelected( myList->index( lbi ) + 1 );
1011 case QEvent::MouseButtonRelease:
1013 if ( o == myList->viewport() )
1028 bool QtxListFrame::event( QEvent* e )
1030 if ( e->type() != (int)ScrollEvent::Scroll )
1031 return QFrame::event( e );
1033 ScrollEvent* se = (ScrollEvent*)e;
1035 setSelected( myList->topItem() + myList->numItemsVisible() );
1037 setSelected( myList->topItem() + 1 );
1043 Watches mouse events on the viewport of the list. [ virtual public ]
1046 bool QtxListFrame::eventFilter( QObject* o, QEvent* e )
1048 bool isKeyEvent = ( e->type() == QEvent::KeyPress ||
1049 e->type() == QEvent::KeyRelease );
1050 bool isMouseEvent = ( e->type() == QEvent::MouseMove ||
1051 e->type() == QEvent::MouseButtonPress ||
1052 e->type() == QEvent::MouseButtonRelease ||
1053 e->type() == QEvent::MouseButtonDblClick );
1057 if ( handleKeyEvent( o, ( QKeyEvent* )e ) )
1060 else if ( isMouseEvent && o != myList->verticalScrollBar() )
1062 if ( handleMouseEvent( o, ( QMouseEvent*)e ) )
1066 if ( o != this && ( e->type() == QEvent::Resize || e->type() == QEvent::Move ) )
1067 setOwner( myOwner );
1069 return QFrame::eventFilter( o, e );
1073 Selects operations while scrolling the list. [ private slot ]
1076 void QtxListFrame::onScroll( int x, int y )
1078 int dx = y - myScrollVal;
1079 if ( !myScrollBlock )
1080 QApplication::postEvent( this, new ScrollEvent( dx > 0 ) );
1085 Selects the actions [ 0 - lastSel ]. [ public ]
1088 void QtxListFrame::setSelected( const int lastSel )
1090 int last = QMIN( lastSel, (int)myList->count() );
1092 for ( int i = 0; i < (int)myList->count(); i++ )
1093 myList->setSelected( i, i < last );
1095 int item = last - 1;
1097 myScrollBlock = true;
1099 if ( item < myList->topItem() )
1100 myList->setTopItem( item );
1102 if ( item >= myList->topItem() + myList->numItemsVisible() )
1103 myList->setTopItem( item - myList->numItemsVisible() + 1 );
1105 myScrollBlock = false;
1107 myList->clearFocus();
1113 return number of selected items
1115 int QtxListFrame::selected() const
1118 while ( sel < myList->count() && myList->isSelected( sel ) )