ui/qt/model.cpp

Sun, 24 Aug 2025 15:24:16 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 24 Aug 2025 15:24:16 +0200
changeset 109
c3dfcb8f0be7
parent 108
77254bd6dccb
permissions
-rw-r--r--

update toolkit, remove getvalue func from model to table/listview args

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2014 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "model.h"


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, ui_getvaluefunc2 getvalue, void *getvaluedata){
    this->obj = obj;
    this->view = view;
    this->var = var;
    this->model = model;
    this->getvalue = getvalue;
    this->getvaluedata = getvaluedata;
    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 = getvalue(ls, rowData, index.row(), col, getvaluedata, &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