mirror of https://github.com/OpenMW/openmw.git
UserSettings system
parent
f6203cac2a
commit
cb9c82324c
@ -0,0 +1,111 @@
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
CsSettings::AbstractBlock::AbstractBlock(QWidget* parent)
|
||||
: QObject (parent), mBox ( new GroupBox (parent) ), mWidgetParent (parent)
|
||||
{}
|
||||
|
||||
CsSettings::AbstractBlock::AbstractBlock(bool isVisible, QWidget* parent)
|
||||
: QObject (parent), mBox ( new GroupBox (isVisible, parent)), mWidgetParent (parent)
|
||||
{}
|
||||
|
||||
QLayout *CsSettings::AbstractBlock::createLayout (OcsWidgetOrientation direction, bool isZeroMargin, QWidget* parent)
|
||||
{
|
||||
QLayout *layout = 0;
|
||||
|
||||
if (direction == OCS_VERTICAL)
|
||||
layout = new QVBoxLayout (parent);
|
||||
else
|
||||
layout = new QHBoxLayout (parent);
|
||||
|
||||
if (isZeroMargin)
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
QGroupBox *CsSettings::AbstractBlock::getGroupBox()
|
||||
{
|
||||
return mBox;
|
||||
}
|
||||
|
||||
CsSettings::AbstractWidget *CsSettings::AbstractBlock::buildWidget (const QString& widgetName, WidgetDef &def,
|
||||
QLayout *layout, bool isConnected) const
|
||||
{
|
||||
AbstractWidget *widg = 0;
|
||||
|
||||
switch (def.type)
|
||||
{
|
||||
|
||||
case OCS_RADIO_WIDGET:
|
||||
widg = createSettingWidget<QRadioButton> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_SPIN_WIDGET:
|
||||
widg = createSettingWidget<QSpinBox> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_CHECK_WIDGET:
|
||||
widg = createSettingWidget<QCheckBox> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_TEXT_WIDGET:
|
||||
widg = createSettingWidget<QLineEdit> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_LIST_WIDGET:
|
||||
widg = createSettingWidget<QListWidget> (def, layout);
|
||||
break;
|
||||
|
||||
case OCS_COMBO_WIDGET:
|
||||
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 CsSettings::AbstractBlock::setVisible (bool isVisible)
|
||||
{
|
||||
mBox->setBorderVisibility (isVisible);
|
||||
}
|
||||
|
||||
bool CsSettings::AbstractBlock::isVisible () const
|
||||
{
|
||||
return mBox->borderVisibile();
|
||||
}
|
||||
|
||||
QWidget *CsSettings::AbstractBlock::getParent() const
|
||||
{
|
||||
return mWidgetParent;
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::slotUpdate (const QString &value)
|
||||
{
|
||||
slotUpdateSetting (objectName(), value);
|
||||
}
|
||||
|
||||
void CsSettings::AbstractBlock::slotSetEnabled(bool value)
|
||||
{
|
||||
mBox->setEnabled(value);
|
||||
}
|
||||
|
||||
void CsSettings::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 "settingsitem.hpp"
|
||||
#include "groupbox.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
{
|
||||
|
||||
class AbstractBlock : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
typedef QMap<QString, 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 SettingList *getSettings() = 0;
|
||||
virtual bool updateSettings (const SettingMap &settings) = 0;
|
||||
virtual bool updateBySignal (const QString &name, const QString &value, bool &doEmit)
|
||||
{ return false; }
|
||||
|
||||
protected:
|
||||
|
||||
QLayout *createLayout (OcsWidgetOrientation 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>
|
||||
|
||||
CsSettings::AbstractPage::AbstractPage(QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::AbstractPage::AbstractPage(const QString &pageName, QWidget *parent):
|
||||
QWidget(parent)
|
||||
{
|
||||
QWidget::setObjectName (pageName);
|
||||
}
|
||||
|
||||
CsSettings::AbstractPage::~AbstractPage()
|
||||
{
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::AbstractPage::getSettings()
|
||||
{
|
||||
SettingList *settings = new SettingList();
|
||||
|
||||
foreach (AbstractBlock *block, mAbstractBlocks)
|
||||
{
|
||||
SettingList *groupSettings = block->getSettings();
|
||||
settings->append (*groupSettings);
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
#ifndef ABSTRACTPAGE_HPP
|
||||
#define ABSTRACTPAGE_HPP
|
||||
|
||||
#include <QWidget>
|
||||
#include <QList>
|
||||
#include <QLayout>
|
||||
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
class SettingMap;
|
||||
class SettingList;
|
||||
|
||||
namespace CsSettings {
|
||||
|
||||
typedef QList<AbstractBlock *> AbstractBlockList;
|
||||
|
||||
class AbstractPage: public QWidget
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
protected:
|
||||
|
||||
AbstractBlockList mAbstractBlocks;
|
||||
|
||||
public:
|
||||
|
||||
AbstractPage(QWidget *parent = 0);
|
||||
AbstractPage (const QString &pageName, QWidget* parent = 0);
|
||||
|
||||
~AbstractPage();
|
||||
|
||||
virtual void setupUi()=0;
|
||||
|
||||
virtual void initializeWidgets (const SettingMap &settings) = 0;
|
||||
|
||||
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,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 "usersettings.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "toggleblock.hpp"
|
||||
|
||||
CsSettings::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 CsSettings::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 (OCS_SPIN_WIDGET);
|
||||
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 (OCS_SPIN_WIDGET);
|
||||
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 (OCS_RADIO_WIDGET);
|
||||
reuseSubWidget.valueList = (reuseSubItem->valueList);
|
||||
reuseSubWidget.widgetAlignment = OCS_LEFT;
|
||||
|
||||
reuseSubwindow.properties << reuseSubItem;
|
||||
reuseSubItem->widget = reuseSubWidget;
|
||||
|
||||
///////////////////////////////
|
||||
//custom window size properties
|
||||
///////////////////////////////
|
||||
|
||||
//custom width
|
||||
SettingsItemDef *widthItem = new SettingsItemDef ("Window Width", "640");
|
||||
widthItem->widget = WidgetDef (OCS_TEXT_WIDGET);
|
||||
widthItem->widget.widgetWidth = 45;
|
||||
|
||||
//custom height
|
||||
SettingsItemDef *heightItem = new SettingsItemDef ("Window Height", "480");
|
||||
heightItem->widget = WidgetDef (OCS_TEXT_WIDGET);
|
||||
heightItem->widget.widgetWidth = 45;
|
||||
heightItem->widget.caption = "x";
|
||||
|
||||
customWindowSize.properties << widthItem << heightItem;
|
||||
customWindowSize.widgetOrientation = OCS_HORIZONTAL;
|
||||
customWindowSize.isVisible = false;
|
||||
|
||||
|
||||
//pre-defined
|
||||
SettingsItemDef *widthByHeightItem = new SettingsItemDef ("Window Size", "640x480");
|
||||
WidgetDef widthByHeightWidget = WidgetDef (OCS_COMBO_WIDGET);
|
||||
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 = OCS_VERTICAL;
|
||||
windowSizeToggle.isVisible = false;
|
||||
|
||||
//define a widget for each group in the toggle
|
||||
for (int i = 0; i < 2; i++)
|
||||
windowSizeToggle.widgets << new WidgetDef (OCS_RADIO_WIDGET);
|
||||
|
||||
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 CsSettings::EditorPage::initializeWidgets (const 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 CsSettings {
|
||||
|
||||
class UserSettings;
|
||||
class AbstractBlock;
|
||||
|
||||
class EditorPage : public AbstractPage
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
EditorPage(QWidget *parent = 0);
|
||||
|
||||
void setupUi();
|
||||
void initializeWidgets (const SettingMap &settings);
|
||||
|
||||
signals:
|
||||
void signalUpdateEditorSetting (const QString &settingName, const QString &settingValue);
|
||||
};
|
||||
}
|
||||
#endif //EDITORPAGE_H
|
@ -0,0 +1,108 @@
|
||||
#include "groupblock.hpp"
|
||||
#include "itemblock.hpp"
|
||||
|
||||
CsSettings::GroupBlock::GroupBlock (QWidget* parent)
|
||||
: AbstractBlock (parent)
|
||||
{}
|
||||
|
||||
CsSettings::GroupBlock::GroupBlock (bool isVisible, QWidget *parent)
|
||||
: AbstractBlock (isVisible, parent)
|
||||
{}
|
||||
|
||||
int CsSettings::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;
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::GroupBlock::getSettings()
|
||||
{
|
||||
SettingList *settings = 0;
|
||||
|
||||
foreach (ItemBlock *block, mItemBlockList)
|
||||
{
|
||||
if (!settings)
|
||||
settings = new SettingList();
|
||||
|
||||
settings->append(*(block->getSettings ()));
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
CsSettings::ItemBlock *CsSettings::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;
|
||||
}
|
||||
|
||||
CsSettings::ItemBlock *CsSettings::GroupBlock::getItemBlock (int index)
|
||||
{
|
||||
ItemBlock *retBlock = 0;
|
||||
|
||||
if (mItemBlockList.size() > index)
|
||||
retBlock = mItemBlockList.at(index);
|
||||
|
||||
return retBlock;
|
||||
}
|
||||
|
||||
bool CsSettings::GroupBlock::updateSettings (const SettingMap &settings)
|
||||
{
|
||||
bool success = true;
|
||||
|
||||
//update all non-proxy settings
|
||||
foreach (ItemBlock *block, mItemBlockList)
|
||||
{
|
||||
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 CsSettings
|
||||
{
|
||||
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 SettingMap &settings);
|
||||
|
||||
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 CsSettings::GroupBox::INVISIBLE_BOX_STYLE =
|
||||
QString::fromUtf8("QGroupBox { border: 0px; padding 0px; margin: 0px;}");
|
||||
|
||||
CsSettings::GroupBox::GroupBox(QWidget *parent) :
|
||||
QGroupBox (parent)
|
||||
{
|
||||
initBox();
|
||||
}
|
||||
|
||||
CsSettings::GroupBox::GroupBox (bool isVisible, QWidget *parent) :
|
||||
QGroupBox (parent)
|
||||
{
|
||||
initBox(isVisible);
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::initBox(bool isVisible)
|
||||
{
|
||||
setFlat (true);
|
||||
VISIBLE_BOX_STYLE = styleSheet();
|
||||
|
||||
if (!isVisible)
|
||||
setStyleSheet (INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
bool CsSettings::GroupBox::borderVisibile() const
|
||||
{
|
||||
return (styleSheet() != INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::setTitle (const QString &title)
|
||||
{
|
||||
if (borderVisibile() )
|
||||
{
|
||||
QGroupBox::setTitle (title);
|
||||
setMinimumWidth();
|
||||
}
|
||||
}
|
||||
|
||||
void CsSettings::GroupBox::setBorderVisibility (bool value)
|
||||
{
|
||||
if (value)
|
||||
setStyleSheet(VISIBLE_BOX_STYLE);
|
||||
else
|
||||
setStyleSheet(INVISIBLE_BOX_STYLE);
|
||||
}
|
||||
|
||||
void CsSettings::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,29 @@
|
||||
#ifndef GROUPBOX_HPP
|
||||
#define GROUPBOX_HPP
|
||||
|
||||
#include <QGroupBox>
|
||||
|
||||
namespace CsSettings
|
||||
{
|
||||
class GroupBox : public QGroupBox
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
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>
|
||||
|
||||
CsSettings::ItemBlock::ItemBlock (QWidget* parent)
|
||||
: mSetting (0), AbstractBlock (false, parent)
|
||||
{
|
||||
}
|
||||
|
||||
int CsSettings::ItemBlock::build(SettingsItemDef &iDef)
|
||||
{
|
||||
buildItemBlock (iDef);
|
||||
buildItemBlockWidgets (iDef);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CsSettings::ItemBlock::buildItemBlockWidgets (SettingsItemDef &iDef)
|
||||
{
|
||||
WidgetDef wDef = iDef.widget;
|
||||
QLayout *blockLayout = 0;
|
||||
QString defaultValue = iDef.defaultValue;
|
||||
|
||||
switch (wDef.type)
|
||||
{
|
||||
|
||||
case OCS_CHECK_WIDGET:
|
||||
case OCS_RADIO_WIDGET:
|
||||
|
||||
foreach (QString item, *(iDef.valueList))
|
||||
{
|
||||
wDef.caption = item;
|
||||
wDef.isDefault = (item == defaultValue);
|
||||
|
||||
blockLayout = buildWidget (item, wDef, blockLayout)->getLayout();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case OCS_COMBO_WIDGET:
|
||||
case OCS_LIST_WIDGET:
|
||||
|
||||
//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 CsSettings::ItemBlock::buildItemBlock (SettingsItemDef &iDef)
|
||||
{
|
||||
QString defaultValue = iDef.defaultValue;
|
||||
|
||||
setObjectName(iDef.name);
|
||||
|
||||
mSetting = new SettingsItem (objectName(),
|
||||
iDef.hasMultipleValues, iDef.defaultValue,
|
||||
parent());
|
||||
|
||||
if (iDef.valueList)
|
||||
mSetting->setValueList(iDef.valueList);
|
||||
|
||||
if (!iDef.minMax.isEmpty())
|
||||
mSetting->setValuePair(iDef.minMax);
|
||||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::update (const QString &value)
|
||||
{
|
||||
bool success = updateItem (value);
|
||||
|
||||
if (success)
|
||||
signalUpdateWidget (value);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::updateItem (const QString &value)
|
||||
{
|
||||
return mSetting->updateItem(value);
|
||||
}
|
||||
|
||||
|
||||
bool CsSettings::ItemBlock::updateBySignal(const QString &name, const QString &value, bool &doEmit)
|
||||
{
|
||||
bool success = (mSetting->getValue() != value);
|
||||
|
||||
if (success)
|
||||
success = updateItem(value);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
CsSettings::SettingList *CsSettings::ItemBlock::getSettings ()
|
||||
{
|
||||
SettingList *list = new SettingList();
|
||||
list->push_back(mSetting);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
QString CsSettings::ItemBlock::getValue() const
|
||||
{
|
||||
return mSetting->getValue();
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
#ifndef ITEMBLOCK_HPP
|
||||
#define ITEMBLOCK_HPP
|
||||
|
||||
#include "abstractblock.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
{
|
||||
|
||||
class ItemBlock : public AbstractBlock
|
||||
{
|
||||
SettingsItem *mSetting;
|
||||
WidgetList mWidgetList;
|
||||
|
||||
public:
|
||||
|
||||
ItemBlock (QWidget* parent = 0);
|
||||
|
||||
bool updateSettings (const SettingMap &settings) { return false; }
|
||||
|
||||
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,102 @@
|
||||
#include "settingsitem.hpp"
|
||||
|
||||
bool CsSettings::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 CsSettings::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 CsSettings::SettingsItem::updateItem(int valueListIndex)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
if (mValueList)
|
||||
{
|
||||
if (mValueList->size() > valueListIndex)
|
||||
success = updateItem (mValueList->at(valueListIndex));
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool CsSettings::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 CsSettings::SettingsItem::setDefaultValue (const QString &value)
|
||||
{
|
||||
mDefaultValue = value;
|
||||
update (value);
|
||||
}
|
||||
|
||||
QString CsSettings::SettingsItem::getDefaultValue() const
|
||||
{
|
||||
return mDefaultValue;
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
#ifndef SETTINGSITEM_HPP
|
||||
#define SETTINGSITEM_HPP
|
||||
|
||||
#include <QObject>
|
||||
#include "support.hpp"
|
||||
#include "settingcontainer.hpp"
|
||||
|
||||
namespace CsSettings
|
||||
{
|
||||
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 "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 CsSettings
|
||||
{
|
||||
//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 CsSettings::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 CsSettings::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 CsSettings::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,170 @@
|
||||
#ifndef SUPPORT_HPP
|
||||
#define SUPPORT_HPP
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
class QLayout;
|
||||
class QWidget;
|
||||
class QListWidgetItem;
|
||||
|
||||
namespace CsSettings
|
||||
{
|
||||
|
||||
class SettingContainer;
|
||||
struct WidgetDef;
|
||||
class ItemBlock;
|
||||
class GroupBlock;
|
||||
struct GroupBlockDef;
|
||||
|
||||
typedef QList<GroupBlockDef *> GroupBlockDefList;
|
||||
typedef QList<GroupBlock *> GroupBlockList;
|
||||
typedef QList<ItemBlock *> ItemBlockList;
|
||||
typedef QList<SettingContainer *> SettingList;
|
||||
typedef QMap<QString, SettingContainer *> SettingMap;
|
||||
typedef QMap<QString, SettingMap *> SectionMap;
|
||||
typedef QList<QStringList *> ProxyList;
|
||||
typedef QList<WidgetDef *> WidgetList;
|
||||
typedef QMap<QString, ItemBlock *> ItemBlockMap;
|
||||
|
||||
enum OcsWidgetOrientation
|
||||
{
|
||||
OCS_HORIZONTAL,
|
||||
OCS_VERTICAL
|
||||
};
|
||||
|
||||
enum OcsWidgetType
|
||||
{
|
||||
OCS_CHECK_WIDGET,
|
||||
OCS_COMBO_WIDGET,
|
||||
OCS_TEXT_WIDGET,
|
||||
OCS_LIST_WIDGET,
|
||||
OCS_RADIO_WIDGET,
|
||||
OCS_SPIN_WIDGET,
|
||||
OCS_UNDEFINED_WIDGET
|
||||
};
|
||||
|
||||
enum OcsAlignment
|
||||
{
|
||||
OCS_LEFT = Qt::AlignLeft,
|
||||
OCS_CENTER = Qt::AlignHCenter,
|
||||
OCS_RIGHT = Qt::AlignRight
|
||||
};
|
||||
|
||||
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()
|
||||
{ return (left.isEmpty() && right.isEmpty()); }
|
||||
};
|
||||
|
||||
//template for defining the widget of a property.
|
||||
struct WidgetDef
|
||||
{
|
||||
OcsWidgetType type; //type of widget providing input
|
||||
int labelWidth; //width of caption label
|
||||
int widgetWidth; //width of input widget
|
||||
OcsWidgetOrientation 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
|
||||
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.
|
||||
OcsAlignment valueAlignment; //left / center / right-justify text in widget
|
||||
OcsAlignment widgetAlignment; //left / center / right-justify widget in group box
|
||||
|
||||
|
||||
WidgetDef() : labelWidth (-1), widgetWidth (-1),
|
||||
orientation (OCS_HORIZONTAL),
|
||||
isDefault (true), valueAlignment (OCS_CENTER),
|
||||
widgetAlignment (OCS_RIGHT),
|
||||
inputMask (""), value (""),
|
||||
caption (""), valueList (0)
|
||||
{}
|
||||
|
||||
WidgetDef (OcsWidgetType widgType)
|
||||
: type (widgType), orientation (OCS_HORIZONTAL),
|
||||
caption (""), value (""), valueAlignment (OCS_CENTER),
|
||||
widgetAlignment (OCS_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;
|
||||
QStringPair minMax; //minimum / maximum value pair
|
||||
WidgetDef widget; //definition of the input widget for this setting
|
||||
OcsWidgetOrientation 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 (OCS_VERTICAL), hasMultipleValues (false)
|
||||
{}
|
||||
|
||||
SettingsItemDef (QString propName, QString propDefault, OcsWidgetOrientation propOrient = OCS_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.
|
||||
OcsWidgetOrientation 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 (OCS_VERTICAL), isVisible (true), isProxy (false), defaultValue ("")
|
||||
{}
|
||||
|
||||
GroupBlockDef (QString blockTitle)
|
||||
: title (blockTitle), widgetOrientation (OCS_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
|
||||
OcsWidgetOrientation blockOrientation;
|
||||
|
||||
CustomBlockDef (): title (""), defaultValue (""), blockOrientation (OCS_HORIZONTAL)
|
||||
{}
|
||||
|
||||
CustomBlockDef (const QString &blockTitle)
|
||||
: title (blockTitle), defaultValue (""), blockOrientation (OCS_HORIZONTAL)
|
||||
{}
|
||||
};
|
||||
}
|
||||
#endif // SUPPORT_HPP
|
@ -0,0 +1,80 @@
|
||||
#include "toggleblock.hpp"
|
||||
#include "groupblock.hpp"
|
||||
#include "groupbox.hpp"
|
||||
#include "itemblock.hpp"
|
||||
|
||||
CsSettings::ToggleBlock::ToggleBlock(QWidget *parent) :
|
||||
CustomBlock(parent)
|
||||
{}
|
||||
|
||||
int CsSettings::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;
|
||||
}
|
||||
|
||||
CsSettings::GroupBox *CsSettings::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 = OCS_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 CsSettings
|
||||
{
|
||||
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
|
Loading…
Reference in New Issue