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
|
/* Preferences.cpp
*
* Copyright (C) 1996-2012 Paul Boersma
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "Preferences.h"
#include "Collection.h"
/*
* Though Preference inherits from Data,
* we will use SimpleString routines with it.
*/
Thing_define (Preference, SimpleString) {
// new data:
public:
int type;
void *value;
int min, max;
const wchar * (*getText) (int value);
int (*getValue) (const wchar *text);
// overridden methods:
void v_destroy ();
};
Thing_implement (Preference, SimpleString, 0);
/* Warning: copy methods etc. not implemented. */
void structPreference :: v_destroy () {
Melder_free (string);
Preference_Parent :: v_destroy ();
}
static SortedSetOfString thePreferences;
static void Preferences_add (const wchar *string, int type, void *value, int min, int max, const wchar *(*getText) (int value), int (*getValue) (const wchar *text)) {
Preference me = Thing_new (Preference);
my string = Melder_wcsdup_f (string);
my type = type;
my value = value;
my min = min;
my max = max;
my getText = getText;
my getValue = getValue;
if (! thePreferences) thePreferences = SortedSetOfString_create ();
Collection_addItem (thePreferences, me);
}
void Preferences_addByte (const wchar_t *string, signed char *value, signed char defaultValue)
{ *value = defaultValue; Preferences_add (string, bytewa, value, 0, 0, NULL, NULL); }
void Preferences_addInt (const wchar_t *string, int *value, int defaultValue)
{ *value = defaultValue; Preferences_add (string, intwa, value, 0, 0, NULL, NULL); }
void Preferences_addLong (const wchar_t *string, long *value, long defaultValue)
{ *value = defaultValue; Preferences_add (string, longwa, value, 0, 0, NULL, NULL); }
void Preferences_addUbyte (const wchar_t *string, unsigned char *value, unsigned char defaultValue)
{ *value = defaultValue; Preferences_add (string, ubytewa, value, 0, 0, NULL, NULL); }
void Preferences_addUint (const wchar_t *string, unsigned int *value, unsigned int defaultValue)
{ *value = defaultValue; Preferences_add (string, uintwa, value, 0, 0, NULL, NULL); }
void Preferences_addUlong (const wchar_t *string, unsigned long *value, unsigned long defaultValue)
{ *value = defaultValue; Preferences_add (string, ulongwa, value, 0, 0, NULL, NULL); }
void Preferences_addBool (const wchar_t *string, bool *value, bool defaultValue)
{ *value = defaultValue; Preferences_add (string, boolwa, value, 0, 0, NULL, NULL); }
void Preferences_addDouble (const wchar_t *string, double *value, double defaultValue)
{ *value = defaultValue; Preferences_add (string, doublewa, value, 0, 0, NULL, NULL); }
void Preferences_addString (const wchar_t *string, wchar_t *value, const wchar_t *defaultValue)
{ wcscpy (value, defaultValue); Preferences_add (string, stringwa, value, 0, 0, NULL, NULL); }
void _Preferences_addEnum (const wchar_t *string, enum kPreferences_dummy *value, int min, int max,
const wchar_t *(*getText) (int value), int (*getValue) (const wchar_t *text), enum kPreferences_dummy defaultValue)
{
{ *value = defaultValue; Preferences_add (string, enumwa, value, min, max, getText, getValue); }
}
void Preferences_read (MelderFile file) {
/*
* It is possible (see praat.c) that this routine is called
* before any preferences have been registered.
* In that case, do nothing.
*/
if (! thePreferences) return;
try {
autoMelderReadText text = MelderReadText_createFromFile (file);
for (;;) {
wchar *line = MelderReadText_readLine (text.peek());
if (line == NULL)
return; // OK: we have read past the last line
wchar *value = wcsstr (line, L": ");
if (value == NULL)
return; // OK: we have read past the last key-value pair
*value = '\0', value += 2;
long ipref = SortedSetOfString_lookUp (thePreferences, line);
if (! ipref) continue; // skip unrecognized keys
Preference pref = (Preference) thePreferences -> item [ipref];
switch (pref -> type) {
case bytewa: * (signed char *) pref -> value = wcstol (value, NULL, 10); break;
case intwa: * (int *) pref -> value = wcstol (value, NULL, 10); break;
case longwa: * (long *) pref -> value = wcstol (value, NULL, 10); break;
case ubytewa: * (unsigned char *) pref -> value = wcstoul (value, NULL, 10); break;
case uintwa: * (unsigned int *) pref -> value = wcstoul (value, NULL, 10); break;
case ulongwa: * (unsigned long *) pref -> value = wcstoul (value, NULL, 10); break;
case boolwa: * (bool *) pref -> value =
wcsnequ (value, L"yes", 3) ? true :
wcsnequ (value, L"no", 2) ? false :
wcstol (value, NULL, 10) != 0; break;
case doublewa: * (double *) pref -> value = Melder_atof (value); break;
case stringwa: {
wcsncpy ((wchar *) pref -> value, value, Preferences_STRING_BUFFER_SIZE);
((wchar *) pref -> value) [Preferences_STRING_BUFFER_SIZE - 1] = '\0'; break;
}
case enumwa: {
int intValue = pref -> getValue (value);
if (intValue < 0)
intValue = pref -> getValue (L"\t"); // look for the default
* (enum kPreferences_dummy *) pref -> value = (enum kPreferences_dummy) intValue; break;
}
}
}
} catch (MelderError) {
Melder_clearError (); // this is done during start-up, so it should never fail
}
}
void Preferences_write (MelderFile file) {
if (! thePreferences || thePreferences -> size == 0) return;
static MelderString buffer = { 0 };
for (long ipref = 1; ipref <= thePreferences -> size; ipref ++) {
Preference pref = (Preference) thePreferences -> item [ipref];
MelderString_append (& buffer, pref -> string, L": ");
switch (pref -> type) {
case bytewa: MelderString_append (& buffer, Melder_integer (* (signed char *) pref -> value)); break;
case intwa: MelderString_append (& buffer, Melder_integer (* (int *) pref -> value)); break;
case longwa: MelderString_append (& buffer, Melder_integer (* (long *) pref -> value)); break;
case ubytewa: MelderString_append (& buffer, Melder_integer (* (unsigned char *) pref -> value)); break;
case uintwa: MelderString_append (& buffer, Melder_integer (* (unsigned int *) pref -> value)); break;
case ulongwa: MelderString_append (& buffer, Melder_integer (* (unsigned long *) pref -> value)); break;
case boolwa: MelderString_append (& buffer, Melder_boolean (* (bool *) pref -> value)); break;
case doublewa: MelderString_append (& buffer, Melder_double (* (double *) pref -> value)); break;
case stringwa: MelderString_append (& buffer, (const wchar *) pref -> value); break;
case enumwa: MelderString_append (& buffer, pref -> getText (* (enum kPreferences_dummy *) pref -> value)); break;
}
MelderString_appendCharacter (& buffer, '\n');
}
try {
MelderFile_writeText (file, buffer.string);
} catch (MelderError) {
Melder_clearError ();
}
forget (thePreferences);
}
/* End of file Preferences.cpp */
|