1/*
2 * Copyright 2015-2016, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "IntegerValueHandler.h"
9
10#include <new>
11
12#include <AutoDeleter.h>
13
14#include "IntegerValue.h"
15#include "Setting.h"
16#include "Settings.h"
17#include "SettingsDescription.h"
18#include "SettingsMenu.h"
19#include "TableCellFormattedValueRenderer.h"
20#include "TableCellIntegerEditor.h"
21
22
23static const char* const kFormatSettingID = "format";
24
25
26// #pragma mark - FormatOption
27
28
29class IntegerValueHandler::FormatOption : public SettingsOption {
30public:
31	FormatOption(const char* id, const char* name, integer_format format)
32		:
33		fID(id),
34		fName(name),
35		fFormat(format)
36	{
37	}
38
39	virtual const char* ID() const
40	{
41		return fID;
42	}
43
44	virtual const char* Name() const
45	{
46		return fName;
47	}
48
49	integer_format Format() const
50	{
51		return fFormat;
52	}
53
54private:
55	const char*		fID;
56	const char*		fName;
57	integer_format	fFormat;
58};
59
60
61// #pragma mark - IntegerFormatterConfig
62
63
64class IntegerValueHandler::IntegerFormatterConfig
65	: public IntegerValueFormatter::Config {
66public:
67	IntegerFormatterConfig()
68		:
69		fSettings(NULL),
70		fFormatSetting(NULL)
71	{
72	}
73
74	~IntegerFormatterConfig()
75	{
76		if (fSettings != NULL)
77			fSettings->ReleaseReference();
78	}
79
80	status_t Init(SettingsDescription* settingsDescription)
81	{
82		fSettings = new(std::nothrow) Settings(settingsDescription);
83		if (fSettings == NULL)
84			return B_NO_MEMORY;
85
86		status_t error = fSettings->Init();
87		if (error != B_OK)
88			return error;
89
90		fFormatSetting = dynamic_cast<OptionsSetting*>(
91			settingsDescription->SettingByID(kFormatSettingID));
92		if (fFormatSetting == NULL)
93			return B_BAD_VALUE;
94
95		return B_OK;
96	}
97
98	virtual Settings* GetSettings() const
99	{
100		return fSettings;
101	}
102
103	virtual integer_format IntegerFormat() const
104	{
105		FormatOption* option = dynamic_cast<FormatOption*>(
106			fSettings->OptionValue(fFormatSetting));
107		return option != NULL ? option->Format() : INTEGER_FORMAT_DEFAULT;
108	}
109
110private:
111	Settings*		fSettings;
112	OptionsSetting*	fFormatSetting;
113};
114
115
116// #pragma mark - IntegerValueHandler
117
118
119IntegerValueHandler::IntegerValueHandler()
120{
121}
122
123
124IntegerValueHandler::~IntegerValueHandler()
125{
126}
127
128
129status_t
130IntegerValueHandler::Init()
131{
132	return B_OK;
133}
134
135
136float
137IntegerValueHandler::SupportsValue(Value* value)
138{
139	return dynamic_cast<IntegerValue*>(value) != NULL ? 0.5f : 0;
140}
141
142
143status_t
144IntegerValueHandler::GetValueFormatter(Value* _value,
145	ValueFormatter*& _formatter)
146{
147	IntegerValue* value = dynamic_cast<IntegerValue*>(_value);
148	if (value == NULL)
149		return B_BAD_VALUE;
150
151	IntegerValueFormatter::Config* config = NULL;
152	status_t error = CreateIntegerFormatterConfig(value, config);
153	if (error != B_OK)
154		return error;
155
156	BReference<IntegerValueFormatter::Config> configReference(config, true);
157	ValueFormatter* formatter = new(std::nothrow) IntegerValueFormatter(config);
158	if (formatter == NULL)
159		return B_NO_MEMORY;
160
161	_formatter = formatter;
162	return B_OK;
163}
164
165
166status_t
167IntegerValueHandler::GetTableCellValueRenderer(Value* _value,
168	TableCellValueRenderer*& _renderer)
169{
170	IntegerValue* value = dynamic_cast<IntegerValue*>(_value);
171	if (value == NULL)
172		return B_BAD_VALUE;
173
174	IntegerValueFormatter::Config* config = NULL;
175	status_t error = CreateIntegerFormatterConfig(value, config);
176	if (error != B_OK)
177		return error;
178	BReference<IntegerValueFormatter::Config> configReference(config, true);
179
180	// create the renderer
181	return CreateTableCellValueRenderer(value, config, _renderer);
182}
183
184
185status_t
186IntegerValueHandler::GetTableCellValueEditor(Value* _value,
187	Settings* settings, TableCellValueEditor*& _editor)
188{
189	IntegerValue* value = dynamic_cast<IntegerValue*>(_value);
190	if (value == NULL)
191		return B_BAD_VALUE;
192
193	IntegerValueFormatter::Config* config = NULL;
194	status_t error = CreateIntegerFormatterConfig(value, config);
195	if (error != B_OK)
196		return error;
197	BReference<IntegerValueFormatter::Config> configReference(config, true);
198
199	ValueFormatter* formatter;
200	error = CreateValueFormatter(config, formatter);
201	if (error != B_OK)
202		return error;
203	BReference<ValueFormatter> formatterReference(formatter, true);
204
205	TableCellIntegerEditor* editor = new(std::nothrow) TableCellIntegerEditor(
206		value, formatter);
207	if (editor == NULL)
208		return B_NO_MEMORY;
209
210	BReference<TableCellIntegerEditor> editorReference(editor, true);
211	error = editor->Init();
212	if (error != B_OK)
213		return error;
214
215	editorReference.Detach();
216	_editor = editor;
217	return B_OK;
218}
219
220
221status_t
222IntegerValueHandler::CreateTableCellValueSettingsMenu(Value* value,
223	Settings* settings, SettingsMenu*& _menu)
224{
225	// get the format option
226	OptionsSetting* formatSetting = dynamic_cast<OptionsSetting*>(
227		settings->Description()->SettingByID(kFormatSettingID));
228	if (formatSetting == NULL)
229		return B_BAD_VALUE;
230
231	// create the settings menu
232	SettingsMenuImpl* menu = new(std::nothrow) SettingsMenuImpl(settings);
233	if (menu == NULL)
234		return B_NO_MEMORY;
235	ObjectDeleter<SettingsMenu> menuDeleter(menu);
236
237	// add the format option menu item
238	if (!menu->AddOptionsItem(formatSetting))
239		return B_NO_MEMORY;
240
241	_menu = menuDeleter.Detach();
242	return B_OK;
243}
244
245
246integer_format
247IntegerValueHandler::DefaultIntegerFormat(IntegerValue* value)
248{
249	return value->IsSigned() ? INTEGER_FORMAT_SIGNED : INTEGER_FORMAT_UNSIGNED;
250}
251
252
253status_t
254IntegerValueHandler::AddIntegerFormatSettingOptions(IntegerValue* value,
255	OptionsSettingImpl* setting)
256{
257	status_t error = AddIntegerFormatOption(setting, "signed", "Signed",
258		INTEGER_FORMAT_SIGNED);
259	if (error != B_OK)
260		return error;
261
262	error = AddIntegerFormatOption(setting, "unsigned", "Unsigned",
263		INTEGER_FORMAT_UNSIGNED);
264	if (error != B_OK)
265		return error;
266
267	error = AddIntegerFormatOption(setting, "hex", "Hexadecimal",
268		INTEGER_FORMAT_HEX_DEFAULT);
269	if (error != B_OK)
270		return error;
271
272	return B_OK;
273}
274
275
276status_t
277IntegerValueHandler::CreateValueFormatter(
278	IntegerValueFormatter::Config* config,
279	ValueFormatter*& _formatter)
280{
281	ValueFormatter* formatter = new(std::nothrow) IntegerValueFormatter(
282		config);
283	if (formatter == NULL)
284		return B_NO_MEMORY;
285
286	_formatter = formatter;
287	return B_OK;
288}
289
290
291status_t
292IntegerValueHandler::CreateTableCellValueRenderer(IntegerValue* value,
293	IntegerValueFormatter::Config* config,
294	TableCellValueRenderer*& _renderer)
295{
296	ValueFormatter* formatter;
297	status_t error = CreateValueFormatter(config, formatter);
298	if (error != B_OK)
299		return error;
300	BReference<ValueFormatter> formatterReference(formatter, true);
301
302	TableCellValueRenderer* renderer
303		= new(std::nothrow) TableCellFormattedValueRenderer(formatter);
304	if (renderer == NULL)
305		return B_NO_MEMORY;
306
307	_renderer = renderer;
308	return B_OK;
309}
310
311
312status_t
313IntegerValueHandler::CreateIntegerFormatterConfig(IntegerValue* value,
314	IntegerValueFormatter::Config*& _config)
315{
316	// create a settings description
317	SettingsDescription* settingsDescription
318		= _CreateTableCellSettingsDescription(value);
319	if (settingsDescription == NULL)
320		return B_NO_MEMORY;
321	BReference<SettingsDescription> settingsDescriptionReference(
322		settingsDescription, true);
323
324	// create config
325	IntegerFormatterConfig* config = new(std::nothrow) IntegerFormatterConfig;
326	if (config == NULL)
327		return B_NO_MEMORY;
328	BReference<IntegerFormatterConfig> configReference(config, true);
329
330	status_t error = config->Init(settingsDescription);
331	if (error != B_OK)
332		return error;
333
334	_config = config;
335	configReference.Detach();
336
337	return B_OK;
338}
339
340
341status_t
342IntegerValueHandler::AddIntegerFormatOption(OptionsSettingImpl* setting,
343	const char* id, const char* name, integer_format format)
344{
345	FormatOption* option = new(std::nothrow) FormatOption(id, name, format);
346	BReference<FormatOption> optionReference(option, true);
347	if (option == NULL || !setting->AddOption(option))
348		return B_NO_MEMORY;
349
350	return B_OK;
351}
352
353
354SettingsDescription*
355IntegerValueHandler::_CreateTableCellSettingsDescription(
356	IntegerValue* value)
357{
358	// create description object
359	SettingsDescription* description = new(std::nothrow) SettingsDescription;
360	if (description == NULL)
361		return NULL;
362	BReference<SettingsDescription> descriptionReference(description, true);
363
364	// integer format setting
365	OptionsSettingImpl* setting = new(std::nothrow) OptionsSettingImpl(
366		kFormatSettingID, "Format");
367	if (setting == NULL)
368		return NULL;
369	BReference<OptionsSettingImpl> settingReference(setting, true);
370
371	// add options
372	if (AddIntegerFormatSettingOptions(value, setting) != B_OK)
373		return NULL;
374
375	// set default
376	integer_format defaultFormat = DefaultIntegerFormat(value);
377	SettingsOption* defaultOption = setting->OptionAt(0);
378	for (int32 i = 0;
379		FormatOption* option
380			= dynamic_cast<FormatOption*>(setting->OptionAt(i));
381		i++) {
382		if (option->Format() == defaultFormat) {
383			defaultOption = option;
384			break;
385		}
386	}
387
388	setting->SetDefaultOption(defaultOption);
389
390	// add setting
391	if (!description->AddSetting(setting))
392		return NULL;
393
394	return descriptionReference.Detach();
395}
396