diff -r 8d3b1ddf789c -r 8b50be3e2998 app-manager/app-manager.c --- a/app-manager/app-manager.c Sat Feb 20 12:11:02 2010 +0000 +++ b/app-manager/app-manager.c Fri Apr 30 20:37:08 2010 +0100 @@ -30,6 +30,169 @@ GtkBuilder *ui; GtkTreeModel *installed,*applications,*location,*local_media; +char *prefix=NULL; +struct razor_relocations *relocations=NULL; + +void show_busy_cursor(gboolean busy) +{ + GList *list,*link,*remaining; + GdkDisplay *display; + GdkCursor *cursor; + GtkWidget *w; + list=gtk_window_list_toplevels(); + while(list) + { + w=GTK_WIDGET(list->data); + if (!w->window) + { + link=list; + list=g_slist_remove_link(list,link); + g_slist_free_1(link); + } + else + { + display=gtk_widget_get_display(w); + cursor=busy?gdk_cursor_new_for_display(display,GDK_WATCH):NULL; + remaining=NULL; + for(link=list;link;link=link->next) + { + w=GTK_WIDGET(link->data); + if (w->window) + { + if (gtk_widget_get_display(w)==display) + gdk_window_set_cursor(w->window,cursor); + else + remaining=g_slist_prepend(remaining,w); + } + } + gdk_display_flush(display); + if (cursor) + gdk_cursor_unref(cursor); + g_list_free(list); + list=remaining; + } + } +} + +/* + * In Gtk+ 2.16.6, the default handler generates g_warnings on error. + * It should display an error to the user. Do it ourselves. + */ + +static void show_uri(GtkLinkButton *button,const gchar *uri,gpointer data) +{ + GdkScreen *screen; + GtkWidget *dialog; + GError *error=NULL; + if (gtk_widget_has_screen(GTK_WIDGET(button))) + screen=gtk_widget_get_screen(GTK_WIDGET(button)); + else + screen=NULL; + gtk_show_uri(screen,uri,GDK_CURRENT_TIME,&error); + if (error) + { + dialog=gtk_message_dialog_new( + GTK_WINDOW(gtk_builder_get_object(ui,"MainWindow")), + GTK_DIALOG_DESTROY_WITH_PARENT,GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE, + "Unable to show '%s'",uri); + gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), + error->message); + g_error_free(error); + gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + } +} + +/* Checks whether a loader for SVG files has been registered + * with GdkPixbuf. + */ +static gboolean pixbuf_supports_svg(void) +{ + GSList *formats; + GSList *tmp_list; + static gint found_svg=-1; + gchar **mime_types,**mime_type; + if (found_svg!=-1) + return found_svg; + formats=gdk_pixbuf_get_formats(); + found_svg=FALSE; + for (tmp_list=formats;tmp_list && !found_svg;tmp_list=tmp_list->next) + { + mime_types=gdk_pixbuf_format_get_mime_types(tmp_list->data); + for (mime_type=mime_types;*mime_type && !found_svg;mime_type++) + if (!strcmp(*mime_type,"image/svg")) + found_svg=TRUE; + g_strfreev(mime_types); + } + g_slist_free(formats); + return found_svg; +} + +static void install_icon_at_size(const char *icon_name,GtkIconSet *icon_set, + GtkIconSize size,const char *filename) +{ + int w,h; + GdkPixbuf *pixbuf; + GtkIconSource *source; + if (gtk_icon_size_lookup(size,&w,&h)) + { + pixbuf=gdk_pixbuf_new_from_file_at_size(filename,w,h,NULL); + if (pixbuf) + { + source=gtk_icon_source_new(); + gtk_icon_source_set_size_wildcarded(source,FALSE); + gtk_icon_source_set_size(source,size); + gtk_icon_source_set_pixbuf(source,pixbuf); + gtk_icon_set_add_source(icon_set,source); + gtk_icon_source_free(source); + g_object_unref(pixbuf); + } + } +} + +static void install_icons(void) +{ + int w,h; + gchar *s; + GdkPixbuf *pixbuf; + GtkIconSource *source; + GtkIconSet *icon_set; + GtkIconFactory *factory; + factory=gtk_icon_factory_new(); + icon_set=gtk_icon_set_new(); + if (pixbuf_supports_svg()) + { + source=gtk_icon_source_new(); + s=g_build_filename(prefix?prefix:"/usr", + "share/icons/hicolor/scalable/apps/plover-applications.svg",NULL); + gtk_icon_source_set_filename(source,s); + g_free(s); + gtk_icon_set_add_source(icon_set,source); + gtk_icon_source_free(source); + } + else + { + s=g_build_filename(prefix?prefix:"/usr", + "share/icons/hicolor/24x24/apps/plover-applications.png",NULL); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_MENU,s); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_BUTTON,s); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_SMALL_TOOLBAR,s); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_LARGE_TOOLBAR,s); + g_free(s); + s=g_build_filename(prefix?prefix:"/usr", + "share/icons/hicolor/48x48/apps/plover-applications.png",NULL); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DND,s); + install_icon_at_size(LOGO_NAME,icon_set,GTK_ICON_SIZE_DIALOG,s); + g_free(s); + } + gtk_icon_factory_add(factory,LOGO_NAME,icon_set); + gtk_icon_set_unref(icon_set); + icon_set=gtk_icon_factory_lookup(factory,LOGO_NAME); + gtk_icon_factory_add_default(factory); + g_object_unref(factory); + icon_set=gtk_icon_factory_lookup_default(LOGO_NAME); + gtk_window_set_default_icon_name(LOGO_NAME); +} int main(int argc,char **argv) { @@ -46,13 +209,20 @@ g_printerr("%s",err->message); exit(0); } - gtk_window_set_default_icon_name(LOGO_NAME); +#ifdef WIN32 + prefix=g_win32_get_package_installation_directory_of_module(NULL); +#endif + install_icons(); ui=gtk_builder_new(); if (!g_file_get_contents("app-manager.ui",&contents,&len,&err) && g_error_matches(err,G_FILE_ERROR,G_FILE_ERROR_NOENT)) { +#ifdef WIN32 + s=g_build_filename(prefix,"share","plover","app-manager.ui",NULL); +#else + s=g_build_filename(PLOVER_DATADIR,"app-manager.ui",NULL); +#endif g_clear_error(&err); - s=g_build_filename(PLOVER_DATADIR,"app-manager.ui",NULL); (void)g_file_get_contents(s,&contents,&len,&err); g_free(s); } @@ -66,15 +236,31 @@ g_error("%s",err->message); exit(0); } + if (prefix) + { + relocations=razor_relocations_create(); + razor_relocations_add(relocations,"/usr",prefix); + } gtk_builder_connect_signals(ui,NULL); + gtk_link_button_set_uri_hook(show_uri,NULL,NULL); installed=GTK_TREE_MODEL(plover_package_store_new()); set=plover_package_set_new_from_installed("",NULL); if (set) + { plover_package_store_add_set(PLOVER_PACKAGE_STORE(installed),set); + if (plover_package_set_get_no_details(set)) + { + w=GTK_WIDGET(gtk_builder_get_object(ui,"ViewFiles")); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w),TRUE); + } + } applications=plover_applications_model_new(installed); set_package_model(applications); gtk_main(); g_object_unref(ui); + if (relocations) + razor_relocations_destroy(relocations); + g_free(prefix); exit(0); } @@ -102,7 +288,11 @@ if (gtk_toggle_tool_button_get_active(button)) { if (!local_media) + { + show_busy_cursor(TRUE); local_media=plover_local_media_store_new(); + show_busy_cursor(FALSE); + } set_package_model(local_media); } } @@ -118,6 +308,9 @@ { GtkWidget *w=GTK_WIDGET(gtk_builder_get_object(ui,"MainWindow")); GtkWidget *dialog; + GFile *file,*parent; + GFileInfo *fi; + GMount *mount; gchar *path,*name; PloverPackageSet *set; GSList *sets; @@ -130,8 +323,9 @@ #endif if (gtk_dialog_run(GTK_DIALOG(dialog))==GTK_RESPONSE_ACCEPT) { + show_busy_cursor(TRUE); path=gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); - set=plover_package_set_new_from_repository(path,&err); + set=plover_package_set_new_from_repository(path,relocations,&err); if (set) { if (!location) @@ -143,7 +337,34 @@ plover_package_store_add_set(PLOVER_PACKAGE_STORE(location),set); g_object_unref(set); w=GTK_WIDGET(gtk_builder_get_object(ui,"LocationButton")); - name=g_filename_display_basename(path); + file=g_file_new_for_path(path); + parent=g_file_get_parent(file); + if (parent) + { + g_object_unref(parent); + mount=NULL; + } + else + mount=g_file_find_enclosing_mount(file,NULL,NULL); + if (mount) + { + name=g_mount_get_name(mount); + g_object_unref(mount); + } + else + { + fi=g_file_query_info(file, + G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,NULL,NULL); + if (fi) + { + name=g_strdup(g_file_info_get_display_name(fi)); + g_object_unref(fi); + } + else + name=g_filename_display_basename(path); + g_object_unref(file); + } gtk_tool_button_set_label(GTK_TOOL_BUTTON(w),name); g_free(name); gtk_widget_show(w); @@ -161,15 +382,18 @@ g_error_free(err); } g_free(path); + show_busy_cursor(FALSE); } gtk_widget_destroy(dialog); } G_MODULE_EXPORT void on_scan_local_media(GtkWidget *widget) { + show_busy_cursor(TRUE); if (!local_media) local_media=plover_local_media_store_new(); plover_local_media_store_scan(PLOVER_LOCAL_MEDIA_STORE(local_media)); + show_busy_cursor(FALSE); } G_MODULE_EXPORT void on_help_about(GtkWidget *widget)