xref: /haiku/src/apps/debugger/user_interface/gui/value/value_handlers/IntegerValueHandler.cpp (revision 3995592cdf304335132305e27c40cbb0b1ac46e3)
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 
23 static const char* const kFormatSettingID = "format";
24 
25 
26 // #pragma mark - FormatOption
27 
28 
29 class IntegerValueHandler::FormatOption : public SettingsOption {
30 public:
FormatOption(const char * id,const char * name,integer_format format)31 	FormatOption(const char* id, const char* name, integer_format format)
32 		:
33 		fID(id),
34 		fName(name),
35 		fFormat(format)
36 	{
37 	}
38 
ID() const39 	virtual const char* ID() const
40 	{
41 		return fID;
42 	}
43 
Name() const44 	virtual const char* Name() const
45 	{
46 		return fName;
47 	}
48 
Format() const49 	integer_format Format() const
50 	{
51 		return fFormat;
52 	}
53 
54 private:
55 	const char*		fID;
56 	const char*		fName;
57 	integer_format	fFormat;
58 };
59 
60 
61 // #pragma mark - IntegerFormatterConfig
62 
63 
64 class IntegerValueHandler::IntegerFormatterConfig
65 	: public IntegerValueFormatter::Config {
66 public:
IntegerFormatterConfig()67 	IntegerFormatterConfig()
68 		:
69 		fSettings(NULL),
70 		fFormatSetting(NULL)
71 	{
72 	}
73 
~IntegerFormatterConfig()74 	~IntegerFormatterConfig()
75 	{
76 		if (fSettings != NULL)
77 			fSettings->ReleaseReference();
78 	}
79 
Init(SettingsDescription * settingsDescription)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 
GetSettings() const98 	virtual Settings* GetSettings() const
99 	{
100 		return fSettings;
101 	}
102 
IntegerFormat() const103 	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 
110 private:
111 	Settings*		fSettings;
112 	OptionsSetting*	fFormatSetting;
113 };
114 
115 
116 // #pragma mark - IntegerValueHandler
117 
118 
IntegerValueHandler()119 IntegerValueHandler::IntegerValueHandler()
120 {
121 }
122 
123 
~IntegerValueHandler()124 IntegerValueHandler::~IntegerValueHandler()
125 {
126 }
127 
128 
129 status_t
Init()130 IntegerValueHandler::Init()
131 {
132 	return B_OK;
133 }
134 
135 
136 float
SupportsValue(Value * value)137 IntegerValueHandler::SupportsValue(Value* value)
138 {
139 	return dynamic_cast<IntegerValue*>(value) != NULL ? 0.5f : 0;
140 }
141 
142 
143 status_t
GetValueFormatter(Value * _value,ValueFormatter * & _formatter)144 IntegerValueHandler::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 
166 status_t
GetTableCellValueRenderer(Value * _value,TableCellValueRenderer * & _renderer)167 IntegerValueHandler::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 
185 status_t
GetTableCellValueEditor(Value * _value,Settings * settings,TableCellValueEditor * & _editor)186 IntegerValueHandler::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 
221 status_t
CreateTableCellValueSettingsMenu(Value * value,Settings * settings,SettingsMenu * & _menu)222 IntegerValueHandler::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 
246 integer_format
DefaultIntegerFormat(IntegerValue * value)247 IntegerValueHandler::DefaultIntegerFormat(IntegerValue* value)
248 {
249 	return value->IsSigned() ? INTEGER_FORMAT_SIGNED : INTEGER_FORMAT_UNSIGNED;
250 }
251 
252 
253 status_t
AddIntegerFormatSettingOptions(IntegerValue * value,OptionsSettingImpl * setting)254 IntegerValueHandler::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 
276 status_t
CreateValueFormatter(IntegerValueFormatter::Config * config,ValueFormatter * & _formatter)277 IntegerValueHandler::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 
291 status_t
CreateTableCellValueRenderer(IntegerValue * value,IntegerValueFormatter::Config * config,TableCellValueRenderer * & _renderer)292 IntegerValueHandler::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 
312 status_t
CreateIntegerFormatterConfig(IntegerValue * value,IntegerValueFormatter::Config * & _config)313 IntegerValueHandler::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 
341 status_t
AddIntegerFormatOption(OptionsSettingImpl * setting,const char * id,const char * name,integer_format format)342 IntegerValueHandler::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 
354 SettingsDescription*
_CreateTableCellSettingsDescription(IntegerValue * value)355 IntegerValueHandler::_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