Salome HOME
433530f819c20b62265090d68312acc993b5e4df
[modules/geom.git] / src / Material / Material_ResourceMgr.cxx
1 // Copyright (C) 2007-2023  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // File   : Material_ResourceMgr.cxx
21 // Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
22
23 #include "Material_ResourceMgr.h"
24
25 #include <QFileInfo>
26 #include <QFileSystemWatcher>
27 #include <QThread>
28
29 /*!
30   \class Material_ResourceMgr::Updater
31   \brief Updates the contents of the resource manager as soon as
32   user materials database file is changed
33   \internal
34 */
35 class Material_ResourceMgr::Updater : public QThread
36 {
37 public:
38   Material_ResourceMgr* myResourceMgr;
39   Updater( Material_ResourceMgr* resMgr ) : myResourceMgr( resMgr )
40   {
41     start();
42   }
43   void run()
44   {
45     QMutexLocker lock( &myResourceMgr->myMutex );
46     myResourceMgr->clear();
47     myResourceMgr->load();
48   }
49 };
50
51 /*!
52   \class Material_ResourceMgr
53   \brief Material properties resources manager.
54
55   This class is used to manage the material properties throughout the application
56   in the similar way as QtxResourceMgr does it with application preferences.
57
58   Standard material types are stored in the global application settings files
59   (named as SalomeMaterial.xml). User-defined materials are stored in user's home
60   directory - in the file .SalomeMaterialrc.
61
62   The Material_ResourceMgr class is used by material properties dialog box
63   (GEOMToolsGUI_MaterialPropertiesDlg class).
64 */
65
66 /*!
67   \brief Constructor
68 */
69 Material_ResourceMgr::Material_ResourceMgr()
70   : QtxResourceMgr( "SalomeMaterial", "%1Config" ),
71     myWatcher( 0 )
72 {
73   if ( dirList().isEmpty() && ::getenv( "GEOM_ROOT_DIR" ) )
74     setDirList( QStringList() << Qtx::addSlash( ::getenv( "GEOM_ROOT_DIR" ) ) + "share/salome/resources/geom" );
75   setCurrentFormat( "xml" );
76 }
77
78 /*!
79   \brief Destructor
80 */
81 Material_ResourceMgr::~Material_ResourceMgr()
82 {
83   watchUserFile( false );
84 }
85
86 /*!
87   \brief Get shared instance of resources manager
88   
89   This instance of resource manager is global for the application;
90   it watches for changes in the user materials database file to
91   maintain the fresh version of the materials data.
92 */
93 Material_ResourceMgr* Material_ResourceMgr::resourceMgr()
94 {
95   static Material_ResourceMgr* resMgr = 0;
96   if ( !resMgr ) {
97     resMgr = new Material_ResourceMgr();
98     resMgr->watchUserFile( true );
99   }
100   return resMgr;
101 }
102
103 /*!
104   \brief Get list of available materials
105   \param theType material type
106   \param theSort if \c true (default), returns a list of materials sorted by name
107   \return list of available materials names
108 */
109 QStringList Material_ResourceMgr::materials( MaterialType theType, bool theSort )
110 {
111   QMutexLocker lock( &myMutex );
112
113   // store original working mode
114   WorkingMode m = workingMode();
115
116   QStringList slglobal, sluser;
117
118   // retrieve all materials : global + user
119   setWorkingMode( AllowUserValues );
120   sluser = sections();
121
122   // retrieve only global materials
123   setWorkingMode( IgnoreUserValues );
124   slglobal = sections();
125
126   // remove global materials from user list to obtain only user materials
127   QMutableListIterator<QString> it( sluser );
128   while ( it.hasNext() ) {
129     QString s = it.next();
130     if ( slglobal.contains( s ) ) it.remove();
131   }
132
133   // remove 'common' material 
134   slglobal.removeAll("[common]");
135
136   // restore original working mode
137   setWorkingMode( m );
138
139   // sort if necessary (separately global and user materials)
140   if ( theSort ) {
141     qSort( slglobal );
142     qSort( sluser );
143   }
144   // special processing for default material (to make it first in the list)
145   if ( slglobal.contains( "[ Default ]" ) ) {
146     slglobal.removeAll( "[ Default ]" );
147     slglobal.prepend( "[ Default ]" );
148   }
149
150   // combine the materials to obtain result list
151   QStringList result;
152   
153   switch ( theType ) {
154   case Global:
155     result = slglobal;
156     break;
157   case User:
158     result = sluser;
159     break;
160   case All:
161     result = slglobal + sluser;
162     break;
163   default:
164     break;
165   }
166
167   return result;
168 }
169
170 /*!
171   \brief Start/stop this resource manager watching the user materials database file.
172   \internal
173 */
174 void Material_ResourceMgr::watchUserFile( bool on )
175 {
176   if ( on ) {
177     if ( !myWatcher ) {
178       myWatcher = new QFileSystemWatcher( this );
179       QFileInfo ufile = userFileName( appName() );
180       if ( ufile.exists() ) {
181         myWatcher->addPath( ufile.filePath() );
182       }
183       connect( myWatcher, SIGNAL( fileChanged( QString ) ), this, SLOT( update() ) );
184     }
185   }
186   else {
187     if ( myWatcher ) {
188       delete myWatcher;
189       myWatcher = 0;
190     }
191   }
192 }
193
194 /*!
195   \brief This function is called after user configuration file is saved.
196   \internal
197 */
198 void Material_ResourceMgr::saved()
199 {
200   if ( resourceMgr() != this ) {
201     resourceMgr()->saved();
202   }
203   else if ( myWatcher ) {
204     QStringList files = myWatcher->files();
205     QFileInfo ufile = userFileName( appName() );
206     if ( ufile.exists() && !files.contains( ufile.filePath() ) ) {
207       myWatcher->addPath( ufile.filePath() );
208       update();
209     }
210   }
211 }
212
213 /*!
214   \brief Update user database slot
215   \internal
216 */
217 void Material_ResourceMgr::update()
218 {
219   Updater( this ).wait();
220   emit changed();
221 }