Merge remote-tracking branch 'zini/master' into animations
commit
53d1c3939c
@ -0,0 +1,82 @@
|
|||||||
|
#include "settingcontainer.hpp"
|
||||||
|
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
CSMSettings::SettingContainer::SettingContainer(QObject *parent) :
|
||||||
|
QObject(parent), mValue (0), mValues (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SettingContainer::SettingContainer(const QString &value, QObject *parent) :
|
||||||
|
QObject(parent), mValue (new QString (value)), mValues (0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMSettings::SettingContainer::insert (const QString &value)
|
||||||
|
{
|
||||||
|
if (mValue)
|
||||||
|
{
|
||||||
|
mValues = new QStringList;
|
||||||
|
mValues->push_back (*mValue);
|
||||||
|
mValues->push_back (value);
|
||||||
|
|
||||||
|
delete mValue;
|
||||||
|
mValue = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete mValue;
|
||||||
|
mValue = new QString (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMSettings::SettingContainer::update (const QString &value, int index)
|
||||||
|
{
|
||||||
|
if (isEmpty())
|
||||||
|
mValue = new QString(value);
|
||||||
|
|
||||||
|
else if (mValue)
|
||||||
|
*mValue = value;
|
||||||
|
|
||||||
|
else if (mValues)
|
||||||
|
mValues->replace(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSMSettings::SettingContainer::getValue (int index) const
|
||||||
|
{
|
||||||
|
QString retVal("");
|
||||||
|
|
||||||
|
//if mValue is valid, it's a single-value property.
|
||||||
|
//ignore the index and return the value
|
||||||
|
if (mValue)
|
||||||
|
retVal = *mValue;
|
||||||
|
|
||||||
|
//otherwise, if it's a multivalued property
|
||||||
|
//return the appropriate value at the index
|
||||||
|
else if (mValues)
|
||||||
|
{
|
||||||
|
if (index == -1)
|
||||||
|
retVal = mValues->at(0);
|
||||||
|
|
||||||
|
else if (index < mValues->size())
|
||||||
|
retVal = mValues->at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSMSettings::SettingContainer::count () const
|
||||||
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
if (!isEmpty())
|
||||||
|
{
|
||||||
|
if (mValues)
|
||||||
|
retVal = mValues->size();
|
||||||
|
else
|
||||||
|
retVal = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef SETTINGCONTAINER_HPP
|
||||||
|
#define SETTINGCONTAINER_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class QStringList;
|
||||||
|
|
||||||
|
namespace CSMSettings
|
||||||
|
{
|
||||||
|
class SettingContainer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QString *mValue;
|
||||||
|
QStringList *mValues;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingContainer (QObject *parent = 0);
|
||||||
|
explicit SettingContainer (const QString &value, QObject *parent = 0);
|
||||||
|
|
||||||
|
virtual QString getName() const {return "";}
|
||||||
|
|
||||||
|
void insert (const QString &value);
|
||||||
|
void update (const QString &value, int index = 0);
|
||||||
|
|
||||||
|
QString getValue (int index = -1) const;
|
||||||
|
inline QStringList *getValues() const { return mValues; }
|
||||||
|
int count() const;
|
||||||
|
|
||||||
|
//test for empty container
|
||||||
|
//useful for default-constructed containers returned by QMap when invalid key is passed
|
||||||
|
inline bool isEmpty() const { return (!mValue && !mValues); }
|
||||||
|
inline bool isMultiValue() const { return (mValues); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // SETTINGCONTAINER_HPP
|
@ -0,0 +1,102 @@
|
|||||||
|
#include "settingsitem.hpp"
|
||||||
|
|
||||||
|
bool CSMSettings::SettingsItem::updateItem (const QStringList *values)
|
||||||
|
{
|
||||||
|
QStringList::ConstIterator it = values->begin();
|
||||||
|
|
||||||
|
//if the item is not multivalued,
|
||||||
|
//save the last value passed in the container
|
||||||
|
if (!mIsMultiValue)
|
||||||
|
{
|
||||||
|
it = values->end();
|
||||||
|
it--;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid = true;
|
||||||
|
QString value ("");
|
||||||
|
|
||||||
|
for (; it != values->end(); ++it)
|
||||||
|
{
|
||||||
|
value = *it;
|
||||||
|
isValid = validate(value);
|
||||||
|
|
||||||
|
//skip only the invalid values
|
||||||
|
if (!isValid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
insert(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMSettings::SettingsItem::updateItem (const QString &value)
|
||||||
|
{
|
||||||
|
//takes a value or a SettingsContainer and updates itself accordingly
|
||||||
|
//after validating the data against it's own definition
|
||||||
|
|
||||||
|
QString newValue = value;
|
||||||
|
|
||||||
|
if (!validate (newValue))
|
||||||
|
newValue = mDefaultValue;
|
||||||
|
|
||||||
|
bool success = (getValue() != newValue);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
if (mIsMultiValue)
|
||||||
|
insert (newValue);
|
||||||
|
else
|
||||||
|
update (newValue);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMSettings::SettingsItem::updateItem(int valueListIndex)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (mValueList)
|
||||||
|
{
|
||||||
|
if (mValueList->size() > valueListIndex)
|
||||||
|
success = updateItem (mValueList->at(valueListIndex));
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMSettings::SettingsItem::validate (const QString &value)
|
||||||
|
{
|
||||||
|
bool isValid = true;
|
||||||
|
|
||||||
|
//validation required only if a value list or min/max value pair has been provided
|
||||||
|
if (mValueList->size()>0)
|
||||||
|
{
|
||||||
|
for (QStringList::ConstIterator it = mValueList->begin(); it !=mValueList->end(); ++it)
|
||||||
|
{
|
||||||
|
isValid = ( value == *it);
|
||||||
|
|
||||||
|
if (isValid)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (mValuePair)
|
||||||
|
{
|
||||||
|
int numVal = value.toInt();
|
||||||
|
|
||||||
|
isValid = (numVal > mValuePair->left.toInt() && numVal < mValuePair->right.toInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMSettings::SettingsItem::setDefaultValue (const QString &value)
|
||||||
|
{
|
||||||
|
mDefaultValue = value;
|
||||||
|
update (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSMSettings::SettingsItem::getDefaultValue() const
|
||||||
|
{
|
||||||
|
return mDefaultValue;
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
#ifndef SETTINGSITEM_HPP
|
||||||
|
#define SETTINGSITEM_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include "support.hpp"
|
||||||
|
#include "settingcontainer.hpp"
|
||||||
|
|
||||||
|
namespace CSMSettings
|
||||||
|
{
|
||||||
|
class SettingsItem : public SettingContainer
|
||||||
|
{
|
||||||
|
QStringPair *mValuePair;
|
||||||
|
QStringList *mValueList;
|
||||||
|
bool mIsMultiValue;
|
||||||
|
QString mName;
|
||||||
|
QString mDefaultValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit SettingsItem(QString name, bool isMultiValue,
|
||||||
|
const QString& defaultValue, QObject *parent = 0)
|
||||||
|
: SettingContainer(defaultValue, parent),
|
||||||
|
mIsMultiValue (isMultiValue), mValueList (0),
|
||||||
|
mName (name), mValuePair (0), mDefaultValue (defaultValue)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool updateItem (const QStringList *values);
|
||||||
|
bool updateItem (const QString &value);
|
||||||
|
bool updateItem (int valueListIndex);
|
||||||
|
|
||||||
|
inline QStringList *getValueList() { return mValueList; }
|
||||||
|
inline void setValueList (QStringList *valueList) { mValueList = valueList; }
|
||||||
|
|
||||||
|
inline QStringPair *getValuePair() { return mValuePair; }
|
||||||
|
inline void setValuePair (QStringPair valuePair) { mValuePair = new QStringPair(valuePair); }
|
||||||
|
|
||||||
|
inline QString getName () const { return mName; }
|
||||||
|
inline bool isMultivalue () { return mIsMultiValue; }
|
||||||
|
|
||||||
|
void setDefaultValue (const QString &value);
|
||||||
|
QString getDefaultValue () const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool validate (const QString &value);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // SETTINGSITEM_HPP
|
||||||
|
|
@ -0,0 +1 @@
|
|||||||
|
#include "support.hpp"
|
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef MODEL_SUPPORT_HPP
|
||||||
|
#define MODEL_SUPPORT_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
class QLayout;
|
||||||
|
class QWidget;
|
||||||
|
class QListWidgetItem;
|
||||||
|
|
||||||
|
namespace CSMSettings
|
||||||
|
{
|
||||||
|
class SettingContainer;
|
||||||
|
|
||||||
|
typedef QList<SettingContainer *> SettingList;
|
||||||
|
typedef QMap<QString, SettingContainer *> SettingMap;
|
||||||
|
typedef QMap<QString, SettingMap *> SectionMap;
|
||||||
|
|
||||||
|
struct QStringPair
|
||||||
|
{
|
||||||
|
QStringPair(): left (""), right ("")
|
||||||
|
{}
|
||||||
|
|
||||||
|
QStringPair (const QString &leftValue, const QString &rightValue)
|
||||||
|
: left (leftValue), right(rightValue)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QStringPair (const QStringPair &pair)
|
||||||
|
: left (pair.left), right (pair.right)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QString left;
|
||||||
|
QString right;
|
||||||
|
|
||||||
|
bool isEmpty() const
|
||||||
|
{ return (left.isEmpty() && right.isEmpty()); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // MODEL_SUPPORT_HPP
|
@ -0,0 +1,137 @@
|
|||||||
|
#include "usersettings.hpp"
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QString>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QMap>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTextCodec>
|
||||||
|
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
|
||||||
|
#include "settingcontainer.hpp"
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
/**
|
||||||
|
* 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::UserSettings()
|
||||||
|
{
|
||||||
|
mUserSettingsInstance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::UserSettings::~UserSettings()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile *CSMSettings::UserSettings::openFile (const QString &filename)
|
||||||
|
{
|
||||||
|
QFile *file = new QFile(filename);
|
||||||
|
|
||||||
|
bool success = (file->open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) ;
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
// File cannot be opened or created
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(QObject::tr("Error writing OpenMW configuration file"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(QObject::tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
||||||
|
Please make sure you have the right permissions \
|
||||||
|
and try again.<br>").arg(file->fileName()));
|
||||||
|
msgBox.exec();
|
||||||
|
delete file;
|
||||||
|
file = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSMSettings::UserSettings::writeFile(QFile *file, QMap<QString, CSMSettings::SettingList *> &settings)
|
||||||
|
{
|
||||||
|
if (!file)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QTextStream stream(file);
|
||||||
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
QList<QString> keyList = settings.keys();
|
||||||
|
|
||||||
|
foreach (QString key, keyList)
|
||||||
|
{
|
||||||
|
SettingList *sectionSettings = settings[key];
|
||||||
|
|
||||||
|
stream << "[" << key << "]" << '\n';
|
||||||
|
|
||||||
|
foreach (SettingContainer *item, *sectionSettings)
|
||||||
|
stream << item->getName() << " = " << item->getValue() << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSMSettings::UserSettings::getSettings(QTextStream &stream, SectionMap §ions)
|
||||||
|
{
|
||||||
|
//looks for a square bracket, "'\\["
|
||||||
|
//that has one or more "not nothing" in it, "([^]]+)"
|
||||||
|
//and is closed with a square bracket, "\\]"
|
||||||
|
|
||||||
|
QRegExp sectionRe("^\\[([^]]+)\\]");
|
||||||
|
|
||||||
|
//Find any character(s) that is/are not equal sign(s), "[^=]+"
|
||||||
|
//followed by an optional whitespace, an equal sign, and another optional whirespace, "\\s*=\\s*"
|
||||||
|
//and one or more periods, "(.+)"
|
||||||
|
|
||||||
|
QRegExp keyRe("^([^=]+)\\s*=\\s*(.+)$");
|
||||||
|
|
||||||
|
CSMSettings::SettingMap *settings = 0;
|
||||||
|
QString section = "none";
|
||||||
|
|
||||||
|
while (!stream.atEnd())
|
||||||
|
{
|
||||||
|
QString line = stream.readLine().simplified();
|
||||||
|
|
||||||
|
if (line.isEmpty() || line.startsWith("#"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//if a section is found, push it onto a new QStringList
|
||||||
|
//and push the QStringList onto
|
||||||
|
if (sectionRe.exactMatch(line))
|
||||||
|
{
|
||||||
|
//add the previous section's settings to the member map
|
||||||
|
if (settings)
|
||||||
|
sections.insert(section, settings);
|
||||||
|
|
||||||
|
//save new section and create a new list
|
||||||
|
section = sectionRe.cap(1);
|
||||||
|
settings = new SettingMap;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyRe.indexIn(line) != -1)
|
||||||
|
{
|
||||||
|
SettingContainer *sc = new SettingContainer (keyRe.cap(2).simplified());
|
||||||
|
(*settings)[keyRe.cap(1).simplified()] = sc;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
sections.insert(section, settings);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
#ifndef USERSETTINGS_HPP
|
||||||
|
#define USERSETTINGS_HPP
|
||||||
|
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QMap>
|
||||||
|
|
||||||
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
|
#include "support.hpp"
|
||||||
|
|
||||||
|
namespace Files { typedef std::vector<boost::filesystem::path> PathContainer;
|
||||||
|
struct ConfigurationManager;}
|
||||||
|
|
||||||
|
class QFile;
|
||||||
|
|
||||||
|
namespace CSMSettings {
|
||||||
|
|
||||||
|
struct UserSettings: public QObject
|
||||||
|
{
|
||||||
|
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static UserSettings &instance()
|
||||||
|
{
|
||||||
|
static UserSettings instance;
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile *openFile (const QString &);
|
||||||
|
bool writeFile(QFile *file, QMap<QString, SettingList *> §ions);
|
||||||
|
void getSettings (QTextStream &stream, SectionMap &settings);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
UserSettings *mUserSettingsInstance;
|
||||||
|
UserSettings();
|
||||||
|
~UserSettings();
|
||||||
|
|
||||||
|
UserSettings (UserSettings const &); //not implemented
|
||||||
|
void operator= (UserSettings const &); //not implemented
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // USERSETTINGS_HPP
|
@ -0,0 +1,6 @@
|
|||||||
|
#include "ocspropertywidget.hpp"
|
||||||
|
|
||||||
|
OcsPropertyWidget::OcsPropertyWidget(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef OCSPROPERTYWIDGET_HPP
|
||||||
|
#define OCSPROPERTYWIDGET_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class OcsPropertyWidget : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit OcsPropertyWidget(QObject *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // OCSPROPERTYWIDGET_HPP
|
@ -0,0 +1,112 @@
|
|||||||
|
#include "abstractblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::AbstractBlock::AbstractBlock(QWidget* parent)
|
||||||
|
: QObject (parent), mBox ( new GroupBox (parent) ), mWidgetParent (parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSVSettings::AbstractBlock::AbstractBlock(bool isVisible, QWidget* parent)
|
||||||
|
: QObject (parent), mBox ( new GroupBox (isVisible, parent)), mWidgetParent (parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
QLayout *CSVSettings::AbstractBlock::createLayout (Orientation direction,
|
||||||
|
bool isZeroMargin, QWidget* parent)
|
||||||
|
{
|
||||||
|
QLayout *layout = 0;
|
||||||
|
|
||||||
|
if (direction == Orient_Vertical)
|
||||||
|
layout = new QVBoxLayout (parent);
|
||||||
|
else
|
||||||
|
layout = new QHBoxLayout (parent);
|
||||||
|
|
||||||
|
if (isZeroMargin)
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGroupBox *CSVSettings::AbstractBlock::getGroupBox()
|
||||||
|
{
|
||||||
|
return mBox;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::AbstractWidget *CSVSettings::AbstractBlock::buildWidget (const QString& widgetName, WidgetDef &def,
|
||||||
|
QLayout *layout, bool isConnected) const
|
||||||
|
{
|
||||||
|
AbstractWidget *widg = 0;
|
||||||
|
|
||||||
|
switch (def.type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case Widget_RadioButton:
|
||||||
|
widg = createSettingWidget<QRadioButton> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_SpinBox:
|
||||||
|
widg = createSettingWidget<QSpinBox> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_CheckBox:
|
||||||
|
widg = createSettingWidget<QCheckBox> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_LineEdit:
|
||||||
|
widg = createSettingWidget<QLineEdit> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_ListBox:
|
||||||
|
widg = createSettingWidget<QListWidget> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_ComboBox:
|
||||||
|
widg = createSettingWidget<QComboBox> (def, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!mBox->layout())
|
||||||
|
mBox->setLayout(widg->getLayout());
|
||||||
|
|
||||||
|
widg->widget()->setObjectName(widgetName);
|
||||||
|
|
||||||
|
if (isConnected)
|
||||||
|
connect (widg, SIGNAL (signalUpdateItem (const QString &)), this, SLOT (slotUpdate (const QString &)));
|
||||||
|
connect (this, SIGNAL (signalUpdateWidget (const QString &)), widg, SLOT (slotUpdateWidget (const QString &) ));
|
||||||
|
|
||||||
|
return widg;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractBlock::setVisible (bool isVisible)
|
||||||
|
{
|
||||||
|
mBox->setBorderVisibility (isVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::AbstractBlock::isVisible () const
|
||||||
|
{
|
||||||
|
return mBox->borderVisibile();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *CSVSettings::AbstractBlock::getParent() const
|
||||||
|
{
|
||||||
|
return mWidgetParent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractBlock::slotUpdate (const QString &value)
|
||||||
|
{
|
||||||
|
slotUpdateSetting (objectName(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractBlock::slotSetEnabled(bool value)
|
||||||
|
{
|
||||||
|
mBox->setEnabled(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractBlock::slotUpdateSetting (const QString &settingName, const QString &settingValue)
|
||||||
|
{
|
||||||
|
bool doEmit = true;
|
||||||
|
updateBySignal (settingName, settingValue, doEmit);
|
||||||
|
|
||||||
|
if (doEmit)
|
||||||
|
emit signalUpdateSetting (settingName, settingValue);
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef ABSTRACTBLOCK_HPP
|
||||||
|
#define ABSTRACTBLOCK_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
#include "settingwidget.hpp"
|
||||||
|
#include "../../model/settings/settingsitem.hpp"
|
||||||
|
#include "groupbox.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
class AbstractBlock : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
typedef QMap<QString, CSMSettings::SettingsItem*> SettingsItemMap;
|
||||||
|
GroupBox *mBox;
|
||||||
|
QWidget *mWidgetParent;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit AbstractBlock (QWidget *parent = 0);
|
||||||
|
explicit AbstractBlock (bool isVisible, QWidget *parent = 0);
|
||||||
|
|
||||||
|
QGroupBox *getGroupBox();
|
||||||
|
void setVisible (bool isVisible);
|
||||||
|
bool isVisible() const;
|
||||||
|
|
||||||
|
virtual CSMSettings::SettingList *getSettings() = 0;
|
||||||
|
virtual bool updateSettings (const CSMSettings::SettingMap &settings) = 0;
|
||||||
|
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
||||||
|
{ return false; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
QLayout *createLayout (Orientation direction, bool isZeroMargin, QWidget* parent = 0);
|
||||||
|
AbstractWidget *buildWidget (const QString &widgetName, WidgetDef &wDef,
|
||||||
|
QLayout *layout = 0, bool isConnected = true) const;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
AbstractWidget *createSettingWidget (WidgetDef &wDef, QLayout *layout) const
|
||||||
|
{
|
||||||
|
return new SettingWidget<T> (wDef, layout, mBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *getParent() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
void slotSetEnabled (bool value);
|
||||||
|
void slotUpdateSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void slotUpdate (const QString &value);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
//signal to functions outside the settings tab widget
|
||||||
|
void signalUpdateSetting (const QString &propertyName, const QString &propertyValue);
|
||||||
|
void signalUpdateWidget (const QString & value);
|
||||||
|
|
||||||
|
//propertyName and propertyValue are for properties for which the updated setting acts as a proxy
|
||||||
|
void signalUpdateProxySetting (const QString &propertyName, const QString &propertyValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // ABSTRACTBLOCK_HPP
|
@ -0,0 +1,39 @@
|
|||||||
|
#include "abstractpage.hpp"
|
||||||
|
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QMargins>
|
||||||
|
|
||||||
|
CSVSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||||
|
QWidget(parent)
|
||||||
|
{
|
||||||
|
QWidget::setObjectName (pageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::AbstractPage::~AbstractPage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SettingList *CSVSettings::AbstractPage::getSettings()
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *settings = new CSMSettings::SettingList();
|
||||||
|
|
||||||
|
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *groupSettings = block->getSettings();
|
||||||
|
settings->append (*groupSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
#ifndef ABSTRACTPAGE_HPP
|
||||||
|
#define ABSTRACTPAGE_HPP
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QList>
|
||||||
|
#include <QLayout>
|
||||||
|
|
||||||
|
#include "abstractblock.hpp"
|
||||||
|
|
||||||
|
class SettingMap;
|
||||||
|
class SettingList;
|
||||||
|
|
||||||
|
namespace CSVSettings {
|
||||||
|
|
||||||
|
typedef QList<AbstractBlock *> AbstractBlockList;
|
||||||
|
|
||||||
|
class AbstractPage: public QWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
AbstractBlockList mAbstractBlocks;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AbstractPage(QWidget *parent = 0);
|
||||||
|
AbstractPage (const QString &pageName, QWidget* parent = 0);
|
||||||
|
|
||||||
|
~AbstractPage();
|
||||||
|
|
||||||
|
virtual void setupUi()=0;
|
||||||
|
|
||||||
|
virtual void initializeWidgets (const CSMSettings::SettingMap &settings) = 0;
|
||||||
|
|
||||||
|
CSMSettings::SettingList *getSettings();
|
||||||
|
|
||||||
|
void setObjectName();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
template <typename S, typename T>
|
||||||
|
AbstractBlock *buildBlock (T &def)
|
||||||
|
{
|
||||||
|
S *block = new S (this);
|
||||||
|
int ret = block->build (def);
|
||||||
|
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
QWidget::layout()->addWidget (block->getGroupBox());
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ABSTRACTPAGE_HPP
|
@ -0,0 +1,78 @@
|
|||||||
|
#include "abstractwidget.hpp"
|
||||||
|
|
||||||
|
#include <QLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::build(QWidget *widget, WidgetDef &def, bool noLabel)
|
||||||
|
{
|
||||||
|
if (!mLayout)
|
||||||
|
createLayout(def.orientation, true);
|
||||||
|
|
||||||
|
buildLabelAndWidget (widget, def, noLabel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel)
|
||||||
|
{
|
||||||
|
if (def.widgetWidth > -1)
|
||||||
|
widget->setFixedWidth (def.widgetWidth);
|
||||||
|
|
||||||
|
if (!(def.caption.isEmpty() || noLabel) )
|
||||||
|
{
|
||||||
|
QLabel *label = new QLabel (def.caption, dynamic_cast<QWidget*>(parent()));
|
||||||
|
label->setBuddy (widget);
|
||||||
|
mLayout->addWidget (label);
|
||||||
|
|
||||||
|
if (def.labelWidth > -1)
|
||||||
|
label->setFixedWidth(def.labelWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
mLayout->addWidget (widget);
|
||||||
|
mLayout->setAlignment (widget, getAlignment (def.widgetAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::createLayout
|
||||||
|
(Orientation direction, bool isZeroMargin)
|
||||||
|
{
|
||||||
|
if (direction == Orient_Vertical)
|
||||||
|
mLayout = new QVBoxLayout ();
|
||||||
|
else
|
||||||
|
mLayout = new QHBoxLayout ();
|
||||||
|
|
||||||
|
if (isZeroMargin)
|
||||||
|
mLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QFlags<Qt::AlignmentFlag> CSVSettings::AbstractWidget::getAlignment (CSVSettings::Alignment flag)
|
||||||
|
{
|
||||||
|
return QFlags<Qt::AlignmentFlag>(static_cast<int>(flag));
|
||||||
|
}
|
||||||
|
|
||||||
|
QLayout *CSVSettings::AbstractWidget::getLayout()
|
||||||
|
{
|
||||||
|
return mLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::slotUpdateWidget (const QString &value)
|
||||||
|
{
|
||||||
|
updateWidget (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::slotUpdateItem(const QString &value)
|
||||||
|
{
|
||||||
|
emit signalUpdateItem (value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::slotUpdateItem(bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
emit signalUpdateItem (widget()->objectName());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::slotUpdateItem(int value)
|
||||||
|
{
|
||||||
|
emit signalUpdateItem (QString::number(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::AbstractWidget::slotUpdateItem (QListWidgetItem* current, QListWidgetItem* previous)
|
||||||
|
{}
|
@ -0,0 +1,64 @@
|
|||||||
|
#ifndef ABSTRACTWIDGET_HPP
|
||||||
|
#define ABSTRACTWIDGET_HPP
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
#include "support.hpp"
|
||||||
|
|
||||||
|
class QLayout;
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
class AbstractWidget : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QLayout *mLayout;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit AbstractWidget (QLayout *layout = 0, QWidget* parent = 0)
|
||||||
|
: QObject (parent), mLayout (layout)
|
||||||
|
{}
|
||||||
|
|
||||||
|
//retrieve layout for insertion into itemblock
|
||||||
|
QLayout *getLayout();
|
||||||
|
|
||||||
|
//create the derived widget instance
|
||||||
|
void build (QWidget* widget, WidgetDef &def, bool noLabel = false);
|
||||||
|
|
||||||
|
//reference to the derived widget instance
|
||||||
|
virtual QWidget *widget() = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
//called by inbound signal for type-specific widget udpates
|
||||||
|
virtual void updateWidget (const QString &value) = 0;
|
||||||
|
|
||||||
|
//converts user-defined enum to Qt equivalents
|
||||||
|
QFlags<Qt::AlignmentFlag> getAlignment (Alignment flag);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
//widget initialization utilities
|
||||||
|
void createLayout (Orientation direction, bool isZeroMargin);
|
||||||
|
void buildLabelAndWidget (QWidget *widget, WidgetDef &def, bool noLabel);
|
||||||
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
//outbound update
|
||||||
|
void signalUpdateItem (const QString &value);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
|
||||||
|
//inbound updates
|
||||||
|
void slotUpdateWidget (const QString &value);
|
||||||
|
|
||||||
|
//Outbound updates from derived widget signal
|
||||||
|
void slotUpdateItem (const QString &value);
|
||||||
|
void slotUpdateItem (bool value);
|
||||||
|
void slotUpdateItem (int value);
|
||||||
|
void slotUpdateItem (QListWidgetItem* current, QListWidgetItem* previous);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // ABSTRACTWIDGET_HPP
|
@ -0,0 +1,58 @@
|
|||||||
|
#include "blankpage.hpp"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
#include <QPlastiqueStyle>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "toggleblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::BlankPage::BlankPage(QWidget *parent):
|
||||||
|
AbstractPage("Blank", parent)
|
||||||
|
{
|
||||||
|
initPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::BlankPage::BlankPage(const QString &title, QWidget *parent):
|
||||||
|
AbstractPage(title, parent)
|
||||||
|
{
|
||||||
|
initPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::BlankPage::initPage()
|
||||||
|
{
|
||||||
|
// Hacks to get the stylesheet look properly
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QPlastiqueStyle *style = new QPlastiqueStyle;
|
||||||
|
//profilesComboBox->setStyle(style);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setupUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::BlankPage::setupUi()
|
||||||
|
{
|
||||||
|
QGroupBox *pageBox = new QGroupBox(this);
|
||||||
|
QLayout* pageLayout = new QVBoxLayout();
|
||||||
|
|
||||||
|
setLayout(pageLayout);
|
||||||
|
pageLayout->addWidget(pageBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::BlankPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
//iterate each item in each blocks in this section
|
||||||
|
//validate the corresponding setting against the defined valuelist if any.
|
||||||
|
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||||
|
block->updateSettings (settings);
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef BLANKPAGE_HPP
|
||||||
|
#define BLANKPAGE_HPP
|
||||||
|
|
||||||
|
#include "abstractpage.hpp"
|
||||||
|
|
||||||
|
class QGroupBox;
|
||||||
|
|
||||||
|
namespace CSVSettings {
|
||||||
|
|
||||||
|
class UserSettings;
|
||||||
|
class AbstractBlock;
|
||||||
|
|
||||||
|
class BlankPage : public AbstractPage
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
BlankPage (QWidget *parent = 0);
|
||||||
|
BlankPage (const QString &title, QWidget *parent);
|
||||||
|
|
||||||
|
void setupUi();
|
||||||
|
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void initPage();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BLANKPAGE_HPP
|
@ -0,0 +1,120 @@
|
|||||||
|
#include "customblock.hpp"
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "itemblock.hpp"
|
||||||
|
#include "proxyblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::CustomBlock::CustomBlock (QWidget *parent) : AbstractBlock (parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSVSettings::CustomBlock::build(GroupBlockDefList &defList, GroupBlockDefList::iterator *it)
|
||||||
|
{
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
GroupBlockDefList::iterator defaultIt;
|
||||||
|
GroupBlockDefList::iterator listIt = defList.begin();
|
||||||
|
GroupBlockDefList::iterator proxyIt = defaultIt;
|
||||||
|
|
||||||
|
if (it)
|
||||||
|
listIt = *it;
|
||||||
|
|
||||||
|
ProxyBlock *proxyBlock = new ProxyBlock(getParent());
|
||||||
|
|
||||||
|
for (; listIt != defList.end(); ++listIt)
|
||||||
|
{
|
||||||
|
if (!(*listIt)->isProxy)
|
||||||
|
retVal = buildGroupBlock (*(*listIt));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mGroupList << proxyBlock;
|
||||||
|
proxyIt = listIt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (proxyIt != defaultIt)
|
||||||
|
retVal = buildProxyBlock (*(*proxyIt), proxyBlock);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBox *CSVSettings::CustomBlock::buildGroupBox (Orientation orientation)
|
||||||
|
{
|
||||||
|
GroupBox *box = new GroupBox (false, mBox);
|
||||||
|
QLayout *layout = createLayout (orientation, true, box);
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSVSettings::CustomBlock::buildGroupBlock(GroupBlockDef &def)
|
||||||
|
{
|
||||||
|
GroupBlock *block = new GroupBlock (getParent());
|
||||||
|
|
||||||
|
mGroupList << block;
|
||||||
|
|
||||||
|
connect (block, SIGNAL (signalUpdateSetting(const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateSetting (const QString &, const QString &)));
|
||||||
|
|
||||||
|
return block->build(def);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSVSettings::CustomBlock::buildProxyBlock(GroupBlockDef& def, ProxyBlock *block)
|
||||||
|
{
|
||||||
|
if (def.properties.size() != 1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int retVal = block->build(def);
|
||||||
|
|
||||||
|
if (retVal != 0)
|
||||||
|
return retVal;
|
||||||
|
|
||||||
|
foreach (QStringList *list, *(def.properties.at(0)->proxyList))
|
||||||
|
{
|
||||||
|
QString proxiedBlockName = list->at(0);
|
||||||
|
|
||||||
|
//iterate each group in the custom block, matching it to each proxied setting
|
||||||
|
//and connecting it appropriately
|
||||||
|
foreach (GroupBlock *groupBlock, mGroupList)
|
||||||
|
{
|
||||||
|
ItemBlock *proxiedBlock = groupBlock->getItemBlock (proxiedBlockName);
|
||||||
|
|
||||||
|
if (proxiedBlock)
|
||||||
|
{
|
||||||
|
block->addSetting(proxiedBlock, list);
|
||||||
|
|
||||||
|
//connect the proxy block's update signal to the custom block's slot
|
||||||
|
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateSetting (const QString &, const QString &)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SettingList *CSVSettings::CustomBlock::getSettings()
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *settings = new CSMSettings::SettingList();
|
||||||
|
|
||||||
|
foreach (GroupBlock *block, mGroupList)
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *groupSettings = block->getSettings();
|
||||||
|
|
||||||
|
if (groupSettings)
|
||||||
|
settings->append(*groupSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::CustomBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
foreach (GroupBlock *block, mGroupList)
|
||||||
|
{
|
||||||
|
bool success2 = block->updateSettings (settings);
|
||||||
|
success = success && success2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef CUSTOMBLOCK_HPP
|
||||||
|
#define CUSTOMBLOCK_HPP
|
||||||
|
|
||||||
|
#include "abstractblock.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
class ProxyBlock;
|
||||||
|
|
||||||
|
class CustomBlock : public AbstractBlock
|
||||||
|
{
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
GroupBlockList mGroupList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit CustomBlock (QWidget *parent = 0);
|
||||||
|
|
||||||
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
CSMSettings::SettingList *getSettings();
|
||||||
|
int build (GroupBlockDefList &defList, GroupBlockDefList::Iterator *it = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
GroupBox *buildGroupBox (Orientation orientation);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int buildGroupBlock(GroupBlockDef &def);
|
||||||
|
int buildProxyBlock(GroupBlockDef &def, ProxyBlock *block);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // CUSTOMBLOCK_HPP
|
@ -0,0 +1,163 @@
|
|||||||
|
#include "editorpage.hpp"
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QListView>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QDockWidget>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QGridLayout>
|
||||||
|
#include <QStyle>
|
||||||
|
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
#include <QPlastiqueStyle>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "toggleblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::EditorPage::EditorPage(QWidget *parent):
|
||||||
|
AbstractPage("Editor", parent)
|
||||||
|
{
|
||||||
|
// Hacks to get the stylesheet look properly
|
||||||
|
#ifdef Q_OS_MAC
|
||||||
|
QPlastiqueStyle *style = new QPlastiqueStyle;
|
||||||
|
//profilesComboBox->setStyle(style);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
setupUi();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::EditorPage::setupUi()
|
||||||
|
{
|
||||||
|
GroupBlockDef undoStack (QString("Undo Stack Size"));
|
||||||
|
GroupBlockDef topLevelWindowCount (QString("Maximum Top-Level Window Count"));
|
||||||
|
GroupBlockDef reuseSubwindow (QString("Reuse Subwindows"));
|
||||||
|
GroupBlockDef customWindowSize (QString ("Custom Window Size"));
|
||||||
|
GroupBlockDef definedWindowSize (QString ("Pre-Defined Window Size"));
|
||||||
|
GroupBlockDef windowSizeToggle (QString ("Window Size"));
|
||||||
|
CustomBlockDef windowSize (QString ("Window Size"));
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
//undo stack size property
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
SettingsItemDef *undoStackItem = new SettingsItemDef (undoStack.title, "32");
|
||||||
|
undoStack.properties << undoStackItem;
|
||||||
|
undoStackItem->minMax.left = "0";
|
||||||
|
undoStackItem->minMax.right = "64";
|
||||||
|
|
||||||
|
WidgetDef stackWidget (Widget_SpinBox);
|
||||||
|
stackWidget.minMax = &(undoStackItem->minMax);
|
||||||
|
stackWidget.widgetWidth = 50;
|
||||||
|
|
||||||
|
undoStackItem->widget = stackWidget;
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
//number of top level windows property
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
SettingsItemDef *topLevelItem = new SettingsItemDef (topLevelWindowCount.title, "100");
|
||||||
|
topLevelWindowCount.properties << topLevelItem;
|
||||||
|
topLevelItem->minMax.left = "1";
|
||||||
|
topLevelItem->minMax.right = "256";
|
||||||
|
|
||||||
|
WidgetDef topLvlWinWidget (Widget_SpinBox);
|
||||||
|
topLvlWinWidget.minMax = &(topLevelItem->minMax);
|
||||||
|
topLvlWinWidget.widgetWidth = 50;
|
||||||
|
|
||||||
|
topLevelItem->widget = topLvlWinWidget;
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
//reuse subwindows property
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
SettingsItemDef *reuseSubItem = new SettingsItemDef (reuseSubwindow.title, "Reuse Subwindows");
|
||||||
|
*(reuseSubItem->valueList) << "None" << "Top-Level" << "Document-Level";
|
||||||
|
|
||||||
|
WidgetDef reuseSubWidget (Widget_RadioButton);
|
||||||
|
reuseSubWidget.valueList = (reuseSubItem->valueList);
|
||||||
|
reuseSubWidget.widgetAlignment = Align_Left;
|
||||||
|
|
||||||
|
reuseSubwindow.properties << reuseSubItem;
|
||||||
|
reuseSubItem->widget = reuseSubWidget;
|
||||||
|
|
||||||
|
///////////////////////////////
|
||||||
|
//custom window size properties
|
||||||
|
///////////////////////////////
|
||||||
|
|
||||||
|
//custom width
|
||||||
|
SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640");
|
||||||
|
widthItem->widget = WidgetDef (Widget_LineEdit);
|
||||||
|
widthItem->widget.widgetWidth = 45;
|
||||||
|
|
||||||
|
//custom height
|
||||||
|
SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480");
|
||||||
|
heightItem->widget = WidgetDef (Widget_LineEdit);
|
||||||
|
heightItem->widget.widgetWidth = 45;
|
||||||
|
heightItem->widget.caption = "x";
|
||||||
|
|
||||||
|
customWindowSize.properties << widthItem << heightItem;
|
||||||
|
customWindowSize.widgetOrientation = Orient_Horizontal;
|
||||||
|
customWindowSize.isVisible = false;
|
||||||
|
|
||||||
|
|
||||||
|
//pre-defined
|
||||||
|
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||||
|
WidgetDef widthByHeightWidget = WidgetDef (Widget_ComboBox);
|
||||||
|
widthByHeightWidget.widgetWidth = 90;
|
||||||
|
*(widthByHeightItem->valueList) << "640x480" << "800x600" << "1024x768";
|
||||||
|
|
||||||
|
QStringList *widthProxy = new QStringList;
|
||||||
|
QStringList *heightProxy = new QStringList;
|
||||||
|
|
||||||
|
(*widthProxy) << "Window Width" << "640" << "800" << "1024";
|
||||||
|
(*heightProxy) << "Window Height" << "480" << "600" << "768";
|
||||||
|
|
||||||
|
*(widthByHeightItem->proxyList) << widthProxy << heightProxy;
|
||||||
|
|
||||||
|
widthByHeightItem->widget = widthByHeightWidget;
|
||||||
|
|
||||||
|
definedWindowSize.properties << widthByHeightItem;
|
||||||
|
definedWindowSize.isProxy = true;
|
||||||
|
definedWindowSize.isVisible = false;
|
||||||
|
|
||||||
|
// window size toggle
|
||||||
|
windowSizeToggle.captions << "Pre-Defined" << "Custom";
|
||||||
|
windowSizeToggle.widgetOrientation = Orient_Vertical;
|
||||||
|
windowSizeToggle.isVisible = false;
|
||||||
|
|
||||||
|
//define a widget for each group in the toggle
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
windowSizeToggle.widgets << new WidgetDef (Widget_RadioButton);
|
||||||
|
|
||||||
|
windowSizeToggle.widgets.at(0)->isDefault = false;
|
||||||
|
|
||||||
|
windowSize.blockDefList << &windowSizeToggle << &definedWindowSize << &customWindowSize;
|
||||||
|
windowSize.defaultValue = "Custom";
|
||||||
|
|
||||||
|
QGridLayout *pageLayout = new QGridLayout(this);
|
||||||
|
|
||||||
|
setLayout (pageLayout);
|
||||||
|
|
||||||
|
mAbstractBlocks << buildBlock<GroupBlock> (topLevelWindowCount)
|
||||||
|
<< buildBlock<GroupBlock> (reuseSubwindow)
|
||||||
|
<< buildBlock<ToggleBlock> (windowSize)
|
||||||
|
<< buildBlock<GroupBlock> (undoStack);
|
||||||
|
|
||||||
|
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||||
|
{
|
||||||
|
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||||
|
this, SIGNAL (signalUpdateEditorSetting (const QString &, const QString &)) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::EditorPage::initializeWidgets (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
//iterate each item in each blocks in this section
|
||||||
|
//validate the corresponding setting against the defined valuelist if any.
|
||||||
|
for (AbstractBlockList::Iterator it_block = mAbstractBlocks.begin();
|
||||||
|
it_block != mAbstractBlocks.end(); ++it_block)
|
||||||
|
(*it_block)->updateSettings (settings);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef EDITORPAGE_H
|
||||||
|
#define EDITORPAGE_H
|
||||||
|
|
||||||
|
#include "abstractpage.hpp"
|
||||||
|
|
||||||
|
class QGroupBox;
|
||||||
|
|
||||||
|
namespace CSVSettings {
|
||||||
|
|
||||||
|
class UserSettings;
|
||||||
|
class AbstractBlock;
|
||||||
|
|
||||||
|
class EditorPage : public AbstractPage
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
EditorPage(QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setupUi();
|
||||||
|
void initializeWidgets (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif //EDITORPAGE_H
|
@ -0,0 +1,108 @@
|
|||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "itemblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::GroupBlock::GroupBlock (QWidget* parent)
|
||||||
|
: AbstractBlock (parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CSVSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
||||||
|
: AbstractBlock (isVisible, parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSVSettings::GroupBlock::build (GroupBlockDef &def)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (def.properties.size() == 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int retVal = 0;
|
||||||
|
|
||||||
|
setVisible (def.isVisible);
|
||||||
|
|
||||||
|
mBox->setLayout(createLayout (def.widgetOrientation, true));
|
||||||
|
|
||||||
|
setObjectName (def.title);
|
||||||
|
mBox->setTitle (def.title);
|
||||||
|
|
||||||
|
foreach (SettingsItemDef *itemDef, def.properties)
|
||||||
|
{
|
||||||
|
ItemBlock *block = new ItemBlock (mBox);
|
||||||
|
|
||||||
|
if (block->build (*itemDef) < 0)
|
||||||
|
{
|
||||||
|
retVal = -2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mItemBlockList << block;
|
||||||
|
mBox->layout()->addWidget (block->getGroupBox());
|
||||||
|
|
||||||
|
connect (block, SIGNAL (signalUpdateSetting (const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateSetting (const QString &, const QString &) ));
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SettingList *CSVSettings::GroupBlock::getSettings()
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *settings = 0;
|
||||||
|
|
||||||
|
foreach (ItemBlock *block, mItemBlockList)
|
||||||
|
{
|
||||||
|
if (!settings)
|
||||||
|
settings = new CSMSettings::SettingList();
|
||||||
|
|
||||||
|
settings->append(*(block->getSettings ()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::ItemBlock *CSVSettings::GroupBlock::getItemBlock (const QString &name, ItemBlockList *blockList)
|
||||||
|
{
|
||||||
|
ItemBlock *retBlock = 0;
|
||||||
|
|
||||||
|
if (!blockList)
|
||||||
|
blockList = &mItemBlockList;
|
||||||
|
|
||||||
|
foreach (ItemBlock *block, *blockList)
|
||||||
|
{
|
||||||
|
if (block->objectName() == name)
|
||||||
|
{
|
||||||
|
retBlock = block;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::ItemBlock *CSVSettings::GroupBlock::getItemBlock (int index)
|
||||||
|
{
|
||||||
|
ItemBlock *retBlock = 0;
|
||||||
|
|
||||||
|
if (mItemBlockList.size() > index)
|
||||||
|
retBlock = mItemBlockList.at(index);
|
||||||
|
|
||||||
|
return retBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::GroupBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
//update all non-proxy settings
|
||||||
|
foreach (ItemBlock *block, mItemBlockList)
|
||||||
|
{
|
||||||
|
CSMSettings::SettingContainer *setting = settings[block->objectName()];
|
||||||
|
|
||||||
|
if (setting)
|
||||||
|
{
|
||||||
|
bool success2 = block->update (setting->getValue());
|
||||||
|
success = success && success2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef GROUPBLOCK_HPP
|
||||||
|
#define GROUPBLOCK_HPP
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include "abstractblock.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
class ItemBlock;
|
||||||
|
|
||||||
|
class GroupBlock : public AbstractBlock
|
||||||
|
{
|
||||||
|
ItemBlockList mItemBlockList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GroupBlock (QWidget* parent = 0);
|
||||||
|
GroupBlock (bool isVisible, QWidget *parent = 0);
|
||||||
|
|
||||||
|
int build (GroupBlockDef &def);
|
||||||
|
|
||||||
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
|
||||||
|
CSMSettings::SettingList *getSettings();
|
||||||
|
ItemBlock *getItemBlock (const QString &name, ItemBlockList *blockList = 0);
|
||||||
|
ItemBlock *getItemBlock (int index);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int buildLayout (GroupBlockDef &def);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // GROUPBLOCK_HPP
|
@ -0,0 +1,56 @@
|
|||||||
|
#include "groupbox.hpp"
|
||||||
|
|
||||||
|
const QString CSVSettings::GroupBox::INVISIBLE_BOX_STYLE =
|
||||||
|
QString::fromUtf8("QGroupBox { border: 0px; padding 0px; margin: 0px;}");
|
||||||
|
|
||||||
|
CSVSettings::GroupBox::GroupBox(QWidget *parent) :
|
||||||
|
QGroupBox (parent)
|
||||||
|
{
|
||||||
|
initBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBox::GroupBox (bool isVisible, QWidget *parent) :
|
||||||
|
QGroupBox (parent)
|
||||||
|
{
|
||||||
|
initBox(isVisible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::GroupBox::initBox(bool isVisible)
|
||||||
|
{
|
||||||
|
setFlat (true);
|
||||||
|
VISIBLE_BOX_STYLE = styleSheet();
|
||||||
|
|
||||||
|
if (!isVisible)
|
||||||
|
setStyleSheet (INVISIBLE_BOX_STYLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::GroupBox::borderVisibile() const
|
||||||
|
{
|
||||||
|
return (styleSheet() != INVISIBLE_BOX_STYLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::GroupBox::setTitle (const QString &title)
|
||||||
|
{
|
||||||
|
if (borderVisibile() )
|
||||||
|
{
|
||||||
|
QGroupBox::setTitle (title);
|
||||||
|
setMinimumWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::GroupBox::setBorderVisibility (bool value)
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
setStyleSheet(VISIBLE_BOX_STYLE);
|
||||||
|
else
|
||||||
|
setStyleSheet(INVISIBLE_BOX_STYLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::GroupBox::setMinimumWidth()
|
||||||
|
{
|
||||||
|
//set minimum width to accommodate title, if needed
|
||||||
|
//1.5 multiplier to account for bold title.
|
||||||
|
QFontMetrics fm (font());
|
||||||
|
int minWidth = fm.width(title());
|
||||||
|
QGroupBox::setMinimumWidth (minWidth * 1.5);
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef GROUPBOX_HPP
|
||||||
|
#define GROUPBOX_HPP
|
||||||
|
|
||||||
|
#include <QGroupBox>
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
class GroupBox : public QGroupBox
|
||||||
|
{
|
||||||
|
static const QString INVISIBLE_BOX_STYLE;
|
||||||
|
QString VISIBLE_BOX_STYLE; //not a const...
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit GroupBox (QWidget *parent = 0);
|
||||||
|
explicit GroupBox (bool isVisible, QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setTitle (const QString &title);
|
||||||
|
void setBorderVisibility (bool value);
|
||||||
|
bool borderVisibile() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setMinimumWidth();
|
||||||
|
void initBox(bool isVisible = true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // GROUPBOX_HPP
|
@ -0,0 +1,115 @@
|
|||||||
|
#include "itemblock.hpp"
|
||||||
|
|
||||||
|
#include <QFontMetrics>
|
||||||
|
|
||||||
|
CSVSettings::ItemBlock::ItemBlock (QWidget* parent)
|
||||||
|
: mSetting (0), AbstractBlock (false, parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int CSVSettings::ItemBlock::build(SettingsItemDef &iDef)
|
||||||
|
{
|
||||||
|
buildItemBlock (iDef);
|
||||||
|
buildItemBlockWidgets (iDef);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
||||||
|
{
|
||||||
|
WidgetDef wDef = iDef.widget;
|
||||||
|
QLayout *blockLayout = 0;
|
||||||
|
QString defaultValue = iDef.defaultValue;
|
||||||
|
|
||||||
|
switch (wDef.type)
|
||||||
|
{
|
||||||
|
|
||||||
|
case Widget_CheckBox:
|
||||||
|
case Widget_RadioButton:
|
||||||
|
|
||||||
|
foreach (QString item, *(iDef.valueList))
|
||||||
|
{
|
||||||
|
wDef.caption = item;
|
||||||
|
wDef.isDefault = (item == defaultValue);
|
||||||
|
|
||||||
|
blockLayout = buildWidget (item, wDef, blockLayout)->getLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Widget_ComboBox:
|
||||||
|
case Widget_ListBox:
|
||||||
|
|
||||||
|
//assign the item's value list to the widget's value list.
|
||||||
|
//pass through to default to finish widget construction.
|
||||||
|
if (!wDef.valueList)
|
||||||
|
wDef.valueList = iDef.valueList;
|
||||||
|
|
||||||
|
default:
|
||||||
|
//only one instance of this non-list widget type.
|
||||||
|
//Set it's value to the default value for the item and build the widget.
|
||||||
|
|
||||||
|
if (wDef.value.isEmpty())
|
||||||
|
wDef.value = iDef.defaultValue;
|
||||||
|
|
||||||
|
buildWidget (iDef.name, wDef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::ItemBlock::buildItemBlock (SettingsItemDef &iDef)
|
||||||
|
{
|
||||||
|
QString defaultValue = iDef.defaultValue;
|
||||||
|
|
||||||
|
setObjectName(iDef.name);
|
||||||
|
|
||||||
|
mSetting = new CSMSettings::SettingsItem (objectName(),
|
||||||
|
iDef.hasMultipleValues, iDef.defaultValue,
|
||||||
|
parent());
|
||||||
|
|
||||||
|
if (iDef.valueList)
|
||||||
|
mSetting->setValueList(iDef.valueList);
|
||||||
|
|
||||||
|
if (!iDef.minMax.isEmpty())
|
||||||
|
mSetting->setValuePair(iDef.minMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CSVSettings::ItemBlock::update (const QString &value)
|
||||||
|
{
|
||||||
|
bool success = updateItem (value);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
signalUpdateWidget (value);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CSVSettings::ItemBlock::updateItem (const QString &value)
|
||||||
|
{
|
||||||
|
return mSetting->updateItem(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CSVSettings::ItemBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||||
|
{
|
||||||
|
bool success = (mSetting->getValue() != value);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
success = updateItem(value);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SettingList *CSVSettings::ItemBlock::getSettings ()
|
||||||
|
{
|
||||||
|
CSMSettings::SettingList *list = new CSMSettings::SettingList();
|
||||||
|
list->push_back(mSetting);
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString CSVSettings::ItemBlock::getValue() const
|
||||||
|
{
|
||||||
|
return mSetting->getValue();
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef ITEMBLOCK_HPP
|
||||||
|
#define ITEMBLOCK_HPP
|
||||||
|
|
||||||
|
#include "abstractblock.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
class ItemBlock : public AbstractBlock
|
||||||
|
{
|
||||||
|
CSMSettings::SettingsItem *mSetting;
|
||||||
|
WidgetList mWidgetList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ItemBlock (QWidget* parent = 0);
|
||||||
|
|
||||||
|
bool updateSettings (const CSMSettings::SettingMap &settings) { return false; }
|
||||||
|
|
||||||
|
CSMSettings::SettingList *getSettings ();
|
||||||
|
QString getValue () const;
|
||||||
|
|
||||||
|
int getSettingCount();
|
||||||
|
bool update (const QString &value);
|
||||||
|
|
||||||
|
int build(SettingsItemDef &iDef);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void buildItemBlock (SettingsItemDef& iDef);
|
||||||
|
void buildItemBlockWidgets (SettingsItemDef& iDef);
|
||||||
|
bool updateItem (const QString &);
|
||||||
|
|
||||||
|
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ITEMBLOCK_HPP
|
@ -0,0 +1,149 @@
|
|||||||
|
#include "proxyblock.hpp"
|
||||||
|
#include "itemblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::ProxyBlock::ProxyBlock (QWidget *parent)
|
||||||
|
: GroupBlock (parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
int CSVSettings::ProxyBlock::build (GroupBlockDef &proxyDef)
|
||||||
|
{
|
||||||
|
//get the list of pre-defined values for the proxy
|
||||||
|
mValueList = proxyDef.properties.at(0)->valueList;
|
||||||
|
|
||||||
|
bool success = GroupBlock::build(proxyDef);
|
||||||
|
|
||||||
|
//connect the item block of the proxy setting to the proxy-update slot
|
||||||
|
connect (getItemBlock(0), SIGNAL (signalUpdateSetting(const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateProxySetting (const QString &, const QString &)));
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::ProxyBlock::addSetting (ItemBlock *settingBlock, QStringList *proxyList)
|
||||||
|
{
|
||||||
|
//connect the item block of the proxied seting to the generic update slot
|
||||||
|
connect (settingBlock, SIGNAL (signalUpdateSetting(const QString &, const QString &)),
|
||||||
|
this, SLOT (slotUpdateProxySetting(const QString &, const QString &)));
|
||||||
|
|
||||||
|
mProxiedItemBlockList << settingBlock;
|
||||||
|
mProxyList << proxyList;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::ProxyBlock::updateSettings (const CSMSettings::SettingMap &settings)
|
||||||
|
{
|
||||||
|
return updateByProxiedSettings(&settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::ProxyBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||||
|
{
|
||||||
|
doEmit = false;
|
||||||
|
return updateProxiedSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::ProxyBlock::slotUpdateProxySetting (const QString &name, const QString &value)
|
||||||
|
{
|
||||||
|
updateByProxiedSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::ProxyBlock::updateProxiedSettings()
|
||||||
|
{
|
||||||
|
foreach (ItemBlock *block, mProxiedItemBlockList)
|
||||||
|
{
|
||||||
|
QString value = getItemBlock(0)->getValue();
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
int i = 0;
|
||||||
|
for (; i < mValueList->size(); ++i)
|
||||||
|
{
|
||||||
|
success = (value == mValueList->at(i));
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
foreach (QStringList *list, mProxyList)
|
||||||
|
{
|
||||||
|
if ( list->at(0) == block->objectName())
|
||||||
|
block->update (list->at(++i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CSVSettings::ProxyBlock::updateByProxiedSettings(const CSMSettings::SettingMap *settings)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
int commonIndex = -1;
|
||||||
|
|
||||||
|
//update all proxy settings based on values from non-proxies
|
||||||
|
foreach (QStringList *list, mProxyList)
|
||||||
|
{
|
||||||
|
//Iterate each proxy item's proxied setting list, getting the current values
|
||||||
|
//Compare those value indices.
|
||||||
|
//If indices match, they correlate to one of the proxy's values in it's value list
|
||||||
|
|
||||||
|
//first value is always the name of the setting the proxy setting manages
|
||||||
|
QStringList::Iterator itProxyValue = list->begin();
|
||||||
|
QString proxiedSettingName = (*itProxyValue);
|
||||||
|
QString proxiedSettingValue = "";
|
||||||
|
itProxyValue++;
|
||||||
|
|
||||||
|
if (!settings)
|
||||||
|
{
|
||||||
|
//get the actual setting value
|
||||||
|
ItemBlock *block = getProxiedItemBlock (proxiedSettingName);
|
||||||
|
|
||||||
|
if (block)
|
||||||
|
proxiedSettingValue = block->getValue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
proxiedSettingValue = (*settings)[proxiedSettingName]->getValue();
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
//iterate each value in the proxy string list
|
||||||
|
for (; itProxyValue != (list)->end(); ++itProxyValue)
|
||||||
|
{
|
||||||
|
success = ((*itProxyValue) == proxiedSettingValue);
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
break;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//break if no match was found
|
||||||
|
if ( !success )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (commonIndex != -1)
|
||||||
|
success = (commonIndex == j);
|
||||||
|
else
|
||||||
|
commonIndex = j;
|
||||||
|
|
||||||
|
//break if indices were found, but mismatch
|
||||||
|
if (!success)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if successful, the proxied setting values match a pre-defined value in the
|
||||||
|
//proxy's value list. Set the proxy to that value index
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
ItemBlock *block = getItemBlock(0);
|
||||||
|
|
||||||
|
if (block)
|
||||||
|
block->update (mValueList->at(commonIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::ItemBlock *CSVSettings::ProxyBlock::getProxiedItemBlock (const QString &name)
|
||||||
|
{
|
||||||
|
return getItemBlock (name, &mProxiedItemBlockList);
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
#ifndef PROXYBLOCK_HPP
|
||||||
|
#define PROXYBLOCK_HPP
|
||||||
|
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
class ProxyBlock : public GroupBlock
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
//NOTE: mProxyItemBlockList and mProxyList
|
||||||
|
//should be combined into a value pair and stored in one list.
|
||||||
|
ItemBlockList mProxiedItemBlockList;
|
||||||
|
ProxyList mProxyList;
|
||||||
|
QStringList *mValueList;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit ProxyBlock (QWidget *parent = 0);
|
||||||
|
explicit ProxyBlock (ItemBlock *proxyItemBlock, QWidget *parent = 0);
|
||||||
|
|
||||||
|
void addSetting (ItemBlock* settingBlock, QStringList *proxyList);
|
||||||
|
int build (GroupBlockDef &def);
|
||||||
|
|
||||||
|
CSMSettings::SettingList *getSettings() { return 0; }
|
||||||
|
bool updateSettings (const CSMSettings::SettingMap &settings);
|
||||||
|
bool updateBySignal (const QString &name, const QString &value, bool &doEmit);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
ItemBlock *getProxiedItemBlock (const QString &name);
|
||||||
|
bool updateByProxiedSettings(const CSMSettings::SettingMap *settings = 0);
|
||||||
|
bool updateProxiedSettings();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
|
||||||
|
void slotUpdateProxySetting (const QString &name, const QString &value);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // PROXYBLOCK_HPP
|
@ -0,0 +1 @@
|
|||||||
|
#include "settingwidget.hpp"
|
@ -0,0 +1,208 @@
|
|||||||
|
#ifndef SETTINGWIDGET_HPP
|
||||||
|
#define SETTINGWIDGET_HPP
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QSpinBox>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QGroupBox>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include "abstractwidget.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
//VALID FOR RADIOBUTTON / CHECKBOX (or other toggle widget with it's own label)
|
||||||
|
template <typename T1>
|
||||||
|
class SettingWidget : public AbstractWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
T1 *mWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit SettingWidget (WidgetDef &def, QLayout *layout, QWidget* parent = 0)
|
||||||
|
: AbstractWidget (layout, parent), mWidget (new T1 (parent))
|
||||||
|
{
|
||||||
|
mWidget->setText(def.caption);
|
||||||
|
build (mWidget, def, true);
|
||||||
|
mWidget->setChecked(def.isDefault);
|
||||||
|
|
||||||
|
connect (mWidget, SIGNAL (toggled (bool)),
|
||||||
|
this, SLOT (slotUpdateItem (bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *widget() { return mWidget; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateWidget (const QString &value)
|
||||||
|
{
|
||||||
|
if ( value == mWidget->objectName() && !mWidget->isChecked() )
|
||||||
|
mWidget->setChecked (true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class SettingWidget <QSpinBox>: public AbstractWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
QSpinBox *mWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SettingWidget (WidgetDef &def, QLayout *layout, QWidget *parent = 0)
|
||||||
|
: AbstractWidget (layout, parent), mWidget (new QSpinBox (parent))
|
||||||
|
{
|
||||||
|
def.caption += tr(" (%1 to %2)").arg(def.minMax->left).arg(def.minMax->right);
|
||||||
|
|
||||||
|
mWidget->setMaximum (def.minMax->right.toInt());
|
||||||
|
mWidget->setMinimum (def.minMax->left.toInt());
|
||||||
|
mWidget->setValue (def.value.toInt());
|
||||||
|
|
||||||
|
build (mWidget, def);
|
||||||
|
|
||||||
|
connect (mWidget, SIGNAL (valueChanged (int)),
|
||||||
|
this, SLOT (slotUpdateItem (int)));
|
||||||
|
|
||||||
|
mWidget->setAlignment (getAlignment(def.valueAlignment));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *widget() { return mWidget; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateWidget (const QString &value)
|
||||||
|
{
|
||||||
|
int intVal = value.toInt();
|
||||||
|
|
||||||
|
if (intVal >= mWidget->minimum() && intVal <= mWidget->maximum() && intVal != mWidget->value())
|
||||||
|
mWidget->setValue (intVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class SettingWidget <QComboBox>: public CSVSettings::AbstractWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
QComboBox *mWidget;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit SettingWidget(WidgetDef &def, QLayout *layout, QWidget *parent = 0)
|
||||||
|
: AbstractWidget (layout, parent), mWidget (new QComboBox (parent))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
foreach (QString item, *(def.valueList))
|
||||||
|
{
|
||||||
|
mWidget->addItem (item);
|
||||||
|
|
||||||
|
if (item == def.value)
|
||||||
|
mWidget->setCurrentIndex(i);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
build (mWidget, def);
|
||||||
|
|
||||||
|
connect (mWidget, SIGNAL (currentIndexChanged (const QString &)),
|
||||||
|
this, SLOT (slotUpdateItem (const QString &)));
|
||||||
|
|
||||||
|
//center the combo box items
|
||||||
|
mWidget->setEditable (true);
|
||||||
|
mWidget->lineEdit()->setReadOnly (true);
|
||||||
|
mWidget->lineEdit()->setAlignment (getAlignment(def.valueAlignment));
|
||||||
|
|
||||||
|
QFlags<Qt::AlignmentFlag> alignment = mWidget->lineEdit()->alignment();
|
||||||
|
|
||||||
|
for (int j = 0; j < mWidget->count(); j++)
|
||||||
|
mWidget->setItemData (j, QVariant(alignment), Qt::TextAlignmentRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *widget() { return mWidget; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void updateWidget (const QString &value)
|
||||||
|
{
|
||||||
|
if (mWidget->currentText() != value)
|
||||||
|
mWidget->setCurrentIndex(mWidget->findText(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class SettingWidget <QLineEdit>: public CSVSettings::AbstractWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
QLineEdit *mWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit SettingWidget(WidgetDef &def, QLayout *layout, QWidget *parent = 0)
|
||||||
|
: AbstractWidget (layout, parent), mWidget (new QLineEdit (parent))
|
||||||
|
{
|
||||||
|
if (!def.inputMask.isEmpty())
|
||||||
|
mWidget->setInputMask (def.inputMask);
|
||||||
|
|
||||||
|
mWidget->setText (def.value);
|
||||||
|
|
||||||
|
build (mWidget, def);
|
||||||
|
|
||||||
|
connect (mWidget, SIGNAL (textChanged (const QString &)),
|
||||||
|
this, SLOT (slotUpdateItem (const QString &)));
|
||||||
|
|
||||||
|
mWidget->setAlignment (getAlignment(def.valueAlignment));
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *widget() { return mWidget; }
|
||||||
|
|
||||||
|
void updateWidget (const QString &value)
|
||||||
|
{
|
||||||
|
if (mWidget->text() != value)
|
||||||
|
mWidget->setText(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class SettingWidget <QListWidget>: public CSVSettings::AbstractWidget
|
||||||
|
{
|
||||||
|
|
||||||
|
QListWidget *mWidget;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
explicit SettingWidget(WidgetDef &def, QLayout *layout, QWidget *parent = 0 )
|
||||||
|
: AbstractWidget (layout, parent), mWidget (new QListWidget (parent))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
foreach (QString item, *(def.valueList))
|
||||||
|
{
|
||||||
|
mWidget->addItem (item);
|
||||||
|
|
||||||
|
if (item == def.value) {}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
build (mWidget, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *widget() { return mWidget; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateWidget (const QString &value) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // SETTINGWIDGET_HPP
|
@ -0,0 +1 @@
|
|||||||
|
#include "support.hpp"
|
@ -0,0 +1,144 @@
|
|||||||
|
#ifndef VIEW_SUPPORT_HPP
|
||||||
|
#define VIEW_SUPPORT_HPP
|
||||||
|
|
||||||
|
#include <QList>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "../../model/settings/support.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
struct WidgetDef;
|
||||||
|
class ItemBlock;
|
||||||
|
class GroupBlock;
|
||||||
|
struct GroupBlockDef;
|
||||||
|
|
||||||
|
typedef QList<GroupBlockDef *> GroupBlockDefList;
|
||||||
|
typedef QList<GroupBlock *> GroupBlockList;
|
||||||
|
typedef QList<ItemBlock *> ItemBlockList;
|
||||||
|
typedef QList<QStringList *> ProxyList;
|
||||||
|
typedef QList<WidgetDef *> WidgetList;
|
||||||
|
typedef QMap<QString, ItemBlock *> ItemBlockMap;
|
||||||
|
|
||||||
|
enum Orientation
|
||||||
|
{
|
||||||
|
Orient_Horizontal,
|
||||||
|
Orient_Vertical
|
||||||
|
};
|
||||||
|
|
||||||
|
enum WidgetType
|
||||||
|
{
|
||||||
|
Widget_CheckBox,
|
||||||
|
Widget_ComboBox,
|
||||||
|
Widget_LineEdit,
|
||||||
|
Widget_ListBox,
|
||||||
|
Widget_RadioButton,
|
||||||
|
Widget_SpinBox,
|
||||||
|
Widget_Undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Alignment
|
||||||
|
{
|
||||||
|
Align_Left = Qt::AlignLeft,
|
||||||
|
Align_Center = Qt::AlignHCenter,
|
||||||
|
Align_Right = Qt::AlignRight
|
||||||
|
};
|
||||||
|
|
||||||
|
//template for defining the widget of a property.
|
||||||
|
struct WidgetDef
|
||||||
|
{
|
||||||
|
WidgetType type; //type of widget providing input
|
||||||
|
int labelWidth; //width of caption label
|
||||||
|
int widgetWidth; //width of input widget
|
||||||
|
Orientation orientation; //label / widget orientation (horizontal / vertical)
|
||||||
|
QString inputMask; //input mask (line edit)
|
||||||
|
QString caption; //label caption. Leave empty for multiple items. See BlockDef::captionList
|
||||||
|
QString value; //widget value. Leave empty for multiple items. See BlockDef::valueList
|
||||||
|
CSMSettings::QStringPair *minMax; //Min/Max QString value pair. If empty, assigned to property item value pair.
|
||||||
|
QStringList *valueList; //value list for list widgets. If left empty, is assigned to property item value list during block build().
|
||||||
|
bool isDefault; //isDefault - determined at runtime.
|
||||||
|
Alignment valueAlignment; //left / center / right-justify text in widget
|
||||||
|
Alignment widgetAlignment; //left / center / right-justify widget in group box
|
||||||
|
|
||||||
|
|
||||||
|
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
||||||
|
orientation (Orient_Horizontal),
|
||||||
|
isDefault (true), valueAlignment (Align_Center),
|
||||||
|
widgetAlignment (Align_Right),
|
||||||
|
inputMask (""), value (""),
|
||||||
|
caption (""), valueList (0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
WidgetDef (WidgetType widgType)
|
||||||
|
: type (widgType), orientation (Orient_Horizontal),
|
||||||
|
caption (""), value (""), valueAlignment (Align_Center),
|
||||||
|
widgetAlignment (Align_Right),
|
||||||
|
labelWidth (-1), widgetWidth (-1),
|
||||||
|
valueList (0), isDefault (true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//Defines the attributes of the property as it is represented in the config file
|
||||||
|
//as well as the UI elements (group box and widget) that serve it.
|
||||||
|
//Only one widget may serve as the input widget for the property.
|
||||||
|
struct SettingsItemDef
|
||||||
|
{
|
||||||
|
QString name; //property name
|
||||||
|
QStringList *valueList; //list of valid values for the property.
|
||||||
|
//Used to populate option widget captions or list widget item lists (see WidgetDef::caption / value)
|
||||||
|
QString defaultValue;
|
||||||
|
bool hasMultipleValues;
|
||||||
|
CSMSettings::QStringPair minMax; //minimum / maximum value pair
|
||||||
|
WidgetDef widget; //definition of the input widget for this setting
|
||||||
|
Orientation orientation; //general orientation of the widget / label for this property
|
||||||
|
ProxyList *proxyList; //list of property and corresponding default values for proxy widget
|
||||||
|
|
||||||
|
SettingsItemDef() : name (""), defaultValue (""), orientation (Orient_Vertical), hasMultipleValues (false)
|
||||||
|
{}
|
||||||
|
|
||||||
|
SettingsItemDef (QString propName, QString propDefault, Orientation propOrient = Orient_Vertical)
|
||||||
|
: name (propName), defaultValue (propDefault), orientation (propOrient),
|
||||||
|
hasMultipleValues(false), valueList (new QStringList), proxyList ( new ProxyList)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Hierarchically, this is a "sub-section" of properties within a section, solely for UI organization.
|
||||||
|
//Does not correlate to config file structure.
|
||||||
|
struct GroupBlockDef
|
||||||
|
{
|
||||||
|
QString title; //title of the block containing the property or properties of this sub-section
|
||||||
|
QStringList captions; //list of captions for widgets at the block level (not associated with any particular property)
|
||||||
|
WidgetList widgets; //list of widgets at the block level (not associated with any particular property)
|
||||||
|
QList<SettingsItemDef *> properties; //list of the property(ies) which are subordinate to the property block.
|
||||||
|
Orientation widgetOrientation; //general orientation of widgets in group block
|
||||||
|
bool isVisible; //determines whether or not box border/title are visible
|
||||||
|
bool isProxy; //indicates whether or not this block defines a proxy block
|
||||||
|
QString defaultValue; //generic default value attribute
|
||||||
|
|
||||||
|
GroupBlockDef (): title(""), widgetOrientation (Orient_Vertical), isVisible (true), isProxy (false), defaultValue ("")
|
||||||
|
{}
|
||||||
|
|
||||||
|
GroupBlockDef (QString blockTitle)
|
||||||
|
: title (blockTitle), widgetOrientation (Orient_Vertical), isProxy (false), isVisible (true), defaultValue ("")
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CustomBlockDef
|
||||||
|
{
|
||||||
|
QString title;
|
||||||
|
QString defaultValue; //default value for widgets unique to the custom block
|
||||||
|
GroupBlockDefList blockDefList; //list of settings groups that comprise the settings within the custom block
|
||||||
|
Orientation blockOrientation;
|
||||||
|
|
||||||
|
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||||
|
{}
|
||||||
|
|
||||||
|
CustomBlockDef (const QString &blockTitle)
|
||||||
|
: title (blockTitle), defaultValue (""), blockOrientation (Orient_Horizontal)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // VIEW_SUPPORT_HPP
|
@ -0,0 +1,80 @@
|
|||||||
|
#include "toggleblock.hpp"
|
||||||
|
#include "groupblock.hpp"
|
||||||
|
#include "groupbox.hpp"
|
||||||
|
#include "itemblock.hpp"
|
||||||
|
|
||||||
|
CSVSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
||||||
|
CustomBlock(parent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int CSVSettings::ToggleBlock::build(CustomBlockDef &def)
|
||||||
|
{
|
||||||
|
if (def.blockDefList.size()==0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
QList<GroupBlockDef *>::Iterator it = def.blockDefList.begin();
|
||||||
|
|
||||||
|
//first def in the list is the def for the toggle block
|
||||||
|
GroupBlockDef *toggleDef = *it++;
|
||||||
|
|
||||||
|
if (toggleDef->captions.size() != def.blockDefList.size()-1 )
|
||||||
|
return -2;
|
||||||
|
|
||||||
|
if (toggleDef->widgets.size() == 0)
|
||||||
|
return -3;
|
||||||
|
|
||||||
|
//create the toogle block UI structure
|
||||||
|
QLayout *blockLayout = createLayout (def.blockOrientation, true);
|
||||||
|
GroupBox *propertyBox = buildGroupBox (toggleDef->widgetOrientation);
|
||||||
|
|
||||||
|
mBox->setLayout(blockLayout);
|
||||||
|
mBox->setTitle (toggleDef->title);
|
||||||
|
|
||||||
|
//build the blocks contained in the def list
|
||||||
|
//this manages proxy block construction.
|
||||||
|
//Any settings managed by the proxy setting
|
||||||
|
//must be included in the blocks defined in the list.
|
||||||
|
CustomBlock::build (def.blockDefList, &it);
|
||||||
|
|
||||||
|
for (GroupBlockList::iterator it = mGroupList.begin(); it != mGroupList.end(); ++it)
|
||||||
|
propertyBox->layout()->addWidget ((*it)->getGroupBox());
|
||||||
|
|
||||||
|
//build togle widgets, linking them to the settings
|
||||||
|
GroupBox *toggleBox = buildToggleWidgets (*toggleDef, def.defaultValue);
|
||||||
|
|
||||||
|
blockLayout->addWidget(toggleBox);
|
||||||
|
blockLayout->addWidget(propertyBox);
|
||||||
|
blockLayout->setAlignment (propertyBox, Qt::AlignRight);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::GroupBox *CSVSettings::ToggleBlock::buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle)
|
||||||
|
{
|
||||||
|
GroupBox *box = new GroupBox (false, getParent());
|
||||||
|
|
||||||
|
QLayout *layout = createLayout (def.widgetOrientation, true, static_cast<QWidget *>(box));
|
||||||
|
|
||||||
|
for (int i = 0; i < def.widgets.size(); ++i)
|
||||||
|
{
|
||||||
|
QString caption = def.captions.at(i);
|
||||||
|
WidgetDef *wDef = def.widgets.at(i);
|
||||||
|
|
||||||
|
wDef->caption = caption;
|
||||||
|
wDef->widgetAlignment = Align_Left;
|
||||||
|
|
||||||
|
AbstractWidget *widg = buildWidget (caption, *wDef, layout, false);
|
||||||
|
|
||||||
|
GroupBlock *block = mGroupList.at(i);
|
||||||
|
|
||||||
|
//connect widget's update to the property block's enabled status
|
||||||
|
connect (widg->widget(), SIGNAL (toggled (bool)), block, SLOT (slotSetEnabled(bool)));
|
||||||
|
|
||||||
|
//enable the default toggle option
|
||||||
|
block->getGroupBox()->setEnabled( caption == defaultToggle );
|
||||||
|
|
||||||
|
layout = widg->getLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef TOGGLEBLOCK_HPP
|
||||||
|
#define TOGGLEBLOCK_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "customblock.hpp"
|
||||||
|
|
||||||
|
namespace CSVSettings
|
||||||
|
{
|
||||||
|
class GroupBlock;
|
||||||
|
class GroupBox;
|
||||||
|
class ToggleWidget;
|
||||||
|
class ItemBlock;
|
||||||
|
|
||||||
|
class ToggleBlock : public CustomBlock
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ToggleBlock(QWidget *parent = 0);
|
||||||
|
|
||||||
|
int build (CustomBlockDef &def);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GroupBox *buildToggleWidgets (GroupBlockDef &def, QString &defaultToggle);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // TOGGLEBLOCK_HPP
|
@ -0,0 +1,173 @@
|
|||||||
|
#include "usersettingsdialog.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDesktopWidget>
|
||||||
|
#include <QWidget>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDockWidget>
|
||||||
|
|
||||||
|
#include "blankpage.hpp"
|
||||||
|
#include "editorpage.hpp"
|
||||||
|
#include "../../model/settings/support.hpp"
|
||||||
|
|
||||||
|
#include "settingwidget.hpp"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
CSVSettings::UserSettingsDialog::UserSettingsDialog(QMainWindow *parent) :
|
||||||
|
QMainWindow (parent), mStackedWidget (0)
|
||||||
|
{
|
||||||
|
setWindowTitle(QString::fromUtf8 ("User Settings"));
|
||||||
|
buildPages();
|
||||||
|
setWidgetStates (loadSettings());
|
||||||
|
positionWindow ();
|
||||||
|
|
||||||
|
connect (mListWidget,
|
||||||
|
SIGNAL (currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
|
||||||
|
this,
|
||||||
|
SLOT (slotChangePage (QListWidgetItem*, QListWidgetItem*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::UserSettingsDialog::~UserSettingsDialog()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::closeEvent (QCloseEvent *event)
|
||||||
|
{
|
||||||
|
writeSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::setWidgetStates (CSMSettings::SectionMap settingsMap)
|
||||||
|
{
|
||||||
|
//iterate the tabWidget's pages (sections)
|
||||||
|
for (int i = 0; i < mStackedWidget->count(); i++)
|
||||||
|
{
|
||||||
|
//get the settings defined for the entire section
|
||||||
|
CSMSettings::SettingMap *settings = settingsMap [mStackedWidget->widget(i)->objectName()];
|
||||||
|
|
||||||
|
//if found, initialize the page's widgets
|
||||||
|
if (settings)
|
||||||
|
{
|
||||||
|
AbstractPage *page = getAbstractPage (i);
|
||||||
|
page->initializeWidgets(*settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::buildPages()
|
||||||
|
{
|
||||||
|
//craete central widget with it's layout and immediate children
|
||||||
|
QWidget *centralWidget = new QWidget (this);
|
||||||
|
|
||||||
|
mListWidget = new QListWidget (centralWidget);
|
||||||
|
mStackedWidget = new QStackedWidget (centralWidget);
|
||||||
|
|
||||||
|
QLayout* dialogLayout = new QHBoxLayout();
|
||||||
|
|
||||||
|
dialogLayout->addWidget (mListWidget);
|
||||||
|
dialogLayout->addWidget (mStackedWidget);
|
||||||
|
|
||||||
|
centralWidget->setLayout (dialogLayout);
|
||||||
|
|
||||||
|
setCentralWidget (centralWidget);
|
||||||
|
setDockOptions (QMainWindow::AllowNestedDocks);
|
||||||
|
//uncomment to test with sample editor page.
|
||||||
|
//createSamplePage();
|
||||||
|
createPage<BlankPage>("Page1");
|
||||||
|
createPage<BlankPage>("Page2");
|
||||||
|
createPage<BlankPage>("Page3");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::createSamplePage()
|
||||||
|
{
|
||||||
|
//add pages to stackedwidget and items to listwidget
|
||||||
|
CSVSettings::AbstractPage *page
|
||||||
|
= new CSVSettings::EditorPage(this);
|
||||||
|
|
||||||
|
mStackedWidget->addWidget (page);
|
||||||
|
|
||||||
|
new QListWidgetItem (page->objectName(), mListWidget);
|
||||||
|
|
||||||
|
connect ( page, SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)),
|
||||||
|
&(CSMSettings::UserSettings::instance()), SIGNAL ( signalUpdateEditorSetting (const QString &, const QString &)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::positionWindow ()
|
||||||
|
{
|
||||||
|
QRect scr = QApplication::desktop()->screenGeometry();
|
||||||
|
|
||||||
|
move(scr.center().x() - (width() / 2), scr.center().y() - (height() / 2));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::SectionMap CSVSettings::UserSettingsDialog::loadSettings ()
|
||||||
|
{
|
||||||
|
QString userPath = QString::fromStdString(mCfgMgr.getUserPath().string());
|
||||||
|
|
||||||
|
mPaths.append(QString("opencs.cfg"));
|
||||||
|
mPaths.append(userPath + QString("opencs.cfg"));
|
||||||
|
|
||||||
|
CSMSettings::SectionMap settingsMap;
|
||||||
|
|
||||||
|
foreach (const QString &path, mPaths)
|
||||||
|
{
|
||||||
|
qDebug() << "Loading config file:" << qPrintable(path);
|
||||||
|
QFile file(path);
|
||||||
|
|
||||||
|
if (file.exists())
|
||||||
|
{
|
||||||
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||||
|
{
|
||||||
|
QMessageBox msgBox;
|
||||||
|
msgBox.setWindowTitle(tr("Error opening OpenCS configuration file"));
|
||||||
|
msgBox.setIcon(QMessageBox::Critical);
|
||||||
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||||
|
msgBox.setText(QObject::tr("<br><b>Could not open %0 for reading</b><br><br> \
|
||||||
|
Please make sure you have the right permissions \
|
||||||
|
and try again.<br>").arg(file.fileName()));
|
||||||
|
msgBox.exec();
|
||||||
|
return settingsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream stream(&file);
|
||||||
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
||||||
|
|
||||||
|
CSMSettings::UserSettings::instance().getSettings(stream, settingsMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return settingsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::writeSettings()
|
||||||
|
{
|
||||||
|
QMap<QString, CSMSettings::SettingList *> settings;
|
||||||
|
|
||||||
|
for (int i = 0; i < mStackedWidget->count(); ++i)
|
||||||
|
{
|
||||||
|
AbstractPage *page = getAbstractPage (i);
|
||||||
|
settings [page->objectName()] = page->getSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
CSMSettings::UserSettings::instance().writeFile(CSMSettings::UserSettings::instance().openFile(mPaths.back()), settings);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
CSVSettings::AbstractPage *CSVSettings::UserSettingsDialog::getAbstractPage (int index)
|
||||||
|
{
|
||||||
|
return dynamic_cast<AbstractPage *>(mStackedWidget->widget(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSVSettings::UserSettingsDialog::slotChangePage(QListWidgetItem *current, QListWidgetItem *previous)
|
||||||
|
{
|
||||||
|
if (!current)
|
||||||
|
current = previous;
|
||||||
|
|
||||||
|
if (!(current == previous))
|
||||||
|
mStackedWidget->setCurrentIndex (mListWidget->row(current));
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef USERSETTINGSDIALOG_H
|
||||||
|
#define USERSETTINGSDIALOG_H
|
||||||
|
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QStackedWidget>
|
||||||
|
|
||||||
|
#ifndef Q_MOC_RUN
|
||||||
|
#include <components/files/configurationmanager.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../model/settings/usersettings.hpp"
|
||||||
|
#include "../../model/settings/support.hpp"
|
||||||
|
|
||||||
|
class QHBoxLayout;
|
||||||
|
class AbstractWidget;
|
||||||
|
class QStackedWidget;
|
||||||
|
class QListWidget;
|
||||||
|
|
||||||
|
namespace CSVSettings {
|
||||||
|
|
||||||
|
class AbstractPage;
|
||||||
|
|
||||||
|
class UserSettingsDialog : public QMainWindow
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
QStringList mPaths;
|
||||||
|
QListWidget *mListWidget;
|
||||||
|
QStackedWidget *mStackedWidget;
|
||||||
|
Files::ConfigurationManager mCfgMgr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
UserSettingsDialog(QMainWindow *parent = 0);
|
||||||
|
~UserSettingsDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void closeEvent (QCloseEvent *event);
|
||||||
|
AbstractPage *getAbstractPage (int index);
|
||||||
|
void setWidgetStates (CSMSettings::SectionMap settingsMap);
|
||||||
|
void buildPages();
|
||||||
|
void positionWindow ();
|
||||||
|
CSMSettings::SectionMap loadSettings();
|
||||||
|
void writeSettings();
|
||||||
|
void createSamplePage();
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void createPage (const QString &title)
|
||||||
|
{
|
||||||
|
T *page = new T(title, this);
|
||||||
|
|
||||||
|
mStackedWidget->addWidget (dynamic_cast<QWidget *>(page));
|
||||||
|
|
||||||
|
new QListWidgetItem (page->objectName(), mListWidget);
|
||||||
|
|
||||||
|
//finishing touches
|
||||||
|
if (mStackedWidget->sizeHint().width() < 640)
|
||||||
|
mStackedWidget->sizeHint().setWidth(640);
|
||||||
|
|
||||||
|
if (mStackedWidget->sizeHint().height() < 480)
|
||||||
|
mStackedWidget->sizeHint().setHeight(480);
|
||||||
|
|
||||||
|
resize (mStackedWidget->sizeHint());
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void slotChangePage (QListWidgetItem*, QListWidgetItem*);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif // USERSETTINGSDIALOG_H
|
Loading…
Reference in New Issue