aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/eel-gconf-extensions.c24
-rw-r--r--lib/eel-gconf-extensions.h2
-rwxr-xr-xlib/egg/egg-editable-toolbar.c14
-rw-r--r--lib/ephy-dialog.c57
-rw-r--r--lib/ephy-dialog.h5
-rw-r--r--lib/ephy-file-helpers.c148
-rw-r--r--lib/ephy-file-helpers.h14
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 */