* 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 <new>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#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),
fUiSettingsFactory(NULL)
{
}
DebuggerSettingsManager::~DebuggerSettingsManager()
{
_Unset();
}
status_t
DebuggerSettingsManager::Init(TeamUiSettingsFactory* factory)
{
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
fUiSettingsFactory = factory;
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) {
_LoadSettings();
} else {
fSettingsPath.Unset();
}
return B_OK;
}
status_t
DebuggerSettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings)
{
AutoLocker<BLocker> 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<BLocker> 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;
while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings)
delete fRecentTeamSettings.RemoveItemAt(0);
}
ObjectDeleter<TeamSettings> 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;
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;
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;
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;
}
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;
}