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