2
Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
4
This library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Lesser General Public
6
License as published by the Free Software Foundation; either
7
version 2.1 of the License, or (at your option) any later version.
9
See the file COPYING for the full license text.
20
#include <gdk/gdkkeysyms.h>
22
void sokoke_combo_box_add_strings(GtkComboBox* combobox
23
, const gchar* sLabelFirst, ...)
25
// Add a number of strings to a combobox, terminated with NULL
26
// This works only for text comboboxes
28
va_start(args, sLabelFirst);
31
for(sLabel = sLabelFirst; sLabel; sLabel = va_arg(args, const gchar*))
32
gtk_combo_box_append_text(combobox, sLabel);
37
void sokoke_radio_action_set_current_value(GtkRadioAction* action
40
// Activates the group member with the given value
41
#if GTK_CHECK_VERSION(2, 10, 0)
42
gtk_radio_action_set_current_value(action, current_value);
44
// TODO: Implement this for older gtk
49
void sokoke_widget_set_visible(GtkWidget* widget, gboolean bVisibility)
51
// Show or hide the widget
53
gtk_widget_show(widget);
55
gtk_widget_hide(widget);
58
void sokoke_container_show_children(GtkContainer* container)
60
// Show every child but not the container itself
61
gtk_container_foreach(container, (GtkCallback)(gtk_widget_show_all), NULL);
64
void sokoke_widget_set_tooltip_text(GtkWidget* widget, const gchar* sText)
66
#if GTK_CHECK_VERSION(2, 12, 0)
67
gtk_widget_set_tooltip_text(widget, sText);
69
static GtkTooltips* tooltips;
71
tooltips = gtk_tooltips_new();
72
gtk_tooltips_set_tip(tooltips, widget, sText, NULL);
76
void sokoke_tool_item_set_tooltip_text(GtkToolItem* toolitem, const gchar* sText)
78
// TODO: Use 2.12 api if available
79
GtkTooltips* tooltips = gtk_tooltips_new();
80
gtk_tool_item_set_tooltip(toolitem, tooltips, sText, NULL);
83
void sokoke_widget_popup(GtkWidget* widget, GtkMenu* menu
84
, GdkEventButton* event)
86
// TODO: Provide a GtkMenuPositionFunc in case a keyboard invoked this
87
int button, event_time;
90
button = event->button;
91
event_time = event->time;
96
event_time = gtk_get_current_event_time();
99
if(!gtk_menu_get_attach_widget(menu))
100
gtk_menu_attach_to_widget(menu, widget, NULL);
101
gtk_menu_popup(menu, NULL, NULL, NULL, NULL, button, event_time);
106
SOKOKE_DESKTOP_UNKNOWN,
110
static guint sokoke_get_desktop(void)
112
// Are we running in Xfce?
113
gint iResult; gchar* stdout; gchar* stderr;
114
gboolean bSuccess = g_spawn_command_line_sync(
115
"xprop -root _DT_SAVE_MODE | grep -q xfce4"
116
, &stdout, &stderr, &iResult, NULL);
117
if(bSuccess && !iResult)
118
return SOKOKE_DESKTOP_XFCE;
120
return SOKOKE_DESKTOP_UNKNOWN;
123
gpointer sokoke_xfce_header_new(const gchar* sIcon, const gchar* sTitle)
126
// Create an xfce header with icon and title
127
// This returns NULL if the desktop is not xfce
128
if(sokoke_get_desktop() == SOKOKE_DESKTOP_XFCE)
130
GtkWidget* entry = gtk_entry_new();
132
GtkWidget* xfce_heading = gtk_event_box_new();
133
gtk_widget_modify_bg(xfce_heading, GTK_STATE_NORMAL
134
, &entry->style->base[GTK_STATE_NORMAL]);
135
GtkWidget* hbox = gtk_hbox_new(FALSE, 12);
136
gtk_container_set_border_width(GTK_CONTAINER(hbox), 6);
137
GtkWidget* icon = gtk_image_new_from_icon_name(sIcon, GTK_ICON_SIZE_DIALOG);
138
gtk_box_pack_start(GTK_BOX(hbox), icon, FALSE, FALSE, 0);
139
GtkWidget* label = gtk_label_new(NULL);
140
gtk_widget_modify_fg(label, GTK_STATE_NORMAL
141
, &entry->style->text[GTK_STATE_NORMAL]);
142
sMarkup = g_strdup_printf("<span size='large' weight='bold'>%s</span>", sTitle);
143
gtk_label_set_markup(GTK_LABEL(label), sMarkup);
144
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
145
gtk_container_add(GTK_CONTAINER(xfce_heading), hbox);
152
gpointer sokoke_superuser_warning_new(void)
154
// Create a horizontal bar with a security warning
155
// This returns NULL if the user is no superuser
157
if(G_UNLIKELY(!geteuid())) // effective superuser?
159
GtkWidget* hbox = gtk_event_box_new();
160
gtk_widget_modify_bg(hbox, GTK_STATE_NORMAL
161
, &hbox->style->bg[GTK_STATE_SELECTED]);
162
GtkWidget* label = gtk_label_new("Warning: You are using the superuser account!");
163
gtk_misc_set_padding(GTK_MISC(label), 0, 2);
164
gtk_widget_modify_fg(GTK_WIDGET(label), GTK_STATE_NORMAL
165
, >K_WIDGET(label)->style->fg[GTK_STATE_SELECTED]);
166
gtk_container_add(GTK_CONTAINER(hbox), GTK_WIDGET(label));
173
GtkWidget* sokoke_hig_frame_new(const gchar* sLabel)
175
// Create a frame with no actual frame but a bold label and indentation
176
GtkWidget* frame = gtk_frame_new(NULL);
177
gchar* sLabelBold = g_strdup_printf("<b>%s</b>", sLabel);
178
GtkWidget* label = gtk_label_new(NULL);
179
gtk_label_set_markup(GTK_LABEL(label), sLabelBold);
181
gtk_frame_set_label_widget(GTK_FRAME(frame), label);
182
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);
186
void sokoke_widget_set_pango_font_style(GtkWidget* widget, PangoStyle style)
188
// Conveniently change the pango font style
189
// For some reason we need to reset if we actually want the normal style
190
if(style == PANGO_STYLE_NORMAL)
191
gtk_widget_modify_font(widget, NULL);
194
PangoFontDescription* pangofontdesc = pango_font_description_new();
195
pango_font_description_set_style(pangofontdesc, PANGO_STYLE_ITALIC);
196
gtk_widget_modify_font(widget, pangofontdesc);
197
pango_font_description_free(pangofontdesc);
201
static gboolean sokoke_on_entry_focus_in_event(GtkEntry* entry, GdkEventFocus *event
204
gboolean bDefaultText = (gboolean)g_object_get_data(G_OBJECT(entry)
205
, "sokoke_bDefaultText");
208
gtk_entry_set_text(entry, "");
209
g_object_set_data(G_OBJECT(entry), "sokoke_bDefaultText", (gpointer)FALSE);
210
sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_NORMAL);
215
static gboolean sokoke_on_entry_focus_out_event(GtkEntry* entry, GdkEventFocus* event
218
const gchar* sText = gtk_entry_get_text(entry);
221
const gchar* sDefaultText = (const gchar*)g_object_get_data(
222
G_OBJECT(entry), "sokoke_sDefaultText");
223
gtk_entry_set_text(entry, sDefaultText);
224
g_object_set_data(G_OBJECT(entry), "sokoke_bDefaultText", (gpointer)TRUE);
225
sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_ITALIC);
230
void sokoke_entry_set_default_text(GtkEntry* entry, const gchar* sDefaultText)
232
// Note: The default text initially overwrites any previous text
233
gchar* sOldValue = g_object_get_data(G_OBJECT(entry), "sokoke_sDefaultText");
236
g_object_set_data(G_OBJECT(entry), "sokoke_bDefaultText", (gpointer)TRUE);
237
sokoke_widget_set_pango_font_style(GTK_WIDGET(entry), PANGO_STYLE_ITALIC);
238
gtk_entry_set_text(entry, sDefaultText);
240
g_object_set_data(G_OBJECT(entry), "sokoke_sDefaultText", (gpointer)sDefaultText);
241
g_signal_connect(entry, "focus-in-event"
242
, G_CALLBACK(sokoke_on_entry_focus_in_event), NULL);
243
g_signal_connect(entry, "focus-out-event"
244
, G_CALLBACK(sokoke_on_entry_focus_out_event), NULL);
247
gchar* sokoke_key_file_get_string_default(GKeyFile* key_file
248
, const gchar* group_name, const gchar* key, const gchar* def, GError* *error)
250
gchar* value = g_key_file_get_string(key_file, group_name, key, error);
251
return value == NULL ? g_strdup(def) : value;
254
gint sokoke_key_file_get_integer_default(GKeyFile* key_file
255
, const gchar* group_name, const gchar* key, const gint def, GError** error)
257
if(!g_key_file_has_key(key_file, group_name, key, NULL))
259
return g_key_file_get_integer(key_file, group_name, key, error);
262
gboolean sokoke_key_file_save_to_file(GKeyFile* key_file
263
, const gchar* sFilename, GError** error)
265
gchar* sData = g_key_file_to_data(key_file, NULL, error);
269
if(!(fp = fopen(sFilename, "w")))
271
*error = g_error_new(G_FILE_ERROR, G_FILE_ERROR_ACCES
272
, "Writing failed.");
281
void sokoke_widget_get_text_size(GtkWidget* widget, const gchar* sText
284
PangoLayout* layout = gtk_widget_create_pango_layout(widget, sText);
285
pango_layout_get_pixel_size(layout, w, h);
286
g_object_unref(layout);
289
void sokoke_menu_item_set_accel(GtkMenuItem* menuitem, const gchar* sPath
290
, const gchar* sKey, GdkModifierType accel_mods)
294
gchar* path = g_strconcat("<", g_get_prgname(), ">/", sPath, NULL);
295
gtk_menu_item_set_accel_path(GTK_MENU_ITEM(menuitem), path);
296
guint keyVal = sKey ? gdk_keyval_from_name(sKey) : 0;
297
gtk_accel_map_add_entry(path, keyVal, accel_mods);
302
gboolean sokoke_entry_can_undo(GtkEntry* entry)
304
// TODO: Can we undo the last input?
308
gboolean sokoke_entry_can_redo(GtkEntry* entry)
310
// TODO: Can we redo the last input?
314
void sokoke_entry_undo(GtkEntry* entry)
316
// TODO: Implement undo
320
void sokoke_entry_redo(GtkEntry* entry)
322
// TODO: Implement redo
326
static gboolean sokoke_on_undo_entry_key_down(GtkEntry* widget, GdkEventKey* event
329
switch(event->keyval)
332
sokoke_entry_undo(widget);
335
sokoke_entry_redo(widget);
342
static void sokoke_on_undo_entry_populate_popup(GtkEntry* entry, GtkMenu* menu
345
// Enhance the entry's menu with undo and redo items.
346
GtkWidget* menuitem = gtk_separator_menu_item_new();
347
gtk_menu_shell_prepend((GtkMenuShell*)menu, menuitem);
348
gtk_widget_show(menuitem);
349
menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_REDO, NULL);
350
g_signal_connect(menuitem, "activate", G_CALLBACK(sokoke_entry_redo), userdata);
351
gtk_widget_set_sensitive(menuitem, sokoke_entry_can_redo(entry));
352
gtk_menu_shell_prepend((GtkMenuShell*)menu, menuitem);
353
gtk_widget_show(menuitem);
354
menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_UNDO, NULL);
355
g_signal_connect(menuitem, "activate", G_CALLBACK(sokoke_entry_undo), userdata);
356
gtk_widget_set_sensitive(menuitem, sokoke_entry_can_undo(entry));
357
gtk_menu_shell_prepend((GtkMenuShell*)menu, menuitem);
358
gtk_widget_show(menuitem);
361
gboolean sokoke_entry_get_can_undo(GtkEntry* entry)
363
// TODO: Is this entry undo enabled?
367
void sokoke_entry_set_can_undo(GtkEntry* entry, gboolean bCanUndo)
371
g_signal_connect(entry, "key-press-event"
372
, G_CALLBACK(sokoke_on_undo_entry_key_down), NULL);
373
g_signal_connect(entry, "populate-popup"
374
, G_CALLBACK(sokoke_on_undo_entry_populate_popup), NULL);
378
; // TODO: disconnect signal