Fix bug causing a transaction without a base to be treated as a programming error
2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
3 * Copyright (C) 2010 J. Ali Harlow <ali@juiblex.co.uk>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include <glib-object.h>
26 #include "plover/plover.h"
27 #include "plover/package.h"
28 #include "plover-gtk/packagestore.h"
30 #define VALID_ITER(iter,store) ((iter) && (iter)->user_data && \
31 PLOVER_PACKAGE_STORE_GET_PRIVATE(store)->stamp==(iter)->stamp && \
32 !g_sequence_iter_is_end((iter)->user_data) && \
33 g_sequence_iter_get_sequence((iter)->user_data)== \
34 PLOVER_PACKAGE_STORE_GET_PRIVATE(store)->seq)
36 static GType column_types[PLOVER_PACKAGE_STORE_NO_COLUMNS];
38 static void plover_package_store_tree_model_init(GtkTreeModelIface *iface);
40 G_DEFINE_TYPE_WITH_CODE(PloverPackageStore,plover_package_store,G_TYPE_OBJECT,
41 G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
42 plover_package_store_tree_model_init));
44 typedef struct _PloverPackageStorePrivate {
48 } PloverPackageStorePrivate;
50 #define PLOVER_PACKAGE_STORE_GET_PRIVATE(obj)\
51 G_TYPE_INSTANCE_GET_PRIVATE(obj,\
52 PLOVER_TYPE_PACKAGE_STORE,\
53 PloverPackageStorePrivate)
55 static void plover_package_store_finalize(GObject *obj)
57 PloverPackageStorePrivate *priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(obj);
58 g_sequence_free(priv->seq);
59 if (G_OBJECT_CLASS(plover_package_store_parent_class)->finalize)
60 G_OBJECT_CLASS(plover_package_store_parent_class)->finalize(obj);
63 static void plover_package_store_dispose(GObject *obj)
65 PloverPackageStorePrivate *priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(obj);
66 g_slist_foreach(priv->sets,(GFunc)g_object_unref,NULL);
67 g_slist_free(priv->sets);
69 g_sequence_free(priv->seq);
70 priv->seq=g_sequence_new(NULL);
71 if (G_OBJECT_CLASS(plover_package_store_parent_class)->dispose)
72 G_OBJECT_CLASS(plover_package_store_parent_class)->dispose(obj);
75 static void plover_package_store_class_init(PloverPackageStoreClass *klass)
77 GObjectClass *oclass=G_OBJECT_CLASS(klass);
78 oclass->finalize=plover_package_store_finalize;
79 oclass->dispose=plover_package_store_dispose;
80 g_type_class_add_private(klass,sizeof(PloverPackageStorePrivate));
81 column_types[PLOVER_PACKAGE_STORE_OBJ_COLUMN]=PLOVER_TYPE_PACKAGE;
82 column_types[PLOVER_PACKAGE_STORE_INSTALLED_COLUMN]=G_TYPE_BOOLEAN;
83 column_types[PLOVER_PACKAGE_STORE_ICON_COLUMN]=GDK_TYPE_PIXBUF;
84 column_types[PLOVER_PACKAGE_STORE_NAME_COLUMN]=G_TYPE_STRING;
85 column_types[PLOVER_PACKAGE_STORE_VERSION_COLUMN]=G_TYPE_STRING;
86 column_types[PLOVER_PACKAGE_STORE_SUMMARY_COLUMN]=G_TYPE_STRING;
89 static GtkTreeModelFlags
90 plover_package_store_get_flags(GtkTreeModel *tree_model)
92 return GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY;
95 static gint plover_package_store_get_n_columns(GtkTreeModel *tree_model)
97 return PLOVER_PACKAGE_STORE_NO_COLUMNS;
101 plover_package_store_get_column_type(GtkTreeModel *tree_model,gint indx)
103 g_return_val_if_fail(indx>=0 && indx<PLOVER_PACKAGE_STORE_NO_COLUMNS,
105 return column_types[indx];
108 static gboolean plover_package_store_get_iter(GtkTreeModel *tree_model,
109 GtkTreeIter *iter,GtkTreePath *path)
112 PloverPackageStorePrivate *priv;
113 PloverPackageStore *store=(PloverPackageStore *)tree_model;
114 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
115 i=gtk_tree_path_get_indices(path)[0];
116 if (i>=g_sequence_get_length(priv->seq))
118 iter->stamp=priv->stamp;
119 iter->user_data=g_sequence_get_iter_at_pos(priv->seq,i);
124 plover_package_store_get_path(GtkTreeModel *tree_model,GtkTreeIter *iter)
127 g_return_val_if_fail(VALID_ITER(iter,tree_model),NULL);
128 if (g_sequence_iter_is_end(iter->user_data))
130 path=gtk_tree_path_new();
131 gtk_tree_path_append_index(path,
132 g_sequence_iter_get_position(iter->user_data));
136 static void plover_package_store_get_value(GtkTreeModel *tree_model,
137 GtkTreeIter *iter,gint column,GValue *value)
141 PloverPackageStore *store=(PloverPackageStore *)tree_model;
142 PloverPackage *package;
143 GInputStream *stream;
145 g_return_if_fail(column>=0 && column<PLOVER_PACKAGE_STORE_NO_COLUMNS);
146 g_return_if_fail(VALID_ITER(iter,store));
147 package=PLOVER_PACKAGE(g_sequence_get(iter->user_data));
148 g_value_init(value,column_types[column]);
149 switch((PloverPackageStoreColumn)column)
151 case PLOVER_PACKAGE_STORE_OBJ_COLUMN:
152 g_value_set_object(value,package);
154 case PLOVER_PACKAGE_STORE_INSTALLED_COLUMN:
156 case PLOVER_PACKAGE_STORE_ICON_COLUMN:
157 stream=plover_package_read_icon(package,NULL);
160 icon=gdk_pixbuf_new_from_stream(stream,NULL,NULL);
161 g_object_unref(stream);
165 g_value_set_object(value,icon);
167 case PLOVER_PACKAGE_STORE_NAME_COLUMN:
168 g_value_set_string(value,plover_package_get_name(package));
170 case PLOVER_PACKAGE_STORE_VERSION_COLUMN:
171 g_value_set_string(value,plover_package_get_version(package));
173 case PLOVER_PACKAGE_STORE_SUMMARY_COLUMN:
174 summary=plover_package_get_summary(package);
176 g_value_set_string(value,summary);
179 s=g_strconcat("The ",plover_package_get_name(package),
181 g_value_set_string(value,s);
185 case PLOVER_PACKAGE_STORE_NO_COLUMNS:
186 /* Quieten compiler warning */
192 plover_package_store_iter_next(GtkTreeModel *tree_model,GtkTreeIter *iter)
194 g_return_val_if_fail(VALID_ITER(iter,tree_model),FALSE);
195 iter->user_data=g_sequence_iter_next(iter->user_data);
196 return !g_sequence_iter_is_end(iter->user_data);
199 static gboolean plover_package_store_iter_children(GtkTreeModel *tree_model,
200 GtkTreeIter *iter,GtkTreeIter *parent)
202 PloverPackageStorePrivate *priv;
203 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
204 /* this is a list, nodes have no children */
207 if (g_sequence_get_length(priv->seq)>0)
209 iter->stamp=priv->stamp;
210 iter->user_data=g_sequence_get_begin_iter(priv->seq);
217 static gboolean plover_package_store_iter_has_child(GtkTreeModel *tree_model,
223 static gint plover_package_store_iter_n_children(GtkTreeModel *tree_model,
226 PloverPackageStorePrivate *priv;
227 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
229 return g_sequence_get_length(priv->seq);
230 g_return_val_if_fail(VALID_ITER(iter,tree_model),-1);
234 static gboolean plover_package_store_iter_nth_child(GtkTreeModel *tree_model,
235 GtkTreeIter *iter,GtkTreeIter *parent,gint n)
237 PloverPackageStorePrivate *priv;
238 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(tree_model);
239 GSequenceIter *child;
242 child=g_sequence_get_iter_at_pos(priv->seq,n);
243 if (g_sequence_iter_is_end(child))
245 iter->stamp=priv->stamp;
246 iter->user_data=child;
250 static gboolean plover_package_store_iter_parent(GtkTreeModel *tree_model,
251 GtkTreeIter *iter,GtkTreeIter *child)
256 static void plover_package_store_tree_model_init(GtkTreeModelIface *iface)
258 iface->get_flags=plover_package_store_get_flags;
259 iface->get_n_columns=plover_package_store_get_n_columns;
260 iface->get_column_type=plover_package_store_get_column_type;
261 iface->get_iter=plover_package_store_get_iter;
262 iface->get_path=plover_package_store_get_path;
263 iface->get_value=plover_package_store_get_value;
264 iface->iter_next=plover_package_store_iter_next;
265 iface->iter_children=plover_package_store_iter_children;
266 iface->iter_has_child=plover_package_store_iter_has_child;
267 iface->iter_n_children=plover_package_store_iter_n_children;
268 iface->iter_nth_child=plover_package_store_iter_nth_child;
269 iface->iter_parent=plover_package_store_iter_parent;
272 static void plover_package_store_init(PloverPackageStore *store)
274 PloverPackageStorePrivate *priv;
275 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
276 priv->seq=g_sequence_new(NULL);
277 priv->stamp=g_random_int();
280 PloverPackageStore *plover_package_store_new(void)
282 return g_object_new(PLOVER_TYPE_PACKAGE_STORE,NULL);
285 GSList *plover_package_store_get_sets(PloverPackageStore *store)
287 PloverPackageStorePrivate *priv;
288 g_return_val_if_fail(PLOVER_IS_PACKAGE_STORE(store),NULL);
289 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
294 plover__package_compar(gconstpointer a,gconstpointer b,gpointer user_data)
296 PloverPackage *pa=PLOVER_PACKAGE(a);
297 PloverPackage *pb=PLOVER_PACKAGE(b);
298 return strcmp(plover_package_get_name(pa),plover_package_get_name(pb));
301 void plover_package_store_add_set(PloverPackageStore *store,
302 PloverPackageSet *set)
304 GSList *packages,*link;
309 PloverPackageStorePrivate *priv;
310 g_return_if_fail(PLOVER_IS_PACKAGE_STORE(store));
311 g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
312 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
313 g_return_if_fail(g_slist_find(priv->sets,set) == NULL);
315 path=gtk_tree_path_new();
316 gtk_tree_path_append_index(path,0);
317 indices=gtk_tree_path_get_indices(path);
318 packages=plover_package_set_get_packages(set);
319 for(link=packages;link;link=link->next)
321 si=g_sequence_insert_sorted(priv->seq,link->data,
322 plover__package_compar,NULL);
323 *indices=g_sequence_iter_get_position(si);
324 ti.stamp=priv->stamp;
326 gtk_tree_model_row_inserted(GTK_TREE_MODEL(store),path,&ti);
328 gtk_tree_path_free(path);
329 priv->sets=g_slist_prepend(priv->sets,set);
332 void plover_package_store_remove_set(PloverPackageStore *store,
333 PloverPackageSet *set)
335 GSList *packages,*link;
337 GSequenceIter *iter,*prev,*remove;
340 PloverPackageStorePrivate *priv;
341 g_return_if_fail(PLOVER_IS_PACKAGE_STORE(store));
342 g_return_if_fail(PLOVER_IS_PACKAGE_SET(set));
343 priv=PLOVER_PACKAGE_STORE_GET_PRIVATE(store);
344 g_return_if_fail(g_slist_find(priv->sets,set) != NULL);
345 seq=g_sequence_new(NULL);
346 path=gtk_tree_path_new();
347 gtk_tree_path_append_index(path,0);
348 indices=gtk_tree_path_get_indices(path);
349 packages=plover_package_set_get_packages(set);
350 for(link=packages;link;link=link->next)
351 g_sequence_insert_sorted(seq,link->data,plover__package_compar,NULL);
353 iter=g_sequence_get_begin_iter(priv->seq);
354 remove=g_sequence_get_begin_iter(seq);
355 while(!g_sequence_iter_is_end(iter) && !g_sequence_iter_is_end(remove))
357 if (g_sequence_get(iter)==g_sequence_get(remove))
359 *indices=g_sequence_iter_get_position(iter);
360 g_sequence_remove(iter);
361 remove=g_sequence_iter_next(remove);
362 gtk_tree_model_row_deleted(GTK_TREE_MODEL(store),path);
367 iter=g_sequence_iter_next(prev);
369 iter=g_sequence_get_begin_iter(priv->seq);
371 gtk_tree_path_free(path);
372 g_sequence_free(seq);
373 priv->sets=g_slist_remove(priv->sets,set);