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/ or email : webmaster.salome@opencascade.com
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;
155 Name: popupMode [public]
156 Desc: Returns popup mode. If popup mode "Item" (default) then action will
157 be added into popup menu as menu item. If popup mode "SubMenu" then
158 action will be added into popup menu as sub menu with list of items.
161 int QtxListAction::popupMode() const
167 Name: setPopupMode [public]
168 Desc: Set the popup mode. Popup mode define way in this action will be
169 added into popup menu. This function should be used before addTo.
172 void QtxListAction::setPopupMode( const int mode )
178 \return list of names
180 QStringList QtxListAction::names() const
184 lst = myFrame->names();
189 Name: addNames [public]
190 Desc: Fills the list of actions. Removes the old contents from
191 the list if 'clear' is true.
194 void QtxListAction::addNames( const QStringList& names, bool clear )
202 myFrame->addNames( names );
204 QStringList lst = myFrame->names();
205 for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
208 QPopupMenu* pm = (QPopupMenu*)pit.key();
209 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
210 pit.data().popup->insertItem( *it, i++ );
211 pm->setItemEnabled( pit.data().id, isEnabled() && pit.data().popup->count() );
214 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
216 bit.data().drop->setEnabled( isEnabled() && !lst.isEmpty() );
217 bit.data().main->setEnabled( isEnabled() && !lst.isEmpty() );
222 Name: addTo [virtual public]
223 Desc: Adds this control to 'popup' or 'toolbar'.
226 bool QtxListAction::addTo( QWidget* w )
228 if ( myButtons.contains( w ) || myPopups.contains( w ) )
231 if ( !w->inherits( "QPopupMenu" ) || popupMode() != SubMenu )
232 if ( !QtxAction::addTo( w ) )
237 addedTo( (QWidget*)w->children()->getLast(), w );
240 if ( w->inherits( "QToolBar" ) )
242 Buttons& entry = myButtons[w];
243 QHBox* dropWrap = new QHBox( w );
244 entry.drop = new ToolButton( this, dropWrap, "qt_dockwidget_internal" );
246 entry.drop->setTextLabel( text() );
247 entry.drop->setToggleButton( true );
248 entry.drop->setAutoRaise( entry.main->autoRaise() );
250 entry.main->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
251 entry.drop->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
253 entry.main->installEventFilter( this );
254 entry.drop->installEventFilter( this );
256 QToolTip::add( entry.drop, toolTip(), myTipGroup, statusTip() );
258 connect( entry.drop, SIGNAL( toggled( bool ) ), this, SLOT( onExpand( bool ) ) );
260 else if ( w->inherits( "QPopupMenu" ) && popupMode() == SubMenu )
263 QPopupMenu* pm = (QPopupMenu*)w;
265 entry.popup = new QPopupMenu( pm );
266 entry.id = pm->insertItem( text(), entry.popup );
269 QStringList lst = myFrame->names();
270 for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
272 int id = entry.popup->insertItem( *it );
273 entry.popup->setItemParameter( id, i++ );
275 pm->setItemEnabled( entry.id, isEnabled() && entry.popup->count() );
276 myPopups.insert( w, entry );
278 connect( entry.popup, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
282 connect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
289 Name: addTo [virtual public]
290 Desc: Adds this control to 'popup' or 'toolbar'. Allow to specify index
291 for adding into 'popup'.
294 bool QtxListAction::addTo( QWidget* w, const int idx )
296 return QtxAction::addTo( w, idx );
300 Name: removeFrom [virtual public]
301 Desc: Removes this control from 'popup' or 'toolbar'.
304 bool QtxListAction::removeFrom( QWidget* w )
306 if ( !QtxAction::removeFrom( w ) )
309 if ( w->inherits( "QToolBar" ) )
314 if ( myButtons.contains( w ) )
316 Buttons& entry = myButtons[w];
318 if ( entry.drop->parent() && entry.drop->parent()->parent() == w )
319 delete entry.drop->parent();
323 myButtons.remove( w );
325 else if ( w->inherits( "QPopupMenu" ) )
326 myPopups.remove( w );
329 disconnect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
336 Name: setEnabled [virtual public slot]
337 Desc: Enables/disables this control.
340 void QtxListAction::setEnabled( bool enable )
342 QtxAction::setEnabled( enable );
344 bool isOn = enable && !myFrame->names().isEmpty();
346 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
348 bit.data().drop->setEnabled( isOn );
349 bit.data().main->setEnabled( isOn );
352 for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
354 QPopupMenu* cont = (QPopupMenu*)pit.key();
355 cont->setItemEnabled( pit.data().id, isOn );
360 Name: setMaxLines [public]
361 Desc: Sets max number of lines that list frame shows
362 without vertical scroll bar. Default value is 5.
365 void QtxListAction::setMaxLines( int nlines )
367 myFrame->setMaxLines( nlines );
371 Name: setMaxLineChars [public]
372 Desc: Sets max number of characters in a line which list frame shows
373 without truncation. Default value is 12 (the widest char size is used).
376 void QtxListAction::setMaxLineChars( int nchars )
378 myFrame->setMaxLineChars( nchars );
382 Name: setComment [public]
383 Desc: Sets the format Qt string for comments displayed under the list
384 of actions for one action and for several actions.
385 Ex. "Undo %1 actions" format string will work as "Undo 3 actions"
386 when 3 actions are selected. The default format string is "%1".
389 void QtxListAction::setComment( const QString& c, const QString& sc )
394 myFrame->setSingleComment( sc.isEmpty() ? c : sc );
395 myFrame->setMultipleComment( c );
399 Name: eventFilter [virtual public]
400 Desc: Reimplemented to paint the tool buttons in 2D/3D.
403 bool QtxListAction::eventFilter( QObject* o, QEvent* e )
405 if ( !myRaise && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) )
408 QWidget* wid = widget( (QWidget*)o );
409 if ( o == mainButton( wid ) )
410 obj = dropButton( wid );
411 else if ( o == dropButton( wid ) )
412 obj = mainButton( wid );
417 QApplication::sendEvent( obj, e );
422 return QObject::eventFilter( o, e );
426 Name: addedTo [protected]
427 Desc: Reimplemented for internal reasons.
430 void QtxListAction::addedTo( QWidget* actionWidget, QWidget* container )
433 QtxAction::addedTo( actionWidget, container );
436 if ( !container->inherits( "QToolBar" ) )
440 entry.main = (QToolButton*)actionWidget;
442 myButtons.insert( container, entry );
446 Name: initialize [private]
447 Desc: Initialization of object QtxListAction.
450 void QtxListAction::initialize()
452 myTipGroup = new QToolTipGroup( this );
454 myFrame = new QtxListFrame( this, qApp->mainWidget() );
455 myFrame->setMaxLines( 5 );
456 myFrame->setMaxLineChars( 7 );
460 connect( myFrame, SIGNAL( hided() ), this, SLOT( onHided() ) );
461 connect( this, SIGNAL( activated() ), this, SLOT( onSingle() ) );
462 connect( myFrame, SIGNAL( selected( int ) ), this, SLOT( onMultiple( int ) ) );
464 connect( myTipGroup, SIGNAL( removeTip() ), this, SLOT( clearStatusText() ) );
465 connect( myTipGroup, SIGNAL( showTip( const QString& ) ), this, SLOT( showStatusText( const QString& ) ) );
469 Name: onSingle [private slot]
470 Desc: Called when a single action is selected.
473 void QtxListAction::onSingle()
479 Name: onMultiple [private slot]
480 Desc: Called when multiple actions are selected.
483 void QtxListAction::onMultiple( int numActions )
488 if ( numActions > 0 )
489 emit activated( numActions );
493 Name: onExpand [private slot]
494 Desc: Activates the list of actions.
497 void QtxListAction::onExpand( bool on )
499 const QObject* obj = sender();
502 QWidget* wid = widget( (QToolButton*)obj );
503 QToolButton* main = mainButton( wid );
504 myFrame->setOwner( main );
513 SLOT: called when frame is hidden
515 void QtxListAction::onHided()
517 for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
519 bool block = bit.data().drop->signalsBlocked();
520 bit.data().drop->blockSignals( true );
521 bit.data().drop->setOn( false );
522 bit.data().drop->blockSignals( block );
527 Name: onActivated [private slot]
528 Desc: Called when a sub menu item is activated.
531 void QtxListAction::onActivated( int id )
533 QPopupMenu* pm = (QPopupMenu*)sender();
534 int num = pm->itemParameter( id );
536 emit activated( num );
540 Name: onDestroyed [private slot]
541 Desc: Called when a container widget is destroyed.
544 void QtxListAction::onDestroyed( QObject* obj )
546 if ( !obj->isWidgetType() )
549 myPopups.remove( (QWidget*)obj );
550 myButtons.remove( (QWidget*)obj );
554 Name: widget [private]
555 Desc: Returns container widget for specified control.
558 QWidget* QtxListAction::widget( QWidget* obj ) const
561 for ( PopupsMap::ConstIterator pit = myPopups.begin(); pit != myPopups.end() && !wid; ++pit )
562 if ( pit.data().popup == obj )
565 for ( ButtonsMap::ConstIterator bit = myButtons.begin(); bit != myButtons.end() && !wid; ++bit )
566 if ( bit.data().main == obj || bit.data().drop == obj )
573 Name: listPopup [private]
574 Desc: Returns sub popup menu widget for specified container.
577 QPopupMenu* QtxListAction::listPopup( QWidget* wid ) const
580 if ( myPopups.contains( wid ) )
581 p = myPopups[wid].popup;
586 Name: mainButton [private]
587 Desc: Returns main tool button for specified container.
590 QToolButton* QtxListAction::mainButton( QWidget* wid ) const
593 if ( myButtons.contains( wid ) )
594 mb = myButtons[wid].main;
599 Name: dropButton [private]
600 Desc: Returns drop tool button for specified container.
603 QToolButton* QtxListAction::dropButton( QWidget* wid ) const
606 if ( myButtons.contains( wid ) )
607 db = myButtons[wid].drop;
612 Name: controlDeleted [private]
613 Desc: Called when action child controls deleted.
616 void QtxListAction::controlDeleted( QWidget* wid )
619 for ( ButtonsMap::Iterator it = myButtons.begin(); it != myButtons.end() && !w; ++it )
621 if ( it.data().main == wid || it.data().drop == wid )
630 myButtons.remove( w );
636 Frame for the list of actions
638 class QtxListFrame::ScrollEvent : public QCustomEvent
641 enum { Scroll = User + 1 };
643 ScrollEvent( bool down ) : QCustomEvent( Scroll ), myDown( down ) {};
644 virtual ~ScrollEvent() {};
646 bool isDown() const { return myDown; };
660 QtxListFrame::QtxListFrame( QtxListAction* a, QWidget* parent, WFlags f )
661 : QFrame( parent, 0, WStyle_Customize | WStyle_NoBorderEx | WType_Popup | WStyle_Tool | WStyle_StaysOnTop ),
667 myMaxLineChars( 10 ),
669 myScrollBlock( false )
671 QVBoxLayout* theLayout = new QVBoxLayout( this, 3 );
672 theLayout->setResizeMode( QLayout::FreeResize );
674 myList = new QListBox( this );
675 myList->setSelectionMode( QListBox::Multi );
676 myList->setHScrollBarMode( QScrollView::AlwaysOff );
677 myList->setFocusPolicy( NoFocus );
679 QPalette p = myList->palette();
680 p.setColor( QPalette::Inactive, QColorGroup::Highlight,
681 p.color( QPalette::Active, QColorGroup::Highlight ) );
682 p.setColor( QPalette::Inactive, QColorGroup::HighlightedText,
683 p.color( QPalette::Active, QColorGroup::HighlightedText ) );
684 myList->setPalette( p );
686 /* We'll have the vertical scroll bar only and
687 truncate the names which are too wide */
688 connect( myList, SIGNAL( contentsMoving( int, int ) ), this, SLOT( onScroll( int, int ) ) );
690 myComment = new QLabel( this );
691 myComment->setFrameStyle( Panel | Sunken );
692 myComment->setAlignment( AlignCenter );
693 myMultipleComment = "%1";
695 theLayout->addWidget( myList );
696 theLayout->addWidget( myComment );
698 setFrameStyle( Panel | Raised );
704 QtxListFrame::~QtxListFrame()
707 myAction->myFrame = 0;
711 Clears list of names [ public ]
714 void QtxListFrame::clear()
721 Adds a names to the list. Truncates the name to fit to the frame width.
722 Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
725 void QtxListFrame::addNames( const QStringList& names )
727 for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
728 myNames.append( *it );
733 Sets a names to the list. Truncates the name to fit to the frame width.
734 Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
737 void QtxListFrame::setNames( const QStringList& names )
744 for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
747 QFontMetrics fm = myList->fontMetrics();
748 int maxW = myMaxLineChars * fm.maxWidth();
749 int w = fm.width( s );
752 QString extra( "..." );
753 int len = s.length();
754 int extraLen = fm.width( extra ) + 1;
757 w = fm.width( s, --len );
758 if ( w + extraLen < maxW )
766 myList->insertItem( s );
771 \return list of names
773 const QStringList QtxListFrame::names() const
779 Sets max number of lines shown without activation of vertical scroll bar. [ public ]
782 void QtxListFrame::setMaxLines( int maxLines )
784 myMaxLines = maxLines;
788 Sets max number of chars in line ( the rest will be truncated ). [ public ]
791 void QtxListFrame::setMaxLineChars( int maxChars )
793 if ( myMaxLineChars == maxChars )
796 myMaxLineChars = maxChars;
801 Sets the format of single comment. [ public ]
804 void QtxListFrame::setSingleComment( const QString& comment )
806 mySingleComment = comment;
812 Sets the format of multiple comment. [ public ]
815 void QtxListFrame::setMultipleComment( const QString& comment )
817 myMultipleComment = comment;
823 Updates comment display. [ public ]
826 void QtxListFrame::updateComment()
829 int selNum = selected();
831 com = myMultipleComment;
832 else if ( selNum > 0 && !mySingleComment.isEmpty() )
833 com = mySingleComment;
835 if ( !com.isEmpty() )
836 com = com.arg( selNum );
838 myComment->setText( com );
843 \param wo - new owner
845 void QtxListFrame::setOwner( QWidget* wo )
851 if ( myOwner->parentWidget() && myOwner->parentWidget()->inherits( "QToolBar" ) &&
852 ((QToolBar*)myOwner->parentWidget())->orientation() == Qt::Vertical )
853 lpos = QPoint( myOwner->x() + myOwner->width() + 2, myOwner->y() );
855 lpos = QPoint( myOwner->x(), myOwner->y() + myOwner->height() + 2 );
856 QPoint gpos = myOwner->parentWidget() ? myOwner->parentWidget()->mapToGlobal( lpos )
857 : myOwner->mapToGlobal( lpos );
858 if ( parentWidget() )
859 move( parentWidget()->mapFromGlobal( gpos ) );
866 Validates the action. [ private slot ]
869 void QtxListFrame::accept()
871 emit selected( selected() );
875 Cancels the action. [ private slot ]
878 void QtxListFrame::reject()
884 Initializes / shows the frame. [ virtual public slot ]
887 void QtxListFrame::show()
889 int cnt = (int)myList->count();
893 myList->setTopItem( 0 );
894 myList->clearSelection();
895 myList->setMinimumSize( 0, ( QMIN( cnt + 1, myMaxLines ) ) * myList->itemHeight() + 1 );
898 int linstep = myList->itemHeight();
899 myList->verticalScrollBar()->setLineStep( linstep );
900 myList->verticalScrollBar()->setPageStep( myMaxLines * linstep );
902 QFontMetrics fm = myList->fontMetrics();
903 layout()->invalidate();
904 int maxHeight = layout()->minimumSize().height() + layout()->margin();
905 int maxWidth = myMaxLineChars * fm.maxWidth();
906 for ( uint i = 0; i <= myList->count(); i++ )
907 maxWidth = QMAX( maxWidth, fm.width( myList->text( i ) ) );
909 resize( width(), maxHeight );
911 myList->updateGeometry();
913 QApplication::sendPostedEvents();
915 myList->resizeContents( myList->contentsWidth(),
916 myList->itemHeight() * cnt );
917 if ( myList->contentsHeight() > myList->visibleHeight() )
918 maxWidth += myList->verticalScrollBar()->width();
920 QString single = mySingleComment.arg( cnt );
921 QString multi = myMultipleComment.arg( cnt );
922 int comWidth = QMAX( myComment->fontMetrics().width( single ), myComment->fontMetrics().width( multi ) );
923 if ( myComment->frameWidth() )
924 comWidth += myComment->fontMetrics().width( "x" );
926 maxWidth = QMAX( maxWidth, comWidth );
928 resize( maxWidth, maxHeight );
931 qApp->installEventFilter( this );
938 Cleanup. [ virtual public slot ]
941 void QtxListFrame::hide()
943 qApp->removeEventFilter( this );
949 Processes KeyUp/KeyDown, PageUp/PageDown, CR and Esc keys.
950 Returns 'true' if event is eaten, 'false' otherwise. [ private ]
953 bool QtxListFrame::handleKeyEvent( QObject* , QKeyEvent* e )
955 if ( e->type() == QEvent::KeyRelease )
958 int selNum = selected();
962 setSelected( QMAX( 1, selNum - 1 ) );
965 setSelected( QMAX( 1, selNum + 1 ) );
968 setSelected( QMAX( 1, selNum - myMaxLines ) );
971 setSelected( selNum += myMaxLines );
977 setSelected( myList->count() );
990 Selects items on move, validates on button release. If object 'o' is not our name list,
991 we close the frame. Returns 'true' if event is eaten, 'false' otherwise. [ private ]
994 bool QtxListFrame::handleMouseEvent( QObject* o, QMouseEvent* e )
998 case QEvent::MouseButtonPress:
1000 if ( o != myList->viewport() && !isPopup() )
1004 case QEvent::MouseMove:
1006 if ( o == myList->viewport() )
1008 QListBoxItem* lbi = myList->itemAt( e->pos() );
1010 setSelected( myList->index( lbi ) + 1 );
1014 case QEvent::MouseButtonRelease:
1016 if ( o == myList->viewport() )
1031 bool QtxListFrame::event( QEvent* e )
1033 if ( e->type() != (int)ScrollEvent::Scroll )
1034 return QFrame::event( e );
1036 ScrollEvent* se = (ScrollEvent*)e;
1038 setSelected( myList->topItem() + myList->numItemsVisible() );
1040 setSelected( myList->topItem() + 1 );
1046 Watches mouse events on the viewport of the list. [ virtual public ]
1049 bool QtxListFrame::eventFilter( QObject* o, QEvent* e )
1051 bool isKeyEvent = ( e->type() == QEvent::KeyPress ||
1052 e->type() == QEvent::KeyRelease );
1053 bool isMouseEvent = ( e->type() == QEvent::MouseMove ||
1054 e->type() == QEvent::MouseButtonPress ||
1055 e->type() == QEvent::MouseButtonRelease ||
1056 e->type() == QEvent::MouseButtonDblClick );
1060 if ( handleKeyEvent( o, ( QKeyEvent* )e ) )
1063 else if ( isMouseEvent && o != myList->verticalScrollBar() )
1065 if ( handleMouseEvent( o, ( QMouseEvent*)e ) )
1069 if ( o != this && ( e->type() == QEvent::Resize || e->type() == QEvent::Move ) )
1070 setOwner( myOwner );
1072 return QFrame::eventFilter( o, e );
1076 Selects operations while scrolling the list. [ private slot ]
1079 void QtxListFrame::onScroll( int x, int y )
1081 int dx = y - myScrollVal;
1082 if ( !myScrollBlock )
1083 QApplication::postEvent( this, new ScrollEvent( dx > 0 ) );
1088 Selects the actions [ 0 - lastSel ]. [ public ]
1091 void QtxListFrame::setSelected( const int lastSel )
1093 int last = QMIN( lastSel, (int)myList->count() );
1095 for ( int i = 0; i < (int)myList->count(); i++ )
1096 myList->setSelected( i, i < last );
1098 int item = last - 1;
1100 myScrollBlock = true;
1102 if ( item < myList->topItem() )
1103 myList->setTopItem( item );
1105 if ( item >= myList->topItem() + myList->numItemsVisible() )
1106 myList->setTopItem( item - myList->numItemsVisible() + 1 );
1108 myScrollBlock = false;
1110 myList->clearFocus();
1116 return number of selected items
1118 int QtxListFrame::selected() const
1121 while ( sel < myList->count() && myList->isSelected( sel ) )