Merge branch 'usersettings'

openmw-38
Marc Zinnschlag 9 years ago
commit 9c7bbd667b

@ -349,8 +349,8 @@ configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg.local
configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg configure_file(${OpenMW_SOURCE_DIR}/files/openmw.cfg
"${OpenMW_BINARY_DIR}/openmw.cfg.install") "${OpenMW_BINARY_DIR}/openmw.cfg.install")
configure_file(${OpenMW_SOURCE_DIR}/files/opencs.ini configure_file(${OpenMW_SOURCE_DIR}/files/openmw-cs.cfg
"${OpenMW_BINARY_DIR}/opencs.ini") "${OpenMW_BINARY_DIR}/openmw-cs.cfg")
configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters configure_file(${OpenMW_SOURCE_DIR}/files/opencs/defaultfilters
"${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY) "${OpenMW_BINARY_DIR}/resources/defaultfilters" COPYONLY)
@ -450,7 +450,7 @@ IF(NOT WIN32 AND NOT APPLE)
INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw") INSTALL(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${SYSCONFDIR}" COMPONENT "openmw")
IF(BUILD_OPENCS) IF(BUILD_OPENCS)
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${SYSCONFDIR}" COMPONENT "opencs")
ENDIF(BUILD_OPENCS) ENDIF(BUILD_OPENCS)
# Install resources # Install resources
@ -483,7 +483,7 @@ if(WIN32)
ENDIF(BUILD_ESSIMPORTER) ENDIF(BUILD_ESSIMPORTER)
IF(BUILD_OPENCS) IF(BUILD_OPENCS)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".") INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-cs.exe" DESTINATION ".")
INSTALL(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION ".") INSTALL(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION ".")
ENDIF(BUILD_OPENCS) ENDIF(BUILD_OPENCS)
IF(BUILD_WIZARD) IF(BUILD_WIZARD)
INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".") INSTALL(PROGRAMS "${OpenMW_BINARY_DIR}/Release/openmw-wizard.exe" DESTINATION ".")
@ -748,7 +748,7 @@ if (APPLE)
install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/openmw.cfg.install" RENAME "openmw.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/settings-default.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/gamecontrollerdb.txt" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
install(FILES "${OpenMW_BINARY_DIR}/opencs.ini" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime) install(FILES "${OpenMW_BINARY_DIR}/openmw-cs.cfg" DESTINATION "${INSTALL_SUBDIR}" COMPONENT Runtime)
set(CPACK_GENERATOR "DragNDrop") set(CPACK_GENERATOR "DragNDrop")
set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION}) set(CPACK_PACKAGE_VERSION ${OPENMW_VERSION})

@ -106,31 +106,16 @@ opencs_units_noqt (view/tools
subviews subviews
) )
opencs_units (view/settings opencs_units (view/prefs
settingwindow dialogue pagebase page
dialog
page
view
booleanview
textview
listview
rangeview
resizeablestackedwidget
spinbox
) )
opencs_units_noqt (view/settings opencs_units (model/prefs
frame state setting intsetting doublesetting boolsetting enumsetting coloursetting
) )
opencs_units (model/settings opencs_units_noqt (model/prefs
usersettings category
setting
connector
)
opencs_hdrs_noqt (model/settings
support
) )
opencs_units_noqt (model/filter opencs_units_noqt (model/filter

@ -18,7 +18,7 @@
#endif #endif
CS::Editor::Editor () CS::Editor::Editor ()
: mUserSettings (mCfgMgr), mDocumentManager (mCfgMgr), : mSettingsState (mCfgMgr), mDocumentManager (mCfgMgr),
mViewManager (mDocumentManager), mPid(""), mViewManager (mDocumentManager), mPid(""),
mLock(), mMerge (mDocumentManager), mLock(), mMerge (mDocumentManager),
mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL) mIpcServerName ("org.openmw.OpenCS"), mServer(NULL), mClientSocket(NULL)
@ -27,9 +27,6 @@ CS::Editor::Editor ()
setupDataFiles (config.first); setupDataFiles (config.first);
CSMSettings::UserSettings::instance().loadSettings ("opencs.ini");
mSettings.setModel (CSMSettings::UserSettings::instance());
NifOsg::Loader::setShowMarkers(true); NifOsg::Loader::setShowMarkers(true);
mVFS.reset(new VFS::Manager(mFsStrict)); mVFS.reset(new VFS::Manager(mFsStrict));

@ -17,15 +17,16 @@
#include <components/files/multidircollection.hpp> #include <components/files/multidircollection.hpp>
#include "model/settings/usersettings.hpp"
#include "model/doc/documentmanager.hpp" #include "model/doc/documentmanager.hpp"
#include "model/prefs/state.hpp"
#include "view/doc/viewmanager.hpp" #include "view/doc/viewmanager.hpp"
#include "view/doc/startup.hpp" #include "view/doc/startup.hpp"
#include "view/doc/filedialog.hpp" #include "view/doc/filedialog.hpp"
#include "view/doc/newgame.hpp" #include "view/doc/newgame.hpp"
#include "view/settings/dialog.hpp" #include "view/prefs/dialogue.hpp"
#include "view/tools/merge.hpp" #include "view/tools/merge.hpp"
@ -49,12 +50,12 @@ namespace CS
std::auto_ptr<VFS::Manager> mVFS; std::auto_ptr<VFS::Manager> mVFS;
Files::ConfigurationManager mCfgMgr; Files::ConfigurationManager mCfgMgr;
CSMSettings::UserSettings mUserSettings; CSMPrefs::State mSettingsState;
CSMDoc::DocumentManager mDocumentManager; CSMDoc::DocumentManager mDocumentManager;
CSVDoc::ViewManager mViewManager; CSVDoc::ViewManager mViewManager;
CSVDoc::StartupDialogue mStartup; CSVDoc::StartupDialogue mStartup;
CSVDoc::NewGameDialogue mNewGame; CSVDoc::NewGameDialogue mNewGame;
CSVSettings::Dialog mSettings; CSVPrefs::Dialogue mSettings;
CSVDoc::FileDialog mFileDialog; CSVDoc::FileDialog mFileDialog;
boost::filesystem::path mLocal; boost::filesystem::path mLocal;
boost::filesystem::path mResources; boost::filesystem::path mResources;

@ -6,7 +6,6 @@
#include <QTimer> #include <QTimer>
#include "../world/universalid.hpp" #include "../world/universalid.hpp"
#include "../settings/usersettings.hpp"
#include "state.hpp" #include "state.hpp"
#include "stage.hpp" #include "stage.hpp"
@ -23,9 +22,6 @@ void CSMDoc::Operation::prepareStages()
{ {
iter->second = iter->first->setup(); iter->second = iter->first->setup();
mTotalSteps += iter->second; mTotalSteps += iter->second;
for (std::map<QString, QStringList>::const_iterator iter2 (mSettings.begin()); iter2!=mSettings.end(); ++iter2)
iter->first->updateUserSetting (iter2->first, iter2->second);
} }
} }
@ -64,14 +60,6 @@ void CSMDoc::Operation::appendStage (Stage *stage)
mStages.push_back (std::make_pair (stage, 0)); mStages.push_back (std::make_pair (stage, 0));
} }
void CSMDoc::Operation::configureSettings (const std::vector<QString>& settings)
{
for (std::vector<QString>::const_iterator iter (settings.begin()); iter!=settings.end(); ++iter)
{
mSettings.insert (std::make_pair (*iter, CSMSettings::UserSettings::instance().definitions (*iter)));
}
}
void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity) void CSMDoc::Operation::setDefaultSeverity (Message::Severity severity)
{ {
mDefaultSeverity = severity; mDefaultSeverity = severity;
@ -101,14 +89,6 @@ void CSMDoc::Operation::abort()
mCurrentStage = mStages.end(); mCurrentStage = mStages.end();
} }
void CSMDoc::Operation::updateUserSetting (const QString& name, const QStringList& value)
{
std::map<QString, QStringList>::iterator iter = mSettings.find (name);
if (iter!=mSettings.end())
iter->second = value;
}
void CSMDoc::Operation::executeStage() void CSMDoc::Operation::executeStage()
{ {
if (!mPrepared) if (!mPrepared)

@ -34,7 +34,6 @@ namespace CSMDoc
bool mError; bool mError;
bool mConnected; bool mConnected;
QTimer *mTimer; QTimer *mTimer;
std::map<QString, QStringList> mSettings;
bool mPrepared; bool mPrepared;
Message::Severity mDefaultSeverity; Message::Severity mDefaultSeverity;
@ -53,11 +52,6 @@ namespace CSMDoc
/// ///
/// \attention Do no call this function while this Operation is running. /// \attention Do no call this function while this Operation is running.
/// Specify settings to be passed on to stages.
///
/// \attention Do no call this function while this Operation is running.
void configureSettings (const std::vector<QString>& settings);
/// \attention Do no call this function while this Operation is running. /// \attention Do no call this function while this Operation is running.
void setDefaultSeverity (Message::Severity severity); void setDefaultSeverity (Message::Severity severity);
@ -77,8 +71,6 @@ namespace CSMDoc
void run(); void run();
void updateUserSetting (const QString& name, const QStringList& value);
private slots: private slots:
void executeStage(); void executeStage();

@ -1,7 +1,5 @@
#include "operationholder.hpp" #include "operationholder.hpp"
#include "../settings/usersettings.hpp"
#include "operation.hpp" #include "operation.hpp"
CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false) CSMDoc::OperationHolder::OperationHolder (Operation *operation) : mRunning (false)
@ -30,9 +28,6 @@ void CSMDoc::OperationHolder::setOperation (Operation *operation)
connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort())); connect (this, SIGNAL (abortSignal()), mOperation, SLOT (abort()));
connect (&mThread, SIGNAL (started()), mOperation, SLOT (run())); connect (&mThread, SIGNAL (started()), mOperation, SLOT (run()));
connect (&CSMSettings::UserSettings::instance(), SIGNAL (userSettingUpdated (const QString&, const QStringList&)),
mOperation, SLOT (updateUserSetting (const QString&, const QStringList&)));
} }
bool CSMDoc::OperationHolder::isRunning() const bool CSMDoc::OperationHolder::isRunning() const

@ -1,5 +1,3 @@
#include "stage.hpp" #include "stage.hpp"
CSMDoc::Stage::~Stage() {} CSMDoc::Stage::~Stage() {}
void CSMDoc::Stage::updateUserSetting (const QString& name, const QStringList& value) {}

@ -23,11 +23,7 @@ namespace CSMDoc
virtual void perform (int stage, Messages& messages) = 0; virtual void perform (int stage, Messages& messages) = 0;
///< Messages resulting from this stage will be appended to \a messages. ///< Messages resulting from this stage will be appended to \a messages.
/// Default-implementation: ignore
virtual void updateUserSetting (const QString& name, const QStringList& value);
}; };
} }
#endif #endif

@ -0,0 +1,47 @@
#include "boolsetting.hpp"
#include <QCheckBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp>
#include "category.hpp"
#include "state.hpp"
CSMPrefs::BoolSetting::BoolSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, bool default_)
: Setting (parent, values, mutex, key, label), mDefault (default_)
{}
CSMPrefs::BoolSetting& CSMPrefs::BoolSetting::setTooltip (const std::string& tooltip)
{
mTooltip = tooltip;
return *this;
}
std::pair<QWidget *, QWidget *> CSMPrefs::BoolSetting::makeWidgets (QWidget *parent)
{
QCheckBox *widget = new QCheckBox (QString::fromUtf8 (getLabel().c_str()), parent);
widget->setCheckState (mDefault ? Qt::Checked : Qt::Unchecked);
if (!mTooltip.empty())
{
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
widget->setToolTip (tooltip);
}
connect (widget, SIGNAL (stateChanged (int)), this, SLOT (valueChanged (int)));
return std::make_pair (static_cast<QWidget *> (0), widget);
}
void CSMPrefs::BoolSetting::valueChanged (int value)
{
{
QMutexLocker lock (getMutex());
getValues().setBool (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this);
}

@ -0,0 +1,31 @@
#ifndef CSM_PREFS_BOOLSETTING_H
#define CSM_PREFS_BOOLSETTING_H
#include "setting.hpp"
namespace CSMPrefs
{
class BoolSetting : public Setting
{
Q_OBJECT
std::string mTooltip;
bool mDefault;
public:
BoolSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, bool default_);
BoolSetting& setTooltip (const std::string& tooltip);
/// Return label, input widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
private slots:
void valueChanged (int value);
};
}
#endif

@ -0,0 +1,51 @@
#include "category.hpp"
#include <stdexcept>
#include "setting.hpp"
#include "state.hpp"
CSMPrefs::Category::Category (State *parent, const std::string& key)
: mParent (parent), mKey (key)
{}
const std::string& CSMPrefs::Category::getKey() const
{
return mKey;
}
CSMPrefs::State *CSMPrefs::Category::getState() const
{
return mParent;
}
void CSMPrefs::Category::addSetting (Setting *setting)
{
mSettings.push_back (setting);
}
CSMPrefs::Category::Iterator CSMPrefs::Category::begin()
{
return mSettings.begin();
}
CSMPrefs::Category::Iterator CSMPrefs::Category::end()
{
return mSettings.end();
}
CSMPrefs::Setting& CSMPrefs::Category::operator[] (const std::string& key)
{
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
if ((*iter)->getKey()==key)
return **iter;
throw std::logic_error ("Invalid user setting: " + key);
}
void CSMPrefs::Category::update()
{
for (Iterator iter = mSettings.begin(); iter!=mSettings.end(); ++iter)
mParent->update (**iter);
}

@ -0,0 +1,45 @@
#ifndef CSM_PREFS_CATEGORY_H
#define CSM_PREFS_CATEGORY_H
#include <string>
#include <vector>
namespace CSMPrefs
{
class State;
class Setting;
class Category
{
public:
typedef std::vector<Setting *> Container;
typedef Container::iterator Iterator;
private:
State *mParent;
std::string mKey;
Container mSettings;
public:
Category (State *parent, const std::string& key);
const std::string& getKey() const;
State *getState() const;
void addSetting (Setting *setting);
Iterator begin();
Iterator end();
Setting& operator[] (const std::string& key);
void update();
};
}
#endif

@ -0,0 +1,52 @@
#include "coloursetting.hpp"
#include <QLabel>
#include <QMutexLocker>
#include <components/settings/settings.hpp>
#include "../../view/widget/coloreditor.hpp"
#include "category.hpp"
#include "state.hpp"
CSMPrefs::ColourSetting::ColourSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, QColor default_)
: Setting (parent, values, mutex, key, label), mDefault (default_)
{}
CSMPrefs::ColourSetting& CSMPrefs::ColourSetting::setTooltip (const std::string& tooltip)
{
mTooltip = tooltip;
return *this;
}
std::pair<QWidget *, QWidget *> CSMPrefs::ColourSetting::makeWidgets (QWidget *parent)
{
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
CSVWidget::ColorEditor *widget = new CSVWidget::ColorEditor (mDefault, parent);
if (!mTooltip.empty())
{
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
label->setToolTip (tooltip);
widget->setToolTip (tooltip);
}
connect (widget, SIGNAL (pickingFinished()), this, SLOT (valueChanged()));
return std::make_pair (label, widget);
}
void CSMPrefs::ColourSetting::valueChanged()
{
CSVWidget::ColorEditor& widget = dynamic_cast<CSVWidget::ColorEditor&> (*sender());
{
QMutexLocker lock (getMutex());
getValues().setString (getKey(), getParent()->getKey(), widget.color().name().toUtf8().data());
}
getParent()->getState()->update (*this);
}

@ -0,0 +1,34 @@
#ifndef CSM_PREFS_COLOURSETTING_H
#define CSM_PREFS_COLOURSETTING_H
#include "setting.hpp"
#include <QColor>
namespace CSMPrefs
{
class ColourSetting : public Setting
{
Q_OBJECT
std::string mTooltip;
QColor mDefault;
public:
ColourSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label,
QColor default_);
ColourSetting& setTooltip (const std::string& tooltip);
/// Return label, input widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
private slots:
void valueChanged();
};
}
#endif

@ -0,0 +1,75 @@
#include "doublesetting.hpp"
#include <limits>
#include <QLabel>
#include <QDoubleSpinBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp>
#include "category.hpp"
#include "state.hpp"
CSMPrefs::DoubleSetting::DoubleSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, double default_)
: Setting (parent, values, mutex, key, label),
mMin (0), mMax (std::numeric_limits<double>::max()),
mDefault (default_)
{}
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setRange (double min, double max)
{
mMin = min;
mMax = max;
return *this;
}
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMin (double min)
{
mMin = min;
return *this;
}
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setMax (double max)
{
mMax = max;
return *this;
}
CSMPrefs::DoubleSetting& CSMPrefs::DoubleSetting::setTooltip (const std::string& tooltip)
{
mTooltip = tooltip;
return *this;
}
std::pair<QWidget *, QWidget *> CSMPrefs::DoubleSetting::makeWidgets (QWidget *parent)
{
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
QDoubleSpinBox *widget = new QDoubleSpinBox (parent);
widget->setRange (mMin, mMax);
widget->setValue (mDefault);
if (!mTooltip.empty())
{
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
label->setToolTip (tooltip);
widget->setToolTip (tooltip);
}
connect (widget, SIGNAL (valueChanged (double)), this, SLOT (valueChanged (double)));
return std::make_pair (label, widget);
}
void CSMPrefs::DoubleSetting::valueChanged (double value)
{
{
QMutexLocker lock (getMutex());
getValues().setFloat (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this);
}

@ -0,0 +1,41 @@
#ifndef CSM_PREFS_DOUBLESETTING_H
#define CSM_PREFS_DOUBLESETTING_H
#include "setting.hpp"
namespace CSMPrefs
{
class DoubleSetting : public Setting
{
Q_OBJECT
double mMin;
double mMax;
std::string mTooltip;
double mDefault;
public:
DoubleSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label,
double default_);
// defaults to [0, std::numeric_limits<double>::max()]
DoubleSetting& setRange (double min, double max);
DoubleSetting& setMin (double min);
DoubleSetting& setMax (double max);
DoubleSetting& setTooltip (const std::string& tooltip);
/// Return label, input widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
private slots:
void valueChanged (double value);
};
}
#endif

@ -0,0 +1,112 @@
#include "enumsetting.hpp"
#include <QLabel>
#include <QComboBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp>
#include "category.hpp"
#include "state.hpp"
CSMPrefs::EnumValue::EnumValue (const std::string& value, const std::string& tooltip)
: mValue (value), mTooltip (tooltip)
{}
CSMPrefs::EnumValue::EnumValue (const char *value)
: mValue (value)
{}
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValues& values)
{
mValues.insert (mValues.end(), values.mValues.begin(), values.mValues.end());
return *this;
}
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const EnumValue& value)
{
mValues.push_back (value);
return *this;
}
CSMPrefs::EnumValues& CSMPrefs::EnumValues::add (const std::string& value, const std::string& tooltip)
{
mValues.push_back (EnumValue (value, tooltip));
return *this;
}
CSMPrefs::EnumSetting::EnumSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, const EnumValue& default_)
: Setting (parent, values, mutex, key, label), mDefault (default_)
{}
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::setTooltip (const std::string& tooltip)
{
mTooltip = tooltip;
return *this;
}
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValues (const EnumValues& values)
{
mValues.add (values);
return *this;
}
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const EnumValue& value)
{
mValues.add (value);
return *this;
}
CSMPrefs::EnumSetting& CSMPrefs::EnumSetting::addValue (const std::string& value, const std::string& tooltip)
{
mValues.add (value, tooltip);
return *this;
}
std::pair<QWidget *, QWidget *> CSMPrefs::EnumSetting::makeWidgets (QWidget *parent)
{
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
QComboBox *widget = new QComboBox (parent);
int index = 0;
for (int i=0; i<static_cast<int> (mValues.mValues.size()); ++i)
{
if (mDefault.mValue==mValues.mValues[i].mValue)
index = i;
widget->addItem (QString::fromUtf8 (mValues.mValues[i].mValue.c_str()));
if (!mValues.mValues[i].mTooltip.empty())
widget->setItemData (i, QString::fromUtf8 (mValues.mValues[i].mTooltip.c_str()),
Qt::ToolTipRole);
}
widget->setCurrentIndex (index);
if (!mTooltip.empty())
{
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
label->setToolTip (tooltip);
}
connect (widget, SIGNAL (currentIndexChanged (int)), this, SLOT (valueChanged (int)));
return std::make_pair (label, widget);
}
void CSMPrefs::EnumSetting::valueChanged (int value)
{
{
QMutexLocker lock (getMutex());
getValues().setString (getKey(), getParent()->getKey(), mValues.mValues.at (value).mValue);
}
getParent()->getState()->update (*this);
}

@ -0,0 +1,62 @@
#ifndef CSM_PREFS_ENUMSETTING_H
#define CSM_PREFS_ENUMSETTING_H
#include <vector>
#include "setting.hpp"
namespace CSMPrefs
{
struct EnumValue
{
std::string mValue;
std::string mTooltip;
EnumValue (const std::string& value, const std::string& tooltip = "");
EnumValue (const char *value);
};
struct EnumValues
{
std::vector<EnumValue> mValues;
EnumValues& add (const EnumValues& values);
EnumValues& add (const EnumValue& value);
EnumValues& add (const std::string& value, const std::string& tooltip);
};
class EnumSetting : public Setting
{
Q_OBJECT
std::string mTooltip;
EnumValue mDefault;
EnumValues mValues;
public:
EnumSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label,
const EnumValue& default_);
EnumSetting& setTooltip (const std::string& tooltip);
EnumSetting& addValues (const EnumValues& values);
EnumSetting& addValue (const EnumValue& value);
EnumSetting& addValue (const std::string& value, const std::string& tooltip);
/// Return label, input widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
private slots:
void valueChanged (int value);
};
}
#endif

@ -0,0 +1,74 @@
#include "intsetting.hpp"
#include <limits>
#include <QLabel>
#include <QSpinBox>
#include <QMutexLocker>
#include <components/settings/settings.hpp>
#include "category.hpp"
#include "state.hpp"
CSMPrefs::IntSetting::IntSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, int default_)
: Setting (parent, values, mutex, key, label), mMin (0), mMax (std::numeric_limits<int>::max()),
mDefault (default_)
{}
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setRange (int min, int max)
{
mMin = min;
mMax = max;
return *this;
}
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMin (int min)
{
mMin = min;
return *this;
}
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setMax (int max)
{
mMax = max;
return *this;
}
CSMPrefs::IntSetting& CSMPrefs::IntSetting::setTooltip (const std::string& tooltip)
{
mTooltip = tooltip;
return *this;
}
std::pair<QWidget *, QWidget *> CSMPrefs::IntSetting::makeWidgets (QWidget *parent)
{
QLabel *label = new QLabel (QString::fromUtf8 (getLabel().c_str()), parent);
QSpinBox *widget = new QSpinBox (parent);
widget->setRange (mMin, mMax);
widget->setValue (mDefault);
if (!mTooltip.empty())
{
QString tooltip = QString::fromUtf8 (mTooltip.c_str());
label->setToolTip (tooltip);
widget->setToolTip (tooltip);
}
connect (widget, SIGNAL (valueChanged (int)), this, SLOT (valueChanged (int)));
return std::make_pair (label, widget);
}
void CSMPrefs::IntSetting::valueChanged (int value)
{
{
QMutexLocker lock (getMutex());
getValues().setInt (getKey(), getParent()->getKey(), value);
}
getParent()->getState()->update (*this);
}

@ -0,0 +1,40 @@
#ifndef CSM_PREFS_INTSETTING_H
#define CSM_PREFS_INTSETTING_H
#include "setting.hpp"
namespace CSMPrefs
{
class IntSetting : public Setting
{
Q_OBJECT
int mMin;
int mMax;
std::string mTooltip;
int mDefault;
public:
IntSetting (Category *parent, Settings::Manager *values,
QMutex *mutex, const std::string& key, const std::string& label, int default_);
// defaults to [0, std::numeric_limits<int>::max()]
IntSetting& setRange (int min, int max);
IntSetting& setMin (int min);
IntSetting& setMax (int max);
IntSetting& setTooltip (const std::string& tooltip);
/// Return label, input widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
private slots:
void valueChanged (int value);
};
}
#endif

@ -0,0 +1,97 @@
#include "setting.hpp"
#include <QColor>
#include <QMutexLocker>
#include "category.hpp"
#include "state.hpp"
Settings::Manager& CSMPrefs::Setting::getValues()
{
return *mValues;
}
QMutex *CSMPrefs::Setting::getMutex()
{
return mMutex;
}
CSMPrefs::Setting::Setting (Category *parent, Settings::Manager *values, QMutex *mutex,
const std::string& key, const std::string& label)
: QObject (parent->getState()), mParent (parent), mValues (values), mMutex (mutex), mKey (key),
mLabel (label)
{}
CSMPrefs::Setting:: ~Setting() {}
std::pair<QWidget *, QWidget *> CSMPrefs::Setting::makeWidgets (QWidget *parent)
{
return std::pair<QWidget *, QWidget *> (0, 0);
}
const CSMPrefs::Category *CSMPrefs::Setting::getParent() const
{
return mParent;
}
const std::string& CSMPrefs::Setting::getKey() const
{
return mKey;
}
const std::string& CSMPrefs::Setting::getLabel() const
{
return mLabel;
}
int CSMPrefs::Setting::toInt() const
{
QMutexLocker lock (mMutex);
return mValues->getInt (mKey, mParent->getKey());
}
double CSMPrefs::Setting::toDouble() const
{
QMutexLocker lock (mMutex);
return mValues->getFloat (mKey, mParent->getKey());
}
std::string CSMPrefs::Setting::toString() const
{
QMutexLocker lock (mMutex);
return mValues->getString (mKey, mParent->getKey());
}
bool CSMPrefs::Setting::isTrue() const
{
QMutexLocker lock (mMutex);
return mValues->getBool (mKey, mParent->getKey());
}
QColor CSMPrefs::Setting::toColor() const
{
QMutexLocker lock (mMutex);
return QColor (QString::fromUtf8 (toString().c_str()));
}
bool CSMPrefs::operator== (const Setting& setting, const std::string& key)
{
std::string fullKey = setting.getParent()->getKey() + "/" + setting.getKey();
return fullKey==key;
}
bool CSMPrefs::operator== (const std::string& key, const Setting& setting)
{
return setting==key;
}
bool CSMPrefs::operator!= (const Setting& setting, const std::string& key)
{
return !(setting==key);
}
bool CSMPrefs::operator!= (const std::string& key, const Setting& setting)
{
return !(key==setting);
}

@ -0,0 +1,74 @@
#ifndef CSM_PREFS_SETTING_H
#define CSM_PREFS_SETTING_H
#include <string>
#include <utility>
#include <QObject>
class QWidget;
class QColor;
class QMutex;
namespace Settings
{
class Manager;
}
namespace CSMPrefs
{
class Category;
class Setting : public QObject
{
Q_OBJECT
Category *mParent;
Settings::Manager *mValues;
QMutex *mMutex;
std::string mKey;
std::string mLabel;
protected:
Settings::Manager& getValues();
QMutex *getMutex();
public:
Setting (Category *parent, Settings::Manager *values, QMutex *mutex, const std::string& key, const std::string& label);
virtual ~Setting();
/// Return label, input widget.
///
/// \note first can be a 0-pointer, which means that the label is part of the input
/// widget.
virtual std::pair<QWidget *, QWidget *> makeWidgets (QWidget *parent);
const Category *getParent() const;
const std::string& getKey() const;
const std::string& getLabel() const;
int toInt() const;
double toDouble() const;
std::string toString() const;
bool isTrue() const;
QColor toColor() const;
};
// note: fullKeys have the format categoryKey/settingKey
bool operator== (const Setting& setting, const std::string& fullKey);
bool operator== (const std::string& fullKey, const Setting& setting);
bool operator!= (const Setting& setting, const std::string& fullKey);
bool operator!= (const std::string& fullKey, const Setting& setting);
}
#endif

@ -0,0 +1,392 @@
#include "state.hpp"
#include <stdexcept>
#include <algorithm>
#include <sstream>
#include "intsetting.hpp"
#include "doublesetting.hpp"
#include "boolsetting.hpp"
#include "coloursetting.hpp"
CSMPrefs::State *CSMPrefs::State::sThis = 0;
void CSMPrefs::State::load()
{
// default settings file
boost::filesystem::path local = mConfigurationManager.getLocalPath() / mConfigFile;
boost::filesystem::path global = mConfigurationManager.getGlobalPath() / mConfigFile;
if (boost::filesystem::exists (local))
mSettings.loadDefault (local.string());
else if (boost::filesystem::exists (global))
mSettings.loadDefault (global.string());
else
throw std::runtime_error ("No default settings file found! Make sure the file \"openmw-cs.cfg\" was properly installed.");
// user settings file
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
if (boost::filesystem::exists (user))
mSettings.loadUser (user.string());
}
void CSMPrefs::State::declare()
{
declareCategory ("Windows");
declareInt ("default-width", "Default window width", 800).
setTooltip ("Newly opened top-level windows will open with this width.").
setMin (80);
declareInt ("default-height", "Default window height", 600).
setTooltip ("Newly opened top-level windows will open with this height.").
setMin (80);
declareBool ("show-statusbar", "Show Status Bar", true).
setTooltip ("If a newly open top level window is showing status bars or not. "
" Note that this does not affect existing windows.");
declareSeparator();
declareBool ("reuse", "Reuse Subviews", true).
setTooltip ("When a new subview is requested and a matching subview already "
" exist, do not open a new subview and use the existing one instead.");
declareInt ("max-subviews", "Maximum number of subviews per top-level window", 256).
setTooltip ("If the maximum number is reached and a new subview is opened "
"it will be placed into a new top-level window.").
setRange (1, 256);
declareBool ("hide-subview", "Hide single subview", false).
setTooltip ("When a view contains only a single subview, hide the subview title "
"bar and if this subview is closed also close the view (unless it is the last "
"view for this document)");
declareInt ("minimum-width", "Minimum subview width", 325).
setTooltip ("Minimum width of subviews.").
setRange (50, 10000);
declareSeparator();
EnumValue scrollbarOnly ("Scrollbar Only", "Simple addition of scrollbars, the view window "
"does not grow automatically.");
declareEnum ("mainwindow-scrollbar", "Horizontal scrollbar mode for main window.", scrollbarOnly).
addValue (scrollbarOnly).
addValue ("Grow Only", "The view window grows as subviews are added. No scrollbars.").
addValue ("Grow then Scroll", "The view window grows. The scrollbar appears once it cannot grow any further.");
declareBool ("grow-limit", "Grow Limit Screen", false).
setTooltip ("When \"Grow then Scroll\" option is selected, the window size grows to"
" the width of the virtual desktop. \nIf this option is selected the the window growth"
"is limited to the current screen.");
declareCategory ("Records");
EnumValue iconAndText ("Icon and Text");
EnumValues recordValues;
recordValues.add (iconAndText).add ("Icon Only").add ("Text Only");
declareEnum ("status-format", "Modification status display format", iconAndText).
addValues (recordValues);
declareEnum ("type-format", "ID type display format", iconAndText).
addValues (recordValues);
declareCategory ("ID Tables");
EnumValue inPlaceEdit ("Edit in Place", "Edit the clicked cell");
EnumValue editRecord ("Edit Record", "Open a dialogue subview for the clicked record");
EnumValue view ("View", "Open a scene subview for the clicked record (not available everywhere)");
EnumValue editRecordAndClose ("Edit Record and Close");
EnumValues doubleClickValues;
doubleClickValues.add (inPlaceEdit).add (editRecord).add (view).add ("Revert").
add ("Delete").add (editRecordAndClose).
add ("View and Close", "Open a scene subview for the clicked record and close the table subview");
declareEnum ("double", "Double Click", inPlaceEdit).addValues (doubleClickValues);
declareEnum ("double-s", "Shift Double Click", editRecord).addValues (doubleClickValues);
declareEnum ("double-c", "Control Double Click", view).addValues (doubleClickValues);
declareEnum ("double-sc", "Shift Control Double Click", editRecordAndClose).addValues (doubleClickValues);
declareSeparator();
EnumValue jumpAndSelect ("Jump and Select", "Scroll new record into view and make it the selection");
declareEnum ("jump-to-added", "Action on adding or cloning a record", jumpAndSelect).
addValue (jumpAndSelect).
addValue ("Jump Only", "Scroll new record into view").
addValue ("No Jump", "No special action");
declareBool ("extended-config",
"Manually specify affected record types for an extended delete/revert", false).
setTooltip ("Delete and revert commands have an extended form that also affects "
"associated records.\n\n"
"If this option is enabled, types of affected records are selected "
"manually before a command execution.\nOtherwise, all associated "
"records are deleted/reverted immediately.");
declareCategory ("ID Dialogues");
declareBool ("toolbar", "Show toolbar", true);
declareCategory ("Reports");
EnumValue actionNone ("None");
EnumValue actionEdit ("Edit", "Open a table or dialogue suitable for addressing the listed report");
EnumValue actionRemove ("Remove", "Remove the report from the report table");
EnumValue actionEditAndRemove ("Edit And Remove", "Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table");
EnumValues reportValues;
reportValues.add (actionNone).add (actionEdit).add (actionRemove).add (actionEditAndRemove);
declareEnum ("double", "Double Click", actionEdit).addValues (reportValues);
declareEnum ("double-s", "Shift Double Click", actionRemove).addValues (reportValues);
declareEnum ("double-c", "Control Double Click", actionEditAndRemove).addValues (reportValues);
declareEnum ("double-sc", "Shift Control Double Click", actionNone).addValues (reportValues);
declareCategory ("Search & Replace");
declareInt ("char-before", "Characters before search string", 10).
setTooltip ("Maximum number of character to display in search result before the searched text");
declareInt ("char-after", "Characters after search string", 10).
setTooltip ("Maximum number of character to display in search result after the searched text");
declareBool ("auto-delete", "Delete row from result table after a successful replace", true);
declareCategory ("Scripts");
declareBool ("show-linenum", "Show Line Numbers", true).
setTooltip ("Show line numbers to the left of the script editor window."
"The current row and column numbers of the text cursor are shown at the bottom.");
declareBool ("mono-font", "Use monospace font", true);
EnumValue warningsNormal ("Normal", "Report warnings as warning");
declareEnum ("warnings", "Warning Mode", warningsNormal).
addValue ("Ignore", "Do not report warning").
addValue (warningsNormal).
addValue ("Strcit", "Promote warning to an error");
declareBool ("toolbar", "Show toolbar", true);
declareInt ("compile-delay", "Delay between updating of source errors", 100).
setTooltip ("Delay in milliseconds").
setRange (0, 10000);
declareInt ("error-height", "Initial height of the error panel", 100).
setRange (100, 10000);
declareSeparator();
declareColour ("colour-int", "Highlight Colour: Integer Literals", QColor ("darkmagenta"));
declareColour ("colour-float", "Highlight Colour: Float Literals", QColor ("magenta"));
declareColour ("colour-name", "Highlight Colour: Names", QColor ("grey"));
declareColour ("colour-keyword", "Highlight Colour: Keywords", QColor ("red"));
declareColour ("colour-special", "Highlight Colour: Special Characters", QColor ("darkorange"));
declareColour ("colour-comment", "Highlight Colour: Comments", QColor ("green"));
declareColour ("colour-id", "Highlight Colour: IDs", QColor ("blue"));
declareCategory ("General Input");
declareBool ("cycle", "Cyclic next/previous", false).
setTooltip ("When using next/previous functions at the last/first item of a "
"list go to the first/last item");
declareCategory ("3D Scene Input");
EnumValue left ("Left Mouse-Button");
EnumValue cLeft ("Ctrl-Left Mouse-Button");
EnumValue right ("Right Mouse-Button");
EnumValue cRight ("Ctrl-Right Mouse-Button");
EnumValue middle ("Middle Mouse-Button");
EnumValue cMiddle ("Ctrl-Middle Mouse-Button");
EnumValues inputButtons;
inputButtons.add (left).add (cLeft).add (right).add (cRight).add (middle).add (cMiddle);
declareEnum ("p-navi", "Primary Camera Navigation Button", left).addValues (inputButtons);
declareEnum ("s-navi", "Secondary Camera Navigation Button", cLeft).addValues (inputButtons);
declareEnum ("p-edit", "Primary Editing Button", right).addValues (inputButtons);
declareEnum ("s-edit", "Secondary Editing Button", cRight).addValues (inputButtons);
declareEnum ("p-select", "Primary Selection Button", middle).addValues (inputButtons);
declareEnum ("s-select", "Secondary Selection Button", cMiddle).addValues (inputButtons);
declareSeparator();
declareBool ("context-select", "Context Sensitive Selection", false);
declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0).
setRange (0.001, 100.0);
declareDouble ("drag-wheel-factor", "Mouse wheel sensitivity during drag operations", 1.0).
setRange (0.001, 100.0);
declareDouble ("drag-shift-factor",
"Shift-acceleration factor during drag operations", 4.0).
setTooltip ("Acceleration factor during drag operations while holding down shift").
setRange (0.001, 100.0);
declareCategory ("Tooltips");
declareBool ("scene", "Show Tooltips in 3D scenes", true);
declareBool ("scene-hide-basic", "Hide basic 3D scenes tooltips", false);
declareInt ("scene-delay", "Tooltip delay in milliseconds", 500).
setMin (1);
}
void CSMPrefs::State::declareCategory (const std::string& key)
{
std::map<std::string, Category>::iterator iter = mCategories.find (key);
if (iter!=mCategories.end())
{
mCurrentCategory = iter;
}
else
{
mCurrentCategory =
mCategories.insert (std::make_pair (key, Category (this, key))).first;
}
}
CSMPrefs::IntSetting& CSMPrefs::State::declareInt (const std::string& key,
const std::string& label, int default_)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
std::ostringstream stream;
stream << default_;
setDefault (key, stream.str());
default_ = mSettings.getInt (key, mCurrentCategory->second.getKey());
CSMPrefs::IntSetting *setting =
new CSMPrefs::IntSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting);
return *setting;
}
CSMPrefs::DoubleSetting& CSMPrefs::State::declareDouble (const std::string& key,
const std::string& label, double default_)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
std::ostringstream stream;
stream << default_;
setDefault (key, stream.str());
default_ = mSettings.getFloat (key, mCurrentCategory->second.getKey());
CSMPrefs::DoubleSetting *setting =
new CSMPrefs::DoubleSetting (&mCurrentCategory->second, &mSettings, &mMutex,
key, label, default_);
mCurrentCategory->second.addSetting (setting);
return *setting;
}
CSMPrefs::BoolSetting& CSMPrefs::State::declareBool (const std::string& key,
const std::string& label, bool default_)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
setDefault (key, default_ ? "true" : "false");
default_ = mSettings.getBool (key, mCurrentCategory->second.getKey());
CSMPrefs::BoolSetting *setting =
new CSMPrefs::BoolSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting);
return *setting;
}
CSMPrefs::EnumSetting& CSMPrefs::State::declareEnum (const std::string& key,
const std::string& label, EnumValue default_)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
setDefault (key, default_.mValue);
default_.mValue = mSettings.getString (key, mCurrentCategory->second.getKey());
CSMPrefs::EnumSetting *setting =
new CSMPrefs::EnumSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting);
return *setting;
}
CSMPrefs::ColourSetting& CSMPrefs::State::declareColour (const std::string& key,
const std::string& label, QColor default_)
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
setDefault (key, default_.name().toUtf8().data());
default_.setNamedColor (QString::fromUtf8 (mSettings.getString (key, mCurrentCategory->second.getKey()).c_str()));
CSMPrefs::ColourSetting *setting =
new CSMPrefs::ColourSetting (&mCurrentCategory->second, &mSettings, &mMutex, key, label,
default_);
mCurrentCategory->second.addSetting (setting);
return *setting;
}
void CSMPrefs::State::declareSeparator()
{
if (mCurrentCategory==mCategories.end())
throw std::logic_error ("no category for setting");
CSMPrefs::Setting *setting =
new CSMPrefs::Setting (&mCurrentCategory->second, &mSettings, &mMutex, "", "");
mCurrentCategory->second.addSetting (setting);
}
void CSMPrefs::State::setDefault (const std::string& key, const std::string& default_)
{
Settings::CategorySetting fullKey (mCurrentCategory->second.getKey(), key);
Settings::CategorySettingValueMap::iterator iter =
mSettings.mDefaultSettings.find (fullKey);
if (iter==mSettings.mDefaultSettings.end())
mSettings.mDefaultSettings.insert (std::make_pair (fullKey, default_));
}
CSMPrefs::State::State (const Files::ConfigurationManager& configurationManager)
: mConfigFile ("openmw-cs.cfg"), mConfigurationManager (configurationManager),
mCurrentCategory (mCategories.end())
{
if (sThis)
throw std::logic_error ("An instance of CSMPRefs::State already exists");
load();
declare();
sThis = this;
}
CSMPrefs::State::~State()
{
sThis = 0;
}
void CSMPrefs::State::save()
{
boost::filesystem::path user = mConfigurationManager.getUserConfigPath() / mConfigFile;
mSettings.saveUser (user.string());
}
CSMPrefs::State::Iterator CSMPrefs::State::begin()
{
return mCategories.begin();
}
CSMPrefs::State::Iterator CSMPrefs::State::end()
{
return mCategories.end();
}
CSMPrefs::Category& CSMPrefs::State::operator[] (const std::string& key)
{
Iterator iter = mCategories.find (key);
if (iter==mCategories.end())
throw std::logic_error ("Invalid user settings category: " + key);
return iter->second;
}
void CSMPrefs::State::update (const Setting& setting)
{
emit (settingChanged (&setting));
}
CSMPrefs::State& CSMPrefs::State::get()
{
if (!sThis)
throw std::logic_error ("No instance of CSMPrefs::State");
return *sThis;
}
CSMPrefs::State& CSMPrefs::get()
{
return State::get();
}

@ -0,0 +1,105 @@
#ifndef CSV_PREFS_STATE_H
#define CSM_PREFS_STATE_H
#include <map>
#include <string>
#include <QObject>
#include <QMutex>
#ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp>
#endif
#include <components/settings/settings.hpp>
#include "category.hpp"
#include "setting.hpp"
#include "enumsetting.hpp"
class QColor;
namespace CSMPrefs
{
class IntSetting;
class DoubleSetting;
class BoolSetting;
class ColourSetting;
/// \brief User settings state
///
/// \note Access to the user settings is thread-safe once all declarations and loading has
/// been completed.
class State : public QObject
{
Q_OBJECT
static State *sThis;
public:
typedef std::map<std::string, Category> Collection;
typedef Collection::iterator Iterator;
private:
const std::string mConfigFile;
const Files::ConfigurationManager& mConfigurationManager;
Settings::Manager mSettings;
Collection mCategories;
Iterator mCurrentCategory;
QMutex mMutex;
// not implemented
State (const State&);
State& operator= (const State&);
private:
void load();
void declare();
void declareCategory (const std::string& key);
IntSetting& declareInt (const std::string& key, const std::string& label, int default_);
DoubleSetting& declareDouble (const std::string& key, const std::string& label, double default_);
BoolSetting& declareBool (const std::string& key, const std::string& label, bool default_);
EnumSetting& declareEnum (const std::string& key, const std::string& label, EnumValue default_);
ColourSetting& declareColour (const std::string& key, const std::string& label, QColor default_);
void declareSeparator();
void setDefault (const std::string& key, const std::string& default_);
public:
State (const Files::ConfigurationManager& configurationManager);
~State();
void save();
Iterator begin();
Iterator end();
Category& operator[](const std::string& key);
void update (const Setting& setting);
static State& get();
signals:
void settingChanged (const CSMPrefs::Setting *setting);
};
// convenience function
State& get();
}
#endif

@ -1,128 +0,0 @@
#include "connector.hpp"
#include "../../view/settings/view.hpp"
#include "../../view/settings/page.hpp"
CSMSettings::Connector::Connector(CSVSettings::View *master,
QObject *parent)
: QObject(parent), mMasterView (master)
{}
void CSMSettings::Connector::addSlaveView (CSVSettings::View *view,
QList <QStringList> &masterProxyValues)
{
mSlaveViews.append (view);
mProxyListMap[view->viewKey()].append (masterProxyValues);
}
QList <QStringList> CSMSettings::Connector::getSlaveViewValues() const
{
QList <QStringList> list;
foreach (const CSVSettings::View *view, mSlaveViews)
list.append (view->selectedValues());
return list;
}
bool CSMSettings::Connector::proxyListsMatch (
const QList <QStringList> &list1,
const QList <QStringList> &list2) const
{
bool success = true;
for (int i = 0; i < list1.size(); i++)
{
success = stringListsMatch (list1.at(i), list2.at(i));
if (!success)
break;
}
return success;
}
void CSMSettings::Connector::slotUpdateMaster() const
{
//list of the current values for each slave.
QList <QStringList> slaveValueList = getSlaveViewValues();
int masterColumn = -1;
/*
* A row in the master view is one of the values in the
* master view's data model. This corresponds directly to the number of
* values in a proxy list contained in the ProxyListMap member.
* Thus, we iterate each "column" in the master proxy list
* (one for each vlaue in the master. Each column represents
* one master value's corresponding list of slave values. We examine
* each master value's list, comparing it to the current slave value list,
* stopping when we find a match using proxyListsMatch().
*
* If no match is found, clear the master view's value
*/
for (int i = 0; i < mMasterView->rowCount(); i++)
{
QList <QStringList> proxyValueList;
foreach (const QString &settingKey, mProxyListMap.keys())
{
// append the proxy value list stored in the i'th column
// for each setting key. A setting key is the id of the setting
// in page.name format.
proxyValueList.append (mProxyListMap.value(settingKey).at(i));
}
if (proxyListsMatch (slaveValueList, proxyValueList))
{
masterColumn = i;
break;
}
}
QString masterValue = mMasterView->value (masterColumn);
mMasterView->setSelectedValue (masterValue);
}
void CSMSettings::Connector::slotUpdateSlaves() const
{
int row = mMasterView->currentIndex();
if (row == -1)
return;
//iterate the proxy lists for the chosen master index
//and pass the list to each slave for updating
for (int i = 0; i < mSlaveViews.size(); i++)
{
QList <QStringList> proxyList =
mProxyListMap.value(mSlaveViews.at(i)->viewKey());
mSlaveViews.at(i)->setSelectedValues (proxyList.at(row));
}
}
bool CSMSettings::Connector::stringListsMatch (
const QStringList &list1,
const QStringList &list2) const
{
//returns a "sloppy" match, verifying that each list contains all the same
//items, though not necessarily in the same order.
if (list1.size() != list2.size())
return false;
QStringList tempList(list2);
//iterate each value in the list, removing one occurrence of the value in
//the other list. If no corresponding value is found, test fails
foreach (const QString &value, list1)
{
if (!tempList.contains(value))
return false;
tempList.removeOne(value);
}
return true;
}

@ -1,67 +0,0 @@
#ifndef CSMSETTINGS_CONNECTOR_HPP
#define CSMSETTINGS_CONNECTOR_HPP
#include <QObject>
#include <QList>
#include <QMap>
#include <QStringList>
#include "support.hpp"
namespace CSVSettings {
class View;
}
namespace CSMSettings {
class Connector : public QObject
{
Q_OBJECT
CSVSettings::View *mMasterView;
///map using the view pointer as a key to it's index value
QList <CSVSettings::View *> mSlaveViews;
///list of proxy values for each master value.
///value list order is indexed to the master value index.
QMap < QString, QList <QStringList> > mProxyListMap;
public:
explicit Connector(CSVSettings::View *master,
QObject *parent = 0);
///Set the view which acts as a proxy for other setting views
void setMasterView (CSVSettings::View *view);
///Add a view to be updated / update to the master
void addSlaveView (CSVSettings::View *view,
QList <QStringList> &masterProxyValues);
private:
///loosely matches lists of proxy values across registered slaves
///against a proxy value list for a given master value
bool proxyListsMatch (const QList <QStringList> &list1,
const QList <QStringList> &list2) const;
///loosely matches two string lists
bool stringListsMatch (const QStringList &list1,
const QStringList &list2) const;
///retrieves current values of registered slave views
QList <QStringList> getSlaveViewValues() const;
public slots:
///updates slave views with proxy values associated with current
///master value
void slotUpdateSlaves() const;
///updates master value associated with the currently selected
///slave values, if applicable.
void slotUpdateMaster() const;
};
}
#endif // CSMSETTINGS_CONNECTOR_HPP

@ -1,414 +0,0 @@
#include "setting.hpp"
#include "support.hpp"
CSMSettings::Setting::Setting(SettingType typ, const QString &settingName,
const QString &pageName, const QString& label)
: mIsEditorSetting (true)
{
buildDefaultSetting();
int settingType = static_cast <int> (typ);
//even-numbered setting types are multi-valued
if ((settingType % 2) == 0)
setProperty (Property_IsMultiValue, QVariant(true).toString());
//view type is related to setting type by an order of magnitude
setProperty (Property_SettingType, QVariant (settingType).toString());
setProperty (Property_Page, pageName);
setProperty (Property_Name, settingName);
setProperty (Property_Label, label.isEmpty() ? settingName : label);
}
void CSMSettings::Setting::buildDefaultSetting()
{
int arrLen = sizeof(sPropertyDefaults) / sizeof (*sPropertyDefaults);
for (int i = 0; i < arrLen; i++)
{
QStringList propertyList;
if (i <Property_DefaultValues)
propertyList.append (sPropertyDefaults[i]);
mProperties.append (propertyList);
}
}
void CSMSettings::Setting::addProxy (const Setting *setting,
const QStringList &vals)
{
if (serializable())
setSerializable (false);
QList <QStringList> list;
foreach (const QString &val, vals)
list << (QStringList() << val);
mProxies [setting->page() + '/' + setting->name()] = list;
}
void CSMSettings::Setting::addProxy (const Setting *setting,
const QList <QStringList> &list)
{
if (serializable())
setProperty (Property_Serializable, false);
mProxies [setting->page() + '/' + setting->name()] = list;
}
void CSMSettings::Setting::setColumnSpan (int value)
{
setProperty (Property_ColumnSpan, value);
}
int CSMSettings::Setting::columnSpan() const
{
return property (Property_ColumnSpan).at(0).toInt();
}
void CSMSettings::Setting::setDeclaredValues (QStringList list)
{
setProperty (Property_DeclaredValues, list);
}
QStringList CSMSettings::Setting::declaredValues() const
{
return property (Property_DeclaredValues);
}
QStringList CSMSettings::Setting::property (SettingProperty prop) const
{
if (prop >= mProperties.size())
return QStringList();
return mProperties.at(prop);
}
void CSMSettings::Setting::setDefaultValue (int value)
{
setDefaultValues (QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setDefaultValue (double value)
{
setDefaultValues (QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setDefaultValue (const QString &value)
{
setDefaultValues (QStringList() << value);
}
void CSMSettings::Setting::setDefaultValues (const QStringList &values)
{
setProperty (Property_DefaultValues, values);
}
QStringList CSMSettings::Setting::defaultValues() const
{
return property (Property_DefaultValues);
}
void CSMSettings::Setting::setDelimiter (const QString &value)
{
setProperty (Property_Delimiter, value);
}
QString CSMSettings::Setting::delimiter() const
{
return property (Property_Delimiter).at(0);
}
void CSMSettings::Setting::setEditorSetting(bool state)
{
mIsEditorSetting = true;
}
bool CSMSettings::Setting::isEditorSetting() const
{
return mIsEditorSetting;
}
void CSMSettings::Setting::setIsMultiLine (bool state)
{
setProperty (Property_IsMultiLine, state);
}
bool CSMSettings::Setting::isMultiLine() const
{
return (property (Property_IsMultiLine).at(0) == "true");
}
void CSMSettings::Setting::setIsMultiValue (bool state)
{
setProperty (Property_IsMultiValue, state);
}
bool CSMSettings::Setting::isMultiValue() const
{
return (property (Property_IsMultiValue).at(0) == "true");
}
const CSMSettings::ProxyValueMap &CSMSettings::Setting::proxyLists() const
{
return mProxies;
}
void CSMSettings::Setting::setSerializable (bool state)
{
setProperty (Property_Serializable, state);
}
bool CSMSettings::Setting::serializable() const
{
return (property (Property_Serializable).at(0) == "true");
}
void CSMSettings::Setting::setSpecialValueText(const QString &text)
{
setProperty (Property_SpecialValueText, text);
}
QString CSMSettings::Setting::specialValueText() const
{
return property (Property_SpecialValueText).at(0);
}
void CSMSettings::Setting::setName (const QString &value)
{
setProperty (Property_Name, value);
}
QString CSMSettings::Setting::name() const
{
return property (Property_Name).at(0);
}
void CSMSettings::Setting::setPage (const QString &value)
{
setProperty (Property_Page, value);
}
QString CSMSettings::Setting::page() const
{
return property (Property_Page).at(0);
}
void CSMSettings::Setting::setStyleSheet (const QString &value)
{
setProperty (Property_StyleSheet, value);
}
QString CSMSettings::Setting::styleSheet() const
{
return property (Property_StyleSheet).at(0);
}
void CSMSettings::Setting::setPrefix (const QString &value)
{
setProperty (Property_Prefix, value);
}
QString CSMSettings::Setting::prefix() const
{
return property (Property_Prefix).at(0);
}
void CSMSettings::Setting::setRowSpan (const int value)
{
setProperty (Property_RowSpan, value);
}
int CSMSettings::Setting::rowSpan () const
{
return property (Property_RowSpan).at(0).toInt();
}
void CSMSettings::Setting::setSingleStep (int value)
{
setProperty (Property_SingleStep, value);
}
void CSMSettings::Setting::setSingleStep (double value)
{
setProperty (Property_SingleStep, value);
}
QString CSMSettings::Setting::singleStep() const
{
return property (Property_SingleStep).at(0);
}
void CSMSettings::Setting::setSuffix (const QString &value)
{
setProperty (Property_Suffix, value);
}
QString CSMSettings::Setting::suffix() const
{
return property (Property_Suffix).at(0);
}
void CSMSettings::Setting::setTickInterval (int value)
{
setProperty (Property_TickInterval, value);
}
int CSMSettings::Setting::tickInterval () const
{
return property (Property_TickInterval).at(0).toInt();
}
void CSMSettings::Setting::setTicksAbove (bool state)
{
setProperty (Property_TicksAbove, state);
}
bool CSMSettings::Setting::ticksAbove() const
{
return (property (Property_TicksAbove).at(0) == "true");
}
void CSMSettings::Setting::setTicksBelow (bool state)
{
setProperty (Property_TicksBelow, state);
}
bool CSMSettings::Setting::ticksBelow() const
{
return (property (Property_TicksBelow).at(0) == "true");
}
void CSMSettings::Setting::setType (int settingType)
{
setProperty (Property_SettingType, settingType);
}
CSMSettings::SettingType CSMSettings::Setting::type() const
{
return static_cast <CSMSettings::SettingType> ( property (
Property_SettingType).at(0).toInt());
}
void CSMSettings::Setting::setRange (int min, int max)
{
setProperty (Property_Minimum, min);
setProperty (Property_Maximum, max);
}
void CSMSettings::Setting::setRange (double min, double max)
{
setProperty (Property_Minimum, min);
setProperty (Property_Maximum, max);
}
QString CSMSettings::Setting::maximum() const
{
return property (Property_Maximum).at(0);
}
QString CSMSettings::Setting::minimum() const
{
return property (Property_Minimum).at(0);
}
CSVSettings::ViewType CSMSettings::Setting::viewType() const
{
return static_cast <CSVSettings::ViewType> ( property (
Property_SettingType).at(0).toInt() / 10);
}
void CSMSettings::Setting::setViewColumn (int value)
{
setProperty (Property_ViewColumn, value);
}
int CSMSettings::Setting::viewColumn() const
{
return property (Property_ViewColumn).at(0).toInt();
}
void CSMSettings::Setting::setViewLocation (int row, int column)
{
setViewRow (row);
setViewColumn (column);
}
void CSMSettings::Setting::setViewRow (int value)
{
setProperty (Property_ViewRow, value);
}
int CSMSettings::Setting::viewRow() const
{
return property (Property_ViewRow).at(0).toInt();
}
void CSMSettings::Setting::setWidgetWidth (int value)
{
setProperty (Property_WidgetWidth, value);
}
int CSMSettings::Setting::widgetWidth() const
{
return property (Property_WidgetWidth).at(0).toInt();
}
void CSMSettings::Setting::setWrapping (bool state)
{
setProperty (Property_Wrapping, state);
}
bool CSMSettings::Setting::wrapping() const
{
return (property (Property_Wrapping).at(0) == "true");
}
void CSMSettings::Setting::setLabel (const QString& label)
{
setProperty (Property_Label, label);
}
QString CSMSettings::Setting::getLabel() const
{
return property (Property_Label).at (0);
}
void CSMSettings::Setting::setToolTip (const QString& toolTip)
{
setProperty (Property_ToolTip, toolTip);
}
QString CSMSettings::Setting::getToolTip() const
{
return property (Property_ToolTip).at (0);
}
void CSMSettings::Setting::setProperty (SettingProperty prop, bool value)
{
setProperty (prop, QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setProperty (SettingProperty prop, int value)
{
setProperty (prop, QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setProperty (SettingProperty prop, double value)
{
setProperty (prop, QStringList() << QVariant (value).toString());
}
void CSMSettings::Setting::setProperty (SettingProperty prop,
const QString &value)
{
setProperty (prop, QStringList() << value);
}
void CSMSettings::Setting::setProperty (SettingProperty prop,
const QStringList &value)
{
if (prop < mProperties.size())
mProperties.replace (prop, value);
}

@ -1,159 +0,0 @@
#ifndef CSMSETTINGS_SETTING_HPP
#define CSMSETTINGS_SETTING_HPP
#include <QStringList>
#include <QMap>
#include "support.hpp"
namespace CSMSettings
{
//QString is the setting id in the form of "page/name"
//QList is a list of stringlists of proxy values.
//Order is important! Proxy stringlists are matched against
//master values by their position in the QList.
typedef QMap <QString, QList <QStringList> > ProxyValueMap;
///Setting class is the interface for the User Settings. It contains
///a great deal of boiler plate to provide the core API functions, as
///well as the property() functions which use enumeration to be iterable.
///This makes the Setting class capable of being manipulated by script.
///See CSMSettings::support.hpp for enumerations / string values.
class Setting
{
QList <QStringList> mProperties;
QStringList mDefaults;
bool mIsEditorSetting;
ProxyValueMap mProxies;
public:
Setting(SettingType typ, const QString &settingName,
const QString &pageName, const QString& label = "");
void addProxy (const Setting *setting, const QStringList &vals);
void addProxy (const Setting *setting, const QList <QStringList> &list);
const QList <QStringList> &properties() const { return mProperties; }
const ProxyValueMap &proxies() const { return mProxies; }
void setColumnSpan (int value);
int columnSpan() const;
void setDeclaredValues (QStringList list);
QStringList declaredValues() const;
void setDefaultValue (int value);
void setDefaultValue (double value);
void setDefaultValue (const QString &value);
void setDefaultValues (const QStringList &values);
QStringList defaultValues() const;
void setDelimiter (const QString &value);
QString delimiter() const;
void setEditorSetting (bool state);
bool isEditorSetting() const;
void setIsMultiLine (bool state);
bool isMultiLine() const;
void setIsMultiValue (bool state);
bool isMultiValue() const;
void setMask (const QString &value);
QString mask() const;
void setRange (int min, int max);
void setRange (double min, double max);
QString maximum() const;
QString minimum() const;
void setName (const QString &value);
QString name() const;
void setPage (const QString &value);
QString page() const;
void setStyleSheet (const QString &value);
QString styleSheet() const;
void setPrefix (const QString &value);
QString prefix() const;
void setRowSpan (const int value);
int rowSpan() const;
const ProxyValueMap &proxyLists() const;
void setSerializable (bool state);
bool serializable() const;
void setSpecialValueText (const QString &text);
QString specialValueText() const;
void setSingleStep (int value);
void setSingleStep (double value);
QString singleStep() const;
void setSuffix (const QString &value);
QString suffix() const;
void setTickInterval (int value);
int tickInterval() const;
void setTicksAbove (bool state);
bool ticksAbove() const;
void setTicksBelow (bool state);
bool ticksBelow() const;
void setViewColumn (int value);
int viewColumn() const;
void setViewLocation (int row = -1, int column = -1);
void setViewRow (int value);
int viewRow() const;
void setType (int settingType);
CSMSettings::SettingType type() const;
CSVSettings::ViewType viewType() const;
void setWrapping (bool state);
bool wrapping() const;
void setWidgetWidth (int value);
int widgetWidth() const;
/// This is the text the user gets to see.
void setLabel (const QString& label);
QString getLabel() const;
void setToolTip (const QString& toolTip);
QString getToolTip() const;
///returns the specified property value
QStringList property (SettingProperty prop) const;
///boilerplate code to convert setting values of common types
void setProperty (SettingProperty prop, bool value);
void setProperty (SettingProperty prop, int value);
void setProperty (SettingProperty prop, double value);
void setProperty (SettingProperty prop, const QString &value);
void setProperty (SettingProperty prop, const QStringList &value);
void addProxy (Setting* setting,
QMap <QString, QStringList> &proxyMap);
protected:
void buildDefaultSetting();
};
}
#endif // CSMSETTINGS_SETTING_HPP

@ -1,149 +0,0 @@
#ifndef SETTING_SUPPORT_HPP
#define SETTING_SUPPORT_HPP
#include <Qt>
#include <QPair>
#include <QList>
#include <QVariant>
#include <QStringList>
//Enums
namespace CSMSettings
{
///Enumerated properties for scripting
enum SettingProperty
{
Property_Name = 0,
Property_Page = 1,
Property_SettingType = 2,
Property_IsMultiValue = 3,
Property_IsMultiLine = 4,
Property_WidgetWidth = 5,
Property_ViewRow = 6,
Property_ViewColumn = 7,
Property_Delimiter = 8,
Property_Serializable = 9,
Property_ColumnSpan = 10,
Property_RowSpan = 11,
Property_Minimum = 12,
Property_Maximum = 13,
Property_SpecialValueText = 14,
Property_Prefix = 15,
Property_Suffix = 16,
Property_SingleStep = 17,
Property_Wrapping = 18,
Property_TickInterval = 19,
Property_TicksAbove = 20,
Property_TicksBelow = 21,
Property_StyleSheet = 22,
Property_Label = 23,
Property_ToolTip = 24,
//Stringlists should always be the last items
Property_DefaultValues = 25,
Property_DeclaredValues = 26,
Property_DefinedValues = 27,
Property_Proxies = 28
};
///Basic setting widget types.
enum SettingType
{
/*
* 0 - 9 - Boolean widgets
* 10-19 - List widgets
* 21-29 - Range widgets
* 31-39 - Text widgets
*
* Each range corresponds to a View_Type enum by a factor of 10.
*
* Even-numbered values are single-value widgets
* Odd-numbered values are multi-valued widgets
*/
Type_CheckBox = 0,
Type_RadioButton = 1,
Type_ListView = 10,
Type_ComboBox = 11,
Type_SpinBox = 21,
Type_DoubleSpinBox = 23,
Type_Slider = 25,
Type_Dial = 27,
Type_TextArea = 30,
Type_LineEdit = 31,
Type_Undefined = 40
};
}
namespace CSVSettings
{
///Categorical view types which encompass the setting widget types
enum ViewType
{
ViewType_Boolean = 0,
ViewType_List = 1,
ViewType_Range = 2,
ViewType_Text = 3,
ViewType_Undefined = 4
};
}
namespace CSMSettings
{
///used to construct default settings in the Setting class
struct PropertyDefaultValues
{
int id;
QString name;
QVariant value;
};
///strings which correspond to setting values. These strings represent
///the script language keywords which would be used to declare setting
///views for 3rd party addons
const QString sPropertyNames[] =
{
"name", "page", "setting_type", "is_multi_value",
"is_multi_line", "widget_width", "view_row", "view_column", "delimiter",
"is_serializable","column_span", "row_span", "minimum", "maximum",
"special_value_text", "prefix", "suffix", "single_step", "wrapping",
"tick_interval", "ticks_above", "ticks_below", "stylesheet",
"defaults", "declarations", "definitions", "proxies"
};
///Default values for a setting. Used in setting creation.
const QString sPropertyDefaults[] =
{
"", //name
"", //page
"40", //setting type
"false", //multivalue
"false", //multiline
"7", //widget width
"-1", //view row
"-1", //view column
",", //delimiter
"true", //serialized
"1", //column span
"1", //row span
"0", //value range
"0", //value minimum
"0", //value maximum
"", //special text
"", //prefix
"", //suffix
"false", //wrapping
"1", //tick interval
"false", //ticks above
"true", //ticks below
"", //StyleSheet
"", //default values
"", //declared values
"", //defined values
"" //proxy values
};
}
#endif // VIEW_SUPPORT_HPP

@ -1,824 +0,0 @@
#include "usersettings.hpp"
#include <QSettings>
#include <QFile>
#include <components/files/configurationmanager.hpp>
#include <components/settings/settings.hpp>
#include <boost/version.hpp>
#include "setting.hpp"
#include "support.hpp"
#include <QTextCodec>
#include <QDebug>
/**
* Workaround for problems with whitespaces in paths in older versions of Boost library
*/
#if (BOOST_VERSION <= 104600)
namespace boost
{
template<>
inline boost::filesystem::path lexical_cast<boost::filesystem::path, std::string>(const std::string& arg)
{
return boost::filesystem::path(arg);
}
} /* namespace boost */
#endif /* (BOOST_VERSION <= 104600) */
CSMSettings::UserSettings *CSMSettings::UserSettings::sUserSettingsInstance = 0;
CSMSettings::UserSettings::UserSettings (const Files::ConfigurationManager& configurationManager)
: mCfgMgr (configurationManager)
, mSettingDefinitions(NULL)
{
assert(!sUserSettingsInstance);
sUserSettingsInstance = this;
buildSettingModelDefaults();
}
void CSMSettings::UserSettings::buildSettingModelDefaults()
{
/*
declareSection ("3d-render", "3D Rendering");
{
Setting *farClipDist = createSetting (Type_DoubleSpinBox, "far-clip-distance", "Far clipping distance");
farClipDist->setDefaultValue (300000);
farClipDist->setRange (0, 1000000);
farClipDist->setToolTip ("The maximum distance objects are still rendered at.");
QString defaultValue = "None";
Setting *antialiasing = createSetting (Type_ComboBox, "antialiasing", "Antialiasing");
antialiasing->setDeclaredValues (QStringList()
<< defaultValue << "MSAA 2" << "MSAA 4" << "MSAA 8" << "MSAA 16");
antialiasing->setDefaultValue (defaultValue);
}
*/
/*
declareSection ("scene-input", "Scene Input");
{
Setting *fastFactor = createSetting (Type_SpinBox, "fast-factor",
"Fast movement factor");
fastFactor->setDefaultValue (4);
fastFactor->setRange (1, 100);
fastFactor->setToolTip (
"Factor by which movement is speed up while the shift key is held down.");
}
*/
declareSection ("window", "Window");
{
Setting *preDefined = createSetting (Type_ComboBox, "pre-defined",
"Default window size");
preDefined->setEditorSetting (false);
preDefined->setDeclaredValues (
QStringList() << "640 x 480" << "800 x 600" << "1024 x 768" << "1440 x 900");
preDefined->setViewLocation (1, 1);
preDefined->setColumnSpan (2);
preDefined->setToolTip ("Newly opened top-level windows will open with this size "
"(picked from a list of pre-defined values)");
Setting *width = createSetting (Type_LineEdit, "default-width",
"Default window width");
width->setDefaultValues (QStringList() << "1024");
width->setViewLocation (2, 1);
width->setColumnSpan (1);
width->setToolTip ("Newly opened top-level windows will open with this width.");
preDefined->addProxy (width, QStringList() << "640" << "800" << "1024" << "1440");
Setting *height = createSetting (Type_LineEdit, "default-height",
"Default window height");
height->setDefaultValues (QStringList() << "768");
height->setViewLocation (2, 2);
height->setColumnSpan (1);
height->setToolTip ("Newly opened top-level windows will open with this height.");
preDefined->addProxy (height, QStringList() << "480" << "600" << "768" << "900");
Setting *reuse = createSetting (Type_CheckBox, "reuse", "Reuse Subviews");
reuse->setDefaultValue ("true");
reuse->setToolTip ("When a new subview is requested and a matching subview already "
" exist, do not open a new subview and use the existing one instead.");
Setting *statusBar = createSetting (Type_CheckBox, "show-statusbar", "Show Status Bar");
statusBar->setDefaultValue ("true");
statusBar->setToolTip ("If a newly open top level window is showing status bars or not. "
" Note that this does not affect existing windows.");
Setting *maxSubView = createSetting (Type_SpinBox, "max-subviews",
"Maximum number of subviews per top-level window");
maxSubView->setDefaultValue (256);
maxSubView->setRange (1, 256);
maxSubView->setToolTip ("If the maximum number is reached and a new subview is opened "
"it will be placed into a new top-level window.");
Setting *hide = createSetting (Type_CheckBox, "hide-subview", "Hide single subview");
hide->setDefaultValue ("false");
hide->setToolTip ("When a view contains only a single subview, hide the subview title "
"bar and if this subview is closed also close the view (unless it is the last "
"view for this document)");
Setting *minWidth = createSetting (Type_SpinBox, "minimum-width",
"Minimum subview width");
minWidth->setDefaultValue (325);
minWidth->setRange (50, 10000);
minWidth->setToolTip ("Minimum width of subviews.");
QString defaultScroll = "Scrollbar Only";
QStringList scrollValues = QStringList() << defaultScroll << "Grow Only" << "Grow then Scroll";
Setting *mainwinScroll = createSetting (Type_RadioButton, "mainwindow-scrollbar",
"Add a horizontal scrollbar to the main view window.");
mainwinScroll->setDefaultValue (defaultScroll);
mainwinScroll->setDeclaredValues (scrollValues);
mainwinScroll->setToolTip ("Scrollbar Only: Simple addition of scrollbars, the view window does not grow"
" automatically.\n"
"Grow Only: Original Editor behaviour. The view window grows as subviews are added. No scrollbars.\n"
"Grow then Scroll: The view window grows. The scrollbar appears once it cannot grow any further.");
Setting *grow = createSetting (Type_CheckBox, "grow-limit", "Grow Limit Screen");
grow->setDefaultValue ("false");
grow->setToolTip ("When \"Grow then Scroll\" option is selected, the window size grows to"
" the width of the virtual desktop. \nIf this option is selected the the window growth"
"is limited to the current screen.");
}
declareSection ("records", "Records");
{
QString defaultValue = "Icon and Text";
QStringList values = QStringList() << defaultValue << "Icon Only" << "Text Only";
Setting *rsd = createSetting (Type_RadioButton, "status-format",
"Modification status display format");
rsd->setDefaultValue (defaultValue);
rsd->setDeclaredValues (values);
Setting *ritd = createSetting (Type_RadioButton, "type-format",
"ID type display format");
ritd->setDefaultValue (defaultValue);
ritd->setDeclaredValues (values);
}
declareSection ("table-input", "ID Tables");
{
QString inPlaceEdit ("Edit in Place");
QString editRecord ("Edit Record");
QString view ("View");
QString editRecordAndClose ("Edit Record and Close");
QStringList values;
values
<< "None" << inPlaceEdit << editRecord << view << "Revert" << "Delete"
<< editRecordAndClose << "View and Close";
QString toolTip = "<ul>"
"<li>None</li>"
"<li>Edit in Place: Edit the clicked cell</li>"
"<li>Edit Record: Open a dialogue subview for the clicked record</li>"
"<li>View: Open a scene subview for the clicked record (not available everywhere)</li>"
"<li>Revert: Revert record</li>"
"<li>Delete: Delete recordy</li>"
"<li>Edit Record and Close: Open a dialogue subview for the clicked record and close the table subview</li>"
"<li>View And Close: Open a scene subview for the clicked record and close the table subview</li>"
"</ul>";
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
doubleClick->setDeclaredValues (values);
doubleClick->setDefaultValue (inPlaceEdit);
doubleClick->setToolTip ("Action on double click in table:<p>" + toolTip);
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
"Shift Double Click");
shiftDoubleClick->setDeclaredValues (values);
shiftDoubleClick->setDefaultValue (editRecord);
shiftDoubleClick->setToolTip ("Action on shift double click in table:<p>" + toolTip);
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
"Control Double Click");
ctrlDoubleClick->setDeclaredValues (values);
ctrlDoubleClick->setDefaultValue (view);
ctrlDoubleClick->setToolTip ("Action on control double click in table:<p>" + toolTip);
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
"Shift Control Double Click");
shiftCtrlDoubleClick->setDeclaredValues (values);
shiftCtrlDoubleClick->setDefaultValue (editRecordAndClose);
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in table:<p>" + toolTip);
QString defaultValue = "Jump and Select";
QStringList jumpValues = QStringList() << defaultValue << "Jump Only" << "No Jump";
Setting *jumpToAdded = createSetting (Type_RadioButton, "jump-to-added",
"Jump to the added or cloned record.");
jumpToAdded->setDefaultValue (defaultValue);
jumpToAdded->setDeclaredValues (jumpValues);
Setting *extendedConfig = createSetting (Type_CheckBox, "extended-config",
"Manually specify affected record types for an extended delete/revert");
extendedConfig->setDefaultValue("false");
extendedConfig->setToolTip("Delete and revert commands have an extended form that also affects "
"associated records.\n\n"
"If this option is enabled, types of affected records are selected "
"manually before a command execution.\nOtherwise, all associated "
"records are deleted/reverted immediately.");
}
declareSection ("dialogues", "ID Dialogues");
{
Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar");
toolbar->setDefaultValue ("true");
}
declareSection ("report-input", "Reports");
{
QString none ("None");
QString edit ("Edit");
QString remove ("Remove");
QString editAndRemove ("Edit And Remove");
QStringList values;
values << none << edit << remove << editAndRemove;
QString toolTip = "<ul>"
"<li>None</li>"
"<li>Edit: Open a table or dialogue suitable for addressing the listed report</li>"
"<li>Remove: Remove the report from the report table</li>"
"<li>Edit and Remove: Open a table or dialogue suitable for addressing the listed report, then remove the report from the report table</li>"
"</ul>";
Setting *doubleClick = createSetting (Type_ComboBox, "double", "Double Click");
doubleClick->setDeclaredValues (values);
doubleClick->setDefaultValue (edit);
doubleClick->setToolTip ("Action on double click in report table:<p>" + toolTip);
Setting *shiftDoubleClick = createSetting (Type_ComboBox, "double-s",
"Shift Double Click");
shiftDoubleClick->setDeclaredValues (values);
shiftDoubleClick->setDefaultValue (remove);
shiftDoubleClick->setToolTip ("Action on shift double click in report table:<p>" + toolTip);
Setting *ctrlDoubleClick = createSetting (Type_ComboBox, "double-c",
"Control Double Click");
ctrlDoubleClick->setDeclaredValues (values);
ctrlDoubleClick->setDefaultValue (editAndRemove);
ctrlDoubleClick->setToolTip ("Action on control double click in report table:<p>" + toolTip);
Setting *shiftCtrlDoubleClick = createSetting (Type_ComboBox, "double-sc",
"Shift Control Double Click");
shiftCtrlDoubleClick->setDeclaredValues (values);
shiftCtrlDoubleClick->setDefaultValue (none);
shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in report table:<p>" + toolTip);
}
declareSection ("search", "Search & Replace");
{
Setting *before = createSetting (Type_SpinBox, "char-before",
"Characters before search string");
before->setDefaultValue (10);
before->setRange (0, 1000);
before->setToolTip ("Maximum number of character to display in search result before the searched text");
Setting *after = createSetting (Type_SpinBox, "char-after",
"Characters after search string");
after->setDefaultValue (10);
after->setRange (0, 1000);
after->setToolTip ("Maximum number of character to display in search result after the searched text");
Setting *autoDelete = createSetting (Type_CheckBox, "auto-delete", "Delete row from result table after a successful replace");
autoDelete->setDefaultValue ("true");
}
declareSection ("script-editor", "Scripts");
{
Setting *lineNum = createSetting (Type_CheckBox, "show-linenum", "Show Line Numbers");
lineNum->setDefaultValue ("true");
lineNum->setToolTip ("Show line numbers to the left of the script editor window."
"The current row and column numbers of the text cursor are shown at the bottom.");
Setting *monoFont = createSetting (Type_CheckBox, "mono-font", "Use monospace font");
monoFont->setDefaultValue ("true");
monoFont->setToolTip ("Whether to use monospaced fonts on script edit subview.");
QString tooltip =
"\n#RGB (each of R, G, and B is a single hex digit)"
"\n#RRGGBB"
"\n#RRRGGGBBB"
"\n#RRRRGGGGBBBB"
"\nA name from the list of colors defined in the list of SVG color keyword names."
"\nX11 color names may also work.";
QString modeNormal ("Normal");
QStringList modes;
modes << "Ignore" << modeNormal << "Strict";
Setting *warnings = createSetting (Type_ComboBox, "warnings",
"Warning Mode");
warnings->setDeclaredValues (modes);
warnings->setDefaultValue (modeNormal);
warnings->setToolTip ("<ul>How to handle warning messages during compilation:<p>"
"<li>Ignore: Do not report warning</li>"
"<li>Normal: Report warning as a warning</li>"
"<li>Strict: Promote warning to an error</li>"
"</ul>");
Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar");
toolbar->setDefaultValue ("true");
Setting *delay = createSetting (Type_SpinBox, "compile-delay",
"Delay between updating of source errors");
delay->setDefaultValue (100);
delay->setRange (0, 10000);
delay->setToolTip ("Delay in milliseconds");
Setting *errorHeight = createSetting (Type_SpinBox, "error-height",
"Initial height of the error panel");
errorHeight->setDefaultValue (100);
errorHeight->setRange (100, 10000);
Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int");
formatInt->setDefaultValues (QStringList() << "Dark magenta");
formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
Setting *formatFloat = createSetting (Type_LineEdit, "colour-float", "Highlight Colour: Float");
formatFloat->setDefaultValues (QStringList() << "Magenta");
formatFloat->setToolTip ("(Default: Magenta) Use one of the following formats:" + tooltip);
Setting *formatName = createSetting (Type_LineEdit, "colour-name", "Highlight Colour: Name");
formatName->setDefaultValues (QStringList() << "Gray");
formatName->setToolTip ("(Default: Gray) Use one of the following formats:" + tooltip);
Setting *formatKeyword = createSetting (Type_LineEdit, "colour-keyword", "Highlight Colour: Keyword");
formatKeyword->setDefaultValues (QStringList() << "Red");
formatKeyword->setToolTip ("(Default: Red) Use one of the following formats:" + tooltip);
Setting *formatSpecial = createSetting (Type_LineEdit, "colour-special", "Highlight Colour: Special");
formatSpecial->setDefaultValues (QStringList() << "Dark yellow");
formatSpecial->setToolTip ("(Default: Dark yellow) Use one of the following formats:" + tooltip);
Setting *formatComment = createSetting (Type_LineEdit, "colour-comment", "Highlight Colour: Comment");
formatComment->setDefaultValues (QStringList() << "Green");
formatComment->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip);
Setting *formatId = createSetting (Type_LineEdit, "colour-id", "Highlight Colour: Id");
formatId->setDefaultValues (QStringList() << "Blue");
formatId->setToolTip ("(Default: Blue) Use one of the following formats:" + tooltip);
}
declareSection ("general-input", "General Input");
{
Setting *cycle = createSetting (Type_CheckBox, "cycle", "Cyclic next/previous");
cycle->setDefaultValue ("false");
cycle->setToolTip ("When using next/previous functions at the last/first item of a "
"list go to the first/last item");
}
declareSection ("scene-input", "3D Scene Input");
{
QString left ("Left Mouse-Button");
QString cLeft ("Ctrl-Left Mouse-Button");
QString right ("Right Mouse-Button");
QString cRight ("Ctrl-Right Mouse-Button");
QString middle ("Middle Mouse-Button");
QString cMiddle ("Ctrl-Middle Mouse-Button");
QStringList values;
values << left << cLeft << right << cRight << middle << cMiddle;
Setting *primaryNavigation = createSetting (Type_ComboBox, "p-navi", "Primary Camera Navigation Button");
primaryNavigation->setDeclaredValues (values);
primaryNavigation->setDefaultValue (left);
Setting *secondaryNavigation = createSetting (Type_ComboBox, "s-navi", "Secondary Camera Navigation Button");
secondaryNavigation->setDeclaredValues (values);
secondaryNavigation->setDefaultValue (cLeft);
Setting *primaryEditing = createSetting (Type_ComboBox, "p-edit", "Primary Editing Button");
primaryEditing->setDeclaredValues (values);
primaryEditing->setDefaultValue (right);
Setting *secondaryEditing = createSetting (Type_ComboBox, "s-edit", "Secondary Editing Button");
secondaryEditing->setDeclaredValues (values);
secondaryEditing->setDefaultValue (cRight);
Setting *primarySelection = createSetting (Type_ComboBox, "p-select", "Selection Button");
primarySelection->setDeclaredValues (values);
primarySelection->setDefaultValue (middle);
Setting *secondarySelection = createSetting (Type_ComboBox, "s-select", "Selection Button");
secondarySelection->setDeclaredValues (values);
secondarySelection->setDefaultValue (cMiddle);
Setting *contextSensitive = createSetting (Type_CheckBox, "context-select", "Context Sensitive Selection");
contextSensitive->setDefaultValue ("false");
Setting *dragMouseSensitivity = createSetting (Type_DoubleSpinBox, "drag-factor",
"Mouse sensitivity during drag operations");
dragMouseSensitivity->setDefaultValue (1.0);
dragMouseSensitivity->setRange (0.001, 100.0);
Setting *dragWheelSensitivity = createSetting (Type_DoubleSpinBox, "drag-wheel-factor",
"Mouse wheel sensitivity during drag operations");
dragWheelSensitivity->setDefaultValue (1.0);
dragWheelSensitivity->setRange (0.001, 100.0);
Setting *dragShiftFactor = createSetting (Type_DoubleSpinBox, "drag-shift-factor",
"Acceleration factor during drag operations while holding down shift");
dragShiftFactor->setDefaultValue (4.0);
dragShiftFactor->setRange (0.001, 100.0);
}
declareSection ("tooltips", "Tooltips");
{
Setting *scene = createSetting (Type_CheckBox, "scene", "Show Tooltips in 3D scenes");
scene->setDefaultValue ("true");
Setting *sceneHideBasic = createSetting (Type_CheckBox, "scene-hide-basic", "Hide basic 3D scenes tooltips");
sceneHideBasic->setDefaultValue ("false");
Setting *sceneDelay = createSetting (Type_SpinBox, "scene-delay",
"Tooltip delay in milliseconds");
sceneDelay->setDefaultValue (500);
sceneDelay->setRange (1, 10000);
}
{
/******************************************************************
* There are three types of values:
*
* Declared values
*
* Pre-determined values, typically for
* combobox drop downs and boolean (radiobutton / checkbox) labels.
* These values represent the total possible list of values that
* may define a setting. No other values are allowed.
*
* Defined values
*
* Values which represent the actual, current value of
* a setting. For settings with declared values, this must be one
* or several declared values, as appropriate.
*
* Proxy values
* Values the proxy master updates the proxy slave when
* it's own definition is set / changed. These are definitions for
* proxy slave settings, but must match any declared values the
* proxy slave has, if any.
*******************************************************************/
/*
//create setting objects, specifying the basic widget type,
//the page name, and the view name
Setting *masterBoolean = createSetting (Type_RadioButton, section,
"Master Proxy");
Setting *slaveBoolean = createSetting (Type_CheckBox, section,
"Proxy Checkboxes");
Setting *slaveSingleText = createSetting (Type_LineEdit, section,
"Proxy TextBox 1");
Setting *slaveMultiText = createSetting (Type_LineEdit, section,
"ProxyTextBox 2");
Setting *slaveAlphaSpinbox = createSetting (Type_SpinBox, section,
"Alpha Spinbox");
Setting *slaveIntegerSpinbox = createSetting (Type_SpinBox, section,
"Int Spinbox");
Setting *slaveDoubleSpinbox = createSetting (Type_DoubleSpinBox,
section, "Double Spinbox");
Setting *slaveSlider = createSetting (Type_Slider, section, "Slider");
Setting *slaveDial = createSetting (Type_Dial, section, "Dial");
//set declared values for selected views
masterBoolean->setDeclaredValues (QStringList()
<< "Profile One" << "Profile Two"
<< "Profile Three" << "Profile Four");
slaveBoolean->setDeclaredValues (QStringList()
<< "One" << "Two" << "Three" << "Four" << "Five");
slaveAlphaSpinbox->setDeclaredValues (QStringList()
<< "One" << "Two" << "Three" << "Four");
masterBoolean->addProxy (slaveBoolean, QList <QStringList>()
<< (QStringList() << "One" << "Three")
<< (QStringList() << "One" << "Three")
<< (QStringList() << "One" << "Three" << "Five")
<< (QStringList() << "Two" << "Four")
);
masterBoolean->addProxy (slaveSingleText, QList <QStringList>()
<< (QStringList() << "Text A")
<< (QStringList() << "Text B")
<< (QStringList() << "Text A")
<< (QStringList() << "Text C")
);
masterBoolean->addProxy (slaveMultiText, QList <QStringList>()
<< (QStringList() << "One" << "Three")
<< (QStringList() << "One" << "Three")
<< (QStringList() << "One" << "Three" << "Five")
<< (QStringList() << "Two" << "Four")
);
masterBoolean->addProxy (slaveAlphaSpinbox, QList <QStringList>()
<< (QStringList() << "Four")
<< (QStringList() << "Three")
<< (QStringList() << "Two")
<< (QStringList() << "One"));
masterBoolean->addProxy (slaveIntegerSpinbox, QList <QStringList> ()
<< (QStringList() << "0")
<< (QStringList() << "7")
<< (QStringList() << "14")
<< (QStringList() << "21"));
masterBoolean->addProxy (slaveDoubleSpinbox, QList <QStringList> ()
<< (QStringList() << "0.17")
<< (QStringList() << "0.34")
<< (QStringList() << "0.51")
<< (QStringList() << "0.68"));
masterBoolean->addProxy (slaveSlider, QList <QStringList> ()
<< (QStringList() << "25")
<< (QStringList() << "50")
<< (QStringList() << "75")
<< (QStringList() << "100")
);
masterBoolean->addProxy (slaveDial, QList <QStringList> ()
<< (QStringList() << "25")
<< (QStringList() << "50")
<< (QStringList() << "75")
<< (QStringList() << "100")
);
//settings with proxies are not serialized by default
//other settings non-serialized for demo purposes
slaveBoolean->setSerializable (false);
slaveSingleText->setSerializable (false);
slaveMultiText->setSerializable (false);
slaveAlphaSpinbox->setSerializable (false);
slaveIntegerSpinbox->setSerializable (false);
slaveDoubleSpinbox->setSerializable (false);
slaveSlider->setSerializable (false);
slaveDial->setSerializable (false);
slaveBoolean->setDefaultValues (QStringList()
<< "One" << "Three" << "Five");
slaveSingleText->setDefaultValue ("Text A");
slaveMultiText->setDefaultValues (QStringList()
<< "One" << "Three" << "Five");
slaveSingleText->setWidgetWidth (24);
slaveMultiText->setWidgetWidth (24);
slaveAlphaSpinbox->setDefaultValue ("Two");
slaveAlphaSpinbox->setWidgetWidth (20);
//slaveAlphaSpinbox->setPrefix ("No. ");
//slaveAlphaSpinbox->setSuffix ("!");
slaveAlphaSpinbox->setWrapping (true);
slaveIntegerSpinbox->setDefaultValue (14);
slaveIntegerSpinbox->setMinimum (0);
slaveIntegerSpinbox->setMaximum (58);
slaveIntegerSpinbox->setPrefix ("$");
slaveIntegerSpinbox->setSuffix (".00");
slaveIntegerSpinbox->setWidgetWidth (10);
slaveIntegerSpinbox->setSpecialValueText ("Nothing!");
slaveDoubleSpinbox->setDefaultValue (0.51);
slaveDoubleSpinbox->setSingleStep(0.17);
slaveDoubleSpinbox->setMaximum(4.0);
slaveSlider->setMinimum (0);
slaveSlider->setMaximum (100);
slaveSlider->setDefaultValue (75);
slaveSlider->setWidgetWidth (100);
slaveSlider->setTicksAbove (true);
slaveSlider->setTickInterval (25);
slaveDial->setMinimum (0);
slaveDial->setMaximum (100);
slaveDial->setSingleStep (5);
slaveDial->setDefaultValue (75);
slaveDial->setTickInterval (25);
*/
}
}
CSMSettings::UserSettings::~UserSettings()
{
sUserSettingsInstance = 0;
}
void CSMSettings::UserSettings::loadSettings (const QString &fileName)
{
QString userFilePath = QString::fromUtf8
(mCfgMgr.getUserConfigPath().string().c_str());
QString globalFilePath = QString::fromUtf8
(mCfgMgr.getGlobalPath().string().c_str());
QString otherFilePath = globalFilePath;
//test for local only if global fails (uninstalled copy)
if (!QFile (globalFilePath + fileName).exists())
{
//if global is invalid, use the local path
otherFilePath = QString::fromUtf8
(mCfgMgr.getLocalPath().string().c_str());
}
QSettings::setPath
(QSettings::IniFormat, QSettings::UserScope, userFilePath);
QSettings::setPath
(QSettings::IniFormat, QSettings::SystemScope, otherFilePath);
mSettingDefinitions = new QSettings
(QSettings::IniFormat, QSettings::UserScope, "opencs", QString(), this);
}
// if the key is not found create one with a default value
QString CSMSettings::UserSettings::setting(const QString &viewKey, const QString &value)
{
if(mSettingDefinitions->contains(viewKey))
return settingValue(viewKey);
else if(value != QString())
{
mSettingDefinitions->setValue (viewKey, QStringList() << value);
return value;
}
return QString();
}
bool CSMSettings::UserSettings::hasSettingDefinitions (const QString &viewKey) const
{
return (mSettingDefinitions->contains (viewKey));
}
void CSMSettings::UserSettings::setDefinitions
(const QString &key, const QStringList &list)
{
mSettingDefinitions->setValue (key, list);
}
void CSMSettings::UserSettings::saveDefinitions() const
{
mSettingDefinitions->sync();
}
QString CSMSettings::UserSettings::settingValue (const QString &settingKey)
{
QStringList defs;
if (!mSettingDefinitions->contains (settingKey))
return QString();
defs = mSettingDefinitions->value (settingKey).toStringList();
if (defs.isEmpty())
return QString();
return defs.at(0);
}
CSMSettings::UserSettings& CSMSettings::UserSettings::instance()
{
assert(sUserSettingsInstance);
return *sUserSettingsInstance;
}
void CSMSettings::UserSettings::updateUserSetting(const QString &settingKey,
const QStringList &list)
{
mSettingDefinitions->setValue (settingKey ,list);
emit userSettingUpdated (settingKey, list);
}
CSMSettings::Setting *CSMSettings::UserSettings::findSetting
(const QString &pageName, const QString &settingName)
{
foreach (Setting *setting, mSettings)
{
if (setting->name() == settingName)
{
if (setting->page() == pageName)
return setting;
}
}
return 0;
}
void CSMSettings::UserSettings::removeSetting
(const QString &pageName, const QString &settingName)
{
if (mSettings.isEmpty())
return;
QList <Setting *>::iterator removeIterator = mSettings.begin();
while (removeIterator != mSettings.end())
{
if ((*removeIterator)->name() == settingName)
{
if ((*removeIterator)->page() == pageName)
{
mSettings.erase (removeIterator);
break;
}
}
removeIterator++;
}
}
CSMSettings::SettingPageMap CSMSettings::UserSettings::settingPageMap() const
{
SettingPageMap pageMap;
foreach (Setting *setting, mSettings)
{
SettingPageMap::iterator iter = pageMap.find (setting->page());
if (iter==pageMap.end())
{
QPair<QString, QList <Setting *> > value;
std::map<QString, QString>::const_iterator iter2 =
mSectionLabels.find (setting->page());
value.first = iter2!=mSectionLabels.end() ? iter2->second : "";
iter = pageMap.insert (setting->page(), value);
}
iter->second.append (setting);
}
return pageMap;
}
CSMSettings::Setting *CSMSettings::UserSettings::createSetting
(CSMSettings::SettingType type, const QString &name, const QString& label)
{
Setting *setting = new Setting (type, name, mSection, label);
// set useful defaults
int row = 1;
if (!mSettings.empty())
row = mSettings.back()->viewRow()+1;
setting->setViewLocation (row, 1);
setting->setColumnSpan (3);
int width = 10;
if (type==Type_CheckBox)
width = 40;
setting->setWidgetWidth (width);
if (type==Type_CheckBox)
setting->setStyleSheet ("QGroupBox { border: 0px; }");
if (type==Type_CheckBox)
setting->setDeclaredValues(QStringList() << "true" << "false");
if (type==Type_CheckBox)
setting->setSpecialValueText (setting->getLabel());
//add declaration to the model
mSettings.append (setting);
return setting;
}
void CSMSettings::UserSettings::declareSection (const QString& page, const QString& label)
{
mSection = page;
mSectionLabels[page] = label;
}
QStringList CSMSettings::UserSettings::definitions (const QString &viewKey) const
{
if (mSettingDefinitions->contains (viewKey))
return mSettingDefinitions->value (viewKey).toStringList();
return QStringList();
}

@ -1,107 +0,0 @@
#ifndef USERSETTINGS_HPP
#define USERSETTINGS_HPP
#include <map>
#include <QList>
#include <QStringList>
#include <QString>
#include <QMap>
#include <QPair>
#include <boost/filesystem/path.hpp>
#include "support.hpp"
#ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp>
#endif
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
struct ConfigurationManager;}
class QFile;
class QSettings;
namespace CSMSettings {
class Setting;
typedef QMap <QString, QPair<QString, QList <Setting *> > > SettingPageMap;
class UserSettings: public QObject
{
Q_OBJECT
static UserSettings *sUserSettingsInstance;
const Files::ConfigurationManager& mCfgMgr;
QSettings *mSettingDefinitions;
QList <Setting *> mSettings;
QString mSection;
std::map<QString, QString> mSectionLabels;
public:
/// Singleton implementation
static UserSettings& instance();
UserSettings (const Files::ConfigurationManager& configurationManager);
~UserSettings();
UserSettings (UserSettings const &); //not implemented
UserSettings& operator= (UserSettings const &); //not implemented
/// Retrieves the settings file at all three levels (global, local and user).
void loadSettings (const QString &fileName);
/// Updates QSettings and syncs with the ini file
void setDefinitions (const QString &key, const QStringList &defs);
QString settingValue (const QString &settingKey);
///retrieve a setting object from a given page and setting name
Setting *findSetting
(const QString &pageName, const QString &settingName = QString());
///remove a setting from the list
void removeSetting
(const QString &pageName, const QString &settingName);
///Retrieve a map of the settings, keyed by page name
SettingPageMap settingPageMap() const;
///Returns a string list of defined vlaues for the specified setting
///in "page/name" format.
QStringList definitions (const QString &viewKey) const;
///Test to indicate whether or not a setting has any definitions
bool hasSettingDefinitions (const QString &viewKey) const;
///Save any unsaved changes in the QSettings object
void saveDefinitions() const;
QString setting(const QString &viewKey, const QString &value = QString());
private:
void buildSettingModelDefaults();
///add a new setting to the model and return it
Setting *createSetting (CSMSettings::SettingType type, const QString &name,
const QString& label);
/// Set the section for createSetting calls.
///
/// Sections can be declared multiple times.
void declareSection (const QString& page, const QString& label);
signals:
void userSettingUpdated (const QString &, const QStringList &);
public slots:
void updateUserSetting (const QString &, const QStringList &);
};
}
#endif // USERSETTINGS_HPP

@ -10,6 +10,8 @@
#include "../world/data.hpp" #include "../world/data.hpp"
#include "../prefs/state.hpp"
CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type) CSMDoc::Message::Severity CSMTools::ScriptCheckStage::getSeverity (Type type)
{ {
switch (type) switch (type)
@ -62,6 +64,15 @@ CSMTools::ScriptCheckStage::ScriptCheckStage (const CSMDoc::Document& document)
int CSMTools::ScriptCheckStage::setup() int CSMTools::ScriptCheckStage::setup()
{ {
std::string warnings = CSMPrefs::get()["Scripts"]["warnings"].toString();
if (warnings=="Ignore")
mWarningMode = Mode_Ignore;
else if (warnings=="Normal")
mWarningMode = Mode_Normal;
else if (warnings=="Strict")
mWarningMode = Mode_Strict;
mContext.clear(); mContext.clear();
mMessages = 0; mMessages = 0;
mId.clear(); mId.clear();
@ -116,16 +127,3 @@ void CSMTools::ScriptCheckStage::perform (int stage, CSMDoc::Messages& messages)
mMessages = 0; mMessages = 0;
} }
void CSMTools::ScriptCheckStage::updateUserSetting (const QString& name, const QStringList& value)
{
if (name=="script-editor/warnings" && !value.isEmpty())
{
if (value.at (0)=="Ignore")
mWarningMode = Mode_Ignore;
else if (value.at (0)=="Normal")
mWarningMode = Mode_Normal;
else if (value.at (0)=="Strict")
mWarningMode = Mode_Strict;
}
}

@ -50,8 +50,6 @@ namespace CSMTools
virtual void perform (int stage, CSMDoc::Messages& messages); virtual void perform (int stage, CSMDoc::Messages& messages);
///< Messages resulting from this tage will be appended to \a messages. ///< Messages resulting from this tage will be appended to \a messages.
virtual void updateUserSetting (const QString& name, const QStringList& value);
}; };
} }

@ -53,11 +53,6 @@ CSMDoc::OperationHolder *CSMTools::Tools::getVerifier()
{ {
mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false); mVerifierOperation = new CSMDoc::Operation (CSMDoc::State_Verifying, false);
std::vector<QString> settings;
settings.push_back ("script-editor/warnings");
mVerifierOperation->configureSettings (settings);
connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); connect (&mVerifier, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int)));
connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); connect (&mVerifier, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool)));
connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)), connect (&mVerifier, SIGNAL (reportMessage (const CSMDoc::Message&, int)),

@ -38,9 +38,6 @@ void CSVDoc::SubView::setStatusBar (bool show) {}
void CSVDoc::SubView::useHint (const std::string& hint) {} void CSVDoc::SubView::useHint (const std::string& hint) {}
void CSVDoc::SubView::updateUserSetting (const QString &, const QStringList &)
{}
void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id)
{ {
mUniversalId = id; mUniversalId = id;

@ -52,8 +52,6 @@ namespace CSVDoc
virtual std::string getTitle() const; virtual std::string getTitle() const;
virtual void updateUserSetting (const QString& name, const QStringList& value);
private: private:
void closeEvent (QCloseEvent *event); void closeEvent (QCloseEvent *event);

@ -15,7 +15,7 @@
#include <QScrollBar> #include <QScrollBar>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
@ -121,10 +121,9 @@ void CSVDoc::View::setupViewMenu()
mShowStatusBar = new QAction (tr ("Show Status Bar"), this); mShowStatusBar = new QAction (tr ("Show Status Bar"), this);
mShowStatusBar->setCheckable (true); mShowStatusBar->setCheckable (true);
connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool))); connect (mShowStatusBar, SIGNAL (toggled (bool)), this, SLOT (toggleShowStatusBar (bool)));
std::string showStatusBar =
CSMSettings::UserSettings::instance().settingValue("window/show-statusbar").toStdString(); mShowStatusBar->setChecked (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
if(showStatusBar == "true")
mShowStatusBar->setChecked(true);
view->addAction (mShowStatusBar); view->addAction (mShowStatusBar);
QAction *filters = new QAction (tr ("Filters"), this); QAction *filters = new QAction (tr ("Filters"), this);
@ -333,9 +332,9 @@ void CSVDoc::View::updateTitle()
if (mViewTotal>1) if (mViewTotal>1)
stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]"; stream << " [" << (mViewIndex+1) << "/" << mViewTotal << "]";
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" && bool hideTitle = windows["hide-subview"].isTrue() &&
mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); mSubViews.size()==1 && !mSubViews.at (0)->isFloating();
if (hideTitle) if (hideTitle)
@ -346,19 +345,18 @@ void CSVDoc::View::updateTitle()
void CSVDoc::View::updateSubViewIndicies(SubView *view) void CSVDoc::View::updateSubViewIndicies(SubView *view)
{ {
CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
if(view && mSubViews.contains(view)) if(view && mSubViews.contains(view))
{ {
mSubViews.removeOne(view); mSubViews.removeOne(view);
// adjust (reduce) the scroll area (even floating), except when it is "Scrollbar Only" // adjust (reduce) the scroll area (even floating), except when it is "Scrollbar Only"
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); if (windows["mainwindow-scrollbar"].toString() == "Grow then Scroll")
if(settings.settingValue ("window/mainwindow-scrollbar") == "Grow then Scroll")
updateScrollbar(); updateScrollbar();
} }
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); bool hideTitle = windows["hide-subview"].isTrue() &&
bool hideTitle = userSettings.setting ("window/hide-subview", QString ("false"))=="true" &&
mSubViews.size()==1 && !mSubViews.at (0)->isFloating(); mSubViews.size()==1 && !mSubViews.at (0)->isFloating();
updateTitle(); updateTitle();
@ -406,21 +404,16 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), : mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1),
mViewTotal (totalViews), mScroll(0), mScrollbarOnly(false) mViewTotal (totalViews), mScroll(0), mScrollbarOnly(false)
{ {
int width = CSMSettings::UserSettings::instance().settingValue CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
("window/default-width").toInt();
int height = CSMSettings::UserSettings::instance().settingValue
("window/default-height").toInt();
width = std::max(width, 300); int width = std::max (windows["default-width"].toInt(), 300);
height = std::max(height, 300); int height = std::max (windows["default-height"].toInt(), 300);
resize (width, height); resize (width, height);
mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks); mSubViewWindow.setDockOptions (QMainWindow::AllowNestedDocks);
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); if (windows["mainwindow-scrollbar"].toString() == "Grow Only")
if(settings.settingValue ("window/mainwindow-scrollbar") == "Grow Only")
{ {
setCentralWidget (&mSubViewWindow); setCentralWidget (&mSubViewWindow);
} }
@ -449,6 +442,9 @@ CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int to
mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>); mSubViewFactory.add (CSMWorld::UniversalId::Type_RunLog, new SubViewFactory<RunLogSubView>);
connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int))); connect (mOperations, SIGNAL (abortOperation (int)), this, SLOT (abortOperation (int)));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
} }
CSVDoc::View::~View() CSVDoc::View::~View()
@ -503,14 +499,12 @@ void CSVDoc::View::updateProgress (int current, int max, int type, int threads)
void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint) void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::string& hint)
{ {
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
bool isReferenceable = id.getClass() == CSMWorld::UniversalId::Class_RefRecord; bool isReferenceable = id.getClass() == CSMWorld::UniversalId::Class_RefRecord;
// User setting to reuse sub views (on a per top level view basis) // User setting to reuse sub views (on a per top level view basis)
bool reuse = if (windows["reuse"].isTrue())
userSettings.setting ("window/reuse", QString("true")) == "true" ? true : false;
if(reuse)
{ {
foreach(SubView *sb, mSubViews) foreach(SubView *sb, mSubViews)
{ {
@ -538,8 +532,7 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
// //
// If the sub view limit setting is one, the sub view title bar is hidden and the // If the sub view limit setting is one, the sub view title bar is hidden and the
// text in the main title bar is adjusted accordingly // text in the main title bar is adjusted accordingly
int maxSubView = userSettings.setting("window/max-subviews", QString("256")).toInt(); if(mSubViews.size() >= windows["max-subviews"].toInt()) // create a new top level view
if(mSubViews.size() >= maxSubView) // create a new top level view
{ {
mViewManager.addView(mDocument, id, hint); mViewManager.addView(mDocument, id, hint);
@ -559,8 +552,8 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
view->setParent(this); view->setParent(this);
mSubViews.append(view); // only after assert mSubViews.append(view); // only after assert
int minWidth = userSettings.setting ("window/minimum-width", QString("325")).toInt(); int minWidth = windows["minimum-width"].toInt();
view->setMinimumWidth(minWidth); view->setMinimumWidth (minWidth);
view->setStatusBar (mShowStatusBar->isChecked()); view->setStatusBar (mShowStatusBar->isChecked());
@ -575,13 +568,11 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin
// should become visible) // should become visible)
// - Move the scroll bar to the newly added subview // - Move the scroll bar to the newly added subview
// //
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); mScrollbarOnly = windows["mainwindow-scrollbar"].toString() == "Scrollbar Only";
QString mainwinScroll = settings.settingValue ("window/mainwindow-scrollbar");
mScrollbarOnly = mainwinScroll.isEmpty() || mainwinScroll == "Scrollbar Only";
QDesktopWidget *dw = QApplication::desktop(); QDesktopWidget *dw = QApplication::desktop();
QRect rect; QRect rect;
if(settings.settingValue ("window/grow-limit") == "true") if (windows["grow-limit"].isTrue())
rect = dw->screenGeometry(this); rect = dw->screenGeometry(this);
else else
rect = dw->screenGeometry(dw->screen(dw->screenNumber(this))); rect = dw->screenGeometry(dw->screen(dw->screenNumber(this)));
@ -637,6 +628,45 @@ void CSVDoc::View::moveScrollBarToEnd(int min, int max)
} }
} }
void CSVDoc::View::settingChanged (const CSMPrefs::Setting *setting)
{
if (*setting=="Windows/hide-subview")
updateSubViewIndicies (0);
else if (*setting=="Windows/mainwindow-scrollbar")
{
if (setting->toString()!="Grow Only")
{
if (mScroll)
{
if (setting->toString()=="Scrollbar Only")
{
mScrollbarOnly = true;
mSubViewWindow.setMinimumWidth(0);
}
else if (mScrollbarOnly)
{
mScrollbarOnly = false;
updateScrollbar();
}
}
else
{
mScroll = new QScrollArea(this);
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
}
}
else if (mScroll)
{
mScroll->takeWidget();
setCentralWidget (&mSubViewWindow);
mScroll->deleteLater();
mScroll = 0;
}
}
}
void CSVDoc::View::newView() void CSVDoc::View::newView()
{ {
mViewManager.addView (mDocument); mViewManager.addView (mDocument);
@ -860,59 +890,6 @@ void CSVDoc::View::resizeViewHeight (int height)
resize (geometry().width(), height); resize (geometry().width(), height);
} }
void CSVDoc::View::updateUserSetting (const QString &name, const QStringList &list)
{
if (name=="window/hide-subview")
updateSubViewIndicies (0);
foreach (SubView *subView, mSubViews)
{
subView->updateUserSetting (name, list);
}
if (name=="window/mainwindow-scrollbar")
{
if(list.at(0) != "Grow Only")
{
if (mScroll)
{
if (list.at(0).isEmpty() || list.at(0) == "Scrollbar Only")
{
mScrollbarOnly = true;
mSubViewWindow.setMinimumWidth(0);
}
else
{
if(!mScrollbarOnly)
return;
mScrollbarOnly = false;
updateScrollbar();
}
}
else
{
mScroll = new QScrollArea(this);
mScroll->setWidgetResizable(true);
mScroll->setWidget(&mSubViewWindow);
setCentralWidget(mScroll);
}
}
else
{
if (mScroll)
{
mScroll->takeWidget();
setCentralWidget (&mSubViewWindow);
mScroll->deleteLater();
mScroll = 0;
}
else
return;
}
}
}
void CSVDoc::View::toggleShowStatusBar (bool show) void CSVDoc::View::toggleShowStatusBar (bool show)
{ {
foreach (QObject *view, mSubViewWindow.children()) foreach (QObject *view, mSubViewWindow.children())
@ -944,10 +921,9 @@ void CSVDoc::View::stop()
void CSVDoc::View::closeRequest (SubView *subView) void CSVDoc::View::closeRequest (SubView *subView)
{ {
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); CSMPrefs::Category& windows = CSMPrefs::State::get()["Windows"];
if (mSubViews.size()>1 || mViewTotal<=1 || if (mSubViews.size()>1 || mViewTotal<=1 || !windows["hide-subview"].isTrue())
userSettings.setting ("window/hide-subview", QString ("false"))!="true")
{ {
subView->deleteLater(); subView->deleteLater();
mSubViews.removeOne (subView); mSubViews.removeOne (subView);

@ -22,6 +22,11 @@ namespace CSMWorld
class UniversalId; class UniversalId;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSVDoc namespace CSVDoc
{ {
class ViewManager; class ViewManager;
@ -83,8 +88,6 @@ namespace CSVDoc
void exitApplication(); void exitApplication();
void loadUserSettings();
/// User preference function /// User preference function
void resizeViewWidth (int width); void resizeViewWidth (int width);
@ -137,8 +140,6 @@ namespace CSVDoc
void abortOperation (int type); void abortOperation (int type);
void updateUserSetting (const QString &, const QStringList &);
void updateTitle(); void updateTitle();
// called when subviews are added or removed // called when subviews are added or removed
@ -146,6 +147,8 @@ namespace CSVDoc
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void newView(); void newView();
void save(); void save();

@ -14,6 +14,8 @@
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/idcompletionmanager.hpp" #include "../../model/world/idcompletionmanager.hpp"
#include "../../model/prefs/state.hpp"
#include "../world/util.hpp" #include "../world/util.hpp"
#include "../world/enumdelegate.hpp" #include "../world/enumdelegate.hpp"
#include "../world/vartypedelegate.hpp" #include "../world/vartypedelegate.hpp"
@ -22,8 +24,6 @@
#include "../world/idcompletiondelegate.hpp" #include "../world/idcompletiondelegate.hpp"
#include "../world/colordelegate.hpp" #include "../world/colordelegate.hpp"
#include "../../model/settings/usersettings.hpp"
#include "view.hpp" #include "view.hpp"
void CSVDoc::ViewManager::updateIndices() void CSVDoc::ViewManager::updateIndices()
@ -165,10 +165,7 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
mViews.push_back (view); mViews.push_back (view);
std::string showStatusBar = view->toggleStatusBar (CSMPrefs::get()["Windows"]["show-statusbar"].isTrue());
CSMSettings::UserSettings::instance().settingValue("window/show-statusbar").toStdString();
view->toggleStatusBar (showStatusBar == "true");
view->show(); view->show();
connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest())); connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest()));
@ -177,11 +174,6 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document)
connect (view, SIGNAL (editSettingsRequest()), this, SIGNAL (editSettingsRequest())); connect (view, SIGNAL (editSettingsRequest()), this, SIGNAL (editSettingsRequest()));
connect (view, SIGNAL (mergeDocument (CSMDoc::Document *)), this, SIGNAL (mergeDocument (CSMDoc::Document *))); connect (view, SIGNAL (mergeDocument (CSMDoc::Document *)), this, SIGNAL (mergeDocument (CSMDoc::Document *)));
connect (&CSMSettings::UserSettings::instance(),
SIGNAL (userSettingUpdated(const QString &, const QStringList &)),
view,
SLOT (updateUserSetting (const QString &, const QStringList &)));
updateIndices(); updateIndices();
return view; return view;

@ -0,0 +1,126 @@
#include "dialogue.hpp"
#include <QApplication>
#include <QDesktopWidget>
#include <QSplitter>
#include <QListWidget>
#include <QStackedWidget>
#include <QListWidgetItem>
#include "../../model/prefs/state.hpp"
#include "page.hpp"
void CSVPrefs::Dialogue::buildCategorySelector (QSplitter *main)
{
mList = new QListWidget (main);
mList->setMinimumWidth (50);
mList->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
mList->setSelectionBehavior (QAbstractItemView::SelectItems);
main->addWidget (mList);
QFontMetrics metrics (QApplication::font());
int maxWidth = 1;
for (CSMPrefs::State::Iterator iter = CSMPrefs::get().begin(); iter!=CSMPrefs::get().end();
++iter)
{
QString label = QString::fromUtf8 (iter->second.getKey().c_str());
maxWidth = std::max (maxWidth, metrics.width (label));
mList->addItem (label);
}
mList->setMaximumWidth (maxWidth + 10);
connect (mList, SIGNAL (currentItemChanged (QListWidgetItem *, QListWidgetItem *)),
this, SLOT (selectionChanged (QListWidgetItem *, QListWidgetItem *)));
}
void CSVPrefs::Dialogue::buildContentArea (QSplitter *main)
{
mContent = new QStackedWidget (main);
mContent->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding);
main->addWidget (mContent);
}
CSVPrefs::PageBase *CSVPrefs::Dialogue::makePage (const std::string& key)
{
// special case page code goes here
return new Page (CSMPrefs::get()[key], mContent);
}
CSVPrefs::Dialogue::Dialogue()
{
setWindowTitle ("User Settings");
setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setMinimumSize (600, 400);
QSplitter *main = new QSplitter (this);
setCentralWidget (main);
buildCategorySelector (main);
buildContentArea (main);
}
CSVPrefs::Dialogue::~Dialogue()
{
if (isVisible())
CSMPrefs::State::get().save();
}
void CSVPrefs::Dialogue::closeEvent (QCloseEvent *event)
{
QMainWindow::closeEvent (event);
CSMPrefs::State::get().save();
}
void CSVPrefs::Dialogue::show()
{
if (QWidget *active = QApplication::activeWindow())
{
// place at the centre of the window with focus
QSize size = active->size();
move (active->geometry().x()+(size.width() - frameGeometry().width())/2,
active->geometry().y()+(size.height() - frameGeometry().height())/2);
}
else
{
// otherwise place at the centre of the screen
QPoint screenCenter = QApplication::desktop()->screenGeometry().center();
move (screenCenter - QPoint(frameGeometry().width()/2, frameGeometry().height()/2));
}
QWidget::show();
}
void CSVPrefs::Dialogue::selectionChanged (QListWidgetItem *current, QListWidgetItem *previous)
{
if (current)
{
std::string key = current->text().toUtf8().data();
for (int i=0; i<mContent->count(); ++i)
{
PageBase& page = dynamic_cast<PageBase&> (*mContent->widget (i));
if (page.getCategory().getKey()==key)
{
mContent->setCurrentIndex (i);
return;
}
}
PageBase *page = makePage (key);
mContent->setCurrentIndex (mContent->addWidget (page));
}
}

@ -0,0 +1,50 @@
#ifndef CSV_PREFS_DIALOGUE_H
#define CSV_PREFS_DIALOGUE_H
#include <QMainWindow>
class QSplitter;
class QListWidget;
class QStackedWidget;
class QListWidgetItem;
namespace CSVPrefs
{
class PageBase;
class Dialogue : public QMainWindow
{
Q_OBJECT
QListWidget *mList;
QStackedWidget *mContent;
private:
void buildCategorySelector (QSplitter *main);
void buildContentArea (QSplitter *main);
PageBase *makePage (const std::string& key);
public:
Dialogue();
virtual ~Dialogue();
protected:
void closeEvent (QCloseEvent *event);
public slots:
void show();
private slots:
void selectionChanged (QListWidgetItem *current, QListWidgetItem *previous);
};
}
#endif

@ -0,0 +1,40 @@
#include "page.hpp"
#include <QGridLayout>
#include "../../model/prefs/setting.hpp"
#include "../../model/prefs/category.hpp"
CSVPrefs::Page::Page (CSMPrefs::Category& category, QWidget *parent)
: PageBase (category, parent)
{
QWidget *widget = new QWidget (parent);
mGrid = new QGridLayout (widget);
for (CSMPrefs::Category::Iterator iter = category.begin(); iter!=category.end(); ++iter)
addSetting (*iter);
setWidget (widget);
}
void CSVPrefs::Page::addSetting (CSMPrefs::Setting *setting)
{
std::pair<QWidget *, QWidget *> widgets = setting->makeWidgets (this);
int next = mGrid->rowCount();
if (widgets.first)
{
mGrid->addWidget (widgets.first, next, 0);
mGrid->addWidget (widgets.second, next, 1);
}
else if (widgets.second)
{
mGrid->addWidget (widgets.second, next, 0, 1, 2);
}
else
{
mGrid->addWidget (new QWidget (this), next, 0);
}
}

@ -0,0 +1,29 @@
#ifndef CSV_PREFS_PAGE_H
#define CSV_PREFS_PAGE_H
#include "pagebase.hpp"
class QGridLayout;
namespace CSMPrefs
{
class Setting;
}
namespace CSVPrefs
{
class Page : public PageBase
{
Q_OBJECT
QGridLayout *mGrid;
public:
Page (CSMPrefs::Category& category, QWidget *parent);
void addSetting (CSMPrefs::Setting *setting);
};
}
#endif

@ -0,0 +1,13 @@
#include "pagebase.hpp"
#include "../../model/prefs/category.hpp"
CSVPrefs::PageBase::PageBase (CSMPrefs::Category& category, QWidget *parent)
: QScrollArea (parent), mCategory (category)
{}
CSMPrefs::Category& CSVPrefs::PageBase::getCategory()
{
return mCategory;
}

@ -0,0 +1,27 @@
#ifndef CSV_PREFS_PAGEBASE_H
#define CSV_PREFS_PAGEBASE_H
#include <QScrollArea>
namespace CSMPrefs
{
class Category;
}
namespace CSVPrefs
{
class PageBase : public QScrollArea
{
Q_OBJECT
CSMPrefs::Category& mCategory;
public:
PageBase (CSMPrefs::Category& category, QWidget *parent);
CSMPrefs::Category& getCategory();
};
}
#endif

@ -24,11 +24,6 @@ void CSVRender::EditMode::activate (CSVWidget::SceneToolbar *toolbar)
mWorldspaceWidget->clearSelection (~mMask); mWorldspaceWidget->clearSelection (~mMask);
} }
void CSVRender::EditMode::updateUserSetting (const QString& name, const QStringList& value)
{
}
void CSVRender::EditMode::setEditLock (bool locked) void CSVRender::EditMode::setEditLock (bool locked)
{ {

@ -30,9 +30,6 @@ namespace CSVRender
virtual void activate (CSVWidget::SceneToolbar *toolbar); virtual void activate (CSVWidget::SceneToolbar *toolbar);
/// Default-implementation: Do nothing.
virtual void updateUserSetting (const QString& name, const QStringList& value);
/// Default-implementation: Ignored. /// Default-implementation: Ignored.
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);

@ -1,7 +1,7 @@
#include "instancemode.hpp" #include "instancemode.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "elements.hpp" #include "elements.hpp"
#include "object.hpp" #include "object.hpp"
@ -9,33 +9,20 @@
CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent) CSVRender::InstanceMode::InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent)
: EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing", : EditMode (worldspaceWidget, QIcon (":placeholder"), Element_Reference, "Instance editing",
parent), mContextSelect (false) parent)
{ {
} }
void CSVRender::InstanceMode::activate (CSVWidget::SceneToolbar *toolbar)
{
EditMode::activate (toolbar);
mContextSelect = CSMSettings::UserSettings::instance().setting ("scene-input/context-select")=="true";
}
void CSVRender::InstanceMode::updateUserSetting (const QString& name, const QStringList& value)
{
if (name=="scene-input/context-select")
mContextSelect = value.at (0)=="true";
}
void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::primaryEditPressed (osg::ref_ptr<TagBase> tag)
{ {
if (mContextSelect) if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
primarySelectPressed (tag); primarySelectPressed (tag);
} }
void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag) void CSVRender::InstanceMode::secondaryEditPressed (osg::ref_ptr<TagBase> tag)
{ {
if (mContextSelect) if (CSMPrefs::get()["3D Scene Input"]["context-select"].isTrue())
secondarySelectPressed (tag); secondarySelectPressed (tag);
} }

@ -9,16 +9,10 @@ namespace CSVRender
{ {
Q_OBJECT Q_OBJECT
bool mContextSelect;
public: public:
InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0); InstanceMode (WorldspaceWidget *worldspaceWidget, QWidget *parent = 0);
virtual void activate (CSVWidget::SceneToolbar *toolbar);
virtual void updateUserSetting (const QString& name, const QStringList& value);
virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void primaryEditPressed (osg::ref_ptr<TagBase> tag);
virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag); virtual void secondaryEditPressed (osg::ref_ptr<TagBase> tag);

@ -16,7 +16,6 @@
#include <components/resource/resourcesystem.hpp> #include <components/resource/resourcesystem.hpp>
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "../../model/settings/usersettings.hpp"
#include "lighting.hpp" #include "lighting.hpp"

@ -20,7 +20,7 @@
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "../widget/scenetoolmode.hpp" #include "../widget/scenetoolmode.hpp"
#include "../widget/scenetooltoggle2.hpp" #include "../widget/scenetooltoggle2.hpp"
@ -31,17 +31,6 @@
#include "editmode.hpp" #include "editmode.hpp"
#include "instancemode.hpp" #include "instancemode.hpp"
namespace
{
static const char * const sMappingSettings[] =
{
"p-navi", "s-navi",
"p-edit", "s-edit",
"p-select", "s-select",
0
};
}
CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent) CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidget* parent)
: SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document), : SceneWidget (document.getData().getResourceSystem(), parent), mSceneElements(0), mRun(0), mDocument(document),
mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false), mInteractionMask (0), mEditMode (0), mLocked (false), mDragging (false),
@ -77,19 +66,10 @@ CSVRender::WorldspaceWidget::WorldspaceWidget (CSMDoc::Document& document, QWidg
connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), connect (debugProfiles, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)),
this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int))); this, SLOT (debugProfileAboutToBeRemoved (const QModelIndex&, int, int)));
for (int i=0; sMappingSettings[i]; ++i) connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
{ this, SLOT (settingChanged (const CSMPrefs::Setting *)));
QString key ("scene-input/"); CSMPrefs::get()["3D Scene Input"].update();
key += sMappingSettings[i]; CSMPrefs::get()["Tooltips"].update();
storeMappingSetting (key, CSMSettings::UserSettings::instance().settingValue (key));
}
mDragFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-factor").toDouble();
mDragWheelFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-wheel-factor").toDouble();
mDragShiftFactor = CSMSettings::UserSettings::instance().settingValue ("scene-input/drag-shift-factor").toDouble();
mShowToolTips = CSMSettings::UserSettings::instance().settingValue ("tooltips/scene") == "true";
mToolTipDelay = CSMSettings::UserSettings::instance().settingValue ("tooltips/scene-delay").toInt();
mToolTipDelayTimer.setSingleShot (true); mToolTipDelayTimer.setSingleShot (true);
connect (&mToolTipDelayTimer, SIGNAL (timeout()), this, SLOT (showToolTip())); connect (&mToolTipDelayTimer, SIGNAL (timeout()), this, SLOT (showToolTip()));
@ -99,6 +79,23 @@ CSVRender::WorldspaceWidget::~WorldspaceWidget ()
{ {
} }
void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setting)
{
if (storeMappingSetting (setting))
return;
if (*setting=="3D Scene Input/drag-factor")
mDragFactor = setting->toDouble();
else if (*setting=="3D Scene Input/drag-wheel-factor")
mDragWheelFactor = setting->toDouble();
else if (*setting=="3D Scene Input/drag-shift-factor")
mDragShiftFactor = setting->toDouble();
else if (*setting=="Tooltips/scene-delay")
mToolTipDelay = setting->toInt();
else if (*setting=="Tooltips/scene")
mShowToolTips = setting->isTrue();
}
void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode)
{ {
if (mode=="1st") if (mode=="1st")
@ -291,25 +288,6 @@ unsigned int CSVRender::WorldspaceWidget::getInteractionMask() const
return mInteractionMask & getVisibilityMask(); return mInteractionMask & getVisibilityMask();
} }
void CSVRender::WorldspaceWidget::updateUserSetting (const QString& name, const QStringList& value)
{
if (!value.isEmpty() && storeMappingSetting (name, value.first()))
return;
if (name=="scene-input/drag-factor")
mDragFactor = value.at (0).toDouble();
else if (name=="scene-input/drag-wheel-factor")
mDragWheelFactor = value.at (0).toDouble();
else if (name=="scene-input/drag-shift-factor")
mDragShiftFactor = value.at (0).toDouble();
else if (name=="tooltips/scene-delay")
mToolTipDelay = value.at (0).toInt();
else if (name=="tooltips/scene")
mShowToolTips = value.at (0)=="true";
else
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).updateUserSetting (name, value);
}
void CSVRender::WorldspaceWidget::setEditLock (bool locked) void CSVRender::WorldspaceWidget::setEditLock (bool locked)
{ {
dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (locked); dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()).setEditLock (locked);
@ -348,34 +326,40 @@ void CSVRender::WorldspaceWidget::dragMoveEvent(QDragMoveEvent *event)
} }
bool CSVRender::WorldspaceWidget::storeMappingSetting (const QString& key, const QString& value) bool CSVRender::WorldspaceWidget::storeMappingSetting (const CSMPrefs::Setting *setting)
{ {
const QString prefix = "scene-input/"; if (setting->getParent()->getKey()!="3D Scene Input")
return false;
if (key.startsWith (prefix)) static const char * const sMappingSettings[] =
{ {
QString key2 (key.mid (prefix.length())); "p-navi", "s-navi",
"p-edit", "s-edit",
"p-select", "s-select",
0
};
for (int i=0; sMappingSettings[i]; ++i) for (int i=0; sMappingSettings[i]; ++i)
if (key2==sMappingSettings[i]) if (setting->getKey()==sMappingSettings[i])
{ {
Qt::MouseButton button = Qt::NoButton; QString value = QString::fromUtf8 (setting->toString().c_str());
if (value.endsWith ("Left Mouse-Button")) Qt::MouseButton button = Qt::NoButton;
button = Qt::LeftButton;
else if (value.endsWith ("Right Mouse-Button"))
button = Qt::RightButton;
else if (value.endsWith ("Middle Mouse-Button"))
button = Qt::MiddleButton;
else
return false;
bool ctrl = value.startsWith ("Ctrl-"); if (value.endsWith ("Left Mouse-Button"))
button = Qt::LeftButton;
else if (value.endsWith ("Right Mouse-Button"))
button = Qt::RightButton;
else if (value.endsWith ("Middle Mouse-Button"))
button = Qt::MiddleButton;
else
return false;
mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i]; bool ctrl = value.startsWith ("Ctrl-");
return true;
} mButtonMapping[std::make_pair (button, ctrl)] = sMappingSettings[i];
} return true;
}
return false; return false;
} }
@ -514,8 +498,7 @@ void CSVRender::WorldspaceWidget::showToolTip()
if (osg::ref_ptr<TagBase> tag = mousePick (mapFromGlobal (pos))) if (osg::ref_ptr<TagBase> tag = mousePick (mapFromGlobal (pos)))
{ {
bool hideBasics = bool hideBasics = CSMPrefs::get()["Tooltips"]["scene-hide-basic"].isTrue();
CSMSettings::UserSettings::instance().settingValue ("tooltips/scene-hide-basic")=="true";
QToolTip::showText (pos, tag->getToolTip (hideBasics), this); QToolTip::showText (pos, tag->getToolTip (hideBasics), this);
} }
} }

@ -13,6 +13,11 @@
#include "scenewidget.hpp" #include "scenewidget.hpp"
#include "elements.hpp" #include "elements.hpp"
namespace CSMPrefs
{
class Setting;
}
namespace CSMWorld namespace CSMWorld
{ {
class UniversalId; class UniversalId;
@ -115,8 +120,6 @@ namespace CSVRender
/// marked for interaction. /// marked for interaction.
unsigned int getInteractionMask() const; unsigned int getInteractionMask() const;
virtual void updateUserSetting (const QString& name, const QStringList& value);
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
CSMDoc::Document& getDocument(); CSMDoc::Document& getDocument();
@ -151,7 +154,7 @@ namespace CSVRender
void dragMoveEvent(QDragMoveEvent *event); void dragMoveEvent(QDragMoveEvent *event);
/// \return Is \a key a button mapping setting? (ignored otherwise) /// \return Is \a key a button mapping setting? (ignored otherwise)
bool storeMappingSetting (const QString& key, const QString& value); bool storeMappingSetting (const CSMPrefs::Setting *setting);
osg::ref_ptr<TagBase> mousePick (const QPoint& localPos); osg::ref_ptr<TagBase> mousePick (const QPoint& localPos);
@ -161,6 +164,8 @@ namespace CSVRender
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void selectNavigationMode (const std::string& mode); void selectNavigationMode (const std::string& mode);
virtual void referenceableDataChanged (const QModelIndex& topLeft, virtual void referenceableDataChanged (const QModelIndex& topLeft,

@ -1,120 +0,0 @@
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QRadioButton>
#include <QGroupBox>
#include <QAbstractButton>
#include "booleanview.hpp"
#include "../../model/settings/setting.hpp"
CSVSettings::BooleanView::BooleanView (CSMSettings::Setting *setting,
Page *parent)
: View (setting, parent), mType(setting->type())
{
foreach (const QString &value, setting->declaredValues())
{
QAbstractButton *button = 0;
switch (mType)
{
case CSMSettings::Type_CheckBox: {
if(mButtons.empty()) // show only one for checkboxes
{
button = new QCheckBox (value, this);
button->setChecked (setting->defaultValues().at(0) == "true" ? true : false);
// special visual treatment option for checkboxes
if(setting->specialValueText() != "") {
Frame::setTitle("");
button->setText(setting->specialValueText());
}
}
}
break;
case CSMSettings::Type_RadioButton:
button = new QRadioButton (value, this);
break;
default:
break;
}
if(button && (mType != CSMSettings::Type_CheckBox || mButtons.empty()))
{
connect (button, SIGNAL (clicked (bool)),
this, SLOT (slotToggled (bool)));
button->setObjectName (value);
addWidget (button);
mButtons[value] = button;
}
}
}
void CSVSettings::BooleanView::slotToggled (bool state)
{
//test only for true to avoid multiple selection updates with radiobuttons
if (!isMultiValue() && !state)
return;
QStringList values;
foreach (QString key, mButtons.keys())
{
// checkbox values are true/false unlike radio buttons
if(mType == CSMSettings::Type_CheckBox)
values.append(mButtons.value(key)->isChecked() ? "true" : "false");
else
{
if (mButtons.value(key)->isChecked())
values.append (key);
}
}
setSelectedValues (values, false);
View::updateView();
}
void CSVSettings::BooleanView::updateView (bool signalUpdate) const
{
QStringList values = selectedValues();
foreach (const QString &buttonName, mButtons.keys())
{
QAbstractButton *button = mButtons[buttonName];
//if the value is not found in the list, the widget is checked false
bool buttonValue = values.contains(buttonName);
//skip if the butotn value will not change
if (button->isChecked() == buttonValue)
continue;
//disable autoexclusive if it's enabled and we're setting
//the button value to false
bool switchExclusive = (!buttonValue && button->autoExclusive());
if (switchExclusive)
button->setAutoExclusive (false);
button->setChecked (buttonValue);
if (switchExclusive)
button->setAutoExclusive(true);
}
View::updateView (signalUpdate);
}
CSVSettings::BooleanView *CSVSettings::BooleanViewFactory::createView
(CSMSettings::Setting *setting,
Page *parent)
{
return new BooleanView (setting, parent);
}

@ -1,45 +0,0 @@
#ifndef CSVSETTINGS_BOOLEANVIEW_HPP
#define CSVSETTINGS_BOOLEANVIEW_HPP
#include <QWidget>
#include <QAbstractButton>
#include "view.hpp"
#include "../../model/settings/support.hpp"
class QStringListModel;
namespace CSVSettings
{
class BooleanView : public View
{
Q_OBJECT
QMap <QString, QAbstractButton *> mButtons;
enum CSMSettings::SettingType mType;
public:
explicit BooleanView (CSMSettings::Setting *setting,
Page *parent);
protected:
void updateView (bool signalUpdate = true) const;
private slots:
void slotToggled (bool state);
};
class BooleanViewFactory : public QObject, public IViewFactory
{
Q_OBJECT
public:
explicit BooleanViewFactory (QWidget *parent = 0)
: QObject (parent)
{}
BooleanView *createView (CSMSettings::Setting *setting,
Page *parent);
};
}
#endif // CSVSETTINGS_BOOLEANVIEW_HPP

@ -1,127 +0,0 @@
#include "dialog.hpp"
#include <algorithm>
#include <QListWidgetItem>
#include <QApplication>
#include <QWidget>
#include <QStackedWidget>
#include <QtGui>
#include <QSplitter>
#include <QDesktopWidget>
#include "../../model/settings/usersettings.hpp"
#include "page.hpp"
CSVSettings::Dialog::Dialog(QMainWindow *parent)
: SettingWindow (parent), mStackedWidget (0), mDebugMode (false)
{
setWindowTitle(QString::fromUtf8 ("User Settings"));
setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setMinimumSize (600, 400);
setupDialog();
connect (mPageListWidget,
SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
this,
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
}
void CSVSettings::Dialog::slotChangePage
(QListWidgetItem *cur, QListWidgetItem *prev)
{
mStackedWidget->changePage
(mPageListWidget->row (cur), mPageListWidget->row (prev));
}
void CSVSettings::Dialog::setupDialog()
{
QSplitter *centralWidget = new QSplitter (this);
centralWidget->setSizePolicy (QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setCentralWidget (centralWidget);
buildPageListWidget (centralWidget);
buildStackedWidget (centralWidget);
}
void CSVSettings::Dialog::buildPages()
{
SettingWindow::createPages ();
QFontMetrics fm (QApplication::font());
int maxWidth = 1;
foreach (Page *page, SettingWindow::pages())
{
maxWidth = std::max (maxWidth, fm.width(page->getLabel()));
new QListWidgetItem (page->getLabel(), mPageListWidget);
mStackedWidget->addWidget (page);
}
mPageListWidget->setMaximumWidth (maxWidth + 10);
resize (mStackedWidget->sizeHint());
}
void CSVSettings::Dialog::buildPageListWidget (QSplitter *centralWidget)
{
mPageListWidget = new QListWidget (centralWidget);
mPageListWidget->setMinimumWidth(50);
mPageListWidget->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
mPageListWidget->setSelectionBehavior (QAbstractItemView::SelectItems);
centralWidget->addWidget(mPageListWidget);
}
void CSVSettings::Dialog::buildStackedWidget (QSplitter *centralWidget)
{
mStackedWidget = new ResizeableStackedWidget (centralWidget);
mStackedWidget->setSizePolicy (QSizePolicy::Preferred, QSizePolicy::Expanding);
centralWidget->addWidget (mStackedWidget);
}
void CSVSettings::Dialog::closeEvent (QCloseEvent *event)
{
//SettingWindow::closeEvent() must be called first to ensure
//model is updated
SettingWindow::closeEvent (event);
saveSettings();
}
void CSVSettings::Dialog::show()
{
if (pages().isEmpty())
{
buildPages();
setViewValues();
}
QWidget *currView = QApplication::activeWindow();
if(currView)
{
// place at the center of the window with focus
QSize size = currView->size();
move(currView->geometry().x()+(size.width() - frameGeometry().width())/2,
currView->geometry().y()+(size.height() - frameGeometry().height())/2);
}
else
{
// something's gone wrong, place at the center of the screen
QPoint screenCenter = QApplication::desktop()->screenGeometry().center();
move(screenCenter - QPoint(frameGeometry().width()/2,
frameGeometry().height()/2));
}
QWidget::show();
}

@ -1,50 +0,0 @@
#ifndef CSVSETTINGS_DIALOG_H
#define CSVSETTINGS_DIALOG_H
#include "settingwindow.hpp"
#include "resizeablestackedwidget.hpp"
class QStackedWidget;
class QListWidget;
class QListWidgetItem;
class QSplitter;
namespace CSVSettings {
class Page;
class Dialog : public SettingWindow
{
Q_OBJECT
QListWidget *mPageListWidget;
ResizeableStackedWidget *mStackedWidget;
bool mDebugMode;
public:
explicit Dialog (QMainWindow *parent = 0);
protected:
/// Settings are written on close
void closeEvent (QCloseEvent *event);
void setupDialog();
private:
void buildPages();
void buildPageListWidget (QSplitter *centralWidget);
void buildStackedWidget (QSplitter *centralWidget);
public slots:
void show();
private slots:
void slotChangePage (QListWidgetItem *, QListWidgetItem *);
};
}
#endif // CSVSETTINGS_DIALOG_H

@ -1,108 +0,0 @@
#include "frame.hpp"
#include <QWidget>
const QString CSVSettings::Frame::sInvisibleBoxStyle =
QString::fromUtf8("Frame { border:2px; padding: 2px; margin: 2px;}");
CSVSettings::Frame::Frame (bool isVisible, const QString &title,
QWidget *parent)
: QGroupBox (title, parent), mIsHorizontal (true),
mLayout (new SettingLayout())
{
setFlat (true);
mVisibleBoxStyle = styleSheet();
if (!isVisible)
{
// must be Page, not a View
setStyleSheet (sInvisibleBoxStyle);
}
setLayout (mLayout);
}
void CSVSettings::Frame::hideWidgets()
{
for (int i = 0; i < children().size(); i++)
{
QObject *obj = children().at(i);
Frame *widgFrame = dynamic_cast <Frame *> (obj);
if (widgFrame)
{
widgFrame->hideWidgets();
continue;
}
QWidget *widg = static_cast <QWidget *> (obj);
if (widg->property("sizePolicy").isValid())
widg->setSizePolicy (QSizePolicy::Expanding, QSizePolicy::Expanding);
}
layout()->activate();
setFixedSize(minimumSizeHint());
}
void CSVSettings::Frame::showWidgets()
{
for (int i = 0; i < children().size(); i++)
{
QObject *obj = children().at(i);
Frame *widgFrame = dynamic_cast <Frame *> (obj);
if (widgFrame)
{
widgFrame->showWidgets();
continue;
}
QWidget *widg = static_cast <QWidget *> (obj);
if (widg->property("sizePolicy").isValid())
{
widg->setSizePolicy
(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}
}
layout()->activate();
setFixedSize(minimumSizeHint());
}
void CSVSettings::Frame::addWidget (QWidget *widget, int row, int column,
int rowSpan, int columnSpan)
{
if (row == -1)
row = getNextRow();
if (column == -1)
column = getNextColumn();
mLayout->addWidget (widget, row, column, rowSpan, columnSpan);
//, Qt::AlignLeft | Qt::AlignTop);
widget->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Ignored);
}
int CSVSettings::Frame::getNextRow () const
{
int row = mLayout->rowCount();
if (mIsHorizontal && row > 0)
row--;
return row;
}
int CSVSettings::Frame::getNextColumn () const
{
int column = 0;
if (mIsHorizontal)
column = mLayout->columnCount();
return column;
}

@ -1,60 +0,0 @@
#ifndef CSVSETTINGS_FRAME_HPP
#define CSVSETTINGS_FRAME_HPP
#include <QSizePolicy>
#include <QGroupBox>
#include <QGridLayout>
#include "../../model/settings/support.hpp"
namespace CSVSettings
{
class SettingLayout : public QGridLayout
{
public:
explicit SettingLayout (QWidget *parent = 0)
: QGridLayout (parent)
{
setContentsMargins(0,0,0,0);
setAlignment(Qt::AlignLeft | Qt::AlignTop);
}
};
/// Custom implementation of QGroupBox to act as a base for view classes
class Frame : public QGroupBox
{
static const QString sInvisibleBoxStyle;
QString mVisibleBoxStyle;
bool mIsHorizontal;
SettingLayout *mLayout;
public:
explicit Frame (bool isVisible, const QString &title = "",
QWidget *parent = 0);
///Adds a widget to the grid layout, setting the position
///relative to the last added widgets, or absolutely for positive
///row / column values
void addWidget (QWidget *widget, int row = -1, int column = -1,
int rowSpan = 1, int columnSpan = 1);
///Force the grid to lay out in horizontal or vertical alignments
void setHLayout() { mIsHorizontal = true; }
void setVLayout() { mIsHorizontal = false; }
///show / hide widgets (when stacked widget page changes)
void showWidgets();
void hideWidgets();
private:
///functions which return the index for the next layout row / column
int getNextColumn() const;
int getNextRow() const;
};
}
#endif // CSVSETTINGS_FRAME_HPP

@ -1,106 +0,0 @@
#include "listview.hpp"
#include "../../model/settings/setting.hpp"
#include <QListView>
#include <QComboBox>
#include <QStringListModel>
CSVSettings::ListView::ListView(CSMSettings::Setting *setting,
Page *parent)
: View(setting, parent), mAbstractItemView (0), mComboBox (0)
{
QWidget *widget =
buildWidget(setting->isMultiLine(), setting->widgetWidth());
addWidget (widget, setting->viewRow(), setting->viewColumn());
if (mComboBox)
buildComboBoxModel();
else if (mAbstractItemView)
buildAbstractItemViewModel();
}
void CSVSettings::ListView::buildComboBoxModel()
{
mComboBox->setModel (dataModel());
mComboBox->setModelColumn (0);
mComboBox->view()->setSelectionModel (selectionModel());
int curIdx = -1;
if (!selectionModel()->selection().isEmpty())
curIdx = selectionModel()->selectedIndexes().at(0).row();
mComboBox->setCurrentIndex (curIdx);
connect (mComboBox, SIGNAL(currentIndexChanged(int)),
this, SLOT(emitItemViewUpdate(int)));
}
void CSVSettings::ListView::buildAbstractItemViewModel()
{
mAbstractItemView->setModel (dataModel());
mAbstractItemView->setSelectionModel (selectionModel());
//connection needs to go here for list view update to signal to
//the outside
}
void CSVSettings::ListView::emitItemViewUpdate (int idx)
{
updateView();
}
QWidget *CSVSettings::ListView::buildWidget(bool isMultiLine, int width)
{
QWidget *widget = 0;
if (isMultiLine)
{
mAbstractItemView = new QListView (this);
widget = mAbstractItemView;
if (width > 0)
widget->setFixedWidth (widgetWidth (width));
}
else
{
mComboBox = new QComboBox (this);
widget = mComboBox;
if (width > 0)
mComboBox->setMinimumContentsLength (width);
}
return widget;
}
void CSVSettings::ListView::showEvent ( QShowEvent * event )
{
View::showEvent (event);
}
void CSVSettings::ListView::updateView (bool signalUpdate) const
{
QStringList values = selectedValues();
if (mComboBox)
{
int idx = -1;
if (values.size() > 0)
idx = (mComboBox->findText(values.at(0)));
mComboBox->setCurrentIndex (idx);
}
View::updateView (signalUpdate);
}
CSVSettings::ListView *CSVSettings::ListViewFactory::createView
(CSMSettings::Setting *setting,
Page *parent)
{
return new ListView(setting, parent);
}

@ -1,63 +0,0 @@
#ifndef CSVSETTINGS_LISTVIEW_HPP
#define CSVSETTINGS_LISTVIEW_HPP
#include "view.hpp"
class QStringListModel;
class QComboBox;
class QAbstractItemView;
namespace CSVSettings
{
class ListView : public View
{
Q_OBJECT
QAbstractItemView *mAbstractItemView;
QComboBox *mComboBox;
public:
explicit ListView (CSMSettings::Setting *setting,
Page *parent);
protected:
void updateView (bool signalUpdate = true) const;
void showEvent ( QShowEvent * event );
///Receives signal from widget and signals viwUpdated()
void slotTextEdited (QString value);
private:
///Helper function to construct a model for an AbstractItemView
void buildAbstractItemViewModel();
///Helper function to construct a model for a combobox
void buildComboBoxModel();
///Helper function to build the view widget
QWidget *buildWidget (bool isMultiLine, int width);
private slots:
///Receives updates from single-select widgets (like combobox) and
///signals viewUpdated with the selected values.
void emitItemViewUpdate (int idx);
};
class ListViewFactory : public QObject, public IViewFactory
{
Q_OBJECT
public:
explicit ListViewFactory (QWidget *parent = 0)
: QObject (parent)
{}
ListView *createView (CSMSettings::Setting *setting,
Page *parent);
};
}
#endif // CSVSETTINGS_LISTVIEW_HPP

@ -1,110 +0,0 @@
#include "page.hpp"
#include <QLabel>
#include "view.hpp"
#include "booleanview.hpp"
#include "textview.hpp"
#include "listview.hpp"
#include "rangeview.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../../model/settings/connector.hpp"
#include "../../model/settings/support.hpp"
#include "settingwindow.hpp"
QMap <CSVSettings::ViewType, CSVSettings::IViewFactory *>
CSVSettings::Page::mViewFactories;
CSVSettings::Page::Page (const QString &pageName, QList <CSMSettings::Setting *> settingList,
SettingWindow *parent, const QString& label)
: Frame(false, "", parent), mParent(parent), mIsEditorPage (false), mLabel (label)
{
setObjectName (pageName);
if (mViewFactories.size() == 0)
buildFactories();
setVLayout();
setupViews (settingList);
}
void CSVSettings::Page::setupViews
(QList <CSMSettings::Setting *> &settingList)
{
foreach (CSMSettings::Setting *setting, settingList)
addView (setting);
}
void CSVSettings::Page::addView (CSMSettings::Setting *setting)
{
if (setting->viewType() == ViewType_Undefined)
{
if(setting->specialValueText() != "")
{
// hack to put a label
addWidget(new QLabel(setting->specialValueText()),
setting->viewRow(), setting->viewColumn(),
setting->rowSpan(), setting->columnSpan());
return;
}
else
return;
}
View *view = mViewFactories[setting->viewType()]->createView(setting, this);
if (!view)
return;
mViews.append (view);
addWidget (view, setting->viewRow(), setting->viewColumn(),
setting->rowSpan(), setting->columnSpan() );
//if this page is an editor page, connect each of it's views up to the
//UserSettings singleton for signaling back to OpenCS
if (setting->isEditorSetting()) {
connect (view, SIGNAL (viewUpdated(const QString&, const QStringList&)),
&CSMSettings::UserSettings::instance(),
SLOT (updateUserSetting (const QString &, const QStringList &)));
}
}
CSVSettings::View *CSVSettings::Page::findView (const QString &page,
const QString &setting) const
{
//if this is not the page we're looking for,
//appeal to the parent setting window to find the appropriate view
if (page != objectName())
return mParent->findView (page, setting);
//otherwise, return the matching view
for (int i = 0; i < mViews.size(); i++)
{
View *view = mViews.at(i);
if (view->parentPage()->objectName() != page)
continue;
if (view->objectName() == setting)
return view;
}
return 0;
}
void CSVSettings::Page::buildFactories()
{
mViewFactories[ViewType_Boolean] = new BooleanViewFactory (this);
mViewFactories[ViewType_Text] = new TextViewFactory (this);
mViewFactories[ViewType_List] = new ListViewFactory (this);
mViewFactories[ViewType_Range] = new RangeViewFactory (this);
}
QString CSVSettings::Page::getLabel() const
{
return mLabel;
}

@ -1,56 +0,0 @@
#ifndef CSVSETTINGS_PAGE_HPP
#define CSVSETTINGS_PAGE_HPP
#include <QWidget>
#include <QMap>
#include <QList>
#include "frame.hpp"
#include "../../model/settings/support.hpp"
namespace CSMSettings { class Setting; }
namespace CSVSettings
{
class View;
class IViewFactory;
class SettingWindow;
class Page : public Frame
{
Q_OBJECT
QList<View *> mViews;
SettingWindow *mParent;
static QMap <ViewType, IViewFactory *> mViewFactories;
bool mIsEditorPage;
QString mLabel;
public:
Page (const QString &pageName, QList <CSMSettings::Setting *> settingList,
SettingWindow *parent, const QString& label);
///Creates a new view based on the passed setting and adds it to
///the page.
void addView (CSMSettings::Setting *setting);
///Iterates the views created for this page based on the passed setting
///and returns it.
View *findView (const QString &page, const QString &setting) const;
///returns the list of views associated with the page
const QList <View *> &views () const { return mViews; }
QString getLabel() const;
private:
///Creates views based on the passed setting list
void setupViews (QList <CSMSettings::Setting *> &settingList);
///Creates factory objects for view construction
void buildFactories();
};
}
#endif // CSVSETTINGS_PAGE_HPP

@ -1,208 +0,0 @@
#include <QSpinBox>
#include <QDoubleSpinBox>
#include <QAbstractSpinBox>
#include <QAbstractSlider>
#include <QDial>
#include <QSlider>
#include "rangeview.hpp"
#include "spinbox.hpp"
#include "../../model/settings/setting.hpp"
#include "../../model/settings/support.hpp"
CSVSettings::RangeView::RangeView (CSMSettings::Setting *setting,
Page *parent)
: View (setting, parent), mRangeWidget (0), mRangeType (setting->type())
{
mRangeWidget = 0;
if (isMultiValue())
return;
switch (mRangeType)
{
case CSMSettings::Type_SpinBox:
case CSMSettings::Type_DoubleSpinBox:
buildSpinBox (setting);
break;
case CSMSettings::Type_Dial:
case CSMSettings::Type_Slider:
buildSlider (setting);
break;
default:
break;
}
if(mRangeWidget)
{
mRangeWidget->setFixedWidth (widgetWidth (setting->widgetWidth()));
mRangeWidget->setObjectName (setting->name());
}
addWidget (mRangeWidget);
}
void CSVSettings::RangeView::buildSlider (CSMSettings::Setting *setting)
{
switch (setting->type())
{
case CSMSettings::Type_Slider:
mRangeWidget = new QSlider (Qt::Horizontal, this);
mRangeWidget->setProperty ("tickInterval", setting->tickInterval());
if (setting->ticksAbove())
{
if (setting->ticksBelow())
mRangeWidget->setProperty ("tickPosition", QSlider::TicksBothSides);
else
mRangeWidget->setProperty ("tickPosition", QSlider::TicksAbove);
}
else if (setting->ticksBelow())
mRangeWidget->setProperty ("tickPosition", QSlider::TicksBelow);
else
mRangeWidget->setProperty ("tickPosition", QSlider::NoTicks);
break;
case CSMSettings::Type_Dial:
mRangeWidget = new QDial (this);
mRangeWidget->setProperty ("wrapping", setting->wrapping());
mRangeWidget->setProperty ("notchesVisible",
(setting->ticksAbove() || setting->ticksBelow()));
break;
default:
break;
}
if(mRangeWidget)
{
mRangeWidget->setProperty ("minimum", setting->minimum());
mRangeWidget->setProperty ("maximum", setting->maximum());
mRangeWidget->setProperty ("tracking", false);
mRangeWidget->setProperty ("singleStep", setting->singleStep());
connect (mRangeWidget, SIGNAL (valueChanged (int)),
this, SLOT (slotUpdateView (int)));
}
}
void CSVSettings::RangeView::buildSpinBox (CSMSettings::Setting *setting)
{
SpinBox *sb = 0;
switch (setting->type())
{
case CSMSettings::Type_SpinBox:
sb = new SpinBox (this);
if (!setting->declaredValues().isEmpty())
sb->setValueList (setting->declaredValues());
mRangeWidget = sb;
connect (mRangeWidget, SIGNAL (valueChanged (int)),
this, SLOT (slotUpdateView (int)));
break;
case CSMSettings::Type_DoubleSpinBox:
mRangeWidget = new QDoubleSpinBox (this);
connect (mRangeWidget, SIGNAL (valueChanged (double)),
this, SLOT (slotUpdateView (double)));
break;
default:
return;
}
//min / max values are set automatically in AlphaSpinBox
if (setting->declaredValues().isEmpty())
{
mRangeWidget->setProperty ("minimum", setting->minimum());
mRangeWidget->setProperty ("maximum", setting->maximum());
mRangeWidget->setProperty ("singleStep", setting->singleStep());
}
mRangeWidget->setProperty ("prefix", setting->prefix());
mRangeWidget->setProperty ("suffix", setting->suffix());
mRangeWidget->setProperty ("wrapping", setting->wrapping());
dynamic_cast<QAbstractSpinBox *> (mRangeWidget)->setAlignment(Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter);
if(setting->type() == CSMSettings::Type_SpinBox && setting->declaredValues().isEmpty())
dynamic_cast<QSpinBox *> (mRangeWidget)->setValue (setting->defaultValues().at(0).toInt());
}
void CSVSettings::RangeView::slotUpdateView (int value)
{
QString textValue = "";
QStringList list;
switch (mRangeType)
{
case CSMSettings::Type_SpinBox:
list = static_cast <SpinBox *> (mRangeWidget)->valueList();
if (!list.isEmpty())
textValue = list.at(value);
break;
default:
break;
}
if (textValue.isEmpty())
textValue = QVariant (value).toString();
setSelectedValue (textValue, false);
View::updateView();
}
void CSVSettings::RangeView::slotUpdateView (double value)
{
setSelectedValue (QVariant(value).toString(), false);
View::updateView();
}
void CSVSettings::RangeView::updateView (bool signalUpdate) const
{
QString value;
if (!selectedValues().isEmpty())
value = selectedValues().at(0);
switch (mRangeType)
{
case CSMSettings::Type_SpinBox:
static_cast <SpinBox *> (mRangeWidget)->setValue (value);
break;
case CSMSettings::Type_DoubleSpinBox:
static_cast <QDoubleSpinBox *> (mRangeWidget)->setValue (value.toDouble());
break;
case CSMSettings::Type_Slider:
case CSMSettings::Type_Dial:
mRangeWidget->setProperty ("value", value.toInt());
mRangeWidget->setProperty ("sliderPosition", value.toInt());
break;
default:
break;
}
View::updateView (signalUpdate);
}
CSVSettings::RangeView *CSVSettings::RangeViewFactory::createView
(CSMSettings::Setting *setting,
Page *parent)
{
return new RangeView (setting, parent);
}

@ -1,55 +0,0 @@
#ifndef CSVSETTINGS_RANGEVIEW_HPP
#define CSVSETTINGS_RANGEVIEW_HPP
#include "view.hpp"
#include "../../model/settings/support.hpp"
class QStringListModel;
class QAbstractSpinBox;
namespace CSVSettings
{
class RangeView : public View
{
Q_OBJECT
QWidget *mRangeWidget;
CSMSettings::SettingType mRangeType;
public:
explicit RangeView (CSMSettings::Setting *setting,
Page *parent);
protected:
///virtual function called through View
void updateView (bool signalUpdate = true) const;
///construct a slider-based view
void buildSlider (CSMSettings::Setting *setting);
///construct a spinbox-based view
void buildSpinBox (CSMSettings::Setting *setting);
private slots:
///responds to valueChanged signals
void slotUpdateView (int value);
void slotUpdateView (double value);
};
class RangeViewFactory : public QObject, public IViewFactory
{
Q_OBJECT
public:
explicit RangeViewFactory (QWidget *parent = 0)
: QObject (parent)
{}
RangeView *createView (CSMSettings::Setting *setting,
Page *parent);
};
}
#endif // CSVSETTINGS_RANGEVIEW_HPP

@ -1,39 +0,0 @@
#include "resizeablestackedwidget.hpp"
#include "page.hpp"
#include <QListWidgetItem>
CSVSettings::ResizeableStackedWidget::ResizeableStackedWidget(QWidget *parent) :
QStackedWidget(parent)
{}
void CSVSettings::ResizeableStackedWidget::addWidget(QWidget* pWidget)
{
QStackedWidget::addWidget(pWidget);
}
void CSVSettings::ResizeableStackedWidget::changePage
(int current, int previous)
{
if (current == previous)
return;
Page *prevPage = 0;
Page *curPage = 0;
if (previous > -1)
prevPage = static_cast <Page *> (widget (previous));
if (current > -1)
curPage = static_cast <Page *> (widget (current));
if (prevPage)
prevPage->hideWidgets();
if (curPage)
curPage->showWidgets();
layout()->activate();
setCurrentIndex (current);
}

@ -1,25 +0,0 @@
#ifndef CSVSETTINGS_RESIZEABLESTACKEDWIDGET_HPP
#define CSVSETTINGS_RESIZEABLESTACKEDWIDGET_HPP
#include <QStackedWidget>
class QListWidgetItem;
namespace CSVSettings
{
class ResizeableStackedWidget : public QStackedWidget
{
Q_OBJECT
public:
explicit ResizeableStackedWidget(QWidget *parent = 0);
///add a widget to the stacked widget
void addWidget(QWidget* pWidget);
///called whenever the stacked widget page is changed
void changePage (int, int);
};
}
#endif // CSVSETTINGS_RESIZEABLESTACKEDWIDGET_HPP

@ -1,131 +0,0 @@
#include <QApplication>
#include <QDebug>
#include "../../model/settings/setting.hpp"
#include "../../model/settings/connector.hpp"
#include "../../model/settings/usersettings.hpp"
#include "settingwindow.hpp"
#include "page.hpp"
#include "view.hpp"
CSVSettings::SettingWindow::SettingWindow(QWidget *parent)
: QMainWindow(parent), mModel(NULL)
{}
void CSVSettings::SettingWindow::createPages()
{
CSMSettings::SettingPageMap pageMap = mModel->settingPageMap();
QList <CSMSettings::Setting *> connectedSettings;
foreach (const QString &pageName, pageMap.keys())
{
QList <CSMSettings::Setting *> pageSettings = pageMap.value (pageName).second;
mPages.append (new Page (pageName, pageSettings, this, pageMap.value (pageName).first));
for (int i = 0; i < pageSettings.size(); i++)
{
CSMSettings::Setting *setting = pageSettings.at(i);
if (!setting->proxyLists().isEmpty())
connectedSettings.append (setting);
}
}
if (!connectedSettings.isEmpty())
createConnections(connectedSettings);
}
void CSVSettings::SettingWindow::createConnections
(const QList <CSMSettings::Setting *> &list)
{
foreach (const CSMSettings::Setting *setting, list)
{
View *masterView = findView (setting->page(), setting->name());
CSMSettings::Connector *connector =
new CSMSettings::Connector (masterView, this);
connect (masterView,
SIGNAL (viewUpdated(const QString &, const QStringList &)),
connector,
SLOT (slotUpdateSlaves())
);
const CSMSettings::ProxyValueMap &proxyMap = setting->proxyLists();
foreach (const QString &key, proxyMap.keys())
{
QStringList keyPair = key.split('/');
if (keyPair.size() != 2)
continue;
View *slaveView = findView (keyPair.at(0), keyPair.at(1));
if (!slaveView)
{
qWarning () << "Unable to create connection for view "
<< key;
continue;
}
QList <QStringList> proxyList = proxyMap.value (key);
connector->addSlaveView (slaveView, proxyList);
connect (slaveView,
SIGNAL (viewUpdated(const QString &, const QStringList &)),
connector,
SLOT (slotUpdateMaster()));
}
}
}
void CSVSettings::SettingWindow::setViewValues()
{
//iterate each page and view, setting their definitions
//if they exist in the model
foreach (const Page *page, mPages)
{
foreach (const View *view, page->views())
{
//testing beforehand prevents overwriting a proxy setting
if (!mModel->hasSettingDefinitions (view->viewKey()))
continue;
QStringList defs = mModel->definitions (view->viewKey());
view->setSelectedValues(defs);
}
}
}
CSVSettings::View *CSVSettings::SettingWindow::findView
(const QString &pageName, const QString &setting)
{
foreach (const Page *page, mPages)
{
if (page->objectName() == pageName)
return page->findView (pageName, setting);
}
return 0;
}
void CSVSettings::SettingWindow::saveSettings()
{
//setting the definition in the model automatically syncs with the file
foreach (const Page *page, mPages)
{
foreach (const View *view, page->views())
{
if (!view->serializable())
continue;
mModel->setDefinitions (view->viewKey(), view->selectedValues());
}
}
mModel->saveDefinitions();
}

@ -1,58 +0,0 @@
#ifndef CSVSETTINGS_SETTINGWINDOW_HPP
#define CSVSETTINGS_SETTINGWINDOW_HPP
#include <QMainWindow>
#include <QList>
#include "../../model/settings/support.hpp"
namespace CSMSettings {
class Setting;
class UserSettings;
}
namespace CSVSettings {
class Page;
class View;
typedef QList <Page *> PageList;
class SettingWindow : public QMainWindow
{
Q_OBJECT
PageList mPages;
CSMSettings::UserSettings *mModel;
public:
explicit SettingWindow(QWidget *parent = 0);
///retrieve a reference to a view based on it's page and setting name
View *findView (const QString &pageName, const QString &setting);
///set the model the view uses (instance of UserSettings)
void setModel (CSMSettings::UserSettings &model) { mModel = &model; }
protected:
///construct the pages to be displayed in the dialog
void createPages();
///return the list of constructed pages
const PageList &pages() const { return mPages; }
///save settings from the GUI to file
void saveSettings();
///sets the defined values for the views that have been created
void setViewValues();
private:
///create connections between settings (used for proxy settings)
void createConnections (const QList <CSMSettings::Setting *> &list);
};
}
#endif // CSVSETTINGS_SETTINGWINDOW_HPP

@ -1,50 +0,0 @@
#include "spinbox.hpp"
#include <QLineEdit>
CSVSettings::SpinBox::SpinBox(QWidget *parent)
: QSpinBox(parent), mValueList(QStringList())
{
setRange (0, 0);
}
QString CSVSettings::SpinBox::textFromValue(int val) const
{
if (mValueList.isEmpty())
return QVariant (val).toString();
QString value;
if (val < mValueList.size())
value = mValueList.at (val);
return value;
}
int CSVSettings::SpinBox::valueFromText(const QString &text) const
{
if (mValueList.isEmpty())
return text.toInt(); // TODO: assumed integer, untested error handling for alpha types
if (mValueList.contains (text))
return mValueList.indexOf(text);
return -1;
}
void CSVSettings::SpinBox::setValue (const QString &value)
{
if (!mValueList.isEmpty())
{
lineEdit()->setText (value);
QSpinBox::setValue(valueFromText(value));
}
else
QSpinBox::setValue (value.toInt());
}
void CSVSettings::SpinBox::setValueList (const QStringList &list)
{
mValueList = list;
setMaximum (list.size() - 1);
}

@ -1,38 +0,0 @@
#ifndef CSVSETTINGS_SPINBOX_HPP
#define CSVSETTINGS_SPINBOX_HPP
#include <QObject>
#include <QStringList>
#include <QSpinBox>
namespace CSVSettings
{
class SpinBox : public QSpinBox
{
Q_OBJECT
QStringList mValueList;
public:
explicit SpinBox(QWidget *parent = 0);
///set the value displayed in the spin box
void setValue (const QString &value);
///set the stringlist that's used as a list of pre-defined values
///to be displayed as the user scrolls
void setValueList (const QStringList &list);
///returns the pre-defined value list.
const QStringList &valueList() const { return mValueList; }
protected:
///converts an index value to corresponding text to be displayed
QString textFromValue (int val) const;
///converts a text value to a corresponding index
int valueFromText (const QString &text) const;
};
}
#endif // CSVSETTINGS_SPINBOX_HPP

@ -1,63 +0,0 @@
#include <QTextEdit>
#include <QLineEdit>
#include "textview.hpp"
#include "../../model/settings/setting.hpp"
CSVSettings::TextView::TextView(CSMSettings::Setting *setting, Page *parent)
: View (setting, parent), mDelimiter (setting->delimiter())
{
if (setting->isMultiLine())
mTextWidget = new QTextEdit ("", this);
else
mTextWidget = new QLineEdit ("", this);
if (setting->widgetWidth() > 0)
mTextWidget->setFixedWidth (widgetWidth (setting->widgetWidth()));
connect (mTextWidget, SIGNAL (textEdited (QString)),
this, SLOT (slotTextEdited (QString)));
addWidget (mTextWidget, setting->viewRow(), setting->viewColumn());
}
bool CSVSettings::TextView::isEquivalent
(const QString &lhs, const QString &rhs) const
{
return (lhs.trimmed() == rhs.trimmed());
}
void CSVSettings::TextView::slotTextEdited (QString value)
{
QStringList values = value.split (mDelimiter, QString::SkipEmptyParts);
QStringList returnValues;
foreach (const QString &splitValue, values)
returnValues.append (splitValue.trimmed());
setSelectedValues (returnValues, false);
View::updateView();
}
void CSVSettings::TextView::updateView(bool signalUpdate) const
{
QString values = selectedValues().join (mDelimiter);
if (isEquivalent (mTextWidget->property("text").toString(), values))
return;
mTextWidget->setProperty("text", values);
View::updateView (signalUpdate);
}
CSVSettings::TextView *CSVSettings::TextViewFactory::createView
(CSMSettings::Setting *setting,
Page *parent)
{
return new TextView (setting, parent);
}

@ -1,51 +0,0 @@
#ifndef CSVSETTINGS_TEXTVIEW_HPP
#define CSVSETTINGS_TEXTVIEW_HPP
#include "view.hpp"
#include "../../model/settings/setting.hpp"
namespace CSVSettings
{
class TextView : public View
{
Q_OBJECT
QWidget *mTextWidget;
QString mDelimiter;
public:
explicit TextView (CSMSettings::Setting *setting,
Page *parent = 0);
protected:
/// virtual function called through View
void updateView (bool signalUpdate = true) const;
protected slots:
///Receives updates to the widget for signalling
void slotTextEdited (QString value);
private:
///Comparison function that returns true if the trimmed() strings
///are equal
bool isEquivalent (const QString &lhs, const QString &rhs) const;
};
class TextViewFactory : public QObject, public IViewFactory
{
Q_OBJECT
public:
explicit TextViewFactory (QWidget *parent = 0)
: QObject (parent)
{}
TextView *createView (CSMSettings::Setting *setting,
Page *parent);
};
}
#endif // CSVSETTINGS_TEXTVIEW_HPP

@ -1,222 +0,0 @@
#include <QStandardItemModel>
#include <QStandardItem>
#include <QApplication>
#include <QItemSelectionModel>
#include <QStringListModel>
#include "view.hpp"
#include "../../model/settings/support.hpp"
#include "../../model/settings/setting.hpp"
#include "page.hpp"
CSVSettings::View::View(CSMSettings::Setting *setting,
Page *parent)
: Frame(true, setting->getLabel(), parent),
mParentPage (parent), mDataModel(0),
mHasFixedValues (!setting->declaredValues().isEmpty()),
mIsMultiValue (setting->isMultiValue()),
mViewKey (setting->page() + '/' + setting->name()),
mSerializable (setting->serializable())
{
if (!setting->getToolTip().isEmpty())
setToolTip (setting->getToolTip());
setObjectName (setting->name());
buildView();
buildModel (setting);
// apply stylesheet to view's frame if exists
if(setting->styleSheet() != "")
Frame::setStyleSheet (setting->styleSheet());
}
void CSVSettings::View::buildModel (const CSMSettings::Setting *setting)
{
QStringList values = setting->defaultValues();
if (mHasFixedValues)
buildFixedValueModel (setting->declaredValues());
else
buildUpdatableValueModel (values);
mSelectionModel = new QItemSelectionModel (mDataModel, this);
setSelectedValues (values, false);
}
void CSVSettings::View::buildFixedValueModel (const QStringList &values)
{
//fixed value models are simple string list models, since they are read-only
mDataModel = new QStringListModel (values, this);
}
void CSVSettings::View::buildUpdatableValueModel (const QStringList &values)
{
//updateable models are standard item models because they support
//replacing entire columns
QList <QStandardItem *> itemList;
foreach (const QString &value, values)
itemList.append (new QStandardItem(value));
QStandardItemModel *model = new QStandardItemModel (this);
model->appendColumn (itemList);
mDataModel = model;
}
void CSVSettings::View::buildView()
{
setFlat (true);
setHLayout();
}
int CSVSettings::View::currentIndex () const
{
if (selectedValues().isEmpty())
return -1;
QString currentValue = selectedValues().at(0);
for (int i = 0; i < mDataModel->rowCount(); i++)
if (value(i) == currentValue)
return i;
return -1;
}
void CSVSettings::View::refresh() const
{
select (mSelectionModel->selection());
updateView();
}
int CSVSettings::View::rowCount() const
{
return mDataModel->rowCount();
}
void CSVSettings::View::select (const QItemSelection &selection) const
{
mSelectionModel->clear();
mSelectionModel->select(selection, QItemSelectionModel::Select);
}
QStringList CSVSettings::View::selectedValues() const
{
QStringList selValues;
foreach (const QModelIndex &idx, mSelectionModel->selectedIndexes())
selValues.append (value(idx.row()));
return selValues;
}
void CSVSettings::View::setSelectedValue (const QString &value,
bool doViewUpdate, bool signalUpdate)
{
setSelectedValues (QStringList() << value, doViewUpdate, signalUpdate);
}
void CSVSettings::View::setSelectedValues (const QStringList &list,
bool doViewUpdate, bool signalUpdate) const
{
QItemSelection selection;
if (stringListsMatch (list, selectedValues()))
return;
if (!mHasFixedValues)
{
QStandardItemModel *model =
static_cast <QStandardItemModel *>(mDataModel);
model->clear();
model->appendColumn (toStandardItemList (list));
for (int i = 0; i < model->rowCount(); i++)
{
QModelIndex idx = model->index(i, 0);
selection.append (QItemSelectionRange (idx, idx));
}
}
else
{
for (int i = 0; i < mDataModel->rowCount(); i++)
{
if (list.contains(value(i)))
{
QModelIndex idx = mDataModel->index(i, 0);
selection.append(QItemSelectionRange (idx, idx));
}
}
}
select (selection);
//update the view if the selection was set from the model side, not by the
//user
if (doViewUpdate)
updateView (signalUpdate);
}
void CSVSettings::View::showEvent ( QShowEvent * event )
{
refresh();
}
bool CSVSettings::View::stringListsMatch (
const QStringList &list1,
const QStringList &list2) const
{
//returns a "sloppy" match, verifying that each list contains all the same
//items, though not necessarily in the same order.
if (list1.size() != list2.size())
return false;
QStringList tempList(list2);
//iterate each value in the list, removing one occurrence of the value in
//the other list. If no corresponding value is found, test fails
foreach (const QString &value, list1)
{
if (!tempList.contains(value))
return false;
tempList.removeOne(value);
}
return true;
}
QList <QStandardItem *> CSVSettings::View::toStandardItemList
(const QStringList &list) const
{
QList <QStandardItem *> itemList;
foreach (const QString &value, list)
itemList.append (new QStandardItem (value));
return itemList;
}
void CSVSettings::View::updateView (bool signalUpdate) const
{
if (signalUpdate)
emit viewUpdated(viewKey(), selectedValues());
}
QString CSVSettings::View::value (int row) const
{
if (row > -1 && row < mDataModel->rowCount())
return mDataModel->data (mDataModel->index(row, 0)).toString();
return QString();
}
int CSVSettings::View::widgetWidth(int characterCount) const
{
QString widthToken = QString().fill ('m', characterCount);
QFontMetrics fm (QApplication::font());
return (fm.width (widthToken));
}

@ -1,160 +0,0 @@
#ifndef CSVSETTINGS_VIEW_HPP
#define CSVSETTINGS_VIEW_HPP
#include <QWidget>
#include <QList>
#include "frame.hpp"
#include "../../model/settings/support.hpp"
class QGroupBox;
class QStringList;
class QStandardItem;
class QItemSelection;
class QAbstractItemModel;
class QItemSelectionModel;
namespace CSMSettings { class Setting; }
namespace CSVSettings
{
class Page;
class View : public Frame
{
Q_OBJECT
///Pointer to the owning Page instance
Page *mParentPage;
///Pointer to the selection model for the view
QItemSelectionModel *mSelectionModel;
///Pointer to the data model for the view's selection model
QAbstractItemModel *mDataModel;
///State indicating whether or not the setting has a pre-defined list
///of values, limiting possible definitions
bool mHasFixedValues;
///State indicating whether the view will allow multiple values
bool mIsMultiValue;
///'pagename.settingname' form of the view's id
QString mViewKey;
///indicates whether or not the setting is written to file
bool mSerializable;
public:
explicit View (CSMSettings::Setting *setting, Page *parent);
///Returns the index / row of the passed value, -1 if not found.
int currentIndex () const;
///Returns the number of rows in the view's data model
int rowCount() const;
///Returns bool indicating the data in this view should / should not
///be serialized to a config file
bool serializable() const { return mSerializable; }
///Returns a pointer to the view's owning parent page
const Page *parentPage() const { return mParentPage; }
///Returns the selected items in the selection model as a QStringList
QStringList selectedValues() const;
///Sets the selected items in the selection model based on passed list.
///Bools allow opt-out of updating the view
///or signaling the view was updatedto avoid viscious cylcing.
void setSelectedValues (const QStringList &values,
bool updateView = true,
bool signalUpdate = true) const;
void setSelectedValue (const QString &value,
bool updateView = true,
bool signalUpdate = true);
///Returns the value of the data model at the specified row
QString value (int row) const;
QString viewKey() const { return mViewKey; }
protected:
/// Returns the model which provides data for the selection model
QAbstractItemModel *dataModel() { return mDataModel; }
///Accessor function for subclasses
bool isMultiValue() { return mIsMultiValue; }
///Returns the view selection model
QItemSelectionModel *selectionModel() { return mSelectionModel;}
///Global callback for basic view initialization
void showEvent ( QShowEvent * event );
///Virtual for updating a specific View subclass
///bool indicates whether viewUpdated() signal is emitted
virtual void updateView (bool signalUpdate = true) const;
///Returns the pixel width corresponding to the specified number of
///characters.
int widgetWidth(int characterCount) const;
private:
///Constructs the view layout
void buildView();
///Constructs the data and selection models
void buildModel (const CSMSettings::Setting *setting);
///In cases where the view has a pre-defined list of possible values,
///a QStringListModel is created using those values.
///View changes operate on the selection model only.
void buildFixedValueModel (const QStringList &definitions);
///In cases where the view does not have a pre-defined list of possible
///values, a QStandardItemModel is created, containing the actual
///setting definitions. View changes first update the data in the
///model to match the data in the view. The selection model always
///selects all values.
void buildUpdatableValueModel (const QStringList &definitions);
///Refreshes the view
void refresh() const;
///Convenince function for selection model's select() method. Also
///clears out the model beforehand to ensure complete selection.
void select (const QItemSelection &selection) const;
///Compares two string lists "loosely", ensuring that all values in
///one list are contained entirely in the other, and that neither list
///has more values than the other. List order is not considered.
bool stringListsMatch (const QStringList &list1,
const QStringList &list2) const;
///Converts a string list to a list of QStandardItem pointers.
QList <QStandardItem *> toStandardItemList(const QStringList &) const;
signals:
///Signals that the view has been changed.
void viewUpdated(const QString &, const QStringList &) const;
};
class IViewFactory
{
public:
///Creation interface for view factories
virtual View *createView (CSMSettings::Setting *setting,
Page *parent) = 0;
};
}
#endif // CSVSETTINGS_VIEW_HPP

@ -27,11 +27,6 @@ void CSVTools::ReportSubView::setEditLock (bool locked)
// ignored. We don't change document state anyway. // ignored. We don't change document state anyway.
} }
void CSVTools::ReportSubView::updateUserSetting (const QString &name, const QStringList &list)
{
mTable->updateUserSetting (name, list);
}
void CSVTools::ReportSubView::refreshRequest() void CSVTools::ReportSubView::refreshRequest()
{ {
if (!(mDocument.getState() & mRefreshState)) if (!(mDocument.getState() & mRefreshState))

@ -29,8 +29,6 @@ namespace CSVTools
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void updateUserSetting (const QString &, const QStringList &);
private slots: private slots:
void refreshRequest(); void refreshRequest();

@ -14,6 +14,8 @@
#include "../../model/tools/reportmodel.hpp" #include "../../model/tools/reportmodel.hpp"
#include "../../model/prefs/state.hpp"
#include "../../view/world/idtypedelegate.hpp" #include "../../view/world/idtypedelegate.hpp"
namespace CSVTools namespace CSVTools
@ -189,6 +191,10 @@ CSVTools::ReportTable::ReportTable (CSMDoc::Document& document,
mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit)); mDoubleClickActions.insert (std::make_pair (Qt::NoModifier, Action_Edit));
mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_Remove)); mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_Remove));
mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_EditAndRemove)); mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_EditAndRemove));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
CSMPrefs::get()["Reports"].update();
} }
std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() const
@ -206,40 +212,6 @@ std::vector<CSMWorld::UniversalId> CSVTools::ReportTable::getDraggedRecords() co
return ids; return ids;
} }
void CSVTools::ReportTable::updateUserSetting (const QString& name, const QStringList& list)
{
mIdTypeDelegate->updateUserSetting (name, list);
QString base ("report-input/double");
if (name.startsWith (base))
{
QString modifierString = name.mid (base.size());
Qt::KeyboardModifiers modifiers = 0;
if (modifierString=="-s")
modifiers = Qt::ShiftModifier;
else if (modifierString=="-c")
modifiers = Qt::ControlModifier;
else if (modifierString=="-sc")
modifiers = Qt::ShiftModifier | Qt::ControlModifier;
DoubleClickAction action = Action_None;
QString value = list.at (0);
if (value=="Edit")
action = Action_Edit;
else if (value=="Remove")
action = Action_Remove;
else if (value=="Edit And Remove")
action = Action_EditAndRemove;
mDoubleClickActions[modifiers] = action;
return;
}
}
std::vector<int> CSVTools::ReportTable::getReplaceIndices (bool selection) const std::vector<int> CSVTools::ReportTable::getReplaceIndices (bool selection) const
{ {
std::vector<int> indices; std::vector<int> indices;
@ -285,6 +257,44 @@ void CSVTools::ReportTable::flagAsReplaced (int index)
mModel->flagAsReplaced (index); mModel->flagAsReplaced (index);
} }
void CSVTools::ReportTable::settingChanged (const CSMPrefs::Setting *setting)
{
if (setting->getParent()->getKey()=="Reports")
{
QString base ("double");
QString key = setting->getKey().c_str();
if (key.startsWith (base))
{
QString modifierString = key.mid (base.size());
Qt::KeyboardModifiers modifiers = 0;
if (modifierString=="-s")
modifiers = Qt::ShiftModifier;
else if (modifierString=="-c")
modifiers = Qt::ControlModifier;
else if (modifierString=="-sc")
modifiers = Qt::ShiftModifier | Qt::ControlModifier;
DoubleClickAction action = Action_None;
std::string value = setting->toString();
if (value=="Edit")
action = Action_Edit;
else if (value=="Remove")
action = Action_Remove;
else if (value=="Edit And Remove")
action = Action_EditAndRemove;
mDoubleClickActions[modifiers] = action;
return;
}
}
else if (*setting=="Records/type-format")
mIdTypeDelegate->settingChanged (setting);
}
void CSVTools::ReportTable::showSelection() void CSVTools::ReportTable::showSelection()
{ {
QModelIndexList selectedRows = selectionModel()->selectedRows(); QModelIndexList selectedRows = selectionModel()->selectedRows();

@ -13,6 +13,11 @@ namespace CSMTools
class ReportModel; class ReportModel;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSVWorld namespace CSVWorld
{ {
class CommandDelegate; class CommandDelegate;
@ -61,8 +66,6 @@ namespace CSVTools
virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const; virtual std::vector<CSMWorld::UniversalId> getDraggedRecords() const;
void updateUserSetting (const QString& name, const QStringList& list);
void clear(); void clear();
/// Return indices of rows that are suitable for replacement. /// Return indices of rows that are suitable for replacement.
@ -77,6 +80,8 @@ namespace CSVTools
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void showSelection(); void showSelection();
void removeSelection(); void removeSelection();

@ -6,7 +6,7 @@
#include "../../model/tools/search.hpp" #include "../../model/tools/search.hpp"
#include "../../model/tools/reportmodel.hpp" #include "../../model/tools/reportmodel.hpp"
#include "../../model/world/idtablebase.hpp" #include "../../model/world/idtablebase.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "reporttable.hpp" #include "reporttable.hpp"
#include "searchbox.hpp" #include "searchbox.hpp"
@ -23,8 +23,7 @@ void CSVTools::SearchSubView::replace (bool selection)
const CSMTools::ReportModel& model = const CSMTools::ReportModel& model =
dynamic_cast<const CSMTools::ReportModel&> (*mTable->model()); dynamic_cast<const CSMTools::ReportModel&> (*mTable->model());
bool autoDelete = CSMSettings::UserSettings::instance().setting ( bool autoDelete = CSMPrefs::get()["Search & Replace"]["auto-delete"].isTrue();
"search/auto-delete", QString ("true"))=="true";
CSMTools::Search search (mSearch); CSMTools::Search search (mSearch);
CSMWorld::IdTableBase *currentTable = 0; CSMWorld::IdTableBase *currentTable = 0;
@ -102,11 +101,6 @@ void CSVTools::SearchSubView::setEditLock (bool locked)
mSearchBox.setEditLock (locked); mSearchBox.setEditLock (locked);
} }
void CSVTools::SearchSubView::updateUserSetting (const QString &name, const QStringList &list)
{
mTable->updateUserSetting (name, list);
}
void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *document) void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *document)
{ {
mSearchBox.setSearchMode (!(state & CSMDoc::State_Searching)); mSearchBox.setSearchMode (!(state & CSMDoc::State_Searching));
@ -114,13 +108,10 @@ void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *documen
void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search) void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search)
{ {
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); CSMPrefs::Category& settings = CSMPrefs::get()["Search & Replace"];
int paddingBefore = userSettings.setting ("search/char-before", QString ("5")).toInt();
int paddingAfter = userSettings.setting ("search/char-after", QString ("5")).toInt();
mSearch = search; mSearch = search;
mSearch.setPadding (paddingBefore, paddingAfter); mSearch.setPadding (settings["char-before"].toInt(), settings["char-after"].toInt());
mTable->clear(); mTable->clear();
mDocument.runSearch (getUniversalId(), mSearch); mDocument.runSearch (getUniversalId(), mSearch);

@ -43,8 +43,6 @@ namespace CSVTools
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void updateUserSetting (const QString &, const QStringList &);
private slots: private slots:
void stateChanged (int state, CSMDoc::Document *document); void stateChanged (int state, CSMDoc::Document *document);

@ -1,5 +1,6 @@
#include "datadisplaydelegate.hpp" #include "datadisplaydelegate.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../../model/prefs/state.hpp"
#include <QApplication> #include <QApplication>
#include <QPainter> #include <QPainter>
@ -8,8 +9,8 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values,
const IconList &icons, const IconList &icons,
CSMWorld::CommandDispatcher *dispatcher, CSMWorld::CommandDispatcher *dispatcher,
CSMDoc::Document& document, CSMDoc::Document& document,
const QString &pageName, const std::string &pageName,
const QString &settingName, const std::string &settingName,
QObject *parent) QObject *parent)
: EnumDelegate (values, dispatcher, document, parent), mDisplayMode (Mode_TextOnly), : EnumDelegate (values, dispatcher, document, parent), mDisplayMode (Mode_TextOnly),
mIcons (icons), mIconSize (QSize(16, 16)), mIcons (icons), mIconSize (QSize(16, 16)),
@ -18,10 +19,8 @@ CSVWorld::DataDisplayDelegate::DataDisplayDelegate(const ValueList &values,
{ {
buildPixmaps(); buildPixmaps();
QString value = if (!pageName.empty())
CSMSettings::UserSettings::instance().settingValue (mSettingKey); updateDisplayMode (CSMPrefs::get()[pageName][settingName].toString());
updateDisplayMode(value);
} }
void CSVWorld::DataDisplayDelegate::buildPixmaps () void CSVWorld::DataDisplayDelegate::buildPixmaps ()
@ -118,19 +117,7 @@ void CSVWorld::DataDisplayDelegate::paintIcon (QPainter *painter, const QStyleOp
QApplication::style()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, mPixmaps.at(index).second); QApplication::style()->drawItemPixmap(painter, iconRect, Qt::AlignCenter, mPixmaps.at(index).second);
} }
void CSVWorld::DataDisplayDelegate::updateUserSetting (const QString &name, void CSVWorld::DataDisplayDelegate::updateDisplayMode (const std::string &mode)
const QStringList &list)
{
if (list.isEmpty())
return;
QString value = list.at(0);
if (name == mSettingKey)
updateDisplayMode (value);
}
void CSVWorld::DataDisplayDelegate::updateDisplayMode (const QString &mode)
{ {
if (mode == "Icon and Text") if (mode == "Icon and Text")
mDisplayMode = Mode_IconAndText; mDisplayMode = Mode_IconAndText;
@ -146,6 +133,13 @@ CSVWorld::DataDisplayDelegate::~DataDisplayDelegate()
{ {
} }
void CSVWorld::DataDisplayDelegate::settingChanged (const CSMPrefs::Setting *setting)
{
if (*setting==mSettingKey)
updateDisplayMode (setting->toString());
}
void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, QString enumName, QString iconFilename) void CSVWorld::DataDisplayDelegateFactory::add (int enumValue, QString enumName, QString iconFilename)
{ {
mIcons.push_back (std::make_pair(enumValue, QIcon(iconFilename))); mIcons.push_back (std::make_pair(enumValue, QIcon(iconFilename)));
@ -158,5 +152,3 @@ CSVWorld::CommandDelegate *CSVWorld::DataDisplayDelegateFactory::makeDelegate (
{ {
return new DataDisplayDelegate (mValues, mIcons, dispatcher, document, "", "", parent); return new DataDisplayDelegate (mValues, mIcons, dispatcher, document, "", "", parent);
} }

@ -4,10 +4,13 @@
#include <QTextOption> #include <QTextOption>
#include "enumdelegate.hpp" #include "enumdelegate.hpp"
namespace CSVWorld namespace CSMPrefs
{ {
class Setting;
}
namespace CSVWorld
{
class DataDisplayDelegate : public EnumDelegate class DataDisplayDelegate : public EnumDelegate
{ {
public: public:
@ -34,12 +37,12 @@ namespace CSVWorld
int mHorizontalMargin; int mHorizontalMargin;
int mTextLeftOffset; int mTextLeftOffset;
QString mSettingKey; std::string mSettingKey;
public: public:
DataDisplayDelegate (const ValueList & values, const IconList & icons, DataDisplayDelegate (const ValueList & values, const IconList & icons,
CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document,
const QString &pageName, const QString &settingName, QObject *parent); const std::string& pageName, const std::string& settingName, QObject *parent);
~DataDisplayDelegate(); ~DataDisplayDelegate();
@ -53,13 +56,10 @@ namespace CSVWorld
/// offset the horizontal position of the text from the right edge of the icon. Default is 8 pixels. /// offset the horizontal position of the text from the right edge of the icon. Default is 8 pixels.
void setTextLeftOffset (int offset); void setTextLeftOffset (int offset);
///update the display mode for the delegate
void updateUserSetting (const QString &name, const QStringList &list);
private: private:
/// update the display mode based on a passed string /// update the display mode based on a passed string
void updateDisplayMode (const QString &); void updateDisplayMode (const std::string &);
/// custom paint function for painting the icon. Mode_IconAndText and Mode_Icon only. /// custom paint function for painting the icon. Mode_IconAndText and Mode_Icon only.
void paintIcon (QPainter *painter, const QStyleOptionViewItem &option, int i) const; void paintIcon (QPainter *painter, const QStyleOptionViewItem &option, int i) const;
@ -67,6 +67,7 @@ namespace CSVWorld
/// rebuild the list of pixmaps from the provided icons (called when icon size is changed) /// rebuild the list of pixmaps from the provided icons (called when icon size is changed)
void buildPixmaps(); void buildPixmaps();
virtual void settingChanged (const CSMPrefs::Setting *setting);
}; };
class DataDisplayDelegateFactory : public EnumDelegateFactory class DataDisplayDelegateFactory : public EnumDelegateFactory

@ -31,7 +31,8 @@
#include "../../model/world/idtree.hpp" #include "../../model/world/idtree.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../../model/prefs/state.hpp"
#include "../widget/coloreditor.hpp" #include "../widget/coloreditor.hpp"
#include "../widget/droplineedit.hpp" #include "../widget/droplineedit.hpp"
@ -883,12 +884,12 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id,
connect (mBottom, SIGNAL (requestFocus (const std::string&)), connect (mBottom, SIGNAL (requestFocus (const std::string&)),
this, SLOT (requestFocus (const std::string&))); this, SLOT (requestFocus (const std::string&)));
// button bar
if (CSMSettings::UserSettings::instance().setting ("dialogues/toolbar", QString("true")) == "true")
addButtonBar();
// layout // layout
getMainLayout().addWidget (mBottom); getMainLayout().addWidget (mBottom);
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
CSMPrefs::get()["ID Dialogues"].update();
} }
void CSVWorld::DialogueSubView::setEditLock (bool locked) void CSVWorld::DialogueSubView::setEditLock (bool locked)
@ -899,29 +900,21 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked)
mButtons->setEditLock (locked); mButtons->setEditLock (locked);
} }
void CSVWorld::DialogueSubView::updateUserSetting (const QString& name, const QStringList& value) void CSVWorld::DialogueSubView::settingChanged (const CSMPrefs::Setting *setting)
{ {
SimpleDialogueSubView::updateUserSetting (name, value); if (*setting=="ID Dialogues/toolbar")
if (name=="dialogues/toolbar")
{ {
if (value.at(0)==QString ("true")) if (setting->isTrue())
{ {
addButtonBar(); addButtonBar();
} }
else else if (mButtons)
{ {
if (mButtons) getMainLayout().removeWidget (mButtons);
{ delete mButtons;
getMainLayout().removeWidget (mButtons); mButtons = 0;
delete mButtons;
mButtons = 0;
}
} }
} }
if (mButtons)
mButtons->updateUserSetting (name, value);
} }
void CSVWorld::DialogueSubView::showPreview () void CSVWorld::DialogueSubView::showPreview ()

@ -27,6 +27,11 @@ namespace CSMWorld
class NestedTableProxyModel; class NestedTableProxyModel;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSMDoc namespace CSMDoc
{ {
class Document; class Document;
@ -271,10 +276,10 @@ namespace CSVWorld
virtual void setEditLock (bool locked); virtual void setEditLock (bool locked);
virtual void updateUserSetting (const QString& name, const QStringList& value);
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void showPreview(); void showPreview();
void viewRecord(); void viewRecord();

@ -5,7 +5,7 @@
CSVWorld::IdTypeDelegate::IdTypeDelegate CSVWorld::IdTypeDelegate::IdTypeDelegate
(const ValueList &values, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) (const ValueList &values, const IconList &icons, CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent)
: DataDisplayDelegate (values, icons, dispatcher, document, : DataDisplayDelegate (values, icons, dispatcher, document,
"records", "type-format", "Records", "type-format",
parent) parent)
{} {}

@ -6,7 +6,7 @@
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "../world/tablebottombox.hpp" #include "../world/tablebottombox.hpp"
@ -32,7 +32,7 @@ void CSVWorld::RecordButtonBar::updatePrevNextButtons()
mPrevButton->setDisabled (true); mPrevButton->setDisabled (true);
mNextButton->setDisabled (true); mNextButton->setDisabled (true);
} }
else if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle")=="true") else if (CSMPrefs::get()["General Input"]["cycle"].isTrue())
{ {
mPrevButton->setDisabled (false); mPrevButton->setDisabled (false);
mNextButton->setDisabled (false); mNextButton->setDisabled (false);
@ -131,6 +131,9 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id,
connect (&mTable, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), connect (&mTable, SIGNAL (rowsRemoved (const QModelIndex&, int, int)),
this, SLOT (rowNumberChanged (const QModelIndex&, int, int))); this, SLOT (rowNumberChanged (const QModelIndex&, int, int)));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
updateModificationButtons(); updateModificationButtons();
updatePrevNextButtons(); updatePrevNextButtons();
} }
@ -141,18 +144,18 @@ void CSVWorld::RecordButtonBar::setEditLock (bool locked)
updateModificationButtons(); updateModificationButtons();
} }
void CSVWorld::RecordButtonBar::updateUserSetting (const QString& name, const QStringList& value)
{
if (name=="general-input/cycle")
updatePrevNextButtons();
}
void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id) void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id)
{ {
mId = id; mId = id;
updatePrevNextButtons(); updatePrevNextButtons();
} }
void CSVWorld::RecordButtonBar::settingChanged (const CSMPrefs::Setting *setting)
{
if (*setting=="General Input/cycle")
updatePrevNextButtons();
}
void CSVWorld::RecordButtonBar::cloneRequest() void CSVWorld::RecordButtonBar::cloneRequest()
{ {
if (mBottom) if (mBottom)
@ -173,8 +176,7 @@ void CSVWorld::RecordButtonBar::nextId()
if (newRow >= mTable.rowCount()) if (newRow >= mTable.rowCount())
{ {
if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle") if (CSMPrefs::get()["General Input"]["cycle"].isTrue())
=="true")
newRow = 0; newRow = 0;
else else
return; return;
@ -189,8 +191,7 @@ void CSVWorld::RecordButtonBar::prevId()
if (newRow < 0) if (newRow < 0)
{ {
if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle") if (CSMPrefs::get()["General Input"]["cycle"].isTrue())
=="true")
newRow = mTable.rowCount()-1; newRow = mTable.rowCount()-1;
else else
return; return;

@ -14,6 +14,11 @@ namespace CSMWorld
class CommandDispatcher; class CommandDispatcher;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSVWorld namespace CSVWorld
{ {
class TableBottomBox; class TableBottomBox;
@ -58,14 +63,14 @@ namespace CSVWorld
void setEditLock (bool locked); void setEditLock (bool locked);
void updateUserSetting (const QString& name, const QStringList& value);
public slots: public slots:
void universalIdChanged (const CSMWorld::UniversalId& id); void universalIdChanged (const CSMWorld::UniversalId& id);
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void cloneRequest(); void cloneRequest();
void nextId(); void nextId();

@ -4,14 +4,13 @@
#include <QApplication> #include <QApplication>
#include <QUndoStack> #include <QUndoStack>
#include "../../model/settings/usersettings.hpp"
#include "../../model/world/columns.hpp" #include "../../model/world/columns.hpp"
CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values, CSVWorld::RecordStatusDelegate::RecordStatusDelegate(const ValueList& values,
const IconList & icons, const IconList & icons,
CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent) CSMWorld::CommandDispatcher *dispatcher, CSMDoc::Document& document, QObject *parent)
: DataDisplayDelegate (values, icons, dispatcher, document, : DataDisplayDelegate (values, icons, dispatcher, document,
"records", "status-format", "Records", "status-format",
parent) parent)
{} {}

@ -147,12 +147,6 @@ std::string CSVWorld::SceneSubView::getTitle() const
return mTitle; return mTitle;
} }
void CSVWorld::SceneSubView::updateUserSetting (const QString& name, const QStringList& value)
{
mScene->updateUserSetting (name, value);
CSVDoc::SubView::updateUserSetting (name, value);
}
void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id) void CSVWorld::SceneSubView::cellSelectionChanged (const CSMWorld::UniversalId& id)
{ {
setUniversalId(id); setUniversalId(id);

@ -59,8 +59,6 @@ namespace CSVWorld
virtual std::string getTitle() const; virtual std::string getTitle() const;
virtual void updateUserSetting (const QString& name, const QStringList& value);
private: private:
void makeConnections(CSVRender::PagedWorldspaceWidget* widget); void makeConnections(CSVRender::PagedWorldspaceWidget* widget);

@ -12,8 +12,7 @@
#include "../../model/world/universalid.hpp" #include "../../model/world/universalid.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit) CSVWorld::ScriptEdit::ChangeLock::ChangeLock (ScriptEdit& edit) : mEdit (edit)
{ {
@ -92,31 +91,24 @@ CSVWorld::ScriptEdit::ScriptEdit (const CSMDoc::Document& document, ScriptHighli
connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting())); connect (&mUpdateTimer, SIGNAL (timeout()), this, SLOT (updateHighlighting()));
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
connect (&userSettings, SIGNAL (userSettingUpdated(const QString &, const QStringList &)), this, SLOT (settingChanged (const CSMPrefs::Setting *)));
this, SLOT (updateUserSetting (const QString &, const QStringList &))); {
ChangeLock lock (*this);
CSMPrefs::get()["Scripts"].update();
}
mUpdateTimer.setSingleShot (true); mUpdateTimer.setSingleShot (true);
// TODO: provide a font selector dialogue // TODO: provide a font selector dialogue
mMonoFont.setStyleHint(QFont::TypeWriter); mMonoFont.setStyleHint(QFont::TypeWriter);
if (userSettings.setting("script-editor/mono-font", "true") == "true")
setFont(mMonoFont);
mLineNumberArea = new LineNumberArea(this); mLineNumberArea = new LineNumberArea(this);
updateLineNumberAreaWidth(0); updateLineNumberAreaWidth(0);
connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
updateHighlighting();
showLineNum(userSettings.settingValue("script-editor/show-linenum") == "true");
}
void CSVWorld::ScriptEdit::updateUserSetting (const QString &name, const QStringList &list)
{
if (mHighlighter->updateUserSetting (name, list))
updateHighlighting();
} }
void CSVWorld::ScriptEdit::showLineNum(bool show) void CSVWorld::ScriptEdit::showLineNum(bool show)
@ -202,6 +194,16 @@ bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const
return !(string.contains(mWhiteListQoutes)); return !(string.contains(mWhiteListQoutes));
} }
void CSVWorld::ScriptEdit::settingChanged (const CSMPrefs::Setting *setting)
{
if (mHighlighter->settingChanged (setting))
updateHighlighting();
else if (*setting=="Scripts/mono-font")
setFont (setting->isTrue() ? mMonoFont : mDefaultFont);
else if (*setting=="Scripts/show-linenum")
showLineNum (setting->isTrue());
}
void CSVWorld::ScriptEdit::idListChanged() void CSVWorld::ScriptEdit::idListChanged()
{ {
mHighlighter->invalidateIds(); mHighlighter->invalidateIds();

@ -91,6 +91,8 @@ namespace CSVWorld
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void idListChanged(); void idListChanged();
void updateHighlighting(); void updateHighlighting();
@ -98,10 +100,6 @@ namespace CSVWorld
void updateLineNumberAreaWidth(int newBlockCount); void updateLineNumberAreaWidth(int newBlockCount);
void updateLineNumberArea(const QRect &, int); void updateLineNumberArea(const QRect &, int);
public slots:
void updateUserSetting (const QString &name, const QStringList &list);
}; };
class LineNumberArea : public QWidget class LineNumberArea : public QWidget

@ -9,7 +9,8 @@
#include <components/compiler/extensions0.hpp> #include <components/compiler/extensions0.hpp>
#include "../../model/doc/document.hpp" #include "../../model/doc/document.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../../model/prefs/state.hpp"
void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type)
{ {
@ -57,7 +58,7 @@ void CSVWorld::ScriptErrorTable::addMessage (const std::string& message,
setItem (row, 2, messageItem); setItem (row, 2, messageItem);
} }
void CSVWorld::ScriptErrorTable::setWarningsMode (const QString& value) void CSVWorld::ScriptErrorTable::setWarningsMode (const std::string& value)
{ {
if (value=="Ignore") if (value=="Ignore")
Compiler::ErrorHandler::setWarningsMode (0); Compiler::ErrorHandler::setWarningsMode (0);
@ -91,17 +92,13 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document,
Compiler::registerExtensions (mExtensions); Compiler::registerExtensions (mExtensions);
mContext.setExtensions (&mExtensions); mContext.setExtensions (&mExtensions);
setWarningsMode (CSMSettings::UserSettings::instance().settingValue ("script-editor/warnings")); connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
CSMPrefs::get()["Scripts"].update();
connect (this, SIGNAL (cellClicked (int, int)), this, SLOT (cellClicked (int, int))); connect (this, SIGNAL (cellClicked (int, int)), this, SLOT (cellClicked (int, int)));
} }
void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const QStringList& value)
{
if (name=="script-editor/warnings" && !value.isEmpty())
setWarningsMode (value.at (0));
}
void CSVWorld::ScriptErrorTable::update (const std::string& source) void CSVWorld::ScriptErrorTable::update (const std::string& source)
{ {
clear(); clear();
@ -136,6 +133,12 @@ bool CSVWorld::ScriptErrorTable::clearLocals (const std::string& script)
return mContext.clearLocals (script); return mContext.clearLocals (script);
} }
void CSVWorld::ScriptErrorTable::settingChanged (const CSMPrefs::Setting *setting)
{
if (*setting=="Scripts/warnings")
setWarningsMode (setting->toString());
}
void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) void CSVWorld::ScriptErrorTable::cellClicked (int row, int column)
{ {
if (item (row, 1)) if (item (row, 1))

@ -14,6 +14,11 @@ namespace CSMDoc
class Document; class Document;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSVWorld namespace CSVWorld
{ {
class ScriptErrorTable : public QTableWidget, private Compiler::ErrorHandler class ScriptErrorTable : public QTableWidget, private Compiler::ErrorHandler
@ -32,14 +37,12 @@ namespace CSVWorld
void addMessage (const std::string& message, CSMDoc::Message::Severity severity, void addMessage (const std::string& message, CSMDoc::Message::Severity severity,
int line = -1, int column = -1); int line = -1, int column = -1);
void setWarningsMode (const QString& value); void setWarningsMode (const std::string& value);
public: public:
ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0); ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0);
void updateUserSetting (const QString& name, const QStringList& value);
void update (const std::string& source); void update (const std::string& source);
void clear(); void clear();
@ -51,6 +54,8 @@ namespace CSVWorld
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void cellClicked (int row, int column); void cellClicked (int row, int column);
signals: signals:

@ -5,7 +5,8 @@
#include <components/compiler/scanner.hpp> #include <components/compiler/scanner.hpp>
#include <components/compiler/extensions0.hpp> #include <components/compiler/extensions0.hpp>
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/setting.hpp"
#include "../../model/prefs/category.hpp"
bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc, bool CSVWorld::ScriptHighlighter::parseInt (int value, const Compiler::TokenLoc& loc,
Compiler::Scanner& scanner) Compiler::Scanner& scanner)
@ -79,79 +80,12 @@ CSVWorld::ScriptHighlighter::ScriptHighlighter (const CSMWorld::Data& data, Mode
: QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data), : QSyntaxHighlighter (parent), Compiler::Parser (mErrorHandler, mContext), mContext (data),
mMode (mode) mMode (mode)
{ {
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance(); QColor color ("black");
QTextCharFormat format;
format.setForeground (color);
QColor color = QColor(); for (int i=0; i<=Type_Id; ++i)
mScheme.insert (std::make_pair (static_cast<Type> (i), format));
{
color.setNamedColor(userSettings.setting("script-editor/colour-int", "Dark magenta"));
if (!color.isValid())
color = QColor(Qt::darkMagenta);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Int, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-float", "Magenta"));
if (!color.isValid())
color = QColor(Qt::magenta);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Float, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-name", "Gray"));
if (!color.isValid())
color = QColor(Qt::gray);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Name, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-keyword", "Red"));
if (!color.isValid())
color = QColor(Qt::red);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Keyword, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-special", "Dark yellow"));
if (!color.isValid())
color = QColor(Qt::darkYellow);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Special, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-comment", "Green"));
if (!color.isValid())
color = QColor(Qt::green);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Comment, format));
}
{
color.setNamedColor(userSettings.setting ("script-editor/colour-id", "Blue"));
if (!color.isValid())
color = QColor(Qt::blue);
QTextCharFormat format;
format.setForeground (color);
mScheme.insert (std::make_pair (Type_Id, format));
}
// configure compiler // configure compiler
Compiler::registerExtensions (mExtensions); Compiler::registerExtensions (mExtensions);
@ -176,85 +110,26 @@ void CSVWorld::ScriptHighlighter::invalidateIds()
mContext.invalidateIds(); mContext.invalidateIds();
} }
bool CSVWorld::ScriptHighlighter::updateUserSetting (const QString &name, const QStringList &list) bool CSVWorld::ScriptHighlighter::settingChanged (const CSMPrefs::Setting *setting)
{ {
if (list.empty()) if (setting->getParent()->getKey()=="Scripts")
return false;
QColor color = QColor();
if (name == "script-editor/colour-int")
{ {
color.setNamedColor(list.at(0)); static const char *const colours[Type_Id+2] =
if (!color.isValid()) {
return false; "colour-int", "colour-float", "colour-name", "colour-keyword",
"colour-special", "colour-comment", "colour-id",
QTextCharFormat format; 0
format.setForeground (color); };
mScheme[Type_Int] = format;
for (int i=0; colours[i]; ++i)
if (setting->getKey()==colours[i])
{
QTextCharFormat format;
format.setForeground (setting->toColor());
mScheme[static_cast<Type> (i)] = format;
return true;
}
} }
else if (name == "script-editor/colour-float")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format;
format.setForeground (color);
mScheme[Type_Float] = format;
}
else if (name == "script-editor/colour-name")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format;
format.setForeground (color);
mScheme[Type_Name] = format;
}
else if (name == "script-editor/colour-keyword")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format; return false;
format.setForeground (color);
mScheme[Type_Keyword] = format;
}
else if (name == "script-editor/colour-special")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format;
format.setForeground (color);
mScheme[Type_Special] = format;
}
else if (name == "script-editor/colour-comment")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format;
format.setForeground (color);
mScheme[Type_Comment] = format;
}
else if (name == "script-editor/colour-id")
{
color.setNamedColor(list.at(0));
if (!color.isValid())
return false;
QTextCharFormat format;
format.setForeground (color);
mScheme[Type_Id] = format;
}
else
return false;
return true;
} }

@ -11,6 +11,11 @@
#include "../../model/world/scriptcontext.hpp" #include "../../model/world/scriptcontext.hpp"
namespace CSMPrefs
{
class Setting;
}
namespace CSVWorld namespace CSVWorld
{ {
class ScriptHighlighter : public QSyntaxHighlighter, private Compiler::Parser class ScriptHighlighter : public QSyntaxHighlighter, private Compiler::Parser
@ -19,13 +24,13 @@ namespace CSVWorld
enum Type enum Type
{ {
Type_Int, Type_Int = 0,
Type_Float, Type_Float = 1,
Type_Name, Type_Name = 2,
Type_Keyword, Type_Keyword = 3,
Type_Special, Type_Special = 4,
Type_Comment, Type_Comment = 5,
Type_Id Type_Id = 6
}; };
enum Mode enum Mode
@ -88,7 +93,7 @@ namespace CSVWorld
void invalidateIds(); void invalidateIds();
bool updateUserSetting (const QString &name, const QStringList &list); bool settingChanged (const CSMPrefs::Setting *setting);
}; };
} }

@ -13,7 +13,7 @@
#include "../../model/world/columnbase.hpp" #include "../../model/world/columnbase.hpp"
#include "../../model/world/commands.hpp" #include "../../model/world/commands.hpp"
#include "../../model/world/idtable.hpp" #include "../../model/world/idtable.hpp"
#include "../../model/settings/usersettings.hpp" #include "../../model/prefs/state.hpp"
#include "scriptedit.hpp" #include "scriptedit.hpp"
#include "recordbuttonbar.hpp" #include "recordbuttonbar.hpp"
@ -39,8 +39,7 @@ void CSVWorld::ScriptSubView::addButtonBar()
void CSVWorld::ScriptSubView::recompile() void CSVWorld::ScriptSubView::recompile()
{ {
if (!mCompileDelay->isActive() && !isDeleted()) if (!mCompileDelay->isActive() && !isDeleted())
mCompileDelay->start ( mCompileDelay->start (CSMPrefs::get()["Scripts"]["compile-delay"].toInt());
CSMSettings::UserSettings::instance().setting ("script-editor/compile-delay").toInt());
} }
bool CSVWorld::ScriptSubView::isDeleted() const bool CSVWorld::ScriptSubView::isDeleted() const
@ -89,7 +88,7 @@ void CSVWorld::ScriptSubView::adjustSplitter()
CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document)
: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0), : SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0),
mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())),
mErrorHeight (CSMSettings::UserSettings::instance().setting ("script-editor/error-height").toInt()) mErrorHeight (CSMPrefs::get()["Scripts"]["error-height"].toInt())
{ {
std::vector<std::string> selection (1, id.getId()); std::vector<std::string> selection (1, id.getId());
mCommandDispatcher.setSelection (selection); mCommandDispatcher.setSelection (selection);
@ -126,9 +125,6 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
// bottom box and buttons // bottom box and buttons
mBottom = new TableBottomBox (CreatorFactory<GenericCreator>(), document, id, this); mBottom = new TableBottomBox (CreatorFactory<GenericCreator>(), document, id, this);
if (CSMSettings::UserSettings::instance().setting ("script-editor/toolbar", QString("true")) == "true")
addButtonBar();
connect (mBottom, SIGNAL (requestFocus (const std::string&)), connect (mBottom, SIGNAL (requestFocus (const std::string&)),
this, SLOT (switchToId (const std::string&))); this, SLOT (switchToId (const std::string&)));
@ -156,55 +152,40 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc:
connect (mCompileDelay, SIGNAL (timeout()), this, SLOT (updateRequest())); connect (mCompileDelay, SIGNAL (timeout()), this, SLOT (updateRequest()));
updateDeletedState(); updateDeletedState();
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
CSMPrefs::get()["Scripts"].update();
} }
void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) void CSVWorld::ScriptSubView::setStatusBar (bool show)
{ {
if (name == "script-editor/show-linenum") mBottom->setStatusBar (show);
{ }
std::string showLinenum = value.at(0).toUtf8().constData();
mEditor->showLineNum(showLinenum == "true"); void CSVWorld::ScriptSubView::settingChanged (const CSMPrefs::Setting *setting)
mBottom->setVisible(showLinenum == "true"); {
} if (*setting=="Scripts/toolbar")
else if (name == "script-editor/mono-font")
{
mEditor->setMonoFont (value.at(0)==QString ("true"));
}
else if (name=="script-editor/toolbar")
{ {
if (value.at(0)==QString ("true")) if (setting->isTrue())
{ {
addButtonBar(); addButtonBar();
} }
else else if (mButtons)
{ {
if (mButtons) mLayout.removeWidget (mButtons);
{ delete mButtons;
mLayout.removeWidget (mButtons); mButtons = 0;
delete mButtons;
mButtons = 0;
}
} }
} }
else if (name=="script-editor/compile-delay") else if (*setting=="Scripts/compile-delay")
{ {
mCompileDelay->setInterval (value.at (0).toInt()); mCompileDelay->setInterval (setting->toInt());
} }
else if (*setting=="Scripts/warnings")
if (mButtons)
mButtons->updateUserSetting (name, value);
mErrors->updateUserSetting (name, value);
if (name=="script-editor/warnings")
recompile(); recompile();
} }
void CSVWorld::ScriptSubView::setStatusBar (bool show)
{
mBottom->setStatusBar (show);
}
void CSVWorld::ScriptSubView::updateStatusBar () void CSVWorld::ScriptSubView::updateStatusBar ()
{ {
mBottom->positionChanged (mEditor->textCursor().blockNumber() + 1, mBottom->positionChanged (mEditor->textCursor().blockNumber() + 1,

@ -23,6 +23,11 @@ namespace CSMWorld
class IdTable; class IdTable;
} }
namespace CSMPrefs
{
class Setting;
}
namespace CSVWorld namespace CSVWorld
{ {
class ScriptEdit; class ScriptEdit;
@ -69,8 +74,6 @@ namespace CSVWorld
virtual void useHint (const std::string& hint); virtual void useHint (const std::string& hint);
virtual void updateUserSetting (const QString& name, const QStringList& value);
virtual void setStatusBar (bool show); virtual void setStatusBar (bool show);
public slots: public slots:
@ -83,6 +86,8 @@ namespace CSVWorld
private slots: private slots:
void settingChanged (const CSMPrefs::Setting *setting);
void updateStatusBar(); void updateStatusBar();
void switchToRow (int row); void switchToRow (int row);

@ -23,7 +23,8 @@
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/tablemimedata.hpp" #include "../../model/world/tablemimedata.hpp"
#include "../../model/world/commanddispatcher.hpp" #include "../../model/world/commanddispatcher.hpp"
#include "../../model/settings/usersettings.hpp"
#include "../../model/prefs/state.hpp"
#include "recordstatusdelegate.hpp" #include "recordstatusdelegate.hpp"
#include "tableeditidaction.hpp" #include "tableeditidaction.hpp"
@ -232,24 +233,6 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
: DragRecordTable(document), mCreateAction (0), : DragRecordTable(document), mCreateAction (0),
mCloneAction(0),mRecordStatusDisplay (0) mCloneAction(0),mRecordStatusDisplay (0)
{ {
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance();
QString jumpSetting = settings.settingValue ("table-input/jump-to-added");
if (jumpSetting.isEmpty() || jumpSetting == "Jump and Select") // default
{
mJumpToAddedRecord = true;
mUnselectAfterJump = false;
}
else if(jumpSetting == "Jump Only")
{
mJumpToAddedRecord = true;
mUnselectAfterJump = true;
}
else
{
mJumpToAddedRecord = false;
mUnselectAfterJump = false;
}
mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id)); mModel = &dynamic_cast<CSMWorld::IdTableBase&> (*mDocument.getData().getTableModel (id));
bool isInfoTable = id.getType() == CSMWorld::UniversalId::Type_TopicInfos || bool isInfoTable = id.getType() == CSMWorld::UniversalId::Type_TopicInfos ||
@ -375,6 +358,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id,
mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_EditRecord)); mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier, Action_EditRecord));
mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_View)); mDoubleClickActions.insert (std::make_pair (Qt::ControlModifier, Action_View));
mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier | Qt::ControlModifier, Action_EditRecordAndClose)); mDoubleClickActions.insert (std::make_pair (Qt::ShiftModifier | Qt::ControlModifier, Action_EditRecordAndClose));
connect (&CSMPrefs::State::get(), SIGNAL (settingChanged (const CSMPrefs::Setting *)),
this, SLOT (settingChanged (const CSMPrefs::Setting *)));
CSMPrefs::get()["ID Tables"].update();
} }
void CSVWorld::Table::setEditLock (bool locked) void CSVWorld::Table::setEditLock (bool locked)
@ -548,9 +535,7 @@ void CSVWorld::Table::previewRecord()
void CSVWorld::Table::executeExtendedDelete() void CSVWorld::Table::executeExtendedDelete()
{ {
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); if (CSMPrefs::get()["ID Tables"]["extended-config"].isTrue())
QString configSetting = settings.settingValue ("table-input/extended-config");
if (configSetting == "true")
{ {
emit extendedDeleteConfigRequest(getSelectedIds()); emit extendedDeleteConfigRequest(getSelectedIds());
} }
@ -562,9 +547,7 @@ void CSVWorld::Table::executeExtendedDelete()
void CSVWorld::Table::executeExtendedRevert() void CSVWorld::Table::executeExtendedRevert()
{ {
CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); if (CSMPrefs::get()["ID Tables"]["extended-config"].isTrue())
QString configSetting = settings.settingValue ("table-input/extended-config");
if (configSetting == "true")
{ {
emit extendedRevertConfigRequest(getSelectedIds()); emit extendedRevertConfigRequest(getSelectedIds());
} }
@ -574,16 +557,16 @@ void CSVWorld::Table::executeExtendedRevert()
} }
} }
void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList &list) void CSVWorld::Table::settingChanged (const CSMPrefs::Setting *setting)
{ {
if (name=="table-input/jump-to-added") if (*setting=="ID Tables/jump-to-added")
{ {
if(list.isEmpty() || list.at(0) == "Jump and Select") // default if (setting->toString()=="Jump and Select")
{ {
mJumpToAddedRecord = true; mJumpToAddedRecord = true;
mUnselectAfterJump = false; mUnselectAfterJump = false;
} }
else if(list.at(0) == "Jump Only") else if (setting->toString()=="Jump Only")
{ {
mJumpToAddedRecord = true; mJumpToAddedRecord = true;
mUnselectAfterJump = true; mUnselectAfterJump = true;
@ -594,28 +577,23 @@ void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList
mUnselectAfterJump = false; mUnselectAfterJump = false;
} }
} }
else if (*setting=="Records/type-format" || *setting=="Records/status-format")
if (name=="records/type-format" || name=="records/status-format")
{ {
int columns = mModel->columnCount(); int columns = mModel->columnCount();
for (int i=0; i<columns; ++i) for (int i=0; i<columns; ++i)
if (QAbstractItemDelegate *delegate = itemDelegateForColumn (i)) if (QAbstractItemDelegate *delegate = itemDelegateForColumn (i))
{ {
dynamic_cast<CommandDelegate&> dynamic_cast<CommandDelegate&> (*delegate).settingChanged (setting);
(*delegate).updateUserSetting (name, list); emit dataChanged (mModel->index (0, i),
{ mModel->index (mModel->rowCount()-1, i));
emit dataChanged (mModel->index (0, i),
mModel->index (mModel->rowCount()-1, i));
}
} }
return;
} }
else if (setting->getParent()->getKey()=="ID Tables" &&
QString base ("table-input/double"); setting->getKey().substr (0, 6)=="double")
if (name.startsWith (base))
{ {
QString modifierString = name.mid (base.size()); std::string modifierString = setting->getKey().substr (6);
Qt::KeyboardModifiers modifiers = 0; Qt::KeyboardModifiers modifiers = 0;
if (modifierString=="-s") if (modifierString=="-s")
@ -627,7 +605,7 @@ void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList
DoubleClickAction action = Action_None; DoubleClickAction action = Action_None;
QString value = list.at (0); std::string value = setting->toString();
if (value=="Edit in Place") if (value=="Edit in Place")
action = Action_InPlaceEdit; action = Action_InPlaceEdit;
@ -645,8 +623,6 @@ void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList
action = Action_ViewAndClose; action = Action_ViewAndClose;
mDoubleClickActions[modifiers] = action; mDoubleClickActions[modifiers] = action;
return;
} }
} }

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save