pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
This took WAY too long to see. The logs shouldn't be sorted while we're
org.guifications.plugins
2008-08-03, rekkanoryo
f8496a6121df
This took WAY too long to see. The logs shouldn't be sorted while we're
still in the outer loop. Sort at the end once we've collected all the logs
we can.
/*************************************************************************
* GTK Timezone widget module
* by Martijn van Oosterhout <kleptog@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
);
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
));
if
(
menu
==
parent
)
break
;
parentitem
=
GTK_MENU_ITEM
(
gtk_menu_get_attach_widget
(
GTK_MENU
(
parent
)));
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"
;
GtkLabel
*
l
=
GTK_LABEL
(
gtk_bin_get_child
(
GTK_BIN
(
menu
)));
return
gtk_label_get_text
(
l
);
}