Merge pull request #478 from Atlante45/master

Settings handling with QSettings
This commit is contained in:
ZappoMan 2013-06-04 17:41:02 -07:00
commit 26542d44c9
4 changed files with 160 additions and 287 deletions

View file

@ -162,7 +162,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_packetCount(0),
_packetsPerSecond(0),
_bytesPerSecond(0),
_bytesCount(0)
_bytesCount(0),
_settings("HighFidelity", "Interface")
{
_applicationStartupTime = startup_time;
_window->setWindowTitle("Interface");
@ -225,6 +226,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_glWidget->setMouseTracking(true);
// initialization continues in initializeGL when OpenGL context is ready
QCoreApplication::setOrganizationDomain("highfidelity.io"); // Used by QSettings on OS X
}
void Application::initializeGL() {
@ -277,8 +280,6 @@ void Application::initializeGL() {
connect(idleTimer, SIGNAL(timeout()), SLOT(idle()));
idleTimer->start(0);
readSettings();
if (_justStarted) {
float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime))/1000000.0;
_justStarted = false;
@ -740,177 +741,6 @@ void Application::wheelEvent(QWheelEvent* event) {
}
}
const char AVATAR_DATA_FILENAME[] = "avatar.ifd";
void Application::readSettingsFile() {
FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "rt");
if (settingsFile) {
char line[LINE_MAX];
while (fgets(line, LINE_MAX, settingsFile) != NULL)
{
if (strcmp(line, " \n") > 0) {
char* token = NULL;
char* settingLine = NULL;
char* toFree = NULL;
settingLine = strdup(line);
if (settingLine != NULL) {
toFree = settingLine;
int i = 0;
char key[128];
char value[128];
while ((token = strsep(&settingLine, "=")) != NULL)
{
switch (i) {
case 0:
strcpy(key, token);
_settingsTable[key] = "";
break;
case 1:
strcpy(value, token);
_settingsTable[key] = token;
break;
default:
break;
}
i++;
}
free(toFree);
}
}
}
fclose(settingsFile);
}
}
void Application::saveSettingsFile() {
FILE* settingsFile = fopen(AVATAR_DATA_FILENAME, "wt");
if (settingsFile) {
for (std::map<std::string, std::string>::iterator i = _settingsTable.begin(); i != _settingsTable.end(); i++)
{
fprintf(settingsFile, "\n%s=%s", i->first.data(), i->second.data());
}
}
fclose(settingsFile);
}
bool Application::getSetting(const char* setting, bool& value, const bool defaultSetting) const {
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
if (iter != _settingsTable.end()) {
int readBool;
int res = sscanf(iter->second.data(), "%d", &readBool);
const char EXPECTED_ITEMS = 1;
if (res == EXPECTED_ITEMS) {
if (readBool == 1) {
value = true;
} else if (readBool == 0) {
value = false;
}
}
} else {
value = defaultSetting;
return false;
}
return true;
}
bool Application::getSetting(const char* setting, float& value, const float defaultSetting) const {
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
if (iter != _settingsTable.end()) {
float readFloat;
int res = sscanf(iter->second.data(), "%f", &readFloat);
const char EXPECTED_ITEMS = 1;
if (res == EXPECTED_ITEMS) {
if (!isnan(readFloat)) {
value = readFloat;
} else {
value = defaultSetting;
return false;
}
} else {
value = defaultSetting;
return false;
}
} else {
value = defaultSetting;
return false;
}
return true;
}
bool Application::getSetting(const char* setting, glm::vec3& value, const glm::vec3& defaultSetting) const {
std::map<std::string, std::string>::const_iterator iter = _settingsTable.find(setting);
if (iter != _settingsTable.end()) {
glm::vec3 readVec;
int res = sscanf(iter->second.data(), "%f,%f,%f", &readVec.x, &readVec.y, &readVec.z);
const char EXPECTED_ITEMS = 3;
if (res == EXPECTED_ITEMS) {
if (!isnan(readVec.x) && !isnan(readVec.y) && !isnan(readVec.z)) {
value = readVec;
} else {
value = defaultSetting;
return false;
}
} else {
value = defaultSetting;
return false;
}
} else {
value = defaultSetting;
return false;
}
return true;
}
const short MAX_SETTINGS_LENGTH = 128;
void Application::setSetting(const char* setting, const bool value) {
char settingValues[MAX_SETTINGS_LENGTH];
sprintf(settingValues, "%d", value);
_settingsTable[setting] = settingValues;
}
void Application::setSetting(const char* setting, const float value) {
char settingValues[MAX_SETTINGS_LENGTH];
sprintf(settingValues, "%f", value);
_settingsTable[setting] = settingValues;
}
void Application::setSetting(const char* setting, const glm::vec3& value) {
char settingValues[MAX_SETTINGS_LENGTH];
sprintf(settingValues, "%f,%f,%f", value.x, value.y, value.z);
_settingsTable[setting] = settingValues;
}
// Every second, check the frame rates and other stuff
void Application::timer() {
gettimeofday(&_timerEnd, NULL);
@ -1143,7 +973,10 @@ void Application::terminate() {
// Close serial port
// close(serial_fd);
saveSettings();
if (_autosave) {
saveSettings();
_settings.sync();
}
if (_enableNetworkThread) {
_stopNetworkReceiveThread = true;
@ -1333,6 +1166,8 @@ void Application::chooseVoxelPaintColor() {
_window->activateWindow();
}
<<<<<<< HEAD
=======
const int MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE = 1500;
struct SendVoxelsOperationArgs {
unsigned char* newBaseOctCode;
@ -1496,6 +1331,7 @@ void Application::pasteVoxels() {
}
}
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
void Application::initMenu() {
QMenuBar* menuBar = new QMenuBar();
_window->setMenuBar(menuBar);
@ -1614,9 +1450,20 @@ void Application::initMenu() {
debugMenu->addAction("Wants Res-In", this, SLOT(setWantsResIn(bool)))->setCheckable(true);
debugMenu->addAction("Wants Monochrome", this, SLOT(setWantsMonochrome(bool)))->setCheckable(true);
debugMenu->addAction("Wants View Delta Sending", this, SLOT(setWantsDelta(bool)))->setCheckable(true);
<<<<<<< HEAD
QMenu* settingsMenu = menuBar->addMenu("Settings");
(_settingsAutosave = settingsMenu->addAction("Autosave", this, SLOT(setAutosave(bool))))->setCheckable(true);
_settingsAutosave->setChecked(true);
settingsMenu->addAction("Load settings", this, SLOT(loadSettings()));
settingsMenu->addAction("Save settings", this, SLOT(saveSettings()));
settingsMenu->addAction("Import settings", this, SLOT(importSettings()));
settingsMenu->addAction("Export settings", this, SLOT(exportSettings()));
=======
_networkAccessManager = new QNetworkAccessManager(this);
_settings = new QSettings("High Fidelity", "Interface", this);
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
}
void Application::updateFrustumRenderModeAction() {
@ -1678,6 +1525,8 @@ void Application::init() {
gettimeofday(&_timerStart, NULL);
gettimeofday(&_lastTimeIdle, NULL);
loadSettings();
}
void Application::updateAvatar(float deltaTime) {
@ -2599,95 +2448,82 @@ void* Application::networkReceive(void* args) {
return NULL;
}
void Application::saveSettings()
{
// Handle any persistent settings saving here when we get a call to terminate.
// This should probably be moved to a map stored in memory at some point to cache settings.
_myAvatar.writeAvatarDataToFile();
setSetting("_gyroLook", _gyroLook->isChecked());
setSetting("_mouseLook", _mouseLook->isChecked());
setSetting("_transmitterDrives", _transmitterDrives->isChecked());
setSetting("_renderVoxels", _renderVoxels->isChecked());
setSetting("_renderVoxelTextures", _renderVoxelTextures->isChecked());
setSetting("_renderStarsOn", _renderStarsOn->isChecked());
setSetting("_renderAtmosphereOn", _renderAtmosphereOn->isChecked());
setSetting("_renderAvatarsOn", _renderAvatarsOn->isChecked());
setSetting("_renderStatsOn", _renderStatsOn->isChecked());
setSetting("_renderFrameTimerOn", _renderFrameTimerOn->isChecked());
setSetting("_renderLookatOn", _renderLookatOn->isChecked());
setSetting("_logOn", _logOn->isChecked());
setSetting("_frustumOn", _frustumOn->isChecked());
setSetting("_viewFrustumFromOffset", _viewFrustumFromOffset->isChecked());
setSetting("_cameraFrustum", _cameraFrustum->isChecked());
saveSettingsFile();
void Application::scanMenuBar(settingsAction modifySetting, QSettings* set) {
if (!_window->menuBar()) {
return;
}
QList<QMenu*> menus = _window->menuBar()->findChildren<QMenu *>();
for (QList<QMenu *>::const_iterator it = menus.begin(); menus.end() != it; ++it) {
scanMenu(*it, modifySetting, set);
}
}
void Application::readSettings()
{
readSettingsFile();
_myAvatar.readAvatarDataFromFile();
bool settingState;
getSetting("_gyroLook", settingState, _gyroLook->isChecked());
_gyroLook->setChecked(settingState);
getSetting("_mouseLook", settingState, _mouseLook->isChecked());
_mouseLook->setChecked(settingState);
getSetting("_transmitterDrives", settingState, _transmitterDrives->isChecked());
_transmitterDrives->setChecked(settingState);
getSetting("_renderVoxels", settingState, _renderVoxels->isChecked());
_renderVoxels->setChecked(settingState);
getSetting("_renderVoxelTextures", settingState, _renderVoxelTextures->isChecked());
_renderVoxelTextures->setChecked(settingState);
getSetting("_renderStarsOn", settingState, _renderStarsOn->isChecked());
_renderStarsOn->setChecked(settingState);
getSetting("_renderAtmosphereOn", settingState, _renderAtmosphereOn->isChecked());
_renderAtmosphereOn->setChecked(settingState);
getSetting("_renderAvatarsOn", settingState, _renderAvatarsOn->isChecked());
_renderAvatarsOn->setChecked(settingState);
getSetting("_renderStatsOn", settingState, _renderStatsOn->isChecked());
_renderStatsOn->setChecked(settingState);
getSetting("_renderFrameTimerOn", settingState, _renderFrameTimerOn->isChecked());
_renderFrameTimerOn->setChecked(settingState);
getSetting("_renderLookatOn", settingState, _renderLookatOn->isChecked());
_renderLookatOn->setChecked(settingState);
getSetting("_logOn", settingState, _logOn->isChecked());
_logOn->setChecked(settingState);
getSetting("_frustumOn", settingState, _frustumOn->isChecked());
_frustumOn->setChecked(settingState);
getSetting("_viewFrustumFromOffset", settingState, _viewFrustumFromOffset->isChecked());
_viewFrustumFromOffset->setChecked(settingState);
getSetting("_cameraFrustum", settingState, _cameraFrustum->isChecked());
_cameraFrustum->setChecked(settingState);
void Application::scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set) {
QList<QAction*> actions = menu->actions();
set->beginGroup(menu->title());
for (QList<QAction *>::const_iterator it = actions.begin(); actions.end() != it; ++it) {
if ((*it)->menu()) {
scanMenu((*it)->menu(), modifySetting, set);
}
if ((*it)->isCheckable()) {
modifySetting(set, *it);
}
}
set->endGroup();
}
void Application::loadAction(QSettings* set, QAction* action) {
action->setChecked(set->value(action->text(), action->isChecked()).toBool());
}
void Application::saveAction(QSettings* set, QAction* action) {
set->setValue(action->text(), action->isChecked());
}
void Application::setAutosave(bool wantsAutosave) {
_autosave = wantsAutosave;
}
void Application::loadSettings(QSettings* set) {
if (!set) set = getSettings();
scanMenuBar(&Application::loadAction, set);
getAvatar()->loadData(set);
}
void Application::saveSettings(QSettings* set) {
if (!set) set = getSettings();
scanMenuBar(&Application::saveAction, set);
getAvatar()->saveData(set);
}
void Application::importSettings() {
QString locationDir(QDesktopServices::displayName(QDesktopServices::DesktopLocation));
QString fileName = QFileDialog::getOpenFileName(_window,
tr("Open .ini config file"),
locationDir,
tr("Text files (*.ini)"));
if (fileName != "") {
QSettings tmp(fileName, QSettings::IniFormat);
loadSettings(&tmp);
}
}
void Application::exportSettings() {
QString locationDir(QDesktopServices::displayName(QDesktopServices::DesktopLocation));
QString fileName = QFileDialog::getSaveFileName(_window,
tr("Save .ini config file"),
locationDir,
tr("Text files (*.ini)"));
if (fileName != "") {
QSettings tmp(fileName, QSettings::IniFormat);
saveSettings(&tmp);
tmp.sync();
}
}

View file

@ -15,6 +15,8 @@
#include <QApplication>
#include <QAction>
#include <QSettings>
#include <QList>
#include <AgentList.h>
@ -69,8 +71,11 @@ public:
Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
VoxelSystem* getVoxels() { return &_voxels; }
QSettings* getSettings() { return &_settings; }
Environment* getEnvironment() { return &_environment; }
bool shouldEchoAudio() { return _echoAudioMode->isChecked(); }
<<<<<<< HEAD
=======
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
@ -124,6 +129,7 @@ public:
@param vecSetting The value to set.
*/
void setSetting(const char* setting, const glm::vec3& value);
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
private slots:
@ -161,12 +167,22 @@ private slots:
void decreaseVoxelSize();
void increaseVoxelSize();
void chooseVoxelPaintColor();
<<<<<<< HEAD
void setAutosave(bool wantsAutosave);
void loadSettings(QSettings* set = NULL);
void saveSettings(QSettings* set = NULL);
void importSettings();
void exportSettings();
=======
void exportVoxels();
void importVoxels();
void cutVoxels();
void copyVoxels();
void pasteVoxels();
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
private:
static bool sendVoxelsOperation(VoxelNode* node, void* extraData);
@ -203,13 +219,13 @@ private:
static void attachNewHeadToAgent(Agent *newAgent);
static void* networkReceive(void* args);
// These two functions are technically not necessary, but they help keep things in one place.
void readSettings(); //! This function is largely to help consolidate getting settings in one place.
void saveSettings(); //! This function is to consolidate any settings setting in one place.
void readSettingsFile(); //! This function reads data from the settings file, splitting data into key value pairs using '=' as a delimiter.
void saveSettingsFile(); //! This function writes all changes in the settings table to the settings file, serializing all settings added through the setSetting functions.
// methodes handling menu settings
typedef void(*settingsAction)(QSettings*, QAction*);
static void loadAction(QSettings* set, QAction* action);
static void saveAction(QSettings* set, QAction* action);
void scanMenuBar(settingsAction modifySetting, QSettings* set);
void scanMenu(QMenu* menu, settingsAction modifySetting, QSettings* set);
QMainWindow* _window;
QGLWidget* _glWidget;
@ -241,6 +257,7 @@ private:
QAction* _cameraFrustum; // which frustum to look at
QAction* _fullScreenMode; // whether we are in full screen mode
QAction* _frustumRenderModeAction;
QAction* _settingsAutosave; // Whether settings are saved automatically
QNetworkAccessManager* _networkAccessManager;
QSettings* _settings;
@ -336,11 +353,8 @@ private:
int _bytesPerSecond;
int _bytesCount;
/*!
* Store settings in a map, storing keys and values as strings.
* Interpret values as needed on demand. through the appropriate getters and setters.
*/
std::map<std::string, std::string> _settingsTable;
QSettings _settings; // Contain Menu settings and Avatar data
bool _autosave; // True if the autosave is on.
};
#endif /* defined(__interface__Application__) */

View file

@ -1252,6 +1252,20 @@ void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity
}
}
<<<<<<< HEAD
void Avatar::loadData(QSettings* set) {
set->beginGroup("Avatar");
_bodyYaw = set->value("bodyYaw", _bodyYaw).toFloat();
_bodyPitch = set->value("bodyPitch", _bodyPitch).toFloat();
_bodyRoll = set->value("bodyRoll", _bodyRoll).toFloat();
_position.x = set->value("position_x", _position.x).toFloat();
_position.y = set->value("position_y", _position.y).toFloat();
_position.z = set->value("position_z", _position.z).toFloat();
set->endGroup();
=======
void Avatar::getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const {
position = _bodyBall[jointID].position;
rotation = _bodyBall[jointID].rotation;
@ -1260,25 +1274,27 @@ void Avatar::getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, gl
void Avatar::writeAvatarDataToFile() {
Application::getInstance()->setSetting("avatarPos", _position);
Application::getInstance()->setSetting("avatarRotation", glm::vec3(_bodyYaw, _bodyPitch, _bodyRoll));
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
}
void Avatar::readAvatarDataFromFile() {
glm::vec3 readPosition;
glm::vec3 readRotation;
Application::getInstance()->getSetting("avatarPos", readPosition, glm::vec3(6.1f, 0, 1.4f));
Application::getInstance()->getSetting("avatarRotation", readRotation, glm::vec3(0, 0, 0));
_bodyYaw = readRotation.x;
_bodyPitch = readRotation.y;
_bodyRoll = readRotation.z;
_position = readPosition;
void Avatar::saveData(QSettings* set) {
set->beginGroup("Avatar");
set->setValue("bodyYaw", _bodyYaw);
set->setValue("bodyPitch", _bodyPitch);
set->setValue("bodyRoll", _bodyRoll);
set->setValue("position_x", _position.x);
set->setValue("position_y", _position.y);
set->setValue("position_z", _position.z);
set->endGroup();
}
// render a makeshift cone section that serves as a body part connecting joint spheres
void Avatar::renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2) {
glBegin(GL_TRIANGLES);
glBegin(GL_TRIANGLES);
glm::vec3 axis = position2 - position1;
float length = glm::length(axis);

View file

@ -11,6 +11,7 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <AvatarData.h>
#include <QSettings>
#include "world.h"
#include "AvatarTouch.h"
#include "AvatarVoxelSystem.h"
@ -130,12 +131,18 @@ public:
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
glm::vec3 getThrust() { return _thrust; };
<<<<<<< HEAD
// get/set avatar data
void saveData(QSettings* set);
void loadData(QSettings* set);
=======
// Get the position/rotation of a single body ball
void getBodyBallTransform(AvatarJointID jointID, glm::vec3& position, glm::quat& rotation) const;
//read/write avatar data
void writeAvatarDataToFile();
void readAvatarDataFromFile();
>>>>>>> 82c1ee2062577f614cfde096f08adfc9e83e4f0f
private:
// privatize copy constructor and assignment operator to avoid copying