ui/qt/model.cpp

changeset 108
77254bd6dccb
parent 103
6606616eca9f
child 109
c3dfcb8f0be7
--- 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());
+}

mercurial