2
Copyright (C) 2007-2008 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.
23
#include <gdk/gdkkeysyms.h>
24
#include <glib/gi18n.h>
25
#include <glib/gprintf.h>
28
sokoke_magic_uri (const gchar* uri, const gchar* default_search_uri)
30
// Add file:// if we have a local path
31
if (g_path_is_absolute (uri))
32
return g_strconcat ("file://", uri, NULL);
33
// Construct an absolute path if the file is relative
34
if (g_file_test (uri, G_FILE_TEST_EXISTS) && g_file_test (uri, G_FILE_TEST_IS_REGULAR))
36
gchar* current_dir = g_get_current_dir ();
37
gchar* result = g_strconcat ("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
41
// Do we need to add a protocol?
42
if (!strstr (uri, "://"))
44
// Do we have a domain, ip address or localhost?
45
if (strchr (uri, '.') != NULL || !strcmp (uri, "localhost"))
46
return g_strconcat ("http://", uri, NULL);
47
// We don't want to search? So return early.
48
if (!default_search_uri)
49
return g_strdup (uri);
51
const gchar* search_uri = NULL;
52
// Do we have a keyword and a string?
53
gchar** parts = g_strsplit (uri, " ", 2);
54
if (parts[0] && parts[1])
56
guint n = g_list_length (searchEngines);
58
for (i = 0; i < n; i++)
60
SearchEngine* search_engine = (SearchEngine*)g_list_nth_data (
62
if (!strcmp (search_engine_get_keyword (search_engine),
64
search_uri = search_engine->url;
67
search = g_strdup_printf (search_uri, parts[1]);
69
// We only have a word or there is no matching keyword, so search for it
71
search = g_strdup_printf (default_search_uri, uri);
74
return g_strdup (uri);
78
sokoke_entry_setup_completion (GtkEntry* entry)
80
/* TODO: The current behavior works only with the beginning of strings
81
But we want to match "localhost" with "loc" and "hos" */
82
GtkEntryCompletion* completion = gtk_entry_completion_new ();
83
gtk_entry_completion_set_model (completion,
84
GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)));
85
gtk_entry_completion_set_text_column (completion, 0);
86
gtk_entry_completion_set_minimum_key_length (completion, 3);
87
gtk_entry_set_completion (entry, completion);
88
gtk_entry_completion_set_popup_completion (completion, FALSE); //...
92
sokoke_entry_append_completion (GtkEntry* entry, const gchar* text)
94
GtkEntryCompletion* completion = gtk_entry_get_completion (entry);
95
GtkTreeModel* completion_store = gtk_entry_completion_get_model (completion);
97
gtk_list_store_insert (GTK_LIST_STORE (completion_store), &iter, 0);
98
gtk_list_store_set (GTK_LIST_STORE (completion_store), &iter, 0, text, -1);
102
sokoke_combo_box_add_strings (GtkComboBox* combobox,
103
const gchar* label_first, ...)
105
// Add a number of strings to a combobox, terminated with NULL
106
// This works only for text comboboxes
108
va_start (args, label_first);
111
for (label = label_first; label; label = va_arg (args, const gchar*))
112
gtk_combo_box_append_text (combobox, label);
117
void sokoke_widget_set_visible (GtkWidget* widget, gboolean visible)
119
// Show or hide the widget
121
gtk_widget_show (widget);
123
gtk_widget_hide (widget);
127
sokoke_container_show_children (GtkContainer* container)
129
// Show every child but not the container itself
130
gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
134
sokoke_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
136
#if GTK_CHECK_VERSION(2, 12, 0)
137
gtk_widget_set_tooltip_text (widget, text);
139
static GtkTooltips* tooltips;
141
tooltips = gtk_tooltips_new ();
142
gtk_tooltips_set_tip (tooltips, widget, text, NULL);
147
sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem, const gchar* text)
151
#if GTK_CHECK_VERSION(2, 12, 0)
152
gtk_tool_item_set_tooltip_text (toolitem, text);
154
static GtkTooltips* tooltips = NULL;
155
if (G_UNLIKELY (!tooltips))
156
tooltips = gtk_tooltips_new();
158
gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
166
SokokeMenuPos position;
170
sokoke_widget_popup_position_menu (GtkMenu* menu,
178
GtkRequisition menu_req;
179
GtkRequisition widget_req;
180
SokokePopupInfo* info = user_data;
181
GtkWidget* widget = info->widget;
183
// Retrieve size and position of both widget and menu
184
if (GTK_WIDGET_NO_WINDOW (widget))
186
gdk_window_get_position (widget->window, &wx, &wy);
187
wx += widget->allocation.x;
188
wy += widget->allocation.y;
191
gdk_window_get_origin (widget->window, &wx, &wy);
192
gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
193
gtk_widget_size_request (widget, &widget_req);
194
menu_width = menu_req.width;
195
gint widget_height = widget_req.height; // Better than allocation.height
197
// Calculate menu position
198
if (info->position == SOKOKE_MENU_POSITION_CURSOR)
200
else if (info->position == SOKOKE_MENU_POSITION_RIGHT)
202
*x = wx + widget->allocation.width - menu_width;
203
*y = wy + widget_height;
204
} else if (info->position == SOKOKE_MENU_POSITION_LEFT)
207
*y = wy + widget_height;
215
sokoke_widget_popup (GtkWidget* widget,
217
GdkEventButton* event,
220
int button, event_time;
223
button = event->button;
224
event_time = event->time;
229
event_time = gtk_get_current_event_time ();
232
if (!gtk_menu_get_attach_widget(menu))
233
gtk_menu_attach_to_widget (menu, widget, NULL);
237
SokokePopupInfo info = { widget, pos };
238
gtk_menu_popup (menu, NULL, NULL,
239
sokoke_widget_popup_position_menu, &info,
243
gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time);
248
SOKOKE_DESKTOP_UNTESTED,
250
SOKOKE_DESKTOP_UNKNOWN
254
sokoke_get_desktop (void)
256
static SokokeDesktop desktop = SOKOKE_DESKTOP_UNTESTED;
257
if (G_UNLIKELY (desktop == SOKOKE_DESKTOP_UNTESTED))
259
// Are we running in Xfce?
260
gint result; gchar* out; gchar* err;
261
gboolean success = g_spawn_command_line_sync (
262
"xprop -root _DT_SAVE_MODE | grep -q xfce4",
263
&out, &err, &result, NULL);
264
if (success && !result)
265
desktop = SOKOKE_DESKTOP_XFCE;
267
desktop = SOKOKE_DESKTOP_UNKNOWN;
274
sokoke_xfce_header_new (const gchar* icon,
277
// Create an xfce header with icon and title
278
// This returns NULL if the desktop is not xfce
279
if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
281
GtkWidget* entry = gtk_entry_new ();
283
GtkWidget* xfce_heading = gtk_event_box_new ();
284
gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
285
&entry->style->base[GTK_STATE_NORMAL]);
286
GtkWidget* hbox = gtk_hbox_new (FALSE, 12);
287
gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
288
GtkWidget* image = gtk_image_new_from_icon_name (icon,
289
GTK_ICON_SIZE_DIALOG);
290
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
291
GtkWidget* label = gtk_label_new (NULL);
292
gtk_widget_modify_fg (label, GTK_STATE_NORMAL
293
, &entry->style->text[GTK_STATE_NORMAL]);
294
markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
296
gtk_label_set_markup (GTK_LABEL (label), markup);
297
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
298
gtk_container_add (GTK_CONTAINER (xfce_heading), hbox);
306
sokoke_superuser_warning_new (void)
308
// Create a horizontal bar with a security warning
309
// This returns NULL if the user is no superuser
311
if (G_UNLIKELY (!geteuid ())) // effective superuser?
313
GtkWidget* hbox = gtk_event_box_new ();
314
gtk_widget_modify_bg (hbox, GTK_STATE_NORMAL,
315
&hbox->style->bg[GTK_STATE_SELECTED]);
316
GtkWidget* label = gtk_label_new (
317
_("Warning: You are using a superuser account!"));
318
gtk_misc_set_padding (GTK_MISC (label), 0, 2);
319
gtk_widget_modify_fg (GTK_WIDGET (label), GTK_STATE_NORMAL,
320
>K_WIDGET (label)->style->fg[GTK_STATE_SELECTED]);
321
gtk_widget_show (label);
322
gtk_container_add (GTK_CONTAINER(hbox), GTK_WIDGET (label));
323
gtk_widget_show (hbox);
331
sokoke_hig_frame_new (const gchar* title)
333
// Create a frame with no actual frame but a bold label and indentation
334
GtkWidget* frame = gtk_frame_new (NULL);
335
gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
336
GtkWidget* label = gtk_label_new (NULL);
337
gtk_label_set_markup (GTK_LABEL (label), title_bold);
339
gtk_frame_set_label_widget (GTK_FRAME (frame), label);
340
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
345
sokoke_widget_set_pango_font_style (GtkWidget* widget,
348
// Conveniently change the pango font style
349
// For some reason we need to reset if we actually want the normal style
350
if (style == PANGO_STYLE_NORMAL)
351
gtk_widget_modify_font (widget, NULL);
354
PangoFontDescription* font_description = pango_font_description_new ();
355
pango_font_description_set_style (font_description, PANGO_STYLE_ITALIC);
356
gtk_widget_modify_font (widget, font_description);
357
pango_font_description_free (font_description);
362
sokoke_on_entry_focus_in_event (GtkEntry* entry,
363
GdkEventFocus* event,
366
gint default_text = GPOINTER_TO_INT (
367
g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
370
gtk_entry_set_text (entry, "");
371
g_object_set_data (G_OBJECT(entry), "sokoke_has_default",
372
GINT_TO_POINTER (0));
373
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
380
sokoke_on_entry_focus_out_event (GtkEntry* entry,
381
GdkEventFocus* event,
384
const gchar* text = gtk_entry_get_text (entry);
387
const gchar* defaultText = (const gchar*)g_object_get_data (
388
G_OBJECT (entry), "sokoke_default_text");
389
gtk_entry_set_text (entry, defaultText);
390
g_object_set_data (G_OBJECT(entry),
391
"sokoke_has_default", GINT_TO_POINTER (1));
392
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
399
sokoke_entry_set_default_text (GtkEntry* entry,
400
const gchar* default_text)
402
// Note: The default text initially overwrites any previous text
403
gchar* old_value = g_object_get_data (G_OBJECT (entry),
404
"sokoke_default_text");
407
g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
408
GINT_TO_POINTER (1));
409
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
411
gtk_entry_set_text (entry, default_text);
413
g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
414
(gpointer)default_text);
415
g_signal_connect (entry, "focus-in-event",
416
G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
417
g_signal_connect (entry, "focus-out-event",
418
G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
422
sokoke_key_file_get_string_default (GKeyFile* key_file,
425
const gchar* default_value,
428
gchar* value = g_key_file_get_string (key_file, group, key, error);
429
return value == NULL ? g_strdup (default_value) : value;
433
sokoke_key_file_get_integer_default (GKeyFile* key_file,
436
const gint default_value,
439
if (!g_key_file_has_key (key_file, group, key, NULL))
440
return default_value;
441
return g_key_file_get_integer (key_file, group, key, error);
445
sokoke_key_file_get_double_default (GKeyFile* key_file,
448
const gdouble default_value,
451
if (!g_key_file_has_key (key_file, group, key, NULL))
452
return default_value;
453
return g_key_file_get_double (key_file, group, key, error);
457
sokoke_key_file_get_boolean_default (GKeyFile* key_file,
460
const gboolean default_value,
463
if (!g_key_file_has_key (key_file, group, key, NULL))
464
return default_value;
465
return g_key_file_get_boolean (key_file, group, key, error);
469
sokoke_key_file_save_to_file (GKeyFile* key_file,
470
const gchar* filename,
473
gchar* data = g_key_file_to_data (key_file, NULL, error);
477
if (!(fp = fopen (filename, "w")))
479
*error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_ACCES,
480
_("Writing failed."));
490
sokoke_widget_get_text_size (GtkWidget* widget,
495
PangoLayout* layout = gtk_widget_create_pango_layout (widget, text);
496
pango_layout_get_pixel_size (layout, width, height);
497
g_object_unref (layout);