Salome HOME
Copyright update 2022
[modules/geom.git] / src / Material / Material_ResourceMgr.cxx
index 97853f5326ec8f5d5923796e3d72f3385bb9b02f..a6fd4d4d9db060d465656ff525a685b6bdc7d161 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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.
+// 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
 
 #include "Material_ResourceMgr.h"
 
+#include <QFileInfo>
+#include <QFileSystemWatcher>
+#include <QThread>
+
+/*!
+  \class Material_ResourceMgr::Updater
+  \brief Updates the contents of the resource manager as soon as
+  user materials database file is changed
+  \internal
+*/
+class Material_ResourceMgr::Updater : public QThread
+{
+public:
+  Material_ResourceMgr* myResourceMgr;
+  Updater( Material_ResourceMgr* resMgr ) : myResourceMgr( resMgr )
+  {
+    start();
+  }
+  void run()
+  {
+    QMutexLocker lock( &myResourceMgr->myMutex );
+    myResourceMgr->clear();
+    myResourceMgr->load();
+  }
+};
+
 /*!
   \class Material_ResourceMgr
   \brief Material properties resources manager.
@@ -41,7 +67,8 @@
   \brief Constructor
 */
 Material_ResourceMgr::Material_ResourceMgr()
-  : QtxResourceMgr( "SalomeMaterial", "%1Config" )
+  : QtxResourceMgr( "SalomeMaterial", "%1Config" ),
+    myWatcher( 0 )
 {
   if ( dirList().isEmpty() && ::getenv( "GEOM_ROOT_DIR" ) )
     setDirList( QStringList() << Qtx::addSlash( ::getenv( "GEOM_ROOT_DIR" ) ) + "share/salome/resources/geom" );
@@ -53,16 +80,36 @@ Material_ResourceMgr::Material_ResourceMgr()
 */
 Material_ResourceMgr::~Material_ResourceMgr()
 {
+  watchUserFile( false );
+}
+
+/*!
+  \brief Get shared instance of resources manager
+  
+  This instance of resource manager is global for the application;
+  it watches for changes in the user materials database file to
+  maintain the fresh version of the materials data.
+*/
+Material_ResourceMgr* Material_ResourceMgr::resourceMgr()
+{
+  static Material_ResourceMgr* resMgr = 0;
+  if ( !resMgr ) {
+    resMgr = new Material_ResourceMgr();
+    resMgr->watchUserFile( true );
+  }
+  return resMgr;
 }
 
 /*!
-  \brief Get list of avaiable materials
+  \brief Get list of available materials
   \param theType material type
   \param theSort if \c true (default), returns a list of materials sorted by name
-  \return list of avaiable materials names
+  \return list of available materials names
 */
 QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort )
 {
+  QMutexLocker lock( &myMutex );
+
   // store original working mode
   WorkingMode m = workingMode();
 
@@ -94,6 +141,11 @@ QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort
     qSort( slglobal );
     qSort( sluser );
   }
+  // special processing for default material (to make it first in the list)
+  if ( slglobal.contains( "[ Default ]" ) ) {
+    slglobal.removeAll( "[ Default ]" );
+    slglobal.prepend( "[ Default ]" );
+  }
 
   // combine the materials to obtain result list
   QStringList result;
@@ -114,3 +166,56 @@ QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort
 
   return result;
 }
+
+/*!
+  \brief Start/stop this resource manager watching the user materials database file.
+  \internal
+*/
+void Material_ResourceMgr::watchUserFile( bool on )
+{
+  if ( on ) {
+    if ( !myWatcher ) {
+      myWatcher = new QFileSystemWatcher( this );
+      QFileInfo ufile = userFileName( appName() );
+      if ( ufile.exists() ) {
+        myWatcher->addPath( ufile.filePath() );
+      }
+      connect( myWatcher, SIGNAL( fileChanged( QString ) ), this, SLOT( update() ) );
+    }
+  }
+  else {
+    if ( myWatcher ) {
+      delete myWatcher;
+      myWatcher = 0;
+    }
+  }
+}
+
+/*!
+  \brief This function is called after user configuration file is saved.
+  \internal
+*/
+void Material_ResourceMgr::saved()
+{
+  if ( resourceMgr() != this ) {
+    resourceMgr()->saved();
+  }
+  else if ( myWatcher ) {
+    QStringList files = myWatcher->files();
+    QFileInfo ufile = userFileName( appName() );
+    if ( ufile.exists() && !files.contains( ufile.filePath() ) ) {
+      myWatcher->addPath( ufile.filePath() );
+      update();
+    }
+  }
+}
+
+/*!
+  \brief Update user database slot
+  \internal
+*/
+void Material_ResourceMgr::update()
+{
+  Updater( this ).wait();
+  emit changed();
+}