app-manager/packagelist.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
parent 10 8b50be3e2998
child 109 2947214c450e
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) 2010  J. Ali Harlow <ali@juiblex.co.uk>
ali@9
     3
 *
ali@9
     4
 * This program is free software; you can redistribute it and/or modify
ali@9
     5
 * it under the terms of the GNU General Public License as published by
ali@9
     6
 * the Free Software Foundation; either version 2 of the License, or
ali@9
     7
 * (at your option) any later version.
ali@9
     8
 *
ali@9
     9
 * This program is distributed in the hope that it will be useful,
ali@9
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ali@9
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
ali@9
    12
 * GNU General Public License for more details.
ali@9
    13
 *
ali@9
    14
 * You should have received a copy of the GNU General Public License along
ali@9
    15
 * with this program; if not, write to the Free Software Foundation, Inc.,
ali@9
    16
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
ali@9
    17
 */
ali@9
    18
ali@9
    19
#include "config.h"
ali@9
    20
#include <stdlib.h>
ali@9
    21
#include <string.h>
ali@9
    22
#include <gtk/gtk.h>
ali@24
    23
#include <plover/package.h>
ali@24
    24
#include <plover/packageset.h>
ali@9
    25
#include <plover-gtk/packagestore.h>
ali@9
    26
#include <plover-gtk/packagefilestore.h>
ali@9
    27
#include "app-manager.h"
ali@9
    28
ali@9
    29
GtkTreeView *view=NULL;
ali@9
    30
PloverPackage *active=NULL;
ali@9
    31
gboolean view_files=FALSE;
ali@9
    32
ali@9
    33
void package_present(PloverPackage *package)
ali@9
    34
{
ali@9
    35
    gchar *s;
ali@9
    36
    const char *text,*t;
ali@9
    37
    GtkWidget *w;
ali@9
    38
    GtkTextBuffer *buf;
ali@24
    39
    PloverPackageFileStore *store;
ali@9
    40
    buf=GTK_TEXT_BUFFER(gtk_builder_get_object(ui,"description"));
ali@9
    41
    if (package)
ali@9
    42
    {
ali@9
    43
	s=g_strdup(plover_package_get_description(package));
ali@9
    44
	g_strdelimit(s,"\t\n",' ');
ali@9
    45
    }
ali@9
    46
    else
ali@9
    47
	s=g_strdup("");
ali@9
    48
    gtk_text_buffer_set_text(buf,s,-1);
ali@9
    49
    g_free(s);
ali@9
    50
    w=GTK_WIDGET(gtk_builder_get_object(ui,"PackageDetails"));
ali@9
    51
    if (!package)
ali@9
    52
    {
ali@9
    53
	gtk_widget_hide(w);
ali@9
    54
	w=GTK_WIDGET(gtk_builder_get_object(ui,"FilesScrolledWindow"));
ali@9
    55
	gtk_widget_hide(w);
ali@9
    56
	w=GTK_WIDGET(gtk_builder_get_object(ui,"DescriptionScrolledWindow"));
ali@9
    57
	gtk_widget_show(w);
ali@9
    58
    }
ali@9
    59
    else
ali@9
    60
    {
ali@9
    61
	if (view_files)
ali@9
    62
	    gtk_widget_hide(w);
ali@9
    63
	else
ali@9
    64
	{
ali@9
    65
	    gtk_widget_show(w);
ali@9
    66
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"HomepageBox"));
ali@9
    67
	    text=plover_package_get_URL(package);
ali@9
    68
	    if (!*text)
ali@9
    69
		gtk_widget_hide(w);
ali@9
    70
	    else
ali@9
    71
	    {
ali@9
    72
		gtk_widget_show(w);
ali@9
    73
		w=GTK_WIDGET(gtk_builder_get_object(ui,"Homepage"));
ali@9
    74
		gtk_link_button_set_uri(GTK_LINK_BUTTON(w),text);
ali@9
    75
		t=strstr(text,"://");
ali@9
    76
		if (t)
ali@9
    77
		    t+=3;
ali@9
    78
		if (t)
ali@10
    79
		    s=g_strndup(t,strcspn(t,"/"));
ali@9
    80
		else
ali@10
    81
		    s=g_strdup(text);
ali@9
    82
		gtk_button_set_label(GTK_BUTTON(w),s);
ali@9
    83
		g_free(s);
ali@9
    84
	    }
ali@9
    85
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"Architecture"));
ali@9
    86
	    gtk_label_set_text(GTK_LABEL(w),plover_package_get_arch(package));
ali@9
    87
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"License"));
ali@9
    88
	    gtk_label_set_text(GTK_LABEL(w),
ali@9
    89
	      plover_package_get_license(package));
ali@9
    90
	}
ali@9
    91
	w=GTK_WIDGET(gtk_builder_get_object(ui,"FilesScrolledWindow"));
ali@9
    92
	if (view_files)
ali@9
    93
	    gtk_widget_show(w);
ali@9
    94
	else
ali@9
    95
	    gtk_widget_hide(w);
ali@9
    96
	w=GTK_WIDGET(gtk_builder_get_object(ui,"DescriptionScrolledWindow"));
ali@9
    97
	if (view_files)
ali@9
    98
	{
ali@9
    99
	    gtk_widget_hide(w);
ali@9
   100
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"Files"));
ali@24
   101
	    store=plover_package_file_store_new_from_package(package);
ali@24
   102
	    gtk_tree_view_set_model(GTK_TREE_VIEW(w),GTK_TREE_MODEL(store));
ali@24
   103
	    g_object_unref(store);
ali@9
   104
	}
ali@9
   105
	else
ali@9
   106
	{
ali@9
   107
	    gtk_widget_show(w);
ali@9
   108
	    /* Without this, Gtk+ 2.18.6 just truncates long license tags */
ali@9
   109
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"DetailsScrolledWindow"));
ali@9
   110
	    gtk_widget_queue_resize(w);
ali@9
   111
	}
ali@9
   112
    }
ali@9
   113
}
ali@9
   114
ali@9
   115
void package_filelist_present(PloverPackage *package)
ali@9
   116
{
ali@9
   117
}
ali@9
   118
ali@9
   119
static void package_selection_changed(GtkTreeSelection *selection)
ali@9
   120
{
ali@9
   121
    GtkTreeIter iter;
ali@9
   122
    GtkTreeView *view;
ali@9
   123
    GtkTreeModel *model;
ali@9
   124
    if (active)
ali@9
   125
	g_object_unref(active);
ali@9
   126
    if (gtk_tree_selection_get_selected(selection,NULL,&iter))
ali@9
   127
    {
ali@9
   128
	view=gtk_tree_selection_get_tree_view(selection);
ali@9
   129
	model=gtk_tree_view_get_model(view);
ali@9
   130
	gtk_tree_model_get(model,&iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN,&active,
ali@9
   131
	  -1);
ali@9
   132
    }
ali@9
   133
    else
ali@9
   134
	active=NULL;
ali@9
   135
    package_present(active);
ali@9
   136
}
ali@9
   137
ali@9
   138
static void package_activated(GtkTreeView *view,GtkTreePath *path,
ali@9
   139
  GtkTreeViewColumn *column,gpointer data)
ali@9
   140
{
ali@9
   141
    GtkTreeIter iter;
ali@9
   142
    GtkTreeModel *model=gtk_tree_view_get_model(view);
ali@9
   143
    PloverPackage *package;
ali@9
   144
    if (gtk_tree_model_get_iter(model,&iter,path))
ali@9
   145
    {
ali@9
   146
	gtk_tree_model_get(model,&iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN,&package,
ali@9
   147
	  -1);
ali@9
   148
	package_filelist_present(package);
ali@9
   149
    }
ali@9
   150
}
ali@9
   151
ali@9
   152
static void package_cell_data_func(GtkTreeViewColumn *column,
ali@9
   153
  GtkCellRenderer *cell,GtkTreeModel *model,GtkTreeIter *iter,gpointer data)
ali@9
   154
{
ali@9
   155
    gchar *markup;
ali@9
   156
    gchar *summary,*name,*version;
ali@10
   157
    g_return_if_fail(GTK_IS_TREE_MODEL(model));
ali@9
   158
    gtk_tree_model_get(model,iter,PLOVER_PACKAGE_STORE_SUMMARY_COLUMN,&summary,
ali@9
   159
      PLOVER_PACKAGE_STORE_NAME_COLUMN,&name,
ali@9
   160
      PLOVER_PACKAGE_STORE_VERSION_COLUMN,&version,-1);
ali@10
   161
    markup=g_markup_printf_escaped("<b>%s</b>\n%s %s",summary,name,version);
ali@9
   162
    g_free(summary);
ali@9
   163
    g_free(name);
ali@9
   164
    g_free(version);
ali@9
   165
    g_object_set(cell,"markup",markup,NULL);
ali@9
   166
    g_free(markup);
ali@9
   167
}
ali@9
   168
ali@9
   169
void set_package_model(GtkTreeModel *model)
ali@9
   170
{
ali@9
   171
    GtkWidget *w;
ali@9
   172
    GtkTreeViewColumn *column;
ali@9
   173
    GtkCellRenderer *renderer;
ali@9
   174
    GtkTreeSelection *selection;
ali@9
   175
    if (!view)
ali@9
   176
    {
ali@9
   177
	w=GTK_WIDGET(gtk_builder_get_object(ui,"Packages"));
ali@9
   178
	if (w)
ali@9
   179
	{
ali@9
   180
	    view=GTK_TREE_VIEW(w);
ali@9
   181
#if 0
ali@9
   182
	    column=gtk_tree_view_column_new_with_attributes("Icon",
ali@9
   183
	      gtk_cell_renderer_pixbuf_new(),"pixbuf",
ali@9
   184
	      PLOVER_PACKAGE_FILE_STORE_ICON_COLUMN,NULL);
ali@9
   185
	    gtk_tree_view_append_column(GTK_TREE_VIEW(w),column);
ali@9
   186
#endif
ali@9
   187
	    column=gtk_tree_view_column_new();
ali@9
   188
	    gtk_tree_view_column_set_title(column,"Summary");
ali@9
   189
	    renderer=gtk_cell_renderer_text_new();
ali@9
   190
	    gtk_tree_view_column_pack_start(column,renderer,FALSE);
ali@9
   191
	    gtk_tree_view_column_set_cell_data_func(column,renderer,
ali@9
   192
	      package_cell_data_func,NULL,NULL);
ali@9
   193
	    gtk_tree_view_append_column(view,column);
ali@9
   194
	    gtk_widget_show_all(w);
ali@9
   195
	    gtk_tree_view_set_headers_visible(view,FALSE);
ali@9
   196
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"SearchEntry"));
ali@9
   197
	    gtk_tree_view_set_search_entry(view,GTK_ENTRY(w));
ali@9
   198
	    selection=gtk_tree_view_get_selection(view);
ali@9
   199
	    g_signal_connect(selection,"changed",
ali@9
   200
	      G_CALLBACK(package_selection_changed),NULL);
ali@9
   201
	    g_signal_connect(view,"row-activated",G_CALLBACK(package_activated),
ali@9
   202
	      NULL);
ali@9
   203
	}
ali@9
   204
	else
ali@9
   205
	    g_warning("Packages: no such widget in UI");
ali@9
   206
	w=GTK_WIDGET(gtk_builder_get_object(ui,"Files"));
ali@9
   207
	if (w)
ali@9
   208
	{
ali@9
   209
	    column=gtk_tree_view_column_new_with_attributes("Name",
ali@9
   210
	      gtk_cell_renderer_text_new(),"text",
ali@9
   211
	      PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN,NULL);
ali@9
   212
	    gtk_tree_view_append_column(GTK_TREE_VIEW(w),column);
ali@9
   213
	    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(w),FALSE);
ali@9
   214
	    gtk_widget_show_all(w);
ali@9
   215
	}
ali@9
   216
	else
ali@9
   217
	    g_warning("Files: no such widget in UI");
ali@9
   218
    }
ali@9
   219
    if (view)
ali@9
   220
    {
ali@9
   221
	gtk_tree_view_set_model(view,model);
ali@9
   222
	gtk_tree_view_set_search_column(view,
ali@9
   223
	  PLOVER_PACKAGE_STORE_NAME_COLUMN);
ali@9
   224
    }
ali@9
   225
    package_present(NULL);
ali@9
   226
}
ali@9
   227
ali@9
   228
PloverPackage *get_active_package(void)
ali@9
   229
{
ali@9
   230
    return active;
ali@9
   231
}
ali@9
   232
ali@9
   233
G_MODULE_EXPORT void
ali@9
   234
  on_view_files_toggled(GtkCheckMenuItem *menuitem,gpointer data)
ali@9
   235
{
ali@9
   236
    view_files=gtk_check_menu_item_get_active(menuitem);
ali@9
   237
    package_present(active);
ali@9
   238
}
ali@9
   239
ali@9
   240
G_MODULE_EXPORT void
ali@9
   241
  on_view_details_toggled(GtkCheckMenuItem *menuitem,gpointer data)
ali@9
   242
{
ali@9
   243
}