From c31d06eabdb933da99a33671e4846d654bb7cdf7 Mon Sep 17 00:00:00 2001 From: stv Date: Tue, 14 Jun 2011 13:33:02 +0000 Subject: [PATCH] GEOM module context menu (popup) optimization. --- src/LightApp/LightApp_Application.cxx | 9 +- src/LightApp/LightApp_Module.cxx | 1 + src/LightApp/LightApp_Selection.cxx | 262 +++++++++++++++--------- src/LightApp/LightApp_Selection.h | 53 +++-- src/LightApp/LightApp_SelectionMgr.cxx | 250 ++++++++++++++++++---- src/LightApp/LightApp_SelectionMgr.h | 33 +++ src/Qtx/QtxPopupMgr.cxx | 22 +- src/Qtx/QtxPopupMgr.h | 7 + src/SalomeApp/SalomeApp_Application.cxx | 79 +++---- 9 files changed, 519 insertions(+), 197 deletions(-) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index edaa4b1a4..c1c5606cb 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -3106,8 +3106,11 @@ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopu { //Add "Rename" item LightApp_SelectionMgr* selMgr = LightApp_Application::selectionMgr(); + bool cacheIsOn = selMgr->isSelectionCacheEnabled(); + selMgr->setSelectionCacheEnabled( true ); + SUIT_DataBrowser* ob = objectBrowser(); - + CAM_Application::contextMenuPopup( type, thePopup, title ); if ( ob && type == ob->popupClientType() ) { @@ -3117,7 +3120,7 @@ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopu a->setShortcut( ob->shortcutKey(SUIT_DataBrowser::UpdateShortcut) ); } - if(selMgr && ob) { + if ( selMgr && ob ) { SALOME_ListIO selected; selMgr->selectedObjects( selected ); if(selected.Extent() == 1){ @@ -3135,6 +3138,8 @@ void LightApp_Application::contextMenuPopup( const QString& type, QMenu* thePopu } } } + + selMgr->setSelectionCacheEnabled( cacheIsOn ); } /*! diff --git a/src/LightApp/LightApp_Module.cxx b/src/LightApp/LightApp_Module.cxx index eb23e0cf8..811d4990c 100644 --- a/src/LightApp/LightApp_Module.cxx +++ b/src/LightApp/LightApp_Module.cxx @@ -138,6 +138,7 @@ void LightApp_Module::contextMenuPopup( const QString& client, QMenu* menu, QStr { LightApp_Selection* sel = createSelection(); sel->init( client, getApp()->selectionMgr() ); + popupMgr()->setSelection( sel ); popupMgr()->setMenu( menu ); popupMgr()->updateMenu(); diff --git a/src/LightApp/LightApp_Selection.cxx b/src/LightApp/LightApp_Selection.cxx index f33c1b970..27a722d7f 100644 --- a/src/LightApp/LightApp_Selection.cxx +++ b/src/LightApp/LightApp_Selection.cxx @@ -35,6 +35,8 @@ #include "SUIT_Desktop.h" #include "SUIT_Selector.h" +#include + /*! Constructor */ @@ -55,12 +57,12 @@ LightApp_Selection::~LightApp_Selection() */ void LightApp_Selection::init( const QString& client, LightApp_SelectionMgr* mgr) { - myPopupClient = client; - - if( mgr ) - { - if( mgr->application() ) + myContext = client; + + if ( mgr ) { + if ( mgr->application() ) myStudy = dynamic_cast( mgr->application()->activeStudy() ); + if( !myStudy ) return; @@ -75,43 +77,47 @@ void LightApp_Selection::init( const QString& client, LightApp_SelectionMgr* mgr while ( it.hasNext() ) { SUIT_Selector* selector = it.next(); - if( selector->type() != client && selector->isEnabled() ) - { - //mgr->selected( cur_sel, selector->type() ); + if ( selector->type() != client && selector->isEnabled() ) { selector->selected( cur_sel ); - SUIT_DataOwnerPtrList::const_iterator aLIt = cur_sel.begin(), aLLast = cur_sel.end(); - for( ; aLIt!=aLLast; aLIt++ ) + + for ( SUIT_DataOwnerPtrList::const_iterator aLIt = cur_sel.begin(); aLIt != cur_sel.end(); ++aLIt ) sel.append( *aLIt ); //check entry and don't append if such entry is in list already } } //3) to analyse owner and fill internal data structures - SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(), aLast = sel.end(); - QMap entries; - QString entry; - int num=0; - for( ; anIt!=aLast; anIt++ ) + + int num = 0; + QSet entries; + myObjects.resize( sel.size() ); + myObjects.fill( ObjectInfo() ); + for ( SUIT_DataOwnerPtrList::const_iterator anIt = sel.begin(); anIt != sel.end(); anIt++ ) { LightApp_DataOwner* sowner = dynamic_cast( (*anIt ).get() ); - if( sowner ) + if ( sowner ) { - entry = referencedToEntry( sowner->entry() ); - if( entries.contains( entry ) ) + QString entry = referencedToEntry( sowner->entry() ); + if ( entries.contains( entry ) ) continue; - entries.insert( entry, 0 ); - myEntries.insert( num, entry ); - myIsReferences.insert( num, sowner->entry() != entry ); - if (processOwner( sowner )) { + entries.insert( entry ); + + setObjectInfo( num, OI_Entry, entry ); + setObjectInfo( num, OI_Reference, sowner->entry() != entry ); + + if ( processOwner( sowner ) ) num++; - } - else { + else entries.remove( entry ); - myEntries.remove( num ); - myIsReferences.remove( num ); - } } } + + myObjects.resize( num ); + /* + myContextParams.clear(); + myObjectsParams.resize( num ); + myObjectsParams.fill( ParameterMap() ); + */ } } @@ -125,89 +131,124 @@ QString LightApp_Selection::referencedToEntry( const QString& entry ) const */ int LightApp_Selection::count() const { - return myEntries.count(); + return myObjects.size(); } /*! - Gets QVariant(); + Gets global parameters. */ -QVariant LightApp_Selection::parameter( const int ind, const QString& p ) const +/* +QVariant LightApp_Selection::parameter( const QString& p ) const { - LightApp_Application* app = dynamic_cast( myStudy ? myStudy->application() : 0 ); - if( !( ind>=0 && indmoduleTitle( parameter( ind, "component" ).toString() ); - LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false ); - // false in last parameter means that now we doesn't load module, if it isn't loaded - - bool vis = false; - if( d ) - vis = d->IsDisplayed( myEntries[ ind ] ); - else - { - LightApp_Displayer local_d; - vis = local_d.IsDisplayed( myEntries[ ind ] ); - } - return QVariant( vis ); - } - - else if( p=="component" ) - { - return myStudy->componentDataType( myEntries[ ind ] ); - } - - else if( p=="isComponent" ) - { - return QVariant( myStudy->isComponent( myEntries[ ind ] ) ); + QVariant v; + if ( myContextParams.contains( p ) ) + v = myContextParams[p]; + else + v = contextParameter( p ); + if ( !v.isValid() ) + v = QtxPopupSelection::parameter( p ); + LightApp_Selection* that = (LightApp_Selection*)this; + that->myContextParams.insert( p, v ); } + return v; +} +*/ - else if( p=="isReference" ) - return QVariant( isReference( ind ) ); - - else if( p=="displayer" ) - return parameter( ind, "component" ); - - else if( p=="canBeDisplayed" ) - { - QString mod_name = app->moduleTitle( parameter( ind, "component" ).toString() ); - LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false ); - // false in last parameter means that now we doesn't load module, if it isn't loaded - - if ( d ) - return d->canBeDisplayed( myEntries[ ind ] ); - else if ( myEntries[ ind ].startsWith( QObject::tr( "SAVE_POINT_DEF_NAME" ) ) ) // object is a Save Point object - return false; - - return true; - //now if displayer is null, it means, that according module isn't loaded, so that we allow to all display/erase - //operations under object +/*! + Gets the object parameter. +*/ + /* +QVariant LightApp_Selection::parameter( const int idx, const QString& p ) const +{ + QVariant v; + if ( 0 <= idx && idx < myObjectsParams.size() ) { + if ( myObjectsParams[idx].contains( p ) ) + v = myObjectsParams[idx][p]; + else { + v = objectParameter( idx, p ); + LightApp_Selection* that = (LightApp_Selection*)this; + that->myObjectsParams[idx].insert( p, v ); + } } - - return QVariant(); + return v; } - + */ /*! Gets global parameters. client, isActiveView, activeView etc. */ + //QVariant LightApp_Selection::contextParameter( const QString& p ) const QVariant LightApp_Selection::parameter( const QString& p ) const { - if ( p == "client" ) return QVariant( myPopupClient ); - else if ( p == "activeModule" ) - { + QVariant v; + + if ( p == "client" ) + v = myContext; + else if ( p == "activeModule" ) { LightApp_Application* app = dynamic_cast( myStudy->application() ); QString mod_name = app ? QString( app->activeModule()->name() ) : QString(); - //cout << "activeModule : " << mod_name.latin1() << endl; - if( !mod_name.isEmpty() ) - return mod_name; - else - return QVariant(); + if ( !mod_name.isEmpty() ) + v = mod_name; } - else if ( p == "isActiveView" ) return QVariant( (bool)activeVW() ); - else if ( p == "activeView" ) return QVariant( activeViewType() ); - else return QtxPopupSelection::parameter( p ); + else if ( p == "isActiveView" ) + v = activeVW() != 0; + else if ( p == "activeView" ) + v = activeViewType(); + else + v = QtxPopupSelection::parameter( p ); + + return v; +} + +/*! + Gets the object parameter. +*/ +//QVariant LightApp_Selection::objectParameter( const int idx, const QString& p ) const +QVariant LightApp_Selection::parameter( const int idx, const QString& p ) const +{ + LightApp_Application* app = 0; + if ( myStudy ) + app = dynamic_cast( myStudy->application() ); + + QVariant v; + if ( app ) { + QString e = entry( idx ); + if ( !e.isEmpty() ) { + if ( p == "isVisible" ) { + QString mod_name = app->moduleTitle( myStudy->componentDataType( e ) ); + LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false ); + // false in last parameter means that now we doesn't load module, if it isn't loaded + + bool vis = false; + if ( d ) + vis = d->IsDisplayed( e ); + else + vis = LightApp_Displayer().IsDisplayed( e ); + v = vis; + } + else if ( p == "component" || p == "displayer" ) + v = myStudy->componentDataType( e ); + else if ( p == "isComponent" ) + v = myStudy->isComponent( e ); + else if ( p == "isReference" ) + v = isReference( idx ); + else if ( p == "canBeDisplayed" ) { + QString mod_name = app->moduleTitle( myStudy->componentDataType( e ) ); + LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( mod_name, false ); + // false in last parameter means that now we doesn't load module, if it isn't loaded + + if ( d ) + v = d->canBeDisplayed( e ); + else if ( e.startsWith( QObject::tr( "SAVE_POINT_DEF_NAME" ) ) ) // object is a Save Point object + v = false; + else + v = true; + //now if displayer is null, it means, that according module isn't loaded, so that we allow to all display/erase + //operations under object + } + } + } + + return v; } /*! @@ -229,9 +270,8 @@ bool LightApp_Selection::processOwner( const LightApp_DataOwner* /*owner*/ ) */ QString LightApp_Selection::entry( const int index ) const { - if ( index >= 0 && index < count() ) - return myEntries[ index ]; - return QString(); + QVariant v = objectInfo( index, OI_Entry ); + return v.canConvert( QVariant::String ) ? v.toString() : QString(); } /*! @@ -239,10 +279,8 @@ QString LightApp_Selection::entry( const int index ) const */ bool LightApp_Selection::isReference( const int index ) const { - if( index >= 0 && index < count() ) - return myIsReferences[ index ]; - else - return false; + QVariant v = objectInfo( index, OI_Reference ); + return v.canConvert( QVariant::Bool ) ? v.toBool() : false; } /*! @@ -269,9 +307,31 @@ SUIT_ViewWindow* LightApp_Selection::activeVW() const SUIT_Application* app = session->activeApplication(); if ( app ) { SUIT_Desktop* desk = app->desktop(); - if ( desk ) + if ( desk ) return desk->activeWindow(); } } return 0; } + +/*! + Gets specified information about object with index idx. +*/ +QVariant LightApp_Selection::objectInfo( const int idx, const int inf ) const +{ + QVariant res; + if ( 0 <= idx && idx < myObjects.size() ) { + if ( myObjects[idx].contains( inf ) ) + res = myObjects[idx][inf]; + } + return res; +} + +/*! + Sets specified information about object with index idx. +*/ +void LightApp_Selection::setObjectInfo( const int idx, const int inf, const QVariant& val ) +{ + if ( 0 <= idx && idx < myObjects.size() ) + myObjects[idx].insert( inf, val ); +} diff --git a/src/LightApp/LightApp_Selection.h b/src/LightApp/LightApp_Selection.h index 491584db8..20aae9110 100644 --- a/src/LightApp/LightApp_Selection.h +++ b/src/LightApp/LightApp_Selection.h @@ -46,32 +46,53 @@ class SUIT_ViewWindow; */ class LIGHTAPP_EXPORT LightApp_Selection : public QtxPopupSelection { +protected: + typedef enum { OI_Entry, OI_Reference, OI_User } ObjectInformation; + public: LightApp_Selection(); virtual ~LightApp_Selection(); - virtual void init( const QString&, LightApp_SelectionMgr* ); - virtual bool processOwner( const LightApp_DataOwner* ); + virtual void init( const QString&, LightApp_SelectionMgr* ); + virtual bool processOwner( const LightApp_DataOwner* ); - virtual int count() const; - virtual QVariant parameter( const int, const QString& ) const; - virtual QVariant parameter( const QString& ) const; - void setModuleName( const QString ); + virtual int count() const; + virtual QVariant parameter( const QString& ) const; + virtual QVariant parameter( const int, const QString& ) const; + void setModuleName( const QString ); protected: - QString entry( const int ) const; - bool isReference( const int ) const; + // virtual QVariant contextParameter( const QString& ) const; + // virtual QVariant objectParameter( const int, const QString& ) const; + + QString entry( const int ) const; + bool isReference( const int ) const; + /*!Gets study.*/ - LightApp_Study* study() const { return myStudy; } - QString activeViewType() const; - SUIT_ViewWindow* activeVW() const; - virtual QString referencedToEntry( const QString& ) const; + LightApp_Study* study() const { return myStudy; } + QString activeViewType() const; + SUIT_ViewWindow* activeVW() const; + virtual QString referencedToEntry( const QString& ) const; + + QVariant objectInfo( const int, const int ) const; + void setObjectInfo( const int, const int, const QVariant& ); private: - QString myPopupClient; - QMap myEntries; // entries of selected objects - QMap myIsReferences; // whether i-th selected object was a reference - LightApp_Study* myStudy; + typedef QMap ObjectInfo; + typedef QVector ObjectInfoVector; + /* + typedef QMap ParameterMap; + typedef QVector ObjectParamVector; + */ +private: + LightApp_Study* myStudy; + QString myContext; + + ObjectInfoVector myObjects; + /* + ParameterMap myContextParams; + ObjectParamVector myObjectsParams; + */ }; #endif diff --git a/src/LightApp/LightApp_SelectionMgr.cxx b/src/LightApp/LightApp_SelectionMgr.cxx index b260ca0af..6b9e46417 100644 --- a/src/LightApp/LightApp_SelectionMgr.cxx +++ b/src/LightApp/LightApp_SelectionMgr.cxx @@ -28,6 +28,7 @@ #include "LightApp_Application.h" #include +#include #ifndef DISABLE_SALOMEOBJECT #include @@ -40,12 +41,16 @@ #include #endif +#include + /*! Constructor. */ LightApp_SelectionMgr::LightApp_SelectionMgr( LightApp_Application* app, const bool fb ) : SUIT_SelectionMgr( fb ), -myApp( app ) + myApp( app ), + myTimeStamp( QTime::currentTime() ), + myCacheState( false ) { } @@ -64,6 +69,13 @@ LightApp_Application* LightApp_SelectionMgr::application() const return myApp; } +void LightApp_SelectionMgr::setSelected( const SUIT_DataOwnerPtrList& lst, const bool append ) +{ + SUIT_SelectionMgr::setSelected( lst, append ); + + myTimeStamp = QTime::currentTime(); +} + #ifndef DISABLE_SALOMEOBJECT /*! Get all selected objects from selection manager @@ -74,43 +86,75 @@ void LightApp_SelectionMgr::selectedObjects( SALOME_ListIO& theList, const QStri LightApp_Study* study = dynamic_cast( application()->activeStudy() ); if ( !study ) return; + theList.Clear(); - SUIT_DataOwnerPtrList aList; - selected( aList, theType ); + QList selList; - QMap entryMap; + if ( isActualSelectionCache( theType ) ) { + selList = selectionCache( theType ); + } + else { + QStringList types; + if ( !theType.isEmpty() ) + types.append( theType ); + else + types = selectorTypes(); + + QSet aSet; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + SUIT_DataOwnerPtrList aList; + selected( aList, *it ); + + QList typeSelList; + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( !owner ) + continue; + + if ( !aSet.contains( owner->entry() ) ) { + selList.append( owner->IO() ); + aSet.insert( owner->entry() ); + } + + typeSelList.append( owner->IO() ); + } - QString entry, checkEntry; - for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) - { - const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); - if( !owner ) - continue; + if ( isSelectionCacheEnabled() ) { + LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this; + that->myCacheSelection.insert( *it, typeSelList ); + that->myCacheTimes.insert( *it, QTime::currentTime() ); + } + } + } - entry = owner->entry(); + QSet entrySet; + for ( QList::const_iterator itr = selList.begin(); itr != selList.end(); ++itr ) + { + Handle(SALOME_InteractiveObject) io = *itr; + QString entry( io->getEntry() ); // Entry to check object uniqueness. // It is selected owner entry in the case, when we do not convert references, // and entry of a real object, when we convert references. - checkEntry = entry; if ( convertReferences ) { QString refEntry = study->referencedToEntry( entry ); - checkEntry = refEntry; - if ( !entryMap.contains( checkEntry ) ) { + if ( !entrySet.contains( refEntry ) ) { if ( refEntry != entry ) { - QString component = study->componentDataType( refEntry ); - theList.Append( new SALOME_InteractiveObject( refEntry.toLatin1().constData(), component.toLatin1().constData(), ""/*refobj->Name().c_str()*/ ) ); + entry = refEntry; + QString component = study->componentDataType( entry ); + theList.Append( new SALOME_InteractiveObject( (const char*)entry.toLatin1(), + (const char*)component.toLatin1(), + ""/*refobj->Name().c_str()*/ ) ); } - else if( !owner->IO().IsNull() ) - theList.Append( owner->IO() ); + else if ( !io.IsNull() ) + theList.Append( io ); } } - else { - if( !entryMap.contains( entry ) && !owner->IO().IsNull() ) - theList.Append( owner->IO() ); - } + else if ( !entrySet.contains( entry ) && !io.IsNull() ) + theList.Append( io ); - entryMap.insert(checkEntry, 1); + entrySet.insert( entry ); } } @@ -139,23 +183,49 @@ void LightApp_SelectionMgr::selectedObjects( QStringList& theList, const QString LightApp_Study* study = dynamic_cast( application()->activeStudy() ); if ( !study ) return; - + theList.clear(); - SUIT_DataOwnerPtrList aList; - selected( aList, theType ); + QStringList selList; - QString entry; - for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) - { - const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); - if( !owner ) - continue; + if ( isActualSelectionCache( theType ) ) + selList = selectionCache( theType ); + else { + QStringList types; + if ( !theType.isEmpty() ) + types.append( theType ); + else + types = selectorTypes(); + + QSet aSet; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + SUIT_DataOwnerPtrList aList; + selected( aList, *it ); + + QStringList typeSelList; + + for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) { + const LightApp_DataOwner* owner = dynamic_cast( (*itr).operator->() ); + if ( !owner ) + continue; + + if ( !aSet.contains( owner->entry() ) ) { + selList.append( owner->entry() ); + aSet.insert( owner->entry() ); + } - entry = owner->entry(); - if( !theList.contains( entry ) ) - theList.append( entry ); + typeSelList.append( owner->entry() ); + } + + if ( isSelectionCacheEnabled() ) { + LightApp_SelectionMgr* that = (LightApp_SelectionMgr*)this; + that->myCacheSelection.insert( *it, typeSelList ); + that->myCacheTimes.insert( *it, QTime::currentTime() ); + } + } } + + theList = selList; } #endif @@ -167,6 +237,8 @@ void LightApp_SelectionMgr::selectionChanged( SUIT_Selector* theSel ) { SUIT_SelectionMgr::selectionChanged( theSel ); + myTimeStamp = QTime::currentTime(); + emit currentSelectionChanged(); } @@ -280,7 +352,6 @@ void LightApp_SelectionMgr::selectObjects( const Handle(SALOME_InteractiveObject } setSelected( aList, append ); - } /*! @@ -304,7 +375,6 @@ void LightApp_SelectionMgr::selectObjects( MapIOOfMapOfInteger theMapIO, bool ap } setSelected( aList, append ); - } /*! @@ -350,3 +420,109 @@ void LightApp_SelectionMgr::selectedSubOwners( MapEntryOfMapOfInteger& theMap ) } #endif + +void LightApp_SelectionMgr::clearSelectionCache() +{ + myCacheTimes.clear(); + myCacheSelection.clear(); +} + +bool LightApp_SelectionMgr::isSelectionCacheEnabled() const +{ + return myCacheState; +} + +void LightApp_SelectionMgr::setSelectionCacheEnabled( bool on ) +{ + if ( myCacheState == on ) + return; + + myCacheState = on; + + if ( !myCacheState ) + clearSelectionCache(); +} + +#ifndef DISABLE_SALOMEOBJECT + +QList LightApp_SelectionMgr::selectionCache( const QString& type ) const +{ + QList res; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + QSet set; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + if ( myCacheSelection.contains( *it ) ) { + const SelList& lst = myCacheSelection[*it]; + for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) { + if ( !set.contains( (*itr)->getEntry() ) ) { + res.append( *itr ); + set.insert( (*itr)->getEntry() ); + } + } + } + } + return res; +} + +#else + +QStringList LightApp_SelectionMgr::selectionCache( const QString& type ) const +{ + QStringList res; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + QSet set; + for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) { + if ( myCacheSelection.contains( *it ) ) { + const SelList& lst = myCacheSelection[*it]; + for ( SelList::const_iterator itr = lst.begin(); itr != lst.end(); ++itr ) { + if ( !set.contains( *itr ) ) { + res.append( *itr ); + set.insert( *itr ); + } + } + } + } + return res; +} + +#endif + +bool LightApp_SelectionMgr::isActualSelectionCache( const QString& type ) const +{ + bool ok = true; + + QStringList types; + if ( !type.isEmpty() ) + types.append( type ); + else + types = selectorTypes(); + + for ( QStringList::iterator it = types.begin(); it != types.end() && ok; ++it ) + ok = myCacheTimes.contains( *it ) && myCacheTimes[*it].isValid() && myCacheTimes[*it] >= myTimeStamp; + + return ok; +} + +QStringList LightApp_SelectionMgr::selectorTypes() const +{ + QStringList types; + QList selectorList; + selectors( selectorList ); + for ( QList::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) { + if ( (*it)->isEnabled() ) + types.append( (*it)->type() ); + } + return types; +} diff --git a/src/LightApp/LightApp_SelectionMgr.h b/src/LightApp/LightApp_SelectionMgr.h index 01661954d..bb6f48633 100644 --- a/src/LightApp/LightApp_SelectionMgr.h +++ b/src/LightApp/LightApp_SelectionMgr.h @@ -27,6 +27,8 @@ #include +#include + #ifndef DISABLE_SALOMEOBJECT #include #include @@ -56,6 +58,8 @@ public: LightApp_Application* application() const; + virtual void setSelected( const SUIT_DataOwnerPtrList&, const bool = false ); + #ifndef DISABLE_SALOMEOBJECT typedef NCollection_DataMap< Handle(SALOME_InteractiveObject), TColStd_IndexedMapOfInteger > MapIOOfMapOfInteger; typedef NCollection_DataMap< TCollection_AsciiString, TColStd_IndexedMapOfInteger > MapEntryOfMapOfInteger; @@ -82,14 +86,43 @@ public: void selectedObjects( QStringList&, const QString& = QString(), const bool = true ) const; #endif + void clearSelectionCache(); + bool isSelectionCacheEnabled() const; + void setSelectionCacheEnabled( bool ); + signals: void currentSelectionChanged(); private: virtual void selectionChanged( SUIT_Selector* ); +#ifndef DISABLE_SALOMEOBJECT + QList selectionCache( const QString& = QString() ) const; +#else + QStringList selectionCache( const QString& = QString() ) const; +#endif + bool isActualSelectionCache( const QString& = QString() ) const; + + QStringList selectorTypes() const; + +private: +#ifndef DISABLE_SALOMEOBJECT + typedef Handle_SALOME_InteractiveObject SelObject; +#else + typedef QString SelObject; +#endif + typedef QList SelList; + typedef QMap TimeMap; + typedef QMap CacheMap; + private: LightApp_Application* myApp; + + QTime myTimeStamp; + + bool myCacheState; + TimeMap myCacheTimes; + CacheMap myCacheSelection; }; #endif diff --git a/src/Qtx/QtxPopupMgr.cxx b/src/Qtx/QtxPopupMgr.cxx index 1f4385ec6..ac1b600ce 100644 --- a/src/Qtx/QtxPopupMgr.cxx +++ b/src/Qtx/QtxPopupMgr.cxx @@ -286,8 +286,11 @@ void QtxPopupMgr::setSelection( QtxPopupSelection* sel ) mySelection = sel; - if ( mySelection ) + if ( mySelection ) { mySelection->setParent( this ); + mySelection->setPopupMgr( this ); + } + connect( mySelection, SIGNAL( destroyed( QObject* ) ), this, SLOT( onSelectionDestroyed( QObject* ) ) ); @@ -676,7 +679,8 @@ void QtxPopupMgr::onSelectionDestroyed( QObject* o ) \brief Constructor. */ QtxPopupSelection::QtxPopupSelection() -: QObject( 0 ) + : QObject( 0 ), + myPopupMgr( 0 ) { } @@ -710,6 +714,16 @@ void QtxPopupSelection::setOption( const QString& optName, const QString& opt ) myOptions.insert( optName, opt ); } +QtxPopupMgr* QtxPopupSelection::popupMgr() const +{ + return myPopupMgr; +} + +void QtxPopupSelection::setPopupMgr( QtxPopupMgr* pm ) +{ + myPopupMgr = pm; +} + /*! \brief Get the parameter value. \param str parameter name @@ -723,9 +737,11 @@ QVariant QtxPopupSelection::parameter( const QString& str ) const { QtxEvalSetSets::ValueSet set; QString par = str.mid( equalityParam().length() ); + + QtxPopupMgr* pMgr = popupMgr(); for ( int i = 0; i < (int)count(); i++ ) { - QVariant v = parameter( i, par ); + QVariant v = pMgr ? pMgr->parameter( par, i ) : parameter( i, par ); if ( v.isValid() ) QtxEvalSetSets::add( set, v ); else diff --git a/src/Qtx/QtxPopupMgr.h b/src/Qtx/QtxPopupMgr.h index 729f612bc..69ffe6b8c 100644 --- a/src/Qtx/QtxPopupMgr.h +++ b/src/Qtx/QtxPopupMgr.h @@ -105,6 +105,8 @@ private: RuleMap myRules; CacheMap myCache; QtxPopupSelection* mySelection; + + friend class QtxPopupSelection; }; class QTX_EXPORT QtxPopupSelection : public QObject @@ -122,15 +124,20 @@ public: QString option( const QString& ) const; void setOption( const QString&, const QString& ); + QtxPopupMgr* popupMgr() const; + void setPopupMgr( QtxPopupMgr* ); + private: QString equalityParam() const; QString selCountParam() const; private: typedef QMap OptionsMap; + typedef QPointer PopupMgrPtr; private: OptionsMap myOptions; + PopupMgrPtr myPopupMgr; }; #endif // QTXPOPUPMGR_H diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index 97c8c1590..fcac1c19d 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -1261,6 +1261,10 @@ void SalomeApp_Application::onProperties() /*!Insert items in popup, which necessary for current application*/ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePopup, QString& title ) { + LightApp_SelectionMgr* mgr = selectionMgr(); + bool cacheIsOn = mgr->isSelectionCacheEnabled(); + mgr->setSelectionCacheEnabled( true ); + LightApp_Application::contextMenuPopup( type, thePopup, title ); // temporary commented @@ -1270,7 +1274,6 @@ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePop // Get selected objects SALOME_ListIO aList; - LightApp_SelectionMgr* mgr = selectionMgr(); mgr->selectedObjects( aList, QString(), false ); // add GUI state commands: restore, rename @@ -1310,49 +1313,49 @@ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePop return; } - aList.Clear(); - mgr->selectedObjects( aList ); - // "Activate module" item should appear only if it's necessary - if (aList.Extent() != 1) - return; - Handle(SALOME_InteractiveObject) aIObj = aList.First(); + if ( aList.Extent() == 1 ) { + aList.Clear(); + mgr->selectedObjects( aList ); - // add extra popup menu (defined in XML) - if (myExtActions.size() > 0) { - // Use only first selected object - SalomeApp_Study* study = dynamic_cast(activeStudy()); - if ( study ) { - _PTR(Study) stdDS = study->studyDS(); - if ( stdDS ) { - _PTR(SObject) aSO = stdDS->FindObjectID( aIObj->getEntry() ); - if ( aSO ) { - _PTR( GenericAttribute ) anAttr; - std::string auid = "AttributeUserID"; - auid += Kernel_Utils::GetGUID(Kernel_Utils::ObjectdID); - if ( aSO->FindAttribute( anAttr, auid ) ) { - _PTR(AttributeUserID) aAttrID = anAttr; - QString aId = aAttrID->Value().c_str(); - if ( myExtActions.contains( aId ) ) { - thePopup->addAction(myExtActions[aId]); - } - } - } + Handle(SALOME_InteractiveObject) aIObj = aList.First(); + + // add extra popup menu (defined in XML) + if ( myExtActions.size() > 0 ) { + // Use only first selected object + SalomeApp_Study* study = dynamic_cast( activeStudy() ); + if ( study ) { + _PTR(Study) stdDS = study->studyDS(); + if ( stdDS ) { + _PTR(SObject) aSO = stdDS->FindObjectID( aIObj->getEntry() ); + if ( aSO ) { + _PTR( GenericAttribute ) anAttr; + std::string auid = "AttributeUserID"; + auid += Kernel_Utils::GetGUID(Kernel_Utils::ObjectdID); + if ( aSO->FindAttribute( anAttr, auid ) ) { + _PTR(AttributeUserID) aAttrID = anAttr; + QString aId = aAttrID->Value().c_str(); + if ( myExtActions.contains( aId ) ) { + thePopup->addAction(myExtActions[aId]); + } + } + } + } } } + + // check if item is a "GUI state" item (also a first level object) + QString entry( aIObj->getEntry() ); + if ( !entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) { + QString aModuleName( aIObj->getComponentDataType() ); + QString aModuleTitle = moduleTitle( aModuleName ); + CAM_Module* currentModule = activeModule(); + if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() ) + thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) ); + } } - // check if item is a "GUI state" item (also a first level object) - QString entry( aIObj->getEntry() ); - if ( entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) - return; - QString aModuleName(aIObj->getComponentDataType()); - QString aModuleTitle = moduleTitle(aModuleName); - CAM_Module* currentModule = activeModule(); - if (currentModule && currentModule->moduleName() == aModuleTitle) - return; - if ( !aModuleTitle.isEmpty() ) - thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) ); + mgr->setSelectionCacheEnabled( cacheIsOn ); } /*!Update obect browser: -- 2.39.2