/** \file liststore.c * Handling of the list store used for tree views and drop boxes */ /* * * Copyright 2016 Martin Fischer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * */ #include #include #include #include #define GTK_DISABLE_SINGLE_INCLUDES #define GDK_DISABLE_DEPRECATED #define GTK_DISABLE_DEPRECATED #define GSEAL_ENABLE #include #include #include "gtkint.h" /** * Get data of one row in a list * \param b IN list widget * \param inx IN row to retrieve * \param childR IN list for data (?) * \returns */ wListItem_p wlibListItemGet( GtkListStore *ls, wIndex_t inx, GList ** childR) { wListItem_p id_p; assert(ls != NULL); if (childR) { *childR = NULL; } if (inx < 0) { return NULL; } id_p = wlibListStoreGetContext(ls, inx); return id_p; } /** * Get the context (user data) for a row in the list store * * \param ls IN list store * \param inx IN row * \returns pointer to data */ void * wlibListStoreGetContext(GtkListStore *ls, int inx) { GtkTreeIter iter; gchar *string = NULL; gboolean result; gint childs; childs = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(ls), NULL); if (inx < childs) { result = gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ls), &iter, NULL, inx); if (result) { gtk_tree_model_get(GTK_TREE_MODEL(ls), &iter, LISTCOL_DATA, &string, -1); } else { printf("Invalid index %d for list!\n", inx); } } return (string); } /** * Clear the list store. All data in the list store will be automatically * free'd when the list store is cleared. * * \param listStore IN */ void wlibListStoreClear(GtkListStore *listStore) { wListItem_p id_p; int i = 0; assert(listStore != NULL); id_p = wlibListStoreGetContext(listStore, i++); while (id_p) { if (id_p->label) g_free(id_p->label); g_free(id_p); id_p = wlibListStoreGetContext(listStore, i++); } gtk_list_store_clear(listStore); } /** * Create a list store. The list store will have one column for user * data that will not be displayed, a column for a bitmap and * colors for data. * * \param colCnt IN number of additional columns * \returns the list store */ GtkListStore * wlibNewListStore(int colCnt) { GtkListStore *ls; GType *colTypes; int i; /* create the list store, using strings for all columns */ colTypes = g_malloc(sizeof(GType) * (colCnt + LISTCOL_TEXT)); colTypes[ LISTCOL_BITMAP ] = GDK_TYPE_PIXBUF; colTypes[ LISTCOL_DATA ] = G_TYPE_POINTER; for (i = 0; i < colCnt; i++) { colTypes[ LISTCOL_TEXT + i ] = G_TYPE_STRING; } ls = gtk_list_store_newv(colCnt + LISTCOL_TEXT, colTypes); g_free(colTypes); return (ls); } /** * Update the list store at the iter's position * * \param ls IN list store * \param iter IN iterator into list store * \param labels IN tab separated label string * \returns number of updated columns */ static int wlibListStoreUpdateIter(GtkListStore *ls, GtkTreeIter *iter, char *labels) { char *convertedLabels; char *text; char *start; int current = 0; convertedLabels = strdup(wlibConvertInput(labels)); start = convertedLabels; while ((text = strchr(start, '\t')) != NULL) { *text = '\0'; gtk_list_store_set(ls, iter, LISTCOL_TEXT + current, start, -1); start = text + 1; current++; } /* add the last piece of the string */ gtk_list_store_set(ls, iter, LISTCOL_TEXT + current, start, -1); free(convertedLabels); return (current+1); } /** * Add a pixbuf to the list store. So pixbuf is unref'ed so it will be freed * with the list store. * * \param ls IN list store * \param iter IN position * \param pixbuf IN pixbuf to add */ void wlibListStoreSetPixbuf(GtkListStore *ls, GtkTreeIter *iter, GdkPixbuf *pixbuf) { gtk_list_store_set(ls, iter, LISTCOL_BITMAP, pixbuf, -1); g_object_ref_sink(pixbuf); g_object_unref(pixbuf); } /** * Add a row to the list store * * \param ls IN the list store * \param cols IN columns in list store * \param id IN id * \returns number columns added */ int wlibListStoreAddData(GtkListStore *ls, GdkPixbuf *pixbuf, int cols, wListItem_p id) { GtkTreeIter iter; int count; gtk_list_store_append(ls, &iter); gtk_list_store_set(ls, &iter, LISTCOL_DATA, id, -1); if (pixbuf) { wlibListStoreSetPixbuf(ls, &iter, pixbuf); } count = wlibListStoreUpdateIter(ls, &iter, (char *)id->label); return (count); } /** * Change a row in the list store. The passed strings are placed * in the first cols text columns of the list store. * * \param ls IN list store * \param row IN row in list store * \param cols IN number of columns to set * \param labels IN tab separated list of texts * \param bm IN bitmap * \return count of updated text fields */ int wlibListStoreUpdateValues(GtkListStore *ls, int row, int cols, char *labels, wIcon_p bm) { GtkTreeIter iter; int count; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(ls), &iter, NULL, row); count = wlibListStoreUpdateIter(ls, &iter, labels); if (bm) { GdkPixbuf *pixbuf; pixbuf = wlibMakePixbuf(bm); wlibListStoreSetPixbuf(ls, &iter, pixbuf); } return (count); }