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: 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 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: 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 110 private: 111 Settings* fSettings; 112 OptionsSetting* fFormatSetting; 113 }; 114 115 116 // #pragma mark - IntegerValueHandler 117 118 119 IntegerValueHandler::IntegerValueHandler() 120 { 121 } 122 123 124 IntegerValueHandler::~IntegerValueHandler() 125 { 126 } 127 128 129 status_t 130 IntegerValueHandler::Init() 131 { 132 return B_OK; 133 } 134 135 136 float 137 IntegerValueHandler::SupportsValue(Value* value) 138 { 139 return dynamic_cast<IntegerValue*>(value) != NULL ? 0.5f : 0; 140 } 141 142 143 status_t 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 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 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 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 247 IntegerValueHandler::DefaultIntegerFormat(IntegerValue* value) 248 { 249 return value->IsSigned() ? INTEGER_FORMAT_SIGNED : INTEGER_FORMAT_UNSIGNED; 250 } 251 252 253 status_t 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 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 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 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 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* 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