]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
GEOM module context menu (popup) optimization.
authorstv <stv@opencascade.com>
Tue, 14 Jun 2011 13:33:02 +0000 (13:33 +0000)
committerstv <stv@opencascade.com>
Tue, 14 Jun 2011 13:33:02 +0000 (13:33 +0000)
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Module.cxx
src/LightApp/LightApp_Selection.cxx
src/LightApp/LightApp_Selection.h
src/LightApp/LightApp_SelectionMgr.cxx
src/LightApp/LightApp_SelectionMgr.h
src/Qtx/QtxPopupMgr.cxx
src/Qtx/QtxPopupMgr.h
src/SalomeApp/SalomeApp_Application.cxx

index edaa4b1a4ea0f2ca5770fbd16d490e4385df86db..c1c5606cb3d05c1d272193faca0e3904caa2c3a5 100644 (file)
@@ -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 );
 }
 
 /*!
index eb23e0cf8aff1d835d902b137f02ab42094af399..811d4990c7f1489b28c3ba89fbd9478280c46c53 100644 (file)
@@ -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();
index f33c1b970ec8c82b25345dff0be393f97adde180..27a722d7f9e81d12081ccca0b967311d11ff9c30 100644 (file)
@@ -35,6 +35,8 @@
 #include "SUIT_Desktop.h"
 #include "SUIT_Selector.h"
 
+#include <QtCore/QSet>
+
 /*!
   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<LightApp_Study*>( 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<QString,int> entries;
-    QString entry;
-    int num=0;
-    for( ; anIt!=aLast; anIt++ )
+
+    int num = 0;
+    QSet<QString> 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<LightApp_DataOwner*>( (*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<LightApp_Application*>( myStudy ? myStudy->application() : 0 );
-  if( !( ind>=0 && ind<count() ) || !app )
-    return QVariant();
-
-  if( p=="isVisible" )
-  {
-    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
-
-    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<LightApp_Application*>( 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<LightApp_Application*>( 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 );
+}
index 491584db8f89bcf56a45e8daad234912e8019607..20aae911051a1b2ef01b2ce7aef2aa9d68388c13 100644 (file)
@@ -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<int,QString>              myEntries; // entries of selected objects
-  QMap<int,bool>                 myIsReferences; // whether i-th selected object was a reference
-  LightApp_Study*                myStudy;
+  typedef QMap<int, QVariant>     ObjectInfo;
+  typedef QVector<ObjectInfo>     ObjectInfoVector;
+  /*
+  typedef QMap<QString, QVariant> ParameterMap;
+  typedef QVector<ParameterMap>   ObjectParamVector;
+  */
+private:
+  LightApp_Study*                 myStudy;
+  QString                         myContext;
+  ObjectInfoVector                myObjects;
+  /*
+  ParameterMap                    myContextParams;
+  ObjectParamVector               myObjectsParams;
+  */
 };
 
 #endif
index b260ca0af52d3b4559bf33f3c8ac80fb0c529be0..6b9e46417d86279a85b94310a1c3894141214d8c 100644 (file)
@@ -28,6 +28,7 @@
 #include "LightApp_Application.h"
 
 #include <SUIT_Session.h>
+#include <SUIT_Selector.h>
 
 #ifndef DISABLE_SALOMEOBJECT
   #include <SALOME_ListIO.hxx>
   #include <TCollection_AsciiString.hxx>
 #endif
 
+#include <QtCore/QSet>
+
 /*!
   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<LightApp_Study*>( application()->activeStudy() );
   if ( !study )
     return;
+  
   theList.Clear();
 
-  SUIT_DataOwnerPtrList aList;
-  selected( aList, theType );
+  QList<Handle(SALOME_InteractiveObject)> selList;
 
-  QMap<QString,int> entryMap;
+  if ( isActualSelectionCache( theType ) ) {
+    selList = selectionCache( theType );
+  }
+  else {
+    QStringList types;
+    if ( !theType.isEmpty() )
+      types.append( theType );
+    else
+      types = selectorTypes();
+
+    QSet<QString> aSet;
+    for ( QStringList::iterator it = types.begin(); it != types.end(); ++it ) {
+      SUIT_DataOwnerPtrList aList;
+      selected( aList, *it );
+
+      QList<Handle(SALOME_InteractiveObject)> typeSelList;
+
+      for ( SUIT_DataOwnerPtrList::const_iterator itr = aList.begin(); itr != aList.end(); ++itr ) {
+       const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*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<const LightApp_DataOwner*>( (*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<QString> entrySet;
+  for ( QList<Handle(SALOME_InteractiveObject)>::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<LightApp_Study*>( 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<const LightApp_DataOwner*>( (*itr).operator->() );
-    if( !owner )
-      continue;
+  if ( isActualSelectionCache( theType ) )
+    selList = selectionCache( theType );
+  else {
+    QStringList types;
+    if ( !theType.isEmpty() )
+      types.append( theType );
+    else
+      types = selectorTypes();
+
+    QSet<QString> 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<const LightApp_DataOwner*>( (*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<Handle_SALOME_InteractiveObject> LightApp_SelectionMgr::selectionCache( const QString& type ) const
+{
+  QList<Handle_SALOME_InteractiveObject> res;
+
+  QStringList types;
+  if ( !type.isEmpty() )
+    types.append( type );
+  else
+    types = selectorTypes();
+
+  QSet<QString> 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<QString> 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<SUIT_Selector*> selectorList;
+  selectors( selectorList );
+  for ( QList<SUIT_Selector*>::const_iterator it = selectorList.begin(); it != selectorList.end(); ++it ) {
+    if ( (*it)->isEnabled() )
+      types.append( (*it)->type() );
+  }
+  return types;
+}
index 01661954df7ce78f4ac296f48eab3d9d125d82e9..bb6f486338764d80550d7fa43f0dd0e235d25a5b 100644 (file)
@@ -27,6 +27,8 @@
 
 #include <SUIT_SelectionMgr.h>
 
+#include <QtCore/QTime>
+
 #ifndef DISABLE_SALOMEOBJECT
   #include <SALOME_InteractiveObject.hxx>
   #include <QMap>
@@ -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<Handle_SALOME_InteractiveObject> 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<SelObject>             SelList;
+  typedef QMap<QString, QTime>         TimeMap;
+  typedef QMap<QString, SelList>       CacheMap;
+
 private:
   LightApp_Application* myApp;
+
+  QTime                 myTimeStamp;
+
+  bool                  myCacheState;
+  TimeMap               myCacheTimes;
+  CacheMap              myCacheSelection;
 };
 
 #endif
index 1f4385ec6d410abeed50987d88f8f75e0480f1d6..ac1b600ce160d00c49a63c2e16f0ea78edc3a348 100644 (file)
@@ -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
index 729f612bc272a1aa50fd950d48dbc406a718dfa7..69ffe6b8cd3b3c1fbed3f3a3c0cef0f0db699bfe 100644 (file)
@@ -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<QString, QString> OptionsMap;
+  typedef QPointer<QtxPopupMgr>  PopupMgrPtr;
 
 private:
   OptionsMap         myOptions;
+  PopupMgrPtr        myPopupMgr;
 };
 
 #endif // QTXPOPUPMGR_H
index 97c8c1590d0ab8f2411e4f1899ed8f57039eda0f..fcac1c19d2650852d927d196f9e1723834e8c987 100644 (file)
@@ -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<SalomeApp_Study*>(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<SalomeApp_Study*>( 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: