[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Antiright-devel] antiright/gtkshell Makefile options.c ptk-app-m...
From: |
Jeffrey Bedard |
Subject: |
[Antiright-devel] antiright/gtkshell Makefile options.c ptk-app-m... |
Date: |
Sun, 02 Nov 2008 19:30:25 +0000 |
CVSROOT: /sources/antiright
Module name: antiright
Changes by: Jeffrey Bedard <jefbed> 08/11/02 19:30:25
Modified files:
gtkshell : Makefile options.c
Added files:
gtkshell : ptk-app-menu.c
Log message:
Add desktop file format menu to show all applications on system.
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/antiright/gtkshell/Makefile?cvsroot=antiright&r1=1.59&r2=1.60
http://cvs.savannah.gnu.org/viewcvs/antiright/gtkshell/options.c?cvsroot=antiright&r1=1.41&r2=1.42
http://cvs.savannah.gnu.org/viewcvs/antiright/gtkshell/ptk-app-menu.c?cvsroot=antiright&rev=1.1
Patches:
Index: Makefile
===================================================================
RCS file: /sources/antiright/antiright/gtkshell/Makefile,v
retrieving revision 1.59
retrieving revision 1.60
diff -u -b -r1.59 -r1.60
--- Makefile 26 Oct 2008 00:38:58 -0000 1.59
+++ Makefile 2 Nov 2008 19:30:15 -0000 1.60
@@ -38,7 +38,8 @@
guidl_util.o about_dialog.o init.o guidl_dialog.o guidl_dictionary.o\
guidl_options.o guidl_widgets.o update_manager.o pane.o\
command_shell.o app_mode.o clock.o tree.o form.o dialog.o swallow.o\
- GSHWidget.o quickstart.o undo.o color.o add_options.o option_options.o
+ GSHWidget.o quickstart.o undo.o color.o add_options.o option_options.o\
+ ptk-app-menu.o
program=main.o
Index: options.c
===================================================================
RCS file: /sources/antiright/antiright/gtkshell/options.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -b -r1.41 -r1.42
--- options.c 16 Jan 2008 21:33:07 -0000 1.41
+++ options.c 2 Nov 2008 19:30:21 -0000 1.42
@@ -89,10 +89,28 @@
#define HANDLE(type)\
gsh_handle_##type##_arguments(gsh, argc, argv, counter)
+GtkWidget * ptk_app_menu_new();
+
/* This exists for testing new code. */
static void
test_cb(GSH * gsh, gint * counter, const gchar ** argv)
{
+ GtkWidget * menu_bar;
+ GtkWidget * app_menu;
+ GtkWidget * menu_item;
+
+ app_menu=ptk_app_menu_new();
+ gtk_widget_show(app_menu);
+
+ menu_bar=gtk_menu_bar_new();
+
+ menu_item=gtk_menu_item_new_with_label("Applications");
+ gtk_widget_show(menu_item);
+
+ gtk_menu_bar_append(menu_bar, menu_item);
+ gtk_menu_item_set_submenu(menu_item, app_menu);
+
+ $(gsh, manage, menu_bar);
}
Index: ptk-app-menu.c
===================================================================
RCS file: ptk-app-menu.c
diff -N ptk-app-menu.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ptk-app-menu.c 2 Nov 2008 19:30:24 -0000 1.1
@@ -0,0 +1,717 @@
+/*
+* ptk-app-menu.c
+*
+* Description: Generate menu from desktop files according to the spec on
freedesktop.org
+*
+*
+* Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006
+*
+* Copyright: GNU Lesser General Public License Version 2
+*
+*/
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <string.h>
+//#include "ptk-app-menu.h"
+
+/* Compatibility macros for older versions of glib */
+#if ! GLIB_CHECK_VERSION(2, 10, 0)
+/* older versions of glib don't provde g_slice API */
+#define g_slice_alloc(size) g_malloc(size)
+#define g_slice_alloc0(size) g_malloc0(size)
+#define g_slice_new(type) g_new(type, 1)
+#define g_slice_new0(type) g_new0(type, 1)
+#define g_slice_free(type, mem) g_free(mem)
+#define g_slice_free1(size, mem) g_free(mem)
+#endif
+
+//#include "misc.h" /* Misc functions for lxpanel */
+
+#define ICON_SIZE 18
+
+GQuark PTK_APP_MENU_ITEM_ID = 0;
+
+GtkWidget* ptk_app_menu_new();
+
+static const char desktop_ent[] = "Desktop Entry";
+static const char app_dir_name[] = "applications";
+
+static time_t* times = NULL;
+
+
+typedef struct _CatInfo
+{
+ char* title;
+ char* directory_file;
+ char* icon;
+ const char** sub_cats;
+}CatInfo;
+
+typedef struct _PtkAppMenuItem
+{
+ char* name;
+ char* icon;
+ char* exec;
+}PtkAppMenuItem;
+
+static const char* development_cats[]={
+ "Development",
+ "Translation",
+ "Building","Debugger",
+ "IDE",
+ "GUIDesigner",
+ "Profiling",
+ "RevisionControl",
+ "WebDevelopment",
+ NULL
+};
+
+static const char* office_cats[] = {
+ "Office",
+ "Dictionary",
+ "Chart",
+ "Calendar",
+ "ContactManagement",
+ "Database",
+ NULL
+};
+
+static const char* graphics_cats[] = {
+ "Graphics",
+ "2DGraphics",
+ "3DGraphics",
+ "VectorGraphics",
+ "RasterGraphics",
+ "Viewer",
+ NULL
+};
+
+static const char* network_cats[] = {
+ "Network",
+ "Dialup",
+ "Email",
+ "WebBrowser",
+ "InstantMessaging",
+ "IRCClient",
+ "FileTransfer",
+ "News",
+ "P2P",
+ "RemoteAccess",
+ "Telephony",
+ NULL
+};
+
+static const char* settings_cats[] = {
+ "Settings",
+ "DesktopSettings",
+ "HardwareSettings",
+ "Accessibility",
+ NULL
+};
+
+static const char* system_cats[] = {
+ "System",
+ "Core",
+ "Security",
+ "PackageManager",
+ NULL
+};
+
+static const char* audiovideo_cats[] ={
+ "AudioVideo",
+ "Audio",
+ "Video",
+ "Mixer",
+ "Sequencer",
+ "Tuner",
+ "TV",
+ "AudioVideoEditing",
+ "Player",
+ "Recorder",
+ "DiscBurning",
+ "Music",
+ NULL
+};
+
+static const char* game_cats[] = {
+ "Game",
+ "Amusement",
+ NULL
+};
+
+static const char* education_cats[] = {
+ "Education",
+ NULL
+};
+
+static const char* utility_cats[] = {
+ "Utility",
+ NULL
+};
+
+static const CatInfo known_cats[]=
+{
+ {N_("Other"), "Other", "gnome-other", NULL},
+ {N_("Game"), "Games", "gnome-joystick", game_cats},
+ {N_("Education"), "Education", "gnome-amusements", education_cats},
+ {N_("Development"), "Development", "gnome-devel", development_cats},
+ {N_("Audio & Video"), "Multimedia", "gnome-multimedia", audiovideo_cats},
+ {N_("Graphics"), "Graphics", "gnome-graphics", graphics_cats},
+ {N_("Settings"), "Settings", "gnome-settings", settings_cats},
+ {N_("System Tools"), "System-Tools", "gnome-system", system_cats},
+ {N_("Network"), "Internet", "gnome-globe", network_cats},
+ {N_("Office"), "Office", "gnome-applications", office_cats},
+ {N_("Accessories"), "Accessories", "gnome-util", utility_cats}
+};
+
+static int find_cat( char** cats )
+{
+ char** cat;
+ for( cat = cats; *cat; ++cat )
+ {
+ int i;
+ /* Skip other */
+ for( i = 1; i < G_N_ELEMENTS(known_cats); ++i )
+ {
+ const char** sub_cats = known_cats[i].sub_cats;
+ while( *sub_cats )
+ {
+ if( 0 == strncmp(*cat, "X-", 2) ) /* Desktop specific*/
+ return -1;
+ if( 0 == strcmp( *sub_cats, *cat ) )
+ return i;
+ ++sub_cats;
+ }
+ }
+ }
+ return -1;
+}
+
+static void app_dirs_foreach( GFunc func, gpointer user_data );
+
+static int compare_menu_item_titles( gpointer a, gpointer b )
+{
+ const gchar *title_a, *title_b;
+ title_a = gtk_label_get_text( GTK_LABEL(gtk_bin_get_child(GTK_BIN(a))) );
+ title_b = gtk_label_get_text( GTK_LABEL(gtk_bin_get_child(GTK_BIN(b))) );
+ return g_ascii_strcasecmp(title_a, title_b);
+}
+
+static int find_menu_item_by_name( gpointer a, gpointer b )
+{
+ PtkAppMenuItem* data = g_object_get_qdata( G_OBJECT(a),
PTK_APP_MENU_ITEM_ID );
+ const char* name = (char*)b;
+ return strcmp(data->name, name);
+}
+
+/* Moved to misc.c of lxpanel to be used in other plugins */
+#if 0
+static char* translate_exec( const char* exec, const char* icon,
+ const char* title, const char* fpath )
+{
+ GString* cmd = g_string_sized_new( 256 );
+ for( ; *exec; ++exec )
+ {
+ if( G_UNLIKELY(*exec == '%') )
+ {
+ ++exec;
+ if( !*exec )
+ break;
+ switch( *exec )
+ {
+ case 'c':
+ g_string_append( cmd, title );
+ break;
+ case 'i':
+ if( icon )
+ {
+ g_string_append( cmd, "--icon " );
+ g_string_append( cmd, icon );
+ }
+ break;
+ case 'k':
+ {
+ char* uri = g_filename_to_uri( fpath, NULL, NULL );
+ g_string_append( cmd, uri );
+ g_free( uri );
+ break;
+ }
+ case '%':
+ g_string_append_c( cmd, '%' );
+ break;
+ }
+ }
+ else
+ g_string_append_c( cmd, *exec );
+ }
+ return g_string_free( cmd, FALSE );
+}
+#endif
+
+static char* load_cat_title( GKeyFile* kf, CatInfo* inf )
+{
+ char* ret = NULL;
+ char* fn = g_strconcat( "desktop-directories/", inf->directory_file,
".directory", NULL );
+ if( g_key_file_load_from_data_dirs( kf, fn, NULL, 0, NULL ) )
+ ret = g_key_file_get_locale_string( kf, desktop_ent, "Name", NULL,
NULL );
+ g_free( fn );
+ return ret;
+}
+
+static void unload_old_icons( GtkWidget* menu )
+{
+ GList* items = gtk_container_get_children( GTK_CONTAINER(menu) );
+ GList* l;
+ for( l = items; l; l = l->next )
+ {
+ GtkWidget* sub_menu = gtk_menu_item_get_submenu(
GTK_MENU_ITEM(l->data) );
+ GtkWidget* img;
+ if( ! GTK_IS_IMAGE_MENU_ITEM(l->data) )
+ continue;
+ img = gtk_image_menu_item_get_image( (GtkImageMenuItem*)l->data );
+ if( ! g_object_get_qdata( G_OBJECT(l->data), PTK_APP_MENU_ITEM_ID ) )
+ continue;
+ if( img )
+ gtk_widget_destroy( img );
+ if( sub_menu )
+ unload_old_icons( sub_menu );
+ }
+ g_list_free( items );
+}
+
+static void on_menu_item_size_request( GtkWidget* item,
+ GtkRequisition* req,
+ gpointer user_data )
+{
+ int min_height = ICON_SIZE + (GTK_CONTAINER(item)->border_width +
+ item->style->ythickness) * 2;
+ if( req->height < min_height ) {
+ req->height = min_height;
+ }
+ if( req->width < ICON_SIZE )
+ req->width = ICON_SIZE;
+}
+
+static gboolean on_menu_item_expose( GtkWidget* item,
+ GdkEventExpose* evt,
+ gpointer user_data )
+{
+ GtkWidget* img;
+ GdkPixbuf* pix;
+ PtkAppMenuItem* data = (PtkAppMenuItem*)user_data;
+ if( !data )
+ return FALSE;
+ if( !GTK_IS_IMAGE_MENU_ITEM(item) )
+ return FALSE;
+ img = GTK_WIDGET(gtk_image_menu_item_get_image((GtkImageMenuItem *) item));
+ if( img )
+ return FALSE;
+ if( G_UNLIKELY(!data) || G_UNLIKELY(!data->icon) )
+ return FALSE;
+ pix = NULL;
+ if( data->icon[0] == '/' )
+ {
+ pix = gdk_pixbuf_new_from_file_at_size(data->icon, ICON_SIZE,
ICON_SIZE, NULL);
+ }
+ else
+ {
+ GtkIconInfo* inf;
+ inf = gtk_icon_theme_lookup_icon(gtk_icon_theme_get_default(),
data->icon, ICON_SIZE, 0);
+ if( inf )
+ {
+ pix = gdk_pixbuf_new_from_file_at_size(
gtk_icon_info_get_filename(inf), ICON_SIZE, ICON_SIZE, NULL);
+ gtk_icon_info_free ( inf );
+ }
+ }
+ if( G_LIKELY(pix) )
+ {
+ img = gtk_image_new_from_pixbuf( pix );
+ if( G_LIKELY(pix) )
+ g_object_unref( pix );
+ }
+ else
+ {
+ img = gtk_image_new();
+ gtk_image_set_pixel_size( GTK_IMAGE(img), ICON_SIZE );
+ }
+ gtk_image_menu_item_set_image( (GtkImageMenuItem *) item, img );
+ return FALSE;
+}
+
+static void on_app_menu_item_activate( GtkMenuItem* item, PtkAppMenuItem* data
)
+{
+ GError* err = NULL;
+ /* FIXME: support startup notification */
+ g_debug("run command: %s", data->exec);
+ if( !g_spawn_command_line_async( data->exec, &err ) )
+ {
+ /* FIXME: show error message */
+ g_error_free( err );
+ }
+}
+
+static void ptk_app_menu_item_free( PtkAppMenuItem* data )
+{
+ g_free( data->name );
+ g_free( data->icon );
+ g_free( data->exec );
+ g_slice_free( PtkAppMenuItem, data );
+}
+
+static char* translate_exec_to_cmd( const char* exec, const char* icon,
+ const char* title, const char* fpath )
+{
+ GString* cmd = g_string_sized_new( 256 );
+ for( ; *exec; ++exec )
+ {
+ if( G_UNLIKELY(*exec == '%') )
+ {
+ ++exec;
+ if( !*exec )
+ break;
+ switch( *exec )
+ {
+ case 'c':
+ g_string_append( cmd, title );
+ break;
+ case 'i':
+ if( icon )
+ {
+ g_string_append( cmd, "--icon " );
+ g_string_append( cmd, icon );
+ }
+ break;
+ case 'k':
+ {
+ char* uri = g_filename_to_uri( fpath, NULL, NULL );
+ g_string_append( cmd, uri );
+ g_free( uri );
+ break;
+ }
+ case '%':
+ g_string_append_c( cmd, '%' );
+ break;
+ }
+ }
+ else
+ g_string_append_c( cmd, *exec );
+ }
+ return g_string_free( cmd, FALSE );
+}
+
+
+static void do_load_dir( int prefix_len,
+ const char* path,
+ GList** sub_menus )
+{
+ GDir* dir = g_dir_open( path, 0, NULL );
+ const char* name;
+ GKeyFile* file;
+
+ if( G_UNLIKELY( ! dir ) )
+ return;
+
+ file = g_key_file_new();
+
+ while( (name = g_dir_read_name( dir )) )
+ {
+ char* fpath;
+ char **cats;
+ char **only_show_in;
+
+ if( name[0] =='.' )
+ continue;
+ fpath = g_build_filename( path, name, NULL );
+ if( g_file_test(fpath, G_FILE_TEST_IS_DIR) )
+ {
+ do_load_dir( prefix_len, fpath, sub_menus );
+ g_free( fpath );
+ continue;
+ }
+ if( ! g_str_has_suffix( name, ".desktop" ) )
+ {
+ g_free( fpath );
+ continue;
+ }
+ if( ! g_key_file_load_from_file( file, fpath, 0, NULL ) )
+ {
+ g_free( fpath );
+ continue;
+ }
+ if( g_key_file_get_boolean( file, desktop_ent, "NoDisplay", NULL ) )
+ {
+ g_free( fpath );
+ continue;
+ }
+ only_show_in = g_key_file_get_string_list( file, desktop_ent,
"OnlyShowIn", NULL, NULL );
+ if( only_show_in )
+ {
+ g_free( fpath );
+ g_strfreev( only_show_in );
+ continue;
+ }
+ cats = g_key_file_get_string_list( file, desktop_ent, "Categories",
NULL, NULL );
+ if( cats )
+ {
+ int i = find_cat( cats );
+ if( i >= 0 )
+ {
+ GtkWidget* menu_item;
+ char *title, *exec, *icon;
+ /* FIXME: processing duplicated items */
+ exec = g_key_file_get_string( file, desktop_ent, "Exec", NULL);
+ if( exec )
+ {
+ title = g_key_file_get_locale_string( file, desktop_ent,
"Name", NULL, NULL);
+ if( title )
+ {
+ PtkAppMenuItem* data;
+ GList* prev;
+ prev =g_list_find_custom( sub_menus[i], (fpath +
prefix_len),
+ (GCompareFunc) find_menu_item_by_name );
+ if( ! prev )
+ {
+ menu_item = gtk_image_menu_item_new_with_label(
title );
+ data = g_slice_new0(PtkAppMenuItem);
+ }
+ else
+ {
+ GtkLabel* label;
+ menu_item = GTK_WIDGET(prev->data);
+ label =
GTK_LABEL(gtk_bin_get_child(GTK_BIN(menu_item)));
+ data = (PtkAppMenuItem*)g_object_get_qdata(
G_OBJECT(menu_item), PTK_APP_MENU_ITEM_ID );
+ gtk_label_set_text( label, title );
+ g_free( data->name );
+ g_free( data->exec );
+ g_free( data->icon );
+ }
+ data->name = g_strdup( fpath + prefix_len );
+ data->exec = exec ? translate_exec_to_cmd( exec,
data->icon, title, fpath ) : NULL;
+ g_free( title );
+ g_signal_connect( menu_item, "expose-event",
+ G_CALLBACK(on_menu_item_expose), data );
+ g_signal_connect( menu_item,
+ "size-request",
+ G_CALLBACK(on_menu_item_size_request), data );
+ icon = g_strdup( g_key_file_get_string( file,
desktop_ent, "Icon", NULL) );
+ if( icon )
+ {
+ char* dot = strchr( icon, '.' );
+ if( icon[0] !='/' && dot )
+ *dot = '\0';
+ }
+ data->icon = icon;
+ if( !prev )
+ {
+ g_signal_connect( menu_item, "activate",
+ G_CALLBACK(on_app_menu_item_activate), data );
+ g_object_set_qdata_full( G_OBJECT(menu_item),
PTK_APP_MENU_ITEM_ID, data,
+ (GDestroyNotify) ptk_app_menu_item_free );
+ sub_menus[i] = g_list_insert_sorted( sub_menus[i],
+ (gpointer) menu_item,
+ (GCompareFunc) compare_menu_item_titles );
+ }
+ } /* if( title ) */
+ g_free( exec );
+ } /* if( exec ) */
+ }
+ g_strfreev(cats);
+ }
+ g_free( fpath );
+ }
+ g_key_file_free( file );
+ g_dir_close( dir );
+}
+
+static void load_dir( const char* path, GList** sub_menus )
+{
+ do_load_dir( strlen( path ) + 1, path, sub_menus );
+}
+
+#if defined( PTK_APP_MENU_DEMO )
+static GtkWidget* app_menu = NULL;
+static void on_menu( GtkWidget* btn, gpointer user_data )
+{
+ if( ptk_app_menu_need_reload() )
+ {
+ if( app_menu )
+ gtk_widget_destroy( app_menu );
+ app_menu = ptk_app_menu_new();
+ }
+ else if( !app_menu )
+ app_menu = ptk_app_menu_new();
+ gtk_menu_popup(GTK_MENU(app_menu), NULL, NULL, NULL, NULL, 0, 0 );
+}
+#endif
+
+static void on_app_menu_destroy( gpointer user_data, GObject* menu )
+{
+ g_signal_handler_disconnect( gtk_icon_theme_get_default(),
+ GPOINTER_TO_INT(user_data) );
+}
+
+gboolean ptk_app_menu_item_has_data( GtkMenuItem* item )
+{
+ return (g_object_get_qdata( G_OBJECT(item), PTK_APP_MENU_ITEM_ID ) != NULL);
+}
+
+/*
+ * Insert application menus into specified menu
+ * menu: The parent menu to which the items should be inserted
+ * pisition: Position to insert items.
+ Passing -1 in this parameter means append all items
+ at the end of menu.
+ */
+void ptk_app_menu_insert_items( GtkMenu* menu, int position )
+{
+ GList* sub_menus[ G_N_ELEMENTS(known_cats) ] = {0};
+ int i;
+ GList *sub_items, *l;
+ guint change_handler;
+ GKeyFile* kf;
+
+ if( G_UNLIKELY( PTK_APP_MENU_ITEM_ID == 0 ) )
+ PTK_APP_MENU_ITEM_ID = g_quark_from_static_string( "PtkAppMenuItem" );
+
+ app_dirs_foreach( (GFunc) load_dir, sub_menus );
+
+ kf = g_key_file_new();
+
+ for( i = 0; i < G_N_ELEMENTS(known_cats); ++i )
+ {
+ GtkMenu* sub_menu;
+ GtkWidget* menu_item;
+ PtkAppMenuItem* data;
+ char* title;
+
+ if( ! (sub_items = sub_menus[i]) )
+ continue;
+ sub_menu = GTK_MENU(gtk_menu_new());
+
+ for( l = sub_items; l; l = l->next )
+ gtk_menu_shell_append( GTK_MENU_SHELL(sub_menu), GTK_WIDGET(l->data)
);
+ g_list_free( sub_items );
+
+ title = load_cat_title( kf, &known_cats[i] );
+ menu_item = gtk_image_menu_item_new_with_label( title ? title :
_(known_cats[i].title) );
+ g_free( title );
+
+ data = g_slice_new0( PtkAppMenuItem );
+ data->icon = g_strdup(known_cats[i].icon);
+ g_object_set_qdata_full( G_OBJECT(menu_item), PTK_APP_MENU_ITEM_ID,
data, (GDestroyNotify) ptk_app_menu_item_free );
+ g_signal_connect( menu_item, "expose-event",
G_CALLBACK(on_menu_item_expose), data );
+ g_signal_connect( menu_item, "size-request",
G_CALLBACK(on_menu_item_size_request), data );
+ on_menu_item_expose( menu_item, NULL, data );
+ gtk_menu_item_set_submenu( GTK_MENU_ITEM(menu_item),
GTK_WIDGET(sub_menu) );
+
+ if( position == -1 )
+ gtk_menu_shell_append( GTK_MENU_SHELL(menu), menu_item );
+ else
+ {
+ gtk_menu_shell_insert( GTK_MENU_SHELL(menu), menu_item, position );
+ ++position;
+ }
+ }
+
+ g_key_file_free( kf );
+
+ gtk_widget_show_all(GTK_WIDGET(menu));
+ change_handler = g_signal_connect_swapped( gtk_icon_theme_get_default(),
"changed", G_CALLBACK(unload_old_icons), menu );
+ g_object_weak_ref( G_OBJECT(menu), on_app_menu_destroy,
GINT_TO_POINTER(change_handler) );
+}
+
+GtkWidget* ptk_app_menu_new()
+{
+ GtkWidget* menu;
+ menu = gtk_menu_new();
+ ptk_app_menu_insert_items( GTK_MENU(menu), -1 );
+ return menu;
+}
+
+static void app_dirs_foreach( GFunc func, gpointer user_data )
+{
+ const char** sys_dirs = (const char**)g_get_system_data_dirs();
+ char* path;
+ int i, len;
+ struct stat dir_stat;
+
+ len = g_strv_length((gchar **) sys_dirs);
+ if( !times )
+ times = g_new0( time_t, len + 2 );
+ for( i = 0; i < len; ++i )
+ {
+ path = g_build_filename( sys_dirs[i], app_dir_name, NULL );
+ if( stat( path, &dir_stat) == 0 )
+ {
+ times[i] = dir_stat.st_mtime;
+ func( path, user_data );
+ }
+ g_free( path );
+ }
+ path = g_build_filename( g_get_user_data_dir(), app_dir_name, NULL );
+ times[i] = dir_stat.st_mtime;
+ if( stat( path, &dir_stat) == 0 )
+ {
+ times[i] = dir_stat.st_mtime;
+ func( path, user_data );
+ }
+ g_free( path );
+}
+
+#if defined( PTK_APP_MENU_DEMO )
+int main( int argc, char** argv )
+{
+ gtk_init(&argc, &argv);
+ GtkWidget* window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+ gtk_window_set_title(GTK_WINDOW( window ), "Show Applications" );
+ GtkWidget* button = gtk_button_new_with_label("Application Menu");
+ g_signal_connect(button, "clicked", G_CALLBACK(on_menu), NULL );
+ gtk_container_add( GTK_CONTAINER(window), button );
+ g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL );
+ gtk_widget_show_all(window);
+ if( app_menu )
+ gtk_widget_destroy( app_menu );
+ gtk_main();
+ return 0;
+}
+#endif
+
+gboolean ptk_app_menu_need_reload( GtkWidget* menu )
+{
+ const char** sys_dirs = (const char**)g_get_system_data_dirs();
+ char* path;
+ int i, len;
+ struct stat dir_stat;
+
+ if( !times )
+ return TRUE;
+ len = g_strv_length((gchar **) sys_dirs);
+ for( i = 0; i < len; ++i )
+ {
+ path = g_build_filename( sys_dirs[i], app_dir_name, NULL );
+ if( stat( path, &dir_stat) == 0 )
+ {
+ if( times[i] != dir_stat.st_mtime )
+ {
+ g_free( path );
+ return TRUE;
+ }
+ }
+ g_free( path );
+ }
+ path = g_build_filename( g_get_user_data_dir(), app_dir_name, NULL );
+ if( stat( path, &dir_stat) == 0 )
+ {
+ if( times[i] != dir_stat.st_mtime )
+ {
+ g_free( path );
+ return TRUE;
+ }
+ }
+ g_free( path );
+ return FALSE;
+}
+
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Antiright-devel] antiright/gtkshell Makefile options.c ptk-app-m...,
Jeffrey Bedard <=