]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
no message
authorstv <stv@opencascade.com>
Wed, 23 May 2007 12:11:41 +0000 (12:11 +0000)
committerstv <stv@opencascade.com>
Wed, 23 May 2007 12:11:41 +0000 (12:11 +0000)
src/Qtx/QtxListAction.cxx
src/Qtx/QtxListAction.h

index 891f64e608affc5f78b1b6f6f5acc06294f85d31..88f26c54495e443d090525e4913a61d425e63508 100755 (executable)
 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-// 
+//
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
+// License as published by the Free Software Foundation; either
 // version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 // File:      QtxListAction.cxx
-// Author:    Sergey TELKOV (Based on code by Eugene AKSENOV)
+// Author:    Sergey TELKOV
 
 #include "QtxListAction.h"
 
-#include <qvbox.h>
-#include <qlabel.h>
-#include <qlayout.h>
-#include <qtooltip.h>
-#include <qlistbox.h>
-#include <qtoolbar.h>
-#include <qwmatrix.h>
-#include <qpopupmenu.h>
-#include <qtoolbutton.h>
-#include <qobjectlist.h>
-#include <qapplication.h>
-
-static const char* list_arrow_icon[] = {
-"10 6 2 1",
-"# c #000000",
-"  c none",
-"          ",
-" #######  ",
-"  #####   ",
-"   ###    ",
-"    #     ",
-"          "
-};
+#include <QMenu>
+#include <QLabel>
+#include <QLayout>
+#include <QToolTip>
+#include <QToolbar>
+#include <QWMatrix>
+#include <QMouseEvent>
+#include <QListWidget>
+#include <QToolButton>
+#include <QObjectList>
+#include <QApplication>
 
 /*!
-  \class QtxListAction::ToolButton
-  Custom tool button
+  \class QtxListAction::ScrollEvent
+  Event for the scrolling in the list of actions
 */
-class QtxListAction::ToolButton : public QToolButton
+class QtxListAction::ScrollEvent : public QEvent
 {
 public:
-  ToolButton( QtxListAction*, QWidget* = 0, const char* = 0 );
-  virtual ~ToolButton();
+  enum { Scroll = User + 1 };
 
-  virtual QSize sizeHint() const;
+  ScrollEvent( bool down ) : QEvent( (QEvent::Type)Scroll ), myDown( down ) {}
+  virtual ~ScrollEvent() {}
+
+  bool isDown() const { return myDown; }
 
 private:
-  QtxListAction* myAction;
+  bool myDown;
 };
 
 /*!
-  Constructor
-*/
-QtxListAction::ToolButton::ToolButton( QtxListAction* a, QWidget* parent, const char* name )
-: QToolButton( parent, name ),
-myAction( a )
-{
-  setIconSet( QPixmap( list_arrow_icon ) );
-}
-
-/*!
-  Destructor
-*/
-QtxListAction::ToolButton::~ToolButton()
-{
-  if ( myAction )
-    myAction->controlDeleted( this );
-}
-
-/*!
-  \return the recommended size for the widget
-*/
-QSize QtxListAction::ToolButton::sizeHint() const
-{
-  QSize sz = iconSet().pixmap().size();
-  return QSize( sz.width() + 2, sz.height() + 2 );
-}
-
-/*!
-  Constructs an list action with given parent and name. If toggle is true the
-  action will be a toggle action, otherwise it will be a command action.
-*/
-QtxListAction::QtxListAction( QObject* parent, const char* name, bool toggle )
-: QtxAction( parent, name, toggle ),
-myFrame( 0 ),
-myMode( Item ),
-myRaise( false )
-{
-  initialize();
-}
-
-/*!
-  This constructor creates an action with the following properties: the
-  description text, the icon or iconset icon, the menu text and keyboard
-  accelerator. It is a child of given parent and named specified name.
-  If toggle is true the action will be a toggle action, otherwise it will
-  be a command action.
-*/
-
-QtxListAction::QtxListAction( const QString& text, const QIconSet& icon,
-                              const QString& menuText, int accel,
-                              QObject* parent, const char* name, bool toggle )
-: QtxAction( text, icon, menuText, accel, parent, name, toggle ),
-myFrame( 0 ),
-myMode( Item ),
-myRaise( false )
-{
-  initialize();
-}
-
-/*!
-  This constructor creates an action with the following properties: the
-  description text, the menu text and keyboard accelerator. It is a child
-  of given parent and named specified name. If toggle is true the action
-  will be a toggle action, otherwise it will be a command action.
-*/
-
-QtxListAction::QtxListAction( const QString& text, const QString& menuText,
-                              int accel, QObject* parent, const char* name, bool toggle )
-: QtxAction( text, menuText, accel, parent, name, toggle ),
-myFrame( 0 ),
-myMode( Item ),
-myRaise( false )
-{
-  initialize();
-}
-
-/*!
-  Destructor.
-*/
-
-QtxListAction::~QtxListAction()
-{
-  if ( myFrame ) {
-    myFrame->myAction = 0;
-    delete myFrame;
-    myFrame = 0;
-  }
-}
-
-/*!
-       Name: popupMode [public]
-       Desc: Returns popup mode. If popup mode "Item" (default) then action will
-             be added into popup menu as menu item. If popup mode "SubMenu" then
-                   action will be added into popup menu as sub menu with list of items.
-*/
-
-int QtxListAction::popupMode() const
-{
-  return myMode;
-}
-
-/*!
-       Name: setPopupMode [public]
-       Desc: Set the popup mode. Popup mode define way in this action will be
-             added into popup menu. This function should be used before addTo.
-*/
-
-void QtxListAction::setPopupMode( const int mode )
-{
-  myMode = mode;
-}
-
-/*!
-  \return list of names
-*/
-QStringList QtxListAction::names() const
-{
-  QStringList lst;
-  if ( myFrame )
-    lst = myFrame->names();
-  return lst;
-}
-
-/*!
-       Name: addNames [public]
-       Desc: Fills the list of actions. Removes the old contents from
-             the list if 'clear' is true.
-*/
-
-void QtxListAction::addNames( const QStringList& names, bool clear )
-{
-  if ( !myFrame )
-    return;
-
-  if ( clear )
-    myFrame->clear();
-
-       myFrame->addNames( names );
-
-       QStringList lst = myFrame->names();
-       for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
-       {
-               int i = 1;
-               QPopupMenu* pm = (QPopupMenu*)pit.key();
-               for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
-                       pit.data().popup->insertItem( *it, i++ );
-               pm->setItemEnabled( pit.data().id, isEnabled() && pit.data().popup->count() );
-  }
-
-       for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
-       {
-               bit.data().drop->setEnabled( isEnabled() && !lst.isEmpty() );
-               bit.data().main->setEnabled( isEnabled() && !lst.isEmpty() );
-       }
-}
-
-/*!
-       Name: addTo [virtual public]
-       Desc: Adds this control to 'popup' or 'toolbar'.
-*/
-
-bool QtxListAction::addTo( QWidget* w )
-{
-       if ( myButtons.contains( w ) || myPopups.contains( w ) )
-               return false;
-
-       if ( !w->inherits( "QPopupMenu" ) || popupMode() != SubMenu )
-               if ( !QtxAction::addTo( w ) )
-                       return false;
-
-  if ( w->inherits( "QToolBar" ) )
-  {
-               Buttons& entry = myButtons[w];
-               QHBox* dropWrap = new QHBox( w );
-    entry.drop = new ToolButton( this, dropWrap, "qt_dockwidget_internal" );
-
-    entry.drop->setTextLabel( text() );
-    entry.drop->setToggleButton( true );
-    entry.drop->setAutoRaise( entry.main->autoRaise() );
-
-    entry.main->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
-    entry.drop->setEnabled( isEnabled() && !myFrame->names().isEmpty() );
-
-               entry.main->installEventFilter( this );
-    entry.drop->installEventFilter( this );
-
-               QToolTip::add( entry.drop, toolTip(), myTipGroup, statusTip() );
-
-    connect( entry.drop, SIGNAL( toggled( bool ) ), this, SLOT( onExpand( bool ) ) );
-  }
-       else if ( w->inherits( "QPopupMenu" ) && popupMode() == SubMenu )
-       {
-               Popups entry;
-               QPopupMenu* pm = (QPopupMenu*)w;
-
-               entry.popup = new QPopupMenu( pm );
-               entry.id = pm->insertItem( text(), entry.popup );
-
-               int i = 1;
-               QStringList lst = myFrame->names();
-               for ( QStringList::ConstIterator it = lst.begin(); it != lst.end(); ++it )
-               {
-                       int id = entry.popup->insertItem( *it );
-                       entry.popup->setItemParameter( id, i++ );
-               }
-               pm->setItemEnabled( entry.id, isEnabled() && entry.popup->count() );
-               myPopups.insert( w, entry );
-
-               connect( entry.popup, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
-       }
-
-    connect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
-
-    return true;
-}
-
-/*!
-       Name: addTo [virtual public]
-       Desc: Adds this control to 'popup' or 'toolbar'. Allow to specify index
-             for adding into 'popup'.
-*/
-
-bool QtxListAction::addTo( QWidget* w, const int idx )
-{
-  return QtxAction::addTo( w, idx );
-}
-
-/*!
-       Name: removeFrom [virtual public]
-       Desc: Removes this control from 'popup' or 'toolbar'.
-*/
-
-bool QtxListAction::removeFrom( QWidget* w )
-{
-  if ( !QtxAction::removeFrom( w ) )
-    return false;
-
-  if ( w->inherits( "QToolBar" ) )
-  {
-    if ( myFrame )
-      myFrame->hide();
-
-    if ( myButtons.contains( w ) )
-    {
-      Buttons& entry = myButtons[w];
-
-      if ( entry.drop->parent() && entry.drop->parent()->parent() == w )
-        delete entry.drop->parent();
-      else
-        delete entry.drop;
-    }
-    myButtons.remove( w );
-  }
-  else if ( w->inherits( "QPopupMenu" ) )
-    myPopups.remove( w );
-
-  disconnect( w, SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
-
-  return true;
-}
-
-/*!
-       Name: setEnabled [virtual public slot]
-       Desc: Enables/disables this control.
-*/
-
-void QtxListAction::setEnabled( bool enable )
-{
-  QtxAction::setEnabled( enable );
-
-       bool isOn = enable && !myFrame->names().isEmpty();
-
-       for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
-       {
-               bit.data().drop->setEnabled( isOn );
-               bit.data().main->setEnabled( isOn );
-       }
-
-       for ( PopupsMap::Iterator pit = myPopups.begin(); pit != myPopups.end(); ++pit )
-       {
-               QPopupMenu* cont = (QPopupMenu*)pit.key();
-               cont->setItemEnabled( pit.data().id, isOn );
-  }
-}
-
-/*!
-       Name: setMaxLines [public]
-       Desc: Sets max number of lines that list frame shows
-                 without vertical scroll bar. Default value is 5.
-*/
-
-void QtxListAction::setMaxLines( int nlines )
-{
-  myFrame->setMaxLines( nlines );
-}
-
-/*!
-       Name: setMaxLineChars [public]
-       Desc: Sets max number of characters in a line which list frame shows
-             without truncation. Default value is 12 (the widest char size is used).
-*/
-
-void QtxListAction::setMaxLineChars( int nchars )
-{
-  myFrame->setMaxLineChars( nchars );
-}
-
-/*!
-       Name: setComment [public]
-       Desc: Sets the format Qt string for comments displayed under the list
-             of actions for one action and for several actions.
-                   Ex. "Undo %1 actions" format string will work as "Undo 3 actions"
-                   when 3 actions are selected. The default format string is "%1".
-*/
-
-void QtxListAction::setComment( const QString& c, const QString& sc )
-{
-  if ( !myFrame )
-    return;
-
-  myFrame->setSingleComment( sc.isEmpty() ? c : sc );
-       myFrame->setMultipleComment( c );
-}
-
-/*!
-       Name: eventFilter [virtual public]
-       Desc: Reimplemented to paint the tool buttons in 2D/3D.
-*/
-
-bool QtxListAction::eventFilter( QObject* o, QEvent* e )
-{
-  if ( !myRaise && ( e->type() == QEvent::Enter || e->type() == QEvent::Leave ) )
-  {
-               QWidget* obj = 0;
-               QWidget* wid = widget( (QWidget*)o );
-               if ( o == mainButton( wid ) )
-                       obj = dropButton( wid );
-               else if ( o == dropButton( wid ) )
-                       obj = mainButton( wid );
-
-               if ( obj )
-               {
-                       myRaise = true;
-                       QApplication::sendEvent( obj, e );
-            obj->repaint();
-                       myRaise = false;
-               }
-  }
-  return QObject::eventFilter( o, e );
-}
-
-/*!
-       Name: addedTo [protected]
-       Desc: Reimplemented for internal reasons.
-*/
-
-void QtxListAction::addedTo( QWidget* actionWidget, QWidget* container )
-{
-       QtxAction::addedTo( actionWidget, container );
-
-       if ( !container->inherits( "QToolBar" ) )
-               return;
-
-       Buttons entry;
-       entry.main = (QToolButton*)actionWidget;
-
-       myButtons.insert( container, entry );
-}
-
-/*!
-       Name: initialize [private]
-       Desc: Initialization of object QtxListAction.
-*/
-
-void QtxListAction::initialize()
-{
-       myTipGroup = new QToolTipGroup( this );
-
-       myFrame = new QtxListFrame( this, qApp->mainWidget() );
-  myFrame->setMaxLines( 5 );
-  myFrame->setMaxLineChars( 7 );
-
-       myFrame->hide();
-
-       connect( myFrame, SIGNAL( hided() ), this, SLOT( onHided() ) );
-  connect( this, SIGNAL( activated() ), this, SLOT( onSingle() ) );
-       connect( myFrame, SIGNAL( selected( int ) ), this, SLOT( onMultiple( int ) ) );
-
-       connect( myTipGroup, SIGNAL( removeTip() ), this, SLOT( clearStatusText() ) );
-       connect( myTipGroup, SIGNAL( showTip( const QString& ) ), this, SLOT( showStatusText( const QString& ) ) );
-}
-
-/*!
-       Name: onSingle [private slot]
-       Desc: Called when a single action is selected.
+  \class QtxListAction::ListWidget
+  List of actions
 */
-
-void QtxListAction::onSingle()
+class QtxListAction::ListWidget : public QListWidget
 {
-  emit activated( 1 );
-}
-
-/*!
-       Name: onMultiple [private slot]
-       Desc: Called when multiple actions are selected.
-*/
-
-void QtxListAction::onMultiple( int numActions )
-{
-  if ( myFrame )
-    myFrame->hide();
-
-  if ( numActions > 0 )
-    emit activated( numActions );
-}
-
-/*!
-       Name: onExpand [private slot]
-       Desc: Activates the list of actions.
-*/
+public:
+  ListWidget( QWidget* parent = 0 ) : QListWidget( parent ) {}
+  virtual ~ListWidget() {}
 
-void QtxListAction::onExpand( bool on )
-{
-       const QObject* obj = sender();
-  if ( on )
+protected:
+  virtual void scrollContentsBy( int dx, int dy )
   {
-    QWidget* wid = widget( (QToolButton*)obj );
-               QToolButton* main = mainButton( wid );
-    myFrame->setOwner( main );
-               if ( main )
-                       myFrame->show();
+    QListWidget::scrollContentsBy( dx, dy );
+    if ( dy != 0 )
+      QApplication::postEvent( viewport(), new ScrollEvent( dy <= 0 ) );
   }
-  else
-    myFrame->hide();
-}
-
-/*!
-  SLOT: called when frame is hidden
-*/
-void QtxListAction::onHided()
-{
-  for ( ButtonsMap::Iterator bit = myButtons.begin(); bit != myButtons.end(); ++bit )
-       {
-    bool block = bit.data().drop->signalsBlocked();
-    bit.data().drop->blockSignals( true );
-    bit.data().drop->setOn( false );
-    bit.data().drop->blockSignals( block );
-  }
-}
-
-/*!
-       Name: onActivated [private slot]
-       Desc: Called when a sub menu item is activated.
-*/
-
-void QtxListAction::onActivated( int id )
-{
-       QPopupMenu* pm = (QPopupMenu*)sender();
-       int num = pm->itemParameter( id );
-       if ( num > 0 )
-               emit activated( num );
-}
-
-/*!
-       Name: onDestroyed [private slot]
-       Desc: Called when a container widget is destroyed.
-*/
-
-void QtxListAction::onDestroyed( QObject* obj )
-{
-       if ( !obj->isWidgetType() )
-               return;
-
-       myPopups.remove( (QWidget*)obj );
-       myButtons.remove( (QWidget*)obj );
-}
+};
 
 /*!
-       Name: widget [private]
-       Desc: Returns container widget for specified control.
+  \class QtxListAction::ListFrame
+  Expanding frame with action list and comment
 */
-
-QWidget* QtxListAction::widget( QWidget* obj ) const
+class QtxListAction::ListFrame: public QMenu
 {
-       QWidget* wid = 0;
-       for ( PopupsMap::ConstIterator pit = myPopups.begin(); pit != myPopups.end() && !wid; ++pit )
-               if ( pit.data().popup == obj )
-                       wid = pit.key();
-
-       for ( ButtonsMap::ConstIterator bit = myButtons.begin(); bit != myButtons.end() && !wid; ++bit )
-               if ( bit.data().main == obj || bit.data().drop == obj )
-                       wid = bit.key();
-
-       return wid;
-}
-
-/*!
-       Name: listPopup [private]
-       Desc: Returns sub popup menu widget for specified container.
-*/
+public:
+  ListFrame( QtxListAction*, QWidget* parent );
+  virtual ~ListFrame();
 
-QPopupMenu* QtxListAction::listPopup( QWidget* wid ) const
-{
-       QPopupMenu* p = 0;
-       if ( myPopups.contains( wid ) )
-               p = myPopups[wid].popup;
-       return p;
-}
+  void                    clear();
+  const QStringList       names() const;
+  void                    addNames( const QStringList& );
 
-/*!
-       Name: mainButton [private]
-       Desc: Returns main tool button for specified container.
-*/
+  void                    setSingleComment( const QString& );
+  void                    setMultipleComment( const QString& );
 
-QToolButton* QtxListAction::mainButton( QWidget* wid ) const
-{
-       QToolButton* mb = 0;
-       if ( myButtons.contains( wid ) )
-               mb = myButtons[wid].main;
-       return mb;
-}
+  int                     selected() const;
+  void                    setSelected( const int );
 
-/*!
-       Name: dropButton [private]
-       Desc: Returns drop tool button for specified container.
-*/
+  int                     linesNumber() const;
+  int                     charsNumber() const;
 
-QToolButton* QtxListAction::dropButton( QWidget* wid ) const
-{
-       QToolButton* db = 0;
-       if ( myButtons.contains( wid ) )
-               db = myButtons[wid].drop;
-       return db;
-}
+  void                    setLinesNumber( const int );
+  void                    setCharsNumber( const int );
 
-/*!
-       Name: controlDeleted [private]
-       Desc: Called when action child controls deleted.
-*/
+  virtual QSize           sizeHint() const;
+  virtual QSize           minimumSizeHint() const;
 
-void QtxListAction::controlDeleted( QWidget* wid )
-{
-  QWidget* w = 0;
-  for ( ButtonsMap::Iterator it = myButtons.begin(); it != myButtons.end() && !w; ++it )
-  {
-    if ( it.data().main == wid || it.data().drop == wid )
-      w = it.key();
-  }
+  virtual bool            eventFilter( QObject*, QEvent* );
 
-  if ( w )
-  {
-    if ( myFrame )
-      myFrame->hide();
+  virtual void            setVisible( bool );
 
-    myButtons.remove( w );
-  }
-}
+protected:
+  virtual void            keyPressEvent( QKeyEvent* );
 
-/*!
-  \class QtxListFrame
-  Frame for the list of actions
-*/
-class QtxListFrame::ScrollEvent : public QCustomEvent
-{
-public:
-       enum { Scroll = User + 1 };
+private:
+  void                    accept();
+  void                    updateComment();
+  void                    setNames( const QStringList& );
+  void                    removePostedEvens( QObject*, int );
 
-       ScrollEvent( bool down ) : QCustomEvent( Scroll ), myDown( down ) {};
-       virtual ~ScrollEvent() {};
+private:
+  QListWidget*            myList;
+  QStringList             myNames;
+  QtxListAction*          myAction;
+  QLabel*                 myComment;
 
-       bool isDown() const { return myDown; };
+  int                     myLines;
+  int                     myChars;
 
-private:
-       bool myDown;
+  QString                 mySingleComment;
+  QString                 myMultipleComment;
 };
 
 /*!
-       Class: QtxListAction
-       Level: Public
-*/
-
-/*!
-    Constructor
+  Constructor
 */
-QtxListFrame::QtxListFrame( QtxListAction* a, QWidget* parent, WFlags f )
-: QFrame( parent, 0, WStyle_Customize | WStyle_NoBorderEx | WType_Popup | WStyle_Tool | WStyle_StaysOnTop ),
+QtxListAction::ListFrame::ListFrame( QtxListAction* a, QWidget* parent )
+: QMenu( parent ),
 myList( 0 ),
-myOwner( 0 ),
+myLines( 5 ),
+myChars( 5 ),
 myAction( a ),
-myComment( 0 ),
-myMaxLines( 5 ),
-myMaxLineChars( 10 ),
-myScrollVal( 0 ),
-myScrollBlock( false )
-{
-  QVBoxLayout* theLayout = new QVBoxLayout( this, 3 );
-       theLayout->setResizeMode( QLayout::FreeResize );
-
-  myList = new QListBox( this );
-  myList->setSelectionMode( QListBox::Multi );
-  myList->setHScrollBarMode( QScrollView::AlwaysOff );
-       myList->setFocusPolicy( NoFocus );
-
-       QPalette p = myList->palette();
-       p.setColor( QPalette::Inactive, QColorGroup::Highlight,
-                                     p.color( QPalette::Active, QColorGroup::Highlight ) );
-       p.setColor( QPalette::Inactive, QColorGroup::HighlightedText,
-                                     p.color( QPalette::Active, QColorGroup::HighlightedText ) );
-       myList->setPalette( p );
-
-  /*  We'll have the vertical scroll bar only and
-      truncate the names which are too wide */
-  connect( myList, SIGNAL( contentsMoving( int, int ) ), this, SLOT( onScroll( int, int ) ) );
-
-  myComment = new QLabel( this );
-  myComment->setFrameStyle( Panel | Sunken );
-  myComment->setAlignment( AlignCenter );
+myComment( 0 )
+{
+  QVBoxLayout* top = new QVBoxLayout( this );
+  top->setMargin( 0 );
+  QFrame* main = new QFrame( this );
+  main->setFrameStyle( QFrame::Panel | QFrame::Raised );
+  top->addWidget( main );
+
+  QVBoxLayout* base = new QVBoxLayout( main );
+  base->setMargin( 3 );
+  base->setSpacing( 2 );
+
+  myList = new ListWidget( main );
+  myList->setSelectionMode( QListWidget::MultiSelection );
+  myList->setVerticalScrollMode( QListWidget::ScrollPerItem );
+  myList->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded );
+  myList->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
+  myList->viewport()->installEventFilter( this );
+  myList->viewport()->setMouseTracking( true );
+  myList->setFocusPolicy( Qt::NoFocus );
+
+  myComment = new QLabel( main );
+  myComment->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+  myComment->setAlignment( Qt::AlignCenter );
   myMultipleComment = "%1";
 
-  theLayout->addWidget( myList );
-  theLayout->addWidget( myComment );
-
-  setFrameStyle( Panel | Raised );
+  base->addWidget( myList );
+  base->addWidget( myComment );
 }
 
 /*!
   Destructor
 */
-QtxListFrame::~QtxListFrame()
+QtxListAction::ListFrame::~ListFrame()
 {
-  if ( myAction )
-    myAction->myFrame = 0;
 }
 
 /*!
-    Clears list of names [ public ]
+  Clears list of names [ public ]
 */
-
-void QtxListFrame::clear()
+void QtxListAction::ListFrame::clear()
 {
        myNames.clear();
        setNames( myNames );
 }
 
 /*!
-    Adds a names to the list. Truncates the name to fit to the frame width.
-    Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
+  Adds a names to the list. Truncates the name to fit to the frame width.
+  Use QtxListAction::setCharsNumber( int ) to set the width in characters. [ public ]
 */
-  
-void QtxListFrame::addNames( const QStringList& names )
+void QtxListAction::ListFrame::addNames( const QStringList& names )
 {
        for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
                myNames.append( *it );
@@ -719,22 +192,21 @@ void QtxListFrame::addNames( const QStringList& names )
 }
 
 /*!
-    Sets a names to the list. Truncates the name to fit to the frame width.
-    Use QtxListAction::setMaxLineChar( int ) to set the width in characters. [ public ]
+  Sets a names to the list. Truncates the name to fit to the frame width.
+  Use QtxListAction::setCharsNumber( int ) to set the width in characters. [ public ]
 */
-
-void QtxListFrame::setNames( const QStringList& names )
+void QtxListAction::ListFrame::setNames( const QStringList& names )
 {
   if ( !myList )
                return;
 
        myList->clear();
-
-       for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it )
+  QStringList strList;
+       for ( QStringList::const_iterator it = names.begin(); it != names.end(); ++it )
        {
                QString s = *it;
     QFontMetrics fm = myList->fontMetrics();
-    int maxW = myMaxLineChars * fm.maxWidth();
+    int maxW = charsNumber() * fm.maxWidth();
     int w = fm.width( s );
     if ( w > maxW )
     {
@@ -752,45 +224,59 @@ void QtxListFrame::setNames( const QStringList& names )
       }
       s += extra;
     }
-    myList->insertItem( s );
+    strList.append( s );
   }
+  myList->addItems( strList );
+}
+
+/*!
+  \return list of names
+*/
+const QStringList QtxListAction::ListFrame::names() const
+{
+       return myNames;
+}
+
+/*!
+    Returns max number of lines shown without activation of vertical scroll bar. [ public ]
+*/
+int QtxListAction::ListFrame::linesNumber() const
+{
+  return myLines;
 }
 
 /*!
-  \return list of names
+    Returns max number of chars in line (the rest will be truncated). [ public ]
 */
-const QStringList QtxListFrame::names() const
+int QtxListAction::ListFrame::charsNumber() const
 {
-       return myNames;
+  return myChars;
 }
 
 /*!
     Sets max number of lines shown without activation of vertical scroll bar. [ public ]
 */
-
-void QtxListFrame::setMaxLines( int maxLines )
+void QtxListAction::ListFrame::setLinesNumber( const int maxLines )
 {
-  myMaxLines = maxLines;
+  myLines = maxLines;
 }
 
 /*!
     Sets max number of chars in line ( the rest will be truncated ). [ public ]
 */
-
-void QtxListFrame::setMaxLineChars( int maxChars )
+void QtxListAction::ListFrame::setCharsNumber( const int maxChars )
 {
-       if ( myMaxLineChars == maxChars )
+       if ( myChars == maxChars )
                return;
 
-  myMaxLineChars = maxChars;
+  myChars = maxChars;
        setNames( myNames );
 }
 
 /*!
     Sets the format of single comment. [ public ]
 */
-
-void QtxListFrame::setSingleComment( const QString& comment )
+void QtxListAction::ListFrame::setSingleComment( const QString& comment )
 {
   mySingleComment = comment;
        setNames( myNames );
@@ -800,8 +286,7 @@ void QtxListFrame::setSingleComment( const QString& comment )
 /*!
     Sets the format of multiple comment. [ public ]
 */
-
-void QtxListFrame::setMultipleComment( const QString& comment )
+void QtxListAction::ListFrame::setMultipleComment( const QString& comment )
 {
   myMultipleComment = comment;
        setNames( myNames );
@@ -811,8 +296,7 @@ void QtxListFrame::setMultipleComment( const QString& comment )
 /*!
     Updates comment display. [ public ]
 */
-
-void QtxListFrame::updateComment()
+void QtxListAction::ListFrame::updateComment()
 {
        QString com;
        int selNum = selected();
@@ -827,287 +311,471 @@ void QtxListFrame::updateComment()
   myComment->setText( com );
 }
 
-/*!
-  Sets owner
-  \param wo - new owner
-*/
-void QtxListFrame::setOwner( QWidget* wo )
+QSize QtxListAction::ListFrame::sizeHint() const
 {
-  myOwner = wo;
-  if ( myOwner )
-  {
-    QPoint lpos;
-    if ( myOwner->parentWidget() && myOwner->parentWidget()->inherits( "QToolBar" ) &&
-         ((QToolBar*)myOwner->parentWidget())->orientation() == Qt::Vertical )
-      lpos = QPoint( myOwner->x() + myOwner->width() + 2, myOwner->y() );
-    else
-                 lpos = QPoint( myOwner->x(), myOwner->y() + myOwner->height() + 2 );
-      QPoint gpos = myOwner->parentWidget() ? myOwner->parentWidget()->mapToGlobal( lpos )
-                                            : myOwner->mapToGlobal( lpos );
-    if ( parentWidget() )
-                       move( parentWidget()->mapFromGlobal( gpos ) );
-    else
-                 move( gpos );
-  }
+  return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
+                qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
+                myComment->sizeHint().height() );
 }
 
-/*!
-    Validates the action. [ private slot ]
-*/
-
-void QtxListFrame::accept()
+QSize QtxListAction::ListFrame::minimumSizeHint() const
 {
-  emit selected( selected() );
+  return QSize( myList->fontMetrics().maxWidth() * charsNumber() + 10,
+                qMax( 1, linesNumber() ) * ( myList->fontMetrics().height() + 2 ) +
+                myComment->sizeHint().height() );
 }
 
 /*!
-    Cancels the action. [ private slot ]
+  Validates the action. [ private slot ]
 */
-
-void QtxListFrame::reject()
+void QtxListAction::ListFrame::accept()
 {
-  emit selected( 0 );
+  int sel = selected();
+  if ( sel && myAction )
+    myAction->onMultiple( sel );
 }
 
 /*!
-    Initializes / shows the frame. [ virtual public slot ]
+  Initializes / shows the frame. [ virtual public slot ]
 */
-
-void QtxListFrame::show()
+void QtxListAction::ListFrame::setVisible( bool on )
 {
-  int cnt = (int)myList->count();
-  if ( cnt )
+  if ( on )
   {
-    myScrollVal = 0;
-               myList->setTopItem( 0 );
-    myList->clearSelection();
-               myList->setMinimumSize( 0, ( QMIN( cnt + 1, myMaxLines ) ) * myList->itemHeight() + 1 );
-    setSelected( 1 );
-
-    int linstep = myList->itemHeight();
-    myList->verticalScrollBar()->setLineStep( linstep );
-    myList->verticalScrollBar()->setPageStep( myMaxLines * linstep );
-
-    QFontMetrics fm = myList->fontMetrics();
-    layout()->invalidate();
-    int maxHeight = layout()->minimumSize().height() + layout()->margin();
-    int maxWidth = myMaxLineChars * fm.maxWidth();
-               for ( uint i = 0; i <= myList->count(); i++ )
-                       maxWidth = QMAX( maxWidth, fm.width( myList->text( i ) ) );
-
-               resize( width(), maxHeight );
-
-               myList->updateGeometry();
-
-               QApplication::sendPostedEvents();
-
-    myList->resizeContents( myList->contentsWidth(),
-                            myList->itemHeight() * cnt );
-    if ( myList->contentsHeight() > myList->visibleHeight() )
-         maxWidth += myList->verticalScrollBar()->width();
-
-               QString single = mySingleComment.arg( cnt );
-               QString multi = myMultipleComment.arg( cnt );
-               int comWidth = QMAX( myComment->fontMetrics().width( single ), myComment->fontMetrics().width( multi ) );
-               if ( myComment->frameWidth() )
-                       comWidth += myComment->fontMetrics().width( "x" );
-
-               maxWidth = QMAX( maxWidth, comWidth );
-
-               resize( maxWidth, maxHeight );
+    myList->setFocus();
+    myList->scrollToItem( myList->item( 0 ), QListWidget::PositionAtTop );
+    setSelected( 0 );
     updateComment();
-
-    qApp->installEventFilter( this );
-
-    QFrame::show();
   }
-}
-
-/*!
-    Cleanup. [ virtual public slot ]
-*/
 
-void QtxListFrame::hide()
-{
-  qApp->removeEventFilter( this );
-  QFrame::hide();
-  emit hided();
+  QMenu::setVisible( on );
 }
 
 /*!
     Processes KeyUp/KeyDown, PageUp/PageDown, CR and Esc keys.
     Returns 'true' if event is eaten, 'false' otherwise. [ private ]
 */
-
-bool QtxListFrame::handleKeyEvent( QObject* , QKeyEvent* e )
+void QtxListAction::ListFrame::keyPressEvent( QKeyEvent* e )
 {
   if ( e->type() == QEvent::KeyRelease )
-    return true;
+    return;
+
+  e->accept();
 
   int selNum = selected();
   switch( e->key() )
   {
-  case Key_Up:
-    setSelected( QMAX( 1, selNum - 1 ) );
+  case Qt::Key_Up:
+    setSelected( qMax( 1, selNum - 1 ) );
     break;
-  case Key_Down:
-    setSelected( QMAX( 1, selNum + 1 ) );
+  case Qt::Key_Down:
+    setSelected( qMax( 1, selNum + 1 ) );
     break;
-  case Key_PageUp:
-    setSelected( QMAX( 1, selNum - myMaxLines ) );
+  case Qt::Key_PageUp:
+    setSelected( qMax( 1, selNum - linesNumber() ) );
     break;
-  case Key_PageDown:
-         setSelected( selNum += myMaxLines );
+  case Qt::Key_PageDown:
+         setSelected( selNum += linesNumber() );
     break;
-  case Key_Home:
+  case Qt::Key_Home:
          setSelected( 1 );
                break;
-  case Key_End:
+  case Qt::Key_End:
          setSelected( myList->count() );
                break;
-  case Key_Return:
+  case Qt::Key_Return:
     accept();
     break;
-  case Key_Escape:
-    reject();
+  case Qt::Key_Escape:
+    hide();
     break;
   }
-  return true;
 }
 
 /*!
-    Selects items on move, validates on button release. If object 'o' is not our name list,
-    we close the frame. Returns 'true' if event is eaten, 'false' otherwise. [ private ]
+  Watches mouse events on the viewport of the list. [virtual public]
 */
-
-bool QtxListFrame::handleMouseEvent( QObject* o, QMouseEvent* e )
+bool QtxListAction::ListFrame::eventFilter( QObject* o, QEvent* e )
 {
+  bool res = true;
+
   switch( e->type() )
   {
-  case QEvent::MouseButtonPress:
-  {
-         if ( o != myList->viewport() && !isPopup() )
-                 reject();
-    return true;
-  }
   case QEvent::MouseMove:
-  {
-    if ( o == myList->viewport() )
     {
-      QListBoxItem* lbi = myList->itemAt( e->pos() );
-      if ( lbi )
-        setSelected( myList->index( lbi ) + 1 );
+      QMouseEvent* me = (QMouseEvent*)e;
+      if ( !myList->viewport()->rect().contains( me->pos() ) )
+        setSelected( 0 );
+      else if ( myList->itemAt( me->pos() ) )
+        setSelected( myList->row( myList->itemAt( me->pos() ) ) + 1 );
     }
     break;
-  }
   case QEvent::MouseButtonRelease:
-  {
-    if ( o == myList->viewport() )
-      accept();
-    else
-                 reject();
+    accept();
+  case QEvent::MouseButtonPress:
+  case QEvent::MouseButtonDblClick:
+    break;
+  case ScrollEvent::Scroll:
+    {
+      ScrollEvent* se = (ScrollEvent*)e;
+      QPoint pos = myList->viewport()->mapFromGlobal( QCursor::pos() );
+      if ( myList->viewport()->rect().contains( pos ) )
+      {
+        if ( myList->itemAt( pos ) )
+          setSelected( myList->row( myList->itemAt( pos ) ) + 1 );
+      }
+      else if ( se->isDown() )
+        setSelected( myList->row( myList->itemAt( myList->viewport()->rect().bottomLeft() -
+                                                  QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
+      else
+        setSelected( myList->row( myList->itemAt( myList->viewport()->rect().topLeft() +
+                                                  QPoint( 0, myList->fontMetrics().height() / 2 ) ) ) + 1 );
+    }
     break;
-  }
   default:
+    res = false;
     break;
   }
-  return true;
+
+  if ( res )
+    return true;
+  else
+    return QMenu::eventFilter( o, e );
 }
 
 /*!
-  Custom event filter
+  return number of selected items
 */
-bool QtxListFrame::event( QEvent* e )
+int QtxListAction::ListFrame::selected() const
 {
-  if ( e->type() != (int)ScrollEvent::Scroll )
-    return QFrame::event( e );
+       int sel = 0;
+  QModelIndexList indexes = myList->selectionModel()->selectedRows();
+  for ( QModelIndexList::const_iterator it = indexes.begin(); it != indexes.end(); ++it )
+    sel = qMax( sel, (*it).row() + 1 );
 
-  ScrollEvent* se = (ScrollEvent*)e;
-  if ( se->isDown() )
-    setSelected( myList->topItem() + myList->numItemsVisible() );
-  else
-    setSelected( myList->topItem() + 1 );
-  
-  return true;
+       return sel;
 }
 
 /*!
-    Watches mouse events on the viewport of the list. [ virtual public ]
+    Selects the actions [ 0 - lastSel ]. [ public ]
 */
+void QtxListAction::ListFrame::setSelected( const int lastSel )
+{
+       int last = qMin( lastSel, (int)myList->count() );
+
+  QItemSelection selection;
+  QItemSelectionModel* selModel = myList->selectionModel();
+
+       for ( int i = 0; i < last; i++ )
+    selection.select( selModel->model()->index( i, 0 ), selModel->model()->index( i, 0 ) );
+
+  selModel->select( selection, QItemSelectionModel::ClearAndSelect );
+
+       int item = last - 1;
+
+  myList->scrollToItem( myList->item( item ) );
+  myList->clearFocus();
 
-bool QtxListFrame::eventFilter( QObject* o, QEvent* e )
+  removePostedEvens( myList->viewport(), ScrollEvent::Scroll );
+
+  updateComment();
+}
+
+void QtxListAction::ListFrame::removePostedEvens( QObject* o, int type )
 {
-  bool isKeyEvent = ( e->type() == QEvent::KeyPress ||
-                      e->type() == QEvent::KeyRelease );
-  bool isMouseEvent = ( e->type() == QEvent::MouseMove ||
-                        e->type() == QEvent::MouseButtonPress ||
-                        e->type() == QEvent::MouseButtonRelease ||
-                        e->type() == QEvent::MouseButtonDblClick );
-
-  if ( isKeyEvent )
+  class Filter : public QObject
   {
-    if ( handleKeyEvent( o, ( QKeyEvent* )e ) )
+  public:
+    Filter() : QObject( 0 ) {}
+    virtual bool eventFilter( QObject*, QEvent* )
+    {
       return true;
-  }
-  else if ( isMouseEvent && o != myList->verticalScrollBar() )
+    }
+  };
+
+  Filter f;
+  o->installEventFilter( &f );
+  QApplication::sendPostedEvents( o, type );
+}
+
+/*!
+  \class QtxListAction
+  Action with list of items
+*/
+
+/*!
+  Constructs an list action with given parent and name. If toggle is true the
+  action will be a toggle action, otherwise it will be a command action.
+*/
+QtxListAction::QtxListAction( QObject* parent )
+: QWidgetAction( parent ),
+myFrame( 0 )
+{
+  initialize();
+}
+
+/*!
+  This constructor creates an action with the following properties: the
+  description text, the icon or iconset icon, the menu text and keyboard
+  accelerator. It is a child of given parent and named specified name.
+  If toggle is true the action will be a toggle action, otherwise it will
+  be a command action.
+*/
+QtxListAction::QtxListAction( const QIcon& icon, const QString& text, int accel, QObject* parent )
+: QWidgetAction( parent ),
+myFrame( 0 )
+{
+  setIcon( icon );
+  setText( text );
+  setShortcut( accel );
+
+  initialize();
+}
+
+/*!
+  This constructor creates an action with the following properties: the
+  description text, the menu text and keyboard accelerator. It is a child
+  of given parent and named specified name. If toggle is true the action
+  will be a toggle action, otherwise it will be a command action.
+*/
+QtxListAction::QtxListAction( const QString& text, int accel, QObject* parent )
+: QWidgetAction( parent ),
+myFrame( 0 )
+{
+  setText( text );
+  setShortcut( accel );
+
+  initialize();
+}
+
+/*!
+  Destructor.
+*/
+QtxListAction::~QtxListAction()
+{
+  delete myFrame;
+  myFrame = 0;
+}
+
+/*!
+       Name: popupMode [public]
+       Desc: Returns popup mode. If popup mode "Item" (default) then action will
+             be added into popup menu as menu item. If popup mode "SubMenu" then
+                   action will be added into popup menu as sub menu with list of items.
+*/
+int QtxListAction::popupMode() const
+{
+  return menu() ? SubMenu : Item;
+}
+
+/*!
+       Name: setPopupMode [public]
+       Desc: Set the popup mode. Popup mode define way in this action will be
+             added into popup menu. This function should be used before addTo.
+*/
+void QtxListAction::setPopupMode( const int mode )
+{
+  if ( mode == popupMode() )
+    return;
+
+  if ( mode == Item )
   {
-    if ( handleMouseEvent( o, ( QMouseEvent*)e ) )
-      return true;
+    delete menu();
+    setMenu( 0 );
   }
+  else
+    setMenu( new QMenu( 0 ) );
 
-  if ( o != this && ( e->type() == QEvent::Resize || e->type() == QEvent::Move ) )
-    setOwner( myOwner );
+  onChanged();
+}
 
-  return QFrame::eventFilter( o, e );
+/*!
+  \return list of names
+*/
+QStringList QtxListAction::names() const
+{
+  QStringList lst;
+  if ( myFrame )
+    lst = myFrame->names();
+  return lst;
 }
 
 /*!
-    Selects operations while scrolling the list. [ private slot ]
+       Name: addNames [public]
+       Desc: Fills the list of actions. Removes the old contents from
+             the list if 'clear' is true.
 */
+void QtxListAction::addNames( const QStringList& names, bool clear )
+{
+  if ( !myFrame )
+    return;
+
+  if ( clear )
+    myFrame->clear();
+
+       myFrame->addNames( names );
+
+  onChanged();
+}
 
-void QtxListFrame::onScroll( int x, int y )
+/*!
+  Returns the number of lines wich will be visible in list frame.
+*/
+int QtxListAction::linesNumber() const
 {
-  int dx = y - myScrollVal;
-       if ( !myScrollBlock )
-               QApplication::postEvent( this, new ScrollEvent( dx > 0 ) );
-  myScrollVal = y;
+  return myFrame->linesNumber();
 }
 
 /*!
-    Selects the actions [ 0 - lastSel ]. [ public ]
+  Returns the number of chars wich will be visible in the each line.
 */
+int QtxListAction::charsNumber() const
+{
+  return myFrame->charsNumber();
+}
 
-void QtxListFrame::setSelected( const int lastSel )
+/*!
+       Sets max number of lines that list frame shows without vertical scroll bar. Default value is 7.
+*/
+void QtxListAction::setLinesNumber( const int nlines )
 {
-       int last = QMIN( lastSel, (int)myList->count() );
+  myFrame->setLinesNumber( nlines );
+}
 
-       for ( int i = 0; i < (int)myList->count(); i++ )
-               myList->setSelected( i, i < last );
+/*!
+       Sets max number of characters in a line which list frame shows without truncation.
+  Default value is 5 (the widest char size is used).
+*/
 
-       int item = last - 1;
+void QtxListAction::setCharsNumber( const int nchars )
+{
+  myFrame->setCharsNumber( nchars );
+}
+
+/*!
+       Name: setComment [public]
+       Desc: Sets the format Qt string for comments displayed under the list
+             of actions for one action and for several actions.
+                   Ex. "Undo %1 actions" format string will work as "Undo 3 actions"
+                   when 3 actions are selected. The default format string is "%1".
+*/
+void QtxListAction::setComment( const QString& c, const QString& sc )
+{
+  if ( !myFrame )
+    return;
 
-       myScrollBlock = true;
+  myFrame->setSingleComment( sc.isEmpty() ? c : sc );
+       myFrame->setMultipleComment( c );
+}
 
-       if ( item < myList->topItem() )
-               myList->setTopItem( item );
+QWidget* QtxListAction::createWidget( QWidget* parent )
+{
+  if ( parent && parent->inherits( "QMenu" ) )
+    return 0;
 
-       if ( item >= myList->topItem() + myList->numItemsVisible() )
-               myList->setTopItem( item - myList->numItemsVisible() + 1 );
+  QToolButton* tb = new QToolButton( parent );
+  tb->setText( text() );
+  tb->setIcon( icon() );
+  tb->setPopupMode( QToolButton::MenuButtonPopup );
+  tb->setMenu( myFrame );
+  tb->setEnabled( isEnabled() && !names().isEmpty() );
+  tb->setToolTip( toolTip() );
+  connect( tb, SIGNAL( clicked( bool ) ), this, SLOT( onSingle( bool ) ) );
 
-       myScrollBlock = false;
+  return tb;
+}
 
-  myList->clearFocus();
+void QtxListAction::deleteWidget( QWidget* widget )
+{
+  delete widget;
+}
 
-  updateComment();
+/*!
+       Name: initialize [private]
+       Desc: Initialization of object QtxListAction.
+*/
+
+void QtxListAction::initialize()
+{
+  setPopupMode( Item );
+
+       myFrame = new QtxListAction::ListFrame( this, 0 );
+  myFrame->setLinesNumber( 7 );
+  myFrame->setCharsNumber( 5 );
+
+       myFrame->hide();
+
+  connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
+  connect( this, SIGNAL( triggered( bool ) ), this, SLOT( onSingle( bool ) ) );
+}
+
+void QtxListAction::onChanged()
+{
+       QStringList lst = myFrame->names();
+
+  if ( menu() )
+  {
+    menu()->clear();
+    for ( QStringList::iterator iter = lst.begin(); iter != lst.end(); ++iter )
+    {
+      QAction* a = new QAction( *iter, menu() );
+      menu()->addAction( a );
+      connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onTriggered( bool ) ) );
+    }
+  }
+
+  QList<QWidget*> widList = createdWidgets();
+       for ( QList<QWidget*>::iterator it = widList.begin(); it != widList.end(); ++it )
+  {
+               (*it)->setEnabled( isEnabled() && !lst.isEmpty() );
+    QToolButton* tb = ::qobject_cast<QToolButton*>( *it );
+    if ( tb )
+    {
+      tb->setText( text() );
+      tb->setIcon( icon() );
+      tb->setToolTip( toolTip() );
+    }
+  }
 }
 
 /*!
-  return number of selected items
+       Name: onSingle [private slot]
+       Desc: Called when a single action is selected.
 */
-int QtxListFrame::selected() const
+
+void QtxListAction::onSingle( bool )
 {
-       uint sel = 0;
-       while ( sel < myList->count() && myList->isSelected( sel ) )
-               sel++;
-       return sel;
+  onMultiple( 1 );
+}
+
+/*!
+       Name: onMultiple [private slot]
+       Desc: Called when multiple actions are selected.
+*/
+
+void QtxListAction::onMultiple( const int numActions )
+{
+  if ( myFrame )
+    myFrame->hide();
+
+  if ( numActions > 0 )
+    emit activated( numActions );
+}
+
+/*!
+       Name: onTriggered [private slot]
+       Desc: Called when a sub menu item is activated.
+*/
+
+void QtxListAction::onTriggered( bool )
+{
+  if ( !menu() )
+    return;
+
+  QList<QAction*> actionList = menu()->actions();
+  int idx = actionList.indexOf( ::qobject_cast<QAction*>( sender() ) );
+  if ( idx < 0 )
+    return;
+
+  emit activated( idx + 1 );
 }
index 8ad60be5bb1e9b0764f7c8f9b69df617c7859a03..7cdd90ffa83923e3691a39b2b672b316a0292865 100755 (executable)
@@ -1,17 +1,17 @@
 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
-// 
+//
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either 
+// License as published by the Free Software Foundation; either
 // version 2.1 of the License.
-// 
-// This library is distributed in the hope that it will be useful 
-// but WITHOUT ANY WARRANTY; without even the implied warranty of 
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 // Lesser General Public License for more details.
 //
-// You should have received a copy of the GNU Lesser General Public  
-// License along with this library; if not, write to the Free Software 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #ifndef QTXLISTACTION_H
 #define QTXLISTACTION_H
 
-#include "QtxAction.h"
+#include "Qtx.h"
 
-#include <qmap.h>
-#include <qframe.h>
-#include <qstringlist.h>
+#include <QMap>
+#include <QMenu>
+#include <QStringList>
+#include <QWidgetAction>
 
 class QLabel;
-class QListBox;
-class QPopupMenu;
 class QToolButton;
-class QToolTipGroup;
+class QListWidget;
 
 class QtxListFrame;
 
@@ -40,153 +39,58 @@ class QtxListFrame;
 #pragma warning( disable:4251 )
 #endif
 
-class QTX_EXPORT QtxListAction : public QtxAction
+class QTX_EXPORT QtxListAction : public QWidgetAction
 {
-    Q_OBJECT
+  Q_OBJECT
 
-    Q_PROPERTY( QStringList names READ names WRITE addNames )
+  Q_PROPERTY( QStringList names READ names WRITE addNames )
 
-    class ToolButton;
+  class ListFrame;
+  class ListWidget;
+  class ScrollEvent;
 
 public:
-    enum { Item, SubMenu } PopupMode;
+  enum { Item, SubMenu } PopupMode;
 
 public:
-    QtxListAction( QObject* = 0, const char* = 0, bool = false );
-    QtxListAction( const QString&, const QIconSet&, const QString&, int, QObject*, const char* = 0, bool = false );
-    QtxListAction( const QString&, const QString&, int, QObject*, const char* = 0, bool = false );
-    virtual ~QtxListAction();
+  QtxListAction( QObject* = 0 );
+  QtxListAction( const QString&, int, QObject* );
+  QtxListAction( const QIcon&, const QString&, int, QObject* );
+  virtual ~QtxListAction();
 
-public:
-    virtual bool            addTo( QWidget* );
-    virtual bool            addTo( QWidget*, const int );
+  int              popupMode() const;
+  void             setPopupMode( const int );
 
-    virtual bool            removeFrom( QWidget* );
-    virtual bool            eventFilter( QObject*, QEvent* );
+  QStringList      names() const;
+  void             addNames( const QStringList&, bool = true );
+  void             setComment( const QString&, const QString& = QString() );
 
-    int                     popupMode() const;
-    void                    setPopupMode( const int );
+  int              linesNumber() const;
+  int              charsNumber() const;
 
-    QStringList             names() const;
-    void                    addNames( const QStringList&, bool = true );
-    void                    setComment( const QString&, const QString& = QString::null );
-
-    void                    setMaxLines( int );
-    void                    setMaxLineChars( int );
+  void             setLinesNumber( const int );
+  void             setCharsNumber( const int );
 
 signals:
-    void                    activated( int );
-
-public slots:
-    virtual void            setEnabled( bool );
+  void             activated( int );
 
 private slots:
-    void                    onHided();
-    void                    onSingle();
-    void                    onExpand( bool );
-    void                    onMultiple( int );
-    void                    onActivated( int );
-    void                    onDestroyed( QObject* );
+  void             onChanged();
+  void             onMultiple( const int );
+  void             onSingle( bool = false );
+  void             onTriggered( bool = false );
 
 protected:
-    virtual void            addedTo( QWidget*, QWidget* );
+  virtual QWidget* createWidget( QWidget* );
+  virtual void     deleteWidget( QWidget* );
 
 private:
-    void                    initialize();
-    QWidget*                widget( QWidget* ) const;
-    QPopupMenu*             listPopup( QWidget* ) const;
-    QToolButton*            mainButton( QWidget* ) const;
-    QToolButton*            dropButton( QWidget* ) const;
+  void             initialize();
 
-    void                    controlDeleted( QWidget* );
-
-private:
-    typedef struct { int id; QPopupMenu* popup; } Popups;
-    typedef struct { QToolButton* main; QToolButton* drop; } Buttons;
-    typedef QMap<QWidget*, Popups>  PopupsMap;
-    typedef QMap<QWidget*, Buttons> ButtonsMap;
-    
 private:
-    int                     myMode;
-    QtxListFrame*           myFrame;
-    bool                    myRaise;
-    PopupsMap               myPopups;
-    ButtonsMap              myButtons;
-    QToolTipGroup*          myTipGroup;
-
-    friend class ToolButton;
-    friend class QtxListFrame;
-};
+  ListFrame*       myFrame;
 
-/*!
-  \class QtxListFrame
-*/
-class QtxListFrame : public QFrame
-{
-    Q_OBJECT
-
-    class ScrollEvent;
-
-public:
-    QtxListFrame( QtxListAction*, QWidget* parent, WFlags f = 0 );
-    virtual ~QtxListFrame();
-
-    void                    clear();
-    const QStringList       names() const;
-    void                    addNames( const QStringList& );
-    
-    void                    setSingleComment( const QString& );
-    void                    setMultipleComment( const QString& );
-    
-    int                     selected() const;
-    void                    setSelected( const int );
-    
-    void                    setMaxLines( int );
-    void                    setMaxLineChars( int );
-    
-    virtual bool            event( QEvent* );
-    virtual bool            eventFilter( QObject*, QEvent* );
-
-    void                    setOwner( QWidget* );
-
-    void                    updateComment();
-    
-signals:
-    void                    hided();
-    void                    selected( int );
-    
-public slots:
-    virtual void            show();
-    virtual void            hide();
-    
-private slots:
-    void                    reject();
-    void                    accept();
-    
-    void                    onScroll( int, int );
-    
-private:
-    void                    setNames( const QStringList& );
-    bool                    handleKeyEvent( QObject*, QKeyEvent* );
-    bool                    handleMouseEvent( QObject*, QMouseEvent* );
-
-    friend class QtxListAction;
-    
-private:
-    QListBox*               myList;
-    QStringList             myNames;
-    QWidget*                myOwner;
-    QtxListAction*          myAction;
-    QLabel*                 myComment;
-    
-    QString                 mySingleComment;
-    QString                 myMultipleComment;
-    
-    int                     myMaxLines;
-    int                     myMaxLineChars;
-    
-    int                     myScrollVal;
-    bool                    myScrollBlock;
+  friend class QtxListAction::ListFrame;
 };
 
 #ifdef WIN32