summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--boost_any_qvariant_convert.hpp121
-rw-r--r--boost_any_to_qvariant.hpp67
-rw-r--r--fusion_model.hpp13
-rw-r--r--fusion_static_dispatch.hpp47
-rw-r--r--gui_item_delegate.cpp29
-rw-r--r--gui_item_delegate.hpp2
-rw-r--r--main.cpp2
-rw-r--r--qt_adapter.hpp19
9 files changed, 223 insertions, 79 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0427ed1..5a880f9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,7 +50,7 @@ add_executable(msc-scriptie
friendly_fusion.hpp
fusion_static_dispatch.hpp
meta_types.hpp
- boost_any_to_qvariant.hpp
+ boost_any_qvariant_convert.hpp
gui_item_delegate.hpp gui_item_delegate.cpp
main_window.hpp main_window.cpp
${qt_sources}
diff --git a/boost_any_qvariant_convert.hpp b/boost_any_qvariant_convert.hpp
new file mode 100644
index 0000000..859623b
--- /dev/null
+++ b/boost_any_qvariant_convert.hpp
@@ -0,0 +1,121 @@
+#pragma once
+
+#include "friendly_fusion.hpp"
+#include "index_list.hpp"
+
+#include <QVariant>
+
+#include <boost/any.hpp>
+
+#include <string>
+
+template<typename value_type>
+QVariant to_qvariant(boost::any const& x)
+{
+ return QVariant::fromValue<value_type>(boost::any_cast<value_type>(x));
+}
+
+template <typename T, int n>
+QVariant to_qvariant(boost::any const& x)
+{
+ typedef friendly_fusion::result_of::begin<T> begin;
+ typedef friendly_fusion::result_of::advance_c<typename begin::type, n> adv_it;
+ typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
+ typedef typename std::decay<typename deref::type>::type value_type;
+ return to_qvariant<value_type>(x);
+}
+
+#if defined( __GNUC__ ) && !defined( __clang__ )
+template <typename T, int index>
+std::function<QVariant(boost::any const&)> to_qvariant_lambda()
+{
+ return [](boost::any const& any)
+ {
+ return convert<T, index>(any);
+ };
+}
+
+#endif //defined( __GNUC__ ) && !defined( __clang__ )
+
+template<typename T, int... Indices>
+QVariant to_qvariant(boost::any const& any, int index, indices<Indices...>)
+{
+ typedef std::function<QVariant(boost::any const&)> element_type;
+ static element_type table[] =
+ {
+#if defined( __GNUC__ ) && !defined( __clang__ )
+ //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
+ to_qvariant_lambda<T, Indices>()
+ ...
+#else
+ [](boost::any const& any){return to_qvariant<T, Indices>(any);}
+ ...
+#endif //defined( __GNUC__ ) && !defined( __clang__ )
+ };
+
+ return table[index](any);
+}
+
+template <typename T>
+QVariant to_qvariant(boost::any const& x, int index)
+{
+ typedef typename friendly_fusion::result_of::size<T>::type seq_size;
+ typedef typename build_indices<seq_size::value>::type indices_type;
+
+ return to_qvariant<T>(x, index, indices_type{});
+}
+
+template<typename value_type>
+boost::any to_boost_any(QVariant const& x)
+{
+ return boost::any(x.value<value_type>());
+}
+
+template <typename T, int n>
+boost::any to_boost_any(QVariant const& x)
+{
+ typedef friendly_fusion::result_of::begin<T> begin;
+ typedef friendly_fusion::result_of::advance_c<typename begin::type, n> adv_it;
+ typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
+ typedef typename std::decay<typename deref::type>::type value_type;
+ return to_boost_any<value_type>(x);
+}
+
+#if defined( __GNUC__ ) && !defined( __clang__ )
+template <typename T, int index>
+std::function<boost::any(QVariant const&)> to_qvariant_lambda()
+{
+ return [](QVariant const& value)
+ {
+ return to_boost_any<T, index>(value);
+ };
+}
+#endif //defined( __GNUC__ ) && !defined( __clang__ )
+
+template<typename T, int... Indices>
+boost::any to_boost_any(QVariant const& value, int index, indices<Indices...>)
+{
+ typedef std::function<boost::any(QVariant const&)> element_type;
+ static element_type table[] =
+ {
+#if defined( __GNUC__ ) && !defined( __clang__ )
+ //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
+ to_boost_any_lambda<T, Indices>()
+ ...
+#else
+ [](QVariant const& value){return to_boost_any<T, Indices>(value);}
+ ...
+#endif //defined( __GNUC__ ) && !defined( __clang__ )
+ };
+
+ return table[index](value);
+}
+
+template <typename T>
+boost::any to_boost_any(QVariant const& x, int index)
+{
+ typedef typename friendly_fusion::result_of::size<T>::type seq_size;
+ typedef typename build_indices<seq_size::value>::type indices_type;
+
+ return to_boost_any<T>(x, index, indices_type{});
+} \ No newline at end of file
diff --git a/boost_any_to_qvariant.hpp b/boost_any_to_qvariant.hpp
deleted file mode 100644
index 6172c09..0000000
--- a/boost_any_to_qvariant.hpp
+++ /dev/null
@@ -1,67 +0,0 @@
-#pragma once
-
-#include "friendly_fusion.hpp"
-#include "index_list.hpp"
-
-#include <QVariant>
-
-#include <boost/any.hpp>
-
-#include <string>
-
-template<typename value_type>
-QVariant convert(boost::any const& x)
-{
- return QVariant::fromValue<value_type>(boost::any_cast<value_type>(x));
-}
-
-template <typename T, int n>
-QVariant convert(boost::any const& x)
-{
- typedef friendly_fusion::result_of::begin<T> begin;
- typedef friendly_fusion::result_of::advance_c<typename begin::type, n> adv_it;
- typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
- typedef typename std::decay<typename deref::type>::type value_type;
- return convert<value_type>(x);
-}
-
-#if defined( __GNUC__ ) && !defined( __clang__ )
-template <typename T, int index>
-std::function<QVariant(boost::any const&)> convert_lambda()
-{
- return [](boost::any const& any)
- {
- return convert<T, index>(any);
- };
-}
-
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
-
-template<typename T, int... Indices>
-QVariant to_qvariant(boost::any const& any, int index, indices<Indices...>)
-{
- typedef std::function<QVariant(boost::any const&)> element_type;
- static element_type table[] =
- {
-#if defined( __GNUC__ ) && !defined( __clang__ )
- //Workaround for gcc bug: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47226
- convert_lambda<T, Indices>()
- ...
-#else
- [](boost::any const& any){return convert<T, Indices>(any);}
- ...
-#endif //defined( __GNUC__ ) && !defined( __clang__ )
- };
-
- return table[index](any);
-}
-
-
-template <typename T>
-QVariant to_qvariant(boost::any const& x, int index)
-{
- typedef typename friendly_fusion::result_of::size<T>::type seq_size;
- typedef typename build_indices<seq_size::value>::type indices_type;
-
- return to_qvariant<T>(x, index, indices_type{});
-} \ No newline at end of file
diff --git a/fusion_model.hpp b/fusion_model.hpp
index f40ac33..4ccaa5b 100644
--- a/fusion_model.hpp
+++ b/fusion_model.hpp
@@ -23,6 +23,7 @@ struct FusionModelInterface {
virtual std::string field_name(size_t section) const {throw std::runtime_error("\"field_name(size_t)\" not implemented for this model");}
virtual std::string key(size_t section) const {throw std::runtime_error("\"key(size_t)\" not implemented for this model");}
virtual boost::any get_cell(size_t row, size_t column) const {throw std::runtime_error("\"get_cell(size_t, size_t)\" not implemented for this model");}
+ virtual void set_cell(size_t row, size_t column, boost::any const& value) {throw std::runtime_error("\"set_cell(size_t, size_t, boost::any const&)\" not implemented for this model");}
};
template <typename T>
@@ -57,6 +58,11 @@ struct fusion_model<std::vector<T>> : public FusionModelInterface
{
return get_nth(data[row], column);
}
+
+ virtual void set_cell(size_t row, size_t column, boost::any const& value) override final
+ {
+ set_nth<row_type>(data[row], column, value);
+ }
};
template <typename T>
@@ -100,4 +106,11 @@ struct fusion_model<std::map<std::string, T>> : public FusionModelInterface
std::advance(cit, row);
return get_nth(cit->second, column);
}
+
+ virtual void set_cell(size_t row, size_t column, boost::any const& value) override final
+ {
+ auto it = data.begin();
+ std::advance(it, row);
+ set_nth<row_type>(it->second, column, value);
+ }
}; \ No newline at end of file
diff --git a/fusion_static_dispatch.hpp b/fusion_static_dispatch.hpp
index 8b68ba0..b0037a6 100644
--- a/fusion_static_dispatch.hpp
+++ b/fusion_static_dispatch.hpp
@@ -7,14 +7,6 @@
#include <functional>
-template <typename T, int index>
-struct TypeAt {
- typedef friendly_fusion::result_of::begin<T> begin;
- typedef friendly_fusion::result_of::advance_c<typename begin::type, index> adv_it;
- typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
- typedef typename std::decay<typename deref::type>::type value_type;
-};
-
#if defined( __GNUC__ ) && !defined( __clang__ )
template<int index, typename T>
std::function<boost::any(T)> make_at_c_lambda(T seq)
@@ -62,6 +54,45 @@ boost::any get_nth(T x, int index)
return get_nth_functor<T>()(x, index);
}
+template <typename T, int... Indices>
+void set_nth_impl(T& seq, int index, boost::any const& value, indices<Indices...>)
+{
+ typedef std::function<void(T&, boost::any const&)> element_type;
+ static element_type table[] =
+ {
+ [](T& seq, boost::any const& value)
+ {
+ typedef friendly_fusion::result_of::begin<T> begin;
+ typedef friendly_fusion::result_of::advance_c<typename begin::type, Indices> adv_it;
+ typedef friendly_fusion::result_of::deref<typename adv_it::type> deref;
+ typedef typename std::decay<typename deref::type>::type value_type;
+
+ friendly_fusion::deref(friendly_fusion::advance_c<Indices>(friendly_fusion::begin(seq))) = boost::any_cast<value_type>(value);
+ }
+ ...
+ };
+
+ table[index](seq, value);
+}
+
+template<typename T>
+struct set_nth_functor
+{
+ void operator()(T& seq, int index, boost::any const& value)
+ {
+ typedef typename friendly_fusion::result_of::size<T>::type seq_size;
+ typedef typename build_indices<seq_size::value>::type indices_type;
+
+ set_nth_impl(seq, index, value, indices_type{});
+ }
+};
+
+template <typename T>
+void set_nth(T& x, int index, boost::any const& value)
+{
+ set_nth_functor<T>()(x, index, value);
+}
+
#if defined( __GNUC__ ) && !defined( __clang__ )
template<int index, typename T>
std::function<std::string()> make_struct_member_name_lambda()
diff --git a/gui_item_delegate.cpp b/gui_item_delegate.cpp
index aba0727..7527020 100644
--- a/gui_item_delegate.cpp
+++ b/gui_item_delegate.cpp
@@ -2,11 +2,40 @@
#include "gui_item_delegate.hpp"
+#include <QMetaProperty>
+#include <iostream>
+
GuiItemDelegate::GuiItemDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{
}
+void GuiItemDelegate::setModelData(QWidget* widget, QAbstractItemModel* model, const QModelIndex& index) const
+{
+ static int string_id = qMetaTypeId<std::string>();
+ QByteArray n = widget->metaObject()->userProperty().name();
+ QVariant variant = widget->property(n);
+
+ if(variant.type() == QVariant::String) {
+ model->setData(index, QVariant::fromValue(variant.toString().toStdString()), Qt::EditRole);
+ } else {
+ QStyledItemDelegate::setModelData(widget, model, index);
+ }
+}
+
+void GuiItemDelegate::setEditorData(QWidget* widget, const QModelIndex& index) const
+{
+ static int string_id = qMetaTypeId<std::string>();
+ QVariant variant = index.data(Qt::EditRole);
+ QByteArray n = widget->metaObject()->userProperty().name();
+
+ if(string_id == variant.userType()) {
+ widget->setProperty(n, QVariant(QString::fromStdString(variant.value<std::string>())));
+ } else {
+ QStyledItemDelegate::setEditorData(widget, index);
+ }
+}
+
QString GuiItemDelegate::displayText(const QVariant &value, const QLocale &locale) const
{
QString ret;
diff --git a/gui_item_delegate.hpp b/gui_item_delegate.hpp
index d715dc2..b0f52a7 100644
--- a/gui_item_delegate.hpp
+++ b/gui_item_delegate.hpp
@@ -9,6 +9,8 @@ public:
explicit GuiItemDelegate(QObject *parent = 0);
virtual ~GuiItemDelegate() = default;
+ virtual void setModelData(QWidget* widget, QAbstractItemModel* model, QModelIndex const& index) const override final;
+ virtual void setEditorData(QWidget* widget, QModelIndex const& index) const override final;
virtual QString displayText(const QVariant &value, const QLocale &locale) const override final;
signals:
diff --git a/main.cpp b/main.cpp
index 380a3a9..6af725f 100644
--- a/main.cpp
+++ b/main.cpp
@@ -68,5 +68,5 @@ int main()
w.add_widget(&widget);
w.add_widget(&widget2);
- w.show_and_run();
+ return w.show_and_run();
}
diff --git a/qt_adapter.hpp b/qt_adapter.hpp
index d19a35c..8af44d7 100644
--- a/qt_adapter.hpp
+++ b/qt_adapter.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "fusion_model.hpp"
-#include "boost_any_to_qvariant.hpp"
+#include "boost_any_qvariant_convert.hpp"
#include "meta_types.hpp"
#include "gui_item_delegate.hpp"
@@ -67,6 +67,7 @@ struct QtWidget : public T {
{
T::setModel(this->model.get());
T::setItemDelegate(&delegate);
+ T::setEditTriggers(QAbstractItemView::DoubleClicked);
}
};
@@ -101,9 +102,23 @@ struct QtAdapter<T, QAbstractTableModel> : public QAbstractTableModel
return model.column_count();
}
+ bool setData(QModelIndex const& index, QVariant const& value, int role) override final
+ {
+ if(role != Qt::EditRole) return false;
+
+ model.set_cell(index.row(), index.column(), to_boost_any<typename T::row_type>(value, index.column()));
+
+ return true;
+ }
+
+ virtual Qt::ItemFlags flags(const QModelIndex &index) const
+ {
+ return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
+ }
+
virtual QVariant data(QModelIndex const& index, int role) const override
{
- if(role != Qt::DisplayRole) return QVariant();
+ if(role != Qt::DisplayRole && role != Qt::EditRole) return QVariant();
return to_qvariant<typename T::row_type>(model.get_cell(index.row(), index.column()), index.column());
}