-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwxMsConfig.cpp
408 lines (380 loc) · 16 KB
/
wxMsConfig.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
/////////////////////////////////////////////////////////////////////////////
// Name: wxMSConfig.cpp
// Purpose: Config file for wxMS Mail Screener
// Author: A. Wiegert based on Julian Smart's code
// Modified by:
// Created: Mar 15/07
// Copyright: (c) A. Wiegert
// Licence: wxWidgets license
/////////////////////////////////////////////////////////////////////////////
//-------------------------------------------------------------------
// Note __VISUALC__ is defined by wxWidgets, not by MSVC IDE
// and thus won't be defined until some wxWidgets headers are included
#if defined( _MSC_VER )
# if defined ( _DEBUG )
// this statement NEEDS to go BEFORE all headers
# define _CRTDBG_MAP_ALLOC
# endif
#endif
#include "wxMsPreProcDefsh.h" // needs to be first
// ------------------------------------------------------------------
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#ifndef WX_PRECOMP
#include "wx/wx.h"
#include "wx/log.h"
#endif
#include <wx/config.h>
#include <wx/fileconf.h>
#include <wx/filename.h>
#include "wxMsh.h"
#include "wxMsConfh.h"
#include "wxMsFrameh.h"
// ------------------------------------------------------------------
// Note __VISUALC__ is defined by wxWidgets, not by MSVC IDE
// and thus won't be defined until some wxWidgets headers are included
#if defined( _MSC_VER )
// only good for MSVC
// this block needs to go AFTER all headers
#include <crtdbg.h>
#ifdef _DEBUG
#ifndef DBG_NEW
#define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
#define new DBG_NEW
#endif
#endif
#endif
// ------------------------------------------------------------------
#ifdef __WIN32__
// this is not supported by native control
#define NO_VARIABLE_HEIGHT
#endif
// ------------------------------------------------------------------
#undef _USE_REGISTRY__ // use .INI file instead
// ------------------------------------------------------------------
/* Note: the entries in enum iniEnts define the sequence of data entries here
* and MUST be in corresponding sequence
* Note the number of initializers here must match the
* number of entries specified in the config.h file
*/
iniPrefs_t g_iniPrefs = {
CURRENT_PREF_VERSION,
{
{ _T("LogWindow"),// path - INI heading [HEADING]
_T("Wanted"), // key key=false/0/1.23/some string
eBool, // type of config entry
// default INI data
// values are only present up to last needed
// others are deemed to be set to 0/NULL/0.0
true, // bool
0, // long
_T(""), // string
0.0, // float
// current value
true },
{ _T("Sash"), _T("Position"), eLong, false, 60 },
{ _T("MainFrame"), _T("x"), eLong, false, 10 },
{ _T("MainFrame"), _T("y"), eLong, false, 20 },
{ _T("MainFrame"), _T("w"), eLong, false, 300 },
{ _T("MainFrame"), _T("h"), eLong, false, 300 },
#if defined( WANT_SCALING )
{ _T("ScreenResol"), _T("x"), eLong, false, 0 },
{ _T("ScreenResol"), _T("y"), eLong, false, 0 },
#endif
{ _T("OptDlg"), _T("Height"), eLong, false, 250 },
{ _T("OptDlg"), _T("Width"), eLong, false, 400 },
{ _T("Config"), _T("Last"), eString, false, 0, _T("") },
// mail grid col widths, as string of numbers with | separator
{ _T("MailGrid"), _T("Cols"), eString, false, 0,
_T("40|40|40|80|120|120|80|80|120|80") },
{ _T("MailGrid"), _T("Labels"), eString, false, 0,
_T("Delete|Bounce|Blacklist|Status|Size|From|Subject|To|Date|Account") },
{ _T("MaxTasks"), _T("Number"), eLong, false, 20 },
{ _T("LogFile"), _T("Wanted"), eBool, false },
{ _T("Log"), _T("Verbosity"), eLong, false, 4 },
{ _T("NewLog"), _T("Frequency"), eLong, false, 0 },
{ _T("LogDir"), _T("Path"), eString, false, 0, _T("") },
{ _T("LogDir"), _T("UseDefault"), eBool, true },
{ _T("LogRot"), _T("MAX"), eLong, false, 10 },
{ _T("LogRot"), _T("Next"), eLong, false, 0 },
{ _T("LastOptionDlg"), _T("Tab"), eLong, false, 0 },
{ _T("MailClient"), _T("Launch"), eBool, true },
{ _T("MailSound"), _T("NewMail"), eBool, true },
{ _T("MailCheck"), _T("Startup"), eBool, false },
{ _T("MailCheck"), _T("Schedule"), eBool, true },
{ _T("MailCheck"), _T("Interval"), eLong, false, 10 },
{ _T("ServerCheck"), _T("Schedule"), eBool, true },
{ _T("ServerCheck"), _T("Interval"), eLong, false, 10 },
{ _T("Update"), _T("AutoCheck"), eBool, true },
{ _T("TOP_Lines"), _T("Number"), eLong, false, 0 },
{ _T("AcctDlg"), _T("Height"), eLong, false, 250 },
{ _T("AcctDlg"), _T("Width"), eLong, false, 400 },
{ _T("AccountGrid"), _T("Cols"), eString, false, 0, _T("40|40|40|80") },
{ _T("Preview"), _T("Height"), eLong, false, 250 },
{ _T("Preview"), _T("Width"), eLong, false, 400 },
{ _T("Filter"), _T("Height"), eLong, false, 250 },
{ _T("Filter"), _T("Width"), eLong, false, 400 },
{ _T("Filter"), _T("LastSel"), eLong, false, 0 },
{ _T("Action"), _T("Legit"), eBool, true }, // action: 'legit' implemented
{ _T("Action"), _T("Blacklist"), eBool, false }, // action: 'blacklist' not implemented
{ _T("Action"), _T("Delete"), eBool, true }, // action: 'delete' implemented
{ _T("Action"), _T("Bounce"), eBool, false }, // action: 'bounce' not implemented
{ _T("POP3"), _T("TimeOut"), eLong, false, 60 }, // secs to wait for POP3 server response
{ _T("Status"), _T("DefColor"), eString, false, 0, _T("#000000") }, // default color for the status field - black
{ _T("EmailClient"), _T("Path"), eString, false, 0, _T("") },
{ _T("AdvPop3Optn"), _T("Height"), eLong, false, 250 },
{ _T("AdvPop3Optn"), _T("Width"), eLong, false, 400 },
#if defined( WANT_AUTO_START )
{ _T("Start"), _T("Auto"), eBool, true }, // start app with Windows
#endif
}
};
// ------------------------------------------------------------------
void MyApp::CreateConfig( void )
{
#if !defined( _MSC_VER )
wxCHANGE_UMASK( 00666 );
#endif
wxASSERT( sizeof(g_iniPrefs.data)/sizeof( entry) == IE_MAX );
// By default, the config data goes to registry under Windows
// we're using wxConfig's "create-on-demand" feature: it will create the
// config object when it's used for the first time. It has a number of
// advantages compared with explicitly creating our wxConfig:
// 1) we don't pay for it if we don't use it
// 2) there is no danger to create it twice
// ====== .INI file ends up in
// Home directory
// XP: c:/Documents and Settings/userName/Application data/wxSr/
// Vista: c:/Users/UserName/AppData/Roaming/wxMS/
// Win7 c:/Users/UserName/AppData/Roaming/wxMS/
// Linux ~/$USER/.wxMS/
wxString wsFileName;
#if 1 //defined( _MSC_VER )
wsFileName = m_wsConfigDir + _T("/") + m_wsAppName + _T(".ini");
#else
/**
* Setup default directory stuff for Linux
* as per https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
* summary at:
https://stackoverflow.com/questions/1024114/location-of-ini-config-files-in-linux-unix
$XDG_CONFIG_HOME (default: "$HOME/.config"): user-specific configuration files.
*
in my case $HOME -> /home/arnold -> /home/$USER
*/
wsFileName = m_wsConfigDir + /*_T("/.") + m_wsAppName + */ _T("/") + m_wsAppName + _T(".ini");
#endif
// if ( g_iniPrefs.data[IE_LOG_VERBOSITY].dataCurrent.lVal > 4 )
// wxLogMessage( _T(".INI file: ") + wsFileName );
m_pConfig = new wxFileConfig(
m_wsAppName,
wxEmptyString, // vendor name
wsFileName, // local filename
_T(""), // global filename
wxCONFIG_USE_LOCAL_FILE );
wxConfigBase::Set( m_pConfig );
#if !defined( _MSC_VER )
m_pConfig->SetUmask( 00777 );
#endif
// see if we have an entry PrefVersion & whether it is recent enough
if( m_pConfig->Exists( _T("/PrefVersion") )
&& ( m_pConfig->Read( _T("/PrefVersion"), &g_iniPrefs.lPrefVer )
&& ( g_iniPrefs.lPrefVer <= CURRENT_PREF_VERSION ) ) )
{
// initialize the default values
for( int i = 0; i < IE_MAX; i++ )
{
if ( g_iniPrefs.data[i].eType == eString )
{
g_iniPrefs.data[i].dataCurrent.wsVal =
g_iniPrefs.data[i].dataDefault.wsVal;
}
}
}
// either found no .INI file or a newer version
// set defaults and save
else
{
g_iniPrefs.lPrefVer = CURRENT_PREF_VERSION;
// read any existing entries, with a default, in
// case they are missing
//pConfig->Read( "key", &Settings.value, default_value);
// might be an idea to delete the file here to clean
// out any cruft
m_pConfig->DeleteAll();
m_pConfig->Write( _T("/PrefVersion"), g_iniPrefs.lPrefVer );
wxString wsData;
for( int i = 0; i < IE_MAX; i++ )
{
wxASSERT_MSG( !g_iniPrefs.data[i].wsPathStr.IsEmpty() &&
!g_iniPrefs.data[i].wsKeyStr.IsEmpty(), _T("NULL entries in iniPrefs.data[]") );
wsData.Printf( _T("%s/%s"), g_iniPrefs.data[i].wsPathStr.c_str(),
g_iniPrefs.data[i].wsKeyStr.c_str() );
switch( g_iniPrefs.data[i].eType )
{
case eBool:
m_pConfig->Write( wsData,
// Note: current == default - supposed to, but may not
(bool)(g_iniPrefs.data[i].dataDefault.bVal) );
break;
case eLong:
m_pConfig->Write( wsData,
g_iniPrefs.data[i].dataDefault.lVal );
break;
case eString:
m_pConfig->Write( wsData,
g_iniPrefs.data[i].dataDefault.wsVal );
g_iniPrefs.data[i].dataCurrent.wsVal =
g_iniPrefs.data[i].dataDefault.wsVal;
break;
case eFloat:
m_pConfig->Write( wsData,
(float)g_iniPrefs.data[i].dataDefault.fVal );
break;
}
}
m_pConfig->Flush();
}
}
//-----------------------------------------------------------------------------
void MyApp::RestoreConfig ( void )
{
// int x, y, w, h;
// x = sizeof(g_iniPrefs.data);
// y = sizeof( entry);
// w = x/y;
wxASSERT( sizeof(g_iniPrefs.data)/sizeof( entry) == IE_MAX );
// restore the control's values from the config
// NB: in this program, the config object is already created
// at this moment because we had called Get() from MyApp::OnInit().
// However, if you later change the code and don't create it
// before this line, it won't break anything - unlike if you
// manually create wxConfig object with Create() or in any
// other way (then you must be sure to create it before using it!).
m_pConfig = (wxFileConfig *)wxConfigBase::Get();
if( m_pConfig->Read( _T("/PrefVersion"), &g_iniPrefs.lPrefVer)
&& g_iniPrefs.lPrefVer < CURRENT_PREF_VERSION )
{
int answer = wxMessageBox(
_T("The configuration file version is incompatible\n")
_T("with the current application.\n")
_T("OK to overwrite?"), _T("Confirm"), wxYES_NO );
if ( answer == wxYES )
{
m_pConfig->DeleteAll();
CreateConfig();
}
// simply carry on if user won't let us update the config file
// it WILL complain the next time as well, until ...
//else
// return;
}
m_pConfig->SetPath(_T("/"));
wxString wsKey;
bool bOK = false;
wxString wsS = _T("");
for( int i = 0; i < IE_MAX; i++ )
{
wxASSERT( !g_iniPrefs.data[i].wsPathStr.IsEmpty()
&& !g_iniPrefs.data[i].wsKeyStr.IsEmpty() );
wsKey.Printf( _T("/%s/%s"), g_iniPrefs.data[i].wsPathStr.c_str(),
g_iniPrefs.data[i].wsKeyStr.c_str() );
switch( g_iniPrefs.data[i].eType )
{
case eBool:
bOK = m_pConfig->Read( wsKey, &(g_iniPrefs.data[i].dataCurrent.bVal),
g_iniPrefs.data[i].dataDefault.bVal );
break;
case eLong:
bOK = m_pConfig->Read( wsKey, &(g_iniPrefs.data[i].dataCurrent.lVal),
g_iniPrefs.data[i].dataDefault.lVal );
break;
case eString:
bOK = m_pConfig->Read( wsKey, &g_iniPrefs.data[i].dataCurrent.wsVal,
g_iniPrefs.data[i].dataDefault.wsVal );
break;
case eFloat:
double f;
bOK = m_pConfig->Read( wsKey, &f,
g_iniPrefs.data[i].dataDefault.fVal );
if( bOK )
g_iniPrefs.data[i].dataCurrent.fVal = f;
break;
}
}
}
//-----------------------------------------------------------------------------
void MyApp::SaveConfig( void )
{
if ( m_pConfig == NULL )
return;
m_pConfig->SetPath(_T("/"));
wxString wsKey;
for( int i = 0; i < IE_MAX; i++ )
{
wsKey.Printf( _T("%s/%s"), g_iniPrefs.data[i].wsPathStr.c_str(),
g_iniPrefs.data[i].wsKeyStr.c_str() );
switch( g_iniPrefs.data[i].eType )
{
case eBool:
m_pConfig->Write( wsKey,
(bool)(g_iniPrefs.data[i].dataCurrent.bVal) );
break;
case eLong:
m_pConfig->Write( wsKey,
(int)g_iniPrefs.data[i].dataCurrent.lVal );
break;
case eString:
m_pConfig->Write( wsKey,
g_iniPrefs.data[i].dataCurrent.wsVal );
break;
case eFloat:
m_pConfig->Write( wsKey,
(float)g_iniPrefs.data[i].dataCurrent.fVal );
break;
}
}
m_pConfig->Flush();// needed to ensure data is written
// avoid memory leaks
delete m_pConfig;
}
// ------------------------------------------------------------------
/**
Make a copy of the Config data structure. The copy is intended to
* be passed to a dialog which might change data. Using the copy
* will allow the user to save the data on exit or
* abandon the changes if he choses 'Cancel'
*/
void MyApp::MakeConfigCopy( iniPrefs_t& iniPrefsSrc,
iniPrefs_t& iniPrefsTarg )
{
iniPrefsTarg.lPrefVer = iniPrefsSrc.lPrefVer;
for( int i = 0; i < IE_MAX; i++ )
{
iniPrefsTarg.data[i].wsPathStr = iniPrefsSrc.data[i].wsPathStr;
iniPrefsTarg.data[i].wsKeyStr = iniPrefsSrc.data[i].wsKeyStr;
iniPrefsTarg.data[i].eType = iniPrefsSrc.data[i].eType;
switch( iniPrefsSrc.data[i].eType )
{
case eBool:
iniPrefsTarg.data[i].dataCurrent.bVal =
iniPrefsSrc.data[i].dataCurrent.bVal;
break;
case eLong:
iniPrefsTarg.data[i].dataCurrent.lVal =
iniPrefsSrc.data[i].dataCurrent.lVal;
break;
case eString:
iniPrefsTarg.data[i].dataCurrent.wsVal =
iniPrefsSrc.data[i].dataCurrent.wsVal;
break;
case eFloat:
iniPrefsTarg.data[i].dataCurrent.fVal =
iniPrefsSrc.data[i].dataCurrent.fVal;
break;
}
}
}
// ---------------------------- eof -------------------------------