--- a/ui/qt/model.cpp Sat Apr 05 17:57:04 2025 +0200 +++ b/ui/qt/model.cpp Sun Jul 20 22:04:39 2025 +0200 @@ -28,3 +28,245 @@ #include "model.h" +static void* model_getvalue(UiModel *model, UiList *list, void *elm, int row, int col, UiBool *freeResult) { + if(model->getvalue2) { + return model->getvalue2(list, elm, row, col, model->getvalue2data, freeResult); + } else if(model->getvalue) { + return model->getvalue(elm, col); + } + return NULL; +} + +ListModel::ListModel(UiObject *obj, QListView *view, UiVar *var, ui_getvaluefunc2 getvalue, void *getvaluedata){ + this->obj = obj; + this->view = view; + this->var = var; + this->getvalue = getvalue; + this->getvaluedata = getvaluedata; + this->onactivate = nullptr; + this->onactivatedata = nullptr; + this->onselection = nullptr; + this->onselectiondata = nullptr; +} + +void ListModel::setActivationCallback(ui_callback f, void *userdata) { + onactivate = f; + onactivatedata = userdata; +} + +void ListModel::setSelectionCallback(ui_callback f, void *userdata) { + onselection = f; + onselectiondata = userdata; +} + +void ListModel::update(int row) { + if(row >= 0) { + this->update(row); + } else { + this->beginResetModel(); + this->endResetModel(); + } +} + +int ListModel::rowCount(const QModelIndex& parent) const { + UiList *list = (UiList*)var->value; + return ui_list_count(list); +} + +QVariant ListModel::data(const QModelIndex &index, int role) const { + if(role == Qt::DisplayRole) { + UiList *ls = (UiList*)var->value; + void *rowData = ls->get(ls, index.row()); + if(rowData && getvalue) { + UiBool freeResult = false; + void *value = getvalue(ls, rowData, index.row(), 0, getvaluedata, &freeResult); + if(value) { + auto qs = QString::fromUtf8((char*)value); + if(freeResult) { + free(value); + } + return qs; + } + } + } + return QVariant(); +} + +void ListModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { + UiListSelection sel = ui_selection_model_to_selection(view->selectionModel()); + + UiEvent event; + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + event.eventdata = &sel; + event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; + event.intval = sel.count; + event.set = ui_get_setop(); + + if(onactivate) { + onactivate(&event, onactivatedata); + } + if(onselection) { + onselection(&event, onselectiondata); + } + + free(sel.rows); +} + + + +TableModel::TableModel(UiObject *obj, QTreeView *view, UiVar *var, UiModel *model){ + this->obj = obj; + this->view = view; + this->var = var; + this->model = model; + this->onactivate = nullptr; + this->onactivatedata = nullptr; + this->onselection = nullptr; + this->onselectiondata = nullptr; +} + +void TableModel::setActivationCallback(ui_callback f, void *userdata) { + onactivate = f; + onactivatedata = userdata; +} + +void TableModel::setSelectionCallback(ui_callback f, void *userdata) { + onselection = f; + onselectiondata = userdata; +} + +void TableModel::update(int row) { + if(row >= 0) { + this->update(row); + } else { + this->beginResetModel(); + this->endResetModel(); + } +} + +int TableModel::rowCount(const QModelIndex& parent) const { + UiList *list = (UiList*)var->value; + return ui_list_count(list); +} + +int TableModel::columnCount(const QModelIndex &parent) const { + return model->columns; +} + +QVariant TableModel::data(const QModelIndex &index, int role) const { + if(role == Qt::DisplayRole) { + UiList *ls = (UiList*)var->value; + void *rowData = ls->get(ls, index.row()); + if(rowData) { + int col = index.column(); + UiBool freeResult = false; + void *value = model_getvalue(model, ls, rowData, index.row(), col, &freeResult); + if(value) { + UiModelType type = model->types[col]; + switch(type) { + case UI_STRING: { + auto qs = QString::fromUtf8((char*)value); + if(freeResult) { + free(value); + } + return qs; + } + case UI_STRING_FREE: { + QString s = QString::fromUtf8((char*)value); + free(value); + return s; + } + case UI_INTEGER: { + intptr_t i = (intptr_t)value; + return QString::number(i); + } + case UI_ICON: { + break; // TODO + } + case UI_ICON_TEXT: { + break; // TODO + } + case UI_ICON_TEXT_FREE: { + break; // TODO + } + } + } + } + } + return QVariant(); +} + +QVariant TableModel::headerData(int section, Qt::Orientation orientation, int role) const { + if(role == Qt::DisplayRole) { + char *label = model->titles[section]; + return QString::fromUtf8(label); + } + return QVariant(); +} + +void TableModel::selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) { + UiListSelection sel = ui_selection_model_to_selection(view->selectionModel()); + + UiEvent event; + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + event.eventdata = &sel; + event.eventdatatype = UI_EVENT_DATA_LIST_SELECTION; + event.intval = sel.count; + event.set = ui_get_setop(); + + if(onactivate) { + onactivate(&event, onactivatedata); + } + if(onselection) { + onselection(&event, onselectiondata); + } + + free(sel.rows); +} + + + +UiListSelection ui_selection_model_to_selection(QItemSelectionModel *model) { + UiListSelection sel; + sel.rows = NULL; + sel.count = 0; + + if(model->hasSelection()) { + QModelIndexList indices = model->selectedIndexes(); + sel.count = indices.count(); + sel.rows = (int*)calloc(sel.count, sizeof(int)); + + int i = 0; + for (const QModelIndex &index : indices) { + sel.rows[i++] = index.row(); + } + } + + return sel; +} + +/* ---------------------- UiList implementation -----------------------------*/ + +void ui_listmodel_update(UiList *list, int row) { + ListModel *model = (ListModel*)list->obj; + model->update(row); +} + +void ui_listmodel_setselection(UiList *list, UiListSelection sel) { + ListModel *model = (ListModel*)list->obj; + QItemSelection selection; + for (int i=0;i<sel.count;i++) { + QModelIndex index = model->index(sel.rows[i]); + selection.select(index, index); + } + model->view->selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect); +} + +UiListSelection ui_listmodel_getselection(UiList *list) { + ListModel *model = (ListModel*)list->obj; + return ui_selection_model_to_selection(model->view->selectionModel()); +}