From 79af684323abfa10abfc31003ab47fd89a03d625 Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Tue, 27 May 2014 16:14:46 +0200 Subject: Tweaked the forms look and feal a bit and changed the way models are created. --- form.hpp | 198 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 174 insertions(+), 24 deletions(-) (limited to 'form.hpp') diff --git a/form.hpp b/form.hpp index 15605a1..e90a3da 100644 --- a/form.hpp +++ b/form.hpp @@ -3,12 +3,15 @@ #include "fusion_static_dispatch.hpp" #include "gui_item_delegate.hpp" #include "boost_any_qvariant_convert.hpp" +#include "fusion_model.hpp" #include +#include #include #include #include #include +#include #include #include @@ -88,12 +91,30 @@ struct StringToBoostAny { std::stringstream ss(str); value_type x; - ss >> x; + ss >> std::boolalpha >> x; return boost::any(x); } }; +template +struct BoostAnyToString { + + typedef std::string return_type; + + template + static return_type call(boost::any any) + { + typedef typename friendly_fusion::utils::DecayedTypeOfAtIndex::type value_type; + + std::stringstream ss; + ss << std::boolalpha << boost::any_cast(any); + + return ss.str(); + } + +}; + class FormUpdateHandler : public QObject { @@ -107,8 +128,10 @@ public: : edit(edit) , cb(cb) { - connect(edit, SIGNAL(textEdited(QString const&)), - this, SLOT(edited(QString const&))); + connect( + edit, SIGNAL(textEdited(QString const&)), + this, SLOT(edited(QString const&)) + ); } private slots: @@ -119,54 +142,173 @@ private slots: }; +//This base is required because an QObject may not be templated and Form is a class template. +//Slots can be virtual however. +class QtFormBase : public QObject +{ + + Q_OBJECT + +protected slots: + virtual void prev_clicked() = 0; + virtual void jump() = 0; + virtual void next_clicked() = 0; +}; + template -struct Form : public QFormLayout{ +struct Form : public QtFormBase, public FusionModelObserver { std::shared_ptr model; QMdiArea* area; + QVBoxLayout* layout; + QFormLayout* form_layout; + QHBoxLayout* button_layout; + QPushButton* prev; + QLineEdit* jump_edit; + QPushButton* next; std::vector> updatehandlers; - std::map> line_edits; - GuiItemDelegate delegate; + std::map line_edits; + + int current_index; Form(std::shared_ptr model) : model(model) , area(new QMdiArea()) + , layout(new QVBoxLayout()) + , form_layout(new QFormLayout()) + , button_layout(new QHBoxLayout()) + , prev(new QPushButton("&Previous")) + , jump_edit(new QLineEdit()) + , next(new QPushButton("&Next")) , updatehandlers() , line_edits() - , delegate() + , current_index(0) { - area->setLayout(this); + layout->setAlignment(Qt::AlignTop); + + prev->setMaximumWidth(150); + + jump_edit->setValidator(new QIntValidator()); + jump_edit->setMaximumWidth(100); + + next->setMaximumWidth(150); + + layout->addLayout(form_layout); + layout->addLayout(button_layout); + + button_layout->addWidget(prev); + button_layout->addWidget(jump_edit); + button_layout->addWidget(next); + button_layout->setAlignment(Qt::AlignHCenter); + + area->setLayout(layout); + setup_gui(); fill_data(); + + area->updateGeometry(); + + set_button_state(); + connect( + prev, SIGNAL(clicked()), + this, SLOT(prev_clicked()) + ); + + connect( + jump_edit, SIGNAL(editingFinished()), + this, SLOT(jump()) + ); + + connect( + next, SIGNAL(clicked()), + this, SLOT(next_clicked()) + ); + + set_current_index(0); } void setup_gui() { - for(int i = 0; i < model->row_count(); ++i) { - for(int j = 0; j < model->column_count(); j++) { - QLineEdit* edit = apply_functor_to_member(j); - updatehandlers.push_back(std::make_shared(edit, [i, j, this](std::string str){update_nth(i, j, str);})); - line_edits[i][j] = edit; - this->addRow( - new QLabel(QString::fromStdString(model->field_name(j))), - edit - ); - } + for(int j = 0; j < model->column_count(); j++) { + QLineEdit* edit = apply_functor_to_member(j); + updatehandlers.push_back(std::make_shared(edit, [j, this](std::string str){update_nth_in_model(j, str);})); + line_edits[j] = edit; + form_layout->addRow( + new QLabel(QString::fromStdString(model->field_name(j))), + edit + ); } } + void update_pos(int i, int j) + { + line_edits[j]->setText(QString::fromStdString(apply_functor_to_member(j, model->get_cell(i, j)))); + } + void fill_data() { - for(int i = 0; i < model->row_count(); ++i) { - for(int j = 0; j < model->column_count(); j++) { - line_edits[i][j]->setText(delegate.displayText(to_qvariant(model->get_cell(i, j), j))); - } + for(int j = 0; j < model->column_count(); j++) { + update_pos(current_index, j); } } - void update_nth(int row, int column, std::string str) + void set_button_state() + { + prev->setEnabled(current_index != 0); + next->setEnabled(current_index != model->row_count() - 1); + } + + void update_nth_in_model(int entry, std::string str) + { + model->set_cell(current_index, entry, apply_functor_to_member(entry, str)); + } + + void set_current_index(int i) { - model->set_cell(row, column, apply_functor_to_member(column, str)); + current_index = i; + fill_data(); + set_button_state(); + jump_edit->setText(QString::number(i + 1)); + } + + int clamp_index(int i) + { + if(i < 0) { + i = 0; + } + + if(i > model->row_count() - 1) { + i = model->row_count() - 1; + } + + return i; + } + + //Observer interface + virtual void cell_changed(int form_id, int entry) override final + { + update_pos(form_id, entry); + } + + //Gui interface. + virtual void prev_clicked() override final + { + int i = clamp_index(current_index - 1); + set_current_index(i); + } + + virtual void jump() override final + { + int jump_to = jump_edit->text().toInt() - 1; + int i = clamp_index(jump_to); + + set_current_index(i); + } + + virtual void next_clicked() override final + { + int i = clamp_index(current_index + 1); + set_current_index(i); } QWidget* get_widget() @@ -174,3 +316,11 @@ struct Form : public QFormLayout{ return area; } }; + +template +std::shared_ptr> make_form(std::shared_ptr model) +{ + auto ret = std::make_shared>(model); + model->add_observer(ret); + return ret; +} -- cgit v1.2.3-70-g09d2