#pragma once #include "fusion_model.hpp" #include "boost_any_qvariant_convert.hpp" #include "meta_types.hpp" #include "gui_item_delegate.hpp" #include #include #include #include #include #include #include #include template struct QtModelType { typedef void type; }; template struct QtModelType> { typedef QAbstractTableModel type; }; template struct QtModelType> { typedef QAbstractTableModel type; }; template struct QtAdapter : public Q { typedef void view; QtAdapter(std::shared_ptr) {} }; template struct AdapterType; template struct QtWidget : public T { GuiItemDelegate delegate; std::shared_ptr::type> model; QtWidget(std::shared_ptr model, QWidget* parent = nullptr) : T(parent) , delegate() , model(std::make_shared::type>(model)) { model->add_observer(this->model); T::setModel(this->model.get()); T::setItemDelegate(&delegate); T::setEditTriggers(QAbstractItemView::DoubleClicked); } }; template struct QtAdapterBase : public Model, public FusionModelObserver { virtual void cell_changed(int row, int column) override { emit this->dataChanged(this->createIndex(row, column), this->createIndex(row, column)); } virtual void append_row_begin() override { this->beginInsertRows(QModelIndex(), this->rowCount(QModelIndex()), this->rowCount(QModelIndex())); } virtual void append_row_end() override { this->endInsertRows(); } }; template struct QtAdapter : public QtAdapterBase { typedef QTableView view; typedef QtWidget widget; std::shared_ptr model; QtAdapter(std::shared_ptr model) : model(model) {} virtual int rowCount(QModelIndex const&) const override { return model->row_count(); } virtual int columnCount(QModelIndex const&) const override { 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(value, index.column())); return true; } virtual Qt::ItemFlags flags(const QModelIndex &index) const { bool constness = is_const(index.column()); return QAbstractTableModel::flags(index) | (constness ? Qt::NoItemFlags : Qt::ItemIsEditable); } virtual QVariant data(QModelIndex const& index, int role) const override { if(role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); return to_qvariant(model->get_cell(index.row(), index.column()), index.column()); } template typename std::enable_if::type get_key(int section) const { return QVariant(QString::fromStdString(model->key(section))); } template typename std::enable_if::type get_key(int section) const { return QVariant(); } template typename std::enable_if::type get_field_name(int section) const { return QVariant(QString::fromStdString(model->field_name(section))); } template typename std::enable_if::type get_field_name(int section) const { return QVariant(); } virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const override { if(role != Qt::DisplayRole) { return QVariant(); } if(orientation == Qt::Horizontal) { return get_field_name(section); } if(orientation == Qt::Vertical) { return get_key(section); } return QVariant(); } }; template struct AdapterType { typedef QtAdapter::type> type; }; template struct WidgetType { typedef typename AdapterType::type::widget type; }; template std::shared_ptr::type> make_qt_widget(std::shared_ptr x) { auto widget_ptr = std::make_shared::type>(x); return widget_ptr; }