app-manager/app-manager.c
author J. Ali Harlow <ali@juiblex.co.uk>
Sat Jul 16 11:07:18 2016 +0100 (2016-07-16)
changeset 61 31fb35727621
parent 38 a29623b68ca2
child 103 c4b0d5cc34bc
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@24
    22
#ifdef WIN32
ali@24
    23
#include <windows.h>
ali@24
    24
#endif	/* WIN32 */
ali@24
    25
#include <lua.h>
ali@9
    26
#include <glib.h>
ali@9
    27
#include <gio/gio.h>
ali@9
    28
#include <gtk/gtk.h>
ali@24
    29
#include <whelk/whelk.h>
ali@31
    30
#include <plover/plover.h>
ali@24
    31
#include <plover/packageset.h>
ali@24
    32
#include <plover-gtk/stockicons.h>
ali@9
    33
#include "app-manager.h"
ali@9
    34
#include "localmedia.h"
ali@9
    35
ali@24
    36
LUALIB_API int luaopen_posix(lua_State *L);
ali@24
    37
ali@9
    38
#define LOGO_NAME	"plover-applications"
ali@9
    39
ali@9
    40
GtkBuilder *ui;
ali@9
    41
GtkTreeModel *installed,*applications,*location,*local_media;
ali@10
    42
char *prefix=NULL;
ali@10
    43
struct razor_relocations *relocations=NULL;
ali@10
    44
ali@10
    45
void show_busy_cursor(gboolean busy)
ali@10
    46
{
ali@10
    47
    GList *list,*link,*remaining;
ali@10
    48
    GdkDisplay *display;
ali@10
    49
    GdkCursor *cursor;
ali@10
    50
    GtkWidget *w;
ali@10
    51
    list=gtk_window_list_toplevels();
ali@10
    52
    while(list)
ali@10
    53
    {
ali@10
    54
	w=GTK_WIDGET(list->data);
ali@10
    55
	if (!w->window)
ali@10
    56
	{
ali@10
    57
	    link=list;
ali@12
    58
	    list=g_list_remove_link(list,link);
ali@12
    59
	    g_list_free_1(link);
ali@10
    60
	}
ali@10
    61
	else
ali@10
    62
	{
ali@10
    63
	    display=gtk_widget_get_display(w);
ali@10
    64
	    cursor=busy?gdk_cursor_new_for_display(display,GDK_WATCH):NULL;
ali@10
    65
	    remaining=NULL;
ali@10
    66
	    for(link=list;link;link=link->next)
ali@10
    67
	    {
ali@10
    68
		w=GTK_WIDGET(link->data);
ali@10
    69
		if (w->window)
ali@10
    70
		{
ali@10
    71
		    if (gtk_widget_get_display(w)==display)
ali@10
    72
			gdk_window_set_cursor(w->window,cursor);
ali@10
    73
		    else
ali@12
    74
			remaining=g_list_prepend(remaining,w);
ali@10
    75
		}
ali@10
    76
	    }
ali@10
    77
	    gdk_display_flush(display);
ali@10
    78
	    if (cursor)
ali@10
    79
		gdk_cursor_unref(cursor);
ali@10
    80
	    g_list_free(list);
ali@10
    81
	    list=remaining;
ali@10
    82
	}
ali@10
    83
    }
ali@10
    84
}
ali@10
    85
ali@10
    86
/*
ali@10
    87
 * In Gtk+ 2.16.6, the default handler generates g_warnings on error.
ali@10
    88
 * It should display an error to the user. Do it ourselves.
ali@10
    89
 */
ali@10
    90
ali@10
    91
static void show_uri(GtkLinkButton *button,const gchar *uri,gpointer data)
ali@10
    92
{
ali@10
    93
    GdkScreen *screen;
ali@10
    94
    GtkWidget *dialog;
ali@10
    95
    GError *error=NULL;
ali@10
    96
    if (gtk_widget_has_screen(GTK_WIDGET(button)))
ali@10
    97
	screen=gtk_widget_get_screen(GTK_WIDGET(button));
ali@10
    98
    else
ali@10
    99
	screen=NULL;
ali@10
   100
    gtk_show_uri(screen,uri,GDK_CURRENT_TIME,&error);
ali@10
   101
    if (error)
ali@10
   102
    {
ali@10
   103
	dialog=gtk_message_dialog_new(
ali@10
   104
	  GTK_WINDOW(gtk_builder_get_object(ui,"MainWindow")),
ali@10
   105
	  GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
ali@10
   106
	  "Unable to show '%s'",uri);
ali@10
   107
	gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
ali@10
   108
	  error->message);
ali@10
   109
	g_error_free(error);
ali@10
   110
	gtk_dialog_run(GTK_DIALOG(dialog));
ali@10
   111
	gtk_widget_destroy(dialog);
ali@10
   112
    }
ali@10
   113
}
ali@10
   114
ali@24
   115
#if 0
ali@10
   116
/* Checks whether a loader for SVG files has been registered
ali@10
   117
 * with GdkPixbuf.
ali@10
   118
 */
ali@10
   119
static gboolean pixbuf_supports_svg(void)
ali@10
   120
{
ali@10
   121
    GSList *formats;
ali@10
   122
    GSList *tmp_list;
ali@10
   123
    static gint found_svg=-1;
ali@10
   124
    gchar **mime_types,**mime_type;
ali@10
   125
    if (found_svg!=-1)
ali@10
   126
	return found_svg;
ali@10
   127
    formats=gdk_pixbuf_get_formats();
ali@10
   128
    found_svg=FALSE;
ali@10
   129
    for (tmp_list=formats;tmp_list && !found_svg;tmp_list=tmp_list->next)
ali@10
   130
    {
ali@10
   131
	mime_types=gdk_pixbuf_format_get_mime_types(tmp_list->data);
ali@10
   132
	for (mime_type=mime_types;*mime_type && !found_svg;mime_type++)
ali@10
   133
	    if (!strcmp(*mime_type,"image/svg"))
ali@10
   134
		found_svg=TRUE;
ali@10
   135
	g_strfreev(mime_types);
ali@10
   136
    }
ali@10
   137
    g_slist_free(formats);
ali@10
   138
    return found_svg;
ali@10
   139
}
ali@10
   140
ali@10
   141
static void install_icon_at_size(const char *icon_name,GtkIconSet *icon_set,
ali@10
   142
  GtkIconSize size,const char *filename)
ali@10
   143
{
ali@10
   144
    int w,h;
ali@10
   145
    GdkPixbuf *pixbuf;
ali@10
   146
    GtkIconSource *source;
ali@10
   147
    if (gtk_icon_size_lookup(size,&w,&h))
ali@10
   148
    {
ali@10
   149
	pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL);
ali@10
   150
	if (pixbuf)
ali@10
   151
	{
ali@10
   152
	    source=gtk_icon_source_new();
ali@10
   153
	    gtk_icon_source_set_size_wildcarded(source,FALSE);
ali@10
   154
	    gtk_icon_source_set_size(source,size);
ali@10
   155
	    gtk_icon_source_set_pixbuf(source,pixbuf);
ali@10
   156
	    gtk_icon_set_add_source(icon_set,source);
ali@10
   157
	    gtk_icon_source_free(source);
ali@10
   158
	    g_object_unref(pixbuf);
ali@10
   159
	}
ali@10
   160
    }
ali@10
   161
}
ali@10
   162
ali@10
   163
static void install_icons(void)
ali@10
   164
{
ali@10
   165
    gchar *s;
ali@10
   166
    GtkIconSource *source;
ali@10
   167
    GtkIconSet *icon_set;
ali@10
   168
    GtkIconFactory *factory;
ali@10
   169
    factory=gtk_icon_factory_new();
ali@10
   170
    icon_set=gtk_icon_set_new();
ali@10
   171
    if (pixbuf_supports_svg())
ali@10
   172
    {
ali@10
   173
	source=gtk_icon_source_new();
ali@10
   174
	s=g_build_filename(prefix?prefix:"/usr",
ali@10
   175
	  "share/icons/hicolor/scalable/apps/plover-applications.svg",NULL);
ali@10
   176
	gtk_icon_source_set_filename(source,s);
ali@10
   177
	g_free(s);
ali@10
   178
	gtk_icon_set_add_source(icon_set,source);
ali@10
   179
	gtk_icon_source_free(source);
ali@10
   180
    }
ali@10
   181
    else
ali@10
   182
    {
ali@10
   183
	s=g_build_filename(prefix?prefix:"/usr",
ali@10
   184
	  "share/icons/hicolor/24x24/apps/plover-applications.png",NULL);
ali@10
   185
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_MENU,s);
ali@10
   186
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_BUTTON,s);
ali@10
   187
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_SMALL_TOOLBAR,s);
ali@10
   188
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR,s);
ali@10
   189
	g_free(s);
ali@10
   190
	s=g_build_filename(prefix?prefix:"/usr",
ali@10
   191
	  "share/icons/hicolor/48x48/apps/plover-applications.png",NULL);
ali@10
   192
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DND,s);
ali@10
   193
	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DIALOG,s);
ali@10
   194
	g_free(s);
ali@10
   195
    }
ali@10
   196
    gtk_icon_factory_add(factory,LOGO_NAME,icon_set);
ali@10
   197
    gtk_icon_set_unref(icon_set);
ali@10
   198
    icon_set=gtk_icon_factory_lookup(factory,LOGO_NAME);
ali@10
   199
    gtk_icon_factory_add_default(factory);
ali@10
   200
    g_object_unref(factory);
ali@10
   201
    icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
ali@10
   202
    gtk_window_set_default_icon_name(LOGO_NAME);
ali@10
   203
}
ali@24
   204
#endif
ali@24
   205
ali@24
   206
static void install_icons(void)
ali@24
   207
{
ali@24
   208
    GtkIconSet *icon_set;
ali@24
   209
    plover_icons_add_to_stock("apps",LOGO_NAME);
ali@24
   210
    icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
ali@24
   211
    gtk_window_set_default_icon_name(LOGO_NAME);
ali@24
   212
}
ali@9
   213
ali@9
   214
int main(int argc,char **argv)
ali@9
   215
{
ali@9
   216
    GError *err=0;
ali@9
   217
    GtkWidget *w;
ali@61
   218
    gchar *s,*database_uri,*contents;
ali@61
   219
    gchar *database=NULL,*setup_base=NULL,*update_base=NULL;
ali@9
   220
    gsize len;
ali@61
   221
    struct comps *comps;
ali@61
   222
    PloverPackageSet *set=NULL;
ali@24
   223
    GSList *objects,*lnk;
ali@24
   224
    gboolean started;
ali@9
   225
    GOptionEntry options[]={
ali@61
   226
	{"database",0,0,G_OPTION_ARG_STRING,&database,
ali@61
   227
	  "Operate on a distribution-local database","vendor/distribution"},
ali@61
   228
	{"setup",0,0,G_OPTION_ARG_STRING,&setup_base,
ali@61
   229
	  "Setup from installation media","uri"},
ali@61
   230
	{"update",0,0,G_OPTION_ARG_STRING,&update_base,
ali@61
   231
	  "Update from upgrade media","uri"},
ali@9
   232
	{NULL}
ali@9
   233
    };
ali@24
   234
#ifdef WIN32
ali@24
   235
    /*
ali@24
   236
     * app-manager is normally a GUI application, but rpm scripts may well
ali@24
   237
     * call console applications and it looks ugly if console windows keep
ali@24
   238
     * popping up. Avoid this by allocating our own console and hiding it.
ali@24
   239
     * Note:
ali@24
   240
     *	- If app-manager is a console application (typically for debugging),
ali@24
   241
     *    then skip this step.
ali@24
   242
     *  - Call ShowWindow twice to negate special handling on first call.
ali@24
   243
     */
ali@24
   244
    if (!GetConsoleWindow())
ali@24
   245
    {
ali@24
   246
	AllocConsole();
ali@24
   247
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@24
   248
	ShowWindow(GetConsoleWindow(),SW_HIDE);
ali@24
   249
    }
ali@24
   250
#endif
ali@31
   251
    plover_exception_handler_init();
ali@38
   252
    razor_set_lua_loader("posix",(void (*)())luaopen_posix);
ali@38
   253
    razor_set_lua_loader("whelk",(void (*)())luaopen_whelk);
ali@9
   254
    if (!gtk_init_with_args(&argc,&argv,NULL,options,NULL,&err))
ali@9
   255
    {
ali@24
   256
	g_printerr("%s\n",err->message);
ali@24
   257
	exit(1);
ali@24
   258
    }
ali@24
   259
    if (setup_base && update_base)
ali@24
   260
    {
ali@24
   261
	g_printerr("--setup and --update are mutually exclusive\n");
ali@24
   262
	exit(1);
ali@9
   263
    }
ali@10
   264
#ifdef WIN32
ali@10
   265
    prefix=g_win32_get_package_installation_directory_of_module(NULL);
ali@10
   266
#endif
ali@10
   267
    install_icons();
ali@9
   268
    ui=gtk_builder_new();
ali@9
   269
    if (!g_file_get_contents("app-manager.ui",&contents,&len,&err) &&
ali@9
   270
      g_error_matches(err,G_FILE_ERROR,G_FILE_ERROR_NOENT))
ali@9
   271
    {
ali@10
   272
#ifdef WIN32
ali@10
   273
	s=g_build_filename(prefix,"share","plover","app-manager.ui",NULL);
ali@10
   274
#else
ali@10
   275
	s=g_build_filename(PLOVER_DATADIR,"app-manager.ui",NULL);
ali@10
   276
#endif
ali@9
   277
	g_clear_error(&err);
ali@9
   278
	(void)g_file_get_contents(s,&contents,&len,&err);
ali@9
   279
	g_free(s);
ali@9
   280
    }
ali@9
   281
    if (!err)
ali@9
   282
    {
ali@9
   283
	(void)gtk_builder_add_from_string(ui,contents,len,&err);
ali@9
   284
	g_free(contents);
ali@9
   285
    }
ali@9
   286
    if (err)
ali@9
   287
    {
ali@9
   288
	g_error("%s",err->message);
ali@9
   289
	exit(0);
ali@9
   290
    }
ali@9
   291
    gtk_builder_connect_signals(ui,NULL);
ali@10
   292
    gtk_link_button_set_uri_hook(show_uri,NULL,NULL);
ali@24
   293
    if (setup_base)
ali@61
   294
	started=setup(setup_base);
ali@24
   295
    else if (update_base)
ali@61
   296
	started=update(update_base);
ali@24
   297
    else
ali@24
   298
    {
ali@61
   299
	if (database)
ali@61
   300
	{
ali@61
   301
	    g_free(prefix);
ali@61
   302
	    prefix=NULL;
ali@61
   303
	    s=strchr(database,'/');
ali@61
   304
	    if (*s)
ali@61
   305
		*s++='\0';
ali@61
   306
	    comps=plover_comps_new();
ali@61
   307
	    plover_comps_set_vendor(comps,database);
ali@61
   308
	    if (s)
ali@61
   309
	    {
ali@61
   310
		plover_comps_set_distribution(comps,s);
ali@61
   311
		*--s='/';
ali@61
   312
	    }
ali@61
   313
	    prefix=plover_comps_get_default_prefix(comps);
ali@61
   314
	    plover_comps_free(comps);
ali@61
   315
	    s=g_strconcat(prefix,"/var/lib/razor",NULL);
ali@61
   316
	    database_uri=razor_path_to_uri(s);
ali@61
   317
	    g_free(s);
ali@61
   318
	    razor_set_database_uri(database_uri);
ali@61
   319
	    g_free(database_uri);
ali@61
   320
	}
ali@61
   321
	if (prefix)
ali@61
   322
	{
ali@61
   323
	    relocations=razor_relocations_create();
ali@61
   324
	    razor_relocations_add(relocations,"/usr",prefix);
ali@61
   325
	}
ali@61
   326
	installed=GTK_TREE_MODEL(plover_package_store_new());
ali@61
   327
	set=plover_package_set_new();
ali@61
   328
	(void)plover_package_set_open(set,"",TRUE,NULL);
ali@61
   329
	plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
ali@61
   330
	if (plover_package_set_get_no_details(set))
ali@61
   331
	{
ali@61
   332
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
ali@61
   333
	    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
ali@61
   334
	}
ali@61
   335
	applications=plover_applications_model_new(installed);
ali@61
   336
	set_package_model(applications);
ali@24
   337
	w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
ali@24
   338
	gtk_widget_show(w);
ali@24
   339
	started=TRUE;
ali@24
   340
    }
ali@24
   341
    if (started)
ali@24
   342
	gtk_main();
ali@24
   343
    g_clear_object(&set);
ali@24
   344
    objects=gtk_builder_get_objects(ui);
ali@24
   345
    for(lnk=objects;lnk;lnk=lnk->next)
ali@24
   346
	if (GTK_IS_WIDGET(lnk->data) &&
ali@24
   347
	  gtk_widget_is_toplevel(GTK_WIDGET(lnk->data)))
ali@24
   348
	    gtk_widget_destroy(GTK_WIDGET(lnk->data));
ali@24
   349
    g_slist_free(objects);
ali@24
   350
    g_clear_object(&ui);
ali@24
   351
    g_clear_object(&installed);
ali@24
   352
    g_clear_object(&applications);
ali@24
   353
    g_clear_object(&location);
ali@24
   354
    g_clear_object(&local_media);
ali@10
   355
    if (relocations)
ali@10
   356
	razor_relocations_destroy(relocations);
ali@10
   357
    g_free(prefix);
ali@24
   358
    g_free(setup_base);
ali@24
   359
    g_free(update_base);
ali@61
   360
    g_free(database);
ali@9
   361
    exit(0);
ali@9
   362
}
ali@9
   363
ali@9
   364
G_MODULE_EXPORT void
ali@9
   365
  on_applications_toggled(GtkToggleToolButton *button,gpointer data)
ali@9
   366
{
ali@9
   367
    if (gtk_toggle_tool_button_get_active(button))
ali@9
   368
    {
ali@9
   369
	if (!applications)
ali@9
   370
	    applications=plover_applications_model_new(installed);
ali@9
   371
	set_package_model(applications);
ali@9
   372
    }
ali@9
   373
}
ali@9
   374
ali@9
   375
G_MODULE_EXPORT void
ali@9
   376
  on_all_packages_toggled(GtkToggleToolButton *button,gpointer data)
ali@9
   377
{
ali@9
   378
    if (gtk_toggle_tool_button_get_active(button))
ali@9
   379
	set_package_model(installed);
ali@9
   380
}
ali@9
   381
ali@9
   382
G_MODULE_EXPORT void
ali@9
   383
  on_local_media_toggled(GtkToggleToolButton *button,gpointer data)
ali@9
   384
{
ali@9
   385
    if (gtk_toggle_tool_button_get_active(button))
ali@9
   386
    {
ali@9
   387
	if (!local_media)
ali@10
   388
	{
ali@10
   389
	    show_busy_cursor(TRUE);
ali@9
   390
	    local_media=plover_local_media_store_new();
ali@10
   391
	    show_busy_cursor(FALSE);
ali@10
   392
	}
ali@9
   393
	set_package_model(local_media);
ali@9
   394
    }
ali@9
   395
}
ali@9
   396
ali@9
   397
G_MODULE_EXPORT void
ali@9
   398
  on_location_toggled(GtkToggleToolButton *button,gpointer data)
ali@9
   399
{
ali@9
   400
    if (gtk_toggle_tool_button_get_active(button))
ali@9
   401
	set_package_model(location);
ali@9
   402
}
ali@9
   403
ali@9
   404
G_MODULE_EXPORT void on_open_location(GtkWidget *widget)
ali@9
   405
{
ali@9
   406
    GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
ali@9
   407
    GtkWidget *dialog;
ali@10
   408
    GFile *file,*parent;
ali@10
   409
    GFileInfo *fi;
ali@10
   410
    GMount *mount;
ali@9
   411
    gchar *path,*name;
ali@9
   412
    PloverPackageSet *set;
ali@9
   413
    GSList *sets;
ali@9
   414
    GError *err=NULL;
ali@9
   415
    dialog=gtk_file_chooser_dialog_new("Open Location",GTK_WINDOW(w),
ali@9
   416
      GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,GTK_STOCK_CANCEL,
ali@9
   417
      GTK_RESPONSE_CANCEL,GTK_STOCK_OPEN,GTK_RESPONSE_ACCEPT,NULL);
ali@9
   418
#if GTK_CHECK_VERSION(2,18,0)
ali@9
   419
    gtk_file_chooser_set_create_folders(GTK_FILE_CHOOSER(dialog),FALSE);
ali@9
   420
#endif
ali@9
   421
    if (gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT)
ali@9
   422
    {
ali@10
   423
	show_busy_cursor(TRUE);
ali@9
   424
	path=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
ali@24
   425
	set=plover_package_set_new_from_yum(path,relocations,&err);
ali@9
   426
	if (set)
ali@9
   427
	{
ali@9
   428
	    if (!location)
ali@9
   429
		location=GTK_TREE_MODEL(plover_package_store_new());
ali@9
   430
	    while((sets=
ali@9
   431
	      plover_package_store_get_sets(PLOVER_PACKAGE_STORE(location))))
ali@9
   432
		plover_package_store_remove_set(PLOVER_PACKAGE_STORE(location),
ali@9
   433
		  PLOVER_PACKAGE_SET(sets->data));
ali@9
   434
	    plover_package_store_add_set(PLOVER_PACKAGE_STORE(location),set);
ali@9
   435
	    g_object_unref(set);
ali@9
   436
	    w=GTK_WIDGET(gtk_builder_get_object(ui,"LocationButton"));
ali@10
   437
	    file=g_file_new_for_path(path);
ali@10
   438
	    parent=g_file_get_parent(file);
ali@10
   439
	    if (parent)
ali@10
   440
	    {
ali@10
   441
		g_object_unref(parent);
ali@10
   442
		mount=NULL;
ali@10
   443
	    }
ali@10
   444
	    else
ali@10
   445
		mount=g_file_find_enclosing_mount(file,NULL,NULL);
ali@10
   446
	    if (mount)
ali@10
   447
	    {
ali@10
   448
		name=g_mount_get_name(mount);
ali@10
   449
		g_object_unref(mount);
ali@10
   450
	    }
ali@10
   451
	    else
ali@10
   452
	    {
ali@10
   453
		fi=g_file_query_info(file,
ali@10
   454
		  G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
ali@10
   455
		  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,NULL);
ali@10
   456
		if (fi)
ali@10
   457
		{
ali@10
   458
		    name=g_strdup(g_file_info_get_display_name(fi));
ali@10
   459
		    g_object_unref(fi);
ali@10
   460
		}
ali@10
   461
		else
ali@10
   462
		    name=g_filename_display_basename(path);
ali@10
   463
		g_object_unref(file);
ali@10
   464
	    }
ali@9
   465
	    gtk_tool_button_set_label(GTK_TOOL_BUTTON(w),name);
ali@9
   466
	    g_free(name);
ali@9
   467
	    gtk_widget_show(w);
ali@9
   468
	    gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(w),TRUE);
ali@9
   469
	}
ali@9
   470
	else
ali@9
   471
	{
ali@9
   472
	    gtk_widget_destroy(dialog);
ali@9
   473
	    dialog=gtk_message_dialog_new(GTK_WINDOW(w),
ali@9
   474
	      GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,
ali@9
   475
	      GTK_BUTTONS_CLOSE,"Error loading repository '%s'",path);
ali@9
   476
	    gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
ali@9
   477
	      "%s",err->message);
ali@9
   478
	    gtk_dialog_run(GTK_DIALOG(dialog));
ali@9
   479
	    g_error_free(err);
ali@9
   480
	}
ali@9
   481
	g_free(path);
ali@10
   482
	show_busy_cursor(FALSE);
ali@9
   483
    }
ali@9
   484
    gtk_widget_destroy(dialog);
ali@9
   485
}
ali@9
   486
ali@9
   487
G_MODULE_EXPORT void on_scan_local_media(GtkWidget *widget)
ali@9
   488
{
ali@10
   489
    show_busy_cursor(TRUE);
ali@9
   490
    if (!local_media)
ali@9
   491
	local_media=plover_local_media_store_new();
ali@9
   492
    plover_local_media_store_scan(PLOVER_LOCAL_MEDIA_STORE(local_media));
ali@10
   493
    show_busy_cursor(FALSE);
ali@9
   494
}
ali@9
   495
ali@9
   496
G_MODULE_EXPORT void on_help_about(GtkWidget *widget)
ali@9
   497
{
ali@9
   498
    GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
ali@9
   499
    gtk_show_about_dialog(GTK_WINDOW(w),"name",PACKAGE_NAME,
ali@9
   500
      "version",PACKAGE_VERSION,"comments","Application Manager",
ali@24
   501
      "copyright","Copyright © 2010, 2014 J. Ali Harlow",
ali@24
   502
      "logo-icon-name",LOGO_NAME,
ali@9
   503
      NULL);
ali@9
   504
}
ali@9
   505
ali@9
   506
G_MODULE_EXPORT void on_find_clicked(GtkButton *button)
ali@9
   507
{
ali@9
   508
    gchar *text;
ali@9
   509
    GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"SearchEntry"));
ali@9
   510
    text=g_strdup(gtk_entry_get_text(GTK_ENTRY(w)));
ali@9
   511
    gtk_entry_set_text(GTK_ENTRY(w),"");
ali@9
   512
    gtk_entry_set_text(GTK_ENTRY(w),text);
ali@9
   513
    g_free(text);
ali@9
   514
}