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