1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Command Line Interface //
9 // //
10 // Program: SAGA_CMD //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // config.cpp //
15 // //
16 // Copyright (C) 2017 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. SAGA is free software; you //
22 // can redistribute it and/or modify it under the terms //
23 // of the GNU General Public License as published by the //
24 // Free Software Foundation, either version 2 of the //
25 // License, or (at your option) any later version. //
26 // //
27 // SAGA is distributed in the hope that it will be //
28 // useful, but WITHOUT ANY WARRANTY; without even the //
29 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
30 // PARTICULAR PURPOSE. See the GNU General Public //
31 // License for more details. //
32 // //
33 // You should have received a copy of the GNU Lesser //
34 // General Public License along with this program; if //
35 // not, see <http://www.gnu.org/licenses/>. //
36 // //
37 //-------------------------------------------------------//
38 // //
39 // contact: Olaf Conrad //
40 // Institute of Geography //
41 // University of Hamburg //
42 // Germany //
43 // //
44 // e-mail: oconrad@saga-gis.org //
45 // //
46 ///////////////////////////////////////////////////////////
47
48 //---------------------------------------------------------
49 #include "config.h"
50 #include "callback.h"
51
52 //---------------------------------------------------------
53 #include <wx/config.h>
54 #include <wx/fileconf.h>
55 #include <wx/wfstream.h>
56 #include <wx/stdpaths.h>
57 #include <wx/utils.h>
58 #include <wx/app.h>
59
60
61 ///////////////////////////////////////////////////////////
62 // //
63 // //
64 // //
65 ///////////////////////////////////////////////////////////
66
67 //---------------------------------------------------------
Config_Read(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,bool & Value)68 bool Config_Read(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, bool &Value)
69 {
70 pConfig->SetPath("/" + Group); return( pConfig->Read(Key, &Value) );
71 }
72
Config_Read(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,int & Value)73 bool Config_Read(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, int &Value)
74 {
75 pConfig->SetPath("/" + Group); return( pConfig->Read(Key, &Value) );
76 }
77
Config_Read(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,double & Value)78 bool Config_Read(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, double &Value)
79 {
80 pConfig->SetPath("/" + Group); return( pConfig->Read(Key, &Value) );
81 }
82
Config_Read(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,wxString & Value)83 bool Config_Read(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, wxString &Value)
84 {
85 pConfig->SetPath("/" + Group); return( pConfig->Read(Key, &Value) );
86 }
87
88 //---------------------------------------------------------
Config_Write(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,bool Value)89 bool Config_Write(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, bool Value)
90 {
91 pConfig->SetPath("/" + Group); return( pConfig->Write(Key, Value) ? pConfig->Flush() : false );
92 }
93
Config_Write(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,int Value)94 bool Config_Write(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, int Value)
95 {
96 pConfig->SetPath("/" + Group); return( pConfig->Write(Key, Value) ? pConfig->Flush() : false );
97 }
98
Config_Write(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,double Value)99 bool Config_Write(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, double Value)
100 {
101 pConfig->SetPath("/" + Group); return( pConfig->Write(Key, Value) ? pConfig->Flush() : false );
102 }
103
Config_Write(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,const wxString & Value)104 bool Config_Write(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, const wxString &Value)
105 {
106 pConfig->SetPath("/" + Group); return( pConfig->Write(Key, Value) ? pConfig->Flush() : false );
107 }
108
Config_Write(wxConfigBase * pConfig,const wxString & Group,const wxString & Key,const SG_Char * Value)109 bool Config_Write(wxConfigBase *pConfig, const wxString &Group, const wxString &Key, const SG_Char *Value)
110 {
111 pConfig->SetPath("/" + Group); return( pConfig->Write(Key, Value) ? pConfig->Flush() : false );
112 }
113
114
115 ///////////////////////////////////////////////////////////
116 // //
117 ///////////////////////////////////////////////////////////
118
119 //---------------------------------------------------------
Config_Create(wxConfigBase * pConfig)120 bool Config_Create (wxConfigBase *pConfig)
121 {
122 Config_Write(pConfig, "CMD", "NO_PROGRESS" , false ); // q, s: no progress report
123 Config_Write(pConfig, "CMD", "NO_MESSAGES" , false ); // r, s: no messages report
124 Config_Write(pConfig, "CMD", "INTERACTIVE" , false ); // i: allow user interaction
125 Config_Write(pConfig, "CMD", "XML_MESSAGE" , false ); // x: message output as xml
126
127 Config_Write(pConfig, "TOOLS", "LNG_FILE_DIC" , SG_T("")); // translation dictionary
128 Config_Write(pConfig, "TOOLS", "PROJECTIONS" , false ); // load projections dictionary
129 Config_Write(pConfig, "TOOLS", "OMP_THREADS_MAX" , SG_OMP_Get_Max_Num_Procs());
130 Config_Write(pConfig, "TOOLS", "ADD_LIB_PATHS" , SG_T("")); // additional tool library paths (aka SAGA_TLB)
131
132 Config_Write(pConfig, "DATA", "GRID_CACHE_TMPDIR" , SG_Grid_Cache_Get_Directory ());
133 Config_Write(pConfig, "DATA", "GRID_CACHE_MODE" , SG_Grid_Cache_Get_Mode ());
134 Config_Write(pConfig, "DATA", "GRID_CACHE_THRESHLOD", SG_Grid_Cache_Get_Threshold_MB());
135 Config_Write(pConfig, "DATA", "GRID_COORD_PRECISION", CSG_Grid_System::Get_Precision());
136 Config_Write(pConfig, "DATA", "HISTORY_DEPTH" , SG_Get_History_Depth());
137 Config_Write(pConfig, "DATA", "HISTORY_LISTS" , SG_Get_History_Ignore_Lists() != 0);
138
139 return( true );
140 }
141
142 //---------------------------------------------------------
Config_Load(wxConfigBase * pConfig)143 bool Config_Load (wxConfigBase *pConfig)
144 {
145 #if defined(_SAGA_LINUX)
146 CSG_String Path_Shared = SHARE_PATH;
147 #elif defined(_SAGA_MSW)
148 CSG_String Path_Shared = SG_UI_Get_Application_Path(true);
149 #endif
150
151 bool bValue; int iValue; double dValue; wxString sValue;
152
153 //-----------------------------------------------------
154 Config_Read(pConfig, "CMD", "NO_PROGRESS", bValue = false); CMD_Set_Show_Progress(bValue == false); // q, s: no progress report
155 Config_Read(pConfig, "CMD", "NO_MESSAGES", bValue = false); CMD_Set_Show_Messages(bValue == false); // r, s: no messages report
156 Config_Read(pConfig, "CMD", "INTERACTIVE", bValue = false); CMD_Set_Interactive (bValue == true); // i: allow user interaction
157 Config_Read(pConfig, "CMD", "XML_MESSAGE", bValue = false); CMD_Set_XML (bValue == true); // x: message output as xml
158
159 //-----------------------------------------------------
160 if( Config_Read(pConfig, "TOOLS", "LNG_FILE_DIC", sValue) && wxFileExists(sValue) ) // load translation dictionary
161 {
162 SG_Printf("\n%s:", _TL("loading translation dictionary"));
163 SG_Printf("\n%s.\n",
164 // SG_Get_Translator().Create(SG_File_Make_Path(Path_Shared, SG_T("saga"), SG_T("lng")), false)
165 SG_Get_Translator().Create(&sValue, false)
166 ? _TL("success") : _TL("failed")
167 );
168 }
169
170 if( Config_Read(pConfig, "TOOLS", "OMP_THREADS_MAX" , iValue) ) { SG_OMP_Set_Max_Num_Threads(iValue); }
171
172 if( Config_Read(pConfig, "TOOLS", "ADD_LIB_PATHS" , sValue) && !sValue.IsEmpty() )
173 {
174 wxString Path;
175
176 if( (wxGetEnv("SAGA_TLB", &Path) || wxGetEnv("SAGA_MLB", &Path)) && !Path.IsEmpty() )
177 {
178 sValue += ";" + Path;
179 }
180
181 wxSetEnv("SAGA_TLB", sValue);
182 }
183
184 //-----------------------------------------------------
185 if( Config_Read(pConfig, "DATA", "GRID_CACHE_TMPDIR" , sValue) ) { SG_Grid_Cache_Set_Directory (sValue); }
186 if( Config_Read(pConfig, "DATA", "GRID_CACHE_MODE" , iValue) ) { SG_Grid_Cache_Set_Mode (iValue); }
187 if( Config_Read(pConfig, "DATA", "GRID_CACHE_THRESHLOD", dValue) ) { SG_Grid_Cache_Set_Threshold_MB(dValue); }
188
189 if( Config_Read(pConfig, "DATA", "GRID_COORD_PRECISION", iValue) ) { CSG_Grid_System::Set_Precision(iValue); }
190
191 if( Config_Read(pConfig, "DATA", "HISTORY_DEPTH" , iValue) ) { SG_Set_History_Depth (iValue ); }
192 if( Config_Read(pConfig, "DATA", "HISTORY_LISTS" , iValue) ) { SG_Set_History_Ignore_Lists(iValue != 0); }
193
194 //-----------------------------------------------------
195 return( true );
196 }
197
198
199 ///////////////////////////////////////////////////////////
200 // //
201 ///////////////////////////////////////////////////////////
202
203 //---------------------------------------------------------
Config_Default(bool bCreate)204 wxConfigBase * Config_Default(bool bCreate)
205 {
206 #if defined(_SAGA_MSW)
207 wxFileName fLocal(SG_UI_Get_Application_Path(false).c_str()); fLocal.SetExt("ini");
208
209 if( !fLocal.FileExists() && !bCreate )
210 {
211 return( NULL );
212 }
213
214 if( ( fLocal.FileExists() && (!fLocal.IsFileReadable() || !fLocal.IsFileWritable()))
215 || (!fLocal.FileExists() && (!fLocal.IsDirReadable () || !fLocal.IsDirWritable ())) )
216 {
217 wxFileName fUser (wxGetHomeDir(), "saga_cmd", "ini");
218 // wxFileName fUser (wxStandardPaths::Get().GetUserConfigDir(), "saga_cmd", "ini");
219
220 if( fLocal.FileExists() && fLocal.IsFileReadable() && !fUser.FileExists() ) // create a copy in user's home directory
221 {
222 wxFileInputStream is(fLocal.GetFullPath());
223 wxFileOutputStream os(fUser .GetFullPath());
224 wxFileConfig ic(is); ic.Save(os);
225 }
226
227 fLocal = fUser;
228 }
229
230 if( (fLocal.FileExists() && fLocal.IsFileWritable()) || (!fLocal.FileExists() && fLocal.IsDirWritable()) )
231 {
232 return( new wxFileConfig(wxEmptyString, wxEmptyString, fLocal.GetFullPath(), fLocal.GetFullPath(), wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_RELATIVE_PATH) );
233 }
234 #endif
235
236 return( new wxConfig ); // this might go to registry
237 }
238
239 //---------------------------------------------------------
Config_Load(void)240 bool Config_Load (void)
241 {
242 wxConfigBase *pConfig = Config_Default(false);
243
244 if( pConfig )
245 {
246 Config_Load(pConfig);
247
248 delete(pConfig);
249
250 return( true );
251 }
252
253 return( false );
254 }
255
256 //---------------------------------------------------------
Config_Load(const CSG_String & File)257 bool Config_Load (const CSG_String &File)
258 {
259 if( !SG_File_Exists(File) )
260 {
261 return( false );
262 }
263
264 wxConfigBase *pConfig = new wxFileConfig(wxEmptyString, wxEmptyString, File.c_str(), File.c_str(), wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_RELATIVE_PATH);
265
266 Config_Load(pConfig);
267
268 delete(pConfig);
269
270 return( true );
271 }
272
273
274 //---------------------------------------------------------
Config_Create(const CSG_String & File)275 bool Config_Create (const CSG_String &File)
276 {
277 wxConfigBase *pConfig;
278
279 if( File.is_Empty() )
280 {
281 SG_Printf(CSG_String::Format("\n%s...", _TL("creating default configuration")));
282
283 pConfig = Config_Default(true);
284 }
285 else
286 {
287 SG_Printf(CSG_String::Format("\n%s\n>>%s\n...", _TL("creating default configuration"), File.c_str()));
288
289 pConfig = new wxFileConfig(wxEmptyString, wxEmptyString, File.c_str(), File.c_str(), wxCONFIG_USE_LOCAL_FILE|wxCONFIG_USE_GLOBAL_FILE|wxCONFIG_USE_RELATIVE_PATH);
290 }
291
292 Config_Create(pConfig);
293
294 delete(pConfig);
295
296 SG_Printf(CSG_String::Format("%s\n", _TL("ready")));
297
298 return( true );
299 }
300
301
302 ///////////////////////////////////////////////////////////
303 // //
304 // //
305 // //
306 ///////////////////////////////////////////////////////////
307
308 //---------------------------------------------------------
309