From e66fae27c832b856ed85a42304f0f3ba335b5c90 Mon Sep 17 00:00:00 2001 From: vsr Date: Mon, 6 Feb 2017 18:16:28 +0300 Subject: [PATCH] 0023352: [CEA] Order and naming of meshing algorithms Introduce new class for QToolButton that behaves similarly to QComboBox but allows grouping items. --- src/Qtx/CMakeLists.txt | 2 + src/Qtx/QtxMenu.cxx | 25 +- src/Qtx/QtxMenu.h | 3 +- src/Qtx/QtxToolButton.cxx | 529 ++++++++++++++++++++++++++++++++++++++ src/Qtx/QtxToolButton.h | 91 +++++++ 5 files changed, 645 insertions(+), 5 deletions(-) create mode 100644 src/Qtx/QtxToolButton.cxx create mode 100644 src/Qtx/QtxToolButton.h diff --git a/src/Qtx/CMakeLists.txt b/src/Qtx/CMakeLists.txt index f25866f09..ad1337ffc 100755 --- a/src/Qtx/CMakeLists.txt +++ b/src/Qtx/CMakeLists.txt @@ -72,6 +72,7 @@ SET(_moc_HEADERS QtxSlider.h QtxSplash.h QtxToolBar.h + QtxToolButton.h QtxToolTip.h QtxTreeView.h QtxValidator.h @@ -164,6 +165,7 @@ SET(_other_SOURCES QtxSlider.cxx QtxSplash.cxx QtxToolBar.cxx + QtxToolButton.cxx QtxToolTip.cxx QtxTranslator.cxx QtxTreeView.cxx diff --git a/src/Qtx/QtxMenu.cxx b/src/Qtx/QtxMenu.cxx index 526965bcf..a70f1f392 100644 --- a/src/Qtx/QtxMenu.cxx +++ b/src/Qtx/QtxMenu.cxx @@ -359,13 +359,30 @@ void QtxMenu::setTitleAlignment( const Qt::Alignment a ) } /*! - * \brief Append a title to the and of the menu - * \param [in] text - title text - */ -void QtxMenu::appendGroupTitle( const QString& text ) + \brief Append group title to the end of the menu. + \param text group title's text +*/ +void QtxMenu::addGroup( const QString& text ) +{ + Title* aTitle = new Title( this ); + aTitle->setText( text ); + + QWidgetAction* anAction = new QWidgetAction( this ); + anAction->setDefaultWidget( aTitle ); + + addAction( anAction ); +} + +/*! + \brief Append group title to the end of the menu. + \param icon group title's icon + \param text group title's text +*/ +void QtxMenu::addGroup( const QIcon& icon, const QString& text ) { Title* aTitle = new Title( this ); aTitle->setText( text ); + aTitle->setIcon( icon ); QWidgetAction* anAction = new QWidgetAction( this ); anAction->setDefaultWidget( aTitle ); diff --git a/src/Qtx/QtxMenu.h b/src/Qtx/QtxMenu.h index 5ed17ed85..493a348e4 100644 --- a/src/Qtx/QtxMenu.h +++ b/src/Qtx/QtxMenu.h @@ -59,7 +59,8 @@ public: virtual void setTitleMode( const TitleMode ); virtual void setTitleAlignment( const Qt::Alignment ); - virtual void appendGroupTitle( const QString& ); + virtual void addGroup( const QString& ); + virtual void addGroup( const QIcon&, const QString& ); public slots: virtual void setVisible( bool ); diff --git a/src/Qtx/QtxToolButton.cxx b/src/Qtx/QtxToolButton.cxx new file mode 100644 index 000000000..d24505168 --- /dev/null +++ b/src/Qtx/QtxToolButton.cxx @@ -0,0 +1,529 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// version 2.1 of the License, or (at your option) any later version. +// +// 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 +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "QtxToolButton.h" +#include "QtxMenu.h" + +#include +#include + +namespace +{ + bool isSeparator( QAction* a ) + { + return a->property( "separator" ).toBool(); + } + void setSeparator( QAction* a ) + { + a->setProperty( "separator", true ); + } +} + +/*! + \class QtxToolButton + \brief Drop-down tool button that behaves like a drop-down combo-box. + + In contrast to the standard combo box, QtxToolButton can show drop-down + menu containing groups of items where each group has a separate title. +*/ + +/*! + \brief Constructor. + \param parent Parent widget. +*/ +QtxToolButton::QtxToolButton( QWidget* parent ) + : QToolButton( parent ) +{ + setMenu( new QtxMenu( this ) ); + setPopupMode( InstantPopup ); + setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); + connect( this, SIGNAL( triggered( QAction* ) ), this, SLOT( actionTriggered( QAction* ) ) ); +} + +/*! + \brief Destructor. +*/ +QtxToolButton::~QtxToolButton() +{ +} + +/*! + \brief Add an item with the given \a text, and containing the specified \a userData. + The item is appended to the list of existing items. + \param text Item's text. + \param userData Item's data. + \return Index of just added item. +*/ +int QtxToolButton::addItem( const QString& text, const QVariant& userData ) +{ + QAction* action = menu()->addAction( text ); + action->setData( userData ); + bool currentChanged = false; + if ( !menu()->defaultAction() ) { + menu()->setDefaultAction( action ); + currentChanged = true; + } + internalUpdate(); + if ( currentChanged ) emitCurrentChanged( false, true ); + return count()-1; +} + +/*! + \brief Add an item with the given \a icon and \a text, and containing the specified + \a userData. The item is appended to the list of existing items. + \param text Item's text. + \param icon Item's icon. + \param userData Item's data. + \return Index of just added item. +*/ +int QtxToolButton::addItem( const QIcon& icon, const QString& text, const QVariant& userData ) +{ + QAction* action = menu()->addAction( icon, text ); + action->setData( userData ); + bool currentChanged = false; + if ( !menu()->defaultAction() ) { + menu()->setDefaultAction( action ); + currentChanged = true; + } + internalUpdate(); + if ( currentChanged ) emitCurrentChanged( false, true ); + return count()-1; +} + +/*! + \brief Add items with given \a texts. Each item is appended to the list of existing + items in turn. + \param texts Items being added. +*/ +void QtxToolButton::addItems( const QStringList& texts ) +{ + Q_FOREACH( QString text, texts ) + menu()->addAction( text ); + bool currentChanged = false; + if ( !menu()->defaultAction() && menu()->actions().count() > 0 ) { + menu()->setDefaultAction( menu()->actions()[0] ); + currentChanged = true; + } + if ( currentChanged ) emitCurrentChanged( false, true ); + internalUpdate(); +} + +/*! + \brief Add separator to the end of the items list. + \param text Separator's text. + \return Index of just added item. +*/ +int QtxToolButton::addSeparator( const QString& text ) +{ + (qobject_cast(menu()))->addGroup( text ); + setSeparator( actionAt( count()-1 ) ); + return count()-1; +} + +/*! + \brief Add separator to the end of the items list. + \param icon Separator's icon. + \param text Separator's text. + \return Index of just added item. +*/ +int QtxToolButton::addSeparator( const QIcon& icon, const QString& text ) +{ + (qobject_cast(menu()))->addGroup( icon, text ); + setSeparator( actionAt( count()-1 ) ); + return count()-1; +} + +/*! + \brief Remove item with given \a index. + \param index Index of item to be removed. +*/ +void QtxToolButton::removeItem( int index ) +{ + QAction* action = actionAt( index ); + if ( !action ) return; + QAction* current = menu()->defaultAction(); + menu()->removeAction( action ); + bool currentChanged = false; + if ( action == current ) { + for ( int i = index; i < count(); i++ ) { + QAction* a = actionAt( i ); + if ( a && !isSeparator( a ) ) { + menu()->setDefaultAction( a ); + currentChanged = true; + break; + } + } + for ( int i = index-1; i >= 0; i-- ) { + QAction* a = actionAt( i ); + if ( a && !isSeparator( a ) ) { + menu()->setDefaultAction( a ); + currentChanged = true; + break; + } + } + } + internalUpdate(); + if ( currentChanged ) emitCurrentChanged( false, true ); +} + +/*! + \brief Get the number of items. + \return Number of items. +*/ +int QtxToolButton::count() const +{ + return menu()->actions().count(); +} + +/*! + \brief Get data of the current item. + \return Current item's data (invalid QVariant if list of items is empty + or current item doesn't have data). +*/ +QVariant QtxToolButton::currentData() const +{ + QAction* action = menu()->defaultAction(); + return action == 0 ? QVariant() : action->data(); +} + +/*! + \brief Get index of current item. + \return Current item's index; -1 if list of items is empty or if there's no + current item. +*/ +int QtxToolButton::currentIndex() const +{ + QAction* action = menu()->defaultAction(); + return action == 0 ? -1 : menu()->actions().indexOf( action ); +} + +/*! + \brief Get text of current item. + \return Current item's text; null sting if list of items is empty or + if there's no current item. +*/ +QString QtxToolButton::currentText() const +{ + QAction* action = menu()->defaultAction(); + return action == 0 ? QString() : action->text(); +} + +/*! + \brief Get custom data of the item at given \a index. + \param index Item's index. + \return Item's data (invalid QVariant if index is out of range). +*/ +QVariant QtxToolButton::itemData( int index ) const +{ + QAction* action = actionAt( index ); + return action == 0 ? QVariant() : action->data(); +} + +/*! + \brief Get icon of the item at given \a index. + \param index Item's index. + \return Item's icon. +*/ +QIcon QtxToolButton::itemIcon( int index ) const +{ + QAction* action = actionAt( index ); + return action == 0 ? QIcon() : action->icon(); +} + +/*! + \brief Get text of the item at given \a index. + \param index Item's index. + \return Item's text. +*/ +QString QtxToolButton::itemText( int index ) const +{ + QAction* action = actionAt( index ); + return action == 0 ? QString() : action->text(); +} + +/*! + \brief Set custom data of the item at given \a index. + \param index Item's index. + \param value Item's data. +*/ +void QtxToolButton::setItemData( int index, const QVariant& value ) +{ + QAction* action = actionAt( index ); + if ( action ) action->setData( value ); +} + +/*! + \brief Set icon of the item at given \a index. + \param index Item's index. + \param icon Item's icon. +*/ +void QtxToolButton::setItemIcon( int index, const QIcon& icon ) +{ + QAction* action = actionAt( index ); + if ( action ) action->setIcon( icon ); + internalUpdate(); +} + +/*! + \brief Set text of the item at given \a index. + \param index Item's index. + \param text Item's text. +*/ +void QtxToolButton::setItemText( int index, const QString& text ) +{ + QAction* action = actionAt( index ); + bool currentChanged = false; + if ( action ) { + currentChanged = menu()->defaultAction() == action && action->text() != text; + action->setText( text ); + } + internalUpdate(); + if ( currentChanged ) + emit currentTextChanged( text ); +} + +/*! + \brief Search item with given \a text. + \param Item's text. + \return Item's index; -1 if item is not found. +*/ +int QtxToolButton::findText( const QString& text ) +{ + int index = -1; + for ( int i = 0; i < count() && index == -1; i++ ) { + QAction* action = actionAt( i ); + if ( isSeparator( action ) ) continue; + if ( action->text() == text ) index = i; + } + return index; +} + +/*! + \brief Clear widget. +*/ +void QtxToolButton::clear() +{ + QAction* action = menu()->defaultAction(); + menu()->clear(); + internalUpdate(); + if ( action ) emitCurrentChanged( false, true ); +} + +/*! + \brief Set current item by given \a index. + \param index Item's index. +*/ +void QtxToolButton::setCurrentIndex( int index ) +{ + bool currentChanged = false; + if ( index == -1 ) { + currentChanged = currentIndex() != -1; + menu()->setDefaultAction( 0 ); + } + else if ( index >= count() ) + return; + else { + QAction* action = actionAt( index ); + if ( !isSeparator( action ) ) { + currentChanged = currentIndex() != index; + menu()->setDefaultAction( action ); + } + } + internalUpdate(); + if ( currentChanged ) emitCurrentChanged( false, true ); +} + +/*! + \brief Set current item by given \a text. + \param index Item's index. +*/ +void QtxToolButton::setCurrentText( const QString& text ) +{ + int index = findText( text ); + if ( index != -1 ) + setCurrentIndex( index ); +} + +/*! + \brief Reimplemented from QToolButton::keyPressEvent(). + Process key press event. + \param e Key press event. +*/ +void QtxToolButton::keyPressEvent( QKeyEvent* e ) +{ + Move move = NoMove; + switch ( e->key() ) { + case Qt::Key_Up: + case Qt::Key_PageUp: + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveFirst : MoveUp; + break; + case Qt::Key_Down: + if ( e->modifiers() & Qt::AltModifier ) { + showMenu(); + return; + } + case Qt::Key_PageDown: + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveLast : MoveDown; + break; + case Qt::Key_Home: + move = MoveFirst; + break; + case Qt::Key_End: + move = MoveLast; + break; + case Qt::Key_F4: + if ( !e->modifiers() ) { + showMenu(); + return; + } + break; + case Qt::Key_Space: + showMenu(); + return; + case Qt::Key_Enter: + case Qt::Key_Return: + case Qt::Key_Escape: + e->ignore(); + break; + case Qt::Key_Select: + showMenu(); + return; + case Qt::Key_Left: + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveFirst : MoveUp; + break; + case Qt::Key_Right: + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveLast : MoveDown; + break; + default: + e->ignore(); + break; + } + moveIndex( move ); +} + +/*! + \brief Reimplemented from QToolButton::wheelEvent(). + Process mouse wheel event. + \param e Mouse wheel event. +*/ +void QtxToolButton::wheelEvent( QWheelEvent* e ) +{ + Move move = NoMove; + if ( e->delta() > 0 ) + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveFirst : MoveUp; + else if ( e->delta() < 0 ) + move = ( e->modifiers() & Qt::ControlModifier ) ? MoveLast : MoveDown; + moveIndex( move ); +} + +/*! + \brief Called when menu action is triggered. + \internal +*/ +void QtxToolButton::actionTriggered( QAction* action ) +{ + if ( action && !isSeparator( action ) ) { + int index = currentIndex(); + menu()->setDefaultAction( action ); + internalUpdate(); + int newIndex = currentIndex(); + emitCurrentChanged( true, index != newIndex ); + } +} + +/*! + \brief Update content of the widget. + \internal +*/ +void QtxToolButton::internalUpdate() +{ + QAction* action = menu()->defaultAction(); + setText( action == 0 ? "" : action->text() ); + setIcon( action == 0 ? QIcon() : action->icon() ); +} + +/*! + \brief Get menu action at given index. + \internal +*/ +QAction* QtxToolButton::actionAt( int index ) const +{ + return ( index >=0 && index < count() ) ? menu()->actions()[index] : 0; +} + +/*! + \brief Move current index. + \internal +*/ +void QtxToolButton::moveIndex( Move move ) +{ + int index = currentIndex(); + int newIndex = index; + switch ( move ) { + case MoveUp: + case MoveFirst: + for ( int i = index-1; i >= 0; i-- ) { + QAction* a = actionAt( i ); + if ( a && !isSeparator( a ) ) { + newIndex = i; + if ( move == MoveUp ) + break; + } + } + break; + case MoveDown: + case MoveLast: + for ( int i = index+1; i < count(); i++ ) { + QAction* a = actionAt( i ); + if ( a && !isSeparator( a ) ) { + newIndex = i; + if ( move == MoveDown ) + break; + } + } + break; + default: + break; + } + if ( newIndex != index ) { + menu()->setDefaultAction( actionAt( newIndex ) ); + internalUpdate(); + emitCurrentChanged( true, true ); + } +} + +/*! + \brief Emit `currentChanged()` signal. + \internal +*/ +void QtxToolButton::emitCurrentChanged( bool activate, bool changed ) +{ + QAction* action = menu()->defaultAction(); + int index = action == 0 ? -1 : menu()->actions().indexOf( action ); + QString text = action == 0 ? QString() : action->text(); + if ( activate ) { + emit activated( index ); + emit activated( text ); + } + if ( changed ) { + emit currentIndexChanged( index ); + emit currentIndexChanged( text ); + emit currentTextChanged( text ); + } +} diff --git a/src/Qtx/QtxToolButton.h b/src/Qtx/QtxToolButton.h new file mode 100644 index 000000000..04a71959d --- /dev/null +++ b/src/Qtx/QtxToolButton.h @@ -0,0 +1,91 @@ +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE +// +// 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 +// version 2.1 of the License, or (at your option) any later version. +// +// 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 +// 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 QTXTOOLBUTTON_H +#define QTXTOOLBUTTON_H + +#include "Qtx.h" + +#include +#include +#include + +class QTX_EXPORT QtxToolButton : public QToolButton +{ + Q_OBJECT + + enum Move { NoMove=0, MoveUp, MoveDown, MoveFirst, MoveLast }; + +public: + QtxToolButton( QWidget* = 0 ); + virtual ~QtxToolButton(); + + int addItem( const QString&, const QVariant& = QVariant() ); + int addItem( const QIcon&, const QString&, const QVariant& = QVariant() ); + void addItems( const QStringList& ); + + int addSeparator( const QString& = QString() ); + int addSeparator( const QIcon&, const QString& ); + + void removeItem( int ); + + int count() const; + + QVariant currentData() const; + int currentIndex() const; + QString currentText() const; + + QVariant itemData( int ) const; + QIcon itemIcon( int ) const; + QString itemText( int ) const; + + void setItemData( int, const QVariant& ); + void setItemIcon( int, const QIcon& ); + void setItemText( int, const QString& ); + + int findText( const QString& ); + +public slots: + void clear(); + + void setCurrentIndex( int ); + void setCurrentText( const QString& ); + +protected: + void keyPressEvent( QKeyEvent* ); + void wheelEvent( QWheelEvent* ); + +signals: + void activated( int ); + void activated( const QString& ); + void currentIndexChanged( int ); + void currentIndexChanged( const QString& ); + void currentTextChanged( const QString& ); + +private slots: + void actionTriggered( QAction* ); + +private: + void internalUpdate(); + QAction* actionAt( int ) const; + void moveIndex( Move ); + void emitCurrentChanged( bool, bool ); +}; + +#endif // QTXTOOLBUTTON_H -- 2.39.2