1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/plover-gtk/packagestore.c Sat Feb 20 12:11:02 2010 +0000
1.3 @@ -0,0 +1,356 @@
1.4 +/*
1.5 + * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
1.6 + * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
1.7 + *
1.8 + * This program is free software; you can redistribute it and/or modify
1.9 + * it under the terms of the GNU General Public License as published by
1.10 + * the Free Software Foundation; either version 2 of the License, or
1.11 + * (at your option) any later version.
1.12 + *
1.13 + * This program is distributed in the hope that it will be useful,
1.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.16 + * GNU General Public License for more details.
1.17 + *
1.18 + * You should have received a copy of the GNU General Public License along
1.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
1.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1.21 + */
1.22 +
1.23 +#include "config.h"
1.24 +#include <stdlib.h>
1.25 +#include <string.h>
1.26 +#include <glib-object.h>
1.27 +#include <gtk/gtk.h>
1.28 +#include <razor.h>
1.29 +#include "plover/plover.h"
1.30 +#include "plover-gtk/package.h"
1.31 +#include "plover-gtk/packagestore.h"
1.32 +
1.33 +#define VALID_ITER(iter,store) ((iter) && (iter)->user_data && \
1.34 + PLOVER_PACKAGE_STORE_GET_PRIVATE(store)->stamp==(iter)->stamp && \
1.35 + !g_sequence_iter_is_end((iter)->user_data) && \
1.36 + g_sequence_iter_get_sequence((iter)->user_data)== \
1.37 + PLOVER_PACKAGE_STORE_GET_PRIVATE(store)->seq)
1.38 +
1.39 +static GType column_types[PLOVER_PACKAGE_STORE_NO_COLUMNS];
1.40 +
1.41 +static void plover_package_store_tree_model_init(GtkTreeModelIface *iface);
1.42 +
1.43 +G_DEFINE_TYPE_WITH_CODE(PloverPackageStore,plover_package_store,G_TYPE_OBJECT,
1.44 + G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
1.45 + plover_package_store_tree_model_init));
1.46 +
1.47 +typedef struct _PloverPackageStorePrivate {
1.48 + GSList *sets;
1.49 + GSequence *seq;
1.50 + int stamp;
1.51 +} PloverPackageStorePrivate;
1.52 +
1.53 +#define PLOVER_PACKAGE_STORE_GET_PRIVATE(obj)\
1.54 + G_TYPE_INSTANCE_GET_PRIVATE(obj,\
1.55 + PLOVER_TYPE_PACKAGE_STORE,\
1.56 + PloverPackageStorePrivate)
1.57 +
1.58 +static void plover_package_store_finalize(GObject *obj)
1.59 +{
1.60 + PloverPackageStorePrivate *priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(obj);
1.61 + g_sequence_free(priv->seq);
1.62 + if (G_OBJECT_CLASS(plover_package_store_parent_class)->finalize)
1.63 + G_OBJECT_CLASS(plover_package_store_parent_class)->finalize(obj);
1.64 +}
1.65 +
1.66 +static void plover_package_store_dispose(GObject *obj)
1.67 +{
1.68 + PloverPackageStorePrivate *priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(obj);
1.69 + g_slist_foreach(priv->sets,(GFunc)g_object_unref,NULL);
1.70 + g_slist_free(priv->sets);
1.71 + priv->sets=NULL;
1.72 + g_sequence_free(priv->seq);
1.73 + priv->seq=g_sequence_new(NULL);
1.74 + if (G_OBJECT_CLASS(plover_package_store_parent_class)->dispose)
1.75 + G_OBJECT_CLASS(plover_package_store_parent_class)->dispose(obj);
1.76 +}
1.77 +
1.78 +static void plover_package_store_class_init(PloverPackageStoreClass *klass)
1.79 +{
1.80 + GObjectClass *oclass=G_OBJECT_CLASS(klass);
1.81 + oclass->finalize=plover_package_store_finalize;
1.82 + oclass->dispose=plover_package_store_dispose;
1.83 + g_type_class_add_private(klass,sizeof(PloverPackageStorePrivate));
1.84 + column_types[PLOVER_PACKAGE_STORE_OBJ_COLUMN]=PLOVER_TYPE_PACKAGE;
1.85 + column_types[PLOVER_PACKAGE_STORE_INSTALLED_COLUMN]=G_TYPE_BOOLEAN;
1.86 + column_types[PLOVER_PACKAGE_STORE_ICON_COLUMN]=GDK_TYPE_PIXBUF;
1.87 + column_types[PLOVER_PACKAGE_STORE_NAME_COLUMN]=G_TYPE_STRING;
1.88 + column_types[PLOVER_PACKAGE_STORE_VERSION_COLUMN]=G_TYPE_STRING;
1.89 + column_types[PLOVER_PACKAGE_STORE_SUMMARY_COLUMN]=G_TYPE_STRING;
1.90 +}
1.91 +
1.92 +static GtkTreeModelFlags
1.93 +plover_package_store_get_flags(GtkTreeModel *tree_model)
1.94 +{
1.95 + return GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY;
1.96 +}
1.97 +
1.98 +static gint plover_package_store_get_n_columns(GtkTreeModel *tree_model)
1.99 +{
1.100 + return PLOVER_PACKAGE_STORE_NO_COLUMNS;
1.101 +}
1.102 +
1.103 +static GType
1.104 + plover_package_store_get_column_type(GtkTreeModel *tree_model,gint indx)
1.105 +{
1.106 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.107 + g_return_val_if_fail(indx>=0 && indx<PLOVER_PACKAGE_STORE_NO_COLUMNS,
1.108 + G_TYPE_INVALID);
1.109 + return column_types[indx];
1.110 +}
1.111 +
1.112 +static gboolean plover_package_store_get_iter(GtkTreeModel *tree_model,
1.113 + GtkTreeIter *iter,GtkTreePath *path)
1.114 +{
1.115 + int i;
1.116 + PloverPackageStorePrivate *priv;
1.117 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.118 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
1.119 + i=gtk_tree_path_get_indices(path)[0];
1.120 + if (i>=g_sequence_get_length(priv->seq))
1.121 + return FALSE;
1.122 + iter->stamp=priv->stamp;
1.123 + iter->user_data=g_sequence_get_iter_at_pos(priv->seq,i);
1.124 + return TRUE;
1.125 +}
1.126 +
1.127 +static GtkTreePath *
1.128 + plover_package_store_get_path(GtkTreeModel *tree_model,GtkTreeIter *iter)
1.129 +{
1.130 + GtkTreePath *path;
1.131 + g_return_val_if_fail(VALID_ITER(iter,tree_model),NULL);
1.132 + if (g_sequence_iter_is_end(iter->user_data))
1.133 + return NULL;
1.134 + path=gtk_tree_path_new();
1.135 + gtk_tree_path_append_index(path,
1.136 + g_sequence_iter_get_position(iter->user_data));
1.137 + return path;
1.138 +}
1.139 +
1.140 +static void plover_package_store_get_value(GtkTreeModel *tree_model,
1.141 + GtkTreeIter *iter,gint column,GValue *value)
1.142 +{
1.143 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.144 + PloverPackage *package;
1.145 + g_return_if_fail(column>=0 && column<PLOVER_PACKAGE_STORE_NO_COLUMNS);
1.146 + g_return_if_fail(VALID_ITER(iter,store));
1.147 + package=g_sequence_get(iter->user_data);
1.148 + g_value_init(value,column_types[column]);
1.149 + switch((PloverPackageStoreColumn)column)
1.150 + {
1.151 + case PLOVER_PACKAGE_STORE_OBJ_COLUMN:
1.152 + g_value_set_object(value,package);
1.153 + break;
1.154 + case PLOVER_PACKAGE_STORE_INSTALLED_COLUMN:
1.155 + break;
1.156 + case PLOVER_PACKAGE_STORE_ICON_COLUMN:
1.157 + g_value_set_object(value,plover_package_get_icon(package));
1.158 + break;
1.159 + case PLOVER_PACKAGE_STORE_NAME_COLUMN:
1.160 + g_value_set_string(value,plover_package_get_name(package));
1.161 + break;
1.162 + case PLOVER_PACKAGE_STORE_VERSION_COLUMN:
1.163 + g_value_set_string(value,plover_package_get_version(package));
1.164 + break;
1.165 + case PLOVER_PACKAGE_STORE_SUMMARY_COLUMN:
1.166 + g_value_set_string(value,plover_package_get_summary(package));
1.167 + break;
1.168 + }
1.169 +}
1.170 +
1.171 +static gboolean
1.172 + plover_package_store_iter_next(GtkTreeModel *tree_model,GtkTreeIter *iter)
1.173 +{
1.174 + g_return_val_if_fail(VALID_ITER(iter,tree_model),FALSE);
1.175 + iter->user_data=g_sequence_iter_next(iter->user_data);
1.176 + return !g_sequence_iter_is_end(iter->user_data);
1.177 +}
1.178 +
1.179 +static gboolean plover_package_store_iter_children(GtkTreeModel *tree_model,
1.180 + GtkTreeIter *iter,GtkTreeIter *parent)
1.181 +{
1.182 + PloverPackageStorePrivate *priv;
1.183 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.184 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
1.185 + /* this is a list, nodes have no children */
1.186 + if (parent)
1.187 + return FALSE;
1.188 + if (g_sequence_get_length(priv->seq)>0)
1.189 + {
1.190 + iter->stamp=priv->stamp;
1.191 + iter->user_data=g_sequence_get_begin_iter(priv->seq);
1.192 + return TRUE;
1.193 + }
1.194 + else
1.195 + return FALSE;
1.196 +}
1.197 +
1.198 +static gboolean plover_package_store_iter_has_child(GtkTreeModel *tree_model,
1.199 + GtkTreeIter *iter)
1.200 +{
1.201 + return FALSE;
1.202 +}
1.203 +
1.204 +static gint plover_package_store_iter_n_children(GtkTreeModel *tree_model,
1.205 + GtkTreeIter *iter)
1.206 +{
1.207 + PloverPackageStorePrivate *priv;
1.208 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.209 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
1.210 + if (!iter)
1.211 + return g_sequence_get_length(priv->seq);
1.212 + g_return_val_if_fail(VALID_ITER(iter,tree_model),-1);
1.213 + return 0;
1.214 +}
1.215 +
1.216 +static gboolean plover_package_store_iter_nth_child(GtkTreeModel *tree_model,
1.217 + GtkTreeIter *iter,GtkTreeIter *parent,gint n)
1.218 +{
1.219 + PloverPackageStorePrivate *priv;
1.220 + PloverPackageStore *store=(PloverPackageStore *)tree_model;
1.221 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
1.222 + GSequenceIter *child;
1.223 + if (parent)
1.224 + return FALSE;
1.225 + child=g_sequence_get_iter_at_pos(priv->seq,n);
1.226 + if (g_sequence_iter_is_end(child))
1.227 + return FALSE;
1.228 + iter->stamp=priv->stamp;
1.229 + iter->user_data=child;
1.230 + return TRUE;
1.231 +}
1.232 +
1.233 +static gboolean plover_package_store_iter_parent(GtkTreeModel *tree_model,
1.234 + GtkTreeIter *iter,GtkTreeIter *child)
1.235 +{
1.236 + return FALSE;
1.237 +}
1.238 +
1.239 +static void plover_package_store_tree_model_init(GtkTreeModelIface *iface)
1.240 +{
1.241 + iface->get_flags=plover_package_store_get_flags;
1.242 + iface->get_n_columns=plover_package_store_get_n_columns;
1.243 + iface->get_column_type=plover_package_store_get_column_type;
1.244 + iface->get_iter=plover_package_store_get_iter;
1.245 + iface->get_path=plover_package_store_get_path;
1.246 + iface->get_value=plover_package_store_get_value;
1.247 + iface->iter_next=plover_package_store_iter_next;
1.248 + iface->iter_children=plover_package_store_iter_children;
1.249 + iface->iter_has_child=plover_package_store_iter_has_child;
1.250 + iface->iter_n_children=plover_package_store_iter_n_children;
1.251 + iface->iter_nth_child=plover_package_store_iter_nth_child;
1.252 + iface->iter_parent=plover_package_store_iter_parent;
1.253 +}
1.254 +
1.255 +static void plover_package_store_init(PloverPackageStore *store)
1.256 +{
1.257 + PloverPackageStorePrivate *priv;
1.258 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
1.259 + priv->seq=g_sequence_new(NULL);
1.260 + priv->stamp=g_random_int();
1.261 +}
1.262 +
1.263 +PloverPackageStore *plover_package_store_new(void)
1.264 +{
1.265 + return g_object_new(PLOVER_TYPE_PACKAGE_STORE,NULL);
1.266 +}
1.267 +
1.268 +GSList *plover_package_store_get_sets(PloverPackageStore *store)
1.269 +{
1.270 + PloverPackageStorePrivate *priv;
1.271 + g_return_val_if_fail(PLOVER_IS_PACKAGE_STORE(store),NULL);
1.272 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
1.273 + return priv->sets;
1.274 +}
1.275 +
1.276 +static gint
1.277 + plover__package_compar(gconstpointer a,gconstpointer b,gpointer user_data)
1.278 +{
1.279 + PloverPackage *pa=PLOVER_PACKAGE(a);
1.280 + PloverPackage *pb=PLOVER_PACKAGE(b);
1.281 + return strcmp(plover_package_get_name(pa),plover_package_get_name(pb));
1.282 +}
1.283 +
1.284 +void plover_package_store_add_set(PloverPackageStore *store,
1.285 + PloverPackageSet *set)
1.286 +{
1.287 + GSList *packages,*link;
1.288 + GSequenceIter *si;
1.289 + GtkTreeIter ti;
1.290 + GtkTreePath *path;
1.291 + gint *indices;
1.292 + PloverPackageStorePrivate *priv;
1.293 + g_return_if_fail(PLOVER_IS_PACKAGE_STORE(store));
1.294 + g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
1.295 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
1.296 + g_return_if_fail(g_slist_find(priv->sets,set) == NULL);
1.297 + g_object_ref(set);
1.298 + path=gtk_tree_path_new();
1.299 + gtk_tree_path_append_index(path,0);
1.300 + indices=gtk_tree_path_get_indices(path);
1.301 + packages=plover_package_set_get_packages(set);
1.302 + for(link=packages;link;link=link->next)
1.303 + {
1.304 + si=g_sequence_insert_sorted(priv->seq,link->data,
1.305 + plover__package_compar,NULL);
1.306 + *indices=g_sequence_iter_get_position(si);
1.307 + ti.stamp=priv->stamp;
1.308 + ti.user_data=si;
1.309 + gtk_tree_model_row_inserted(GTK_TREE_MODEL(store),path,&ti);
1.310 + }
1.311 + gtk_tree_path_free(path);
1.312 + priv->sets=g_slist_prepend(priv->sets,set);
1.313 +}
1.314 +
1.315 +void plover_package_store_remove_set(PloverPackageStore *store,
1.316 + PloverPackageSet *set)
1.317 +{
1.318 + GSList *packages,*link;
1.319 + GSequence *seq;
1.320 + GSequenceIter *iter,*prev,*remove;
1.321 + GtkTreePath *path;
1.322 + gint *indices;
1.323 + PloverPackageStorePrivate *priv;
1.324 + g_return_if_fail(PLOVER_IS_PACKAGE_STORE(store));
1.325 + g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
1.326 + priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
1.327 + g_return_if_fail(g_slist_find(priv->sets,set) != NULL);
1.328 + seq=g_sequence_new(NULL);
1.329 + path=gtk_tree_path_new();
1.330 + gtk_tree_path_append_index(path,0);
1.331 + indices=gtk_tree_path_get_indices(path);
1.332 + packages=plover_package_set_get_packages(set);
1.333 + for(link=packages;link;link=link->next)
1.334 + g_sequence_insert_sorted(seq,link->data,plover__package_compar,NULL);
1.335 + prev=NULL;
1.336 + iter=g_sequence_get_begin_iter(priv->seq);
1.337 + remove=g_sequence_get_begin_iter(seq);
1.338 + while(!g_sequence_iter_is_end(iter) && !g_sequence_iter_is_end(remove))
1.339 + {
1.340 + if (g_sequence_get(iter)==g_sequence_get(remove))
1.341 + {
1.342 + *indices=g_sequence_iter_get_position(iter);
1.343 + g_sequence_remove(iter);
1.344 + remove=g_sequence_iter_next(remove);
1.345 + gtk_tree_model_row_deleted(GTK_TREE_MODEL(store),path);
1.346 + }
1.347 + else
1.348 + prev=iter;
1.349 + if (prev)
1.350 + iter=g_sequence_iter_next(prev);
1.351 + else
1.352 + iter=g_sequence_get_begin_iter(priv->seq);
1.353 + }
1.354 + gtk_tree_path_free(path);
1.355 + g_sequence_free(seq);
1.356 + priv->sets=g_slist_remove(priv->sets,set);
1.357 + g_object_unref(set);
1.358 + priv->stamp++;
1.359 +}