ali@9: /* ali@9: * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford ali@9: * Copyright (C) 2010 J. Ali Harlow ali@9: * ali@9: * This program is free software; you can redistribute it and/or modify ali@9: * it under the terms of the GNU General Public License as published by ali@9: * the Free Software Foundation; either version 2 of the License, or ali@9: * (at your option) any later version. ali@9: * ali@9: * This program is distributed in the hope that it will be useful, ali@9: * but WITHOUT ANY WARRANTY; without even the implied warranty of ali@9: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ali@9: * GNU General Public License for more details. ali@9: * ali@9: * You should have received a copy of the GNU General Public License along ali@9: * with this program; if not, write to the Free Software Foundation, Inc., ali@9: * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ali@9: */ ali@9: ali@9: #include "config.h" ali@9: #include ali@9: #include ali@9: #include ali@9: #include ali@9: #include "plover-gtk/packagefilestore.h" ali@9: ali@9: #define VALID_ITER(iter,store) ((iter) && (iter)->user_data && \ ali@9: PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store)->stamp==(iter)->stamp && \ ali@9: !g_sequence_iter_is_end((iter)->user_data) && \ ali@9: g_sequence_iter_get_sequence((iter)->user_data)== \ ali@9: PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store)->seq) ali@9: ali@9: static GType column_types[PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS]; ali@9: ali@9: static void plover_package_file_store_tree_model_init(GtkTreeModelIface *iface); ali@9: ali@9: G_DEFINE_TYPE_WITH_CODE(PloverPackageFileStore,plover_package_file_store, ali@9: G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL, ali@9: plover_package_file_store_tree_model_init)); ali@9: ali@9: typedef struct _PloverPackageFileStorePrivate { ali@9: GSequence *seq; ali@9: int stamp; ali@9: } PloverPackageFileStorePrivate; ali@9: ali@9: #define PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(obj)\ ali@9: G_TYPE_INSTANCE_GET_PRIVATE(obj,\ ali@9: PLOVER_TYPE_PACKAGE_FILE_STORE,\ ali@9: PloverPackageFileStorePrivate) ali@9: ali@9: static void plover_package_file_store_finalize(GObject *obj) ali@9: { ali@9: PloverPackageFileStorePrivate *priv= ali@9: PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(obj); ali@9: g_sequence_free(priv->seq); ali@9: if (G_OBJECT_CLASS(plover_package_file_store_parent_class)->finalize) ali@9: G_OBJECT_CLASS(plover_package_file_store_parent_class)->finalize(obj); ali@9: } ali@9: ali@9: static void ali@9: plover_package_file_store_class_init(PloverPackageFileStoreClass *klass) ali@9: { ali@9: GObjectClass *oclass=G_OBJECT_CLASS(klass); ali@9: oclass->finalize=plover_package_file_store_finalize; ali@9: g_type_class_add_private(klass,sizeof(PloverPackageFileStorePrivate)); ali@9: column_types[PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN]=G_TYPE_STRING; ali@9: } ali@9: ali@9: static GtkTreeModelFlags ali@9: plover_package_file_store_get_flags(GtkTreeModel *tree_model) ali@9: { ali@9: return GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY; ali@9: } ali@9: ali@9: static gint plover_package_file_store_get_n_columns(GtkTreeModel *tree_model) ali@9: { ali@9: return PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS; ali@9: } ali@9: ali@9: static GType ali@9: plover_package_file_store_get_column_type(GtkTreeModel *tree_model,gint indx) ali@9: { ali@9: PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model; ali@9: g_return_val_if_fail(indx>=0 && indx=g_sequence_get_length(priv->seq)) ali@9: return FALSE; ali@9: iter->stamp=priv->stamp; ali@9: iter->user_data=g_sequence_get_iter_at_pos(priv->seq,i); ali@9: return TRUE; ali@9: } ali@9: ali@9: static GtkTreePath * ali@9: plover_package_file_store_get_path(GtkTreeModel *tree_model,GtkTreeIter *iter) ali@9: { ali@9: GtkTreePath *path; ali@9: g_return_val_if_fail(VALID_ITER(iter,tree_model),NULL); ali@9: if (g_sequence_iter_is_end(iter->user_data)) ali@9: return NULL; ali@9: path=gtk_tree_path_new(); ali@9: gtk_tree_path_append_index(path, ali@9: g_sequence_iter_get_position(iter->user_data)); ali@9: return path; ali@9: } ali@9: ali@9: static void plover_package_file_store_get_value(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter,gint column,GValue *value) ali@9: { ali@9: PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model; ali@9: char *name; ali@9: g_return_if_fail(column>=0 && columnuser_data); ali@9: g_value_init(value,column_types[column]); ali@9: switch((PloverPackageFileStoreColumn)column) ali@9: { ali@9: case PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN: ali@9: g_value_set_string(value,name); ali@9: break; ali@9: } ali@9: } ali@9: ali@9: static gboolean plover_package_file_store_iter_next(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter) ali@9: { ali@9: g_return_val_if_fail(VALID_ITER(iter,tree_model),FALSE); ali@9: iter->user_data=g_sequence_iter_next(iter->user_data); ali@9: return !g_sequence_iter_is_end(iter->user_data); ali@9: } ali@9: ali@9: static gboolean ali@9: plover_package_file_store_iter_children(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter,GtkTreeIter *parent) ali@9: { ali@9: PloverPackageFileStorePrivate *priv; ali@9: PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model; ali@9: priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model); ali@9: /* this is a list, nodes have no children */ ali@9: if (parent) ali@9: return FALSE; ali@9: if (g_sequence_get_length(priv->seq)>0) ali@9: { ali@9: iter->stamp=priv->stamp; ali@9: iter->user_data=g_sequence_get_begin_iter(priv->seq); ali@9: return TRUE; ali@9: } ali@9: else ali@9: return FALSE; ali@9: } ali@9: ali@9: static gboolean ali@9: plover_package_file_store_iter_has_child(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter) ali@9: { ali@9: return FALSE; ali@9: } ali@9: ali@9: static gint plover_package_file_store_iter_n_children(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter) ali@9: { ali@9: PloverPackageFileStorePrivate *priv; ali@9: PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model; ali@9: priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model); ali@9: if (!iter) ali@9: return g_sequence_get_length(priv->seq); ali@9: g_return_val_if_fail(VALID_ITER(iter,tree_model),-1); ali@9: return 0; ali@9: } ali@9: ali@9: static gboolean ali@9: plover_package_file_store_iter_nth_child(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter,GtkTreeIter *parent,gint n) ali@9: { ali@9: PloverPackageFileStorePrivate *priv; ali@9: PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model; ali@9: priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model); ali@9: GSequenceIter *child; ali@9: if (parent) ali@9: return FALSE; ali@9: child=g_sequence_get_iter_at_pos(priv->seq,n); ali@9: if (g_sequence_iter_is_end(child)) ali@9: return FALSE; ali@9: iter->stamp=priv->stamp; ali@9: iter->user_data=child; ali@9: return TRUE; ali@9: } ali@9: ali@9: static gboolean plover_package_file_store_iter_parent(GtkTreeModel *tree_model, ali@9: GtkTreeIter *iter,GtkTreeIter *child) ali@9: { ali@9: return FALSE; ali@9: } ali@9: ali@9: static void plover_package_file_store_tree_model_init(GtkTreeModelIface *iface) ali@9: { ali@9: iface->get_flags=plover_package_file_store_get_flags; ali@9: iface->get_n_columns=plover_package_file_store_get_n_columns; ali@9: iface->get_column_type=plover_package_file_store_get_column_type; ali@9: iface->get_iter=plover_package_file_store_get_iter; ali@9: iface->get_path=plover_package_file_store_get_path; ali@9: iface->get_value=plover_package_file_store_get_value; ali@9: iface->iter_next=plover_package_file_store_iter_next; ali@9: iface->iter_children=plover_package_file_store_iter_children; ali@9: iface->iter_has_child=plover_package_file_store_iter_has_child; ali@9: iface->iter_n_children=plover_package_file_store_iter_n_children; ali@9: iface->iter_nth_child=plover_package_file_store_iter_nth_child; ali@9: iface->iter_parent=plover_package_file_store_iter_parent; ali@9: } ali@9: ali@9: static void plover_package_file_store_init(PloverPackageFileStore *store) ali@9: { ali@9: PloverPackageFileStorePrivate *priv; ali@9: priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store); ali@9: priv->seq=g_sequence_new(g_free); ali@9: priv->stamp=g_random_int(); ali@9: } ali@9: ali@9: PloverPackageFileStore * ali@9: plover_package_file_store_new(struct razor_file_iterator *files) ali@9: { ali@9: const char *name; ali@10: char *s; ali@9: GSequenceIter *si; ali@9: GtkTreeIter ti; ali@9: GtkTreePath *path; ali@9: gint *indices; ali@9: PloverPackageFileStore *store; ali@9: PloverPackageFileStorePrivate *priv; ali@9: store=g_object_new(PLOVER_TYPE_PACKAGE_FILE_STORE,NULL); ali@9: priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store); ali@9: path=gtk_tree_path_new(); ali@9: gtk_tree_path_append_index(path,0); ali@9: indices=gtk_tree_path_get_indices(path); ali@9: while(razor_file_iterator_next(files,&name)) ali@9: { ali@10: s=g_strdup(name); ali@10: #ifdef WIN32 ali@10: s=g_strdelimit(s,"/",'\\'); ali@10: #endif ali@10: si=g_sequence_insert_sorted(priv->seq,s,g_strcmp0,NULL); ali@9: *indices=g_sequence_iter_get_position(si); ali@9: ti.stamp=priv->stamp; ali@9: ti.user_data=si; ali@9: gtk_tree_model_row_inserted(GTK_TREE_MODEL(store),path,&ti); ali@9: } ali@9: gtk_tree_path_free(path); ali@9: return store; ali@9: }