From 880dae9309e495263750d9fce8eaaf65f74c2eff Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 7 Oct 2008 03:53:55 +0000 Subject: [PATCH] Merging GUI_SRC module with the BR_HDF_dev_merged branch, which has been merged with the BR_V5_DEV branch. --- src/Qtx/Qtx.cxx | 37 +++++++-- src/Qtx/Qtx.h | 1 + src/Qtx/QtxAction.cxx | 12 ++- src/Qtx/QtxActionMenuMgr.cxx | 144 ++++++++++++++++++++++++++++++----- src/Qtx/QtxActionMenuMgr.h | 9 ++- src/Qtx/QtxActionMgr.cxx | 4 +- src/Qtx/QtxActionMgr.h | 4 +- 7 files changed, 177 insertions(+), 34 deletions(-) diff --git a/src/Qtx/Qtx.cxx b/src/Qtx/Qtx.cxx index 11b6166a4..896eed39a 100755 --- a/src/Qtx/Qtx.cxx +++ b/src/Qtx/Qtx.cxx @@ -303,6 +303,33 @@ bool Qtx::isParent( QObject* child, QObject* parent ) return res; } +/*! + \brief Find the parent object of class specified by \a className (in terms of QObject). + + \param obj current object + \param className class name of the parent + \return parent object or null pointer if the parent not found +*/ +QObject* Qtx::findParent( QObject* obj, const char* className ) +{ + if ( !obj ) + return 0; + + if ( !className || !strlen( className ) ) + return obj->parent(); + + QObject* res = 0; + QObject* p = obj->parent(); + while ( p && !res ) + { + if ( p->inherits( className ) ) + res = p; + p = p->parent(); + } + + return res; +} + /*! \brief Return directory part of the file path. @@ -1036,9 +1063,9 @@ QString Qtx::gradientToString( const QRadialGradient& gradient ) data << "radial"; data << QString::number( gradient.center().x() ); data << QString::number( gradient.center().y() ); - data << QString::number( gradient.radius() ); data << QString::number( gradient.focalPoint().x() ); data << QString::number( gradient.focalPoint().y() ); + data << QString::number( gradient.radius() ); switch( gradient.spread() ) { case QGradient::PadSpread: @@ -1171,9 +1198,9 @@ bool Qtx::stringToRadialGradient( const QString& str, QRadialGradient& gradient bool bOk1, bOk2, bOk3, bOk4, bOk5; cx = vals[1].toDouble( &bOk1 ); cy = vals[2].toDouble( &bOk2 ); - r = vals[3].toDouble( &bOk3 ); - fx = vals[4].toDouble( &bOk4 ); - fy = vals[5].toDouble( &bOk5 ); + fx = vals[3].toDouble( &bOk4 ); + fy = vals[4].toDouble( &bOk5 ); + r = vals[5].toDouble( &bOk3 ); if ( bOk1 && bOk2 && bOk3 && bOk4 && bOk5 ) { gradient = QRadialGradient( cx, cy, r, fx, fy ); @@ -1277,7 +1304,7 @@ bool Qtx::hasAnyPrinters() bool aRes = true; #if !defined(WIN32) && !defined(QT_NO_CUPS) #if QT_VERSION < 0x040303 - QLibrary aCupsLib( QString( "cups" ) ); + QLibrary aCupsLib( QString( "cups" ), 2 ); if ( !aCupsLib.load() ) aRes = false; else { diff --git a/src/Qtx/Qtx.h b/src/Qtx/Qtx.h index c8c4f41d6..8e67524fc 100755 --- a/src/Qtx/Qtx.h +++ b/src/Qtx/Qtx.h @@ -108,6 +108,7 @@ public: static void simplifySeparators( QWidget*, const bool = true ); static bool isParent( QObject*, QObject* ); + static QObject* findParent( QObject*, const char* ); static QString dir( const QString&, const bool = true ); static QString file( const QString&, const bool = true ); diff --git a/src/Qtx/QtxAction.cxx b/src/Qtx/QtxAction.cxx index 1e46ce16d..e4da75af7 100755 --- a/src/Qtx/QtxAction.cxx +++ b/src/Qtx/QtxAction.cxx @@ -22,6 +22,7 @@ #include "QtxAction.h" #include +#include #include #include @@ -37,12 +38,12 @@ public: ActionNotify( bool add, QWidget* wid ) : QEvent( QEvent::User ), myAdd( add ), myWidget( wid ) {}; ~ActionNotify() {}; - bool isAdded() const { return myAdd; } - QWidget* widget() const { return myWidget; } + bool isAdded() const { return myAdd; } + QWidget* widget() const { return myWidget; } private: - bool myAdd; - QWidget* myWidget; + bool myAdd; + QPointer myWidget; }; /*! @@ -195,6 +196,9 @@ void QtxAction::removedFrom( QWidget* /*w*/ ) void QtxAction::customEvent( QEvent* e ) { ActionNotify* ae = (ActionNotify*)e; + if ( !ae->widget() ) + return; + if ( ae->isAdded() ) addedTo( ae->widget() ); else diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index f3b42a46d..94368536e 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -46,6 +46,7 @@ public: int idx; //!< menu node index int group; //!< menu group ID bool visible; //!< visibility status + int emptyEnabled; //!< enable empty menu flag NodeList children; //!< children menu nodes list }; @@ -54,7 +55,7 @@ public: \internal */ QtxActionMenuMgr::MenuNode::MenuNode() -: parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ) + : parent( 0 ), id( -1 ), idx( -1 ), group( -1 ), visible( true ), emptyEnabled( 0 ) { } @@ -70,7 +71,7 @@ QtxActionMenuMgr::MenuNode::MenuNode( MenuNode* p, const int _id, const int _idx, const int _group ) -: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ) +: parent( p ), id( _id ), idx( _idx ), group( _group ), visible( true ), emptyEnabled( 0 ) { if ( p ) p->children.append( this ); @@ -139,8 +140,9 @@ QtxActionMenuMgr::~QtxActionMenuMgr() { for ( MenuMap::Iterator itr = myMenus.begin(); itr != myMenus.end(); ++itr ) { - delete itr.value()->menu(); - delete itr.value(); + QPointer a = itr.value(); + delete a->menu(); + delete a; } delete myRoot; @@ -327,8 +329,9 @@ int QtxActionMenuMgr::insert( const QString& title, const int pId, const int gro int gid = (id == -1 || eNode ) ? generateId() : id; - QAction* ma = new QAction( title, this ); - ma->setMenu( new QMenu( 0 ) ); + QMenu* menu = new QMenu( 0 ); + QAction* ma = menu->menuAction(); + ma->setText( title ); connect( ma->menu(), SIGNAL( aboutToShow() ), this, SLOT( onAboutToShow() ) ); connect( ma->menu(), SIGNAL( aboutToHide() ), this, SLOT( onAboutToHide() ) ); @@ -853,17 +856,40 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo bool filled = checkWidget( mw ); - for ( NodeList::iterator it1 = node->children.begin(); it1 != node->children.end(); ++it1 ) + // first remove all own actions and collect foreign ones + QMap< QAction*, QList > foreign; + QAction* a; + QAction* preva = 0; + QListIterator ait( mw->actions() ); ait.toBack(); + while ( ait.hasPrevious() ) { - QAction* a = itemAction( (*it1)->id ); - if ( !a ) - a = menuAction( (*it1)->id ); - - mw->removeAction( a ); -// if ( a ) -// a->removeFrom( mw ); + a = ait.previous(); + if ( ownAction( a, node ) ) + { + preva = a; + mw->removeAction( a ); // remove own actions + } + else + { + foreign[preva].prepend(a); // do not yet remove foreign actions + } } + // now only foreign actions should stay in the menu, thus remove them also + QMap< QAction*, QList >::Iterator formapit; + for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit ) + { + QMutableListIterator foralit( formapit.value() ); + while ( foralit.hasNext() ) + { + a = foralit.next(); + if ( !mw->actions().contains( a ) ) + foralit.remove(); + } + } + QList alist = mw->actions(); + foreach( a, alist ) mw->removeAction( a ); + // collect all registered menus by group id QMap idMap; for ( NodeList::iterator it2 = node->children.begin(); it2 != node->children.end(); ++it2 ) { @@ -881,6 +907,7 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo groups.removeAll( -1 ); groups.append( -1 ); + // rebuild menu: 1. add all registered actions for ( QIntList::const_iterator gIt = groups.begin(); gIt != groups.end(); ++gIt ) { if ( !idMap.contains( *gIt ) ) @@ -890,6 +917,7 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo for ( NodeList::const_iterator iter = lst.begin(); iter != lst.end(); ++iter ) { MenuNode* node = *iter; + if ( !node ) continue; if ( rec ) updateMenu( node, rec, false ); @@ -905,14 +933,24 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo isMenu = true; a = menuAction( node->id ); } + if ( !a ) continue; - if ( !isMenu || !a->menu()->isEmpty() ) + if ( !isMenu || !a->menu()->isEmpty() || node->emptyEnabled > 0 ) mw->addAction( a ); } } + // rebuild menu: 2. insert back all foreign actions + for( formapit = foreign.begin(); formapit != foreign.end(); ++formapit ) { + preva = formapit.key(); + foreach( a, formapit.value() ) + mw->insertAction( preva, a ); + } + + // remove extra separators simplifySeparators( mw ); + // update parent menu if necessary if ( updParent && node->parent && filled != checkWidget( mw ) ) updateMenu( node->parent, false ); } @@ -931,6 +969,24 @@ void QtxActionMenuMgr::internalUpdate() myUpdateIds.clear(); } +/*! + \brief Check if action belongs to the menu manager + \internal + \param a action being checked + \param node parent menu node + \return \c true if action belongs to the menu \a node +*/ +bool QtxActionMenuMgr::ownAction( QAction* a, MenuNode* node ) const +{ + for ( NodeList::const_iterator iter = node->children.begin(); iter != node->children.end(); ++iter ) + { + QAction* mya = itemAction( (*iter)->id ); + if ( !mya ) mya = menuAction( (*iter)->id ); + if ( mya && mya == a ) return true; + } + return false; +} + /*! \brief Check if menu widget has any actions. \param wid widget to be checked @@ -1027,9 +1083,9 @@ bool QtxActionMenuMgr::load( const QString& fname, QtxActionMgr::Reader& r ) \param pid parent menu item ID \return \c true if parent menu item contains such child item */ -bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const +bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid, const bool rec ) const { - return (bool)find( title, pid, false ); + return (bool)find( title, pid, rec ); } /*! @@ -1038,9 +1094,9 @@ bool QtxActionMenuMgr::containsMenu( const QString& title, const int pid ) const \param pid parent menu item ID \return \c true if parent menu item contains such child item */ -bool QtxActionMenuMgr::containsMenu( const int id, const int pid ) const +bool QtxActionMenuMgr::containsMenu( const int id, const int pid, const bool rec ) const { - return (bool)find( id, pid, false ); + return (bool)find( id, pid, rec ); } /*! @@ -1057,6 +1113,56 @@ QMenu* QtxActionMenuMgr::findMenu( const int id ) const return m; } +/*! + \brief Get menu by the title. + \param title menu text + \param pid parent menu item ID (to start search) + \param rec if \c true, perform recursive update + \return menu pointer or 0 if menu is not found +*/ +QMenu* QtxActionMenuMgr::findMenu( const QString& title, const int pid, const bool rec ) const +{ + QMenu* m = 0; + MenuNode* node = find( title, pid, rec ); + if ( node ) + { + QAction* a = menuAction( node->id ); + if ( a ) + m = a->menu(); + } + return m; +} + +/*! + \brief Check if empty menu is enabled + \param id menu item ID + \return \c true if empty menu is enabled +*/ +bool QtxActionMenuMgr::isEmptyEnabled( const int id ) const +{ + MenuNode* node = find( id ); + if ( node && menuAction( id ) ) + return node->emptyEnabled > 0; + + return false; +} + +/*! + \brief Enable/disable empty menu + \param id menu item ID + \param enable if \c true, empty menu will be enabled, otherwise empty menu will be disabled +*/ +void QtxActionMenuMgr::setEmptyEnabled( const int id, const bool enable ) +{ + MenuNode* node = find( id ); + if ( node && menuAction( id ) ) { + int old = node->emptyEnabled; + node->emptyEnabled += enable ? 1 : -1; + if ( old <= 0 && enable || old > 0 && !enable ) // update menu only if enabled state has been changed + updateMenu( node, true, true ); + } +} + /*! \brief Perform delayed menu update. \param id menu item ID diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index 96d15b51b..6ee27cf61 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -90,10 +90,14 @@ public: virtual bool load( const QString&, QtxActionMgr::Reader& ); - bool containsMenu( const QString&, const int ) const; - bool containsMenu( const int, const int ) const; + bool containsMenu( const QString&, const int, const bool = false ) const; + bool containsMenu( const int, const int, const bool = false ) const; QMenu* findMenu( const int ) const; + QMenu* findMenu( const QString&, const int, const bool = false ) const; + + bool isEmptyEnabled( const int ) const; + void setEmptyEnabled( const int, const bool ); private slots: void onAboutToShow(); @@ -126,6 +130,7 @@ protected: virtual void updateContent(); private: + bool ownAction( QAction*, MenuNode* ) const; bool checkWidget( QWidget* ) const; QWidget* menuWidget( MenuNode* ) const; void simplifySeparators( QWidget* ); diff --git a/src/Qtx/QtxActionMgr.cxx b/src/Qtx/QtxActionMgr.cxx index a1aa362b5..053d5ab75 100644 --- a/src/Qtx/QtxActionMgr.cxx +++ b/src/Qtx/QtxActionMgr.cxx @@ -52,7 +52,7 @@ void qtxSeparatorActionCleanup() \internal */ -class QtxActionMgr::SeparatorAction : public QtxAction +class QtxActionMgr::SeparatorAction : public QAction { public: SeparatorAction( QObject* = 0 ); @@ -65,7 +65,7 @@ public: \param parent parent object */ QtxActionMgr::SeparatorAction::SeparatorAction( QObject* parent ) -: QtxAction( parent ) +: QAction( parent ) { setSeparator( true ); } diff --git a/src/Qtx/QtxActionMgr.h b/src/Qtx/QtxActionMgr.h index 98d99e3c6..d7c4d6a6d 100644 --- a/src/Qtx/QtxActionMgr.h +++ b/src/Qtx/QtxActionMgr.h @@ -118,7 +118,7 @@ public: protected: static int intValue( const ItemAttributes&, const QString&, const int ); static QString strValue( const ItemAttributes&, const QString&, - const QString& = QString::null ); + const QString& = QString() ); private: QtxActionMgr::Reader* myReader; //!< actions reader }; @@ -130,7 +130,7 @@ public: virtual ~Reader(); QStringList options() const; - QString option( const QString&, const QString& = QString::null ) const; + QString option( const QString&, const QString& = QString() ) const; void setOption( const QString&, const QString& ); virtual bool read( const QString&, Creator& ) const = 0; -- 2.39.2