Project

General

Profile

Bug #3371 ยป modelview2.cpp

Alexander Morozov, 06/23/2014 04:28 PM

 
1
#include <string>
2
#include <vector>
3
#include <boost/any.hpp>
4
#include <boost/thread.hpp>
5
#include <Wt/WAbstractItemDelegate>
6
#include <Wt/WAbstractTableModel>
7
#include <Wt/WApplication>
8
#include <Wt/WPushButton>
9
#include <Wt/WTableView>
10

    
11
using namespace Wt;
12

    
13
class Model : public WAbstractTableModel
14
{
15
public:
16
    Model(WObject *parent = 0);
17

    
18
    virtual int columnCount(const WModelIndex &parent = WModelIndex()) const;
19
    virtual int rowCount(const WModelIndex &parent = WModelIndex()) const;
20
    virtual boost::any data(const WModelIndex &index, int role = DisplayRole) const;
21

    
22
    void push_front(const std::string &text);
23
    void pop_front();
24

    
25
private:
26
    std::vector<std::string> data_;
27
};
28

    
29
Model::Model(WObject *parent) :
30
    WAbstractTableModel(parent)
31
{
32
    data_.push_back("1");
33
    data_.push_back("2");
34
    data_.push_back("3");
35
    data_.push_back("4");
36
    data_.push_back("5");
37
}
38

    
39
int Model::columnCount(const WModelIndex &parent) const
40
{
41
    return 1;
42
}
43

    
44
int Model::rowCount(const WModelIndex &parent) const
45
{
46
    return data_.size();
47
}
48

    
49
boost::any Model::data(const WModelIndex &index, int role) const
50
{
51
    if (role != DisplayRole) return boost::any();
52
    if (index.row() >= data_.size()) return boost::any();
53
    return boost::any(data_[index.row()]);
54
}
55

    
56
void Model::push_front(const std::string &text)
57
{
58
    beginInsertRows(WModelIndex(), 0, 0);
59
    data_.insert(data_.begin(), text);
60
    endInsertRows();
61
}
62

    
63
void Model::pop_front()
64
{
65
    if (data_.size()) {
66
        beginRemoveRows(WModelIndex(), 0, 0);
67
        data_.erase(data_.begin());
68
        endRemoveRows();
69
    }
70
}
71

    
72
class ItemWidget : public WPushButton
73
{
74
public:
75
    ItemWidget(const WModelIndex &index, WContainerWidget *parent = 0) :
76
        WPushButton(parent), index_(index), state_(0)
77
    {
78
        onClicked();
79
        clicked().connect(this, &ItemWidget::onClicked);
80
    }
81

    
82
    void setIndex(const WModelIndex &index) { index_ = index; }
83

    
84
private:
85
    void onClicked();
86

    
87
    WModelIndex index_;
88
    int state_;
89
};
90

    
91
void ItemWidget::onClicked()
92
{
93
    if (state_) {
94
        setText(boost::any_cast<const std::string &>(index_.data()));
95
        state_ = 0;
96
    } else {
97
        setText("[" + boost::any_cast<const std::string &>(index_.data()) + "]");
98
        state_ = 1;
99
    }
100
}
101

    
102
class Delegate : public WAbstractItemDelegate
103
{
104
public:
105
    Delegate(WObject *parent = 0) : WAbstractItemDelegate(parent) {}
106

    
107
    virtual WWidget *update(WWidget *widget, const WModelIndex &index,
108
            WFlags<ViewItemRenderFlag> flags);
109

    
110
    virtual void updateModelIndex(WWidget *widget, const WModelIndex &index);
111
};
112

    
113
WWidget *Delegate::update(WWidget *widget, const WModelIndex &index,
114
        WFlags<ViewItemRenderFlag> flags)
115
{
116
    if (widget) {
117
        updateModelIndex(widget, index);
118
        return widget;
119
    } else {
120
        WContainerWidget *container = new WContainerWidget;
121
        new ItemWidget(index, container);
122
        return container;
123
    }
124
}
125

    
126
void Delegate::updateModelIndex(WWidget *widget, const WModelIndex &index)
127
{
128
    WContainerWidget *container = dynamic_cast<WContainerWidget *>(widget);
129
    assert(container);
130
    ItemWidget *item = dynamic_cast<ItemWidget *>(container->widget(0));
131
    assert(item);
132
    item->setIndex(index);
133
}
134

    
135
class App : public WApplication
136
{
137
public:
138
    App(const WEnvironment &env);
139

    
140
private:
141
    void addRow();
142
    void removeRow();
143

    
144
    Model *model_;
145
    WTableView *table_;
146
};
147

    
148
App::App(const WEnvironment &env) :
149
    WApplication(env)
150
{
151
    model_ = new Model(this);
152

    
153
    Delegate *delegate = new Delegate(this);
154

    
155
    table_ = new WTableView(root());
156
    table_->setHeaderHeight(0);
157
    table_->setRowHeight(30);
158
    table_->setModel(model_);
159
    table_->setItemDelegate(delegate);
160

    
161
    WPushButton *addButton = new WPushButton("Add", root());
162
    WPushButton *removeButton = new WPushButton("Remove", root());
163
    addButton->clicked().connect(this, &App::addRow);
164
    removeButton->clicked().connect(this, &App::removeRow);
165
}
166

    
167
void App::addRow()
168
{
169
    model_->push_front("x");
170
}
171

    
172
void App::removeRow()
173
{
174
    model_->pop_front();
175
}
176

    
177
static WApplication *createApplication(const WEnvironment &env)
178
{
179
    return new App(env);
180
}
181

    
182
int main(int argc, char **argv)
183
{
184
    return WRun(argc, argv, createApplication);
185
}
    (1-1/1)