/* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2016, Rene Gollent, rene@gollent.com. * Distributed under the terms of the MIT License. */ #include "DebuggerSettingsManager.h" #include #include #include #include #include #include #include "TeamSettings.h" static const char* const kSettingsDirPath = "Debugger"; static const char* const kGlobalSettingsName = "Global"; static const int32 kMaxRecentTeamSettings = 10; DebuggerSettingsManager::DebuggerSettingsManager() : SettingsManager(), fLock("settings manager"), fRecentTeamSettings(kMaxRecentTeamSettings, true), fUiSettingsFactory(NULL) { } DebuggerSettingsManager::~DebuggerSettingsManager() { _Unset(); } status_t DebuggerSettingsManager::Init(TeamUiSettingsFactory* factory) { // check the lock status_t error = fLock.InitCheck(); if (error != B_OK) return error; fUiSettingsFactory = factory; // get and create our settings directory if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath, true) == B_OK && fSettingsPath.Append(kSettingsDirPath) == B_OK && create_directory(fSettingsPath.Path(), 0700) == B_OK && fSettingsPath.Append(kGlobalSettingsName) == B_OK) { // load the settings _LoadSettings(); } else { // something went wrong -- clear the path fSettingsPath.Unset(); } return B_OK; } status_t DebuggerSettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings) { AutoLocker locker(fLock); int32 index = _TeamSettingsIndex(teamName); if (index < 0) return B_ENTRY_NOT_FOUND; try { settings = *fRecentTeamSettings.ItemAt(index); return B_OK; } catch (std::bad_alloc&) { return B_NO_MEMORY; } } status_t DebuggerSettingsManager::SaveTeamSettings(const TeamSettings& _settings) { AutoLocker locker(fLock); TeamSettings* settings; int32 index = _TeamSettingsIndex(_settings.TeamName()); if (index >= 0) { settings = fRecentTeamSettings.RemoveItemAt(index); } else { settings = new(std::nothrow) TeamSettings; if (settings == NULL) return B_NO_MEMORY; // enforce recent limit while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings) delete fRecentTeamSettings.RemoveItemAt(0); } ObjectDeleter settingsDeleter(settings); try { *settings = _settings; if (!fRecentTeamSettings.AddItem(settings)) return B_NO_MEMORY; settingsDeleter.Detach(); return _SaveSettings(); } catch (std::bad_alloc&) { return B_NO_MEMORY; } } void DebuggerSettingsManager::_Unset() { fRecentTeamSettings.MakeEmpty(); } status_t DebuggerSettingsManager::_LoadSettings() { _Unset(); if (fSettingsPath.Path() == NULL) return B_ENTRY_NOT_FOUND; // read the settings file BFile file; status_t error = file.SetTo(fSettingsPath.Path(), B_READ_ONLY); if (error != B_OK) return error; BMessage archive; error = archive.Unflatten(&file); if (error != B_OK) return error; // unarchive the recent team settings BMessage childArchive; for (int32 i = 0; archive.FindMessage("teamSettings", i, &childArchive) == B_OK; i++) { TeamSettings* settings = new(std::nothrow) TeamSettings; if (settings == NULL) return B_NO_MEMORY; error = settings->SetTo(childArchive, *fUiSettingsFactory); if (error != B_OK) { delete settings; continue; } if (!fRecentTeamSettings.AddItem(settings)) { delete settings; return B_NO_MEMORY; } } return B_OK; } status_t DebuggerSettingsManager::_SaveSettings() { if (fSettingsPath.Path() == NULL) return B_ENTRY_NOT_FOUND; // archive the recent team settings BMessage archive; for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i); i++) { BMessage childArchive; status_t error = settings->WriteTo(childArchive); if (error != B_OK) return error; error = archive.AddMessage("teamSettings", &childArchive); if (error != B_OK) return error; } // open the settings file BFile file; status_t error = file.SetTo(fSettingsPath.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE); if (error != B_OK) return error; return archive.Flatten(&file); } int32 DebuggerSettingsManager::_TeamSettingsIndex(const char* teamName) const { for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i); i++) { if (settings->TeamName() == teamName) return i; } return -1; }