1/*
2 * Copyright 1998-1999 Be, Inc. All Rights Reserved.
3 * Copyright 2003-2019 Haiku, Inc. All rights reserved.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "Settings.h"
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13
14#include <Catalog.h>
15#include <Debug.h>
16#include <Locale.h>
17
18
19#undef B_TRANSLATION_CONTEXT
20#define B_TRANSLATION_CONTEXT "Settings"
21
22
23Settings* settings = NULL;
24
25
26StringValueSetting::StringValueSetting(const char* name,
27	const char* defaultValue, const char* valueExpectedErrorString,
28	const char* wrongValueErrorString)
29	:
30	SettingsArgvDispatcher(name),
31	fDefaultValue(defaultValue),
32	fValueExpectedErrorString(valueExpectedErrorString),
33	fWrongValueErrorString(wrongValueErrorString),
34	fValue(strdup(defaultValue))
35{
36}
37
38
39StringValueSetting::~StringValueSetting()
40{
41	free(fValue);
42}
43
44
45void
46StringValueSetting::ValueChanged(const char* newValue)
47{
48	if (newValue == fValue)
49		// guard against self assingment
50		return;
51
52	free(fValue);
53	fValue = strdup(newValue);
54}
55
56
57const char*
58StringValueSetting::Value() const
59{
60	return fValue;
61}
62
63
64void
65StringValueSetting::SaveSettingValue(Settings* settings)
66{
67	printf("-----StringValueSetting::SaveSettingValue %s %s\n", Name(), fValue);
68	settings->Write("\"%s\"", fValue);
69}
70
71
72bool
73StringValueSetting::NeedsSaving() const
74{
75	// needs saving if different than default
76	return strcmp(fValue, fDefaultValue) != 0;
77}
78
79
80const char*
81StringValueSetting::Handle(const char* const *argv)
82{
83	if (*++argv == NULL)
84		return fValueExpectedErrorString;
85
86	ValueChanged(*argv);
87	return 0;
88}
89
90
91//	#pragma mark -
92
93
94EnumeratedStringValueSetting::EnumeratedStringValueSetting(const char* name,
95	const char* defaultValue, StringEnumerator enumerator,
96	const char* valueExpectedErrorString,
97	const char* wrongValueErrorString)
98	:
99	StringValueSetting(name, defaultValue, valueExpectedErrorString,
100		wrongValueErrorString),
101	fEnumerator(enumerator)
102{
103}
104
105
106void
107EnumeratedStringValueSetting::ValueChanged(const char* newValue)
108{
109#if DEBUG
110	// must be one of the enumerated values
111	ASSERT(_ValidateString(newValue));
112#endif
113	StringValueSetting::ValueChanged(newValue);
114}
115
116
117const char*
118EnumeratedStringValueSetting::Handle(const char* const *argv)
119{
120	if (*++argv == NULL)
121		return fValueExpectedErrorString;
122
123	printf("---EnumeratedStringValueSetting::Handle %s %s\n", *(argv-1), *argv);
124	if (!_ValidateString(*argv))
125		return fWrongValueErrorString;
126
127	ValueChanged(*argv);
128	return 0;
129}
130
131
132bool
133EnumeratedStringValueSetting::_ValidateString(const char* string)
134{
135	for (int32 i = 0;; i++) {
136		const char* enumString = fEnumerator(i);
137		if (enumString == NULL)
138			return false;
139		if (strcmp(enumString, string) == 0)
140			return true;
141	}
142	return false;
143}
144
145
146//	#pragma mark -
147
148
149ScalarValueSetting::ScalarValueSetting(const char* name, int32 defaultValue,
150	const char* valueExpectedErrorString, const char* wrongValueErrorString,
151	int32 min, int32 max)
152	:
153	SettingsArgvDispatcher(name),
154	fDefaultValue(defaultValue),
155	fValue(defaultValue),
156	fMax(max),
157	fMin(min),
158	fValueExpectedErrorString(valueExpectedErrorString),
159	fWrongValueErrorString(wrongValueErrorString)
160{
161}
162
163
164ScalarValueSetting::~ScalarValueSetting()
165{
166}
167
168
169void
170ScalarValueSetting::ValueChanged(int32 newValue)
171{
172	ASSERT(newValue > fMin);
173	ASSERT(newValue < fMax);
174	fValue = newValue;
175}
176
177
178int32
179ScalarValueSetting::Value() const
180{
181	return fValue;
182}
183
184
185void
186ScalarValueSetting::GetValueAsString(char* buffer) const
187{
188	sprintf(buffer, "%" B_PRId32, fValue);
189}
190
191
192const char*
193ScalarValueSetting::Handle(const char* const *argv)
194{
195	if (*++argv == NULL)
196		return fValueExpectedErrorString;
197
198	int32 newValue = atoi(*argv);
199	if (newValue < fMin || newValue > fMax)
200		return fWrongValueErrorString;
201
202	fValue = newValue;
203	return 0;
204}
205
206
207void
208ScalarValueSetting::SaveSettingValue(Settings* settings)
209{
210	settings->Write("%" B_PRId32, fValue);
211}
212
213
214bool
215ScalarValueSetting::NeedsSaving() const
216{
217	return fValue != fDefaultValue;
218}
219
220
221//	#pragma mark -
222
223
224BooleanValueSetting::BooleanValueSetting(const char* name, bool defaultValue)
225	:
226	ScalarValueSetting(name, defaultValue, 0, 0)
227{
228}
229
230
231BooleanValueSetting::~BooleanValueSetting()
232{
233}
234
235
236bool
237BooleanValueSetting::Value() const
238{
239	return fValue;
240}
241
242
243const char*
244BooleanValueSetting::Handle(const char* const *argv)
245{
246	if (*++argv == NULL) {
247		return B_TRANSLATE_COMMENT("on or off expected","Do not translate "
248			"'on' and 'off'");
249	}
250
251	if (strcmp(*argv, "on") == 0)
252		fValue = true;
253	else if (strcmp(*argv, "off") == 0)
254		fValue = false;
255	else {
256		return B_TRANSLATE_COMMENT("on or off expected", "Do not translate "
257		"'on' and 'off'");
258	}
259
260	return 0;
261}
262
263
264void
265BooleanValueSetting::SaveSettingValue(Settings* settings)
266{
267	settings->Write(fValue ? "on" : "off");
268}
269