Data model for settings/options updates
[qtrapids] / src / utest / options / Options.cpp
diff --git a/src/utest/options/Options.cpp b/src/utest/options/Options.cpp
new file mode 100644 (file)
index 0000000..10cd514
--- /dev/null
@@ -0,0 +1,142 @@
+#include "Options.hpp"
+
+#include <QVariant>
+
+#include <algorithm>
+
+namespace qtplus
+{
+
+SettingsModel::SettingsModel(QObject *parent)
+               : QAbstractItemModel(parent)
+{
+
+}
+
+QModelIndex SettingsModel::index(int row, int col, const QModelIndex &parent) const
+{
+       if (row < 0 || col < 0) {
+               return QModelIndex();
+       }
+
+       if ( !parent.isValid()) {
+
+               if (col == 0 && row < groups_.size() ) {
+                       return QAbstractItemModel::createIndex(row, col, groups_[row].data());
+               } else if (col == 2 && row < options_.size()) {
+                       return QAbstractItemModel::createIndex(row, col, options_[row].data());
+               }
+               return QModelIndex();
+       }
+
+       if (parent.parent().isValid() || col > 0) {
+               // only one nesting level is support
+               return QModelIndex();
+       }
+
+       OptionsGroup *group = reinterpret_cast<OptionsGroup*>(parent.internalPointer());
+       if (!group) {
+               thrown std::exception();
+       }
+       return QAbstractItemModel::createIndex(row, col, options_[group->getOptionPos(row)].data());
+}
+
+QModelIndex SettingsModel::parent(const QModelIndex &child) const
+{
+       return QModelIndex();
+}
+
+int SettingsModel::rowCount(const QModelIndex &parent) const
+{
+       if (!parent.isValid()) {
+               return std::max(groups_.size(), options_.size());
+       }
+
+       // only one level of nesting is supported (group/option)
+       if (parent.parent().isValid() || parent.column() || index.column() > 0) {
+               throw std::exception();
+       }
+
+       OptionsGroup *group = reinterpret_cast<OptionsGroup*>(parent.internalPointer());
+       if (!group) {
+               thrown std::exception();
+       }
+
+       return group->optionsCount();
+}
+
+int SettingsModel::columnCount(const QModelIndex &parent) const
+{
+       return ( groups_.size()
+                ? ( options_.size() ? 2 : 1 ) );
+}
+
+static inline QVariant getTopLevelDisplayData_(const QModelIndex &index)
+{
+       if ( index.column() == 0) {
+               OptionsGroup *group = reinterpret_cast<OptionsGroup*>(index.internalPointer());
+               if (!group) {
+                       thrown std::exception();
+               }
+               return QVariant(group->name());
+       }
+
+       Option *option = reinterpret_cast<Option*>(index.internalPointer());
+       if (!option) {
+               thrown std::exception();
+       }
+       return option->value();
+}
+
+QVariant SettingsModel::data(const QModelIndex &index, int role) const
+{
+       if (role != Qt::DisplayRole) {
+               return QVariant();
+       }
+
+       if (!index.isValid()) {
+               return QVariant();
+       }
+
+       if (!index.parent().isValid()) {
+               return getTopLevelDisplayData_(index);
+       }
+
+       if (index.column() > 0) {
+               // only one level of nesting
+               return QVariant();
+       }
+
+       Option *option = reinterpret_cast<Option*>(index.internalPointer());
+       if (!option) {
+               thrown std::exception();
+       }
+       return option.value();
+
+}
+
+bool SettingsModel::addGroup(QString const &name)
+{
+       group_ptr group(new SettingsModel::OptionsGroup(name), this);
+
+       if (idx_.find(name) == idx_.end()) {
+               idx_[name] = group;
+               groups_.push_back(group);
+               return true;
+       }
+
+       return false;
+}
+
+size_t SettingsModel::addOption(OptionsGroup *group, QString const& name, QVariant const& value)
+{
+       if (idx_.find(group->name()) == idx_.end()) {
+               throw std::exception(); // TODO use custom exception
+       }
+
+       options_.push_back(option_ptr(new Option(name, value)));
+       return options_.size();
+}
+
+
+} // namespace qtplus