| 26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ |
27 */ |
| 28 |
28 |
| 29 #include "model.h" |
29 #include "model.h" |
| 30 |
30 |
| |
31 static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { |
| |
32 if(model->getvalue2) { |
| |
33 return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); |
| |
34 } else if(model->getvalue) { |
| |
35 return model->getvalue(elm, col); |
| |
36 } |
| |
37 return NULL; |
| |
38 } |
| |
39 |
| |
40 ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc2 getvalue, void *getvaluedata){ |
| |
41 this->obj = obj; |
| |
42 this->view = view; |
| |
43 this->var = var; |
| |
44 this->getvalue = getvalue; |
| |
45 this->getvaluedata = getvaluedata; |
| |
46 this->onactivate = nullptr; |
| |
47 this->onactivatedata = nullptr; |
| |
48 this->onselection = nullptr; |
| |
49 this->onselectiondata = nullptr; |
| |
50 } |
| |
51 |
| |
52 void ListModel::setActivationCallback(ui_callback f, void *userdata) { |
| |
53 onactivate = f; |
| |
54 onactivatedata = userdata; |
| |
55 } |
| |
56 |
| |
57 void ListModel::setSelectionCallback(ui_callback f, void *userdata) { |
| |
58 onselection = f; |
| |
59 onselectiondata = userdata; |
| |
60 } |
| |
61 |
| |
62 void ListModel::update(int row) { |
| |
63 if(row >= 0) { |
| |
64 this->update(row); |
| |
65 } else { |
| |
66 this->beginResetModel(); |
| |
67 this->endResetModel(); |
| |
68 } |
| |
69 } |
| |
70 |
| |
71 int ListModel::rowCount(const QModelIndex& parent) const { |
| |
72 UiList *list = (UiList*)var->value; |
| |
73 return ui_list_count(list); |
| |
74 } |
| |
75 |
| |
76 QVariant ListModel::data(const QModelIndex &index, int role) const { |
| |
77 if(role == Qt::DisplayRole) { |
| |
78 UiList *ls = (UiList*)var->value; |
| |
79 void *rowData = ls->get(ls, index.row()); |
| |
80 if(rowData && getvalue) { |
| |
81 UiBool freeResult = false; |
| |
82 void *value = getvalue(ls, rowData, index.row(), 0, getvaluedata, &freeResult); |
| |
83 if(value) { |
| |
84 auto qs = QString::fromUtf8((char*)value); |
| |
85 if(freeResult) { |
| |
86 free(value); |
| |
87 } |
| |
88 return qs; |
| |
89 } |
| |
90 } |
| |
91 } |
| |
92 return QVariant(); |
| |
93 } |
| |
94 |
| |
95 void ListModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { |
| |
96 UiListSelection sel = ui_selection_model_to_selection(view->selectionModel()); |
| |
97 |
| |
98 UiEvent event; |
| |
99 event.obj = obj; |
| |
100 event.window = obj->window; |
| |
101 event.document = obj->ctx->document; |
| |
102 event.eventdata = &sel; |
| |
103 event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; |
| |
104 event.intval = sel.count; |
| |
105 event.set = ui_get_setop(); |
| |
106 |
| |
107 if(onactivate) { |
| |
108 onactivate(&event, onactivatedata); |
| |
109 } |
| |
110 if(onselection) { |
| |
111 onselection(&event, onselectiondata); |
| |
112 } |
| |
113 |
| |
114 free(sel.rows); |
| |
115 } |
| |
116 |
| |
117 |
| |
118 |
| |
119 TableModel::TableModel(UiObject *obj, QTreeView *view, UiVar *var, UiModel *model){ |
| |
120 this->obj = obj; |
| |
121 this->view = view; |
| |
122 this->var = var; |
| |
123 this->model = model; |
| |
124 this->onactivate = nullptr; |
| |
125 this->onactivatedata = nullptr; |
| |
126 this->onselection = nullptr; |
| |
127 this->onselectiondata = nullptr; |
| |
128 } |
| |
129 |
| |
130 void TableModel::setActivationCallback(ui_callback f, void *userdata) { |
| |
131 onactivate = f; |
| |
132 onactivatedata = userdata; |
| |
133 } |
| |
134 |
| |
135 void TableModel::setSelectionCallback(ui_callback f, void *userdata) { |
| |
136 onselection = f; |
| |
137 onselectiondata = userdata; |
| |
138 } |
| |
139 |
| |
140 void TableModel::update(int row) { |
| |
141 if(row >= 0) { |
| |
142 this->update(row); |
| |
143 } else { |
| |
144 this->beginResetModel(); |
| |
145 this->endResetModel(); |
| |
146 } |
| |
147 } |
| |
148 |
| |
149 int TableModel::rowCount(const QModelIndex& parent) const { |
| |
150 UiList *list = (UiList*)var->value; |
| |
151 return ui_list_count(list); |
| |
152 } |
| |
153 |
| |
154 int TableModel::columnCount(const QModelIndex &parent) const { |
| |
155 return model->columns; |
| |
156 } |
| |
157 |
| |
158 QVariant TableModel::data(const QModelIndex &index, int role) const { |
| |
159 if(role == Qt::DisplayRole) { |
| |
160 UiList *ls = (UiList*)var->value; |
| |
161 void *rowData = ls->get(ls, index.row()); |
| |
162 if(rowData) { |
| |
163 int col = index.column(); |
| |
164 UiBool freeResult = false; |
| |
165 void *value = model_getvalue(model, ls, rowData, index.row(), col, &freeResult); |
| |
166 if(value) { |
| |
167 UiModelType type = model->types[col]; |
| |
168 switch(type) { |
| |
169 case UI_STRING: { |
| |
170 auto qs = QString::fromUtf8((char*)value); |
| |
171 if(freeResult) { |
| |
172 free(value); |
| |
173 } |
| |
174 return qs; |
| |
175 } |
| |
176 case UI_STRING_FREE: { |
| |
177 QString s = QString::fromUtf8((char*)value); |
| |
178 free(value); |
| |
179 return s; |
| |
180 } |
| |
181 case UI_INTEGER: { |
| |
182 intptr_t i = (intptr_t)value; |
| |
183 return QString::number(i); |
| |
184 } |
| |
185 case UI_ICON: { |
| |
186 break; // TODO |
| |
187 } |
| |
188 case UI_ICON_TEXT: { |
| |
189 break; // TODO |
| |
190 } |
| |
191 case UI_ICON_TEXT_FREE: { |
| |
192 break; // TODO |
| |
193 } |
| |
194 } |
| |
195 } |
| |
196 } |
| |
197 } |
| |
198 return QVariant(); |
| |
199 } |
| |
200 |
| |
201 QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const { |
| |
202 if(role == Qt::DisplayRole) { |
| |
203 char *label = model->titles[section]; |
| |
204 return QString::fromUtf8(label); |
| |
205 } |
| |
206 return QVariant(); |
| |
207 } |
| |
208 |
| |
209 void TableModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { |
| |
210 UiListSelection sel = ui_selection_model_to_selection(view->selectionModel()); |
| |
211 |
| |
212 UiEvent event; |
| |
213 event.obj = obj; |
| |
214 event.window = obj->window; |
| |
215 event.document = obj->ctx->document; |
| |
216 event.eventdata = &sel; |
| |
217 event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; |
| |
218 event.intval = sel.count; |
| |
219 event.set = ui_get_setop(); |
| |
220 |
| |
221 if(onactivate) { |
| |
222 onactivate(&event, onactivatedata); |
| |
223 } |
| |
224 if(onselection) { |
| |
225 onselection(&event, onselectiondata); |
| |
226 } |
| |
227 |
| |
228 free(sel.rows); |
| |
229 } |
| |
230 |
| |
231 |
| |
232 |
| |
233 UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model) { |
| |
234 UiListSelection sel; |
| |
235 sel.rows = NULL; |
| |
236 sel.count = 0; |
| |
237 |
| |
238 if(model->hasSelection()) { |
| |
239 QModelIndexList indices = model->selectedIndexes(); |
| |
240 sel.count = indices.count(); |
| |
241 sel.rows = (int*)calloc(sel.count, sizeof(int)); |
| |
242 |
| |
243 int i = 0; |
| |
244 for (const QModelIndex &index : indices) { |
| |
245 sel.rows[i++] = index.row(); |
| |
246 } |
| |
247 } |
| |
248 |
| |
249 return sel; |
| |
250 } |
| |
251 |
| |
252 /* ---------------------- UiList implementation -----------------------------*/ |
| |
253 |
| |
254 void ui_listmodel_update(UiList *list, int row) { |
| |
255 ListModel *model = (ListModel*)list->obj; |
| |
256 model->update(row); |
| |
257 } |
| |
258 |
| |
259 void ui_listmodel_setselection(UiList *list, UiListSelection sel) { |
| |
260 ListModel *model = (ListModel*)list->obj; |
| |
261 QItemSelection selection; |
| |
262 for (int i=0;i<sel.count;i++) { |
| |
263 QModelIndex index = model->index(sel.rows[i]); |
| |
264 selection.select(index, index); |
| |
265 } |
| |
266 model->view->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); |
| |
267 } |
| |
268 |
| |
269 UiListSelection ui_listmodel_getselection(UiList *list) { |
| |
270 ListModel *model = (ListModel*)list->obj; |
| |
271 return ui_selection_model_to_selection(model->view->selectionModel()); |
| |
272 } |