pidgin/purple-plugin-pack
Clone
Summary
Browse
Changes
Graph
closing merged branch
org.guifications.plugins.debian
2017-04-05, Gary Kramlich
a9832e2b7f4a
closing merged branch
/*************************************************************************
* 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
);
}