1
/* Copyright (c) 2009 Mark Trompell <mark@foresightlinux.org>
3
* This program is free software; you can redistribute it and/or modify
4
* it under the terms of the GNU General Public License as published by
5
* the Free Software Foundation; either version 2 of the License, or
6
* (at your option) any later version.
8
* This program is distributed in the hope that it will be useful,
9
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
* GNU Library General Public License for more details.
13
* You should have received a copy of the GNU General Public License
14
* along with this program; if not, write to the Free Software
15
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26
#include <libxfce4util/libxfce4util.h>
27
#include <libxfce4panel/xfce-panel-plugin.h>
28
#include <libxfce4panel/xfce-hvbox.h>
29
#include <libindicator/indicator-object.h>
31
#include "indicator.h"
35
indicator_construct (XfcePanelPlugin *plugin);
38
load_module (const gchar * name, IndicatorPlugin * indicator);
40
/* register the plugin */
41
XFCE_PANEL_PLUGIN_REGISTER_EXTERNAL (indicator_construct);
44
static IndicatorPlugin *
45
indicator_new (XfcePanelPlugin *plugin)
47
IndicatorPlugin *indicator;
48
GtkOrientation orientation;
49
gint indicators_loaded = 0;
51
/* allocate memory for the plugin structure */
52
indicator = panel_slice_new0 (IndicatorPlugin);
54
/* pointer to plugin */
55
indicator->plugin = plugin;
57
/* get the current orientation */
58
orientation = xfce_panel_plugin_get_orientation (plugin);
60
/* Init some theme/icon stuff */
61
gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
63
gtk_widget_set_name(GTK_WIDGET (indicator), "indicator-plugin");
65
indicator->buttonbox = gtk_hbox_new(FALSE,0);
66
gtk_widget_set_can_focus(GTK_WIDGET(indicator->buttonbox), TRUE);
68
"style \"indicator-plugin-style\"\n"
70
" GtkButton::internal-border= 0\n"
71
" GtkWidget::focus-line-width = 0\n"
72
" GtkWidget::focus-padding = 0\n"
74
"widget \"*.indicator-button\" style \"indicator-plugin-style\"");
76
gtk_widget_set_name(GTK_WIDGET (indicator->buttonbox), "indicator-button");
77
gtk_container_set_border_width(GTK_CONTAINER(indicator->buttonbox), 0);
80
if (g_file_test(INDICATOR_DIR, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) {
81
GDir * dir = g_dir_open(INDICATOR_DIR, 0, NULL);
84
while ((name = g_dir_read_name(dir)) != NULL) {
85
if (load_module(name, indicator))
91
if (indicators_loaded == 0) {
92
/* A label to allow for click through */
93
indicator->item = xfce_create_panel_button();
94
gtk_button_set_label(GTK_BUTTON(indicator->item), _("No Indicators"));
95
gtk_container_add (GTK_CONTAINER (plugin), indicator->item);
96
gtk_widget_show(indicator->item);
98
indicator->ebox = gtk_event_box_new();
99
gtk_widget_set_can_focus(GTK_WIDGET(indicator->ebox), TRUE);
100
gtk_container_add (GTK_CONTAINER (indicator->ebox), GTK_WIDGET(indicator->buttonbox));
101
gtk_container_add (GTK_CONTAINER (plugin), GTK_WIDGET(indicator->ebox));
102
gtk_widget_show(GTK_WIDGET(indicator->buttonbox));
103
gtk_widget_show(GTK_WIDGET(indicator->ebox));
111
indicator_free (XfcePanelPlugin *plugin,
112
IndicatorPlugin *indicator)
116
/* check if the dialog is still open. if so, destroy it */
117
dialog = g_object_get_data (G_OBJECT (plugin), "dialog");
118
if (G_UNLIKELY (dialog != NULL))
119
gtk_widget_destroy (dialog);
121
/* free the plugin structure */
122
panel_slice_free (IndicatorPlugin, indicator);
128
indicator_orientation_changed (XfcePanelPlugin *plugin,
129
GtkOrientation orientation,
130
IndicatorPlugin *indicator)
132
gint sizex=-1, sizey=-1;
133
gtk_orientable_set_orientation (GTK_ORIENTABLE(indicator->buttonbox), orientation);
134
gtk_widget_get_size_request (GTK_WIDGET (plugin), &sizex, &sizey);
135
gtk_widget_set_size_request (GTK_WIDGET (plugin), sizey, sizex);
141
indicator_size_changed (XfcePanelPlugin *plugin,
143
IndicatorPlugin *indicator)
145
GtkOrientation orientation;
147
/* get the orientation of the plugin */
148
orientation = xfce_panel_plugin_get_orientation (plugin);
150
/* set the widget size */
151
if (orientation == GTK_ORIENTATION_HORIZONTAL)
152
gtk_widget_set_size_request (GTK_WIDGET (plugin), -1, size);
154
gtk_widget_set_size_request (GTK_WIDGET (plugin), size, -1);
160
on_button_press (GtkWidget *widget, GdkEventButton *event, IndicatorPlugin *indicator)
162
if (indicator != NULL)
164
if( event->button == 1) /* left click only */
166
GtkMenu * menu = GTK_MENU(g_object_get_data (G_OBJECT(widget),"menu"));
167
gtk_menu_attach_to_widget(menu, widget, NULL);
168
gtk_menu_popup (menu, NULL, NULL,
169
xfce_panel_plugin_position_menu,
170
indicator->plugin, 1, gtk_get_current_event_time ());
174
/* event doesn't make it to the ebox, so I just push it. */
175
gtk_widget_event (indicator->ebox, (GdkEvent*)event);
181
indicator_construct (XfcePanelPlugin *plugin)
183
IndicatorPlugin *indicator;
185
/* setup transation domain */
186
xfce_textdomain(GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
188
/* create the plugin */
189
indicator = indicator_new (plugin);
191
/* show the panel's right-click menu on this menu */
192
xfce_panel_plugin_add_action_widget (plugin, indicator->ebox);
193
xfce_panel_plugin_add_action_widget (plugin, indicator->item);
195
/* connect plugin signals */
196
g_signal_connect (G_OBJECT (plugin), "free-data",
197
G_CALLBACK (indicator_free), indicator);
199
g_signal_connect (G_OBJECT (plugin), "size-changed",
200
G_CALLBACK (indicator_size_changed), indicator);
202
g_signal_connect (G_OBJECT (plugin), "orientation-changed",
203
G_CALLBACK (indicator_orientation_changed), indicator);
208
entry_scrolled (GtkWidget *menuitem, GdkEventScroll *event, gpointer data)
210
IndicatorObject *io = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-object-data");
211
IndicatorObjectEntry *entry = g_object_get_data (G_OBJECT (menuitem), "indicator-custom-entry-data");
213
g_return_val_if_fail(INDICATOR_IS_OBJECT(io), FALSE);
215
g_signal_emit_by_name (io, "scroll", 1, event->direction);
216
g_signal_emit_by_name (io, "scroll-entry", entry, 1, event->direction);
223
entry_added (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data)
225
GtkWidget * button = gtk_button_new();
226
gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
227
gtk_button_set_use_underline(GTK_BUTTON (button),TRUE);
228
gtk_widget_set_name(GTK_WIDGET (button), "indicator-button");
230
if (entry->image != NULL)
231
gtk_button_set_image(GTK_BUTTON(button), GTK_WIDGET(entry->image));
233
if (entry->label != NULL)
234
gtk_button_set_label(GTK_BUTTON(button), gtk_label_get_label (entry->label));
236
if (entry->menu != NULL)
237
g_object_set_data(G_OBJECT(button), "menu", entry->menu);
239
g_signal_connect(button, "button-press-event", G_CALLBACK(on_button_press),
241
gtk_box_pack_start(GTK_BOX(((IndicatorPlugin *)user_data)->buttonbox), button, TRUE, TRUE, 0);
242
gtk_widget_show(button);
243
g_object_set_data(G_OBJECT(button), "indicator-custom-object-data", io);
244
g_object_set_data(G_OBJECT(button), "indicator-custom-entry-data", entry);
249
entry_removed_cb (GtkWidget * widget, gpointer userdata)
251
gpointer data = g_object_get_data(G_OBJECT(widget), "indicator-custom-entry-data");
253
if (data != userdata)
256
gtk_widget_destroy(widget);
261
entry_removed (IndicatorObject * io, IndicatorObjectEntry * entry, gpointer user_data)
263
gtk_container_foreach(GTK_CONTAINER(user_data), entry_removed_cb, entry);
268
load_module (const gchar * name, IndicatorPlugin * indicator)
270
g_debug("Looking at Module: %s", name);
271
g_return_val_if_fail(name != NULL, FALSE);
273
if (!g_str_has_suffix(name,G_MODULE_SUFFIX))
276
g_debug("Loading Module: %s", name);
278
gchar * fullpath = g_build_filename(INDICATOR_DIR, name, NULL);
279
IndicatorObject * io = indicator_object_new_from_file(fullpath);
282
g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
283
G_CALLBACK(entry_added), indicator);
284
g_signal_connect(G_OBJECT(io), INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
285
G_CALLBACK(entry_removed), indicator->buttonbox);
287
GList * entries = indicator_object_get_entries(io);
288
GList * entry = NULL;
290
for (entry = entries; entry != NULL; entry = g_list_next(entry)) {
291
IndicatorObjectEntry * entrydata = (IndicatorObjectEntry *)entry->data;
292
entry_added(io, entrydata, indicator);
295
g_list_free(entries);