app-manager/app-manager.c
changeset 11 0987519d94ba
parent 9 8d3b1ddf789c
child 12 1d18b9c34d26
     1.1 --- a/app-manager/app-manager.c	Sat Feb 20 12:11:02 2010 +0000
     1.2 +++ b/app-manager/app-manager.c	Fri Apr 30 20:37:08 2010 +0100
     1.3 @@ -30,6 +30,169 @@
     1.4  
     1.5  GtkBuilder *ui;
     1.6  GtkTreeModel *installed,*applications,*location,*local_media;
     1.7 +char *prefix=NULL;
     1.8 +struct razor_relocations *relocations=NULL;
     1.9 +
    1.10 +void show_busy_cursor(gboolean busy)
    1.11 +{
    1.12 +    GList *list,*link,*remaining;
    1.13 +    GdkDisplay *display;
    1.14 +    GdkCursor *cursor;
    1.15 +    GtkWidget *w;
    1.16 +    list=gtk_window_list_toplevels();
    1.17 +    while(list)
    1.18 +    {
    1.19 +	w=GTK_WIDGET(list->data);
    1.20 +	if (!w->window)
    1.21 +	{
    1.22 +	    link=list;
    1.23 +	    list=g_slist_remove_link(list,link);
    1.24 +	    g_slist_free_1(link);
    1.25 +	}
    1.26 +	else
    1.27 +	{
    1.28 +	    display=gtk_widget_get_display(w);
    1.29 +	    cursor=busy?gdk_cursor_new_for_display(display,GDK_WATCH):NULL;
    1.30 +	    remaining=NULL;
    1.31 +	    for(link=list;link;link=link->next)
    1.32 +	    {
    1.33 +		w=GTK_WIDGET(link->data);
    1.34 +		if (w->window)
    1.35 +		{
    1.36 +		    if (gtk_widget_get_display(w)==display)
    1.37 +			gdk_window_set_cursor(w->window,cursor);
    1.38 +		    else
    1.39 +			remaining=g_slist_prepend(remaining,w);
    1.40 +		}
    1.41 +	    }
    1.42 +	    gdk_display_flush(display);
    1.43 +	    if (cursor)
    1.44 +		gdk_cursor_unref(cursor);
    1.45 +	    g_list_free(list);
    1.46 +	    list=remaining;
    1.47 +	}
    1.48 +    }
    1.49 +}
    1.50 +
    1.51 +/*
    1.52 + * In Gtk+ 2.16.6, the default handler generates g_warnings on error.
    1.53 + * It should display an error to the user. Do it ourselves.
    1.54 + */
    1.55 +
    1.56 +static void show_uri(GtkLinkButton *button,const gchar *uri,gpointer data)
    1.57 +{
    1.58 +    GdkScreen *screen;
    1.59 +    GtkWidget *dialog;
    1.60 +    GError *error=NULL;
    1.61 +    if (gtk_widget_has_screen(GTK_WIDGET(button)))
    1.62 +	screen=gtk_widget_get_screen(GTK_WIDGET(button));
    1.63 +    else
    1.64 +	screen=NULL;
    1.65 +    gtk_show_uri(screen,uri,GDK_CURRENT_TIME,&error);
    1.66 +    if (error)
    1.67 +    {
    1.68 +	dialog=gtk_message_dialog_new(
    1.69 +	  GTK_WINDOW(gtk_builder_get_object(ui,"MainWindow")),
    1.70 +	  GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
    1.71 +	  "Unable to show '%s'",uri);
    1.72 +	gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
    1.73 +	  error->message);
    1.74 +	g_error_free(error);
    1.75 +	gtk_dialog_run(GTK_DIALOG(dialog));
    1.76 +	gtk_widget_destroy(dialog);
    1.77 +    }
    1.78 +}
    1.79 +
    1.80 +/* Checks whether a loader for SVG files has been registered
    1.81 + * with GdkPixbuf.
    1.82 + */
    1.83 +static gboolean pixbuf_supports_svg(void)
    1.84 +{
    1.85 +    GSList *formats;
    1.86 +    GSList *tmp_list;
    1.87 +    static gint found_svg=-1;
    1.88 +    gchar **mime_types,**mime_type;
    1.89 +    if (found_svg!=-1)
    1.90 +	return found_svg;
    1.91 +    formats=gdk_pixbuf_get_formats();
    1.92 +    found_svg=FALSE;
    1.93 +    for (tmp_list=formats;tmp_list && !found_svg;tmp_list=tmp_list->next)
    1.94 +    {
    1.95 +	mime_types=gdk_pixbuf_format_get_mime_types(tmp_list->data);
    1.96 +	for (mime_type=mime_types;*mime_type && !found_svg;mime_type++)
    1.97 +	    if (!strcmp(*mime_type,"image/svg"))
    1.98 +		found_svg=TRUE;
    1.99 +	g_strfreev(mime_types);
   1.100 +    }
   1.101 +    g_slist_free(formats);
   1.102 +    return found_svg;
   1.103 +}
   1.104 +
   1.105 +static void install_icon_at_size(const char *icon_name,GtkIconSet *icon_set,
   1.106 +  GtkIconSize size,const char *filename)
   1.107 +{
   1.108 +    int w,h;
   1.109 +    GdkPixbuf *pixbuf;
   1.110 +    GtkIconSource *source;
   1.111 +    if (gtk_icon_size_lookup(size,&w,&h))
   1.112 +    {
   1.113 +	pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL);
   1.114 +	if (pixbuf)
   1.115 +	{
   1.116 +	    source=gtk_icon_source_new();
   1.117 +	    gtk_icon_source_set_size_wildcarded(source,FALSE);
   1.118 +	    gtk_icon_source_set_size(source,size);
   1.119 +	    gtk_icon_source_set_pixbuf(source,pixbuf);
   1.120 +	    gtk_icon_set_add_source(icon_set,source);
   1.121 +	    gtk_icon_source_free(source);
   1.122 +	    g_object_unref(pixbuf);
   1.123 +	}
   1.124 +    }
   1.125 +}
   1.126 +
   1.127 +static void install_icons(void)
   1.128 +{
   1.129 +    int w,h;
   1.130 +    gchar *s;
   1.131 +    GdkPixbuf *pixbuf;
   1.132 +    GtkIconSource *source;
   1.133 +    GtkIconSet *icon_set;
   1.134 +    GtkIconFactory *factory;
   1.135 +    factory=gtk_icon_factory_new();
   1.136 +    icon_set=gtk_icon_set_new();
   1.137 +    if (pixbuf_supports_svg())
   1.138 +    {
   1.139 +	source=gtk_icon_source_new();
   1.140 +	s=g_build_filename(prefix?prefix:"/usr",
   1.141 +	  "share/icons/hicolor/scalable/apps/plover-applications.svg",NULL);
   1.142 +	gtk_icon_source_set_filename(source,s);
   1.143 +	g_free(s);
   1.144 +	gtk_icon_set_add_source(icon_set,source);
   1.145 +	gtk_icon_source_free(source);
   1.146 +    }
   1.147 +    else
   1.148 +    {
   1.149 +	s=g_build_filename(prefix?prefix:"/usr",
   1.150 +	  "share/icons/hicolor/24x24/apps/plover-applications.png",NULL);
   1.151 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_MENU,s);
   1.152 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_BUTTON,s);
   1.153 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_SMALL_TOOLBAR,s);
   1.154 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR,s);
   1.155 +	g_free(s);
   1.156 +	s=g_build_filename(prefix?prefix:"/usr",
   1.157 +	  "share/icons/hicolor/48x48/apps/plover-applications.png",NULL);
   1.158 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DND,s);
   1.159 +	install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DIALOG,s);
   1.160 +	g_free(s);
   1.161 +    }
   1.162 +    gtk_icon_factory_add(factory,LOGO_NAME,icon_set);
   1.163 +    gtk_icon_set_unref(icon_set);
   1.164 +    icon_set=gtk_icon_factory_lookup(factory,LOGO_NAME);
   1.165 +    gtk_icon_factory_add_default(factory);
   1.166 +    g_object_unref(factory);
   1.167 +    icon_set=gtk_icon_factory_lookup_default(LOGO_NAME);
   1.168 +    gtk_window_set_default_icon_name(LOGO_NAME);
   1.169 +}
   1.170  
   1.171  int main(int argc,char **argv)
   1.172  {
   1.173 @@ -46,13 +209,20 @@
   1.174  	g_printerr("%s",err->message);
   1.175  	exit(0);
   1.176      }
   1.177 -    gtk_window_set_default_icon_name(LOGO_NAME);
   1.178 +#ifdef WIN32
   1.179 +    prefix=g_win32_get_package_installation_directory_of_module(NULL);
   1.180 +#endif
   1.181 +    install_icons();
   1.182      ui=gtk_builder_new();
   1.183      if (!g_file_get_contents("app-manager.ui",&contents,&len,&err) &&
   1.184        g_error_matches(err,G_FILE_ERROR,G_FILE_ERROR_NOENT))
   1.185      {
   1.186 +#ifdef WIN32
   1.187 +	s=g_build_filename(prefix,"share","plover","app-manager.ui",NULL);
   1.188 +#else
   1.189 +	s=g_build_filename(PLOVER_DATADIR,"app-manager.ui",NULL);
   1.190 +#endif
   1.191  	g_clear_error(&err);
   1.192 -	s=g_build_filename(PLOVER_DATADIR,"app-manager.ui",NULL);
   1.193  	(void)g_file_get_contents(s,&contents,&len,&err);
   1.194  	g_free(s);
   1.195      }
   1.196 @@ -66,15 +236,31 @@
   1.197  	g_error("%s",err->message);
   1.198  	exit(0);
   1.199      }
   1.200 +    if (prefix)
   1.201 +    {
   1.202 +	relocations=razor_relocations_create();
   1.203 +	razor_relocations_add(relocations,"/usr",prefix);
   1.204 +    }
   1.205      gtk_builder_connect_signals(ui,NULL);
   1.206 +    gtk_link_button_set_uri_hook(show_uri,NULL,NULL);
   1.207      installed=GTK_TREE_MODEL(plover_package_store_new());
   1.208      set=plover_package_set_new_from_installed("",NULL);
   1.209      if (set)
   1.210 +    {
   1.211  	plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set);
   1.212 +	if (plover_package_set_get_no_details(set))
   1.213 +	{
   1.214 +	    w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles"));
   1.215 +	    gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE);
   1.216 +	}
   1.217 +    }
   1.218      applications=plover_applications_model_new(installed);
   1.219      set_package_model(applications);
   1.220      gtk_main();
   1.221      g_object_unref(ui);
   1.222 +    if (relocations)
   1.223 +	razor_relocations_destroy(relocations);
   1.224 +    g_free(prefix);
   1.225      exit(0);
   1.226  }
   1.227  
   1.228 @@ -102,7 +288,11 @@
   1.229      if (gtk_toggle_tool_button_get_active(button))
   1.230      {
   1.231  	if (!local_media)
   1.232 +	{
   1.233 +	    show_busy_cursor(TRUE);
   1.234  	    local_media=plover_local_media_store_new();
   1.235 +	    show_busy_cursor(FALSE);
   1.236 +	}
   1.237  	set_package_model(local_media);
   1.238      }
   1.239  }
   1.240 @@ -118,6 +308,9 @@
   1.241  {
   1.242      GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow"));
   1.243      GtkWidget *dialog;
   1.244 +    GFile *file,*parent;
   1.245 +    GFileInfo *fi;
   1.246 +    GMount *mount;
   1.247      gchar *path,*name;
   1.248      PloverPackageSet *set;
   1.249      GSList *sets;
   1.250 @@ -130,8 +323,9 @@
   1.251  #endif
   1.252      if (gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT)
   1.253      {
   1.254 +	show_busy_cursor(TRUE);
   1.255  	path=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
   1.256 -	set=plover_package_set_new_from_repository(path,&err);
   1.257 +	set=plover_package_set_new_from_repository(path,relocations,&err);
   1.258  	if (set)
   1.259  	{
   1.260  	    if (!location)
   1.261 @@ -143,7 +337,34 @@
   1.262  	    plover_package_store_add_set(PLOVER_PACKAGE_STORE(location),set);
   1.263  	    g_object_unref(set);
   1.264  	    w=GTK_WIDGET(gtk_builder_get_object(ui,"LocationButton"));
   1.265 -	    name=g_filename_display_basename(path);
   1.266 +	    file=g_file_new_for_path(path);
   1.267 +	    parent=g_file_get_parent(file);
   1.268 +	    if (parent)
   1.269 +	    {
   1.270 +		g_object_unref(parent);
   1.271 +		mount=NULL;
   1.272 +	    }
   1.273 +	    else
   1.274 +		mount=g_file_find_enclosing_mount(file,NULL,NULL);
   1.275 +	    if (mount)
   1.276 +	    {
   1.277 +		name=g_mount_get_name(mount);
   1.278 +		g_object_unref(mount);
   1.279 +	    }
   1.280 +	    else
   1.281 +	    {
   1.282 +		fi=g_file_query_info(file,
   1.283 +		  G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
   1.284 +		  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,NULL);
   1.285 +		if (fi)
   1.286 +		{
   1.287 +		    name=g_strdup(g_file_info_get_display_name(fi));
   1.288 +		    g_object_unref(fi);
   1.289 +		}
   1.290 +		else
   1.291 +		    name=g_filename_display_basename(path);
   1.292 +		g_object_unref(file);
   1.293 +	    }
   1.294  	    gtk_tool_button_set_label(GTK_TOOL_BUTTON(w),name);
   1.295  	    g_free(name);
   1.296  	    gtk_widget_show(w);
   1.297 @@ -161,15 +382,18 @@
   1.298  	    g_error_free(err);
   1.299  	}
   1.300  	g_free(path);
   1.301 +	show_busy_cursor(FALSE);
   1.302      }
   1.303      gtk_widget_destroy(dialog);
   1.304  }
   1.305  
   1.306  G_MODULE_EXPORT void on_scan_local_media(GtkWidget *widget)
   1.307  {
   1.308 +    show_busy_cursor(TRUE);
   1.309      if (!local_media)
   1.310  	local_media=plover_local_media_store_new();
   1.311      plover_local_media_store_scan(PLOVER_LOCAL_MEDIA_STORE(local_media));
   1.312 +    show_busy_cursor(FALSE);
   1.313  }
   1.314  
   1.315  G_MODULE_EXPORT void on_help_about(GtkWidget *widget)