org.guifications.plugins.buddytools: 80c48775896345bafbd7073503e7fe1c02c256f9

rlaager at guifications.org rlaager at guifications.org
Mon Oct 22 00:20:24 CDT 2007


-----------------------------------------------------------------
Revision: 80c48775896345bafbd7073503e7fe1c02c256f9
Ancestor: c8682a291bffc1cc284247e82a2f14994180dee1
Author: rlaager at guifications.org
Date: 2006-05-16T03:40:04
Branch: org.guifications.plugins.buddytools
Tag: v0.4pre2

Added files:
        gtktimezone.c
Modified files:
        Changelog Makefile README buddytimezone.c

ChangeLog: 

[buddytools @ 12]
Importing Martijn's changes, which resulted in version 0.4pre2:

version 0.4pre2 (9 Apr 2006)
        * Fix compilation issues for Gaim 2 (kleptog)
        * Update Makefile to allow compilation against multiple versions of
          gaim easily. New compiletest target.
        * Integrate custom GTK widget (optional) for timezone selection (kleptog)


-----------------------------------------------------------------
This revision's diffstat output:
 Changelog       |    7 +
 Makefile        |   47 ++++++++--
 README          |   22 +++++
 buddytimezone.c |   37 +++++++-
 gtktimezone.c   |  244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 344 insertions(+), 13 deletions(-)
-------------- next part --------------
============================================================
--- gtktimezone.c	27586df46582c96e2e0f7077f84474c3f49149bb
+++ gtktimezone.c	27586df46582c96e2e0f7077f84474c3f49149bb
@@ -0,0 +1,244 @@
+/*************************************************************************
+ * GTK Timezone widget module
+ * by Martijn van Oosterhout <kleptog at svana.org> (C) April 2006
+ * Licenced under the GNU General Public Licence version 2.
+ *
+ * This module creates the GTK widget used to select timezones. It's here to
+ * clearly seperate the GTK stuff from the plugin itself.
+ *************************************************************************/
+
+#include <gtk/gtk.h>
+#include <string.h>
+#include <ctype.h>
+#include "recurse.h"
+
+#define DISABLED_STRING "<Disabled>"
+#define DEFAULT_STRING "<Default>"
+#define MORE_STRING "More..."
+
+struct nodestate
+{
+    GtkWidget *submenu;
+    gchar *string;
+};
+
+struct state
+{
+    GtkWidget *base;
+    GtkWidget *extra;
+    int currdepth;
+    struct nodestate stack[4];
+};
+
+static inline const char *
+menuitem_get_label(GtkMenuItem * menuitem)
+{
+    return gtk_label_get_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(menuitem))));
+}
+
+static GtkMenuItem *
+menu_get_first_menuitem(GtkWidget * menu)
+{
+    GList *list = gtk_container_get_children(GTK_CONTAINER(menu));
+    GtkMenuItem *selection = GTK_MENU_ITEM(g_list_nth_data(list, 0));
+    g_list_free(list);
+    return selection;
+}
+
+static int
+menu_select_cb(GtkMenuItem * menuitem, GtkWidget * menu)
+{
+    const char *label = menuitem_get_label( menuitem );
+
+//      printf( "menuitem = %s(%p), menu = %s(%p)\n", G_OBJECT_TYPE_NAME(menuitem), menuitem, G_OBJECT_TYPE_NAME(menu), menu );
+
+    if(label[0] == '<')
+    {
+        GtkWidget *selection;
+        gchar *selstring;
+
+        if(strcmp(label, DEFAULT_STRING) == 0)
+            selstring = "";
+        else if(strcmp(label, DISABLED_STRING) == 0)
+            selstring = "none";
+
+        selection = GTK_WIDGET(menu_get_first_menuitem(menu));
+        gtk_widget_hide(selection);
+    }
+    else
+    {
+        char *str = g_strdup(label);
+
+        GtkWidget *parent;
+
+        for (;;)
+        {
+            GtkMenuItem *parentitem;
+            const char *label2;
+            char *temp;
+
+            parent = gtk_widget_get_parent(GTK_WIDGET(menuitem));
+//                      printf( "parent = %s(%p)\n", G_OBJECT_TYPE_NAME(parent), parent);
+            if(menu == parent)
+                break;
+
+            parentitem = GTK_MENU_ITEM(gtk_menu_get_attach_widget(GTK_MENU(parent)));
+//                      printf( "parentitem = %s(%p)\n", G_OBJECT_TYPE_NAME(parentitem), parentitem);
+            label2 = menuitem_get_label(parentitem);
+            if(strcmp(label2, MORE_STRING) != 0)
+            {
+                temp = g_strconcat(label2, "/", str, NULL);
+                g_free(str);
+                str = temp;
+            }
+
+            menuitem = parentitem;
+        }
+        {
+            GtkLabel *label;
+
+            GtkMenuItem *selection = menu_get_first_menuitem(menu);
+            GtkOptionMenu *optionmenu = GTK_OPTION_MENU(gtk_menu_get_attach_widget(GTK_MENU(menu)));
+
+            label = GTK_LABEL(gtk_bin_get_child(GTK_BIN(selection)));
+
+            gtk_label_set_text(label, str);
+            gtk_widget_show(GTK_WIDGET(selection));
+            gtk_option_menu_set_history(optionmenu, 0);
+            
+            printf("optionmenu=%p, menu=%p, menuitem=%p, label=%p\n", optionmenu, menu, selection, label );
+            g_free(str);
+        }
+    }
+    return 0;
+}
+
+static int
+make_menu_cb(char *path, struct state *state)
+{
+    int i, j;
+
+    char **elements;
+
+    /* Here we ignore strings not beginning with uppercase, since they are auxilliary files, not timezones */
+    if(!isupper(path[0]))
+        return 0;
+
+    elements = g_strsplit(path, "/", 4);
+
+    for (i = 0; i < state->currdepth && state->stack[i].string; i++)
+    {
+        if(strcmp(elements[i], state->stack[i].string) != 0)
+            break;
+    }
+    /* i is now the index of the first non-matching element, so free the rest */
+    for (j = i; j < state->currdepth; j++)
+        g_free(state->stack[j].string);
+    state->currdepth = i;
+
+    while (elements[i])
+    {
+        GtkWidget *parent = (i == 0) ? state->base : state->stack[i - 1].submenu;
+        GtkWidget *menuitem;
+
+        if(i == 0 && elements[1] == NULL)
+            parent = state->extra;
+
+        menuitem = gtk_menu_item_new_with_label(elements[i]);
+        gtk_menu_append(parent, menuitem);
+
+        if(elements[i + 1] != NULL)     /* Has submenu */
+        {
+            state->stack[i].submenu = gtk_menu_new();
+            gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), state->stack[i].submenu);
+
+            state->currdepth++;
+            state->stack[i].string = g_strdup(elements[i]);
+        }
+        else
+            g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menu_select_cb),
+                             state->base);
+
+        i++;
+    }
+    g_strfreev(elements);
+    return 0;
+}
+
+void *
+make_timezone_menu(const char *selected)
+{
+    int i;
+    struct state state;
+
+    GtkWidget *menu;
+    GtkWidget *optionmenu, *menuitem, *selection;
+
+    if( selected == NULL )
+        selected = "";
+        
+    menu = gtk_menu_new();
+    menuitem = gtk_menu_item_new_with_label(selected);
+    gtk_menu_append(menu, menuitem);
+    selection = menuitem;
+
+    menuitem = gtk_menu_item_new_with_label(DISABLED_STRING);
+    g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menu_select_cb), menu);
+    gtk_menu_append(menu, menuitem);
+    menuitem = gtk_menu_item_new_with_label(DEFAULT_STRING);
+    g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(menu_select_cb), menu);
+    gtk_menu_append(menu, menuitem);
+    menuitem = gtk_menu_item_new_with_label(MORE_STRING);
+    gtk_menu_append(menu, menuitem);
+
+    state.base = menu;
+    state.extra = gtk_menu_new();
+    gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), state.extra);
+
+    state.currdepth = 0;
+
+    recurse_directory("/usr/share/zoneinfo", (DirRecurseMatch)make_menu_cb, &state);
+
+    for (i = 0; i < state.currdepth; i++)
+        g_free(state.stack[i].string);
+
+    optionmenu = gtk_option_menu_new();
+    gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu);
+    gtk_widget_show_all(optionmenu);
+
+    if(strcmp(selected, "") == 0)
+    {
+        gtk_option_menu_set_history(GTK_OPTION_MENU(optionmenu), 2);
+        gtk_widget_hide(selection);
+    }
+    else if(strcmp(selected, "none") == 0)
+    {
+        gtk_option_menu_set_history(GTK_OPTION_MENU(optionmenu), 1);
+        gtk_widget_hide(selection);
+    }
+    else
+    {
+        gtk_option_menu_set_history(GTK_OPTION_MENU(optionmenu), 0);
+    }
+
+    return optionmenu;
+}
+
+const char *
+get_timezone_menu_selection( void *widget )
+{
+    GtkOptionMenu *menu = GTK_OPTION_MENU(widget);
+    
+    int sel = gtk_option_menu_get_history( menu );
+    if( sel == 2 )  /* Default */
+    	return NULL;
+    if( sel == 1 )  /* Disabled */
+    	return "none";
+
+//    GtkMenu *m = GTK_MENU( gtk_option_menu_get_menu(menu) );
+//    GtkMenuItem *mi = GTK_MENU_ITEM( gtk_menu_get_active( m ));
+    GtkLabel *l = GTK_LABEL(gtk_bin_get_child(GTK_BIN(menu)));
+//    printf("optionmenu=%p, menu=%p, menuitem=%p, label=%p\n", menu, m, mi, l );
+    return gtk_label_get_text(l);
+//    return ;
+}
============================================================
--- Changelog	97674e88933a96a6878a1b24cc30f2501bda70f6
+++ Changelog	c48ca2e2da6790f777b3eb31f18ce6a4829b9798
@@ -1,6 +1,13 @@
+version 0.4pre2 (9 Apr 2006)
+	* Fix compilation issues for Gaim 2 (kleptog)
+	* Update Makefile to allow compilation against multiple versions of
+	  gaim easily. New compiletest target.
+	* Integrate custom GTK widget (optional) for timezone selection (kleptog)
+
 version 0.4pre1 (7 Apr 2006)
 	* Various cleanups (rlaager)
 	* Fix so time only displays when different from system time
+	* Display time difference as well as time.
 	* Attach copyright notices and clarify GPLv2+
 	* Makefile cleanups (rlaager)
 
============================================================
--- Makefile	6e1ab8409dd1b663c367ead01e59972bce43ea8b
+++ Makefile	468ad88ebb98d73a89836d27b1144a8370af6d30
@@ -1,15 +1,27 @@
 #*************************************************************************
 #* Buddy Edit Makefile
 #* by Martijn van Oosterhout <kleptog at svana.org> (C) April 2006
 #* Licenced under the GNU General Public Licence version 2.
 #*************************************************************************/
 
-VERSION=0.4pre1
-# yes or no
+VERSION=0.4pre2
+
+# Use internal timezone library rather than system one: yes or no
 PRIVATE_TZLIB ?= yes
 
-CFLAGS=-O2 -g -Wall `pkg-config --cflags glib-2.0 gaim` -DPLUGIN_VERSION=$(VERSION)
-LDFLAGS=`pkg-config --libs glib-2.0 gaim`
+# Use Custom GTK widget for timezone selection: yes or no
+CUSTOM_GTK ?= yes
+
+# For choosing which version to compile against
+# This is name of the pkgconfig file to use
+
+GAIM_NAME ?= gaim
+
+# Where to install the modules
+INSTALL_PATH=$(HOME)/.$(GAIM_NAME)/plugins/
+
+CFLAGS=-O2 -g -Wall `pkg-config --cflags glib-2.0 $(GAIM_NAME)` -DPLUGIN_VERSION=$(VERSION)
+LDFLAGS=`pkg-config --libs glib-2.0 $(GAIM_NAME)`
 CC=gcc
 
 ifeq ($(PRIVATE_TZLIB),yes)
@@ -17,6 +29,11 @@ endif
 PRIVATE_TZLIB_OBJS=localtime.o
 endif
 
+ifeq ($(CUSTOM_GTK),yes)
+CFLAGS += -DCUSTOM_GTK
+PRIVATE_TZLIB_OBJS += gtktimezone.o
+endif
+
 LIB_TARGETS=buddyedit.so buddytimezone.so buddynotes.so buddylang.so
 EXE_TARGETS=timetest recursetest gtktimezonetest
 
@@ -29,6 +46,9 @@ gtktimezonetest.o: gtktimezonetest.c
 gtktimezonetest.o: gtktimezonetest.c
 	$(CC) -c $(CFLAGS) `pkg-config --cflags gtk+-2.0` -o $@ $<
 
+gtktimezone.o: gtktimezone.c
+	$(CC) -c $(CFLAGS) `pkg-config --cflags gtk+-2.0` -o $@ $<
+
 gtktimezonetest: gtktimezonetest.o recurse.o
 	$(CC) $(LDFLAGS) -lgtk-x11-2.0 -lgdk-x11-2.0 -o $@ $^
 
@@ -50,14 +70,23 @@ install: all
 	rm -f *.o $(LIB_TARGETS) $(EXE_TARGETS)
 
 install: all
-	install -m 755 -d $(HOME)/.gaim/plugins
-	install -m 644 buddytimezone.so $(HOME)/.gaim/plugins/
-	install -m 644 buddyedit.so $(HOME)/.gaim/plugins/
-	install -m 644 buddynotes.so $(HOME)/.gaim/plugins/
-	install -m 644 buddylang.so $(HOME)/.gaim/plugins/
+	install -m 755 -d $(INSTALL_PATH)
+	install -m 644 buddytimezone.so $(INSTALL_PATH)
+	install -m 644 buddyedit.so $(INSTALL_PATH)
+	install -m 644 buddynotes.so $(INSTALL_PATH)
+	install -m 644 buddylang.so $(INSTALL_PATH)
 
 bundle:
 	ln -s . buddyedit-$(VERSION)
 	tar cvzf ../buddyedit-$(VERSION).tar.gz buddyedit-$(VERSION)/{*.c,*.h,Makefile,README,COPYING,Changelog}
 	rm buddyedit-$(VERSION)
 
+# Tests that all the different combinations compile. Probably only
+# meaningful on my computer where 'gaim' = Gaim1.5 and 'gaim2' = Gaim2.0
+# - Martijn
+compiletest:
+	for i in gaim gaim2 ; do for j in yes no ; do for k in yes no ; do \
+		if [ $$i = gaim -a $$j = yes ] ; then continue ; fi ; \
+		make clean ; \
+		make all GAIM_NAME=$$i CUSTOM_GTK=$$j PRIVATE_TZLIB=$$k ; \
+	done ; done ; done
============================================================
--- README	5f7a0ea8b41fc9bf1ce90821b144f1d529b49673
+++ README	da7dcf138897cac16d829894fd172061330ebfb1
@@ -40,6 +40,8 @@
  * world.
  *************************************************************************
 
+COMPILATION:
+
 To build them, just unpack this package and run "make && make install". You
 will need the gaim header files, which for major distributions are shipped
 in the gaim-dev package. For the spelling control module you will also need
@@ -47,3 +49,23 @@
 
 This will install the module in ~/.gaim/plugins and they will be available
 next time you start Gaim.
+
+There are three options you can control in the compilation phase:
+
+- PRIVATE_TZLIB=yes/no
+
+If yes, a priviate timezone library will be used which is more efficient and
+cleaner in implementation, but does duplicate some system functionality.
+
+- CUSTOM_GTK=yes/no
+
+If yes, the timezone plugin will include a custom GTK widget for timezone
+selection. While this widget is easier to use, it does make the plugin
+depend on gtk. If you select no it will only use standard Gaim components.
+Note, the custom GTK widget only works with Gaim2.
+
+- GAIM_NAME=gaim
+
+If you have multiple versions of Gaim installed you can use this variable to
+select which version to compile against. It should correspond to the name
+used in the .pc file. It also changes the install directory.
============================================================
--- buddytimezone.c	c7997b8b417d2b63aa1be225c61c441f8e07468e
+++ buddytimezone.c	3fd1166f48e589108105f656004deb1bf7a78efa
@@ -26,7 +26,13 @@
  *************************************************************************/
 
 #define GAIM_PLUGINS
+
+#ifdef CUSTOM_GTK
+#define PLUGIN "gtk-kleptog-buddytimezone"
+#else
 #define PLUGIN "core-kleptog-buddytimezone"
+#endif
+
 #define SETTING_NAME "timezone"
 #define CONTROL_NAME PLUGIN "-" SETTING_NAME
 
@@ -50,6 +56,11 @@ void *gaim_gtk_blist_get_handle();
 
 void *gaim_gtk_blist_get_handle();
 
+#if defined(CUSTOM_GTK) && (GAIM_MAJOR_VERSION < 2)
+//#error Custom GTK Widget only works in Gaim 2
+#undef CUSTOM_GTK
+#endif
+
 //#include "gtkblist.h"   /* gaim_gtk_blist_get_handle */  Requires gtk-dev
 
 #define TIMEZONE_FLAG  ((void*)1)
@@ -60,6 +71,8 @@ static GaimPlugin *plugin_self;
 //#define TIME_FORMAT  "%H:%M"
 
 static GaimPlugin *plugin_self;
+void *make_timezone_menu(const char *selected);
+const char *get_timezone_menu_selection( void *widget );
 
 /* Resolve specifies what the return value should mean:
  *
@@ -270,7 +283,7 @@ buddytimezone_tooltip_cb(GaimBlistNode *
     else if( ret == 0 )
     {
 #if GAIM_MAJOR_VERSION > 1
-        char *timetext = gaim_date_format_short(tm);
+        const char *timetext = gaim_time_format(&tm);
 #else
         char timetext[64];
         strftime(timetext, sizeof(timetext), TIME_FORMAT, &tm);
@@ -290,8 +303,6 @@ buddytimezone_submitfields_cb(GaimReques
 {
     GaimBlistNode *node;
     GaimRequestField *list;
-    const GList *sellist;
-    void *seldata = NULL;
 
     /* timezone stuff */
     gaim_debug(GAIM_DEBUG_INFO, PLUGIN, "buddytimezone_submitfields_cb(%p,%p)\n", fields, data);
@@ -314,6 +325,15 @@ buddytimezone_submitfields_cb(GaimReques
     }
 
     list = gaim_request_fields_get_field(fields, CONTROL_NAME);
+#ifdef CUSTOM_GTK
+    const char *seldata = get_timezone_menu_selection( list->ui_data );
+    if( seldata == NULL )
+        gaim_blist_node_remove_setting(node, SETTING_NAME);
+    else
+        gaim_blist_node_set_string(node, SETTING_NAME, seldata);
+#else
+    const GList *sellist;
+    void *seldata = NULL;
     sellist = gaim_request_field_list_get_selected(list);
     if(sellist)
         seldata = gaim_request_field_list_get_data(list, sellist->data);
@@ -325,8 +345,10 @@ buddytimezone_submitfields_cb(GaimReques
         gaim_blist_node_set_string(node, SETTING_NAME, "none");
     else
         gaim_blist_node_remove_setting(node, SETTING_NAME);
+#endif
 }
 
+#ifndef CUSTOM_GTK
 static int
 buddy_add_timezone_cb(char *filename, void *data)
 {
@@ -335,6 +357,7 @@ buddy_add_timezone_cb(char *filename, vo
         gaim_request_field_list_add(field, filename, TIMEZONE_FLAG);
     return 0;
 }
+#endif
 
 static void
 buddytimezone_createfields_cb(GaimRequestFields * fields, GaimBlistNode * data)
@@ -364,6 +387,12 @@ buddytimezone_createfields_cb(GaimReques
     group = gaim_request_field_group_new(NULL);
     gaim_request_fields_add_group(fields, group);
 
+    timezone = buddy_get_timezone(data, FALSE);
+
+#ifdef CUSTOM_GTK
+    field = gaim_request_field_new( CONTROL_NAME, "Timezone", GAIM_REQUEST_FIELD_LIST );
+    field->ui_data = make_timezone_menu(timezone);
+#else
     field =
         gaim_request_field_list_new(CONTROL_NAME,
                                     is_default ? "Default timezone for group" :
@@ -374,7 +403,6 @@ buddytimezone_createfields_cb(GaimReques
 
     recurse_directory("/usr/share/zoneinfo/", buddy_add_timezone_cb, field);
 
-    timezone = buddy_get_timezone(data, FALSE);
     if(timezone)
     {
         if(strcmp(timezone, "none") == 0)
@@ -384,6 +412,7 @@ buddytimezone_createfields_cb(GaimReques
     }
     else
         gaim_request_field_list_add_selected(field, "<Default>");
+#endif
 
     gaim_request_field_group_add_field(group, field);
 }


More information about the Plugins-commits mailing list