*.lo
*.la
plover/plover.pc
+plover-gtk/plover-gtk.pc
setup/resources.rc
setup/setup
update/resources.rc
update/update
+app-manager/resources.rc
desktop_DATA=app-manager.desktop
scaleabledir=$(datadir)/icons/hicolor/scalable/apps
scaleable_DATA=plover-applications.svg
+smallicondir=$(datadir)/icons/hicolor/24x24/apps
+smallicon_DATA=24x24/plover-applications.png
+bigicondir=$(datadir)/icons/hicolor/48x48/apps
+bigicon_DATA=48x48/plover-applications.png
.rc.$(OBJEXT):
$(WINDRES) $< $@
-resources.$(OBJEXT): plover-applications.ico
+resources.$(OBJEXT): app-manager.ico
plover-applications%.pnm: plover-applications.svg
rsvg -w $* -h $* -f png $< temp.png
pngtopnm temp.png | pnmquant 256 > $@
$(RM) temp.png
-app-manager.ico: plover-applications16.pnm \
- plover-applications22.pnm plover-applications32.pnm
- ppmtowinicon -output=$@ $^
+plover-applications%.pgm: plover-applications.svg
+ rsvg -w $* -h $* -f png $< temp.png
+ pngtopnm -alpha temp.png > $@
+ $(RM) temp.png
+
+24x24/plover-applications.png: plover-applications.svg
+ mkdir -p 24x24
+ rsvg -w 24 -h 24 -f png $< $@
+
+48x48/plover-applications.png: plover-applications.svg
+ mkdir -p 48x48
+ rsvg -w 48 -h 48 -f png $< $@
+
+app-manager.ico: plover-applications16.pnm plover-applications16.pgm \
+ plover-applications22.pnm plover-applications22.pgm \
+ plover-applications32.pnm plover-applications32.pgm \
+ plover-applications46.pnm plover-applications46.pgm
+ ppmtowinicon -andpgms -output=$@ $^
+
+clean-local:
+ -rm -rf 24x24 48x48
EXTRA_DIST=app-manager.desktop app-manager.ui plover-applications.svg
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)
{
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))
{
- g_clear_error(&err);
+#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);
(void)g_file_get_contents(s,&contents,&len,&err);
g_free(s);
}
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);
}
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);
}
}
{
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;
#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)
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);
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)
+#include <razor.h>
#include <gtk/gtk.h>
#include <plover-gtk/package.h>
extern GtkBuilder *ui;
+extern struct razor_relocations *relocations;
GtkTreeModel *plover_applications_model_new(GtkTreeModel *installed);
void set_package_model(GtkTreeModel *model);
PloverPackage *get_active_package(void);
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
- <object class="GtkRadioMenuItem" id="menuitem2">
+ <object class="GtkRadioMenuItem" id="ViewFiles">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="tooltip_text" translatable="yes">Show a list of files owned by the selected package</property>
<property name="use_underline">True</property>
<property name="active">True</property>
<property name="draw_as_radio">True</property>
- <property name="group">menuitem2</property>
+ <property name="group">ViewFiles</property>
<signal name="toggled" handler="on_view_details_toggled"/>
</object>
</child>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="orientation">vertical</property>
- <property name="position">200</property>
+ <property name="position">215</property>
<property name="position_set">True</property>
<child>
<object class="GtkAlignment" id="alignment1">
<property name="tooltip_text" translatable="yes">Show installed applications</property>
<property name="label" translatable="yes">_Applications</property>
<property name="use_underline">True</property>
- <property name="icon_name">plover-applications</property>
+ <property name="stock_id">plover-applications</property>
<property name="active">True</property>
<signal name="toggled" handler="on_applications_toggled"/>
</object>
#include "config.h"
#include <stdlib.h>
#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
#include <glib.h>
#include <gtk/gtk.h>
#include <plover-gtk/packagestore.h>
#include "app-manager.h"
+#ifdef WIN32
+static BOOL CALLBACK plover_applications_visible_callback(HMODULE module,
+ const char *type,char *name,long *param)
+{
+ gboolean *visible=(void *)param;
+ if (!IS_INTRESOURCE(name) && !strcmp(name,"MAINICON"))
+ *visible=TRUE;
+ return !*visible;
+}
+#endif
+
static gboolean plover_applications_visible_func(GtkTreeModel *model,
GtkTreeIter *iter,gpointer data)
{
/* Visible if row is non-empty and package contains a .desktop file
- * in /usr/share/applications
+ * in /usr/share/applications (UNIX) or package contains a .exe file
+ * which has a default application icon (MS-Windows).
*/
PloverPackage *package;
GtkTreeModel *file_store;
GtkTreeIter fi;
- gchar *name,*dir;
+ gchar *name;
+#ifdef WIN32
+ HMODULE module;
+ DWORD flags=
+#ifdef LOAD_LIBRARY_AS_IMAGE_RESOURCE
+ LOAD_LIBRARY_AS_IMAGE_RESOURCE|
+#endif
+ LOAD_LIBRARY_AS_DATAFILE;
+#else
+ gchar *dir;
+#endif
gboolean visible=FALSE;
gtk_tree_model_get(model,iter,PLOVER_PACKAGE_STORE_OBJ_COLUMN,&package,-1);
if (package)
{
gtk_tree_model_get(file_store,&fi,
PLOVER_PACKAGE_FILE_STORE_NAME_COLUMN,&name,-1);
+#ifdef WIN32
+ if (g_str_has_suffix(name,".exe"))
+ {
+ module=LoadLibraryExA(name,NULL,flags);
+ if (module)
+ {
+ (void)EnumResourceNamesA(module,RT_ICON,
+ plover_applications_visible_callback,&visible);
+ if (!visible)
+ (void)EnumResourceNamesA(module,RT_GROUP_ICON,
+ plover_applications_visible_callback,&visible);
+ FreeLibrary(module);
+ }
+ }
+#else
dir=g_path_get_dirname(name);
if (!strcmp(dir,"/usr/share/applications") &&
g_str_has_suffix(name,".desktop"))
visible=TRUE;
g_free(dir);
+#endif
g_free(name);
} while(!visible && gtk_tree_model_iter_next(file_store,&fi));
}
{
GtkTreeModel *model;
model=gtk_tree_model_filter_new(installed,NULL);
- gtk_tree_model_filter_set_visible_func(model,
+ gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(model),
plover_applications_visible_func,NULL,NULL);
return model;
}
#include "config.h"
#include <stdlib.h>
#include <string.h>
+#ifdef WIN32
+#include <windows.h>
+#endif
#include <glib.h>
#include <gio/gio.h>
#include <gtk/gtk.h>
#include <plover-gtk/packagestore.h>
+#include "app-manager.h"
#include "localmedia.h"
G_DEFINE_TYPE(PloverLocalMediaStore,plover_local_media_store,
{
GFile *root;
gchar *path;
+#ifdef WIN32
+ gunichar2 *path2;
+ UINT type;
+#endif
PloverPackageSet *set;
root=g_mount_get_root(mount);
path=g_file_get_path(root);
+#ifdef WIN32
if (path)
{
- set=plover_package_set_new_from_repository(path,NULL);
+ path2=g_utf8_to_utf16(path,-1,NULL,NULL,NULL);
+ if (path2)
+ {
+ type=GetDriveTypeW(path2);
+ g_free(path2);
+ }
+ else
+ type=DRIVE_UNKNOWN;
+ if (type!=DRIVE_REMOVABLE && type!=DRIVE_CDROM)
+ {
+ gchar *name=g_mount_get_name(mount);
+ g_debug("Skipping non-local mount \"%s\"",name);
+ g_free(name);
+ g_free(path);
+ path=NULL;
+ }
+ }
+#endif
+ if (path)
+ {
+ set=plover_package_set_new_from_repository(path,relocations,NULL);
if (set)
{
g_object_set_data(G_OBJECT(mount),"plover-local-media-set",set);
{
GVolume *volume;
GMount *mount;
- GList *volumes,*link;
- if (g_drive_has_media(drive))
- {
+ GList *volumes,*mounts,*link;
+ if (!drive)
+ volumes=g_volume_monitor_get_volumes(store->monitor);
+ else if (g_drive_has_media(drive))
volumes=g_drive_get_volumes(drive);
- for(link=volumes;link;link=link->next)
+ else
+ volumes=NULL;
+ for(link=volumes;link;link=link->next)
+ {
+ volume=G_VOLUME(link->data);
+ mount=g_volume_get_mount(volume);
+ if (mount)
{
- volume=G_VOLUME(link->data);
- mount=g_volume_get_mount(volume);
- if (mount)
- {
- local_media_scan_mount(store,mount);
- g_object_unref(mount);
- }
- else if (!store->implicit_scan && g_volume_can_mount(volume))
- g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL,
- local_media_mounted,store);
- g_object_unref(volume);
+ local_media_scan_mount(store,mount);
+ g_object_unref(mount);
+ }
+ else if (!store->implicit_scan && g_volume_can_mount(volume))
+ g_volume_mount(volume,G_MOUNT_MOUNT_NONE,NULL,NULL,
+ local_media_mounted,store);
+ g_object_unref(volume);
+ }
+ g_list_free(volumes);
+ if (!drive)
+ {
+ mounts=g_volume_monitor_get_mounts(store->monitor);
+ for(link=mounts;link;link=link->next)
+ {
+ mount=G_MOUNT(link->data);
+ local_media_scan_mount(store,mount);
+ g_object_unref(mount);
}
- g_list_free(volumes);
+ g_list_free(mounts);
}
}
void plover_local_media_store_scan(PloverLocalMediaStore *store)
{
- GList *drives,*link;
+ GList *sets,*drives,*link;
GDrive *drive;
g_return_if_fail(PLOVER_IS_LOCAL_MEDIA_STORE(store));
+ sets=
+ g_slist_copy(plover_package_store_get_sets(PLOVER_PACKAGE_STORE(store)));
+ for(link=sets;link;link=link->next)
+ plover_package_store_remove_set(PLOVER_PACKAGE_STORE(store),
+ PLOVER_PACKAGE_SET(link->data));
+ g_slist_free(sets);
drives=g_volume_monitor_get_connected_drives(store->monitor);
for(link=drives;link;link=link->next)
{
g_object_unref(drive);
}
g_list_free(drives);
+ local_media_scan_drive(store,NULL);
}
static void local_media_mount_added(GVolumeMonitor *volume_monitor,
if (t)
t+=3;
if (t)
- s=strndup(t,strcspn(t,"/"));
+ s=g_strndup(t,strcspn(t,"/"));
else
- s=strdup(text);
+ s=g_strdup(text);
gtk_button_set_label(GTK_BUTTON(w),s);
g_free(s);
}
{
gchar *markup;
gchar *summary,*name,*version;
+ g_return_if_fail(GTK_IS_TREE_MODEL(model));
gtk_tree_model_get(model,iter,PLOVER_PACKAGE_STORE_SUMMARY_COLUMN,&summary,
PLOVER_PACKAGE_STORE_NAME_COLUMN,&name,
PLOVER_PACKAGE_STORE_VERSION_COLUMN,&version,-1);
- markup=g_strdup_printf("<b>%s</b>\n%s %s",summary,name,version,NULL);
+ markup=g_markup_printf_escaped("<b>%s</b>\n%s %s",summary,name,version);
g_free(summary);
g_free(name);
g_free(version);
##################################################
# Checks for library functions.
##################################################
+AC_CHECK_FUNCS_ONCE([fchdir])
##################################################
# Checks for processor independent files.
AM_CFLAGS=-g $(PLOVER_GTK_CFLAGS)
-LIBS=$(PLOVER_GTK_LIBS)
+LIBS=../plover/libplover.la $(PLOVER_GTK_LIBS)
INCLUDES=-I$(top_srcdir)
LDFLAGS=-no-undefined -version-info $(PLOVER_GTK_LT_VERSION_INFO)
#include <stdlib.h>
#include <string.h>
#include <glib-object.h>
+#include <gtk/gtk.h>
#include <razor.h>
#include "plover-gtk/package.h"
const char *plover_package_get_name(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *name;
+ const char *name=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_NAME,&name,
const char *plover_package_get_summary(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *summary;
+ const char *summary=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_SUMMARY,&summary,
const char *plover_package_get_version(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *version;
+ const char *version=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_VERSION,&version,
const char *plover_package_get_license(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *license;
+ const char *license=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_LICENSE,&license,
const char *plover_package_get_arch(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *arch;
+ const char *arch=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_ARCH,&arch,
const char *plover_package_get_description(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *description;
+ const char *description=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_DESCRIPTION,
const char *plover_package_get_URL(PloverPackage *package)
{
PloverPackagePrivate *priv;
- const char *URL;
+ const char *URL=NULL;
g_return_val_if_fail(PLOVER_IS_PACKAGE(package),NULL);
priv=PLOVER_PACKAGE_GET_PRIVATE(package);
razor_package_get_details(priv->set,priv->pkg,RAZOR_DETAIL_URL,&URL,
plover_package_file_store_new(struct razor_file_iterator *files)
{
const char *name;
+ char *s;
GSequenceIter *si;
GtkTreeIter ti;
GtkTreePath *path;
indices=gtk_tree_path_get_indices(path);
while(razor_file_iterator_next(files,&name))
{
- si=g_sequence_insert_sorted(priv->seq,g_strdup(name),g_strcmp0,NULL);
+ s=g_strdup(name);
+#ifdef WIN32
+ s=g_strdelimit(s,"/",'\\');
+#endif
+ si=g_sequence_insert_sorted(priv->seq,s,g_strcmp0,NULL);
*indices=g_sequence_iter_get_position(si);
ti.stamp=priv->stamp;
ti.user_data=si;
struct razor_root *root;
struct razor_set *set;
GSList *packages;
+ int no_details;
} PloverPackageSetPrivate;
#define PLOVER_PACKAGE_SET_GET_PRIVATE(obj)\
static void plover_package_set_init(PloverPackageSet *set)
{
+ PloverPackageSetPrivate *priv;
+ priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
+ priv->no_details=-1;
}
PloverPackageSet *plover_package_set_new(void)
}
PloverPackageSet *plover_package_set_new_from_repository(const char *base,
- GError **err)
+ struct razor_relocations *relocations,GError **err)
{
+#if HAVE_FCHDIR
int fd;
+#else
+ size_t wd_len;
+ char *wd;
+#endif
gchar *s;
+ struct razor_set *reloc;
PloverPackageSet *set;
PloverPackageSetPrivate *priv;
set=plover_package_set_new();
priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
+#if HAVE_FCHDIR
fd=open(".",O_RDONLY);
+#else
+ wd_len=32;
+ wd=malloc(wd_len);
+ while (!getcwd(wd,wd_len) && errno==ERANGE)
+ {
+ free(wd);
+ wd_len*=2;
+ wd=malloc(wd_len);
+ }
+#endif
s=g_build_filename(base,"repodata",NULL);
if (chdir(s)<0)
{
g_set_error(err,G_FILE_ERROR,g_file_error_from_errno(errno),
"%s: %s",s,g_strerror(errno));
g_object_unref(set);
+#if HAVE_FCHDIR
+ close(fd);
+#else
+ free(wd);
+#endif
return NULL;
}
g_free(s);
priv->set=plover_razor_set_create_from_yum("..");
+#if HAVE_FCHDIR
fchdir(fd);
close(fd);
+#else
+ chdir(wd);
+ free(wd);
+#endif
+ if (priv->set && relocations)
+ {
+ reloc=plover_relocate_packages(priv->set,base,relocations);
+ razor_set_destroy(priv->set);
+ priv->set=reloc;
+ }
if (!priv->set)
{
g_set_error(err,PLOVER_RAZOR_ERROR,PLOVER_RAZOR_ERROR_FAILED,
}
return priv->packages;
}
+
+/*
+ * Some versions of razor have a bug which causes all detail strings
+ * to be discarded. If such a version of razor is used to install or
+ * update a package, then all the detail strings for the installed
+ * set will be lost. This function tests for this condition and can
+ * be used to present something more useful than blank details.
+ */
+
+gboolean plover_package_set_get_no_details(PloverPackageSet *set)
+{
+ PloverPackageSetPrivate *priv;
+ PloverPackage *package;
+ GSList *packages,*link;
+ g_return_val_if_fail(PLOVER_IS_PACKAGE_SET(set),FALSE);
+ priv=PLOVER_PACKAGE_SET_GET_PRIVATE(set);
+ if (priv->no_details<0)
+ {
+ packages=plover_package_set_get_packages(set);
+ if (packages)
+ {
+ priv->no_details=0;
+ for(link=packages;link;link=link->next)
+ {
+ package=link->data;
+ priv->no_details+=2;
+ if (*plover_package_get_summary(package))
+ priv->no_details--;
+ if (*plover_package_get_license(package))
+ priv->no_details--;
+ if (*plover_package_get_description(package))
+ priv->no_details--;
+ if (*plover_package_get_URL(package))
+ priv->no_details--;
+ }
+ if (priv->no_details<0) /* More than 50% of strings present */
+ priv->no_details=0;
+ }
+ }
+ return priv->no_details>0;
+}
#ifndef __PLOVER_PACKAGE_SET_H__
#define __PLOVER_PACKAGE_SET_H__
+#include <razor.h>
#include <glib-object.h>
G_BEGIN_DECLS
PloverPackageSet *plover_package_set_new_from_installed(const char *root,
GError **err);
PloverPackageSet *plover_package_set_new_from_repository(const char *base,
- GError **err);
+ struct razor_relocations *relocations,GError **err);
GSList *plover_package_set_get_packages(PloverPackageSet *set);
+gboolean plover_package_set_get_no_details(PloverPackageSet *set);
G_END_DECLS
static void plover_package_store_get_value(GtkTreeModel *tree_model,
GtkTreeIter *iter,gint column,GValue *value)
{
+ char *s;
PloverPackageStore *store=(PloverPackageStore *)tree_model;
PloverPackage *package;
g_return_if_fail(column>=0 && column<PLOVER_PACKAGE_STORE_NO_COLUMNS);
g_return_if_fail(VALID_ITER(iter,store));
- package=g_sequence_get(iter->user_data);
+ package=PLOVER_PACKAGE(g_sequence_get(iter->user_data));
g_value_init(value,column_types[column]);
switch((PloverPackageStoreColumn)column)
{
g_value_set_string(value,plover_package_get_version(package));
break;
case PLOVER_PACKAGE_STORE_SUMMARY_COLUMN:
- g_value_set_string(value,plover_package_get_summary(package));
+ s=plover_package_get_summary(package);
+ if (*s)
+ g_value_set_string(value,s);
+ else
+ {
+ s=g_strconcat("The ",plover_package_get_name(package),
+ " package",NULL);
+ g_value_set_string(value,s);
+ g_free(s);
+ }
break;
}
}
$(WINDRES) resources.rc $@
setup.ico: icon16.pnm icon22.pnm icon32.pnm
- ppmtowinicon -output=$@ $^
+ ppmtowinicon -output=$@ $^
EXTRA_DIST=icon16.png icon22.png icon32.png
MAINICON ICON "setup.ico"
VS_VERSION_INFO VERSIONINFO
- FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_VERS
-ION@,0
- PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_V
-ERSION@,0
+ FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
+ @PLOVER_MICRO_VERSION@,0
+ PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
+ @PLOVER_MICRO_VERSION@,0
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
$(WINDRES) resources.rc $@
update.ico: icon16.pnm icon22.pnm icon32.pnm
- ppmtowinicon -output=$@ $^
+ ppmtowinicon -output=$@ $^
EXTRA_DIST=icon16.png icon22.png icon32.png
MAINICON ICON "update.ico"
VS_VERSION_INFO VERSIONINFO
- FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_VERS
-ION@,0
- PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,@PLOVER_MICRO_V
-ERSION@,0
+ FILEVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
+ @PLOVER_MICRO_VERSION@,0
+ PRODUCTVERSION @PLOVER_MAJOR_VERSION@,@PLOVER_MINOR_VERSION@,
+ @PLOVER_MICRO_VERSION@,0
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{