diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/eel-gconf-extensions.c | 24 | ||||
-rw-r--r-- | lib/eel-gconf-extensions.h | 2 | ||||
-rwxr-xr-x | lib/egg/egg-editable-toolbar.c | 14 | ||||
-rw-r--r-- | lib/ephy-dialog.c | 57 | ||||
-rw-r--r-- | lib/ephy-dialog.h | 5 | ||||
-rw-r--r-- | lib/ephy-file-helpers.c | 148 | ||||
-rw-r--r-- | lib/ephy-file-helpers.h | 14 |
7 files changed, 246 insertions, 18 deletions
diff --git a/lib/eel-gconf-extensions.c b/lib/eel-gconf-extensions.c index 432b0d693..d34df9f0b 100644 --- a/lib/eel-gconf-extensions.c +++ b/lib/eel-gconf-extensions.c @@ -699,3 +699,27 @@ eel_gconf_set_path (const char *key, g_free (tilde_path); g_free (converted); } + +void +eel_gconf_unset_key (const char *key) +{ + GConfClient *client; + GError *error = NULL; + + client = eel_gconf_client_get_global (); + g_return_if_fail (client != NULL); + + gconf_client_unset (client, key, &error); + eel_gconf_handle_error (&error); +} + +void +eel_gconf_notify (const char *key) +{ + GConfClient *client; + + client = eel_gconf_client_get_global (); + g_return_if_fail (client != NULL); + + gconf_client_notify (client, key); +} diff --git a/lib/eel-gconf-extensions.h b/lib/eel-gconf-extensions.h index 410668273..de87c3973 100644 --- a/lib/eel-gconf-extensions.h +++ b/lib/eel-gconf-extensions.h @@ -76,6 +76,8 @@ void eel_gconf_set_float (const char *key, gfloat eel_gconf_get_float (const char *key); void eel_gconf_set_path (const char *key, const char *value); +void eel_gconf_unset_key (const char *key); +void eel_gconf_notify (const char *key); G_END_DECLS diff --git a/lib/egg/egg-editable-toolbar.c b/lib/egg/egg-editable-toolbar.c index d52da9915..6189291c8 100755 --- a/lib/egg/egg-editable-toolbar.c +++ b/lib/egg/egg-editable-toolbar.c @@ -368,10 +368,11 @@ popup_context_menu_cb (GtkWidget *toolbar, { if (etoolbar->priv->popup != 0) { + GtkMenu *menu; egg_editable_toolbar_set_selected (etoolbar, toolbar); g_object_notify (G_OBJECT (etoolbar), "selected"); - GtkMenu *menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); + menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button_number, gtk_get_current_event_time ()); } } @@ -383,10 +384,11 @@ button_press_event_cb (GtkWidget *widget, { if (event->button == 3 && etoolbar->priv->popup != 0) { + GtkMenu *menu; egg_editable_toolbar_set_selected (etoolbar, widget); g_object_notify (G_OBJECT (etoolbar), "selected"); - GtkMenu *menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); + menu = GTK_MENU (gtk_ui_manager_get_widget (etoolbar->priv->manager, "/ToolbarPopup")); gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button, event->time); return TRUE; @@ -1053,8 +1055,6 @@ static void egg_editable_toolbar_set_ui_manager (EggEditableToolbar *etoolbar, GtkUIManager *manager) { - g_return_if_fail (GTK_IS_UI_MANAGER (manager)); - GtkActionGroup *group = gtk_action_group_new ("ToolbarActions"); GtkActionEntry actions[] = { { "MoveToolItem", NULL, _("_Move on Toolbar"), NULL, @@ -1086,10 +1086,12 @@ void egg_editable_toolbar_set_selected (EggEditableToolbar *etoolbar, GtkWidget *widget) { + gboolean toolitem, toolbar; + etoolbar->priv->selected = widget; - gboolean toolitem = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM) != 0); - gboolean toolbar = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR) != 0); + toolitem = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOL_ITEM) != 0); + toolbar = (gtk_widget_get_ancestor (widget, GTK_TYPE_TOOLBAR) != 0); gtk_action_set_visible (find_action (etoolbar, "RemoveToolbar"), toolbar && (etoolbar->priv->edit_mode > 0)); gtk_action_set_visible (find_action (etoolbar, "RemoveToolItem"), toolitem); diff --git a/lib/ephy-dialog.c b/lib/ephy-dialog.c index f171d4dae..669f6d5d8 100644 --- a/lib/ephy-dialog.c +++ b/lib/ephy-dialog.c @@ -178,7 +178,7 @@ set_value_from_pref (PropertyInfo *info, GValue *value) case G_TYPE_STRING: g_value_init (value, G_TYPE_STRING); text = eel_gconf_get_string (info->pref); - g_value_take_string (value, text ? text : g_strdup ("")); + g_value_take_string (value, text); break; case G_TYPE_INT: g_value_init (value, G_TYPE_INT); @@ -212,8 +212,18 @@ set_pref_from_value (PropertyInfo *info, GValue *value) switch (info->data_type) { case G_TYPE_STRING: - eel_gconf_set_string (pref, g_value_get_string (value)); + { + const char *string = g_value_get_string (value); + if (string != NULL) + { + eel_gconf_set_string (pref, string); + } + else + { + eel_gconf_unset_key (pref); + } break; + } case G_TYPE_INT: eel_gconf_set_integer (pref, g_value_get_int (value)); break; @@ -412,6 +422,11 @@ set_value_from_togglebutton (PropertyInfo *info, GValue *value) active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (info->widget)); + if (info->apply_type & PT_INVERTED) + { + active = !active; + } + if (info->data_type == G_TYPE_BOOLEAN) { g_value_init (value, info->data_type); @@ -499,6 +514,26 @@ set_editable_from_value (PropertyInfo *info, const GValue *value) } static int +strcmp_with_null (const char *key1, + const char *key2) +{ + if (key1 == NULL && key2 == NULL) + { + return 0; + } + if (key1 == NULL) + { + return -1; + } + if (key2 == NULL) + { + return 1; + } + + return strcmp (key1, key2); +} + +static int get_index_from_value (const GValue *value, GList *string_enum) { int index = -1; @@ -509,10 +544,7 @@ get_index_from_value (const GValue *value, GList *string_enum) { val = g_value_get_string (value); - if (val) - { - s = g_list_find_custom (string_enum, val, (GCompareFunc) strcmp); - } + s = g_list_find_custom (string_enum, val, (GCompareFunc) strcmp_with_null); if (s) { @@ -538,7 +570,7 @@ compare_values (const GValue *a, const GValue *b) ta = g_value_get_string (a); tb = g_value_get_string (b); - return (ta && tb && strcmp (ta, tb) == 0); + return (strcmp_with_null (ta, tb) == 0); } else if (G_VALUE_HOLDS (a, G_TYPE_INT)) { @@ -689,6 +721,11 @@ set_togglebutton_from_value (PropertyInfo *info, const GValue *value) active = g_value_get_boolean (value); + if (info->apply_type & PT_INVERTED) + { + active = !active; + } + info->sane_state = TRUE; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (info->widget), active); @@ -740,7 +777,7 @@ set_pref_from_info_and_emit (PropertyInfo *info) g_signal_emit (info->dialog, signals[CHANGED], g_quark_from_string (info->id), &value); - if (info->apply_type == PT_AUTOAPPLY && info->pref != NULL) + if ((info->apply_type & PT_AUTOAPPLY) && info->pref != NULL) { set_pref_from_value (info, &value); } @@ -812,7 +849,7 @@ spinbutton_changed_cb (GtkWidget *widget, PropertyInfo *info) { GTimer *spin_timer; - if (info->apply_type != PT_AUTOAPPLY) return; + if ((info->apply_type & PT_AUTOAPPLY) == 0) return; spin_timer = g_object_get_data (G_OBJECT (info->widget), "timer"); @@ -977,7 +1014,7 @@ save_info (gpointer key, PropertyInfo *info, EphyDialog *dialog) { GValue value = { 0, }; - if (info->pref == NULL || info->apply_type != PT_NORMAL) + if (info->pref == NULL || (info->apply_type & PT_NORMAL) == 0) { return; } diff --git a/lib/ephy-dialog.h b/lib/ephy-dialog.h index e8e45ca72..6a22f585b 100644 --- a/lib/ephy-dialog.h +++ b/lib/ephy-dialog.h @@ -41,8 +41,9 @@ typedef struct _EphyDialogPrivate EphyDialogPrivate; typedef enum { - PT_NORMAL, - PT_AUTOAPPLY + PT_NORMAL = 0, + PT_AUTOAPPLY = 1 << 0, + PT_INVERTED = 1 << 1 } EphyDialogApplyType; typedef struct diff --git a/lib/ephy-file-helpers.c b/lib/ephy-file-helpers.c index a6db91d70..60d9a8790 100644 --- a/lib/ephy-file-helpers.c +++ b/lib/ephy-file-helpers.c @@ -954,3 +954,151 @@ ephy_file_launch_handler (const char *mime_type, return ret; } + +#define DELAY_MAX_TICKS 64 + +struct _EphyFileMonitor +{ + GnomeVFSMonitorHandle *handle; + EphyFileMonitorFunc callback; + EphyFileMonitorDelayFunc delay_func; + gpointer user_data; + char *uri; + guint delay; + guint timeout_id; + guint ticks; +}; + +static gboolean +ephy_file_monitor_timeout_cb (EphyFileMonitor *monitor) +{ + if (monitor->ticks > 0) + { + monitor->ticks--; + + /* Run again */ + return TRUE; + } + + if (monitor->delay_func && + monitor->delay_func (monitor, monitor->user_data)) + { + monitor->ticks = DELAY_MAX_TICKS / 2; + + /* Run again */ + return TRUE; + } + + monitor->timeout_id = 0; + + monitor->callback (monitor, monitor->uri, monitor->user_data); + + /* don't run again */ + return FALSE; +} + +static void +ephy_file_monitor_cb (GnomeVFSMonitorHandle *handle, + const char *monitor_uri, + const char *info_uri, + GnomeVFSMonitorEventType event_type, + EphyFileMonitor *monitor) +{ + LOG ("File '%s' has changed, scheduling reload", monitor_uri); + + switch (event_type) + { + case GNOME_VFS_MONITOR_EVENT_CHANGED: + case GNOME_VFS_MONITOR_EVENT_CREATED: + /* We make a lot of assumptions here, but basically we know + * that we just have to reload, by construction. + * Delay the reload a little bit so we don't endlessly + * reload while a file is written. + */ + if (monitor->ticks == 0) + { + monitor->ticks = 1; + } + else + { + /* Exponential backoff */ + monitor->ticks = MIN (monitor->ticks * 2, + DELAY_MAX_TICKS); + } + + if (monitor->timeout_id == 0) + { + monitor->timeout_id = + g_timeout_add (monitor->delay, + (GSourceFunc) ephy_file_monitor_timeout_cb, + monitor); + } + + break; + + case GNOME_VFS_MONITOR_EVENT_DELETED: + case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING: + case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING: + case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED: + default: + break; + } +} + +EphyFileMonitor * +ephy_file_monitor_add (const char *uri, + GnomeVFSMonitorType monitor_type, + guint delay, + EphyFileMonitorFunc callback, + EphyFileMonitorDelayFunc delay_func, + gpointer user_data) +{ + EphyFileMonitor *monitor; + + g_return_val_if_fail (uri != NULL, NULL); + g_return_val_if_fail (callback, NULL); + + monitor = g_new (EphyFileMonitor, 1); + monitor->callback = callback; + monitor->delay_func = delay_func; + monitor->user_data = user_data; + monitor->uri = g_strdup (uri); + monitor->delay = delay; + monitor->ticks = 0; + monitor->timeout_id = 0; + + if (gnome_vfs_monitor_add (&monitor->handle, uri, monitor_type, + (GnomeVFSMonitorCallback) ephy_file_monitor_cb, + monitor) != GNOME_VFS_OK) + { + LOG ("Failed to add file monitor for '%s'", uri); + + g_free (monitor->uri); + g_free (monitor); + return NULL; + } + + LOG ("File monitor for '%s' added", uri); + + return monitor; +} + +void +ephy_file_monitor_cancel (EphyFileMonitor *monitor) +{ + g_return_if_fail (monitor != NULL); + g_return_if_fail (monitor->handle != NULL); + g_return_if_fail (monitor->uri != NULL); + + LOG ("Cancelling file monitor for '%s'", monitor->uri); + + gnome_vfs_monitor_cancel (monitor->handle); + + if (monitor->timeout_id != 0) + { + g_source_remove (monitor->timeout_id); + } + + g_free (monitor->uri); + g_free (monitor); +} diff --git a/lib/ephy-file-helpers.h b/lib/ephy-file-helpers.h index 2e5b7f111..709ff77b0 100644 --- a/lib/ephy-file-helpers.h +++ b/lib/ephy-file-helpers.h @@ -25,6 +25,7 @@ #include <glib.h> #include <libgnomevfs/gnome-vfs-mime-handlers.h> +#include <libgnomevfs/gnome-vfs-ops.h> G_BEGIN_DECLS @@ -35,6 +36,10 @@ typedef enum EPHY_MIME_PERMISSION_UNKNOWN = 3 } EphyMimePermission; +typedef struct _EphyFileMonitor EphyFileMonitor; +typedef void (* EphyFileMonitorFunc) (EphyFileMonitor*, const char*, gpointer); +typedef gboolean (* EphyFileMonitorDelayFunc) (EphyFileMonitor*, gpointer); + const char *ephy_file (const char *filename); const char *ephy_dot_dir (void); @@ -78,6 +83,15 @@ gboolean ephy_file_launch_handler (const char *mime_type, const char *address, guint32 user_time); +EphyFileMonitor *ephy_file_monitor_add (const char *uri, + GnomeVFSMonitorType monitor_type, + guint delay, + EphyFileMonitorFunc callback, + EphyFileMonitorDelayFunc delay_func, + gpointer user_data); + +void ephy_file_monitor_cancel (EphyFileMonitor *monitor); + G_END_DECLS #endif /* EPHY_FILE_HELPERS_H */ |