plover-gtk/packagefilestore.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
parent 24 2b9f54d14cc2
permissions -rw-r--r--
Support parallel installations. The idea is that for CAD screener, we want
to be able to install this on the same machine as a standard AVOT setup
(most notably for John's laptop). To allow for the possibility of a second
application that might have the same requirements, we add the concept of
vendor-specific distributions. Thus we can have one distribution for CAD
screener and one for The Next Big Thing. It doesn't seem trivial to have
both CAD screener and AVOT under the same vendor tag so we'll have to have
AVOT under "City Occupational" and CAD screener under "City Occupational Ltd"
or some such kludge.

Most of this is done although we are very short of test cases (in particular
we don't test that it's actually possible to install CAD screener in parallel
with AVOT or to update either of them once installed, which is fundamental).

We also have a lot of baggage left over, including an intercept of razor_set.
The problem that this was introduced to debug has been fixed but it looks
like there are a number of memory leaks which it might be useful to help
track down so it has been left in place for now.

There is still a lot of confusion in plover between path-based and URI-based
API. We should review the API, decide what we want and have a general clear up.

There is also confusion as to the purpose of RAZOR_ROOT (and meaning; path or
URI). This is not used at all in librazor (although it is used in razor.exe).
Ideally we shouldn't use it in plover or plover-gtk either although again, we
might want to support it or an equivalent in (some of) the various executables.

Work that would still to nice to do for CAD screener:

- uninstall (ideally as an installed program that hooks into Add/Remove programs
but even re-running the installer would be acceptable).
- xz support (smaller packages).
- repomd.xml and xml:base (would be needed for an Internet installer).
- graphical installer.
ali@9
     1
/*
ali@9
     2
 * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
ali@9
     3
 * Copyright (C) 2010  J. Ali Harlow <ali@juiblex.co.uk>
ali@9
     4
 *
ali@9
     5
 * This program is free software; you can redistribute it and/or modify
ali@9
     6
 * it under the terms of the GNU General Public License as published by
ali@9
     7
 * the Free Software Foundation; either version 2 of the License, or
ali@9
     8
 * (at your option) any later version.
ali@9
     9
 *
ali@9
    10
 * This program is distributed in the hope that it will be useful,
ali@9
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@9
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@9
    13
 * GNU General Public License for more details.
ali@9
    14
 *
ali@9
    15
 * You should have received a copy of the GNU General Public License along
ali@9
    16
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@9
    17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@9
    18
 */
ali@9
    19
ali@9
    20
#include "config.h"
ali@9
    21
#include <stdlib.h>
ali@9
    22
#include <string.h>
ali@9
    23
#include <glib-object.h>
ali@9
    24
#include <gtk/gtk.h>
ali@9
    25
#include "plover-gtk/packagefilestore.h"
ali@9
    26
ali@9
    27
#define VALID_ITER(iter,store) ((iter) && (iter)->user_data && \
ali@9
    28
	PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store)->stamp==(iter)->stamp && \
ali@9
    29
	!g_sequence_iter_is_end((iter)->user_data) && \
ali@9
    30
	g_sequence_iter_get_sequence((iter)->user_data)== \
ali@9
    31
	PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store)->seq)
ali@9
    32
ali@9
    33
static GType column_types[PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS];
ali@9
    34
ali@9
    35
static void plover_package_file_store_tree_model_init(GtkTreeModelIface *iface);
ali@9
    36
ali@9
    37
G_DEFINE_TYPE_WITH_CODE(PloverPackageFileStore,plover_package_file_store,
ali@9
    38
  G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
ali@9
    39
  plover_package_file_store_tree_model_init));
ali@9
    40
ali@9
    41
typedef struct _PloverPackageFileStorePrivate {
ali@9
    42
    GSequence *seq;
ali@9
    43
    int stamp;
ali@9
    44
} PloverPackageFileStorePrivate;
ali@9
    45
ali@9
    46
#define PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(obj)\
ali@9
    47
				G_TYPE_INSTANCE_GET_PRIVATE(obj,\
ali@9
    48
				  PLOVER_TYPE_PACKAGE_FILE_STORE,\
ali@9
    49
				  PloverPackageFileStorePrivate)
ali@9
    50
ali@9
    51
static void plover_package_file_store_finalize(GObject *obj)
ali@9
    52
{
ali@9
    53
    PloverPackageFileStorePrivate *priv=
ali@9
    54
      PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(obj);
ali@9
    55
    g_sequence_free(priv->seq);
ali@9
    56
    if (G_OBJECT_CLASS(plover_package_file_store_parent_class)->finalize)
ali@9
    57
	G_OBJECT_CLASS(plover_package_file_store_parent_class)->finalize(obj);
ali@9
    58
}
ali@9
    59
ali@9
    60
static void
ali@9
    61
  plover_package_file_store_class_init(PloverPackageFileStoreClass *klass)
ali@9
    62
{
ali@9
    63
    GObjectClass *oclass=G_OBJECT_CLASS(klass);
ali@9
    64
    oclass->finalize=plover_package_file_store_finalize;
ali@9
    65
    g_type_class_add_private(klass,sizeof(PloverPackageFileStorePrivate));
ali@9
    66
    column_types[PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN]=G_TYPE_STRING;
ali@9
    67
}
ali@9
    68
ali@9
    69
static GtkTreeModelFlags
ali@9
    70
plover_package_file_store_get_flags(GtkTreeModel *tree_model)
ali@9
    71
{
ali@9
    72
    return GTK_TREE_MODEL_ITERS_PERSIST|GTK_TREE_MODEL_LIST_ONLY;
ali@9
    73
}
ali@9
    74
ali@9
    75
static gint plover_package_file_store_get_n_columns(GtkTreeModel *tree_model)
ali@9
    76
{
ali@9
    77
    return PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS;
ali@9
    78
}
ali@9
    79
ali@9
    80
static GType
ali@9
    81
  plover_package_file_store_get_column_type(GtkTreeModel *tree_model,gint indx)
ali@9
    82
{
ali@9
    83
    g_return_val_if_fail(indx>=0 && indx<PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS,
ali@9
    84
      G_TYPE_INVALID);
ali@9
    85
    return column_types[indx];
ali@9
    86
}
ali@9
    87
ali@9
    88
static gboolean plover_package_file_store_get_iter(GtkTreeModel *tree_model,
ali@9
    89
  GtkTreeIter *iter,GtkTreePath *path)
ali@9
    90
{
ali@9
    91
    int i;
ali@9
    92
    PloverPackageFileStorePrivate *priv;
ali@9
    93
    PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model;
ali@9
    94
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store);
ali@9
    95
    i=gtk_tree_path_get_indices(path)[0];
ali@9
    96
    if (i>=g_sequence_get_length(priv->seq))
ali@9
    97
	return FALSE;
ali@9
    98
    iter->stamp=priv->stamp;
ali@9
    99
    iter->user_data=g_sequence_get_iter_at_pos(priv->seq,i);
ali@9
   100
    return TRUE;
ali@9
   101
}
ali@9
   102
ali@9
   103
static GtkTreePath *
ali@9
   104
  plover_package_file_store_get_path(GtkTreeModel *tree_model,GtkTreeIter *iter)
ali@9
   105
{
ali@9
   106
    GtkTreePath *path;
ali@9
   107
    g_return_val_if_fail(VALID_ITER(iter,tree_model),NULL);
ali@9
   108
    if (g_sequence_iter_is_end(iter->user_data))
ali@9
   109
	return NULL;
ali@9
   110
    path=gtk_tree_path_new();
ali@9
   111
    gtk_tree_path_append_index(path,
ali@9
   112
      g_sequence_iter_get_position(iter->user_data));
ali@9
   113
    return path;
ali@9
   114
}
ali@9
   115
ali@9
   116
static void plover_package_file_store_get_value(GtkTreeModel *tree_model,
ali@9
   117
  GtkTreeIter *iter,gint column,GValue *value)
ali@9
   118
{
ali@9
   119
    PloverPackageFileStore *store=(PloverPackageFileStore *)tree_model;
ali@9
   120
    char *name;
ali@9
   121
    g_return_if_fail(column>=0 && column<PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS);
ali@9
   122
    g_return_if_fail(VALID_ITER(iter,store));
ali@9
   123
    name=g_sequence_get(iter->user_data);
ali@9
   124
    g_value_init(value,column_types[column]);
ali@9
   125
    switch((PloverPackageFileStoreColumn)column)
ali@9
   126
    {
ali@9
   127
	case PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN:
ali@9
   128
	    g_value_set_string(value,name);
ali@9
   129
	    break;
ali@12
   130
	case PLOVER_PACKAGE_FILE_STORE_NO_COLUMNS:
ali@12
   131
	    /* Quieten compiler warning */
ali@12
   132
	    break;
ali@9
   133
    }
ali@9
   134
}
ali@9
   135
ali@9
   136
static gboolean plover_package_file_store_iter_next(GtkTreeModel *tree_model,
ali@9
   137
  GtkTreeIter *iter)
ali@9
   138
{
ali@9
   139
    g_return_val_if_fail(VALID_ITER(iter,tree_model),FALSE);
ali@9
   140
    iter->user_data=g_sequence_iter_next(iter->user_data);
ali@9
   141
    return !g_sequence_iter_is_end(iter->user_data);
ali@9
   142
}
ali@9
   143
ali@9
   144
static gboolean
ali@9
   145
  plover_package_file_store_iter_children(GtkTreeModel *tree_model,
ali@9
   146
  GtkTreeIter *iter,GtkTreeIter *parent)
ali@9
   147
{
ali@9
   148
    PloverPackageFileStorePrivate *priv;
ali@9
   149
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model);
ali@9
   150
    /* this is a list, nodes have no children */
ali@9
   151
    if (parent)
ali@9
   152
	return FALSE;
ali@9
   153
    if (g_sequence_get_length(priv->seq)>0)
ali@9
   154
    {
ali@9
   155
	iter->stamp=priv->stamp;
ali@9
   156
	iter->user_data=g_sequence_get_begin_iter(priv->seq);
ali@9
   157
	return TRUE;
ali@9
   158
    }
ali@9
   159
    else
ali@9
   160
	return FALSE;
ali@9
   161
}
ali@9
   162
ali@9
   163
static gboolean
ali@9
   164
  plover_package_file_store_iter_has_child(GtkTreeModel *tree_model,
ali@9
   165
  GtkTreeIter *iter)
ali@9
   166
{
ali@9
   167
    return FALSE;
ali@9
   168
}
ali@9
   169
ali@9
   170
static gint plover_package_file_store_iter_n_children(GtkTreeModel *tree_model,
ali@9
   171
  GtkTreeIter *iter)
ali@9
   172
{
ali@9
   173
    PloverPackageFileStorePrivate *priv;
ali@9
   174
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model);
ali@9
   175
    if (!iter)
ali@9
   176
	return g_sequence_get_length(priv->seq);
ali@9
   177
    g_return_val_if_fail(VALID_ITER(iter,tree_model),-1);
ali@9
   178
    return 0;
ali@9
   179
}
ali@9
   180
ali@9
   181
static gboolean
ali@9
   182
  plover_package_file_store_iter_nth_child(GtkTreeModel *tree_model,
ali@9
   183
  GtkTreeIter *iter,GtkTreeIter *parent,gint n)
ali@9
   184
{
ali@9
   185
    PloverPackageFileStorePrivate *priv;
ali@9
   186
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(tree_model);
ali@9
   187
    GSequenceIter *child;
ali@9
   188
    if (parent)
ali@9
   189
	return FALSE;
ali@9
   190
    child=g_sequence_get_iter_at_pos(priv->seq,n);
ali@9
   191
    if (g_sequence_iter_is_end(child))
ali@9
   192
	return FALSE;
ali@9
   193
    iter->stamp=priv->stamp;
ali@9
   194
    iter->user_data=child;
ali@9
   195
    return TRUE;
ali@9
   196
}
ali@9
   197
ali@9
   198
static gboolean plover_package_file_store_iter_parent(GtkTreeModel *tree_model,
ali@9
   199
  GtkTreeIter *iter,GtkTreeIter *child)
ali@9
   200
{
ali@9
   201
    return FALSE;
ali@9
   202
}
ali@9
   203
ali@9
   204
static void plover_package_file_store_tree_model_init(GtkTreeModelIface *iface)
ali@9
   205
{
ali@9
   206
    iface->get_flags=plover_package_file_store_get_flags;
ali@9
   207
    iface->get_n_columns=plover_package_file_store_get_n_columns;
ali@9
   208
    iface->get_column_type=plover_package_file_store_get_column_type;
ali@9
   209
    iface->get_iter=plover_package_file_store_get_iter;
ali@9
   210
    iface->get_path=plover_package_file_store_get_path;
ali@9
   211
    iface->get_value=plover_package_file_store_get_value;
ali@9
   212
    iface->iter_next=plover_package_file_store_iter_next;
ali@9
   213
    iface->iter_children=plover_package_file_store_iter_children;
ali@9
   214
    iface->iter_has_child=plover_package_file_store_iter_has_child;
ali@9
   215
    iface->iter_n_children=plover_package_file_store_iter_n_children;
ali@9
   216
    iface->iter_nth_child=plover_package_file_store_iter_nth_child;
ali@9
   217
    iface->iter_parent=plover_package_file_store_iter_parent;
ali@9
   218
}
ali@9
   219
ali@9
   220
static void plover_package_file_store_init(PloverPackageFileStore *store)
ali@9
   221
{
ali@9
   222
    PloverPackageFileStorePrivate *priv;
ali@9
   223
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store);
ali@9
   224
    priv->seq=g_sequence_new(g_free);
ali@9
   225
    priv->stamp=g_random_int();
ali@9
   226
}
ali@9
   227
ali@9
   228
PloverPackageFileStore *
ali@9
   229
  plover_package_file_store_new(struct razor_file_iterator *files)
ali@9
   230
{
ali@9
   231
    const char *name;
ali@10
   232
    char *s;
ali@9
   233
    GSequenceIter *si;
ali@9
   234
    GtkTreeIter ti;
ali@9
   235
    GtkTreePath *path;
ali@9
   236
    gint *indices;
ali@9
   237
    PloverPackageFileStore *store;
ali@9
   238
    PloverPackageFileStorePrivate *priv;
ali@9
   239
    store=g_object_new(PLOVER_TYPE_PACKAGE_FILE_STORE,NULL);
ali@9
   240
    priv=PLOVER_PACKAGE_FILE_STORE_GET_PRIVATE(store);
ali@9
   241
    path=gtk_tree_path_new();
ali@9
   242
    gtk_tree_path_append_index(path,0);
ali@9
   243
    indices=gtk_tree_path_get_indices(path);
ali@9
   244
    while(razor_file_iterator_next(files,&name))
ali@9
   245
    {
ali@10
   246
	s=g_strdup(name);
ali@10
   247
#ifdef WIN32
ali@10
   248
	s=g_strdelimit(s,"/",'\\');
ali@10
   249
#endif
ali@12
   250
	si=g_sequence_insert_sorted(priv->seq,s,(GCompareDataFunc)g_strcmp0,
ali@12
   251
	  NULL);
ali@9
   252
	*indices=g_sequence_iter_get_position(si);
ali@9
   253
	ti.stamp=priv->stamp;
ali@9
   254
	ti.user_data=si;
ali@9
   255
	gtk_tree_model_row_inserted(GTK_TREE_MODEL(store),path,&ti);
ali@9
   256
    }
ali@9
   257
    gtk_tree_path_free(path);
ali@9
   258
    return store;
ali@9
   259
}
ali@24
   260
ali@24
   261
PloverPackageFileStore *
ali@24
   262
  plover_package_file_store_new_from_package(PloverPackage *package)
ali@24
   263
{
ali@24
   264
    PloverPackageFileStore *store;
ali@24
   265
    g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
ali@24
   266
    struct razor_file_iterator *iter;
ali@24
   267
    iter=plover_package_file_iterator_create(package,FALSE);
ali@38
   268
    store=plover_package_file_store_new(iter);
ali@24
   269
    razor_file_iterator_destroy(iter);
ali@24
   270
    return store;
ali@24
   271
}