diff options
author | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2002-12-30 19:29:24 +0000 |
---|---|---|
committer | Marco Pesenti Gritti <mpeseng@src.gnome.org> | 2002-12-30 19:29:24 +0000 |
commit | 6876ede98282c7db318089bfefb292aa59e55d48 (patch) | |
tree | 76b23252d04da232d0ebf22e53bfe3e022686af9 /embed | |
download | epiphany-6876ede98282c7db318089bfefb292aa59e55d48.tar.gz |
Initial revision
Diffstat (limited to 'embed')
90 files changed, 20998 insertions, 0 deletions
diff --git a/embed/.cvsignore b/embed/.cvsignore new file mode 100644 index 000000000..20e4cb0c8 --- /dev/null +++ b/embed/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +*.lo +.deps +.libs +*.la diff --git a/embed/Makefile.am b/embed/Makefile.am new file mode 100644 index 000000000..a6f43fb46 --- /dev/null +++ b/embed/Makefile.am @@ -0,0 +1,57 @@ +SUBDIRS = mozilla + +INCLUDES = \ + -I$(top_srcdir)/embed/mozilla \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/widgets \ + -I$(MOZILLA_INCLUDE_ROOT)/gtkembedmoz \ + $(WARN_CFLAGS) \ + $(EPIPHANY_DEPENDENCY_CFLAGS) \ + -DSHARE_DIR=\"$(pkgdatadir)\" \ + -DG_DISABLE_DEPRECATED \ + -DGDK_DISABLE_DEPRECATED \ + -DGTK_DISABLE_DEPRECATED \ + -DGDK_PIXBUF_DISABLE_DEPRECATED \ + -DGNOME_DISABLE_DEPRECATED + +noinst_LTLIBRARIES = libephyembed.la + +libephyembed_la_SOURCES = \ + ephy-embed-types.h \ + downloader-view.c \ + downloader-view.h \ + ephy-history.c \ + ephy-history.h \ + ephy-embed.c \ + ephy-embed.h \ + ephy-embed-shell.c \ + ephy-embed-shell.h \ + ephy-embed-persist.c \ + ephy-embed-persist.h \ + ephy-embed-popup.c \ + ephy-embed-popup.h \ + ephy-embed-popup-bw.c \ + ephy-embed-popup-bw.h \ + ephy-embed-popup-control.c \ + ephy-embed-popup-control.h \ + ephy-embed-event.c \ + ephy-embed-event.h \ + ephy-embed-utils.c \ + ephy-embed-utils.h \ + ephy-embed-dialog.c \ + ephy-embed-dialog.h \ + find-dialog.c \ + find-dialog.h \ + print-dialog.c \ + print-dialog.h \ + ephy-embed-prefs.h \ + ephy-favicon-cache.c \ + ephy-favicon-cache.h \ + ephy-embed-favicon.c \ + ephy-embed-favicon.h \ + ephy-favicon.c \ + ephy-favicon.h + + +libephyembed_la_LIBADD = \ + $(top_builddir)/embed/mozilla/libephymozillaembed.la diff --git a/embed/downloader-view.c b/embed/downloader-view.c new file mode 100644 index 000000000..97e05a613 --- /dev/null +++ b/embed/downloader-view.c @@ -0,0 +1,1100 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "downloader-view.h" +#include "eel-gconf-extensions.h" +#include "ephy-gui.h" +#include "ephy-prefs.h" +#include "ephy-ellipsizing-label.h" +#include "ephy-embed-utils.h" +#include "ephy-file-helpers.h" + +#include <gtk/gtktreeview.h> +#include <gtk/gtkliststore.h> +#include <gtk/gtktreeviewcolumn.h> +#include <libgnome/gnome-i18n.h> +#include <libgnomeui/gnome-dialog-util.h> +#include <libgnomeui/gnome-dialog.h> +#include <gtk/gtkprogressbar.h> +#include <libgnomevfs/gnome-vfs-mime-handlers.h> + +enum +{ + DOWNLOAD_REMOVE, + DOWNLOAD_PAUSE, + DOWNLOAD_RESUME, + LAST_SIGNAL +}; + +enum +{ + COL_PERCENT, + COL_FILENAME, + COL_SIZE, + COL_REMAINING, + COL_PERSIST_OBJECT +}; + +struct DownloaderViewPrivate +{ + GHashTable *details_hash; + GtkTreeModel *model; + gboolean show_details; + + /* Widgets */ + GtkWidget *treeview; + GtkWidget *details_file; + GtkWidget *details_location; + GtkWidget *details_status; + GtkWidget *details_elapsed; + GtkWidget *details_remaining; + GtkWidget *details_progress; + GtkWidget *details_button; + GtkWidget *keep_open_check; + GtkWidget *pause_button; + GtkWidget *resume_button; + GtkWidget *abort_button; + GtkWidget *open_button; +}; + +typedef struct +{ + glong elapsed; + glong remaining; + gfloat speed; + gint size_total; + gint size_done; + gfloat progress; + gboolean can_pause; + gchar *filename; + gchar *source; + gchar *dest; + DownloadStatus status; + + GtkTreeRowReference *ref; +} DownloadDetails; + +typedef struct +{ + gboolean can_resume; + gboolean can_pause; + gboolean can_abort; + gboolean can_open; + DownloaderViewPrivate *priv; +} ControlsInfo; + +enum +{ + PROP_TREEVIEW, + PROP_KEEP_OPEN, + PROP_DETAILS_FRAME, + PROP_DETAILS_SEPARATOR, + PROP_DETAILS_TABLE, + PROP_DETAILS_STATUS, + PROP_DETAILS_ELAPSED, + PROP_DETAILS_REMAINING, + PROP_DETAILS_PROGRESS, + PROP_PAUSE_BUTTON, + PROP_RESUME_BUTTON, + PROP_ABORT_BUTTON, + PROP_OPEN_BUTTON, + PROP_DETAILS_BUTTON +}; + +static const +EphyDialogProperty properties [] = +{ + { PROP_TREEVIEW, "clist", NULL, PT_NORMAL, NULL }, + { PROP_KEEP_OPEN, "keep_open_check", CONF_DOWNLOADING_KEEP_OPEN, PT_NORMAL, NULL }, + { PROP_DETAILS_FRAME, "details_frame", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_SEPARATOR, "details_separator", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_TABLE, "details_table", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_STATUS, "details_status", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_ELAPSED, "details_elapsed", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_REMAINING, "details_remaining", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_PROGRESS, "details_progress", NULL, PT_NORMAL, NULL }, + { PROP_PAUSE_BUTTON, "pause_button", NULL, PT_NORMAL, NULL }, + { PROP_RESUME_BUTTON, "resume_button", NULL, PT_NORMAL, NULL }, + { PROP_ABORT_BUTTON, "abort_button", NULL, PT_NORMAL, NULL }, + { PROP_OPEN_BUTTON, "open_button", NULL, PT_NORMAL, NULL }, + { PROP_DETAILS_BUTTON, "details_togglebutton", CONF_DOWNLOADING_SHOW_DETAILS, PT_NORMAL, NULL }, + + { -1, NULL, NULL } +}; + +static void +downloader_view_build_ui (DownloaderView *dv); +static void +downloader_view_class_init (DownloaderViewClass *klass); +static void +downloader_view_finalize (GObject *object); +static void +downloader_view_init (DownloaderView *dv); + +/* Callbacks */ +void +download_dialog_resume_cb (GtkButton *button, DownloaderView *dv); +void +download_dialog_pause_cb (GtkButton *button, DownloaderView *dv); +void +download_dialog_abort_cb (GtkButton *button, DownloaderView *dv); +static void +downloader_treeview_selection_changed_cb (GtkTreeSelection *selection, + DownloaderView *dv); +gboolean +download_dialog_delete_cb (GtkWidget *window, GdkEventAny *event, + DownloaderView *dv); +void +download_dialog_details_cb (GtkToggleButton *button, + DownloaderView *dv); +void +download_dialog_open_cb (GtkWidget *button, + DownloaderView *dv); + +static GObjectClass *parent_class = NULL; +static guint downloader_view_signals[LAST_SIGNAL] = { 0 }; + +GType +downloader_view_get_type (void) +{ + static GType downloader_view_type = 0; + + if (downloader_view_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (DownloaderViewClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) downloader_view_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (DownloaderView), + 0, /* n_preallocs */ + (GInstanceInitFunc) downloader_view_init + }; + + downloader_view_type = g_type_register_static (EPHY_DIALOG_TYPE, + "DownloaderView", + &our_info, 0); + } + + return downloader_view_type; +} + +static void +format_time (gchar *buffer, glong time) +{ + gint secs, hours, mins; + + secs = (gint)(time + .5); + hours = secs / 3600; + secs -= hours * 3600; + mins = secs / 60; + secs -= mins * 60; + + if (hours) + { + sprintf (buffer, "%u:%02u.%02u", hours, mins, secs); + } + else + { + sprintf (buffer, "%02u.%02u", mins, secs); + } +} + +static void +downloader_view_class_init (DownloaderViewClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + EphyDialogClass *ephy_dialog_class; + + parent_class = g_type_class_peek_parent (klass); + ephy_dialog_class = EPHY_DIALOG_CLASS (klass); + + object_class->finalize = downloader_view_finalize; + + /* init signals */ + downloader_view_signals[DOWNLOAD_REMOVE] = + g_signal_new ("download_remove", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DownloaderViewClass, download_remove), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + downloader_view_signals[DOWNLOAD_PAUSE] = + g_signal_new ("download_pause", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DownloaderViewClass, download_pause), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + downloader_view_signals[DOWNLOAD_RESUME] = + g_signal_new ("download_resume", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (DownloaderViewClass, download_resume), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + +} + +static void +destroy_details_cb (DownloadDetails *details) +{ + g_free (details->filename); + g_free (details->source); + g_free (details->dest); + g_free (details); +} + +static void +downloader_view_init (DownloaderView *dv) +{ + dv->priv = g_new0 (DownloaderViewPrivate, 1); + dv->priv->details_hash = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + (GDestroyNotify)destroy_details_cb); + + downloader_view_build_ui (dv); +} + +static void +downloader_view_finalize (GObject *object) +{ + DownloaderView *dv; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_DOWNLOADER_VIEW (object)); + + dv = DOWNLOADER_VIEW (object); + + g_return_if_fail (dv->priv != NULL); + + g_hash_table_destroy (dv->priv->details_hash); + + g_free (dv->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +DownloaderView * +downloader_view_new (void) +{ + return DOWNLOADER_VIEW (g_object_new + (DOWNLOADER_VIEW_TYPE, NULL)); +} + +static void +controls_info_foreach (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + ControlsInfo *info) +{ + DownloadDetails *details; + GValue val = {0, }; + gpointer persist_object; + + gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (info->priv->details_hash, + persist_object); + + info->can_pause |= details->can_pause; + info->can_resume |= (details->status == DOWNLOAD_STATUS_PAUSED); + info->can_abort |= (details->status != DOWNLOAD_STATUS_COMPLETED); + info->can_open |= (details->status == DOWNLOAD_STATUS_COMPLETED); +} + +static void +downloader_view_update_controls (DownloaderViewPrivate *priv) +{ + GtkTreeSelection *selection; + ControlsInfo *info; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); + + info = g_new0 (ControlsInfo, 1); + info->priv = priv; + + /* initial conditions */ + info->can_pause = info->can_resume = info->can_abort + = info->can_open = FALSE; + + if (selection) + { + gtk_tree_selection_selected_foreach + (selection, + (GtkTreeSelectionForeachFunc)controls_info_foreach, + info); + } + + /* setup buttons */ + gtk_widget_set_sensitive (priv->pause_button, info->can_pause); + gtk_widget_set_sensitive (priv->resume_button, info->can_resume); + gtk_widget_set_sensitive (priv->abort_button, info->can_abort); + gtk_widget_set_sensitive (priv->open_button, info->can_open); + + g_free (info); +} + +static void +downloader_view_update_details (DownloaderViewPrivate *priv, + DownloadDetails *details) +{ + gchar buffer[50]; + + ephy_ellipsizing_label_set_text + (EPHY_ELLIPSIZING_LABEL (priv->details_location), + details->source); + ephy_ellipsizing_label_set_text + (EPHY_ELLIPSIZING_LABEL (priv->details_file), + details->filename); + + if (details->size_total >= 10000) + { + sprintf (buffer, _("%.1f of %.1f MB"), + details->size_done / 1024.0, + details->size_total / 1024.0); + } + else if (details->size_total > 0) + { + sprintf (buffer, _("%d of %d KB"), + details->size_done, + details->size_total); + } + else + { + sprintf (buffer, _("%d KB"), + details->size_done); + } + + if (details->speed > 0) + { + sprintf (buffer, "%s at %.1f KB/s", buffer, details->speed); + } + gtk_label_set_text (GTK_LABEL (priv->details_status), + buffer); + + format_time (buffer, details->elapsed/1000000); + gtk_label_set_text (GTK_LABEL (priv->details_elapsed), + buffer); + + format_time (buffer, details->remaining); + gtk_label_set_text (GTK_LABEL (priv->details_remaining), + buffer); + + if (details->progress >= 0) + { + gtk_progress_bar_set_fraction + (GTK_PROGRESS_BAR (priv->details_progress), + details->progress); + } + else + { + gtk_progress_bar_pulse + (GTK_PROGRESS_BAR (priv->details_progress)); + } +} + +static gboolean +get_selected_row (DownloaderViewPrivate *priv, GtkTreeIter *iter) +{ + GList *l; + GtkTreePath *node; + GtkTreeSelection *selection; + GtkTreeModel *model; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); + l = gtk_tree_selection_get_selected_rows (selection, &model); + + if (l == NULL) return FALSE; + + node = l->data; + gtk_tree_model_get_iter (model, iter, node); + + g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL); + g_list_free (l); + + return TRUE; +} + +static void +downloader_view_set_download_info (DownloaderViewPrivate *priv, + DownloadDetails *details, + GtkTreeIter *iter) +{ + gchar buffer[50]; + GtkTreePath *path; + GtkTreePath *selected_path = NULL; + GtkTreeIter selected_iter; + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection + (GTK_TREE_VIEW(priv->treeview)); + + if (get_selected_row (priv, &selected_iter)) + { + selected_path = gtk_tree_model_get_path + (priv->model, &selected_iter); + } + + path = gtk_tree_row_reference_get_path (details->ref); + + gtk_list_store_set (GTK_LIST_STORE (priv->model), + iter, + COL_FILENAME, details->filename, + -1); + + /* Progress */ + if (details->status == DOWNLOAD_STATUS_COMPLETED) + details->progress = 1; + sprintf (buffer, "%.1f%%", + details->progress > 0 ? + details->progress * 100.0 : + 0); + gtk_list_store_set (GTK_LIST_STORE (priv->model), + iter, + COL_PERCENT, buffer, + -1); + + /* Total */ + if (details->size_total >= 10000) + { + sprintf (buffer, "%.2f MB", details->size_total / 1024.0); + } + else if (details->size_total > 0) + { + sprintf (buffer, "%d KB", details->size_total); + } + else + { + sprintf (buffer, _("Unknown")); + } + + gtk_list_store_set (GTK_LIST_STORE (priv->model), + iter, + COL_SIZE, buffer, + -1); + + /* Remaining */ + if (details->remaining >= 0) + { + format_time (buffer, details->remaining); + } + else + { + sprintf (buffer, _("Unknown")); + } + gtk_list_store_set (GTK_LIST_STORE (priv->model), + iter, + COL_REMAINING, buffer, + -1); + + if (gtk_tree_path_compare (path, selected_path) == 0) + { + downloader_view_update_details (priv, details); + } +} + +static void +ensure_selected_row (DownloaderView *dv) +{ + GtkTreeIter iter; + GtkTreeSelection *selection; + + g_return_if_fail (IS_DOWNLOADER_VIEW(dv)); + + selection = gtk_tree_view_get_selection + (GTK_TREE_VIEW(dv->priv->treeview)); + if (get_selected_row (dv->priv, &iter)) + { + /* there is already a selection */ + return; + } + + if (gtk_tree_model_get_iter_first (dv->priv->model, &iter)) + { + gtk_tree_selection_select_iter (selection, &iter); + } +} + +void +downloader_view_add_download (DownloaderView *dv, + gchar *filename, + gchar *source, + gchar *dest, + gpointer persist_object) +{ + GtkTreeIter iter; + DownloadDetails *details; + GtkTreeSelection *selection; + + details = g_new0 (DownloadDetails, 1); + details->filename = g_strdup (filename); + details->source = g_strdup (source); + details->dest = g_strdup (dest); + details->elapsed = -1; + details->remaining = -1; + details->speed = -1; + details->size_total = -1; + details->size_done = -1; + details->progress = -1; + dv->priv->show_details = FALSE; + + g_hash_table_insert (dv->priv->details_hash, + persist_object, + details); + + gtk_list_store_append (GTK_LIST_STORE (dv->priv->model), + &iter); + + details->ref = gtk_tree_row_reference_new + (GTK_TREE_MODEL (dv->priv->model), + gtk_tree_model_get_path + (GTK_TREE_MODEL (dv->priv->model), &iter)); + + gtk_list_store_set (GTK_LIST_STORE (dv->priv->model), + &iter, + COL_PERSIST_OBJECT, persist_object, + -1); + + selection = gtk_tree_view_get_selection + (GTK_TREE_VIEW(dv->priv->treeview)); + gtk_tree_selection_unselect_all (selection); + gtk_tree_selection_select_iter (selection, &iter); + + downloader_view_set_download_info (dv->priv, details, &iter); + + ephy_dialog_show (EPHY_DIALOG(dv)); +} + +void +downloader_view_remove_download (DownloaderView *dv, + gpointer persist_object) +{ + DownloadDetails *details; + GtkTreeIter iter; + GValue keep_open = {0, }; + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), + &iter, + gtk_tree_row_reference_get_path (details->ref)); + + gtk_list_store_remove (GTK_LIST_STORE (dv->priv->model), &iter); + + g_hash_table_remove (dv->priv->details_hash, + persist_object); + + ephy_dialog_get_value (EPHY_DIALOG(dv), PROP_KEEP_OPEN, &keep_open); + + if (!g_value_get_boolean (&keep_open) && + g_hash_table_size (dv->priv->details_hash) == 0) + { + g_object_unref (dv); + } + else + { + ensure_selected_row (dv); + } +} + +void +downloader_view_set_download_progress (DownloaderView *dv, + glong elapsed, + glong remaining, + gfloat speed, + gint size_total, + gint size_done, + gfloat progress, + gboolean can_pause, + gpointer persist_object) +{ + DownloadDetails *details; + GtkTreeIter iter; + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + details->elapsed = elapsed; + details->remaining = remaining; + details->speed = speed; + details->size_total = size_total; + details->size_done = size_done; + details->can_pause = can_pause; + details->progress = progress; + + gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), + &iter, + gtk_tree_row_reference_get_path (details->ref)); + + downloader_view_set_download_info (dv->priv, details, &iter); +} + +void +downloader_view_set_download_status (DownloaderView *dv, + DownloadStatus status, + gpointer persist_object) +{ + DownloadDetails *details; + GtkTreeIter iter; + GValue keep_open = {0, }; + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + details->status = status; + + gtk_tree_model_get_iter (GTK_TREE_MODEL (dv->priv->model), + &iter, + gtk_tree_row_reference_get_path (details->ref)); + + downloader_view_set_download_info (dv->priv, details, &iter); + downloader_view_update_controls (dv->priv); + + ephy_dialog_get_value (EPHY_DIALOG(dv), PROP_KEEP_OPEN, &keep_open); + + if (status == DOWNLOAD_STATUS_COMPLETED && + !g_value_get_boolean (&keep_open)) + { + downloader_view_remove_download (dv, persist_object); + } +} + +static void +downloader_view_build_ui (DownloaderView *dv) +{ + DownloaderViewPrivate *priv = dv->priv; + GtkListStore *liststore; + GtkTreeViewColumn *column; + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + GtkWidget *details_table; + EphyDialog *d = EPHY_DIALOG (dv); + + ephy_dialog_construct (d, + properties, + "epiphany.glade", + "download_manager_dialog"); + + /* lookup needed widgets */ + priv->treeview = ephy_dialog_get_control (d, PROP_TREEVIEW); + priv->details_status = ephy_dialog_get_control (d, PROP_DETAILS_STATUS); + priv->details_elapsed = ephy_dialog_get_control (d, PROP_DETAILS_ELAPSED); + priv->details_remaining = ephy_dialog_get_control (d, PROP_DETAILS_REMAINING); + priv->details_progress = ephy_dialog_get_control (d, PROP_DETAILS_PROGRESS); + priv->keep_open_check = ephy_dialog_get_control (d, PROP_KEEP_OPEN); + priv->details_button = ephy_dialog_get_control (d, PROP_DETAILS_BUTTON); + priv->pause_button = ephy_dialog_get_control (d, PROP_PAUSE_BUTTON); + priv->resume_button = ephy_dialog_get_control (d, PROP_RESUME_BUTTON); + priv->abort_button = ephy_dialog_get_control (d, PROP_ABORT_BUTTON); + priv->open_button = ephy_dialog_get_control (d, PROP_OPEN_BUTTON); + details_table = ephy_dialog_get_control (d, PROP_DETAILS_TABLE); + + /* create file and location details labels */ + priv->details_location = ephy_ellipsizing_label_new (""); + priv->details_file = ephy_ellipsizing_label_new (""); + gtk_table_attach_defaults (GTK_TABLE(details_table), priv->details_location, + 1, 2, 0, 1); + gtk_table_attach_defaults (GTK_TABLE(details_table), priv->details_file, + 1, 2, 1, 2); + gtk_misc_set_alignment (GTK_MISC(priv->details_location), 0, 0); + gtk_misc_set_alignment (GTK_MISC(priv->details_file), 0, 0); + gtk_label_set_selectable (GTK_LABEL(priv->details_location), TRUE); + gtk_label_set_selectable (GTK_LABEL(priv->details_file), TRUE); + gtk_widget_show (priv->details_location); + gtk_widget_show (priv->details_file); + + liststore = gtk_list_store_new (5, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_POINTER); + + gtk_tree_view_set_model (GTK_TREE_VIEW(priv->treeview), + GTK_TREE_MODEL (liststore)); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(priv->treeview), + TRUE); + + renderer = gtk_cell_renderer_text_new (); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), + 0, _("%"), + renderer, + "text", 0, + NULL); + column = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->treeview), 0); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_reorderable (column, TRUE); + gtk_tree_view_column_set_sort_column_id (column, COL_PERCENT); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), + COL_FILENAME, _("Filename"), + renderer, + "text", COL_FILENAME, + NULL); + column = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->treeview), + COL_FILENAME); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_reorderable (column, TRUE); + gtk_tree_view_column_set_sort_column_id (column, COL_FILENAME); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), + COL_SIZE, _("Size"), + renderer, + "text", COL_SIZE, + NULL); + column = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->treeview), + COL_SIZE); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_reorderable (column, TRUE); + gtk_tree_view_column_set_sort_column_id (column, COL_SIZE); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(priv->treeview), + COL_REMAINING, _("Remaining"), + renderer, + "text", COL_REMAINING, + NULL); + column = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->treeview), + COL_REMAINING); + gtk_tree_view_column_set_resizable (column, TRUE); + gtk_tree_view_column_set_reorderable (column, TRUE); + gtk_tree_view_column_set_sort_column_id (column, COL_REMAINING); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE); + g_signal_connect (G_OBJECT (selection), "changed", + G_CALLBACK (downloader_treeview_selection_changed_cb), dv); + + priv->model = GTK_TREE_MODEL (liststore); +} + +static void +resume_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, + DownloaderView *dv) +{ + DownloadDetails *details; + GValue val = {0, }; + gpointer *persist_object; + + gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + if (details->status == DOWNLOAD_STATUS_COMPLETED) return; + + downloader_view_set_download_status (dv, DOWNLOAD_STATUS_RESUMING, persist_object); + + g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_RESUME], 0); +} + +void +download_dialog_resume_cb (GtkButton *button, DownloaderView *dv) +{ + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); + + gtk_tree_selection_selected_foreach + (selection, + (GtkTreeSelectionForeachFunc)resume_selection_foreach, + (gpointer)dv); +} + +static void +pause_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, + DownloaderView *dv) +{ + DownloadDetails *details; + GValue val = {0, }; + gpointer *persist_object; + + gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + if (details->status == DOWNLOAD_STATUS_COMPLETED) return; + + downloader_view_set_download_status (dv, DOWNLOAD_STATUS_PAUSED, persist_object); + + g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_PAUSE], 0); +} + +void +download_dialog_pause_cb (GtkButton *button, DownloaderView *dv) +{ + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); + + gtk_tree_selection_selected_foreach + (selection, + (GtkTreeSelectionForeachFunc)pause_selection_foreach, + (gpointer)dv); +} + +void +download_dialog_abort_cb (GtkButton *button, DownloaderView *dv) +{ + GList *l, *r = NULL; + GtkTreeSelection *selection; + GtkTreeModel *model; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); + l = gtk_tree_selection_get_selected_rows (selection, &model); + for (;l != NULL; l = l->next) + { + r = g_list_append (r, gtk_tree_row_reference_new + (model, (GtkTreePath *)l->data)); + } + + for (; r != NULL; r = g_list_next (r)) + { + GtkTreeRowReference *node = r->data; + GValue val = {0, }; + gpointer *persist_object; + GtkTreeIter iter; + DownloadDetails *details; + + gtk_tree_model_get_iter (model, &iter, + gtk_tree_row_reference_get_path (node)); + + gtk_tree_model_get_value (model, &iter, + COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_REMOVE], 0); + + downloader_view_remove_download (dv, persist_object); + + gtk_tree_row_reference_free (node); + } + + l = g_list_first (l); + g_list_foreach (l, (GFunc)gtk_tree_path_free, NULL); + g_list_free (l); + g_list_free (r); +} + +static void +downloader_treeview_selection_changed_cb (GtkTreeSelection *selection, + DownloaderView *dv) +{ + GtkTreeIter iter; + GValue val = {0, }; + gpointer *persist_object; + DownloadDetails *details = NULL; + GtkWidget *details_frame; + DownloaderViewPrivate *priv= dv->priv; + + details_frame = ephy_dialog_get_control (EPHY_DIALOG(dv), + PROP_DETAILS_FRAME); + + if (get_selected_row (priv, &iter)) + { + gtk_tree_model_get_value (priv->model, &iter, COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (priv->details_hash, + persist_object); + g_return_if_fail (details); + + gtk_widget_set_sensitive (details_frame, TRUE); + + downloader_view_update_details (priv, details); + downloader_view_update_controls (priv); + } + else + { + gtk_label_set_text (GTK_LABEL (priv->details_location), ""); + gtk_label_set_text (GTK_LABEL (priv->details_file), ""); + gtk_label_set_text (GTK_LABEL (priv->details_status), ""); + gtk_label_set_text (GTK_LABEL (priv->details_elapsed), ""); + gtk_label_set_text (GTK_LABEL (priv->details_remaining), ""); + gtk_progress_bar_set_fraction + (GTK_PROGRESS_BAR (priv->details_progress), + 0); + + gtk_widget_set_sensitive (details_frame, FALSE); + } +} + +static void +alive_download_foreach (gpointer persist_object, + DownloadDetails *details, + gboolean *alive) +{ + if (details->status != DOWNLOAD_STATUS_COMPLETED) + { + *alive = TRUE; + } +} + +static gboolean +delete_pending_foreach (gpointer persist_object, + DownloadDetails *details, + DownloaderView *dv) +{ + g_signal_emit (G_OBJECT (dv), downloader_view_signals[DOWNLOAD_REMOVE], + 0, persist_object); + + return TRUE; +} + +gboolean +download_dialog_delete_cb (GtkWidget *window, GdkEventAny *event, + DownloaderView *dv) +{ + GtkWidget *dialog; + gboolean choice; + gboolean alive_download = FALSE; + + g_hash_table_foreach (dv->priv->details_hash, + (GHFunc)alive_download_foreach, + &alive_download); + + if (!alive_download) return FALSE; + + /* build question dialog */ + dialog = gtk_message_dialog_new ( + GTK_WINDOW(window), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_YES_NO, + _("Cancel all pending downloads?")); + + /* run it */ + choice = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + /* do the appropriate thing */ + if (choice == GTK_RESPONSE_YES) + { + g_hash_table_foreach_remove (dv->priv->details_hash, + (GHRFunc)delete_pending_foreach, + dv); + return FALSE; + } + + return TRUE; +} + +void +download_dialog_details_cb (GtkToggleButton *button, + DownloaderView *dv) +{ + GtkWidget *details_frame; + GtkWidget *details_separator; + + details_frame = ephy_dialog_get_control (EPHY_DIALOG(dv), + PROP_DETAILS_FRAME); + details_separator = ephy_dialog_get_control (EPHY_DIALOG(dv), + PROP_DETAILS_SEPARATOR); + + if (gtk_toggle_button_get_active (button)) + { + gtk_widget_show (GTK_WIDGET (details_frame)); + gtk_widget_show (GTK_WIDGET (details_separator)); + dv->priv->show_details = TRUE; + } + else + { + gtk_widget_hide (GTK_WIDGET (details_frame)); + gtk_widget_hide (GTK_WIDGET (details_separator)); + dv->priv->show_details = FALSE; + } + +} + +static void +open_selection_foreach (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, + DownloaderView *dv) +{ + DownloadDetails *details; + GValue val = {0, }; + gpointer *persist_object; + GnomeVFSMimeApplication *app; + char *mime; + + gtk_tree_model_get_value (model, iter, COL_PERSIST_OBJECT, &val); + persist_object = g_value_get_pointer (&val); + + details = g_hash_table_lookup (dv->priv->details_hash, + persist_object); + g_return_if_fail (details); + + if (details->status != DOWNLOAD_STATUS_COMPLETED) return; + + mime = gnome_vfs_get_mime_type (details->dest); + g_return_if_fail (mime != NULL); + + app = gnome_vfs_mime_get_default_application (mime); + if (app) + { + ephy_file_launch_application (app->command, + details->dest, + app->requires_terminal); + } + else + { + GtkWidget *parent; + parent = gtk_widget_get_toplevel (dv->priv->open_button); + ephy_embed_utils_nohandler_dialog_run (parent); + } + + g_free(mime); +} + +void +download_dialog_open_cb (GtkWidget *button, + DownloaderView *dv) +{ + GtkTreeSelection *selection; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(dv->priv->treeview)); + + gtk_tree_selection_selected_foreach + (selection, + (GtkTreeSelectionForeachFunc)open_selection_foreach, + (gpointer)dv); +} diff --git a/embed/downloader-view.h b/embed/downloader-view.h new file mode 100644 index 000000000..a01d5f30d --- /dev/null +++ b/embed/downloader-view.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef DOWNLOADER_VIEW_H +#define DOWNLOADER_VIEW_H + +#include "ephy-dialog.h" + +#include <glib-object.h> +#include <glib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DownloaderView DownloaderView; +typedef struct DownloaderViewClass DownloaderViewClass; + +#define DOWNLOADER_VIEW_TYPE (downloader_view_get_type ()) +#define DOWNLOADER_VIEW(obj) (GTK_CHECK_CAST ((obj), DOWNLOADER_VIEW_TYPE, DownloaderView)) +#define DOWNLOADER_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), DOWNLOADER_VIEW, DownloaderViewClass)) +#define IS_DOWNLOADER_VIEW(obj) (GTK_CHECK_TYPE ((obj), DOWNLOADER_VIEW_TYPE)) +#define IS_DOWNLOADER_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), DOWNLOADER_VIEW)) + +typedef struct DownloaderViewPrivate DownloaderViewPrivate; + +#define CONF_DOWNLOADING_KEEP_OPEN "/apps/epiphany/downloader/keep_open" + +typedef enum +{ + DOWNLOAD_STATUS_DOWNLOADING, + DOWNLOAD_STATUS_PAUSED, + DOWNLOAD_STATUS_RESUMING, + DOWNLOAD_STATUS_COMPLETED +} DownloadStatus; + +struct DownloaderView +{ + EphyDialog parent; + DownloaderViewPrivate *priv; +}; + +struct DownloaderViewClass +{ + EphyDialogClass parent_class; + + void (*download_remove) (DownloaderView *dv); + + void (*download_pause) (DownloaderView *dv); + + void (*download_resume) (DownloaderView *dv); +}; + +GType downloader_view_get_type (void); + +DownloaderView *downloader_view_new (void); + +void downloader_view_add_download (DownloaderView *dv, + gchar *filename, + gchar *source, + gchar *dest, + gpointer persist_object); + +void downloader_view_remove_download (DownloaderView *dv, + gpointer persist_object); + +void downloader_view_set_download_status (DownloaderView *dv, + DownloadStatus status, + gpointer persist_object); + +void downloader_view_set_download_progress (DownloaderView *dv, + glong elapsed, + glong remaining, + gfloat speed, + gint size_total, + gint size_done, + gfloat progress, + gboolean can_pause, + gpointer persist_object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/embed/ephy-embed-dialog.c b/embed/ephy-embed-dialog.c new file mode 100644 index 000000000..cc019253a --- /dev/null +++ b/embed/ephy-embed-dialog.c @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-embed-dialog.h" +#include "ephy-embed-shell.h" + +static void +ephy_embed_dialog_class_init (EphyEmbedDialogClass *klass); +static void +ephy_embed_dialog_init (EphyEmbedDialog *window); +static void +ephy_embed_dialog_finalize (GObject *object); +static void +ephy_embed_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void +ephy_embed_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); + +enum +{ + PROP_0, + PROP_EPHY_EMBED +}; + +struct EphyEmbedDialogPrivate +{ + EphyEmbed *embed; +}; + +static GObjectClass *parent_class = NULL; + +GType +ephy_embed_dialog_get_type (void) +{ + static GType ephy_embed_dialog_type = 0; + + if (ephy_embed_dialog_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_embed_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyEmbedDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_embed_dialog_init + }; + + ephy_embed_dialog_type = g_type_register_static (EPHY_DIALOG_TYPE, + "EphyEmbedDialog", + &our_info, 0); + } + + return ephy_embed_dialog_type; +} + +static void +ephy_embed_dialog_class_init (EphyEmbedDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_dialog_finalize; + object_class->set_property = ephy_embed_dialog_set_property; + object_class->get_property = ephy_embed_dialog_get_property; + + g_object_class_install_property (object_class, + PROP_EPHY_EMBED, + g_param_spec_object ("EphyEmbed", + "EphyEmbed", + "Ephy Embed", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); +} + +static void +ephy_embed_dialog_init (EphyEmbedDialog *dialog) +{ + dialog->priv = g_new0 (EphyEmbedDialogPrivate, 1); + + dialog->priv->embed = NULL; +} + +static void +ephy_embed_dialog_finalize (GObject *object) +{ + EphyEmbedDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_DIALOG (object)); + + dialog = EPHY_EMBED_DIALOG (object); + + g_return_if_fail (dialog->priv != NULL); + + g_free (dialog->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_embed_dialog_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEmbedDialog *d = EPHY_EMBED_DIALOG (object); + + switch (prop_id) + { + case PROP_EPHY_EMBED: + ephy_embed_dialog_set_embed (d, g_value_get_object (value)); + break; + } +} + +static void +ephy_embed_dialog_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEmbedDialog *d = EPHY_EMBED_DIALOG (object); + + switch (prop_id) + { + case PROP_EPHY_EMBED: + g_value_set_object (value, d->priv->embed); + break; + } +} + +EphyEmbedDialog * +ephy_embed_dialog_new (EphyEmbed *embed) +{ + return EPHY_EMBED_DIALOG (g_object_new (EPHY_EMBED_DIALOG_TYPE, + "EphyEmbed", embed, + NULL)); +} + +EphyEmbedDialog * +ephy_embed_dialog_new_with_parent (GtkWidget *parent_window, + EphyEmbed *embed) +{ + return EPHY_EMBED_DIALOG (g_object_new + (EPHY_EMBED_DIALOG_TYPE, + "ParentWindow", parent_window, + "EphyEmbed", embed, + NULL)); +} + +void +ephy_embed_dialog_set_embed (EphyEmbedDialog *dialog, + EphyEmbed *embed) +{ + dialog->priv->embed = embed; +} + +EphyEmbed * +ephy_embed_dialog_get_embed (EphyEmbedDialog *dialog) +{ + if (dialog->priv->embed == NULL) + { + EphyEmbed *embed; + embed = ephy_embed_shell_get_active_embed (embed_shell); + ephy_embed_dialog_set_embed (dialog, embed); + } + + return dialog->priv->embed; +} diff --git a/embed/ephy-embed-dialog.h b/embed/ephy-embed-dialog.h new file mode 100644 index 000000000..e8b7d3a3e --- /dev/null +++ b/embed/ephy-embed-dialog.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_DIALOG_H +#define EPHY_EMBED_DIALOG_H + +#include "ephy-embed.h" +#include "ephy-dialog.h" + +#include <glib-object.h> +#include <glib.h> +#include <gtk/gtkwidget.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedDialogClass EphyEmbedDialogClass; + +#define EPHY_EMBED_DIALOG_TYPE (ephy_embed_dialog_get_type ()) +#define EPHY_EMBED_DIALOG(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_DIALOG_TYPE, EphyEmbedDialog)) +#define EPHY_EMBED_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_EMBED_DIALOG_TYPE, EphyEmbedDialogClass)) +#define IS_EPHY_EMBED_DIALOG(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_DIALOG_TYPE)) +#define IS_EPHY_EMBED_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_DIALOG)) +#define EPHY_EMBED_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_EMBED_DIALOG_TYPE, EphyEmbedDialogClass)) + +typedef struct EphyEmbedDialog EphyEmbedDialog; +typedef struct EphyEmbedDialogPrivate EphyEmbedDialogPrivate; + +struct EphyEmbedDialog +{ + EphyDialog parent; + EphyEmbedDialogPrivate *priv; +}; + +struct EphyEmbedDialogClass +{ + EphyDialogClass parent_class; +}; + +GType ephy_embed_dialog_get_type (void); + +EphyEmbedDialog *ephy_embed_dialog_new (EphyEmbed *embed); + +EphyEmbedDialog *ephy_embed_dialog_new_with_parent (GtkWidget *parent_window, + EphyEmbed *embed); + +void ephy_embed_dialog_set_embed (EphyEmbedDialog *dialog, + EphyEmbed *embed); + +EphyEmbed * ephy_embed_dialog_get_embed (EphyEmbedDialog *dialog); + +G_END_DECLS + +#endif + diff --git a/embed/ephy-embed-event.c b/embed/ephy-embed-event.c new file mode 100644 index 000000000..fdbd53eab --- /dev/null +++ b/embed/ephy-embed-event.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-embed-event.h" + +#include <bonobo/bonobo-i18n.h> +#include <glib/ghash.h> +#include <gtk/gtktypeutils.h> + +struct EphyEmbedEventPrivate +{ + GHashTable *props; +}; + +static void +ephy_embed_event_class_init (EphyEmbedEventClass *klass); +static void +ephy_embed_event_init (EphyEmbedEvent *ges); +static void +ephy_embed_event_finalize (GObject *object); + +static GObjectClass *parent_class = NULL; + +GType +ephy_embed_event_get_type (void) +{ + static GType ephy_embed_event_type = 0; + + if (ephy_embed_event_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedEventClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_embed_event_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyEmbedEvent), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_embed_event_init + }; + + ephy_embed_event_type = g_type_register_static (G_TYPE_OBJECT, + "EphyEmbedEvent", + &our_info, 0); + } + + return ephy_embed_event_type; +} + +static void +ephy_embed_event_class_init (EphyEmbedEventClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_event_finalize; +} + +static void +ephy_embed_event_init (EphyEmbedEvent *event) +{ + event->priv = g_new0 (EphyEmbedEventPrivate, 1); + + event->priv->props = g_hash_table_new (g_str_hash, g_str_equal); +} + +static void +ephy_embed_event_finalize (GObject *object) +{ + EphyEmbedEvent *event; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_EVENT (object)); + + event = EPHY_EMBED_EVENT (object); + + g_return_if_fail (event->priv != NULL); + + g_hash_table_foreach_remove (event->priv->props, + (GHRFunc)g_free, + NULL); + g_hash_table_destroy (event->priv->props); + + g_free (event->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +EphyEmbedEvent * +ephy_embed_event_new (void) +{ + EphyEmbedEvent *event; + + event = EPHY_EMBED_EVENT (g_object_new (EPHY_EMBED_EVENT_TYPE, NULL)); + + g_return_val_if_fail (event->priv != NULL, NULL); + + return event; +} + +guint +ephy_embed_event_get_modifier (EphyEmbedEvent *event) +{ + return event->modifier; +} + +gresult +ephy_embed_event_get_mouse_button (EphyEmbedEvent *event, + guint *mouse_button) +{ + *mouse_button = event->mouse_button; + return G_OK; +} + +gresult +ephy_embed_event_get_mouse_coords (EphyEmbedEvent *event, + guint *x, guint *y) +{ + *x = event->mouse_x; + *y = event->mouse_y; + return G_OK; +} + +gresult +ephy_embed_event_get_context (EphyEmbedEvent *event, + EmbedEventContext *context) +{ + *context = event->context; + return G_OK; +} + +void +ephy_embed_event_set_property (EphyEmbedEvent *event, + const char *name, + GValue *value) +{ + g_hash_table_insert (event->priv->props, + g_strdup (name), + value); +} + +void +ephy_embed_event_get_property (EphyEmbedEvent *event, + const char *name, + GValue **value) +{ + *value = g_hash_table_lookup (event->priv->props, name); +} + +gboolean +ephy_embed_event_has_property (EphyEmbedEvent *event, + const char *name) +{ + gpointer tmp; + + tmp = g_hash_table_lookup (event->priv->props, + name); + + return tmp != NULL; +} diff --git a/embed/ephy-embed-event.h b/embed/ephy-embed-event.h new file mode 100644 index 000000000..1256dcffc --- /dev/null +++ b/embed/ephy-embed-event.h @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_EVENT_H +#define EPHY_EMBED_EVENT_H + +#include "ephy-embed-types.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedEventClass EphyEmbedEventClass; + +#define EPHY_EMBED_EVENT_TYPE (ephy_embed_event_get_type ()) +#define EPHY_EMBED_EVENT(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_EVENT_TYPE, EphyEmbedEvent)) +#define EPHY_EMBED_EVENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_PERSIST_SHELL, EphyEmbedEventClass)) +#define IS_EPHY_EMBED_EVENT(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_EVENT_TYPE)) +#define IS_EPHY_EMBED_EVENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_EVENT)) +#define EPHY_EMBED_EVENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_EMBED_SHELL_TYPE, EphyEmbedEventClass)) + +typedef struct EphyEmbedEvent EphyEmbedEvent; +typedef struct EphyEmbedEventPrivate EphyEmbedEventPrivate; + +typedef enum +{ + EMBED_CONTEXT_NONE = 0, + EMBED_CONTEXT_DEFAULT = 1 << 1, + EMBED_CONTEXT_LINK = 1 << 2, + EMBED_CONTEXT_IMAGE = 1 << 3, + EMBED_CONTEXT_DOCUMENT = 1 << 4, + EMBED_CONTEXT_INPUT = 1 << 5, + EMBED_CONTEXT_XUL = 1 << 7, + EMBED_CONTEXT_EMAIL_LINK = 1 << 8 +} EmbedEventContext; + +struct EphyEmbedEvent +{ + GObject parent; + EphyEmbedEventPrivate *priv; + + /* Public to the embed implementations */ + guint modifier; + guint mouse_button; + guint context; + guint timestamp; + guint mouse_x, mouse_y; +}; + +struct EphyEmbedEventClass +{ + GObjectClass parent_class; +}; + +GType ephy_embed_event_get_type (void); + +EphyEmbedEvent *ephy_embed_event_new (void); + +guint ephy_embed_event_get_modifier (EphyEmbedEvent *event); + +gresult ephy_embed_event_get_mouse_button (EphyEmbedEvent *event, + guint *mouse_button); + +gresult ephy_embed_event_get_mouse_coords (EphyEmbedEvent *event, + guint *x, guint *y); + +gresult ephy_embed_event_get_context (EphyEmbedEvent *event, + EmbedEventContext *context); + +void ephy_embed_event_set_property (EphyEmbedEvent *event, + const char *name, + GValue *value); + +void ephy_embed_event_get_property (EphyEmbedEvent *event, + const char *name, + GValue **value); + +gboolean ephy_embed_event_has_property (EphyEmbedEvent *event, + const char *name); + + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-favicon.c b/embed/ephy-embed-favicon.c new file mode 100644 index 000000000..d88eb91cf --- /dev/null +++ b/embed/ephy-embed-favicon.c @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <string.h> + +#include "ephy-embed-favicon.h" +#include "ephy-embed-shell.h" + +static void ephy_embed_favicon_class_init (EphyEmbedFaviconClass *klass); +static void ephy_embed_favicon_init (EphyEmbedFavicon *ma); +static void ephy_embed_favicon_finalize (GObject *object); +static void ephy_embed_favicon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void ephy_embed_favicon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +struct EphyEmbedFaviconPrivate +{ + EphyEmbed *embed; +}; + +enum +{ + PROP_0, + PROP_EMBED +}; + +static GObjectClass *parent_class = NULL; + +GType +ephy_embed_favicon_get_type (void) +{ + static GType ephy_embed_favicon_type = 0; + + if (ephy_embed_favicon_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedFaviconClass), + NULL, + NULL, + (GClassInitFunc) ephy_embed_favicon_class_init, + NULL, + NULL, + sizeof (EphyEmbedFavicon), + 0, + (GInstanceInitFunc) ephy_embed_favicon_init + }; + + ephy_embed_favicon_type = g_type_register_static (EPHY_TYPE_FAVICON, + "EphyEmbedFavicon", + &our_info, 0); + } + + return ephy_embed_favicon_type; +} + +static void +ephy_embed_favicon_class_init (EphyEmbedFaviconClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_favicon_finalize; + + object_class->set_property = ephy_embed_favicon_set_property; + object_class->get_property = ephy_embed_favicon_get_property; + + g_object_class_install_property (object_class, + PROP_EMBED, + g_param_spec_object ("embed", + "Associated embed", + "Associated embed", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); +} + +static void +ephy_embed_favicon_init (EphyEmbedFavicon *ma) +{ + ma->priv = g_new0 (EphyEmbedFaviconPrivate, 1); +} + +static void +ephy_embed_favicon_finalize (GObject *object) +{ + EphyEmbedFavicon *ma; + + g_return_if_fail (object != NULL); + g_return_if_fail (EPHY_IS_EMBED_FAVICON (object)); + + ma = EPHY_EMBED_FAVICON (object); + + g_return_if_fail (ma->priv != NULL); + + g_free (ma->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +location_changed_cb (EphyEmbed *embed, + EphyEmbedFavicon *favicon) +{ + char *location; + + ephy_embed_get_location (embed, TRUE, FALSE, &location); + ephy_favicon_set_url (EPHY_FAVICON (favicon), location); + + g_free (location); +} + +static void +favicon_cb (EphyEmbed *embed, + const char *favicon_url, + EphyEmbedFavicon *favicon) +{ + char *url = NULL; + EphyFaviconCache *cache; + + if (favicon->priv->embed == NULL) + return; + + ephy_embed_get_location (favicon->priv->embed, TRUE, TRUE, &url); + + g_object_get (G_OBJECT (favicon), + "cache", &cache, + NULL); + + ephy_favicon_cache_insert_from_url (cache, + url, + favicon_url); + + g_object_unref (cache); + + g_free (url); +} + +static void +ephy_embed_favicon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEmbedFavicon *favicon = EPHY_EMBED_FAVICON (object); + + switch (prop_id) + { + case PROP_EMBED: + favicon->priv->embed = g_value_get_object (value); + + if (favicon->priv->embed != NULL) + { + g_signal_connect_object (G_OBJECT (favicon->priv->embed), + "ge_favicon", + G_CALLBACK (favicon_cb), + favicon, + 0); + g_signal_connect_object (G_OBJECT (favicon->priv->embed), + "ge_location", + G_CALLBACK (location_changed_cb), + favicon, + 0); + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_embed_favicon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEmbedFavicon *favicon = EPHY_EMBED_FAVICON (object); + + switch (prop_id) + { + case PROP_EMBED: + g_value_set_object (value, favicon->priv->embed); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +GtkWidget * +ephy_embed_favicon_new (EphyEmbed *embed) +{ + EphyEmbedFavicon *favicon; + EphyFaviconCache *cache = ephy_embed_shell_get_favicon_cache (embed_shell); + + g_return_val_if_fail (EPHY_IS_FAVICON_CACHE (cache), NULL); + + favicon = EPHY_EMBED_FAVICON (g_object_new (EPHY_TYPE_EMBED_FAVICON, + "cache", cache, + "embed", embed, + NULL)); + + g_return_val_if_fail (favicon->priv != NULL, NULL); + + return GTK_WIDGET (favicon); +} + +void +ephy_embed_favicon_set_embed (EphyEmbedFavicon *favicon, + EphyEmbed *embed) +{ + g_return_if_fail (EPHY_IS_EMBED_FAVICON (favicon)); + + g_object_set (G_OBJECT (favicon), + "embed", embed, + NULL); +} + +EphyEmbed * +ephy_embed_favicon_get_embed (EphyEmbedFavicon *favicon) +{ + EphyEmbed *embed; + + g_return_val_if_fail (EPHY_IS_EMBED_FAVICON (favicon), NULL); + + g_object_get (G_OBJECT (favicon), + "embed", &embed, + NULL); + + return embed; +} diff --git a/embed/ephy-embed-favicon.h b/embed/ephy-embed-favicon.h new file mode 100644 index 000000000..36f69cc82 --- /dev/null +++ b/embed/ephy-embed-favicon.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <glib-object.h> +#include <gtk/gtkimage.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +#include "ephy-favicon.h" +#include "ephy-embed.h" + +#ifndef __EPHY_EMBED_FAVICON_H +#define __EPHY_EMBED_FAVICON_H + +G_BEGIN_DECLS + +#define EPHY_TYPE_EMBED_FAVICON (ephy_embed_favicon_get_type ()) +#define EPHY_EMBED_FAVICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_EMBED_FAVICON, EphyEmbedFavicon)) +#define EPHY_EMBED_FAVICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EPHY_TYPE_EMBED_FAVICON, EphyEmbedFaviconClass)) +#define EPHY_IS_EMBED_FAVICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_EMBED_FAVICON)) +#define EPHY_IS_EMBED_FAVICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EMBED_FAVICON)) +#define EPHY_EMBED_FAVICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_EMBED_FAVICON, EphyEmbedFaviconClass)) + +typedef struct EphyEmbedFaviconPrivate EphyEmbedFaviconPrivate; + +typedef struct +{ + EphyFavicon parent; + + EphyEmbedFaviconPrivate *priv; +} EphyEmbedFavicon; + +typedef struct +{ + EphyFaviconClass parent_class; +} EphyEmbedFaviconClass; + +GType ephy_embed_favicon_get_type (void); + +GtkWidget *ephy_embed_favicon_new (EphyEmbed *embed); + +void ephy_embed_favicon_set_embed (EphyEmbedFavicon *favicon, + EphyEmbed *embed); + +EphyEmbed *ephy_embed_favicon_get_embed (EphyEmbedFavicon *favicon); + +G_END_DECLS + +#endif /* __EPHY_EMBED_FAVICON_H */ diff --git a/embed/ephy-embed-persist.c b/embed/ephy-embed-persist.c new file mode 100644 index 000000000..a1d742587 --- /dev/null +++ b/embed/ephy-embed-persist.c @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <config.h> + +#include "ephy-embed-persist.h" + +#include "mozilla-embed.h" +#include "mozilla-embed-persist.h" + +#include <bonobo/bonobo-i18n.h> + +enum +{ + COMPLETED, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_EMBED, + PROP_SOURCE, + PROP_DEST, + PROP_MAX_SIZE, + PROP_FLAGS, + PROP_HANDLER +}; + +struct EphyEmbedPersistPrivate +{ + char *dir; + char *src; + PersistHandlerInfo *handler; + EphyEmbed *embed; + int max_size; + EmbedPersistFlags flags; +}; + +static void +ephy_embed_persist_class_init (EphyEmbedPersistClass *klass); +static void +ephy_embed_persist_init (EphyEmbedPersist *ges); +static void +ephy_embed_persist_finalize (GObject *object); +static void +ephy_embed_persist_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void +ephy_embed_persist_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static gresult +impl_set_source (EphyEmbedPersist *persist, + const char *url); +static gresult +impl_set_dest (EphyEmbedPersist *persist, + const char *dir); +static gresult +impl_set_max_size (EphyEmbedPersist *persist, + int kb_size); +static gresult +impl_set_embed (EphyEmbedPersist *persist, + EphyEmbed *embed); +static gresult +impl_set_flags (EphyEmbedPersist *persist, + EmbedPersistFlags flags); +static gresult +impl_set_handler (EphyEmbedPersist *persist, + const char *command, + gboolean need_terminal); + +static GObjectClass *parent_class = NULL; +static guint ephy_embed_persist_signals[LAST_SIGNAL] = { 0 }; + +GType +ephy_embed_persist_get_type (void) +{ + static GType ephy_embed_persist_type = 0; + + if (ephy_embed_persist_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedPersistClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_embed_persist_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyEmbedPersist), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_embed_persist_init + }; + + ephy_embed_persist_type = g_type_register_static (G_TYPE_OBJECT, + "EphyEmbedPersist", + &our_info, 0); + } + + return ephy_embed_persist_type; +} + +static void +ephy_embed_persist_class_init (EphyEmbedPersistClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_persist_finalize; + object_class->set_property = ephy_embed_persist_set_property; + object_class->get_property = ephy_embed_persist_get_property; + + klass->set_source = impl_set_source; + klass->set_dest = impl_set_dest; + klass->set_embed = impl_set_embed; + klass->set_max_size = impl_set_max_size; + klass->set_flags = impl_set_flags; + klass->set_handler = impl_set_handler; + + /* init signals */ + ephy_embed_persist_signals[COMPLETED] = + g_signal_new ("completed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedPersistClass, completed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_object_class_install_property (object_class, + PROP_EMBED, + g_param_spec_object ("embed", + "Embed", + "The embed containing the document", + G_TYPE_OBJECT, + G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_SOURCE, + g_param_spec_string ("source", + "Source", + "Url of the document to save", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_DEST, + g_param_spec_string ("dest", + "Destination", + "Destination directory", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_MAX_SIZE, + g_param_spec_int ("max_size", + "Maxsize", + "Maximum size of the file", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_FLAGS, + g_param_spec_int ("flags", + "Flags", + "Flags", + 0, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property (object_class, + PROP_HANDLER, + g_param_spec_pointer ("handler", + "Handler", + "Handler", + G_PARAM_READWRITE)); +} + +static void +ephy_embed_persist_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPersist *persist; + PersistHandlerInfo *h; + + persist = EPHY_EMBED_PERSIST (object); + + switch (prop_id) + { + case PROP_EMBED: + ephy_embed_persist_set_embed (persist, + g_value_get_object (value)); + break; + case PROP_SOURCE: + ephy_embed_persist_set_source (persist, + g_value_get_string (value)); + break; + case PROP_DEST: + ephy_embed_persist_set_dest (persist, + g_value_get_string (value)); + break; + case PROP_MAX_SIZE: + ephy_embed_persist_set_max_size (persist, + g_value_get_int (value)); + break; + case PROP_FLAGS: + ephy_embed_persist_set_flags + (persist, + (EmbedPersistFlags)g_value_get_int (value)); + break; + case PROP_HANDLER: + h = (PersistHandlerInfo *)g_value_get_pointer (value); + ephy_embed_persist_set_handler + (persist, h->command, h->need_terminal); + break; + } +} + +static void +ephy_embed_persist_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPersist *persist; + + persist = EPHY_EMBED_PERSIST (object); + + switch (prop_id) + { + case PROP_EMBED: + g_value_set_object (value, persist->priv->embed); + break; + case PROP_SOURCE: + g_value_set_string (value, persist->priv->src); + break; + case PROP_DEST: + g_value_set_string (value, persist->priv->dir); + break; + case PROP_MAX_SIZE: + g_value_set_int (value, persist->priv->max_size); + break; + case PROP_FLAGS: + g_value_set_int (value, (int)persist->priv->flags); + break; + case PROP_HANDLER: + g_value_set_pointer (value, persist->priv->handler); + } +} + +static void +ephy_embed_persist_init (EphyEmbedPersist *persist) +{ + persist->priv = g_new0 (EphyEmbedPersistPrivate, 1); + persist->priv->src = NULL; + persist->priv->dir = NULL; + persist->priv->handler = NULL; +} + +static void +ephy_embed_persist_finalize (GObject *object) +{ + EphyEmbedPersist *persist; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_PERSIST (object)); + + persist = EPHY_EMBED_PERSIST (object); + + g_return_if_fail (persist->priv != NULL); + + g_free (persist->priv->dir); + g_free (persist->priv->src); + + if (persist->priv->handler) + { + g_free (persist->priv->handler->command); + g_free (persist->priv->handler); + } + + g_free (persist->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + + +EphyEmbedPersist * +ephy_embed_persist_new (EphyEmbed *embed) +{ + EphyEmbedPersist *persist; + GType type = 0; + + type = MOZILLA_EMBED_PERSIST_TYPE; + + g_assert (type != 0); + + persist = EPHY_EMBED_PERSIST (g_object_new (type, + "embed", embed, + NULL)); + + g_return_val_if_fail (persist->priv != NULL, NULL); + + return persist; +} + +gresult +ephy_embed_persist_set_source (EphyEmbedPersist *persist, + const char *url) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_source (persist, url); +} + +gresult +ephy_embed_persist_get_source (EphyEmbedPersist *persist, + const char **url) +{ + *url = persist->priv->src; + + return G_OK; +} + +gresult +ephy_embed_persist_get_dest (EphyEmbedPersist *persist, + const char **dir) +{ + *dir = persist->priv->dir; + + return G_OK; +} + +gresult +ephy_embed_persist_set_dest (EphyEmbedPersist *persist, + const char *dir) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_dest (persist, dir); +} + +gresult +ephy_embed_persist_save (EphyEmbedPersist *persist) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->save (persist); +} + +gresult +ephy_embed_persist_set_max_size (EphyEmbedPersist *persist, + int kb_size) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_max_size (persist, kb_size); +} + +gresult +ephy_embed_persist_set_embed (EphyEmbedPersist *persist, + EphyEmbed *embed) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_embed (persist, embed); +} + +gresult +ephy_embed_persist_get_embed (EphyEmbedPersist *persist, + EphyEmbed **embed) +{ + *embed = persist->priv->embed; + + return G_OK; +} + +gresult +ephy_embed_persist_set_flags (EphyEmbedPersist *persist, + EmbedPersistFlags flags) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_flags (persist, flags); +} + +gresult +ephy_embed_persist_get_flags (EphyEmbedPersist *persist, + EmbedPersistFlags *flags) +{ + *flags = persist->priv->flags= persist->priv->flags; + + return G_OK; +} + +gresult +ephy_embed_persist_set_handler (EphyEmbedPersist *persist, + const char *command, + gboolean need_terminal) +{ + EphyEmbedPersistClass *klass = EPHY_EMBED_PERSIST_GET_CLASS (persist); + return klass->set_handler (persist, command, need_terminal); +} + +static gresult +impl_set_handler (EphyEmbedPersist *persist, + const char *command, + gboolean need_terminal) +{ + persist->priv->handler = g_new0 (PersistHandlerInfo, 1); + persist->priv->handler->command = g_strdup (command); + persist->priv->handler->need_terminal = need_terminal; + + g_object_notify (G_OBJECT(persist), "handler"); + + return G_OK; +} + +static gresult +impl_set_flags (EphyEmbedPersist *persist, + EmbedPersistFlags flags) +{ + persist->priv->flags = flags; + + g_object_notify (G_OBJECT(persist), "flags"); + + return G_OK; +} + +static gresult +impl_set_source (EphyEmbedPersist *persist, + const char *url) +{ + persist->priv->src = g_strdup(url); + + g_object_notify (G_OBJECT(persist), "source"); + + return G_OK; +} + +static gresult +impl_set_dest (EphyEmbedPersist *persist, + const char *dir) +{ + persist->priv->dir = g_strdup (dir); + + g_object_notify (G_OBJECT(persist), "dest"); + + return G_OK; +} + +static gresult +impl_set_max_size (EphyEmbedPersist *persist, + int kb_size) +{ + persist->priv->max_size = kb_size; + + g_object_notify (G_OBJECT(persist), "max_size"); + + return G_OK; +} + +static gresult +impl_set_embed (EphyEmbedPersist *persist, + EphyEmbed *embed) +{ + persist->priv->embed = embed; + + g_object_notify (G_OBJECT(persist), "embed"); + + return G_OK; +} diff --git a/embed/ephy-embed-persist.h b/embed/ephy-embed-persist.h new file mode 100644 index 000000000..2ad883647 --- /dev/null +++ b/embed/ephy-embed-persist.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_PERSIST_H +#define EPHY_EMBED_PERSIST_H + +#include "ephy-embed.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedPersistClass EphyEmbedPersistClass; + +#define EPHY_EMBED_PERSIST_TYPE (ephy_embed_persist_get_type ()) +#define EPHY_EMBED_PERSIST(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_PERSIST_TYPE, EphyEmbedPersist)) +#define EPHY_EMBED_PERSIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_EMBED_PERSIST_TYPE, EphyEmbedPersistClass)) +#define IS_EPHY_EMBED_PERSIST(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_PERSIST_TYPE)) +#define IS_EPHY_EMBED_PERSIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_PERSIST)) +#define EPHY_EMBED_PERSIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_EMBED_PERSIST_TYPE, EphyEmbedPersistClass)) + +typedef struct EphyEmbedPersist EphyEmbedPersist; +typedef struct EphyEmbedPersistPrivate EphyEmbedPersistPrivate; + +typedef enum +{ + EMBED_PERSIST_SHOW_PROGRESS = 1 << 0, + EMBED_PERSIST_SAVE_CONTENT = 1 << 1, + EMBED_PERSIST_FROMCACHE = 1 << 2, + EMBED_PERSIST_BYPASSCACHE = 1 << 3, + EMBED_PERSIST_MAINDOC = 1 << 4 +} EmbedPersistFlags; + +typedef struct +{ + char *command; + gboolean need_terminal; +} PersistHandlerInfo; + +struct EphyEmbedPersist +{ + GObject parent; + EphyEmbedPersistPrivate *priv; +}; + +struct EphyEmbedPersistClass +{ + GObjectClass parent_class; + + void (* completed) (EphyEmbedPersist *persist); + + /* Methods */ + + gresult (* set_source) (EphyEmbedPersist *persist, + const char *url); + gresult (* set_dest) (EphyEmbedPersist *persist, + const char *dir); + gresult (* save) (EphyEmbedPersist *persist); + + gresult (* set_max_size) (EphyEmbedPersist *persist, + int max_size); + + gresult (* set_embed) (EphyEmbedPersist *persist, + EphyEmbed *embed); + + gresult (* set_flags) (EphyEmbedPersist *persist, + EmbedPersistFlags flags); + + gresult (* set_handler) (EphyEmbedPersist *persist, + const char *command, + gboolean need_terminal); +}; + +GType ephy_embed_persist_get_type (void); + +EphyEmbedPersist *ephy_embed_persist_new (EphyEmbed *embed); + +gresult ephy_embed_persist_set_source (EphyEmbedPersist *persist, + const char *url); + +gresult ephy_embed_persist_get_source (EphyEmbedPersist *persist, + const char **url); + +gresult ephy_embed_persist_set_dest (EphyEmbedPersist *persist, + const char *dir); + +gresult ephy_embed_persist_get_dest (EphyEmbedPersist *persist, + const char **dir); + +gresult ephy_embed_persist_set_handler (EphyEmbedPersist *persist, + const char *handler, + gboolean need_terminal); + +gresult ephy_embed_persist_set_max_size (EphyEmbedPersist *persist, + int kb_size); + +gresult ephy_embed_persist_set_embed (EphyEmbedPersist *persist, + EphyEmbed *embed); + +gresult ephy_embed_persist_get_embed (EphyEmbedPersist *persist, + EphyEmbed **embed); + +gresult ephy_embed_persist_set_flags (EphyEmbedPersist *persist, + EmbedPersistFlags flags); + +gresult ephy_embed_persist_get_flags (EphyEmbedPersist *persist, + EmbedPersistFlags *flags); + +gresult ephy_embed_persist_save (EphyEmbedPersist *persist); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-popup-bw.c b/embed/ephy-embed-popup-bw.c new file mode 100644 index 000000000..553f73205 --- /dev/null +++ b/embed/ephy-embed-popup-bw.c @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-embed-popup-bw.h" +#include "ephy-gobject-misc.h" + +#include <gtk/gtkmain.h> + +enum +{ + PROP_0, + PROP_BONOBO_WINDOW +}; + +struct EphyEmbedPopupBWPrivate +{ + BonoboWindow *window; + GtkWidget *menu; +}; + +static void +ephy_embed_popup_bw_class_init (EphyEmbedPopupBWClass *klass); +static void +ephy_embed_popup_bw_init (EphyEmbedPopupBW *gep); +static void +ephy_embed_popup_bw_finalize (GObject *object); +static void +ephy_embed_popup_bw_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void +ephy_embed_popup_bw_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void +ephy_embed_popup_bw_set_window (EphyEmbedPopupBW *p, + BonoboWindow *window); +static void +ephy_embed_popup_bw_show_impl (EphyEmbedPopup *p, + EphyEmbed *embed); + +static EphyEmbedPopupClass *parent_class = NULL; + +MAKE_GET_TYPE (ephy_embed_popup_bw, "EphyEmbedPopupBW", EphyEmbedPopupBW, + ephy_embed_popup_bw_class_init, ephy_embed_popup_bw_init, EPHY_EMBED_POPUP_TYPE); + +static void +ephy_embed_popup_bw_class_init (EphyEmbedPopupBWClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = EPHY_EMBED_POPUP_CLASS (g_type_class_peek_parent (klass)); + + object_class->finalize = ephy_embed_popup_bw_finalize; + object_class->set_property = ephy_embed_popup_bw_set_property; + object_class->get_property = ephy_embed_popup_bw_get_property; + + g_object_class_install_property (object_class, + PROP_BONOBO_WINDOW, + g_param_spec_object ("BonoboWindow", + "BonoboWindow", + "Bonobo window", + BONOBO_TYPE_WINDOW, + G_PARAM_READWRITE)); + + EPHY_EMBED_POPUP_CLASS (klass)->show = ephy_embed_popup_bw_show_impl; +} + +static void +ephy_embed_popup_bw_init (EphyEmbedPopupBW *gep) +{ + gep->priv = g_new0 (EphyEmbedPopupBWPrivate, 1); + gep->priv->window = NULL; + gep->priv->menu = NULL; +} + +static void +ephy_embed_popup_bw_finalize (GObject *object) +{ + EphyEmbedPopupBW *gep; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_POPUP_BW (object)); + + gep = EPHY_EMBED_POPUP_BW (object); + + g_return_if_fail (gep->priv != NULL); + + g_free (gep->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_embed_popup_bw_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPopupBW *p = EPHY_EMBED_POPUP_BW (object); + + switch (prop_id) + { + case PROP_BONOBO_WINDOW: + ephy_embed_popup_bw_set_window (p, g_value_get_object (value)); + break; + } +} + +static void +ephy_embed_popup_bw_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPopupBW *p = EPHY_EMBED_POPUP_BW (object); + + switch (prop_id) + { + case PROP_BONOBO_WINDOW: + g_value_set_object (value, p->priv->window); + break; + } +} + +static void +ephy_embed_popup_bw_set_window (EphyEmbedPopupBW *p, + BonoboWindow *window) +{ + p->priv->window = window; +} + +EphyEmbedPopupBW * +ephy_embed_popup_bw_new (BonoboWindow *window) +{ + EphyEmbedPopupBW *p; + + p = EPHY_EMBED_POPUP_BW (g_object_new (EPHY_EMBED_POPUP_BW_TYPE, + "BonoboWindow", window, + NULL)); + + g_return_val_if_fail (p->priv != NULL, NULL); + + return p; +} + +static void +ephy_embed_popup_bw_show_impl (EphyEmbedPopup *pp, + EphyEmbed *embed) +{ + EphyEmbedPopupBW *p = EPHY_EMBED_POPUP_BW (pp); + EphyEmbedEvent *event = ephy_embed_popup_get_event (pp); + guint button; + + ephy_embed_popup_set_embed (pp, embed); + + ephy_embed_event_get_mouse_button (event, &button); + + p->priv->menu = gtk_menu_new (); + gtk_widget_show (p->priv->menu); + + bonobo_window_add_popup (p->priv->window, + GTK_MENU (p->priv->menu), + ephy_embed_popup_get_popup_path (EPHY_EMBED_POPUP (p))); + + gtk_menu_popup (GTK_MENU (p->priv->menu), + NULL, NULL, NULL, NULL, + button, gtk_get_current_event_time ()); +} + diff --git a/embed/ephy-embed-popup-bw.h b/embed/ephy-embed-popup-bw.h new file mode 100644 index 000000000..49f8fecd5 --- /dev/null +++ b/embed/ephy-embed-popup-bw.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_POPUP_BW_H +#define EPHY_EMBED_POPUP_BW_H + +#include "ephy-embed-popup.h" +#include <bonobo/bonobo-window.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedPopupBWClass EphyEmbedPopupBWClass; + +#define EPHY_EMBED_POPUP_BW_TYPE (ephy_embed_popup_bw_get_type ()) +#define EPHY_EMBED_POPUP_BW(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_POPUP_BW_TYPE, \ + EphyEmbedPopupBW)) +#define EPHY_EMBED_POPUP_BW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_EMBED_POPUP_BW_TYPE,\ + EphyEmbedPopupBWClass)) +#define IS_EPHY_EMBED_POPUP_BW(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_POPUP_BW_TYPE)) +#define IS_EPHY_EMBED_POPUP_BW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_POPUP_BW)) +#define EPHY_EMBED_POPUP_BW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + EPHY_EMBED_POPUP_BW_TYPE, EphyEmbedPopupBWClass)) + +typedef struct EphyEmbedPopupBW EphyEmbedPopupBW; +typedef struct EphyEmbedPopupBWPrivate EphyEmbedPopupBWPrivate; + +struct EphyEmbedPopupBW +{ + EphyEmbedPopup parent; + EphyEmbedPopupBWPrivate *priv; +}; + +struct EphyEmbedPopupBWClass +{ + EphyEmbedPopupClass parent_class; +}; + +GType ephy_embed_popup_bw_get_type (void); +EphyEmbedPopupBW * ephy_embed_popup_bw_new (BonoboWindow *window); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-popup-control.c b/embed/ephy-embed-popup-control.c new file mode 100644 index 000000000..a74249cc8 --- /dev/null +++ b/embed/ephy-embed-popup-control.c @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2000, 2001, 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-embed-popup-control.h" +#include "ephy-gobject-misc.h" +#include "ephy-bonobo-extensions.h" + +#include <gtk/gtkmain.h> + +enum +{ + PROP_0, + PROP_BONOBO_CONTROL +}; + +struct EphyEmbedPopupControlPrivate +{ + BonoboControl *control; +}; + +static void +ephy_embed_popup_control_class_init (EphyEmbedPopupControlClass *klass); +static void +ephy_embed_popup_control_init (EphyEmbedPopupControl *gep); +static void +ephy_embed_popup_control_finalize (GObject *object); +static void +ephy_embed_popup_control_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void +ephy_embed_popup_control_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void +ephy_embed_popup_control_set_control (EphyEmbedPopupControl *p, + BonoboControl *control); +static void +ephy_embed_popup_control_show_impl (EphyEmbedPopup *p, + EphyEmbed *embed); + +static EphyEmbedPopupClass *parent_class = NULL; + +MAKE_GET_TYPE (ephy_embed_popup_control, "EphyEmbedPopupControl", EphyEmbedPopupControl, + ephy_embed_popup_control_class_init, ephy_embed_popup_control_init, + EPHY_EMBED_POPUP_TYPE); + +static void +ephy_embed_popup_control_class_init (EphyEmbedPopupControlClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = EPHY_EMBED_POPUP_CLASS (g_type_class_peek_parent (klass)); + + object_class->finalize = ephy_embed_popup_control_finalize; + object_class->set_property = ephy_embed_popup_control_set_property; + object_class->get_property = ephy_embed_popup_control_get_property; + + g_object_class_install_property (object_class, + PROP_BONOBO_CONTROL, + g_param_spec_object ("BonoboControl", + "BonoboControl", + "Bonobo control", + BONOBO_TYPE_CONTROL, + G_PARAM_READWRITE)); + + EPHY_EMBED_POPUP_CLASS (klass)->show = ephy_embed_popup_control_show_impl; +} + +static void +ephy_embed_popup_control_init (EphyEmbedPopupControl *gep) +{ + gep->priv = g_new0 (EphyEmbedPopupControlPrivate, 1); + gep->priv->control = NULL; +} + +static void +ephy_embed_popup_control_finalize (GObject *object) +{ + EphyEmbedPopupControl *gep; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_POPUP_CONTROL (object)); + + gep = EPHY_EMBED_POPUP_CONTROL (object); + + g_return_if_fail (gep->priv != NULL); + + g_free (gep->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_embed_popup_control_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPopupControl *p = EPHY_EMBED_POPUP_CONTROL (object); + + switch (prop_id) + { + case PROP_BONOBO_CONTROL: + ephy_embed_popup_control_set_control (p, g_value_get_object (value)); + break; + } +} + +static void +ephy_embed_popup_control_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyEmbedPopupControl *p = EPHY_EMBED_POPUP_CONTROL (object); + + switch (prop_id) + { + case PROP_BONOBO_CONTROL: + g_value_set_object (value, p->priv->control); + break; + } +} + +static void +ephy_embed_popup_control_set_control (EphyEmbedPopupControl *p, + BonoboControl *control) +{ + p->priv->control = control; +} + +EphyEmbedPopupControl * +ephy_embed_popup_control_new (BonoboControl *control) +{ + EphyEmbedPopupControl *p; + + p = EPHY_EMBED_POPUP_CONTROL (g_object_new (EPHY_EMBED_POPUP_CONTROL_TYPE, + "BonoboControl", control, + NULL)); + + g_return_val_if_fail (p->priv != NULL, NULL); + + return p; +} + +static void +ephy_embed_popup_control_show_impl (EphyEmbedPopup *pp, + EphyEmbed *embed) +{ + EphyEmbedPopupControl *p = EPHY_EMBED_POPUP_CONTROL (pp); + EphyEmbedEvent *event = ephy_embed_popup_get_event (pp); + BonoboUIComponent *uic = bonobo_control_get_popup_ui_component (p->priv->control); + const char *path; + char *path_dst; + guint button; + + ephy_embed_event_get_mouse_button (event, &button); + ephy_embed_popup_set_embed (pp, embed); + path = ephy_embed_popup_get_popup_path (pp); + path_dst = g_strdup_printf ("/popups/button%d", button); + + /* this is a hack because bonobo apis for showing popups are broken */ + ephy_bonobo_replace_path (uic, path, path_dst); + + bonobo_control_do_popup (p->priv->control, button, + gtk_get_current_event_time ()); + + g_free (path_dst); +} + diff --git a/embed/ephy-embed-popup-control.h b/embed/ephy-embed-popup-control.h new file mode 100644 index 000000000..4f45efe5f --- /dev/null +++ b/embed/ephy-embed-popup-control.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2000, 2001, 2002 Ricardo Fernández Pascual + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_POPUP_CONTROL_H +#define EPHY_EMBED_POPUP_CONTROL_H + +#include "ephy-embed-popup.h" +#include <bonobo/bonobo-control.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedPopupControlClass EphyEmbedPopupControlClass; + +#define EPHY_EMBED_POPUP_CONTROL_TYPE (ephy_embed_popup_control_get_type ()) +#define EPHY_EMBED_POPUP_CONTROL(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_POPUP_CONTROL_TYPE, \ + EphyEmbedPopupControl)) +#define EPHY_EMBED_POPUP_CONTROL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), \ + EPHY_EMBED_POPUP_CONTROL_TYPE,\ + EphyEmbedPopupControlClass)) +#define IS_EPHY_EMBED_POPUP_CONTROL(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_POPUP_CONTROL_TYPE)) +#define IS_EPHY_EMBED_POPUP_CONTROL_CLASS(klass)(GTK_CHECK_CLASS_TYPE ((klass), \ + EPHY_EMBED_POPUP_CONTROL)) +#define EPHY_EMBED_POPUP_CONTROL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), \ + EPHY_EMBED_POPUP_CONTROL_TYPE, \ + EphyEmbedPopupControlClass)) + +typedef struct EphyEmbedPopupControl EphyEmbedPopupControl; +typedef struct EphyEmbedPopupControlPrivate EphyEmbedPopupControlPrivate; + +struct EphyEmbedPopupControl +{ + EphyEmbedPopup parent; + EphyEmbedPopupControlPrivate *priv; +}; + +struct EphyEmbedPopupControlClass +{ + EphyEmbedPopupClass parent_class; +}; + +GType ephy_embed_popup_control_get_type (void); +EphyEmbedPopupControl *ephy_embed_popup_control_new (BonoboControl *control); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-popup.c b/embed/ephy-embed-popup.c new file mode 100644 index 000000000..4710fa211 --- /dev/null +++ b/embed/ephy-embed-popup.c @@ -0,0 +1,623 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-embed-popup.h" +#include "ephy-embed-event.h" +#include "ephy-embed-utils.h" +#include "ephy-prefs.h" +#include "eel-gconf-extensions.h" +#include "ephy-bonobo-extensions.h" +#include "ephy-file-helpers.h" + +#include <string.h> +#include <bonobo/bonobo-ui-component.h> +#include <gtk/gtkclipboard.h> +#include <libgnome/gnome-exec.h> + +typedef enum +{ + EMBED_POPUP_INPUT, + EMBED_POPUP_DOCUMENT, + EMBED_POPUP_ELEMENT +} EmbedPopupType; + +struct EphyEmbedPopupPrivate +{ + EphyEmbedEvent *event; + EphyEmbed *embed; + EmbedEventContext context; + BonoboUIComponent *ui_component; + char *selection; + EmbedPopupType popup_type; +}; + +static void +ephy_embed_popup_class_init (EphyEmbedPopupClass *klass); +static void +ephy_embed_popup_init (EphyEmbedPopup *gep); +static void +ephy_embed_popup_finalize (GObject *object); +static void +embed_popup_copy_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_copy_email_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_copy_link_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_download_link_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_save_image_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_set_image_as_background_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_copy_image_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_save_page_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_save_background_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_open_frame_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_reload_frame_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); + +static void +embed_popup_open_image_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname); +static void +embed_popup_copy_to_clipboard (EphyEmbedPopup *popup, const char *text); + +static GObjectClass *parent_class = NULL; + +#define DOCUMENT_POPUP_PATH "/popups/EphyEmbedDocumentPopup" +#define ELEMENT_POPUP_PATH "/popups/EphyEmbedElementPopup" +#define INPUT_POPUP_PATH "/popups/EphyEmbedInputPopup" + +#define EPHY_POPUP_NAVIGATION_ITEMS_PLACEHOLDER "/popups/EphyEmbedDocumentPopup/NavigationItems" +#define EPHY_POPUP_LINK_ITEMS_PLACEHOLDER "/popups/EphyEmbedElementPopup/LinkItems" +#define EPHY_POPUP_EMAIL_LINK_ITEMS_PLACEHOLDER "/popups/EphyEmbedElementPopup/EmailLinkItems" +#define EPHY_POPUP_IMAGE_ITEMS_PLACEHOLDER "/popups/EphyEmbedElementPopup/ImageItems" +#define EPHY_POPUP_FRAME_ITEMS_PLACEHOLDER "/popups/EphyEmbedDocumentPopup/FrameItems" +#define EPHY_POPUP_BETWEEN_ELEMENTS1_PLACEHOLDER "/popups/EphyEmbedElementPopup/BetweenElements1" +#define EPHY_POPUP_SAVE_BG_PATH "/commands/DPSaveBackgroundAs" +#define EPHY_POPUP_OPEN_IMAGE_PATH "/commands/EPOpenImage" + +BonoboUIVerb embed_popup_verbs [] = { + BONOBO_UI_VERB ("EPCopyLinkLocation", (BonoboUIVerbFn)embed_popup_copy_link_location_cmd), + BONOBO_UI_VERB ("EPDownloadLink", (BonoboUIVerbFn)embed_popup_download_link_cmd), + BONOBO_UI_VERB ("EPOpenImage", (BonoboUIVerbFn)embed_popup_open_image_cmd), + BONOBO_UI_VERB ("EPSaveImageAs", (BonoboUIVerbFn)embed_popup_save_image_as_cmd), + BONOBO_UI_VERB ("EPSetImageAsBackground", (BonoboUIVerbFn)embed_popup_set_image_as_background_cmd), + BONOBO_UI_VERB ("EPCopyImageLocation", (BonoboUIVerbFn)embed_popup_copy_image_location_cmd), + + BONOBO_UI_VERB ("DPCopyLocation", (BonoboUIVerbFn)embed_popup_copy_location_cmd), + BONOBO_UI_VERB ("EPCopyEmail", (BonoboUIVerbFn)embed_popup_copy_email_cmd), + BONOBO_UI_VERB ("DPSavePageAs", (BonoboUIVerbFn)embed_popup_save_page_as_cmd), + BONOBO_UI_VERB ("DPSaveBackgroundAs", (BonoboUIVerbFn)embed_popup_save_background_as_cmd), + BONOBO_UI_VERB ("DPOpenFrame", (BonoboUIVerbFn)embed_popup_open_frame_cmd), + BONOBO_UI_VERB ("DPReloadFrame", (BonoboUIVerbFn)embed_popup_reload_frame_cmd), + + BONOBO_UI_VERB_END +}; + +GType +ephy_embed_popup_get_type (void) +{ + static GType ephy_embed_popup_type = 0; + + if (ephy_embed_popup_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedPopupClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_embed_popup_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyEmbedPopup), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_embed_popup_init + }; + + + ephy_embed_popup_type = g_type_register_static (G_TYPE_OBJECT, + "EphyEmbedPopup", + &our_info, 0); + } + + return ephy_embed_popup_type; +} + +static void +ephy_embed_popup_class_init (EphyEmbedPopupClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_popup_finalize; + + klass->show = NULL; /* abstract */ +} + +static void +ephy_embed_popup_init (EphyEmbedPopup *gep) +{ + gep->priv = g_new0 (EphyEmbedPopupPrivate, 1); + gep->priv->embed = NULL; + gep->priv->event = NULL; + gep->priv->ui_component = NULL; +} + +static void +ephy_embed_popup_finalize (GObject *object) +{ + EphyEmbedPopup *gep; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_POPUP (object)); + + gep = EPHY_EMBED_POPUP (object); + + g_return_if_fail (gep->priv != NULL); + + if (gep->priv->event) + { + g_object_unref (G_OBJECT (gep->priv->event)); + } + + g_free (gep->priv->selection); + + g_free (gep->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +setup_element_menu (EphyEmbedPopup *p) +{ + gboolean is_link, is_image, is_email_link; + + is_image = p->priv->context & EMBED_CONTEXT_IMAGE; + is_email_link = p->priv->context & EMBED_CONTEXT_EMAIL_LINK; + is_link = (p->priv->context & EMBED_CONTEXT_LINK) && !is_email_link; + + ephy_bonobo_set_hidden (p->priv->ui_component, + EPHY_POPUP_LINK_ITEMS_PLACEHOLDER, + !is_link); + ephy_bonobo_set_hidden (p->priv->ui_component, + EPHY_POPUP_IMAGE_ITEMS_PLACEHOLDER, + !is_image); + ephy_bonobo_set_hidden (p->priv->ui_component, + EPHY_POPUP_EMAIL_LINK_ITEMS_PLACEHOLDER, + !is_email_link); + ephy_bonobo_set_hidden (p->priv->ui_component, + EPHY_POPUP_BETWEEN_ELEMENTS1_PLACEHOLDER, + !is_image || (!is_link && !is_email_link)); +} + +static void +setup_document_menu (EphyEmbedPopup *p) +{ + gboolean is_framed; + GValue *value; + gboolean has_background; + + ephy_embed_event_get_property (p->priv->event, + "framed_page", &value); + is_framed = g_value_get_int (value); + ephy_bonobo_set_hidden (BONOBO_UI_COMPONENT(p->priv->ui_component), + EPHY_POPUP_FRAME_ITEMS_PLACEHOLDER, !is_framed); + + has_background = ephy_embed_event_has_property (p->priv->event, + "background_image"); + ephy_bonobo_set_hidden (BONOBO_UI_COMPONENT(p->priv->ui_component), + EPHY_POPUP_SAVE_BG_PATH, !has_background); +} + +void +ephy_embed_popup_set_event (EphyEmbedPopup *p, + EphyEmbedEvent *event) +{ + EmbedEventContext context; + + if (p->priv->event) + { + g_object_unref (G_OBJECT (p->priv->event)); + } + + ephy_embed_event_get_context (event, &context); + + p->priv->context = context; + + p->priv->event = event; + g_object_ref (G_OBJECT(event)); + + if ((p->priv->context & EMBED_CONTEXT_LINK) || + (p->priv->context & EMBED_CONTEXT_EMAIL_LINK) || + (p->priv->context & EMBED_CONTEXT_IMAGE)) + { + setup_element_menu (p); + p->priv->popup_type = EMBED_POPUP_ELEMENT; + } + else if (p->priv->context & EMBED_CONTEXT_INPUT) + { + p->priv->popup_type = EMBED_POPUP_INPUT; + } + else + { + setup_document_menu (p); + p->priv->popup_type = EMBED_POPUP_DOCUMENT; + } +} + +void +ephy_embed_popup_set_embed (EphyEmbedPopup *p, + EphyEmbed *e) +{ + p->priv->embed = e; +} + +EphyEmbed * +ephy_embed_popup_get_embed (EphyEmbedPopup *p) +{ + return p->priv->embed; +} + +void +ephy_embed_popup_show (EphyEmbedPopup *p, + EphyEmbed *embed) +{ + EphyEmbedPopupClass *klass = EPHY_EMBED_POPUP_GET_CLASS (p); + return klass->show (p, embed); + +} + +void +ephy_embed_popup_connect_verbs (EphyEmbedPopup *p, + BonoboUIComponent *ui_component) +{ + + p->priv->ui_component = BONOBO_UI_COMPONENT (ui_component); + + bonobo_ui_component_add_verb_list_with_data (BONOBO_UI_COMPONENT(ui_component), + embed_popup_verbs, + p); +} + +EphyEmbedEvent * +ephy_embed_popup_get_event (EphyEmbedPopup *p) +{ + g_return_val_if_fail (IS_EPHY_EMBED_POPUP (p), NULL); + + return p->priv->event; +} + +static void +embed_popup_copy_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + char *location; + ephy_embed_get_location (popup->priv->embed, FALSE, + FALSE, &location); + embed_popup_copy_to_clipboard (popup, location); + g_free (location); +} + +static void +embed_popup_copy_email_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + EphyEmbedEvent *info; + const char *location; + GValue *value; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, "email", &value); + location = g_value_get_string (value); + embed_popup_copy_to_clipboard (popup, location); +} + +static void +embed_popup_copy_link_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + EphyEmbedEvent *info; + const char *location; + GValue *value; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, "link", &value); + location = g_value_get_string (value); + embed_popup_copy_to_clipboard (popup, location); +} + +static void +save_property_url (EphyEmbedPopup *popup, + gboolean ask_dest, + gboolean show_progress, + const char *property) +{ + EphyEmbedEvent *info; + const char *location; + GValue *value; + GtkWidget *widget; + GtkWidget *window; + EphyEmbedPersist *persist; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, property, &value); + location = g_value_get_string (value); + + widget = GTK_WIDGET (popup->priv->embed); + window = gtk_widget_get_toplevel (widget); + + persist = ephy_embed_persist_new (popup->priv->embed); + + ephy_embed_persist_set_source (persist, location); + + if (show_progress) + { + ephy_embed_persist_set_flags (persist, + EMBED_PERSIST_SHOW_PROGRESS); + } + + ephy_embed_utils_save (window, + CONF_STATE_DOWNLOADING_DIR, + ask_dest, + FALSE, + persist); +} + +const char * +ephy_embed_popup_get_popup_path (EphyEmbedPopup *p) +{ + const char *result = NULL; + + switch (p->priv->popup_type) + { + case EMBED_POPUP_INPUT: + result = INPUT_POPUP_PATH; + break; + case EMBED_POPUP_ELEMENT: + result = ELEMENT_POPUP_PATH; + break; + case EMBED_POPUP_DOCUMENT: + result = DOCUMENT_POPUP_PATH; + break; + } + + return result; +} + +/* commands */ + +static void +embed_popup_download_link_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + save_property_url (popup, + eel_gconf_get_boolean + (CONF_STATE_DOWNLOADING_DIR), + TRUE, "link"); +} + +static void +embed_popup_save_image_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + save_property_url (popup, TRUE, FALSE, "image"); +} + +#define CONF_DESKTOP_BG_PICTURE "/desktop/gnome/background/picture_filename" +#define CONF_DESKTOP_BG_TYPE "/desktop/gnome/background/picture_options" + +static void +background_download_completed (EphyEmbedPersist *persist, + gpointer data) +{ + const char *bg; + char *type; + + ephy_embed_persist_get_dest (persist, &bg); + eel_gconf_set_string (CONF_DESKTOP_BG_PICTURE, bg); + + type = eel_gconf_get_string (CONF_DESKTOP_BG_TYPE); + if (type || strcmp (type, "none") == 0) + { + eel_gconf_set_string (CONF_DESKTOP_BG_TYPE, + "wallpaper"); + } + + g_free (type); + + g_object_unref (persist); +} + +static void +embed_popup_set_image_as_background_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + EphyEmbedEvent *info; + const char *location; + char *dest, *base; + GValue *value; + EphyEmbedPersist *persist; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, "image", &value); + location = g_value_get_string (value); + + persist = ephy_embed_persist_new (popup->priv->embed); + + base = g_path_get_basename (location); + dest = g_build_filename (ephy_dot_dir (), + base, NULL); + + ephy_embed_persist_set_source (persist, location); + ephy_embed_persist_set_dest (persist, dest); + + ephy_embed_persist_save (persist); + + g_signal_connect (persist, "completed", + G_CALLBACK (background_download_completed), + NULL); + + g_free (dest); + g_free (base); +} + +static void +embed_popup_copy_image_location_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + EphyEmbedEvent *info; + const char *location; + GValue *value; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, "image", &value); + location = g_value_get_string (value); + embed_popup_copy_to_clipboard (popup, location); +} + +static void +save_url (EphyEmbedPopup *popup, + gboolean ask_dest, + gboolean show_progress, + const char *url) +{ + GtkWidget *widget; + GtkWidget *window; + EphyEmbedPersist *persist; + + widget = GTK_WIDGET (popup->priv->embed); + window = gtk_widget_get_toplevel (widget); + + persist = ephy_embed_persist_new (popup->priv->embed); + ephy_embed_persist_set_source (persist, url); + + if (show_progress) + { + ephy_embed_persist_set_flags (persist, + EMBED_PERSIST_SHOW_PROGRESS); + } + + ephy_embed_utils_save (window, + CONF_STATE_DOWNLOADING_DIR, + ask_dest, + FALSE, + persist); +} + +static void +embed_popup_save_page_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + char *location; + + ephy_embed_get_location (popup->priv->embed, + FALSE, FALSE, &location); + save_url (popup, TRUE, FALSE, location); + g_free (location); +} + +static void +embed_popup_save_background_as_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + save_property_url (popup, TRUE, FALSE, "background_image"); +} + +static void +embed_popup_open_frame_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + char *location; + + ephy_embed_get_location (popup->priv->embed, + FALSE, FALSE, &location); + + ephy_embed_load_url (popup->priv->embed, location); +} + +static void +embed_popup_reload_frame_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + /* FIXME implement */ +} + +static void +embed_popup_open_image_cmd (BonoboUIComponent *uic, + EphyEmbedPopup *popup, + const char* verbname) +{ + EphyEmbedEvent *info; + const char *location; + GValue *value; + + info = ephy_embed_popup_get_event (popup); + ephy_embed_event_get_property (info, "image", &value); + location = g_value_get_string (value); + + ephy_embed_load_url (popup->priv->embed, location); +} + +static void +embed_popup_copy_to_clipboard (EphyEmbedPopup *popup, const char *text) +{ + gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), + text, -1); + gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY), + text, -1); +} diff --git a/embed/ephy-embed-popup.h b/embed/ephy-embed-popup.h new file mode 100644 index 000000000..6416bdfcd --- /dev/null +++ b/embed/ephy-embed-popup.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_POPUP_H +#define EPHY_EMBED_POPUP_H + +#include "ephy-embed.h" +#include <glib-object.h> +#include <bonobo/bonobo-ui-component.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedPopupClass EphyEmbedPopupClass; + +#define EPHY_EMBED_POPUP_TYPE (ephy_embed_popup_get_type ()) +#define EPHY_EMBED_POPUP(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_POPUP_TYPE, EphyEmbedPopup)) +#define EPHY_EMBED_POPUP_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_EMBED_POPUP_TYPE, EphyEmbedPopupClass)) +#define IS_EPHY_EMBED_POPUP(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_POPUP_TYPE)) +#define IS_EPHY_EMBED_POPUP_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_POPUP)) +#define EPHY_EMBED_POPUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_EMBED_POPUP_TYPE, EphyEmbedPopupClass)) + +typedef struct EphyEmbedPopup EphyEmbedPopup; +typedef struct EphyEmbedPopupPrivate EphyEmbedPopupPrivate; + +struct EphyEmbedPopup +{ + GObject parent; + EphyEmbedPopupPrivate *priv; +}; + +struct EphyEmbedPopupClass +{ + GObjectClass parent_class; + + void (*show) (EphyEmbedPopup *p, + EphyEmbed *embed); +}; + + + +/* this class is abstract, don't look for the constructor */ + +GType ephy_embed_popup_get_type (void); +void ephy_embed_popup_connect_verbs (EphyEmbedPopup *p, + BonoboUIComponent *ui_component); +void ephy_embed_popup_set_embed (EphyEmbedPopup *p, + EphyEmbed *e); +EphyEmbed * ephy_embed_popup_get_embed (EphyEmbedPopup *p); +void ephy_embed_popup_set_event (EphyEmbedPopup *p, + EphyEmbedEvent *event); +EphyEmbedEvent * ephy_embed_popup_get_event (EphyEmbedPopup *p); +void ephy_embed_popup_show (EphyEmbedPopup *p, + EphyEmbed *embed); +const char * ephy_embed_popup_get_popup_path (EphyEmbedPopup *p); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-prefs.h b/embed/ephy-embed-prefs.h new file mode 100644 index 000000000..8caa14b07 --- /dev/null +++ b/embed/ephy-embed-prefs.h @@ -0,0 +1,46 @@ +#define CONF_NETWORK_SOCKS_PROXY_VERSION "/apps/epiphany/network/socks_proxy_version" +#define CONF_NETWORK_NO_PROXIES_FOR "/apps/epiphany/network/no_proxies_for" +#define CONF_NETWORK_DISK_CACHE "/apps/epiphany/network/disk_cache_size" +#define CONF_NETWORK_MEMORY_CACHE "/apps/epiphany/network/mem_cache_size" +#define CONF_NETWORK_CACHE_COMPARE "/apps/epiphany/network/cache_compare" +#define CONF_NETWORK_USER_AGENT "/apps/epiphany/network/user_agent" +#define CONF_RENDERING_FONT "/apps/epiphany/rendering/font" +#define CONF_RENDERING_FONT_VAR_SIZE "/apps/epiphany/rendering/font_var_size" +#define CONF_RENDERING_FONT_FIXED_SIZE "/apps/epiphany/rendering/font_fixed_size" +#define CONF_RENDERING_FONT_MIN_SIZE "/apps/epiphany/rendering/font_min_size" +#define CONF_RENDERING_LANGUAGE "/apps/epiphany/rendering/lang" +#define CONF_RENDERING_USE_OWN_COLORS "/apps/epiphany/rendering/use_own_colors" +#define CONF_RENDERING_USE_SYSTEM_COLORS "/apps/epiphany/rendering/use_system_colors" +#define CONF_RENDERING_USE_OWN_FONTS "/apps/epiphany/rendering/use_own_fonts" +#define CONF_RENDERING_BG_COLOR "/apps/epiphany/rendering/background_color" +#define CONF_RENDERING_TEXT_COLOR "/apps/epiphany/rendering/text_color" +#define CONF_RENDERING_VISITED_LINKS "/apps/epiphany/rendering/visited_link_color" +#define CONF_RENDERING_UNVISITED_LINKS "/apps/epiphany/rendering/unvisited_link_color" +#define CONF_RENDERING_UNDERLINE_LINKS "/apps/epiphany/rendering/underline_links" +#define CONF_FILTERING_ALLOW_POPUPS "/apps/epiphany/filtering/allow_popups" +#define CONF_FILTERING_IMAGE_LOADING_TYPE "/apps/epiphany/filtering/image_loading_type" +#define CONF_FILTERING_ANIMATE_TYPE "/apps/epiphany/filtering/animate_type" +#define CONF_FILTERING_STATUSBAR_REWRITE "/apps/epiphany/filtering/statusbar_rewrite" +#define CONF_FILTERING_JAVA_ENABLED "/apps/epiphany/filtering/java_enabled" +#define CONF_FILTERING_JAVASCRIPT_ENABLED "/apps/epiphany/filtering/javascript_enabled" +#define CONF_PERSISTENT_COOKIES_BEHAVIOR "/apps/epiphany/filtering/cookie_behavior" +#define CONF_PERSISTENT_COOKIE_WARN "/apps/epiphany/filterin/cookie_warn" +#define CONF_PERSISTENT_COOKIE_LIFETIME "/apps/epiphany/filtering/cookie_lifetime" +#define CONF_PERSISTENT_PASSWORDS_SAVE "/apps/epiphany/filtering/passwords_save" +#define CONF_LANGUAGE_AUTODETECT_CHARSET "/apps/epiphany/rendering/autodetect_charset" +#define CONF_LANGUAGE_DEFAULT_CHARSET "/apps/epiphany/rendering/default_charset" +#define CONF_RENDERING_DEFAULT_FONT "/apps/epiphany/rendering/default_font" +#define CONF_FILTERING_DEFAULT_STATUSBAR "/apps/epiphany/filtering/default_allow_statusbar" + +/* These are defined gnome wide now */ +#define CONF_NETWORK_PROXY_MODE "/system/proxy/mode" +#define CONF_NETWORK_HTTP_PROXY "/system/http_proxy/host" +#define CONF_NETWORK_SSL_PROXY "/system/proxy/secure_host" +#define CONF_NETWORK_FTP_PROXY "/system/proxy/ftp_host" +#define CONF_NETWORK_SOCKS_PROXY "/system/proxy/socks_host" +#define CONF_NETWORK_HTTP_PROXY_PORT "/system/http_proxy/port" +#define CONF_NETWORK_SSL_PROXY_PORT "/system/proxy/secure_port" +#define CONF_NETWORK_FTP_PROXY_PORT "/system/proxy/ftp_port" +#define CONF_NETWORK_SOCKS_PROXY_PORT "/system/proxy/socks_port" +#define CONF_NETWORK_PROXY_AUTO_URL "/system/proxy/autoconfig_url" + diff --git a/embed/ephy-embed-shell.c b/embed/ephy-embed-shell.c new file mode 100644 index 000000000..541e48007 --- /dev/null +++ b/embed/ephy-embed-shell.c @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <config.h> + +#include "ephy-embed-shell.h" +#include "ephy-marshal.h" +#include "ephy-favicon-cache.h" + +#include "mozilla-embed-shell.h" + +#include <string.h> + +enum +{ + NEW_WINDOW, + LAST_SIGNAL +}; + +struct EphyEmbedShellPrivate +{ + EphyHistory *global_history; + DownloaderView *downloader_view; + GList *embeds; + EphyFaviconCache *favicon_cache; +}; + +static void +ephy_embed_shell_class_init (EphyEmbedShellClass *klass); +static void +ephy_embed_shell_init (EphyEmbedShell *ges); +static void +ephy_embed_shell_finalize (GObject *object); +static void +ephy_embed_shell_finalize (GObject *object); + +static EphyHistory * +impl_get_global_history (EphyEmbedShell *shell); +static DownloaderView * +impl_get_downloader_view (EphyEmbedShell *shell); + +static GObjectClass *parent_class = NULL; +static guint ephy_embed_shell_signals[LAST_SIGNAL] = { 0 }; + +EphyEmbedShell *embed_shell; + +GType +ephy_embed_shell_get_type (void) +{ + static GType ephy_embed_shell_type = 0; + + if (ephy_embed_shell_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedShellClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_embed_shell_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (EphyEmbedShell), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_embed_shell_init + }; + + ephy_embed_shell_type = g_type_register_static (G_TYPE_OBJECT, + "EphyEmbedShell", + &our_info, 0); + } + + return ephy_embed_shell_type; +} + +static void +ephy_embed_shell_class_init (EphyEmbedShellClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + + object_class->finalize = ephy_embed_shell_finalize; + klass->get_downloader_view = impl_get_downloader_view; + klass->get_global_history = impl_get_global_history; + + ephy_embed_shell_signals[NEW_WINDOW] = + g_signal_new ("new_window_orphan", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedShellClass, new_window), + NULL, NULL, + ephy_marshal_VOID__POINTER_INT, + G_TYPE_NONE, + 2, + G_TYPE_POINTER, + G_TYPE_INT); +} + +static void +ephy_embed_shell_init (EphyEmbedShell *ges) +{ + + /* Singleton, globally accessible */ + embed_shell = ges; + + ges->priv = g_new0 (EphyEmbedShellPrivate, 1); + + ges->priv->global_history = NULL; + ges->priv->downloader_view = NULL; + ges->priv->embeds = NULL; + + ges->priv->favicon_cache = NULL; +} + +static void +ephy_embed_shell_finalize (GObject *object) +{ + EphyEmbedShell *ges; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_EPHY_EMBED_SHELL (object)); + + ges = EPHY_EMBED_SHELL (object); + + g_return_if_fail (ges->priv != NULL); + + if (ges->priv->global_history) + { + g_object_unref (ges->priv->global_history); + } + + if (ges->priv->downloader_view) + { + g_object_remove_weak_pointer + (G_OBJECT(ges->priv->downloader_view), + (gpointer *)&ges->priv->downloader_view); + g_object_unref (ges->priv->downloader_view); + } + + if (ges->priv->favicon_cache) + { + g_object_unref (G_OBJECT (ges->priv->favicon_cache)); + } + + g_free (ges->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyEmbedShell * +ephy_embed_shell_new (const char *type) +{ + if (strcmp (type, "mozilla") == 0) + { + return EPHY_EMBED_SHELL (g_object_new + (MOZILLA_EMBED_SHELL_TYPE, NULL)); + } + + g_assert_not_reached (); + return NULL; +} + +const char *supported_embeds [] = { +#ifdef ENABLE_MOZILLA_EMBED + "mozilla", +#endif +#ifdef ENABLE_GTKHTML_EMBED + "gtkhtml", +#endif + NULL }; + +const char ** +ephy_embed_shell_get_supported (void) +{ + return supported_embeds; +} + +/** + * ephy_embed_shell_get_favicon_cache: + * @gs: a #EphyShell + * + * Returns the favicons cache. + * + * Return value: the favicons cache + **/ +EphyFaviconCache * +ephy_embed_shell_get_favicon_cache (EphyEmbedShell *ees) +{ + if (ees->priv->favicon_cache == NULL) + { + EphyHistory *history; + + history = ephy_embed_shell_get_global_history (ees); + ees->priv->favicon_cache = ephy_favicon_cache_new (history); + } + + return ees->priv->favicon_cache; +} + +void +ephy_embed_shell_add_embed (EphyEmbedShell *ges, + EphyEmbed *embed) +{ + ges->priv->embeds = g_list_append (ges->priv->embeds, embed); +} + +void +ephy_embed_shell_remove_embed (EphyEmbedShell *ges, + EphyEmbed *embed) +{ + ges->priv->embeds = g_list_remove (ges->priv->embeds, embed); +} + +EphyEmbed * +ephy_embed_shell_get_active_embed (EphyEmbedShell *ges) +{ + GList *list = ges->priv->embeds; + + g_return_val_if_fail (ges->priv->embeds != NULL, NULL); + + return EPHY_EMBED (list->data); +} + +GList * +ephy_embed_shell_get_embeds (EphyEmbedShell *ges) +{ + return ges->priv->embeds; +} + +void +ephy_embed_shell_get_capabilities (EphyEmbedShell *shell, + EmbedShellCapabilities *caps) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_capabilities (shell, caps); +} + +EphyHistory * +ephy_embed_shell_get_global_history (EphyEmbedShell *shell) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_global_history (shell); +} + +DownloaderView * +ephy_embed_shell_get_downloader_view (EphyEmbedShell *shell) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_downloader_view (shell); +} + +gresult +ephy_embed_shell_clear_cache (EphyEmbedShell *shell, + CacheType type) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->clear_cache (shell, type); +} + +gresult +ephy_embed_shell_set_offline_mode (EphyEmbedShell *shell, + gboolean offline) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->set_offline_mode (shell, offline); +} + +gresult +ephy_embed_shell_load_proxy_autoconf (EphyEmbedShell *shell, + const char* url) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->load_proxy_autoconf (shell, url); +} + +gresult +ephy_embed_shell_get_charset_titles (EphyEmbedShell *shell, + const char *group, + GList **charsets) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_charset_titles (shell, group, charsets); +} + +gresult +ephy_embed_shell_get_charset_groups (EphyEmbedShell *shell, + GList **groups) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_charset_groups (shell, groups); +} + +gresult +ephy_embed_shell_get_font_list (EphyEmbedShell *shell, + const char *langGroup, + const char *fontType, + GList **fontList, + char **default_font) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->get_font_list (shell, langGroup, fontType, fontList, + default_font); +} + +gresult +ephy_embed_shell_set_permission (EphyEmbedShell *shell, + const char *url, + PermissionType type, + gboolean allow) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->set_permission (shell, url, type, allow); +} + +gresult +ephy_embed_shell_list_permissions (EphyEmbedShell *shell, + PermissionType type, + GList **permissions) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->list_permissions (shell, type, permissions); +} + +gresult +ephy_embed_shell_remove_permissions (EphyEmbedShell *shell, + PermissionType type, + GList *permissions) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->remove_permissions (shell, type, permissions); +} + +gresult +ephy_embed_shell_list_cookies (EphyEmbedShell *shell, + GList **cookies) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->list_cookies (shell, cookies); +} + +gresult +ephy_embed_shell_remove_cookies (EphyEmbedShell *shell, + GList *cookies) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->remove_cookies (shell, cookies); +} + +gresult +ephy_embed_shell_list_passwords (EphyEmbedShell *shell, + PasswordType type, + GList **passwords) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->list_passwords (shell, type, passwords); +} + +gresult +ephy_embed_shell_remove_passwords (EphyEmbedShell *shell, + GList *passwords, + PasswordType type) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->remove_passwords (shell, passwords, type); +} + +/** + * show_file_picker: Shows a file picker. Can be configured to select a + * file or a directory. + * @parentWidget: Parent Widget for file picker. + * @title: Title for file picker. + * @directory: Initial directory to start in. + * @file: Initial filename to show in filepicker. + * @mode: Mode to run filepicker in (modeOpen, modeSave, modeGetFolder) + * @ret_fullpath: On a successful return, will hold the full path to selected + * file or directory. + * @file_formats: an array of FileFormat structures to fill the format chooser + * optionmenu. NULL if not needed. The last item must have + * description == NULL. + * @ret_file_format: where to store the index of the format selected (can be + * NULL) + * returns: TRUE for success, FALSE for failure. + */ + +gresult +ephy_embed_shell_show_file_picker (EphyEmbedShell *shell, + GtkWidget *parentWidget, + const char *title, + const char *directory, + const char *file, + FilePickerMode mode, + char **ret_fullpath, + gboolean *ret_save_content, + FileFormat *file_formats, + int *ret_file_format) +{ + EphyEmbedShellClass *klass = EPHY_EMBED_SHELL_GET_CLASS (shell); + return klass->show_file_picker (shell, parentWidget, title, + directory, file, mode, + ret_fullpath, ret_save_content, + file_formats, ret_file_format); +} + +static EphyHistory * +impl_get_global_history (EphyEmbedShell *shell) +{ + if (!shell->priv->global_history) + { + shell->priv->global_history = ephy_history_new (); + } + + return shell->priv->global_history; +} + +static DownloaderView * +impl_get_downloader_view (EphyEmbedShell *shell) +{ + if (!shell->priv->downloader_view) + { + shell->priv->downloader_view = downloader_view_new (); + g_object_add_weak_pointer + (G_OBJECT(shell->priv->downloader_view), + (gpointer *)&shell->priv->downloader_view); + } + + return shell->priv->downloader_view; +} + +gresult +ephy_embed_shell_free_permissions (EphyEmbedShell *shell, + GList *permissions) +{ + GList *l; + + for (l = permissions; l != NULL; l = l->next) + { + PermissionInfo *info = (PermissionInfo *)l->data; + + g_free (info->type); + g_free (info->domain); + g_free (info); + } + + g_list_free (permissions); + + return G_OK; +} + +gresult +ephy_embed_shell_free_cookies (EphyEmbedShell *shell, + GList *cookies) +{ + GList *l; + + for (l = cookies; l != NULL; l = l->next) + { + CookieInfo *info = (CookieInfo *)l->data; + + g_free (info->base.type); + g_free (info->base.domain); + g_free (info->name); + g_free (info->value); + g_free (info->path); + g_free (info->secure); + g_free (info->expire); + g_free (info); + } + + g_list_free (cookies); + + return G_OK; +} + +gresult +ephy_embed_shell_free_passwords (EphyEmbedShell *shell, + GList *passwords) +{ + GList *l; + + for (l = passwords; l != NULL; l = l->next) + { + PasswordInfo *info = (PasswordInfo *)l->data; + g_free (info->host); + g_free (info->username); + g_free (info); + } + + g_list_free (passwords); + + return G_OK; +} + diff --git a/embed/ephy-embed-shell.h b/embed/ephy-embed-shell.h new file mode 100644 index 000000000..3c3b11603 --- /dev/null +++ b/embed/ephy-embed-shell.h @@ -0,0 +1,307 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_SHELL_H +#define EPHY_EMBED_SHELL_H + +#include "ephy-embed.h" +#include "ephy-favicon-cache.h" +#include "ephy-history.h" +#include "downloader-view.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedShellClass EphyEmbedShellClass; + +#define EPHY_EMBED_SHELL_TYPE (ephy_embed_shell_get_type ()) +#define EPHY_EMBED_SHELL(obj) (GTK_CHECK_CAST ((obj), EPHY_EMBED_SHELL_TYPE, EphyEmbedShell)) +#define EPHY_EMBED_SHELL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EPHY_EMBED_SHELL_TYPE, EphyEmbedShellClass)) +#define IS_EPHY_EMBED_SHELL(obj) (GTK_CHECK_TYPE ((obj), EPHY_EMBED_SHELL_TYPE)) +#define IS_EPHY_EMBED_SHELL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), EPHY_EMBED_SHELL)) +#define EPHY_EMBED_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EPHY_EMBED_SHELL_TYPE, EphyEmbedShellClass)) + +typedef struct EphyEmbedShell EphyEmbedShell; +typedef struct EphyEmbedShellPrivate EphyEmbedShellPrivate; + +extern EphyEmbedShell *embed_shell; + +/** + * FilePickerMode: What mode FilePicker should run in + */ + +typedef enum +{ + modeOpen = 0, + modeSave = 1, + modeGetFolder =2 +} FilePickerMode; + +typedef struct +{ + /* description of the file format */ + gchar *description; + /* tipical sufixes, NULL terminated */ + gchar **extensions; +} FileFormat; + +/** + * BlockedHost: a blocked host + */ +typedef struct +{ + gchar *type; + gchar *domain; +} PermissionInfo; + +/** + * Cookie: the type of cookies + */ +typedef struct +{ + PermissionInfo base; + gchar *name; + gchar *value; + gchar *path; + gchar *secure; + gchar *expire; +} CookieInfo; + +/** + * Password: a password manager entry + */ +typedef struct +{ + gchar *host; + gchar *username; +} PasswordInfo; + +typedef struct +{ + const char *name; + const char *title; +} CharsetInfo; + +/** + * PasswordType: To distinguish actual passwords from blocked password sites + */ +typedef enum +{ + PASSWORD_PASSWORD, + PASSWORD_REJECT +} PasswordType; + +typedef enum +{ + COOKIES_PERMISSION, + IMAGES_PERMISSION +} PermissionType; + +typedef enum +{ + DISK_CACHE = 2, + MEMORY_CACHE = 1 +} CacheType; + +typedef enum +{ + CACHE_CLEAR_CAP = 1 << 0, + OFFLINE_CAP = 1 << 1, + PROXY_AUTOCONF_CAP = 1 << 2, + JAVA_CONSOLE_CAP = 1 << 3, + JS_CONSOLE_CAP = 1 << 4, + CHARSETS_CAP = 1 << 5, + PERMISSIONS_CAP = 1 << 6, + COOKIES_CAP = 1 << 7, + PASSWORDS_CAP = 1 << 8, + FILEPICKER_CAP = 1 << 9 +} EmbedShellCapabilities; + +struct EphyEmbedShell +{ + GObject parent; + EphyEmbedShellPrivate *priv; +}; + +struct EphyEmbedShellClass +{ + GObjectClass parent_class; + + void (* new_window) (EphyEmbedShell *shell, + EphyEmbed **new_embed, + EmbedChromeMask chromemask); + + /* Methods */ + + void (* get_capabilities) (EphyEmbedShell *shell, + EmbedShellCapabilities *caps); + EphyHistory * (* get_global_history) (EphyEmbedShell *shell); + DownloaderView* (* get_downloader_view) (EphyEmbedShell *shell); + gresult (* clear_cache) (EphyEmbedShell *shell, + CacheType type); + gresult (* set_offline_mode) (EphyEmbedShell *shell, + gboolean offline); + gresult (* load_proxy_autoconf) (EphyEmbedShell *shell, + const char* url); + gresult (* show_java_console) (EphyEmbedShell *shell); + gresult (* show_js_console) (EphyEmbedShell *shell); + gresult (* get_charset_groups) (EphyEmbedShell *shell, + GList **groups); + gresult (* get_charset_titles) (EphyEmbedShell *shell, + const char *group, + GList **charsets); + gresult (* get_font_list) (EphyEmbedShell *shell, + const char *langGroup, + const char *fontType, + GList **fontList, + char **default_font); + gresult (* set_permission) (EphyEmbedShell *shell, + const char *url, + PermissionType type, + gboolean allow); + gresult (* list_permissions) (EphyEmbedShell *shell, + PermissionType type, + GList **permissions); + gresult (* remove_permissions) (EphyEmbedShell *shell, + PermissionType type, + GList *permissions); + gresult (* list_cookies) (EphyEmbedShell *shell, + GList **cokies); + gresult (* remove_cookies) (EphyEmbedShell *shell, + GList *cookies); + gresult (* list_passwords) (EphyEmbedShell *shell, + PasswordType type, + GList **passwords); + gresult (* remove_passwords) (EphyEmbedShell *shell, + GList *passwords, + PasswordType type); + gresult (* show_file_picker) (EphyEmbedShell *shell, + GtkWidget *parentWidget, + const char* title, + const char* directory, + const char* file, + FilePickerMode mode, + char **ret_fullpath, + gboolean *ret_save_content, + FileFormat *file_formats, + gint *ret_file_format); +}; + +GType ephy_embed_shell_get_type (void); + +EphyEmbedShell *ephy_embed_shell_new (const char *type); + +EphyFaviconCache *ephy_embed_shell_get_favicon_cache (EphyEmbedShell *ges); + +void ephy_embed_shell_add_embed (EphyEmbedShell *ges, + EphyEmbed *embed); + +void ephy_embed_shell_remove_embed (EphyEmbedShell *ges, + EphyEmbed *embed); + +EphyEmbed *ephy_embed_shell_get_active_embed (EphyEmbedShell *ges); + +GList *ephy_embed_shell_get_embeds (EphyEmbedShell *ges); + +const char **ephy_embed_shell_get_supported (void); + +void ephy_embed_shell_get_capabilities (EphyEmbedShell *shell, + EmbedShellCapabilities *caps); + +EphyHistory *ephy_embed_shell_get_global_history (EphyEmbedShell *shell); + +DownloaderView *ephy_embed_shell_get_downloader_view (EphyEmbedShell *shell); + +gresult ephy_embed_shell_clear_cache (EphyEmbedShell *shell, + CacheType type); + +gresult ephy_embed_shell_set_offline_mode (EphyEmbedShell *shell, + gboolean offline); + +gresult ephy_embed_shell_load_proxy_autoconf (EphyEmbedShell *shell, + const char* url); + +/* Charsets */ +gresult ephy_embed_shell_get_charset_groups (EphyEmbedShell *shell, + GList **groups); + +gresult ephy_embed_shell_get_charset_titles (EphyEmbedShell *shell, + const char *group, + GList **charsets); + +gresult ephy_embed_shell_get_font_list (EphyEmbedShell *shell, + const char *langGroup, + const char *fontType, + GList **fontList, + char **default_font); + +/* Permissions */ +gresult ephy_embed_shell_set_permission (EphyEmbedShell *shell, + const char *url, + PermissionType type, + gboolean allow); + +gresult ephy_embed_shell_list_permissions (EphyEmbedShell *shell, + PermissionType type, + GList **permissions); + +gresult ephy_embed_shell_free_permissions (EphyEmbedShell *shell, + GList *permissions); + +gresult ephy_embed_shell_remove_permissions (EphyEmbedShell *shell, + PermissionType type, + GList *permissions); + +/* Cookies */ +gresult ephy_embed_shell_list_cookies (EphyEmbedShell *shell, + GList **cookies); + +gresult ephy_embed_shell_remove_cookies (EphyEmbedShell *shell, + GList *cookies); + +gresult ephy_embed_shell_free_cookies (EphyEmbedShell *shell, + GList *cookies); + +/* Passwords */ +gresult ephy_embed_shell_list_passwords (EphyEmbedShell *shell, + PasswordType type, + GList **passwords); + +gresult ephy_embed_shell_free_passwords (EphyEmbedShell *shell, + GList *passwords); + +gresult ephy_embed_shell_remove_passwords (EphyEmbedShell *shell, + GList *passwords, + PasswordType type); + +gresult ephy_embed_shell_show_file_picker (EphyEmbedShell *shell, + GtkWidget *parentWidget, + const char *title, + const char *directory, + const char *file, + FilePickerMode mode, + char **ret_fullpath, + gboolean *ret_save_content, + FileFormat *file_formats, + int *ret_file_format); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-types.h b/embed/ephy-embed-types.h new file mode 100644 index 000000000..adf32cc6f --- /dev/null +++ b/embed/ephy-embed-types.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef GALEON_EMBED_TYPES_H +#define GALEON_EMBED_TYPES_H + +#include "ephy-types.h" + +G_BEGIN_DECLS + +typedef enum +{ + EMBED_CHROME_NONE = 0, + EMBED_CHROME_DEFAULT = 1 << 0, + EMBED_CHROME_MENUBARON = 1 << 1, + EMBED_CHROME_TOOLBARON = 1 << 2, + EMBED_CHROME_PERSONALTOOLBARON = 1 << 3, + EMBED_CHROME_STATUSBARON = 1 << 4, + EMBED_CHROME_WINDOWRAISED = 1 << 5, + EMBED_CHROME_WINDOWLOWERED = 1 << 6, + EMBED_CHROME_CENTERSCREEN = 1 << 7, + EMBED_CHROME_OPENASDIALOG = 1 << 8, + EMBED_CHROME_OPENASCHROME = 1 << 9, + EMBED_CHROME_OPENASPOPUP = 1 << 10, + EMBED_CHROME_OPENASFULLSCREEN = 1 << 11, + EMBED_CHROME_PPVIEWTOOLBARON = 1 << 12, + EMBED_CHROME_SIDEBARON = 1 << 13 +} EmbedChromeMask; + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed-utils.c b/embed/ephy-embed-utils.c new file mode 100644 index 000000000..0d94e5374 --- /dev/null +++ b/embed/ephy-embed-utils.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "eel-gconf-extensions.h" +#include "ephy-embed-utils.h" +#include "ephy-embed-shell.h" +#include "ephy-bonobo-extensions.h" +#include "ephy-gui.h" + +#include <gtk/gtkdialog.h> +#include <gtk/gtkmessagedialog.h> +#include <bonobo/bonobo-i18n.h> +#include <bonobo/bonobo-ui-util.h> +#include <libgnomevfs/gnome-vfs-uri.h> +#include <string.h> + +/** + * ephy_embed_utils_save: + * @window: the referrer window. Used to parent the dialogs. + * @default_dir_pref: the gconf path to persist the directory selected by the user. + * @ask_dest: ask the user the destination path + * @ask_content: show the user an option to save the content + * of the web page (images, javascript...) + * @persist: the #GaleonEmbedPersist referring to the url + * + * Download a save an url asking a location to the user when requested + **/ +void +ephy_embed_utils_save (GtkWidget *window, + const char *default_dir_pref, + gboolean ask_dest, gboolean ask_content, + EphyEmbedPersist *persist) +{ + GnomeVFSURI *uri; + char *retPath = NULL; + char *fileName = NULL; + char *dirName = NULL; + char *retDir; + char *target; + const char *source; + gresult ret; + EphyEmbed *embed; + EmbedPersistFlags flags; + gboolean content; + + g_object_ref (G_OBJECT(persist)); + + ephy_embed_persist_get_flags (persist, &flags); + + ephy_embed_persist_get_source (persist, &source); + + if (source) + { + target = g_strdup (source); + } + else + { + ephy_embed_persist_get_embed (persist, &embed); + g_return_if_fail (embed != NULL); + + ephy_embed_get_location (embed, + flags & + EMBED_PERSIST_MAINDOC, + FALSE, + &target); + } + + /* Get a filename from the target url */ + uri = gnome_vfs_uri_new (target); + if (uri) + { + fileName = gnome_vfs_uri_extract_short_name (uri); + gnome_vfs_uri_unref (uri); + } + + dirName = eel_gconf_get_string (default_dir_pref); + if (dirName && dirName[0] == '\0') + { + g_free (dirName); + dirName = NULL; + } + + if (!dirName || strcmp (dirName,"~") == 0) + { + g_free (dirName); + dirName = g_strdup(g_get_home_dir ()); + } + + /* If we aren't asking for downloading dir, check that we aren't + * overwriting anything. If we are, pop up a warning dialog and show + * the filepicker if the user doesn't want to overwrite the file. + */ + ret = G_FAILED; + if (!ask_dest) + { + retPath = g_build_filename (dirName, fileName, NULL); + if (ephy_gui_confirm_overwrite_file (window, retPath)) + { + ret = G_OK; + } + else + { + g_free (retPath); + ask_dest = TRUE; + } + } + + if (ask_dest) + { + /* show the file picker */ + ret = ephy_embed_shell_show_file_picker + (embed_shell, window, + _("Select the destination filename"), + dirName, fileName, modeSave, &retPath, + ask_content ? &content : NULL, + NULL, NULL); + } + + if (ret == G_OK) + { + uri = gnome_vfs_uri_new (retPath); + g_return_if_fail (uri != NULL); + + retDir = gnome_vfs_uri_extract_dirname (uri); + + if (ask_content && content) + { + flags |= EMBED_PERSIST_SAVE_CONTENT; + ephy_embed_persist_set_flags (persist, + flags); + } + + ephy_embed_persist_set_dest (persist, retPath); + + ephy_embed_persist_save (persist); + + /* set default save dir */ + eel_gconf_set_string (default_dir_pref, + retDir); + + g_free (retDir); + gnome_vfs_uri_unref (uri); + } + + g_object_unref (G_OBJECT(persist)); + + g_free (dirName); + g_free (fileName); + g_free (retPath); +} + +static void +build_group (GString *xml_string, const char *group, int index) +{ + char *tmp; + + tmp = g_strdup_printf ("<submenu label=\"%s\" name=\"CharsetGroup%d\">\n", + group, index); + xml_string = g_string_append (xml_string, tmp); + g_free (tmp); +} + +static void +build_charset (GString *xml_string, CharsetInfo *info, int index) +{ + char *tmp; + char *verb; + + verb = g_strdup_printf ("Charset%d", index); + tmp = g_strdup_printf ("<menuitem label=\"%s\" name=\"%s\" verb=\"%s\"/>\n", + info->title, verb, verb); + xml_string = g_string_append (xml_string, tmp); + + g_free (tmp); + g_free (verb); +} + +static void +add_verbs (BonoboUIComponent *ui_component, + BonoboUIVerbFn fn, GList *verbs) +{ + GList *l; + char verb[15]; + int charset_index = 0; + + for (l = verbs; l != NULL; l = l->next) + { + EncodingMenuData *edata = (EncodingMenuData *)l->data; + + sprintf (verb, "Charset%d", charset_index); + charset_index++; + bonobo_ui_component_add_verb_full + (ui_component, verb, + g_cclosure_new (G_CALLBACK (fn), edata, + (GClosureNotify)g_free)); + } +} + +/** + * ephy_embed_utils_build_charsets_submenu: + * @ui_component: the parent #BonoboUIComponent + * @path: the bonoboui path where to create the submenu. + * It's recommended to use a <placeholder/> + * @fn: callback to report the selected charsets + * @data: the data passed to the callback + * + * Create a charset submenu using bonobo ui. + **/ +void +ephy_embed_utils_build_charsets_submenu (BonoboUIComponent *ui_component, + const char *path, + BonoboUIVerbFn fn, + gpointer data) +{ + GList *groups; + GString *xml_string; + GList *verbs = NULL; + int group_index = 0; + int charset_index = 0; + +#ifdef DEBUG_MARCO + GTimer *timer; + gulong s; + + timer = g_timer_new (); + g_timer_start(timer); +#endif + + g_return_if_fail (ephy_embed_shell_get_charset_groups (embed_shell, &groups) == G_OK); + + xml_string = g_string_new (NULL); + g_string_append (xml_string, "<submenu name=\"Encoding\" _label=\"_Encoding\">"); + + for (; groups != NULL; groups = groups->next) + { + GList *charsets; + const char *group = (const char *)groups->data; + + build_group (xml_string, group, group_index); + + ephy_embed_shell_get_charset_titles (embed_shell, + group, + &charsets); + + for (; charsets != NULL; charsets = charsets->next) + { + CharsetInfo *info = (CharsetInfo *) charsets->data; + EncodingMenuData *edata; + + edata = g_new0 (EncodingMenuData, 1); + edata->encoding = info->name; + edata->data = data; + verbs = g_list_append (verbs, edata); + + build_charset (xml_string, info, charset_index); + charset_index++; + } + + + g_list_free (charsets); + g_string_append (xml_string, "</submenu>"); + group_index++; + } + + g_string_append (xml_string, "</submenu>"); + + bonobo_ui_component_set_translate (ui_component, path, + xml_string->str, NULL); + add_verbs (ui_component, fn, verbs); + + g_list_free (verbs); + g_list_free (groups); + g_string_free (xml_string, TRUE); + +#ifdef DEBUG_MARCO + g_timer_stop (timer); + g_timer_elapsed (timer, &s); + g_print ("Time to build charset menu: %f\n", (double)(s)/1000000); +#endif +} + +/** + * ephy_embed_utils_handlernotfound_dialog_run: + * @parent: the dialog parent window + * + * Show a dialog to warn the user that no application capable + * to open the specified file are found. Used in the downloader + * and in the mime type dialog. + **/ +void +ephy_embed_utils_nohandler_dialog_run (GtkWidget *parent) +{ + GtkWidget *dialog; + + /* FIXME mime db shortcut */ + + dialog = gtk_message_dialog_new + (GTK_WINDOW(parent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("No available applications to open " + "the specified file.")); + gtk_dialog_run (GTK_DIALOG(dialog)); + gtk_widget_destroy (dialog); +} diff --git a/embed/ephy-embed-utils.h b/embed/ephy-embed-utils.h new file mode 100644 index 000000000..19f7b72f1 --- /dev/null +++ b/embed/ephy-embed-utils.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_UTILS_H +#define EPHY_EMBED_UTILS_H + +#include "ephy-embed-persist.h" + +#include <gtk/gtkwidget.h> +#include <bonobo/bonobo-ui-component.h> + +G_BEGIN_DECLS + +typedef struct +{ + const char *encoding; + gpointer data; +} EncodingMenuData; + +void ephy_embed_utils_save (GtkWidget *window, + const char *default_dir_pref, + gboolean ask_dest, + gboolean ask_content, + EphyEmbedPersist *persist); + +void ephy_embed_utils_build_charsets_submenu (BonoboUIComponent *ui_component, + const char *path, + BonoboUIVerbFn fn, + gpointer data); + +void ephy_embed_utils_nohandler_dialog_run (GtkWidget *parent); + +G_END_DECLS + +#endif diff --git a/embed/ephy-embed.c b/embed/ephy-embed.c new file mode 100644 index 000000000..cb513f95c --- /dev/null +++ b/embed/ephy-embed.c @@ -0,0 +1,608 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ephy-marshal.h" +#include "ephy-embed.h" + +#include "mozilla-embed.h" +#include "mozilla-embed-shell.h" + +enum +{ + NEW_WINDOW, + LINK_MESSAGE, + FAVICON, + JS_STATUS, + LOCATION, + TITLE, + PROGRESS, + NET_STATE, + VISIBILITY, + DESTROY_BRSR, + OPEN_URI, + SIZE_TO, + DOM_MOUSE_CLICK, + DOM_MOUSE_DOWN, + SECURITY_CHANGE, + ZOOM_CHANGE, + LAST_SIGNAL +}; + +static void +ephy_embed_base_init (gpointer base_class); + +struct EphyEmbedPrivate +{ + gpointer dummy; +}; + +static guint ephy_embed_signals[LAST_SIGNAL] = { 0 }; + +GType +ephy_embed_get_type (void) +{ + static GType ephy_embed_type = 0; + + if (ephy_embed_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyEmbedClass), + ephy_embed_base_init, + NULL, + }; + + ephy_embed_type = g_type_register_static (G_TYPE_INTERFACE, + "EphyEmbed", + &our_info, + (GTypeFlags)0); + } + + return ephy_embed_type; +} + +static void +ephy_embed_base_init (gpointer g_class) +{ + static gboolean initialized = FALSE; + + if (! initialized) + { + ephy_embed_signals[NEW_WINDOW] = + g_signal_new ("ge_new_window", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, new_window), + NULL, NULL, + ephy_marshal_VOID__POINTER_INT, + G_TYPE_NONE, + 2, + G_TYPE_POINTER, + G_TYPE_INT); + ephy_embed_signals[LINK_MESSAGE] = + g_signal_new ("ge_link_message", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, link_message), + NULL, NULL, + ephy_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + ephy_embed_signals[FAVICON] = + g_signal_new ("ge_favicon", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, favicon), + NULL, NULL, + ephy_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + ephy_embed_signals[JS_STATUS] = + g_signal_new ("ge_js_status", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, js_status), + NULL, NULL, + ephy_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); + ephy_embed_signals[LOCATION] = + g_signal_new ("ge_location", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, location), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + ephy_embed_signals[TITLE] = + g_signal_new ("ge_title", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, title), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + ephy_embed_signals[PROGRESS] = + g_signal_new ("ge_progress", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, progress), + NULL, NULL, + ephy_marshal_VOID__STRING_INT_INT, + G_TYPE_NONE, + 3, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_INT); + ephy_embed_signals[NET_STATE] = + g_signal_new ("ge_net_state", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, net_state), + NULL, NULL, + ephy_marshal_VOID__STRING_INT, + G_TYPE_NONE, + 2, + G_TYPE_STRING, + G_TYPE_INT); + ephy_embed_signals[VISIBILITY] = + g_signal_new ("ge_visibility", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, visibility), + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, + 1, + G_TYPE_BOOLEAN); + ephy_embed_signals[DESTROY_BRSR] = + g_signal_new ("ge_destroy_brsr", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyEmbedClass, destroy_brsr), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + ephy_embed_signals[OPEN_URI] = + g_signal_new ("ge_open_uri", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, open_uri), + NULL, NULL, + ephy_marshal_INT__STRING, + G_TYPE_INT, + 1, + G_TYPE_STRING); + ephy_embed_signals[SIZE_TO] = + g_signal_new ("ge_size_to", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, size_to), + NULL, NULL, + ephy_marshal_VOID__INT_INT, + G_TYPE_NONE, + 2, + G_TYPE_INT, + G_TYPE_INT); + ephy_embed_signals[DOM_MOUSE_DOWN] = + g_signal_new ("ge_dom_mouse_down", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, dom_mouse_down), + NULL, NULL, + ephy_marshal_INT__OBJECT, + G_TYPE_INT, + 1, + G_TYPE_POINTER); + ephy_embed_signals[DOM_MOUSE_CLICK] = + g_signal_new ("ge_dom_mouse_click", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, dom_mouse_click), + NULL, NULL, + ephy_marshal_INT__OBJECT, + G_TYPE_INT, + 1, + G_TYPE_POINTER); + ephy_embed_signals[SECURITY_CHANGE] = + g_signal_new ("ge_security_change", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, security_change), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); + ephy_embed_signals[ZOOM_CHANGE] = + g_signal_new ("ge_zoom_change", + EPHY_EMBED_TYPE, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyEmbedClass, zoom_change), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); + } +} + +EphyEmbed * +ephy_embed_new (GObject *shell) +{ + if (IS_MOZILLA_EMBED_SHELL (shell)) + { + return EPHY_EMBED (g_object_new + (MOZILLA_EMBED_TYPE, NULL)); + } + + g_assert_not_reached (); + + return NULL; +} + +void +ephy_embed_get_capabilities (EphyEmbed *embed, + EmbedCapabilities *caps) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + klass->get_capabilities (embed, caps); +} + +gresult +ephy_embed_load_url (EphyEmbed *embed, + const char *url) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->load_url (embed, url); +} + +gresult +ephy_embed_stop_load (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->stop_load (embed); +} + +gresult +ephy_embed_can_go_back (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->can_go_back (embed); +} + +gresult +ephy_embed_can_go_forward (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->can_go_forward (embed); +} + +gresult +ephy_embed_can_go_up (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->can_go_up (embed); +} + +gresult +ephy_embed_get_go_up_list (EphyEmbed *embed, GSList **l) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->get_go_up_list (embed, l); +} + +gresult +ephy_embed_go_back (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->go_back (embed); +} + +gresult +ephy_embed_go_forward (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->go_forward (embed); +} + +gresult +ephy_embed_go_up (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->go_up (embed); +} + +gresult +ephy_embed_render_data (EphyEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->render_data (embed, data, len, base_uri, mime_type); +} + +gresult +ephy_embed_open_stream (EphyEmbed *embed, + const char *base_uri, + const char *mime_type) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->open_stream (embed, base_uri, mime_type); +} + +gresult +ephy_embed_append_data (EphyEmbed *embed, + const char *data, + guint32 len) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->append_data (embed, data, len); +} + +gresult +ephy_embed_close_stream (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->close_stream (embed); +} + +gresult +ephy_embed_get_title (EphyEmbed *embed, + char **title) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->get_title (embed, title); +} + +gresult +ephy_embed_get_location (EphyEmbed *embed, + gboolean toplevel, + gboolean requested, + char **location) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->get_location (embed, toplevel, requested, location); +} + +gresult +ephy_embed_reload (EphyEmbed *embed, + EmbedReloadFlags flags) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->reload (embed, flags); +} + +gresult +ephy_embed_copy_page (EphyEmbed *dest, + EphyEmbed *source, + EmbedDisplayType display_type) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (dest); + return klass->copy_page (dest, source, display_type); +} + +gresult +ephy_embed_grab_focus (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->grab_focus (embed); +} + +gresult +ephy_embed_get_link_tags (EphyEmbed *embed, + const char *link_type, + GList **tags) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->get_link_tags (embed, link_type, tags); +} + +gresult +ephy_embed_zoom_set (EphyEmbed *embed, + int zoom, + gboolean reflow) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->zoom_set (embed, zoom, reflow); +} + +gresult +ephy_embed_zoom_get (EphyEmbed *embed, + int *zoom) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->zoom_get (embed, zoom); +} + +gresult +ephy_embed_selection_can_cut (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->selection_can_cut (embed); +} + +gresult +ephy_embed_selection_can_copy (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->selection_can_copy (embed); +} + +gresult +ephy_embed_can_paste (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->can_paste (embed); +} + +gresult +ephy_embed_select_all (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->select_all (embed); +} + +gresult +ephy_embed_selection_cut (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->selection_cut (embed); +} + +gresult +ephy_embed_selection_copy (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->selection_copy (embed); +} + +gresult +ephy_embed_paste (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->paste (embed); +} + +gresult +ephy_embed_shistory_count (EphyEmbed *embed, + int *count) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->shistory_count (embed, count); +} + +gresult +ephy_embed_shistory_get_nth (EphyEmbed *embed, + int nth, + gboolean is_relative, + char **url, + char **title) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->shistory_get_nth (embed, nth, is_relative, url, title); +} + +gresult +ephy_embed_shistory_get_pos (EphyEmbed *embed, + int *pos) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->shistory_get_pos (embed, pos); +} + +gresult +ephy_embed_shistory_go_nth (EphyEmbed *embed, + int nth) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->shistory_go_nth (embed, nth); +} + +gboolean +ephy_embed_shistory_copy (EphyEmbed *source, + EphyEmbed *dest) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (source); + return klass->shistory_copy (source, dest); +} + +gresult +ephy_embed_scroll (EphyEmbed *embed, + EmbedScrollDirection direction) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->scroll (embed, direction); +} + +gresult +ephy_embed_fine_scroll (EphyEmbed *embed, + int horiz, int vert) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->fine_scroll (embed, horiz, vert); +} + +gresult +ephy_embed_get_security_level (EphyEmbed *embed, + EmbedSecurityLevel *level, + char **description) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->get_security_level (embed, level, description); +} + +gresult +ephy_embed_find (EphyEmbed *embed, + EmbedFindInfo *info) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->find (embed, info); +} + +gresult +ephy_embed_set_charset (EphyEmbed *embed, + const char *charset) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->set_charset (embed, charset); +} + +gresult +ephy_embed_print (EphyEmbed *embed, + EmbedPrintInfo *info) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->print (embed, info); +} + +gresult +ephy_embed_print_preview_close (EphyEmbed *embed) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->print_preview_close (embed); +} + +gresult +ephy_embed_print_preview_num_pages (EphyEmbed *embed, gint *retNum) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->print_preview_num_pages (embed, retNum); +} + +gresult +ephy_embed_print_preview_navigate (EphyEmbed *embed, + EmbedPrintPreviewNavType navType, + gint pageNum) +{ + EphyEmbedClass *klass = EPHY_EMBED_GET_CLASS (embed); + return klass->print_preview_navigate (embed, navType, pageNum); +} + diff --git a/embed/ephy-embed.h b/embed/ephy-embed.h new file mode 100644 index 000000000..1de35d7aa --- /dev/null +++ b/embed/ephy-embed.h @@ -0,0 +1,443 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EMBED_H +#define EPHY_EMBED_H + +#include "ephy-embed-types.h" +#include "ephy-embed-event.h" + +#include <glib-object.h> +#include <glib.h> +#include <gtk/gtkwidget.h> + +G_BEGIN_DECLS + +typedef struct EphyEmbedClass EphyEmbedClass; + +#define EPHY_EMBED_TYPE (ephy_embed_get_type ()) +#define EPHY_EMBED(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_EMBED_TYPE, EphyEmbed)) +#define EPHY_EMBED_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), EPHY_EMBED_TYPE, EphyEmbedClass)) +#define IS_EPHY_EMBED(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_EMBED_TYPE)) +#define IS_EPHY_EMBED_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), EPHY_EMBED_TYPE)) +#define EPHY_EMBED_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_EMBED_TYPE, EphyEmbedClass)) + +typedef struct _EphyEmbed EphyEmbed; + +typedef enum +{ + EMBED_STATE_UNKNOWN = 0, + EMBED_STATE_START = 1 << 0, + EMBED_STATE_REDIRECTING = 1 << 1, + EMBED_STATE_TRANSFERRING = 1 << 2, + EMBED_STATE_NEGOTIATING = 1 << 3, + EMBED_STATE_STOP = 1 << 4, + + EMBED_STATE_IS_REQUEST = 1 << 5, + EMBED_STATE_IS_DOCUMENT = 1 << 6, + EMBED_STATE_IS_NETWORK = 1 << 7, + EMBED_STATE_IS_WINDOW = 1 << 8 +} EmbedState; + +typedef enum +{ + EMBED_CLIPBOARD_CAP = 1 << 0, + EMBED_COOKIES_CAP = 1 << 1, + EMBED_LINKS_CAP = 1 << 2, + EMBED_ZOOM_CAP = 1 << 3, + EMBED_PRINT_CAP = 1 << 6, + EMBED_FIND_CAP = 1 << 7, + EMBED_SCROLL_CAP = 1 << 8, + EMBED_SECURITY_CAP = 1 << 9, + EMBED_CHARSET_CAP = 1 << 10, + EMBED_SHISTORY_CAP = 1 << 11, + EMBED_FINE_SCROLL_CAP = 1 << 12 +} EmbedCapabilities; + +typedef struct +{ + char *modification_date; + + /* lists of hashtables with gvalues */ + GList *images; /* url, alt, title, width, height */ + GList *forms; /* action, type */ + GList *links; /* url, title, type */ + GList *stylesheets; /* url, title */ +} EmbedPageInfo; + +typedef enum +{ + EMBED_RELOAD_NORMAL = 1 << 1, + EMBED_RELOAD_BYPASSCACHE = 1 << 2, + EMBED_RELOAD_BYPASSPROXY = 1 << 3 +} EmbedReloadFlags; + +typedef enum +{ + DISPLAY_AS_SOURCE = 1U, + DISPLAY_NORMAL = 2U +} EmbedDisplayType; + +typedef struct +{ + gchar *search_string; + gboolean backwards; + gboolean wrap; + gboolean entire_word; + gboolean match_case; + gboolean search_frames; + gboolean interactive; +} EmbedFindInfo; + +typedef struct +{ + gboolean print_to_file; + gchar *printer; + gchar *file; + gint paper; + gdouble top_margin; + gdouble bottom_margin; + gdouble left_margin; + gdouble right_margin; + gint pages; + gint from_page; + gint to_page; + gint frame_type; + gint orientation; + gboolean print_color; + + /* + * &T - title + * &U - Document URL + * &D - Date/Time + * &P - Page Number + * &PT - Page Number with total Number of Pages (example: 1 of 34) + * + * So, if headerLeftStr = "&T" the title and the document URL + * will be printed out on the top left-hand side of each page. + */ + gchar *header_left_string; + gchar *header_center_string; + gchar *header_right_string; + gchar *footer_left_string; + gchar *footer_center_string; + gchar *footer_right_string; + + gboolean preview; +} +EmbedPrintInfo; + +typedef enum +{ + PRINTPREVIEW_GOTO_PAGENUM = 0, + PRINTPREVIEW_PREV_PAGE = 1, + PRINTPREVIEW_NEXT_PAGE = 2, + PRINTPREVIEW_HOME = 3, + PRINTPREVIEW_END = 4 +} EmbedPrintPreviewNavType; + +typedef enum +{ + EMBED_SCROLL_UP, + EMBED_SCROLL_DOWN, + EMBED_SCROLL_LEFT, + EMBED_SCROLL_RIGHT +} EmbedScrollDirection; + +typedef enum +{ + STATE_IS_UNKNOWN, + STATE_IS_INSECURE, + STATE_IS_BROKEN, + STATE_IS_SECURE_MED, + STATE_IS_SECURE_LOW, + STATE_IS_SECURE_HIGH +} EmbedSecurityLevel; + +struct EphyEmbedClass +{ + GTypeInterface base_iface; + + void (* favicon) (EphyEmbed *embed, + const char *location); + void (* link_message) (EphyEmbed *embed, + const char *link); + void (* js_status) (EphyEmbed *embed, + const char *status); + void (* location) (EphyEmbed *embed); + void (* title) (EphyEmbed *embed); + void (* progress) (EphyEmbed *embed, + const char *uri, + gint curprogress, + gint maxprogress); + void (* net_state) (EphyEmbed *embed, + const char *uri, + EmbedState state); + void (* new_window) (EphyEmbed *embed, + EphyEmbed **new_embed, + EmbedChromeMask chromemask); + void (* visibility) (EphyEmbed *embed, + gboolean visibility); + void (* destroy_brsr) (EphyEmbed *embed); + gint (* open_uri) (EphyEmbed *embed, + const char *uri); + void (* size_to) (EphyEmbed *embed, + gint width, + gint height); + gint (* dom_mouse_click) (EphyEmbed *embed, + EphyEmbedEvent *event); + gint (* dom_mouse_down) (EphyEmbed *embed, + EphyEmbedEvent *event); + void (* security_change) (EphyEmbed *embed, + EmbedSecurityLevel level); + void (* zoom_change) (EphyEmbed *embed, + guint new_zoom); + + /* Methods */ + void (* get_capabilities) (EphyEmbed *embed, + EmbedCapabilities *caps); + gresult (* load_url) (EphyEmbed *embed, + const char *url); + gresult (* stop_load) (EphyEmbed *embed); + gresult (* can_go_back) (EphyEmbed *embed); + gresult (* can_go_forward) (EphyEmbed *embed); + gresult (* can_go_up) (EphyEmbed *embed); + gresult (* get_go_up_list) (EphyEmbed *embed, GSList **l); + gresult (* go_back) (EphyEmbed *embed); + gresult (* go_forward) (EphyEmbed *embed); + gresult (* go_up) (EphyEmbed *embed); + gresult (* render_data) (EphyEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type); + gresult (* open_stream) (EphyEmbed *embed, + const char *base_uri, + const char *mime_type); + gresult (* append_data) (EphyEmbed *embed, + const char *data, + guint32 len); + gresult (* close_stream) (EphyEmbed *embed); + gresult (* get_title) (EphyEmbed *embed, + char **title); + gresult (* get_location) (EphyEmbed *embed, + gboolean toplevel, + gboolean requested, + char **location); + gresult (* reload) (EphyEmbed *embed, + EmbedReloadFlags flags); + gresult (* copy_page) (EphyEmbed *dest, + EphyEmbed *source, + EmbedDisplayType display_type); + gresult (* grab_focus) (EphyEmbed *embed); + gresult (* get_link_tags) (EphyEmbed *embed, + const char *link_type, + GList **tags); + gresult (* zoom_set) (EphyEmbed *embed, + int zoom, + gboolean reflow); + gresult (* zoom_get) (EphyEmbed *embed, + int *zoom); + gresult (* selection_can_cut) (EphyEmbed *embed); + gresult (* selection_can_copy) (EphyEmbed *embed); + gresult (* can_paste) (EphyEmbed *embed); + gresult (* selection_cut) (EphyEmbed *embed); + gresult (* selection_copy) (EphyEmbed *embed); + gresult (* paste) (EphyEmbed *embed); + gresult (* select_all) (EphyEmbed *embed); + gresult (* shistory_count) (EphyEmbed *embed, + int *count); + gresult (* shistory_get_nth) (EphyEmbed *embed, + int nth, + gboolean is_relative, + char **url, + char **title); + gresult (* shistory_get_pos) (EphyEmbed *embed, + int *pos); + gresult (* shistory_go_nth) (EphyEmbed *embed, + int nth); + gboolean (* shistory_copy) (EphyEmbed *source, + EphyEmbed *dest); + gresult (* scroll) (EphyEmbed *embed, + EmbedScrollDirection direction); + gresult (* fine_scroll) (EphyEmbed *embed, + int horiz, int vert); + gresult (* get_security_level) (EphyEmbed *embed, + EmbedSecurityLevel *level, + char **description); + gresult (* find) (EphyEmbed *embed, + EmbedFindInfo *find); + gresult (* print) (EphyEmbed *embed, + EmbedPrintInfo *info); + gresult (* print_preview_close) (EphyEmbed *embed); + gresult (* print_preview_num_pages) (EphyEmbed *embed, + gint *retNum); + gresult (* print_preview_navigate) (EphyEmbed *embed, + EmbedPrintPreviewNavType navType, + gint pageNum); + gresult (* set_charset) (EphyEmbed *embed, + const char *charset); +}; + +GType ephy_embed_get_type (void); + +/* Base */ + +EphyEmbed *ephy_embed_new (GObject *shell); + +void ephy_embed_get_capabilities (EphyEmbed *embed, + EmbedCapabilities *caps); + +gresult ephy_embed_load_url (EphyEmbed *embed, + const char *url); + +gresult ephy_embed_stop_load (EphyEmbed *embed); + +gresult ephy_embed_can_go_back (EphyEmbed *embed); + +gresult ephy_embed_can_go_forward (EphyEmbed *embed); + +gresult ephy_embed_can_go_up (EphyEmbed *embed); + +gresult ephy_embed_get_go_up_list (EphyEmbed *embed, + GSList **l); + +gresult ephy_embed_go_back (EphyEmbed *embed); + +gresult ephy_embed_go_forward (EphyEmbed *embed); + +gresult ephy_embed_go_up (EphyEmbed *embed); + +gresult ephy_embed_render_data (EphyEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type); + +gresult ephy_embed_open_stream (EphyEmbed *embed, + const char *base_uri, + const char *mime_type); + +gresult ephy_embed_append_data (EphyEmbed *embed, + const char *data, + guint32 len); + +gresult ephy_embed_close_stream (EphyEmbed *embed); + +gresult ephy_embed_get_title (EphyEmbed *embed, + char **title); + +gresult ephy_embed_get_location (EphyEmbed *embed, + gboolean toplevel, + gboolean requested, + char **location); + +gresult ephy_embed_reload (EphyEmbed *embed, + EmbedReloadFlags flags); + +gresult ephy_embed_copy_page (EphyEmbed *dest, + EphyEmbed *source, + EmbedDisplayType display_type); + +gresult ephy_embed_grab_focus (EphyEmbed *embed); + +/* Link */ +gresult ephy_embed_get_favicon_location (EphyEmbed *embed, + char **url); + +gresult ephy_embed_get_link_tags (EphyEmbed *embed, + const char *link_type, + GList **tags); + +/* Zoom */ +gresult ephy_embed_zoom_set (EphyEmbed *embed, + int zoom, + gboolean reflow); + +gresult ephy_embed_zoom_get (EphyEmbed *embed, + int *zoom); + +/* Clipboard */ +gresult ephy_embed_selection_can_cut (EphyEmbed *embed); + +gresult ephy_embed_selection_can_copy (EphyEmbed *embed); + +gresult ephy_embed_can_paste (EphyEmbed *embed); + +gresult ephy_embed_selection_cut (EphyEmbed *embed); + +gresult ephy_embed_selection_copy (EphyEmbed *embed); + +gresult ephy_embed_paste (EphyEmbed *embed); + +gresult ephy_embed_select_all (EphyEmbed *embed); + +/* Session history */ +gresult ephy_embed_shistory_count (EphyEmbed *embed, + int *count); + +gresult ephy_embed_shistory_get_nth (EphyEmbed *embed, + int nth, + gboolean is_relative, + char **url, + char **title); + +gresult ephy_embed_shistory_get_pos (EphyEmbed *embed, + int *pos); + +gresult ephy_embed_shistory_go_nth (EphyEmbed *embed, + int nth); + +gboolean ephy_embed_shistory_copy (EphyEmbed *source, + EphyEmbed *dest); + +/* Utils */ + +gresult ephy_embed_scroll (EphyEmbed *embed, + EmbedScrollDirection direction); + +gresult ephy_embed_fine_scroll (EphyEmbed *embed, + int horiz, int vert); + +gresult ephy_embed_get_security_level (EphyEmbed *embed, + EmbedSecurityLevel *level, + char **description); + +gresult ephy_embed_find (EphyEmbed *embed, + EmbedFindInfo *find); + +gresult ephy_embed_set_charset (EphyEmbed *embed, + const char *charset); + +/* Printing */ + +gresult ephy_embed_print (EphyEmbed *embed, + EmbedPrintInfo *info); + +gresult ephy_embed_print_preview_close (EphyEmbed *embed); + +gresult ephy_embed_print_preview_num_pages (EphyEmbed *embed, + gint *retNum); + +gresult ephy_embed_print_preview_navigate (EphyEmbed *embed, + EmbedPrintPreviewNavType navType, + gint pageNum); + +G_END_DECLS + +#endif diff --git a/embed/ephy-favicon-cache.c b/embed/ephy-favicon-cache.c new file mode 100644 index 000000000..fd3c4192b --- /dev/null +++ b/embed/ephy-favicon-cache.c @@ -0,0 +1,367 @@ +/* + * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <libgnomevfs/gnome-vfs-uri.h> +#include <libxml/tree.h> +#include <string.h> +#include <gtk/gtktoolbar.h> +#include <gtk/gtkstock.h> +#include <sys/stat.h> + +#include "ephy-embed-persist.h" +#include "ephy-file-helpers.h" +#include "ephy-favicon-cache.h" + +static void ephy_favicon_cache_class_init (EphyFaviconCacheClass *klass); +static void ephy_favicon_cache_init (EphyFaviconCache *ma); +static void ephy_favicon_cache_finalize (GObject *object); +static void ephy_favicon_cache_insert (EphyFaviconCache *cache, + const char *url, + const char *pixbuf_location); +static char *ephy_favicon_cache_dest (EphyFaviconCache *cache, + const char *url); +static void favicon_download_completed_cb (EphyEmbedPersist *persist, + EphyFaviconCache *cache); + +struct EphyFaviconCachePrivate +{ + char *directory; + + GdkPixbuf *default_pixbuf; + EphyHistory *history; +}; + +enum +{ + CHANGED, + LAST_SIGNAL +}; + +enum +{ + PROP_0, + PROP_HISTORY +}; + +enum +{ + EPHY_NODE_PAGE_PROP_FAVICON = 100 +}; + +static guint ephy_favicon_cache_signals[LAST_SIGNAL] = { 0 }; + +static GObjectClass *parent_class = NULL; + +GType +ephy_favicon_cache_get_type (void) +{ + static GType ephy_favicon_cache_type = 0; + + if (ephy_favicon_cache_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyFaviconCacheClass), + NULL, + NULL, + (GClassInitFunc) ephy_favicon_cache_class_init, + NULL, + NULL, + sizeof (EphyFaviconCache), + 0, + (GInstanceInitFunc) ephy_favicon_cache_init + }; + + ephy_favicon_cache_type = g_type_register_static (G_TYPE_OBJECT, + "EphyFaviconCache", + &our_info, 0); + } + + return ephy_favicon_cache_type; +} + +static void +ephy_favicon_cache_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyFaviconCache *cache = EPHY_FAVICON_CACHE (object); + + switch (prop_id) + { + case PROP_HISTORY: + cache->priv->history = g_value_get_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_favicon_cache_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyFaviconCache *cache = EPHY_FAVICON_CACHE (object); + + switch (prop_id) + { + case PROP_HISTORY: + g_value_set_object (value, cache->priv->history); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} +static void +ephy_favicon_cache_class_init (EphyFaviconCacheClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_favicon_cache_finalize; + object_class->set_property = ephy_favicon_cache_set_property; + object_class->get_property = ephy_favicon_cache_get_property; + + g_object_class_install_property (object_class, + PROP_HISTORY, + g_param_spec_object ("History", + "Source history", + "Source history", + EPHY_HISTORY_TYPE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + + ephy_favicon_cache_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyFaviconCacheClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); +} + +static void +ephy_favicon_cache_init (EphyFaviconCache *cache) +{ + GtkWidget *dummy; + + cache->priv = g_new0 (EphyFaviconCachePrivate, 1); + + cache->priv->directory = g_build_filename (ephy_dot_dir (), + "favicon_cache/", + NULL); + + if (g_file_test (cache->priv->directory, G_FILE_TEST_IS_DIR) == FALSE) + { + if (g_file_test (cache->priv->directory, G_FILE_TEST_EXISTS)) + { + g_error ("Please remove %s to continue.", cache->priv->directory); + } + + if (mkdir (cache->priv->directory, 488) != 0) + { + g_error ("Couldn't mkdir %s.", cache->priv->directory); + } + } + + dummy = gtk_toolbar_new (); + cache->priv->default_pixbuf = gtk_widget_render_icon (dummy, + GTK_STOCK_JUMP_TO, + GTK_ICON_SIZE_MENU, NULL); + gtk_widget_destroy (dummy); +} + +static void +ephy_favicon_cache_finalize (GObject *object) +{ + EphyFaviconCache *cache; + + g_return_if_fail (object != NULL); + g_return_if_fail (EPHY_IS_FAVICON_CACHE (object)); + + cache = EPHY_FAVICON_CACHE (object); + + g_return_if_fail (cache->priv != NULL); + + g_object_unref (G_OBJECT (cache->priv->default_pixbuf)); + + g_object_unref (cache->priv->history); + + g_free (cache->priv->directory); + + g_free (cache->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyFaviconCache * +ephy_favicon_cache_new (EphyHistory *history) +{ + EphyFaviconCache *cache; + + cache = EPHY_FAVICON_CACHE (g_object_new (EPHY_TYPE_FAVICON_CACHE, + "History", history, + NULL)); + + g_return_val_if_fail (cache->priv != NULL, NULL); + + return cache; +} + +GdkPixbuf * +ephy_favicon_cache_lookup (EphyFaviconCache *cache, + const char *url) +{ + GdkPixbuf *ret; + + g_return_val_if_fail (EPHY_IS_FAVICON_CACHE (cache), NULL); + + if (url == NULL) + { + return cache->priv->default_pixbuf; + } + + ret = ephy_favicon_cache_lookup_direct (cache, url); + + if (ret == NULL) + { + return cache->priv->default_pixbuf; + } + + return ret; +} + +GdkPixbuf * +ephy_favicon_cache_lookup_direct (EphyFaviconCache *cache, + const char *cache_url) +{ + GdkPixbuf *pixbuf; + EphyNode *node; + const char *pix_file; + + node = ephy_history_get_page (cache->priv->history, cache_url); + if (node == NULL) return NULL; + + pix_file = ephy_node_get_property_string + (node, EPHY_NODE_PAGE_PROP_FAVICON); + if (pix_file == NULL) return NULL; + + pixbuf = gdk_pixbuf_new_from_file (pix_file, NULL); + g_return_val_if_fail (pixbuf != NULL, NULL); + + if (gdk_pixbuf_get_width (pixbuf) > 16 || + gdk_pixbuf_get_height (pixbuf) > 16) + { + GdkPixbuf *scaled = gdk_pixbuf_scale_simple (pixbuf, 16, 16, + GDK_INTERP_NEAREST); + g_object_unref (G_OBJECT (pixbuf)); + pixbuf = scaled; + } + + return pixbuf; +} + +static void +ephy_favicon_cache_insert (EphyFaviconCache *cache, + const char *url, + const char *pixbuf_location) +{ + EphyNode *node; + GValue value = { 0, }; + + node = ephy_history_get_page (cache->priv->history, url); + g_return_if_fail (node != NULL); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, pixbuf_location); + ephy_node_set_property (node, EPHY_NODE_PAGE_PROP_FAVICON, + &value); + g_value_unset (&value); + + g_signal_emit (G_OBJECT (cache), ephy_favicon_cache_signals[CHANGED], 0, url); +} + +static char * +ephy_favicon_cache_dest (EphyFaviconCache *cache, const char *url) +{ + char *slashpos, *dest, *my_url; + + my_url = g_strdup (url); + + while ((slashpos = strstr (my_url, "/")) != NULL) + *slashpos = '_'; + + dest = g_build_filename (cache->priv->directory, my_url, NULL); + + g_free (my_url); + + return dest; +} + +void +ephy_favicon_cache_insert_from_url (EphyFaviconCache *cache, + const char *url, + const char *favicon_url) +{ + EphyEmbedPersist *persist; + char *dest; + + g_return_if_fail (EPHY_IS_FAVICON_CACHE (cache)); + g_return_if_fail (url != NULL); + g_return_if_fail (favicon_url != NULL); + + dest = ephy_favicon_cache_dest (cache, favicon_url); + g_return_if_fail (dest != NULL); + + persist = ephy_embed_persist_new (NULL); + + ephy_embed_persist_set_max_size (persist, 100); + ephy_embed_persist_set_flags (persist, EMBED_PERSIST_BYPASSCACHE); + ephy_embed_persist_set_source (persist, favicon_url); + ephy_embed_persist_set_dest (persist, dest); + + g_object_set_data_full (G_OBJECT (persist), "url", g_strdup (url), g_free); + g_object_set_data_full (G_OBJECT (persist), "favicon", dest, g_free); + + g_signal_connect (G_OBJECT (persist), + "completed", + G_CALLBACK (favicon_download_completed_cb), + cache); + + ephy_embed_persist_save (persist); +} + +static void +favicon_download_completed_cb (EphyEmbedPersist *persist, + EphyFaviconCache *cache) +{ + ephy_favicon_cache_insert (cache, + g_object_get_data (G_OBJECT (persist), "url"), + g_object_get_data (G_OBJECT (persist), "favicon")); + + g_object_unref (G_OBJECT (persist)); +} diff --git a/embed/ephy-favicon-cache.h b/embed/ephy-favicon-cache.h new file mode 100644 index 000000000..ff4ebcd56 --- /dev/null +++ b/embed/ephy-favicon-cache.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-history.h" + +#include <glib-object.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +#ifndef __EPHY_FAVICON_CACHE_H +#define __EPHY_FAVICON_CACHE_H + +G_BEGIN_DECLS + +#define EPHY_TYPE_FAVICON_CACHE (ephy_favicon_cache_get_type ()) +#define EPHY_FAVICON_CACHE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_FAVICON_CACHE, EphyFaviconCache)) +#define EPHY_FAVICON_CACHE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EPHY_TYPE_FAVICON_CACHE, EphyFaviconCacheClass)) +#define EPHY_IS_FAVICON_CACHE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_FAVICON_CACHE)) +#define EPHY_IS_FAVICON_CACHE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_FAVICON_CACHE)) +#define EPHY_FAVICON_CACHE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_FAVICON_CACHE, EphyFaviconCacheClass)) + +typedef struct EphyFaviconCachePrivate EphyFaviconCachePrivate; + +typedef struct +{ + GObject parent; + + EphyFaviconCachePrivate *priv; +} EphyFaviconCache; + +typedef struct +{ + GObjectClass parent_class; + + void (*changed) (EphyFaviconCache *cache, const char *url); +} EphyFaviconCacheClass; + +GType ephy_favicon_cache_get_type (void); + +EphyFaviconCache *ephy_favicon_cache_new (EphyHistory *history); + +GdkPixbuf *ephy_favicon_cache_lookup (EphyFaviconCache *cache, + const char *url); + +GdkPixbuf *ephy_favicon_cache_lookup_direct (EphyFaviconCache *cache, + const char *cache_url); + +void ephy_favicon_cache_insert_from_url (EphyFaviconCache *cache, + const char *url, + const char *favicon_url); + +G_END_DECLS + +#endif /* __EPHY_FAVICON_CACHE_H */ diff --git a/embed/ephy-favicon.c b/embed/ephy-favicon.c new file mode 100644 index 000000000..6670c20ab --- /dev/null +++ b/embed/ephy-favicon.c @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <gtk/gtkwidget.h> +#include <string.h> + +#include "ephy-favicon.h" +#include "ephy-embed-shell.h" + +static void ephy_favicon_class_init (EphyFaviconClass *klass); +static void ephy_favicon_init (EphyFavicon *ma); +static void ephy_favicon_finalize (GObject *object); +static void ephy_favicon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void ephy_favicon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); +static void ephy_favicon_update_image (EphyFavicon *favicon); +static void cache_changed_cb (EphyFaviconCache *cache, + const char *url, + EphyFavicon *favicon); + +struct EphyFaviconPrivate +{ + EphyFaviconCache *cache; + + char *url; +}; + +enum +{ + PROP_0, + PROP_CACHE, + PROP_URL +}; + +enum +{ + CHANGED, + LAST_SIGNAL +}; + +static guint ephy_favicon_signals[LAST_SIGNAL] = { 0 }; + +static GObjectClass *parent_class = NULL; + +GType +ephy_favicon_get_type (void) +{ + static GType ephy_favicon_type = 0; + + if (ephy_favicon_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyFaviconClass), + NULL, + NULL, + (GClassInitFunc) ephy_favicon_class_init, + NULL, + NULL, + sizeof (EphyFavicon), + 0, + (GInstanceInitFunc) ephy_favicon_init + }; + + ephy_favicon_type = g_type_register_static (GTK_TYPE_IMAGE, + "EphyFavicon", + &our_info, 0); + } + + return ephy_favicon_type; +} + +static void +ephy_favicon_class_init (EphyFaviconClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_favicon_finalize; + + object_class->set_property = ephy_favicon_set_property; + object_class->get_property = ephy_favicon_get_property; + + g_object_class_install_property (object_class, + PROP_CACHE, + g_param_spec_object ("cache", + "Favicon cache", + "Favicon cache", + EPHY_TYPE_FAVICON_CACHE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (object_class, + PROP_URL, + g_param_spec_string ("url", + "Associated URL", + "Associated URL", + NULL, + G_PARAM_READWRITE)); + + ephy_favicon_signals[CHANGED] = + g_signal_new ("changed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EphyFaviconClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +ephy_favicon_init (EphyFavicon *ma) +{ + ma->priv = g_new0 (EphyFaviconPrivate, 1); + + gtk_widget_set_size_request (GTK_WIDGET (ma), 16, 16); +} + +static void +ephy_favicon_finalize (GObject *object) +{ + EphyFavicon *ma; + + g_return_if_fail (object != NULL); + g_return_if_fail (EPHY_IS_FAVICON (object)); + + ma = EPHY_FAVICON (object); + + g_return_if_fail (ma->priv != NULL); + + g_free (ma->priv->url); + + g_free (ma->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +ephy_favicon_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EphyFavicon *favicon = EPHY_FAVICON (object); + + switch (prop_id) + { + case PROP_CACHE: + favicon->priv->cache = g_value_get_object (value); + + g_signal_connect_object (G_OBJECT (favicon->priv->cache), + "changed", + G_CALLBACK (cache_changed_cb), + favicon, + 0); + + ephy_favicon_update_image (favicon); + break; + case PROP_URL: + g_free (favicon->priv->url); + favicon->priv->url = g_strdup (g_value_get_string (value)); + + ephy_favicon_update_image (favicon); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +ephy_favicon_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EphyFavicon *favicon = EPHY_FAVICON (object); + + switch (prop_id) + { + case PROP_CACHE: + g_value_set_object (value, favicon->priv->cache); + break; + case PROP_URL: + g_value_set_string (value, favicon->priv->url); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +GtkWidget * +ephy_favicon_new (const char *url) +{ + EphyFavicon *favicon; + EphyFaviconCache *cache = ephy_embed_shell_get_favicon_cache (embed_shell); + + g_return_val_if_fail (EPHY_IS_FAVICON_CACHE (cache), NULL); + + favicon = EPHY_FAVICON (g_object_new (EPHY_TYPE_FAVICON, + "cache", cache, + "url", url, + NULL)); + + g_return_val_if_fail (favicon->priv != NULL, NULL); + + return GTK_WIDGET (favicon); +} + +void +ephy_favicon_set_url (EphyFavicon *favicon, + const char *url) +{ + g_return_if_fail (EPHY_IS_FAVICON (favicon)); + + g_object_set (G_OBJECT (favicon), + "url", url, + NULL); +} + +const char * +ephy_favicon_get_url (EphyFavicon *favicon) +{ + char *url; + + g_return_val_if_fail (EPHY_IS_FAVICON (favicon), NULL); + + g_object_get (G_OBJECT (favicon), + "url", &url, + NULL); + + return (const char *) url; +} + +static void +cache_changed_cb (EphyFaviconCache *cache, + const char *url, + EphyFavicon *favicon) +{ + if (strcmp (url, favicon->priv->url) == 0) + { + ephy_favicon_update_image (favicon); + } +} + +static void +ephy_favicon_update_image (EphyFavicon *favicon) +{ + GdkPixbuf *pixbuf; + + g_return_if_fail (EPHY_IS_FAVICON_CACHE (favicon->priv->cache)); + + pixbuf = ephy_favicon_cache_lookup (favicon->priv->cache, + favicon->priv->url); + + gtk_image_set_from_pixbuf (GTK_IMAGE (favicon), pixbuf); + + g_signal_emit (G_OBJECT (favicon), ephy_favicon_signals[CHANGED], 0); +} diff --git a/embed/ephy-favicon.h b/embed/ephy-favicon.h new file mode 100644 index 000000000..97206cde5 --- /dev/null +++ b/embed/ephy-favicon.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <glib-object.h> +#include <gtk/gtkimage.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +#include "ephy-favicon-cache.h" + +#ifndef __EPHY_FAVICON_H +#define __EPHY_FAVICON_H + +G_BEGIN_DECLS + +#define EPHY_TYPE_FAVICON (ephy_favicon_get_type ()) +#define EPHY_FAVICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_FAVICON, EphyFavicon)) +#define EPHY_FAVICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), EPHY_TYPE_FAVICON, EphyFaviconClass)) +#define EPHY_IS_FAVICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_FAVICON)) +#define EPHY_IS_FAVICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_FAVICON)) +#define EPHY_FAVICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_FAVICON, EphyFaviconClass)) + +typedef struct EphyFaviconPrivate EphyFaviconPrivate; + +typedef struct +{ + GtkImage parent; + + EphyFaviconPrivate *priv; +} EphyFavicon; + +typedef struct +{ + GtkImageClass parent_class; + + void (*changed) (EphyFavicon *favicon); +} EphyFaviconClass; + +GType ephy_favicon_get_type (void); + +GtkWidget *ephy_favicon_new (const char *url); + +void ephy_favicon_set_url (EphyFavicon *favicon, + const char *url); + +const char *ephy_favicon_get_url (EphyFavicon *favicon); + +G_END_DECLS + +#endif /* __EPHY_FAVICON_H */ diff --git a/embed/ephy-history.c b/embed/ephy-history.c new file mode 100644 index 000000000..c106b274a --- /dev/null +++ b/embed/ephy-history.c @@ -0,0 +1,644 @@ +/* + * Copyright (C) 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-history.h" +#include "ephy-file-helpers.h" +#include "ephy-autocompletion-source.h" + +#include <time.h> +#include <string.h> +#include <libgnome/gnome-i18n.h> +#include <libgnomevfs/gnome-vfs-uri.h> + +//#define DEBUG_MSG(x) g_print x +#define DEBUG_MSG(x) + +#define EPHY_HISTORY_XML_VERSION "0.1" + +struct EphyHistoryPrivate +{ + char *xml_file; + EphyNode *hosts; + EphyNode *pages; + EphyNode *last_page; + GHashTable *hosts_hash; + GStaticRWLock *hosts_hash_lock; + GHashTable *pages_hash; + GStaticRWLock *pages_hash_lock; +}; + +enum +{ + ADD, + UPDATE, + REMOVE, + VISITED, + LAST_SIGNAL +}; + +static void +ephy_history_class_init (EphyHistoryClass *klass); +static void +ephy_history_init (EphyHistory *tab); +static void +ephy_history_finalize (GObject *object); +static void +ephy_history_autocompletion_source_init (EphyAutocompletionSourceIface *iface); + +static GObjectClass *parent_class = NULL; + +static guint ephy_history_signals[LAST_SIGNAL] = { 0 }; + +GType +ephy_history_get_type (void) +{ + static GType ephy_history_type = 0; + + if (ephy_history_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (EphyHistoryClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) ephy_history_class_init, + NULL, + NULL, /* class_data */ + sizeof (EphyHistory), + 0, /* n_preallocs */ + (GInstanceInitFunc) ephy_history_init + }; + + static const GInterfaceInfo autocompletion_source_info = + { + (GInterfaceInitFunc) ephy_history_autocompletion_source_init, + NULL, + NULL + }; + + ephy_history_type = g_type_register_static (G_TYPE_OBJECT, + "EphyHistory", + &our_info, 0); + + g_type_add_interface_static (ephy_history_type, + EPHY_TYPE_AUTOCOMPLETION_SOURCE, + &autocompletion_source_info); + } + + return ephy_history_type; +} + +static void +ephy_history_autocompletion_source_set_basic_key (EphyAutocompletionSource *source, + const gchar *basic_key) +{ + /* nothing to do here */ +} + +static void +ephy_history_autocompletion_source_foreach (EphyAutocompletionSource *source, + const gchar *current_text, + EphyAutocompletionSourceForeachFunc func, + gpointer data) +{ + GPtrArray *children; + int i; + EphyHistory *eb = EPHY_HISTORY (source); + + children = ephy_node_get_children (eb->priv->pages); + for (i = 0; i < children->len; i++) + { + EphyNode *kid; + const char *url, *title; + + kid = g_ptr_array_index (children, i); + url = ephy_node_get_property_string + (kid, EPHY_NODE_PAGE_PROP_LOCATION); + title = ephy_node_get_property_string + (kid, EPHY_NODE_PAGE_PROP_TITLE); + + func (source, url, + url, url, FALSE, + FALSE, 0, data); + } + ephy_node_thaw (eb->priv->pages); +} + +static void +ephy_history_emit_data_changed (EphyHistory *eb) +{ + g_signal_emit_by_name (eb, "data-changed"); +} + +static void +ephy_history_autocompletion_source_init (EphyAutocompletionSourceIface *iface) +{ + iface->foreach = ephy_history_autocompletion_source_foreach; + iface->set_basic_key = ephy_history_autocompletion_source_set_basic_key; +} + +static void +ephy_history_class_init (EphyHistoryClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = ephy_history_finalize; + + ephy_history_signals[VISITED] = + g_signal_new ("visited", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EphyHistoryClass, visited), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, + 1, + G_TYPE_STRING); +} + +static void +ephy_history_load (EphyHistory *eb) +{ + xmlDocPtr doc; + xmlNodePtr root, child; + char *tmp; + + if (g_file_test (eb->priv->xml_file, G_FILE_TEST_EXISTS) == FALSE) + return; + + doc = xmlParseFile (eb->priv->xml_file); + g_assert (doc != NULL); + + root = xmlDocGetRootElement (doc); + + tmp = xmlGetProp (root, "version"); + g_assert (tmp != NULL && strcmp (tmp, EPHY_HISTORY_XML_VERSION) == 0); + g_free (tmp); + + for (child = root->children; child != NULL; child = child->next) + { + EphyNode *node; + + node = ephy_node_new_from_xml (child); + } + + xmlFreeDoc (doc); +} + +static void +ephy_history_save (EphyHistory *eb) +{ + xmlDocPtr doc; + xmlNodePtr root; + GPtrArray *children; + int i; + + DEBUG_MSG (("Saving history\n")); + + /* save nodes to xml */ + xmlIndentTreeOutput = TRUE; + doc = xmlNewDoc ("1.0"); + + root = xmlNewDocNode (doc, NULL, "ephy_history", NULL); + xmlSetProp (root, "version", EPHY_HISTORY_XML_VERSION); + xmlDocSetRootElement (doc, root); + + children = ephy_node_get_children (eb->priv->hosts); + for (i = 0; i < children->len; i++) + { + EphyNode *kid; + + kid = g_ptr_array_index (children, i); + + ephy_node_save_to_xml (kid, root); + } + ephy_node_thaw (eb->priv->hosts); + + children = ephy_node_get_children (eb->priv->pages); + for (i = 0; i < children->len; i++) + { + EphyNode *kid; + + kid = g_ptr_array_index (children, i); + + ephy_node_save_to_xml (kid, root); + } + ephy_node_thaw (eb->priv->pages); + + xmlSaveFormatFile (eb->priv->xml_file, doc, 1); +} + +static void +hosts_added_cb (EphyNode *node, + EphyNode *child, + EphyHistory *eb) +{ + g_static_rw_lock_writer_lock (eb->priv->hosts_hash_lock); + + g_hash_table_insert (eb->priv->hosts_hash, + (char *) ephy_node_get_property_string (child, EPHY_NODE_PAGE_PROP_TITLE), + child); + + g_static_rw_lock_writer_unlock (eb->priv->hosts_hash_lock); +} + +static void +hosts_removed_cb (EphyNode *node, + EphyNode *child, + EphyHistory *eb) +{ + g_static_rw_lock_writer_lock (eb->priv->hosts_hash_lock); + + g_hash_table_remove (eb->priv->hosts_hash, + ephy_node_get_property_string (child, EPHY_NODE_PAGE_PROP_TITLE)); + + g_static_rw_lock_writer_unlock (eb->priv->hosts_hash_lock); +} + +static void +pages_added_cb (EphyNode *node, + EphyNode *child, + EphyHistory *eb) +{ + g_static_rw_lock_writer_lock (eb->priv->pages_hash_lock); + + g_hash_table_insert (eb->priv->pages_hash, + (char *) ephy_node_get_property_string (child, EPHY_NODE_PAGE_PROP_LOCATION), + child); + + g_static_rw_lock_writer_unlock (eb->priv->pages_hash_lock); +} + +static void +pages_removed_cb (EphyNode *node, + EphyNode *child, + EphyHistory *eb) +{ + g_static_rw_lock_writer_lock (eb->priv->pages_hash_lock); + + g_hash_table_remove (eb->priv->pages_hash, + ephy_node_get_property_string (child, EPHY_NODE_PAGE_PROP_LOCATION)); + + g_static_rw_lock_writer_unlock (eb->priv->pages_hash_lock); +} + +static void +ephy_history_init (EphyHistory *eb) +{ + eb->priv = g_new0 (EphyHistoryPrivate, 1); + + eb->priv->xml_file = g_build_filename (ephy_dot_dir (), + "ephy-history.xml", + NULL); + + ephy_node_system_init (); + + eb->priv->pages_hash = g_hash_table_new (g_str_hash, + g_str_equal); + eb->priv->pages_hash_lock = g_new0 (GStaticRWLock, 1); + g_static_rw_lock_init (eb->priv->pages_hash_lock); + + eb->priv->hosts_hash = g_hash_table_new (g_str_hash, + g_str_equal); + eb->priv->hosts_hash_lock = g_new0 (GStaticRWLock, 1); + g_static_rw_lock_init (eb->priv->hosts_hash_lock); + + /* Bookmarks */ + eb->priv->pages = ephy_node_new (); + ephy_node_ref (eb->priv->pages); + g_signal_connect_object (G_OBJECT (eb->priv->pages), + "child_added", + G_CALLBACK (pages_added_cb), + G_OBJECT (eb), + 0); + g_signal_connect_object (G_OBJECT (eb->priv->pages), + "child_removed", + G_CALLBACK (pages_removed_cb), + G_OBJECT (eb), + 0); + + /* Hosts */ + eb->priv->hosts = ephy_node_new (); + ephy_node_ref (eb->priv->hosts); + g_signal_connect_object (G_OBJECT (eb->priv->hosts), + "child_added", + G_CALLBACK (hosts_added_cb), + G_OBJECT (eb), + 0); + g_signal_connect_object (G_OBJECT (eb->priv->hosts), + "child_removed", + G_CALLBACK (hosts_removed_cb), + G_OBJECT (eb), + 0); + + ephy_history_load (eb); + ephy_history_emit_data_changed (eb); +} + +static void +ephy_history_finalize (GObject *object) +{ + EphyHistory *eb; + + g_return_if_fail (IS_EPHY_HISTORY (object)); + + eb = EPHY_HISTORY (object); + + g_return_if_fail (eb->priv != NULL); + + ephy_history_save (eb); + + ephy_node_unref (eb->priv->pages); + ephy_node_unref (eb->priv->hosts); + + g_hash_table_destroy (eb->priv->pages_hash); + g_static_rw_lock_free (eb->priv->pages_hash_lock); + g_hash_table_destroy (eb->priv->hosts_hash); + g_static_rw_lock_free (eb->priv->hosts_hash_lock); + + g_free (eb->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyHistory * +ephy_history_new () +{ + EphyHistory *tab; + + tab = EPHY_HISTORY (g_object_new (EPHY_HISTORY_TYPE, NULL)); + + return tab; +} + +static EphyNode * +ephy_history_add_host (EphyHistory *eh, const char *url) +{ + EphyNode *host; + GnomeVFSURI *vfs_uri = NULL; + const char *host_name = NULL; + char *host_location = NULL; + GTime now; + GValue value = { 0, }; + int visits; + + now = time (NULL); + + /* Build an host name */ + if (!g_ascii_strncasecmp (url, "file://", 7)) + { + host_name = _("Local files"); + host_location = g_strdup ("file://"); + } + else + { + vfs_uri = gnome_vfs_uri_new (url); + if (vfs_uri != NULL) + { + host_name = gnome_vfs_uri_get_host_name (vfs_uri); + host_location = gnome_vfs_uri_to_string + (vfs_uri, GNOME_VFS_URI_HIDE_FRAGMENT_IDENTIFIER); + } + + if (host_name == NULL) + { + host_name = _("Other"); + host_location = g_strdup ("about:blank"); + } + } + + g_static_rw_lock_reader_lock (eh->priv->hosts_hash_lock); + host = g_hash_table_lookup (eh->priv->hosts_hash, host_name); + g_static_rw_lock_reader_unlock (eh->priv->hosts_hash_lock); + + if (!host) + { + host = ephy_node_new (); + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, host_name); + ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_TITLE, + &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, host_location); + ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_LOCATION, + &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, now); + ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_FIRST_VISIT, + &value); + g_value_unset (&value); + + ephy_node_add_child (eh->priv->hosts, host); + } + + visits = ephy_node_get_property_int + (host, EPHY_NODE_PAGE_PROP_VISITS); + if (visits < 0) visits = 0; + visits++; + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, visits); + ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_VISITS, + &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, now); + ephy_node_set_property (host, EPHY_NODE_PAGE_PROP_LAST_VISIT, + &value); + g_value_unset (&value); + + if (vfs_uri) + { + gnome_vfs_uri_unref (vfs_uri); + } + + g_free (host_location); + + return host; +} + +static void +ephy_history_visited (EphyHistory *eh, EphyNode *node) +{ + GValue value = { 0, }; + GTime now; + int visits; + const char *url; + + now = time (NULL); + + url = ephy_node_get_property_string + (node, EPHY_NODE_PAGE_PROP_LOCATION); + + visits = ephy_node_get_property_int + (node, EPHY_NODE_PAGE_PROP_VISITS); + if (visits < 0) visits = 0; + visits++; + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, visits); + ephy_node_set_property (node, EPHY_NODE_PAGE_PROP_VISITS, + &value); + g_value_unset (&value); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, now); + ephy_node_set_property (node, EPHY_NODE_PAGE_PROP_LAST_VISIT, + &value); + if (visits == 1) + { + ephy_node_set_property + (node, EPHY_NODE_PAGE_PROP_FIRST_VISIT, &value); + } + g_value_unset (&value); + + eh->priv->last_page = node; + + g_signal_emit (G_OBJECT (eh), ephy_history_signals[VISITED], 0, url); + ephy_history_emit_data_changed (eh); +} + +int +ephy_history_get_page_visits (EphyHistory *gh, + const char *url) +{ + EphyNode *node; + int visits; + + node = ephy_history_get_page (gh, url); + + visits = ephy_node_get_property_int + (node, EPHY_NODE_PAGE_PROP_VISITS); + if (visits < 0) visits = 0; + visits++; + + return visits; +} + +void +ephy_history_add_page (EphyHistory *eb, + const char *url) +{ + EphyNode *bm, *node, *host; + GValue value = { 0, }; + + node = ephy_history_get_page (eb, url); + if (node) + { + ephy_history_visited (eb, node); + return; + } + + bm = ephy_node_new (); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, url); + ephy_node_set_property (bm, EPHY_NODE_PAGE_PROP_LOCATION, + &value); + ephy_node_set_property (bm, EPHY_NODE_PAGE_PROP_TITLE, + &value); + g_value_unset (&value); + + host = ephy_history_add_host (eb, url); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, ephy_node_get_id (host)); + ephy_node_set_property (bm, EPHY_NODE_PAGE_PROP_HOST_ID, + &value); + g_value_unset (&value); + + ephy_history_visited (eb, bm); + + ephy_node_add_child (host, bm); + ephy_node_add_child (eb->priv->pages, bm); +} + +EphyNode * +ephy_history_get_page (EphyHistory *eb, + const char *url) +{ + EphyNode *node; + + g_static_rw_lock_reader_lock (eb->priv->pages_hash_lock); + node = g_hash_table_lookup (eb->priv->pages_hash, url); + g_static_rw_lock_reader_unlock (eb->priv->pages_hash_lock); + + return node; +} + +gboolean +ephy_history_is_page_visited (EphyHistory *gh, + const char *url) +{ + return (ephy_history_get_page (gh, url) != NULL); +} + +void +ephy_history_set_page_title (EphyHistory *gh, + const char *url, + const char *title) +{ + EphyNode *node; + + node = ephy_history_get_page (gh, url); + if (node) + { + GValue value = { 0, }; + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, title); + ephy_node_set_property + (node, EPHY_NODE_PAGE_PROP_TITLE, &value); + g_value_unset (&value); + } +} + +void +ephy_history_clear (EphyHistory *gh) +{ + ephy_node_unref (gh->priv->hosts); + ephy_history_save (gh); +} + +EphyNode * +ephy_history_get_hosts (EphyHistory *eb) +{ + return eb->priv->hosts; +} + +EphyNode * +ephy_history_get_pages (EphyHistory *eb) +{ + return eb->priv->pages; +} + +const char * +ephy_history_get_last_page (EphyHistory *gh) +{ + if (gh->priv->last_page == NULL) return NULL; + + return ephy_node_get_property_string + (gh->priv->last_page, EPHY_NODE_PAGE_PROP_LOCATION); +} diff --git a/embed/ephy-history.h b/embed/ephy-history.h new file mode 100644 index 000000000..641ab6d7c --- /dev/null +++ b/embed/ephy-history.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_HISTORY_H +#define EPHY_HISTORY_H + +#include <glib-object.h> + +#include "ephy-node.h" + +G_BEGIN_DECLS + +typedef struct EphyHistoryClass EphyHistoryClass; + +#define EPHY_HISTORY_TYPE (ephy_history_get_type ()) +#define EPHY_HISTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_HISTORY_TYPE, EphyHistory)) +#define EPHY_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_HISTORY_TYPE, EphyHistoryClass)) +#define IS_EPHY_HISTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_HISTORY_TYPE)) +#define IS_EPHY_HISTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EPHY_HISTORY_TYPE)) + +typedef struct EphyHistory EphyHistory; +typedef struct EphyHistoryPrivate EphyHistoryPrivate; + +enum +{ + EPHY_NODE_PAGE_PROP_TITLE = 2, + EPHY_NODE_PAGE_PROP_LOCATION = 3, + EPHY_NODE_PAGE_PROP_VISITS = 4, + EPHY_NODE_PAGE_PROP_LAST_VISIT = 5, + EPHY_NODE_PAGE_PROP_FIRST_VISIT = 6, + EPHY_NODE_PAGE_PROP_HOST_ID = 7 +}; + +struct EphyHistory +{ + GObject parent; + EphyHistoryPrivate *priv; +}; + +struct EphyHistoryClass +{ + GObjectClass parent_class; + + void (* visited) (const char *url); +}; + +GType ephy_history_get_type (void); + +EphyHistory *ephy_history_new (void); + +EphyNode *ephy_history_get_hosts (EphyHistory *gh); + +EphyNode *ephy_history_get_pages (EphyHistory *gh); + +EphyNode *ephy_history_get_page (EphyHistory *gh, + const char *url); + +void ephy_history_add_page (EphyHistory *gh, + const char *url); + +gboolean ephy_history_is_page_visited (EphyHistory *gh, + const char *url); + +int ephy_history_get_page_visits (EphyHistory *gh, + const char *url); + +void ephy_history_set_page_title (EphyHistory *gh, + const char *url, + const char *title); + +const char *ephy_history_get_last_page (EphyHistory *gh); + +void ephy_history_clear (EphyHistory *gh); + +G_END_DECLS + +#endif diff --git a/embed/find-dialog.c b/embed/find-dialog.c new file mode 100755 index 000000000..7b96e86c1 --- /dev/null +++ b/embed/find-dialog.c @@ -0,0 +1,431 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "find-dialog.h" +#include "ephy-prefs.h" +#include "ephy-embed.h" + +#define CONF_FIND_MATCH_CASE "/apps/epiphany/find/match_case" +#define CONF_FIND_AUTOWRAP "/apps/epiphany/find/autowrap" +#define CONF_FIND_WORD "/apps/epiphany/find/word" + +static void find_dialog_class_init (FindDialogClass *klass); +static void find_dialog_init (FindDialog *dialog); +static void find_dialog_finalize (GObject *object); + +static void +impl_construct (EphyDialog *dialog, + const EphyDialogProperty *properties, + const char *file, + const char *name); +static void +impl_destruct (EphyDialog *dialog); +static void +impl_show (EphyDialog *dialog); + + +/* Glade callbacks */ +void find_close_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); +void find_next_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); +void find_prev_button_clicked_cb (GtkWidget *button, EphyDialog *dialog); +void find_entry_activate_cb (GtkWidget *editable, EphyDialog *dialog); +void find_entry_changed_cb (GtkWidget *editable, EphyDialog *dialog); +void find_check_toggled_cb (GtkWidget *toggle, EphyDialog *dialog); + +static GObjectClass *parent_class = NULL; + +struct FindDialogPrivate +{ + EmbedFindInfo *properties; + gboolean can_go_prev; + gboolean can_go_next; + gboolean constructed; +}; + +enum +{ + SEARCH, + LAST_SIGNAL +}; + +enum +{ + MATCH_CASE_PROP, + AUTOWRAP_PROP, + WORD_PROP, + BACK_BUTTON, + FORWARD_BUTTON +}; + +static const +EphyDialogProperty properties [] = +{ + { MATCH_CASE_PROP, "case_check", CONF_FIND_MATCH_CASE, PT_NORMAL, NULL }, + { AUTOWRAP_PROP, "wrap_check", CONF_FIND_AUTOWRAP, PT_NORMAL, NULL }, + { WORD_PROP, "find_entry", CONF_FIND_WORD, PT_NORMAL, NULL }, + { BACK_BUTTON, "back_button", NULL, PT_NORMAL, NULL }, + { FORWARD_BUTTON, "forward_button", NULL, PT_NORMAL, NULL }, + { -1, NULL, NULL } +}; + +static guint find_dialog_signals[LAST_SIGNAL] = { 0 }; + +GType +find_dialog_get_type (void) +{ + static GType find_dialog_type = 0; + + if (find_dialog_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (FindDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) find_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (FindDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) find_dialog_init + }; + + find_dialog_type = g_type_register_static (EPHY_EMBED_DIALOG_TYPE, + "FindDialog", + &our_info, 0); + } + + return find_dialog_type; + +} + +static void +find_dialog_class_init (FindDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + EphyDialogClass *ephy_dialog_class; + + parent_class = g_type_class_peek_parent (klass); + ephy_dialog_class = EPHY_DIALOG_CLASS (klass); + + object_class->finalize = find_dialog_finalize; + + ephy_dialog_class->construct = impl_construct; + ephy_dialog_class->destruct = impl_destruct; + ephy_dialog_class->show = impl_show; + + find_dialog_signals[SEARCH] = + g_signal_new ("search", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (FindDialogClass, search), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +find_update_nav (EphyDialog *dialog) +{ + GtkWidget *forward_button; + GtkWidget *back_button; + + g_signal_emit (G_OBJECT (dialog), find_dialog_signals[SEARCH], 0); + + if (!FIND_DIALOG(dialog)->priv->constructed) return; + + forward_button = ephy_dialog_get_control (dialog, FORWARD_BUTTON); + gtk_widget_set_sensitive (forward_button, + FIND_DIALOG(dialog)->priv->can_go_next); + + back_button = ephy_dialog_get_control (dialog, BACK_BUTTON); + gtk_widget_set_sensitive (back_button, + FIND_DIALOG(dialog)->priv->can_go_prev); +} + +void static +ensure_constructed (FindDialog *dialog) +{ + if (!dialog->priv->constructed) + { + ephy_dialog_construct (EPHY_DIALOG(dialog), + properties, + "epiphany.glade", + "find_dialog"); + } +} + +static void +find_dialog_init (FindDialog *dialog) +{ + dialog->priv = g_new0 (FindDialogPrivate, 1); + + dialog->priv->properties = NULL; + dialog->priv->can_go_prev = TRUE; + dialog->priv->can_go_next = TRUE; + dialog->priv->constructed = FALSE; + + ensure_constructed (dialog); +} + +static void +impl_construct (EphyDialog *dialog, + const EphyDialogProperty *properties, + const char *file, + const char *name) +{ + FIND_DIALOG(dialog)->priv->constructed = TRUE; + + EPHY_DIALOG_CLASS (parent_class)->construct (dialog, properties, file, name); +} + +static void +impl_destruct (EphyDialog *dialog) +{ + FIND_DIALOG(dialog)->priv->constructed = FALSE; + + EPHY_DIALOG_CLASS (parent_class)->destruct (dialog); +} + +static void +impl_show (EphyDialog *dialog) +{ + FindDialog *find_dialog = FIND_DIALOG(dialog); + ensure_constructed (find_dialog); + + find_dialog->priv->can_go_prev = TRUE; + find_dialog->priv->can_go_next = TRUE; + find_update_nav (dialog); + + /* Focus the text entry. This will correctly select or leave + * unselected the existing text in the entry depending on the + * 'gtk-entry-select-on-focus = 0 / 1' setting in user's gtkrc. + */ + gtk_widget_grab_focus (ephy_dialog_get_control (dialog, WORD_PROP)); + + EPHY_DIALOG_CLASS (parent_class)->show (dialog); +} + +static void +find_dialog_finalize (GObject *object) +{ + FindDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_FIND_DIALOG (object)); + + dialog = FIND_DIALOG (object); + + g_return_if_fail (dialog->priv != NULL); + + g_free (dialog->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyDialog * +find_dialog_new (EphyEmbed *embed) +{ + FindDialog *dialog; + + dialog = FIND_DIALOG (g_object_new (FIND_DIALOG_TYPE, + "EphyEmbed", embed, + NULL)); + + return EPHY_DIALOG(dialog); +} + +EphyDialog * +find_dialog_new_with_parent (GtkWidget *window, + EphyEmbed *embed) +{ + FindDialog *dialog; + + dialog = FIND_DIALOG (g_object_new (FIND_DIALOG_TYPE, + "EphyEmbed", embed, + "ParentWindow", window, + NULL)); + + return EPHY_DIALOG(dialog); +} + +gboolean +find_dialog_can_go_next (FindDialog *dialog) +{ + return dialog->priv->can_go_next; +} + +gboolean +find_dialog_can_go_prev (FindDialog *dialog) +{ + return dialog->priv->can_go_prev; +} + +void +find_dialog_go_next (FindDialog *dialog, + gboolean interactive) +{ + gresult result; + EphyEmbed *embed; + + if (!find_dialog_can_go_next (dialog)) return; + + dialog->priv->properties->backwards = FALSE; + dialog->priv->properties->interactive = interactive; + + embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG(dialog)); + g_return_if_fail (embed != NULL); + + result = ephy_embed_find (embed, + dialog->priv->properties); + + dialog->priv->can_go_prev = TRUE; + if (result != G_OK) + { + dialog->priv->can_go_next = FALSE; + } + + find_update_nav (EPHY_DIALOG(dialog)); +} + +void +find_dialog_go_prev (FindDialog *dialog, + gboolean interactive) +{ + gresult result; + EphyEmbed *embed; + + if (!find_dialog_can_go_prev (dialog)) return; + + dialog->priv->properties->backwards = TRUE; + dialog->priv->properties->interactive = interactive; + + embed = ephy_embed_dialog_get_embed (EPHY_EMBED_DIALOG(dialog)); + g_return_if_fail (embed != NULL); + + result = ephy_embed_find (embed, + dialog->priv->properties); + + dialog->priv->can_go_next = TRUE; + if (result != G_OK) + { + dialog->priv->can_go_prev = FALSE; + } + + find_update_nav (EPHY_DIALOG(dialog)); +} + +static void +find_get_info (EphyDialog *dialog) +{ + EmbedFindInfo *properties; + char *search_string; + GValue word = {0, }; + GValue match_case = {0, }; + GValue wrap = {0, }; + FindDialog *find_dialog = FIND_DIALOG(dialog); + + /* get the search string from the entry field */ + ephy_dialog_get_value (dialog, WORD_PROP, &word); + search_string = g_strdup(g_value_get_string (&word)); + + /* don't do null searches */ + if (search_string[0] == '\0') + { + return; + } + + if (find_dialog->priv->properties != NULL) + { + g_free (find_dialog->priv->properties->search_string); + g_free (find_dialog->priv->properties); + } + + /* build search structure */ + properties = g_new0 (EmbedFindInfo,1); + properties->search_string = search_string; + + ephy_dialog_get_value (dialog, MATCH_CASE_PROP, &match_case); + properties->match_case = g_value_get_boolean (&match_case); + + ephy_dialog_get_value (dialog, AUTOWRAP_PROP, &wrap); + properties->wrap = g_value_get_boolean (&wrap); + + properties->entire_word = FALSE; + properties->search_frames = TRUE; + + find_dialog->priv->properties = properties; +} + +void +find_close_button_clicked_cb (GtkWidget *button, + EphyDialog *dialog) +{ + ephy_dialog_destruct (dialog); + g_object_unref (dialog); +} + +void find_next_button_clicked_cb (GtkWidget *button, + EphyDialog *dialog) +{ + find_dialog_go_next (FIND_DIALOG(dialog), TRUE); +} + +void +find_prev_button_clicked_cb (GtkWidget *button, + EphyDialog *dialog) +{ + find_dialog_go_prev (FIND_DIALOG(dialog), TRUE); +} + +void +find_entry_activate_cb (GtkWidget *editable, + EphyDialog *dialog) +{ + find_dialog_go_next (FIND_DIALOG(dialog), TRUE); + find_update_nav (dialog); +} + +void +find_entry_changed_cb (GtkWidget *editable, + EphyDialog *dialog) +{ + FindDialog *find_dialog = FIND_DIALOG(dialog); + + find_dialog->priv->can_go_prev = TRUE; + find_dialog->priv->can_go_next = TRUE; + + find_get_info (dialog); + + find_update_nav (dialog); +} + +void +find_check_toggled_cb (GtkWidget *toggle, + EphyDialog *dialog) +{ + FindDialog *find_dialog = FIND_DIALOG(dialog); + + find_dialog->priv->can_go_prev = TRUE; + find_dialog->priv->can_go_next = TRUE; + + find_get_info (dialog); + + find_update_nav (dialog); +} diff --git a/embed/find-dialog.h b/embed/find-dialog.h new file mode 100644 index 000000000..325f8a7b7 --- /dev/null +++ b/embed/find-dialog.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FIND_DIALOG_H +#define FIND_DIALOG_H + +#include "ephy-embed-dialog.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct FindDialog FindDialog; +typedef struct FindDialogClass FindDialogClass; + +#define FIND_DIALOG_TYPE (find_dialog_get_type ()) +#define FIND_DIALOG(obj) (GTK_CHECK_CAST ((obj), FIND_DIALOG_TYPE, FindDialog)) +#define FIND_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), FIND_DIALOG, FindDialogClass)) +#define IS_FIND_DIALOG(obj) (GTK_CHECK_TYPE ((obj), FIND_DIALOG_TYPE)) +#define IS_FIND_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), FIND_DIALOG)) + +typedef struct FindDialogPrivate FindDialogPrivate; + +struct FindDialog +{ + EphyEmbedDialog parent; + FindDialogPrivate *priv; +}; + +struct FindDialogClass +{ + EphyEmbedDialogClass parent_class; + + void (* search) (FindDialog *dialog); +}; + +GType find_dialog_get_type (void); + +EphyDialog *find_dialog_new (EphyEmbed *embed); + +EphyDialog *find_dialog_new_with_parent (GtkWidget *window, + EphyEmbed *embed); + + +gboolean find_dialog_can_go_next (FindDialog *dialog); + +gboolean find_dialog_can_go_prev (FindDialog *dialog); + +void find_dialog_go_next (FindDialog *dialog, + gboolean interactive); + +void find_dialog_go_prev (FindDialog *dialog, + gboolean interactive); + +G_END_DECLS + +#endif + diff --git a/embed/mozilla/.cvsignore b/embed/mozilla/.cvsignore new file mode 100644 index 000000000..20e4cb0c8 --- /dev/null +++ b/embed/mozilla/.cvsignore @@ -0,0 +1,6 @@ +Makefile +Makefile.in +*.lo +.deps +.libs +*.la diff --git a/embed/mozilla/BaseProtocolContentHandler.cpp b/embed/mozilla/BaseProtocolContentHandler.cpp new file mode 100644 index 000000000..741d21722 --- /dev/null +++ b/embed/mozilla/BaseProtocolContentHandler.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "nsCOMPtr.h" +#include "nsIURI.h" +#include "nsIChannel.h" +#include "nsIStorageStream.h" +#include "nsIInputStream.h" +#include "nsIOutputStream.h" +#include "nsNetUtil.h" +#include "nsIExternalProtocolService.h" +#include "nsCExternalHandlerService.h" + +#include "BaseProtocolContentHandler.h" + +/* Implementation file */ +NS_IMPL_ISUPPORTS2 (GBaseProtocolContentHandler, nsIProtocolHandler, nsIContentHandler) + +GBaseProtocolContentHandler::GBaseProtocolContentHandler(const char *aScheme) : + GBaseProtocolHandler(aScheme) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + mMimeType = NS_LITERAL_CSTRING("application-x-gnome-") + mScheme; +} + +GBaseProtocolContentHandler::~GBaseProtocolContentHandler() +{ + /* destructor code */ +} + +/* nsIChannel newChannel (in nsIURI aURI); */ +NS_IMETHODIMP GBaseProtocolContentHandler::NewChannel(nsIURI *aURI, + nsIChannel **_retval) +{ + nsCOMPtr<nsIStorageStream> sStream; + nsresult rv = NS_NewStorageStream(1, 16, getter_AddRefs(sStream)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr<nsIOutputStream> oStream; + rv = sStream->GetOutputStream(0, getter_AddRefs(oStream)); + + PRUint32 bytes; + oStream->Write("Dummy stream\0", 13, &bytes); + + nsCOMPtr<nsIInputStream> iStream; + rv = sStream->NewInputStream(0, getter_AddRefs(iStream)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr<nsIChannel> channel; + rv = NS_NewInputStreamChannel(getter_AddRefs(channel), aURI, + iStream, mMimeType, NS_LITERAL_CSTRING(""), 0); + if (NS_FAILED(rv)) return rv; + + NS_IF_ADDREF (*_retval = channel); + return rv; +} + +NS_IMETHODIMP GBaseProtocolContentHandler::HandleContent ( + const char * aContentType, + const char * aCommand, + nsISupports * aWindowContext, + nsIRequest *aRequest) +{ + nsresult rv = NS_OK; + if (!aRequest) + return NS_ERROR_NULL_POINTER; + // First of all, get the content type and make sure it is a + // content type we know how to handle! + if (mMimeType.Equals(aContentType)) + { + nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest); + if(!channel) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + rv = channel->GetURI(getter_AddRefs(uri)); + if (NS_FAILED(rv)) return rv; + + aRequest->Cancel(NS_BINDING_ABORTED); + if (uri) + { + nsCOMPtr<nsIExternalProtocolService> ps = + do_GetService (NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv) || !ps) return NS_ERROR_FAILURE; + ps->LoadUrl (uri); + } + } + return rv; +} diff --git a/embed/mozilla/BaseProtocolContentHandler.h b/embed/mozilla/BaseProtocolContentHandler.h new file mode 100644 index 000000000..b1f5c1e71 --- /dev/null +++ b/embed/mozilla/BaseProtocolContentHandler.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BaseProtocolContentHandler_h_ +#define _BaseProtocolContentHandler_h_ + +#include "BaseProtocolHandler.h" +#include "nsIContentHandler.h" + +#include "nsString.h" + +class GBaseProtocolContentHandler : public GBaseProtocolHandler, + public nsIContentHandler +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICONTENTHANDLER + + NS_IMETHODIMP NewChannel(nsIURI *aURI, nsIChannel **_retval); + + GBaseProtocolContentHandler (const char *aScheme); + virtual ~GBaseProtocolContentHandler(); + /* additional members */ + protected: + nsCString mMimeType; +}; + +#endif //_BaseProtocolContentHandler_h_ diff --git a/embed/mozilla/BaseProtocolHandler.cpp b/embed/mozilla/BaseProtocolHandler.cpp new file mode 100644 index 000000000..728465a15 --- /dev/null +++ b/embed/mozilla/BaseProtocolHandler.cpp @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "nsCOMPtr.h" +#include "nsIComponentManager.h" +#include "nsIURI.h" +#include "nsNetCID.h" + +#include "BaseProtocolHandler.h" + +static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); + +/* Implementation file */ +NS_IMPL_ISUPPORTS1 (GBaseProtocolHandler, nsIProtocolHandler) + +GBaseProtocolHandler::GBaseProtocolHandler(const char *aScheme) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + mScheme.Assign(aScheme); +} + +GBaseProtocolHandler::~GBaseProtocolHandler() +{ + /* destructor code */ +} + +/* readonly attribute string scheme; */ +NS_IMETHODIMP GBaseProtocolHandler::GetScheme(nsACString &aScheme) +{ + aScheme = mScheme; + return NS_OK; +} + +/* readonly attribute long defaultPort; */ +NS_IMETHODIMP GBaseProtocolHandler::GetDefaultPort(PRInt32 *aDefaultPort) +{ + if (aDefaultPort) + *aDefaultPort = -1; + else + return NS_ERROR_NULL_POINTER; + return NS_OK; +} + +/* readonly attribute short protocolFlags; */ +NS_IMETHODIMP GBaseProtocolHandler::GetProtocolFlags(PRUint32 *aProtocolFlags) +{ + if (aProtocolFlags) + *aProtocolFlags = nsIProtocolHandler::URI_STD; + else + return NS_ERROR_NULL_POINTER; + return NS_OK; +} + +/* nsIURI newURI (in string aSpec, in nsIURI aBaseURI); */ +NS_IMETHODIMP GBaseProtocolHandler::NewURI(const nsACString &aSpec, + const char *aOriginCharset, nsIURI *aBaseURI, + nsIURI **_retval) +{ + nsresult rv = NS_OK; + nsCOMPtr <nsIURI> newUri; + + rv = nsComponentManager::CreateInstance(kSimpleURICID, nsnull, + NS_GET_IID(nsIURI), + getter_AddRefs(newUri)); + + if (NS_SUCCEEDED(rv)) + { + newUri->SetSpec(aSpec); + rv = newUri->QueryInterface(NS_GET_IID(nsIURI), + (void **) _retval); + } + return rv; + +} + +/* nsIChannel newChannel (in nsIURI aURI); */ +NS_IMETHODIMP GBaseProtocolHandler::NewChannel(nsIURI *aURI, + nsIChannel **_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* boolean allowPort (in long port, in string scheme); */ +NS_IMETHODIMP GBaseProtocolHandler::AllowPort(PRInt32 port, const char *scheme, + PRBool *_retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + diff --git a/embed/mozilla/BaseProtocolHandler.h b/embed/mozilla/BaseProtocolHandler.h new file mode 100644 index 000000000..ab25a680d --- /dev/null +++ b/embed/mozilla/BaseProtocolHandler.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _BaseProtocolHandler_h_ +#define _BaseProtocolHandler_h_ + +#include "nsIProtocolHandler.h" + +#include "nsString.h" + +class GBaseProtocolHandler : public nsIProtocolHandler +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPROTOCOLHANDLER + + GBaseProtocolHandler (const char *aScheme); + virtual ~GBaseProtocolHandler(); + /* additional members */ + protected: + nsCString mScheme; +}; + +#endif //_BaseProtocolHandler_h_ diff --git a/embed/mozilla/ContentHandler.cpp b/embed/mozilla/ContentHandler.cpp new file mode 100644 index 000000000..9476a2f72 --- /dev/null +++ b/embed/mozilla/ContentHandler.cpp @@ -0,0 +1,671 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * The functioning of the download architecture, as described by Philip + * on 28 May 2001 and updated on 28 June 2001: + * + * When mozilla runs into a file it cannot render internally or that it + * does not have a plugin for, it calls the + * nsIExternalHelperAppService. This service will then either attempt to + * save the file or run it with a helper app depending on what the + * mozilla mime database returns. + * + * nsIExternalHelperAppService then calls out to the nsIHelperAppDialog + * interface which handles the UI for the service. This is the interface + * which we have reimplemented. Therefore, with a major caveat, we have + * put a GNOME/GTK frontend on an unmodified mozilla backend. + * + * Now for the caveat. With respect to saving files to disk, the mozilla + * backend works exactly the same as it does in + * mozilla-the-browser. However, for dealing with helper apps, we do not + * use the mozilla backend at all. This is because we want to use the + * gnome-vfs database to retrieve helper-app info, rather than the + * mozilla helper app database. + * + * How it works: + * + * a) The user clicks on a link or follows a redirect to a file of a type + * that mozilla cannot handle. Mozilla passes the link to the + * ExternalHelperAppService which in turn calls the Show() method of + * nsIHelperAppDialog. + * + * b) In our implementation of Show() we first compare the passed mime + * type to epiphany's mime list. If the mime type is in the list, we then + * lookup the Action associated with the mime type. Currently, the + * possible mime-actions are: + * + * Save to Disk + * Run with Helper App + * Ask User + * + * The default action is Ask User, and if the mime-type is not in our + * list, this is what will be assumed. + * + * c) If Ask User is the chosen action, a dialog will be shown to the + * user allowing the user to choose from the other two possible actions + * as well as a checkbox to let the user set the default action to the + * chosen action for the future. + * + * d-1) The "Save to Disk" action. We first check epiphany preferences to + * see if the user wants to use the built-in mozilla downloader, gtm or + * a command-line executed downloader. + * + * d-2a) The built-in downloader. This action is handled by the mozilla + * backend. Our nsIHelperAppDialog does the same thing that the + * mozilla-the-browser one does, which is to call the SaveToDisk() method + * of nsIExternalHelperAppService. This in turn calls the + * PromptForSaveToFile() method of nsIHelperAppDialog putting the ball + * back in our court. + * + * d-2b) Now, if epiphany is configured to always ask for a download + * directory, it will pop up a file selector so that the user can select + * the directory and filename to save the file to. Otherwise, it will + * use epiphany's default download directory and proceed without + * interaction. + * + * d-2c) When PromptForSaveToFile() returns, nsIExternalHelperAppService + * will then call the ShowProgressDialog() method of + * nsIHelperAppDialog. This progress dialog, obviously, tracks the + * progress of the download. It is worth noting that mozilla starts the + * actual download as soon as the user clicks on the link or follows the + * redirect. While the user is deciding what action to take, the file is + * downloading. Often, for small files, the file is already downloaded + * when the user decides what directory to put it in. The progress dialog + * does not appear in these cases. Also, we currently have a small + * problem where our progress dialog times the download from the point + * the dialog appears, not from the time the download starts. This is due + * to the timestamp that is passed to us is just plain weird, and I + * haven't worked out how to turn it into a useable time. The fact that + * the download starts early means that the file is actually downloaded + * to a temp file and only at the end is it moved to it's final location. + * + * d-3a) The two external downloader options. These options are + * handled completely by epiphany. The first thing that we do is call the + * Cancel() method of nsIExternalHelperAppService to cancel the mozilla + * download. We then pass the url to our own LaunchExternalDownloader() + * method. This method will ask for a download directory as appropriate + * as with the "Save to disk" action. + * + * d-3b) Finally, depending on whether GTM or a command line handler was + * selected in prefs, the external handler will be called with the url + * passed and the directory selected. + * + * e-1) The "Run with Helper App" action. This action is currently only + * working with a minimal implementation. First, we explicitly call + * ShowProgressDialog() so the user knows that the file is being + * downloaded. We also need this so that we only run the helper after the + * file is completely downloaded. The file will download to temp location + * that it would be moved from if the action was "Save to Disk". We have + * to call ShowProgressDialog() ourselves because we are not using + * mozilla's helper mechanism which would usually make the call for us. + * + * e-2) If there is a default helper app in our mime database and alwaysAsk + * is false, epiphany will run the default helper automatically. Otherwise it + * will pop up a helper chooser dialog which lists the helpers that gnome-vfs + * knows about as well as providing a GnomeFileEntry to allow the user to + * select and arbitrary application. The default value of the GnomeFileEntry + * is the helper stored in our database if one exits. + * + * f) General notes. We cannot use this infrastructure to override + * native mozilla types. mozilla will attempt to render these types and + * never call out to us. We are at the end of the chain as the handler of + * last resort, so native and plugin types will never reach us. This also + * means that a file with an incorrect mime-type ( eg: .tar.bz2 marked as + * text/plain ) will be incorrectly rendered by mozilla. We cannot help + * this. + * + * Despite the apparent user-side similarity with explicit downloads by + * a shift-click or context-menu item, there is actually none at all. + * Explicit downloads are handled by the nsIStreamTransfer manager which + * we use as is. Currently the progress dialog for the stream transfer + * manager is un-overridable, so it appears in XUL. This will change in + * due course. + * + * Matt would like the modifiy the progress dialog so each file currently + * being downloaded becomes a clist entry in a master dialog rather than + * causing a separate progress dialog. a lot of progress dialogs gets + * really messy. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +extern "C" { +#include "libgnomevfs/gnome-vfs-mime-handlers.h" +} + +#include "ephy-embed-shell.h" +#include "ephy-prefs.h" +#include "eel-gconf-extensions.h" +#include "ephy-glade.h" +#include "ephy-string.h" +#include "ephy-gui.h" +#include "ephy-embed-utils.h" +#include "ephy-file-helpers.h" +#include "ProgressListener.h" +#include "ContentHandler.h" + +#include <gtk/gtkentry.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkprogress.h> +#include <gtk/gtkoptionmenu.h> +#include <libgnome/gnome-exec.h> +#include <libgnome/gnome-i18n.h> +#include <libgnome/gnome-config.h> +#include <libgnome/gnome-util.h> +#include <libgnomevfs/gnome-vfs-mime.h> + +#include "FilePicker.h" +#include "MozillaPrivate.h" + +#include "nsCRT.h" +#include "nsCOMPtr.h" +#include "nsIFactory.h" +#include "nsISupportsArray.h" +#include "nsIServiceManager.h" +#include "nsWeakReference.h" +#include "nsXPComFactory.h" + +#include "nsString.h" +#include "nsIURI.h" +#include "nsIURL.h" +#include "nsIMIMEInfo.h" +#include "nsIChannel.h" +#include "nsIFTPChannel.h" +#include "nsILocalFile.h" +#include "nsIPrefService.h" +#include "nsIDOMWindow.h" +#include "nsIDOMWindowInternal.h" + +class GContentHandler; +class GDownloadProgressListener; +struct MimeAskActionDialog; +struct HelperAppChooserDialog; + +extern "C" +void mime_ask_dialog_save_clicked_cb (GtkButton *button, + MimeAskActionDialog *dialog); +extern "C" +void mime_ask_dialog_open_clicked_cb (GtkButton *button, + MimeAskActionDialog *dialog); +extern "C" +gint mime_ask_dialog_cancel_clicked_cb (GtkButton *button, + MimeAskActionDialog *dialog); + +/* + * MimeAskActionDialog: the representation of dialogs used to ask + * about actions on MIME types + */ +struct MimeAskActionDialog +{ + MimeAskActionDialog(GContentHandler *aContentHandler, + GtkWidget *aParentWidget, + const char *aMimeType); + ~MimeAskActionDialog(); + + GContentHandler *mContentHandler; + GladeXML *mGXml; + GtkWidget *mParent; + GtkWidget *mAppMenu; + + GnomeVFSMimeApplication *mDefaultApp; +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS1(GContentHandler, nsIHelperAppLauncherDialog) + +GContentHandler::GContentHandler() : mUri(nsnull), + mMimeType(nsnull), + mDownloadCanceled(PR_FALSE), + mHelperProgress(PR_FALSE) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ +} + +GContentHandler::~GContentHandler() +{ + /* destructor code */ + g_free (mUri); + g_free (mMimeType); +} + +//////////////////////////////////////////////////////////////////////////////// +// begin nsIHelperAppLauncher impl +//////////////////////////////////////////////////////////////////////////////// + +/* void show (in nsIHelperAppLauncher aLauncher, in nsISupports aContext); */ +NS_IMETHODIMP GContentHandler::Show(nsIHelperAppLauncher *aLauncher, + nsISupports *aContext) +{ + nsresult rv; + + mLauncher = aLauncher; + mContext = aContext; + rv = Init (); + + MIMEAskAction (); + + return NS_OK; +} + +/* nsILocalFile promptForSaveToFile (in nsISupports aWindowContext, in wstring aDefaultFile, in wstring aSuggestedFileExtension); */ +NS_IMETHODIMP GContentHandler:: + PromptForSaveToFile(nsISupports *aWindowContext, + const PRUnichar *aDefaultFile, + const PRUnichar *aSuggestedFileExtension, + nsILocalFile **_retval) +{ + nsresult rv; + + mContext = aWindowContext; + + nsCOMPtr<nsIDOMWindowInternal> windowInternal = + do_QueryInterface (aWindowContext); + + nsCOMPtr<nsILocalFile> saveDir; + char *dirName; + + /* FIXME persist download dir */ + dirName = g_strdup (g_get_home_dir()); + + saveDir = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + saveDir->InitWithPath (NS_ConvertUTF8toUCS2(dirName)); + g_free (dirName); + + nsCOMPtr <nsILocalFile> saveFile (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + + PRInt16 okToSave = nsIFilePicker::returnCancel; + + if (okToSave == nsIFilePicker::returnCancel) + { + nsCOMPtr<nsIFilePicker> filePicker = + do_CreateInstance (G_FILEPICKER_CONTRACTID); + + const nsAString &title = NS_ConvertUTF8toUCS2(_("Select the destination filename")); + + filePicker->Init (windowInternal, + PromiseFlatString(title).get(), + nsIFilePicker::modeSave); + filePicker->SetDefaultString (aDefaultFile); + filePicker->SetDisplayDirectory (saveDir); + + filePicker->Show (&okToSave); + + if (okToSave == nsIFilePicker::returnOK) + { + filePicker->GetFile (getter_AddRefs(saveFile)); + } + } + + if (okToSave == nsIFilePicker::returnCancel) + return NS_ERROR_FAILURE; + else + { + nsCOMPtr<nsIFile> directory; + rv = saveFile->GetParent (getter_AddRefs(directory)); + + NS_IF_ADDREF (*_retval = saveFile); + return NS_OK; + } +} + +/* void showProgressDialog (in nsIHelperAppLauncher aLauncher, in nsISupports aContext); */ +NS_METHOD GContentHandler::ShowProgressDialog(nsIHelperAppLauncher *aLauncher, + nsISupports *aContext) +{ + g_print ("GContentHandler::ShowProgressDialog is depreciated!\n"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin local public methods impl +//////////////////////////////////////////////////////////////////////////////// + +NS_METHOD GContentHandler::FindHelperApp (void) +{ + if (mUrlHelper) + { + return LaunchHelperApp (); + } + else + { + if (NS_SUCCEEDED(SynchroniseMIMEInfo())) + { + return mLauncher->LaunchWithApplication(nsnull, PR_FALSE); + } + else + { + return NS_ERROR_FAILURE; + } + } +} + +NS_METHOD GContentHandler::LaunchHelperApp (void) +{ + if (mMimeType) + { + nsresult rv; + nsCOMPtr<nsIExternalHelperAppService> helperService = + do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID); + + nsCOMPtr<nsPIExternalAppLauncher> appLauncher = + do_QueryInterface (helperService, &rv); + if (NS_SUCCEEDED(rv)) + { + appLauncher->DeleteTemporaryFileOnExit(mTempFile); + } + + nsString uFileName; + mTempFile->GetPath(uFileName); + const nsCString &aFileName = NS_ConvertUCS2toUTF8(uFileName); + + const nsCString &document = (mUrlHelper) ? mUrl : aFileName; + + char *param = g_strdup (document.get()); + ephy_file_launch_application (mHelperApp->command, + param, + mHelperApp->requires_terminal); + + if(mUrlHelper) mLauncher->Cancel(); + + g_free (param); + } + else + { + mLauncher->Cancel (); + } + + return NS_OK; +} + +NS_METHOD GContentHandler::ShowHelperProgressDialog (void) +{ + mHelperProgress = PR_TRUE; + return ShowProgressDialog (mLauncher,mContext); +} + +NS_METHOD GContentHandler::GetLauncher (nsIHelperAppLauncher * *_retval) +{ + NS_IF_ADDREF (*_retval = mLauncher); + return NS_OK; +} + +NS_METHOD GContentHandler::GetContext (nsISupports * *_retval) +{ + NS_IF_ADDREF (*_retval = mContext); + return NS_OK; +} + +static gboolean +application_support_scheme (GnomeVFSMimeApplication *app, const nsCString &aScheme) +{ + GList *l; + + g_return_val_if_fail (app != NULL, FALSE); + g_return_val_if_fail (!aScheme.IsEmpty(), FALSE); + + if (app->expects_uris != GNOME_VFS_MIME_APPLICATION_ARGUMENT_TYPE_URIS) + return FALSE; + + for (l = app->supported_uri_schemes; l != NULL; l = l->next) + { + char *uri_scheme = (char *)l->data; + g_return_val_if_fail (uri_scheme != NULL, FALSE); + if (aScheme.Equals(uri_scheme)) return TRUE; + } + + return FALSE; +} + +NS_METHOD GContentHandler::SetHelperApp(GnomeVFSMimeApplication *aHelperApp, + PRBool alwaysUse) +{ + mHelperApp = aHelperApp; + mUrlHelper = application_support_scheme (aHelperApp, mScheme); + + return NS_OK; +} + +NS_METHOD GContentHandler::SynchroniseMIMEInfo (void) +{ + nsresult rv; + nsCOMPtr<nsIMIMEInfo> mimeInfo; + rv = mLauncher->GetMIMEInfo(getter_AddRefs(mimeInfo)); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsILocalFile> helperFile; + rv = NS_NewNativeLocalFile(nsDependentCString(mHelperApp->command), + PR_TRUE, + getter_AddRefs(helperFile)); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + rv = mimeInfo->SetPreferredApplicationHandler(helperFile); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsMIMEInfoHandleAction mimeInfoAction; + mimeInfoAction = nsIMIMEInfo::alwaysAsk; + + if(mHelperApp->requires_terminal) //Information passing kludge! + { + rv = mimeInfo->SetApplicationDescription + (NS_LITERAL_STRING("runInTerminal").get()); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + } + + rv = mimeInfo->SetPreferredAction(mimeInfoAction); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin local private methods impl +//////////////////////////////////////////////////////////////////////////////// +NS_METHOD GContentHandler::Init (void) +{ + nsresult rv; + + nsCOMPtr<nsIMIMEInfo> MIMEInfo; + rv = mLauncher->GetMIMEInfo (getter_AddRefs(MIMEInfo)); + rv = MIMEInfo->GetMIMEType (&mMimeType); + + rv = mLauncher->GetDownloadInfo(getter_AddRefs(mUri), + &mTimeDownloadStarted, + getter_AddRefs(mTempFile)); + rv = mUri->GetSpec (mUrl); + rv = mUri->GetScheme (mScheme); +#if 0 + /* GetSource seems redundant and isn't in 0.9 This code is here while + it remains unclear what GetSource is for. --phil */ + nsCOMPtr<nsIURI> uri; + rv = mLauncher->GetSource(getter_AddRefs(uri)); + rv = uri->GetSpec (mUrl); +#endif + ProcessMimeInfo (); + + return NS_OK; +} + +NS_METHOD GContentHandler::ProcessMimeInfo (void) +{ + if (mMimeType == NULL || + !nsCRT::strcmp(mMimeType, "application/octet-stream")) + { + nsresult rv; + nsCOMPtr<nsIURL> url = do_QueryInterface(mUri, &rv); + if (NS_SUCCEEDED(rv) && url) + { + nsCAutoString uriFileName; + url->GetFileName(uriFileName); + mMimeType = g_strdup + (gnome_vfs_mime_type_from_name + (uriFileName.get())); + } + else + mMimeType = g_strdup ("application/octet-stream"); + } + + return NS_OK; +} + +NS_METHOD GContentHandler::MIMEAskAction (void) +{ + nsCOMPtr<nsIDOMWindow> parent = do_QueryInterface (mContext); + GtkWidget *parentWidget = MozillaFindGtkParent (parent); + + new MimeAskActionDialog(this, parentWidget, mMimeType); + + return NS_OK; +} + +//------------------------------------------------------------------------------ + +NS_DEF_FACTORY (GContentHandler, GContentHandler); + +/** + * NS_NewContentHandlerFactory: + */ +nsresult NS_NewContentHandlerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGContentHandlerFactory *result = new nsGContentHandlerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin MIMEAskActionDialog methods. +//////////////////////////////////////////////////////////////////////////////// + +MimeAskActionDialog::MimeAskActionDialog(GContentHandler *aContentHandler, + GtkWidget *aParentWidget, + const char *aMimeType) : + mContentHandler(aContentHandler), + mParent(aParentWidget) +{ + GtkWidget *label; + GtkWidget *dialogWidget; + const char *description; + char ltext[255]; //philipl: Fixed length buffer == potential security problem... + + mGXml = ephy_glade_widget_new ("epiphany.glade", "mime_ask_action_dialog", + &dialogWidget, this); + mAppMenu = glade_xml_get_widget (mGXml, "mime_ask_dialog_app_menu"); + + mDefaultApp = gnome_vfs_mime_get_default_application(aMimeType); + + GtkWidget *aMimeIcon = glade_xml_get_widget (mGXml, + "mime_ask_action_icon"); + gtk_image_set_from_file(GTK_IMAGE(aMimeIcon), + gnome_vfs_mime_get_icon(aMimeType)); + + description = gnome_vfs_mime_get_description (aMimeType); + if (!description) description = aMimeType; + + g_snprintf (ltext, 255, "<b>%s</b>", description); + label = glade_xml_get_widget (mGXml, "mime_ask_action_description"); + gtk_label_set_markup (GTK_LABEL (label), ltext); + + gtk_window_set_transient_for (GTK_WINDOW (dialogWidget), + GTK_WINDOW (aParentWidget)); + + gtk_widget_show(dialogWidget); +} + +MimeAskActionDialog::~MimeAskActionDialog() +{ +#if 0 + if(mApps) + gnome_vfs_mime_application_list_free(mApps); +#endif + + gtk_widget_destroy(glade_xml_get_widget(mGXml, "mime_ask_action_dialog")); + g_object_unref(G_OBJECT(mGXml)); +} + +//////////////////////////////////////////////////////////////////////////////// +// begin MIMEAskActionDialog callbacks. +//////////////////////////////////////////////////////////////////////////////// + +extern "C" void +mime_ask_dialog_save_clicked_cb (GtkButton *button, MimeAskActionDialog *dialog) +{ + gtk_widget_hide (glade_xml_get_widget (dialog->mGXml, + "mime_ask_action_dialog")); + + nsresult rv; + nsCOMPtr<nsIHelperAppLauncher> launcher; + rv = dialog->mContentHandler->GetLauncher (getter_AddRefs(launcher)); + + launcher->SaveToDisk (nsnull,PR_FALSE); + + delete dialog; +} + +static void +mime_ask_dialog_download_cancel (MimeAskActionDialog *dialog) +{ + nsresult rv; + nsCOMPtr<nsIHelperAppLauncher> launcher; + rv = dialog->mContentHandler->GetLauncher (getter_AddRefs(launcher)); + + launcher->Cancel (); + + delete dialog; +} + +extern "C" void +mime_ask_dialog_open_clicked_cb (GtkButton *button, MimeAskActionDialog *dialog) +{ + nsresult rv; + nsCOMPtr<nsIHelperAppLauncher> launcher; + rv = dialog->mContentHandler->GetLauncher (getter_AddRefs(launcher)); + GnomeVFSMimeApplication *app = dialog->mDefaultApp; + + if (app) + { + dialog->mContentHandler->SetHelperApp (app, FALSE); + dialog->mContentHandler->FindHelperApp (); + delete dialog; + } + else + { + mime_ask_dialog_download_cancel (dialog); + ephy_embed_utils_nohandler_dialog_run (dialog->mParent); + } +} + +extern "C" gint +mime_ask_dialog_cancel_clicked_cb (GtkButton *button, + MimeAskActionDialog *dialog) +{ + mime_ask_dialog_download_cancel (dialog); + return 0; /* FIXME: philipl, is this the right thing to return? */ +} diff --git a/embed/mozilla/ContentHandler.h b/embed/mozilla/ContentHandler.h new file mode 100644 index 000000000..6ae61f657 --- /dev/null +++ b/embed/mozilla/ContentHandler.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ContentHandler_h +#define __ContentHandler_h + +#include "mozilla-embed-shell.h" + +#include <libgnomevfs/gnome-vfs-mime-handlers.h> +#include "nsIHelperAppLauncherDialog.h" +#include "nsIExternalHelperAppService.h" +#include "nsCExternalHandlerService.h" +#include "nsIWebProgressListener.h" + +#include "nsString.h" +#include "nsIURI.h" +#include "nsILocalFile.h" + +#include "nsCOMPtr.h" +#include "nsISupports.h" +#include "nsError.h" + +typedef enum +{ + ACTION_NONE, + ACTION_SAVEFORHELPER, + ACTION_OBJECT_NOTIFY +} DownloadAction; + +#define G_CONTENTHANDLER_CID \ +{ /* 16072c4a-23a6-4996-9beb-9335c06bbeae */ \ + 0x16072c4a, \ + 0x23a6, \ + 0x4996, \ + {0x9b, 0xeb, 0x93, 0x35, 0xc0, 0x6b, 0xbe, 0xae} \ +} + +class nsIFactory; + +class GContentHandler : public nsIHelperAppLauncherDialog +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIHELPERAPPLAUNCHERDIALOG + + GContentHandler(); + virtual ~GContentHandler(); + + NS_METHOD FindHelperApp (void); + NS_METHOD LaunchHelperApp (void); + NS_METHOD ShowHelperProgressDialog (void); + + NS_METHOD GetLauncher (nsIHelperAppLauncher * *_retval); + NS_METHOD GetContext (nsISupports * *_retval); + NS_METHOD SetHelperApp(GnomeVFSMimeApplication *mHelperApp, + PRBool alwaysUse); + NS_METHOD SynchroniseMIMEInfo (void); + + private: + /* additional members */ + NS_METHOD Init (void); + NS_METHOD ProcessMimeInfo (void); + NS_METHOD MIMEAskAction (void); + + nsCOMPtr<nsIHelperAppLauncher> mLauncher; + nsCOMPtr<nsISupports> mContext; + + nsCOMPtr<nsIURI> mUri; + PRInt64 mTimeDownloadStarted; + nsCOMPtr<nsIFile> mTempFile; + + char *mMimeType; + PRBool mUrlHelper; + GnomeVFSMimeApplication *mHelperApp; + + nsCString mUrl; + nsCString mScheme; + + PRBool mDownloadCanceled; + PRBool mHelperProgress; + + nsCOMPtr<nsIWebProgressListener> mListener; +}; + +extern nsresult NS_NewContentHandlerFactory(nsIFactory** aFactory); + +#endif diff --git a/embed/mozilla/EphyEventListener.cpp b/embed/mozilla/EphyEventListener.cpp new file mode 100644 index 000000000..de696bf1e --- /dev/null +++ b/embed/mozilla/EphyEventListener.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <nsCOMPtr.h> + +#include "EphyEventListener.h" +#include "nsIDOMNode.h" +#include "nsIDOMElement.h" +#include "nsString.h" +#include "nsUnicharUtils.h" +#include "nsIDOMDocument.h" +#include "nsIURI.h" +#include "nsIDocument.h" +#include "nsIDOMEventTarget.h" +#include "nsIDOMEvent.h" + +EphyEventListener::EphyEventListener(void) +{ + NS_INIT_ISUPPORTS(); + mOwner = nsnull; +} + +EphyEventListener::~EphyEventListener() +{ +} + +NS_IMPL_ISUPPORTS1(EphyEventListener, nsIDOMEventListener) + +nsresult +EphyEventListener::Init(EphyEmbed *aOwner) +{ + mOwner = aOwner; + return NS_OK; +} + +nsresult +EphyEventListener::HandleFaviconLink (nsIDOMNode *node) +{ + nsresult result; + + nsCOMPtr<nsIDOMElement> linkElement; + linkElement = do_QueryInterface (node); + if (!linkElement) return NS_ERROR_FAILURE; + + NS_NAMED_LITERAL_STRING(attr_rel, "rel"); + nsAutoString value; + result = linkElement->GetAttribute (attr_rel, value); + if (NS_FAILED(result)) return NS_ERROR_FAILURE; + + if (value.Equals(NS_LITERAL_STRING("SHORTCUT ICON"), + nsCaseInsensitiveStringComparator()) || + value.Equals(NS_LITERAL_STRING("ICON"), + nsCaseInsensitiveStringComparator())) + { + NS_NAMED_LITERAL_STRING(attr_href, "href"); + nsAutoString value; + result = linkElement->GetAttribute (attr_href, value); + if (NS_FAILED (result) || value.IsEmpty()) + return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMDocument> domDoc; + result = node->GetOwnerDocument(getter_AddRefs(domDoc)); + if (NS_FAILED(result) || !domDoc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocument> doc = do_QueryInterface (domDoc); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + result = doc->GetDocumentURL(getter_AddRefs(uri)); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + const nsACString &link = NS_ConvertUCS2toUTF8(value); + nsCAutoString favicon_url; + result = uri->Resolve (link, favicon_url); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + char *url = g_strdup (favicon_url.get()); + g_signal_emit_by_name (mOwner, "ge_favicon", url); + g_free (url); + } + + return NS_OK; +} + +NS_IMETHODIMP +EphyEventListener::HandleEvent(nsIDOMEvent* aDOMEvent) +{ + nsCOMPtr<nsIDOMEventTarget> eventTarget; + + aDOMEvent->GetTarget(getter_AddRefs(eventTarget)); + + nsresult result; + nsCOMPtr<nsIDOMNode> node = do_QueryInterface(eventTarget, &result); + if (NS_FAILED(result) || !node) return NS_ERROR_FAILURE; + + HandleFaviconLink (node); + + return NS_OK; +} diff --git a/embed/mozilla/EphyEventListener.h b/embed/mozilla/EphyEventListener.h new file mode 100644 index 000000000..32f84e904 --- /dev/null +++ b/embed/mozilla/EphyEventListener.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_EVENT_LISTENER_H +#define EPHY_EVENT_LISTENER_H + +#include "ephy-embed.h" + +#include <nsIDOMEventListener.h> + +class EphyEventListener : public nsIDOMEventListener +{ +public: + EphyEventListener(); + virtual ~EphyEventListener(); + + nsresult Init(EphyEmbed *aOwner); + + NS_DECL_ISUPPORTS + + // nsIDOMEventListener + + NS_IMETHOD HandleEvent(nsIDOMEvent* aEvent); + +private: + EphyEmbed *mOwner; + + nsresult HandleFaviconLink (nsIDOMNode *node); +}; + +#endif diff --git a/embed/mozilla/EphyWrapper.cpp b/embed/mozilla/EphyWrapper.cpp new file mode 100644 index 000000000..ade9e67b2 --- /dev/null +++ b/embed/mozilla/EphyWrapper.cpp @@ -0,0 +1,1384 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "EphyWrapper.h" +#include "GlobalHistory.h" +#include "ProgressListener.h" +#include "PrintProgressListener.h" +#include "ephy-embed.h" +#include "ephy-string.h" + +#include <gtkmozembed_internal.h> +#include <unistd.h> + +#include "nsIContentViewer.h" +#include "nsIPermissionManager.h" +#include "nsIGlobalHistory.h" +#include "nsIDocShellHistory.h" +#include "nsIWebBrowserFind.h" +#include "nsIWebBrowserFocus.h" +#include "nsIDocument.h" +#include "nsISHEntry.h" +#include "nsISHistoryInternal.h" +#include "nsIHistoryEntry.h" +#include "nsIWebBrowserPrint.h" +#include "nsIURI.h" +#include "nsIPresShell.h" +#include "nsIMarkupDocumentViewer.h" +#include "nsIComponentManager.h" +#include "nsIDOMElement.h" +#include "nsIDOMNodeList.h" +#include "nsIScriptGlobalObject.h" +#include "nsIScriptContext.h" + +#include "nsIDOMWindowInternal.h" +#include "nsICharsetConverterManager.h" +#include "nsICharsetConverterManager2.h" +#include "nsIInterfaceRequestor.h" +#include "nsIFocusController.h" +#include "nsIWebBrowserPersist.h" +#include "nsCWebBrowserPersist.h" +#include "nsNetUtil.h" +#include "nsIChromeEventHandler.h" +#include "nsIClipboardCommands.h" +#include "nsIDOMDocumentStyle.h" +#include "nsIDocShellTreeItem.h" +#include "nsIDocShellTreeNode.h" +#include "nsIDocShellTreeOwner.h" +#include "nsIHTMLContentContainer.h" +#include "nsICSSLoader.h" +#include "nsICSSStyleSheet.h" +#include "nsICSSLoaderObserver.h" +#include "nsIStyleSet.h" +#include "nsIDocumentObserver.h" +#include "nsCWebBrowser.h" +#include "nsReadableUtils.h" +#include "nsUnicharUtils.h" +#include "nsIDOMNSHTMLDocument.h" +#include "nsIDOMHTMLDocument.h" +#include "nsIDOMHTMLCollection.h" +#include "nsIDOMHTMLElement.h" +#include "nsIDOMHTMLImageElement.h" +#include "nsIDOMHTMLFormElement.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "caps/nsIPrincipal.h" +#include "nsIDeviceContext.h" +#include "nsIPresContext.h" +#include "ContentHandler.h" +#include "nsITypeAheadFind.h" +#include "nsSupportsPrimitives.h" +#include "EphyEventListener.h" + +EphyWrapper::EphyWrapper () +{ +} + +EphyWrapper::~EphyWrapper () +{ +} + +nsresult EphyWrapper::Init (GtkMozEmbed *mozembed) +{ + nsresult result; + + gtk_moz_embed_get_nsIWebBrowser (mozembed, + getter_AddRefs(mWebBrowser)); + if (!mWebBrowser) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocShellHistory> dsHistory = do_QueryInterface (DocShell); + if (!dsHistory) return NS_ERROR_FAILURE; + + static NS_DEFINE_CID(kGlobalHistoryCID, GALEON_GLOBALHISTORY_CID); + + nsCOMPtr<nsIFactory> GHFactory; + result = NS_NewGlobalHistoryFactory(getter_AddRefs(GHFactory)); + if (NS_FAILED(result)) return NS_ERROR_FAILURE; + + result = nsComponentManager::RegisterFactory(kGlobalHistoryCID, + "Global history", + NS_GLOBALHISTORY_CONTRACTID, + GHFactory, + PR_TRUE); + + nsCOMPtr<nsIGlobalHistory> inst = + do_GetService(NS_GLOBALHISTORY_CONTRACTID, &result); + + mEventListener = new EphyEventListener(); + mEventListener->Init (EPHY_EMBED (mozembed)); + GetListener(); + AttachListeners(); + + return dsHistory->SetGlobalHistory(inst); +} + +void +EphyWrapper::GetListener (void) +{ + if (mEventReceiver) return; + + nsCOMPtr<nsIDOMWindow> domWindowExternal; + mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindowExternal)); + + nsCOMPtr<nsIDOMWindowInternal> domWindow; + domWindow = do_QueryInterface(domWindowExternal); + + nsCOMPtr<nsPIDOMWindow> piWin(do_QueryInterface(domWindow)); + if (!piWin) return; + + nsCOMPtr<nsIChromeEventHandler> chromeHandler; + piWin->GetChromeEventHandler(getter_AddRefs(chromeHandler)); + + mEventReceiver = do_QueryInterface(chromeHandler); +} + +void +EphyWrapper::AttachListeners(void) +{ + if (!mEventReceiver || mListenersAttached) + return; + + nsCOMPtr<nsIDOMEventTarget> target; + target = do_QueryInterface (mEventReceiver); + + target->AddEventListener(NS_LITERAL_STRING("DOMLinkAdded"), mEventListener, PR_FALSE); + + mListenersAttached = PR_TRUE; +} + +void +EphyWrapper::DetachListeners(void) +{ + if (!mListenersAttached || !mEventReceiver) + return; + + nsCOMPtr<nsIDOMEventTarget> target; + target = do_QueryInterface (mEventReceiver); + + target->RemoveEventListener(NS_LITERAL_STRING("DOMLinkAdded"), mEventListener, PR_FALSE); +} + +nsresult EphyWrapper::GetDocShell (nsIDocShell **aDocShell) +{ + nsCOMPtr<nsIDocShellTreeItem> browserAsItem; + browserAsItem = do_QueryInterface(mWebBrowser); + if (!browserAsItem) return NS_ERROR_FAILURE; + + // get the owner for that item + nsCOMPtr<nsIDocShellTreeOwner> treeOwner; + browserAsItem->GetTreeOwner(getter_AddRefs(treeOwner)); + if (!treeOwner) return NS_ERROR_FAILURE; + + // get the primary content shell as an item + nsCOMPtr<nsIDocShellTreeItem> contentItem; + treeOwner->GetPrimaryContentShell(getter_AddRefs(contentItem)); + if (!contentItem) return NS_ERROR_FAILURE; + + // QI that back to a docshell + nsCOMPtr<nsIDocShell> DocShell; + DocShell = do_QueryInterface(contentItem); + if (!DocShell) return NS_ERROR_FAILURE; + + *aDocShell = DocShell.get(); + + NS_IF_ADDREF(*aDocShell); + + return NS_OK; +} +nsresult EphyWrapper::Print (nsIPrintSettings *options, PRBool preview) +{ + nsresult result; + + nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser, &result)); + if (NS_FAILED(result) || !print) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = mWebBrowser->GetContentDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + if (!preview) + { + GPrintListener *listener = new GPrintListener(); + result = print->Print (options, listener); + } + else + { + result = print->PrintPreview(options, nsnull, nsnull); + } + + return result; +} + +nsresult EphyWrapper::PrintPreviewClose (void) +{ + nsresult rv; + PRBool isPreview = PR_FALSE; + + nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser, &rv)); + if (NS_FAILED(rv) || !print) return NS_ERROR_FAILURE; + + rv = print->GetDoingPrintPreview(&isPreview); + if (isPreview == PR_TRUE) + { + rv = print->ExitPrintPreview(); + } + + return rv; +} + +nsresult EphyWrapper::PrintPreviewNumPages (int *numPages) +{ + nsresult rv; + + nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser, &rv)); + if (NS_FAILED(rv) || !print) return NS_ERROR_FAILURE; + + rv = print->GetPrintPreviewNumPages(numPages); + return rv; +} + +nsresult EphyWrapper::PrintPreviewNavigate(PRInt16 navType, PRInt32 pageNum) +{ + nsresult rv; + + nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser, &rv)); + if (NS_FAILED(rv) || !print) return NS_ERROR_FAILURE; + + rv = print->PrintPreviewNavigate(navType, pageNum); + return rv; +} + +nsresult EphyWrapper::GetPrintSettings (nsIPrintSettings **options) +{ + nsresult result; + nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(mWebBrowser, &result)); + if (NS_FAILED(result) || !print) return NS_ERROR_FAILURE; + + return print->GetGlobalPrintSettings(options); +} + +nsresult EphyWrapper::GetSHistory (nsISHistory **aSHistory) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> ContentNav = do_QueryInterface (DocShell, + &result); + if (!ContentNav) return NS_ERROR_FAILURE; + + nsCOMPtr<nsISHistory> SessionHistory; + result = ContentNav->GetSessionHistory (getter_AddRefs (SessionHistory)); + if (!SessionHistory) return NS_ERROR_FAILURE; + + *aSHistory = SessionHistory.get(); + NS_IF_ADDREF (*aSHistory); + + return NS_OK; +} + +nsresult EphyWrapper::Destroy () +{ + DetachListeners (); + + mWebBrowser = nsnull; + mChromeNav = nsnull; + + return NS_OK; +} + +nsresult EphyWrapper::GoToHistoryIndex (PRInt16 index) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> ContentNav = do_QueryInterface (DocShell, + &result); + if (!ContentNav) return NS_ERROR_FAILURE; + + return ContentNav->GotoIndex (index); +} + +nsresult EphyWrapper::SetZoom (float aZoom, PRBool reflow) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + if (reflow) + { + nsCOMPtr<nsIContentViewer> contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (!NS_SUCCEEDED (result) || !contentViewer) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIMarkupDocumentViewer> mdv = do_QueryInterface(contentViewer, + &result); + if (NS_FAILED(result) || !mdv) return NS_ERROR_FAILURE; + + return mdv->SetTextZoom (aZoom); + } + else + { + SetZoomOnDocshell (aZoom, DocShell); + + nsCOMPtr<nsIDocShellTreeNode> docShellNode(do_QueryInterface(DocShell)); + if (docShellNode) + { + PRInt32 i; + PRInt32 n; + docShellNode->GetChildCount(&n); + for (i=0; i < n; i++) + { + nsCOMPtr<nsIDocShellTreeItem> child; + docShellNode->GetChildAt(i, getter_AddRefs(child)); + nsCOMPtr<nsIDocShell> childAsShell(do_QueryInterface(child)); + if (childAsShell) + { + return SetZoomOnDocshell (aZoom, childAsShell); + } + } + } + } + + return NS_OK; +} + +nsresult EphyWrapper::SetZoomOnDocshell (float aZoom, nsIDocShell *DocShell) +{ + nsresult result; + + nsCOMPtr<nsIPresContext> PresContext; + result = DocShell->GetPresContext (getter_AddRefs(PresContext)); + if (NS_FAILED(result)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDeviceContext> DeviceContext; + result = PresContext->GetDeviceContext (getter_AddRefs(DeviceContext)); + + return DeviceContext->SetTextZoom (aZoom); +} + +nsresult EphyWrapper::GetZoom (float *aZoom) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIContentViewer> contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (!NS_SUCCEEDED (result) || !contentViewer) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIMarkupDocumentViewer> mdv = do_QueryInterface(contentViewer, + &result); + if (NS_FAILED(result) || !mdv) return NS_ERROR_FAILURE; + + return mdv->GetTextZoom (aZoom); +} + +nsresult EphyWrapper::GetFocusedDOMWindow (nsIDOMWindow **aDOMWindow) +{ + nsresult rv; + + nsCOMPtr<nsIWebBrowserFocus> focus = do_GetInterface(mWebBrowser, &rv); + if (NS_FAILED(rv) || !focus) return NS_ERROR_FAILURE; + + rv = focus->GetFocusedWindow (aDOMWindow); + if (NS_FAILED(rv)) + rv = mWebBrowser->GetContentDOMWindow (aDOMWindow); + return rv; +} + +nsresult EphyWrapper::GetDOMWindow (nsIDOMWindow **aDOMWindow) +{ + nsresult rv; + + rv = mWebBrowser->GetContentDOMWindow (aDOMWindow); + + return rv; +} + +nsresult EphyWrapper::GetDOMDocument (nsIDOMDocument **aDOMDocument) +{ + nsresult result; + + /* Use the current target document */ + if (mTargetDocument) + { + *aDOMDocument = mTargetDocument.get(); + + NS_IF_ADDREF(*aDOMDocument); + + return NS_OK; + } + + /* Use the focused document */ + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_SUCCEEDED(result) && DOMWindow) + { + return DOMWindow->GetDocument (aDOMDocument); + } + + /* Use the main document */ + return GetMainDOMDocument (aDOMDocument); +} + +nsresult EphyWrapper::GetMainDOMDocument (nsIDOMDocument **aDOMDocument) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIContentViewer> contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (!NS_SUCCEEDED (result) || !contentViewer) return NS_ERROR_FAILURE; + + return contentViewer->GetDOMDocument (aDOMDocument); +} + +nsresult EphyWrapper::GetSHInfo (PRInt32 *count, PRInt32 *index) +{ + nsresult result; + + nsCOMPtr<nsISHistory> SessionHistory; + result = GetSHistory (getter_AddRefs(SessionHistory)); + if (NS_FAILED(result) || ! SessionHistory) return NS_ERROR_FAILURE; + + SessionHistory->GetCount (count); + SessionHistory->GetIndex (index); + + return NS_OK; +} + +nsresult EphyWrapper::GetSHTitleAtIndex (PRInt32 index, PRUnichar **title) +{ + nsresult result; + + nsCOMPtr<nsISHistory> SessionHistory; + result = GetSHistory (getter_AddRefs(SessionHistory)); + if (NS_FAILED(result) || ! SessionHistory) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIHistoryEntry> he; + result = SessionHistory->GetEntryAtIndex (index, PR_FALSE, + getter_AddRefs (he)); + if (!NS_SUCCEEDED(result) || (!he)) return NS_ERROR_FAILURE; + + result = he->GetTitle (title); + if (!NS_SUCCEEDED(result) || (!title)) return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult EphyWrapper::GetSHUrlAtIndex (PRInt32 index, nsCString &url) +{ + nsresult result; + + nsCOMPtr<nsISHistory> SessionHistory; + result = GetSHistory (getter_AddRefs(SessionHistory)); + if (NS_FAILED(result) || ! SessionHistory) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIHistoryEntry> he; + result = SessionHistory->GetEntryAtIndex (index, PR_FALSE, + getter_AddRefs (he)); + if (NS_FAILED(result) || (!he)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + result = he->GetURI (getter_AddRefs(uri)); + if (NS_FAILED(result) || (!uri)) return NS_ERROR_FAILURE; + + result = uri->GetSpec(url); + if (NS_FAILED(result) || url.IsEmpty()) return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult EphyWrapper::Find (const PRUnichar *search_string, + PRBool interactive, + PRBool matchcase, PRBool search_backwards, + PRBool search_wrap_around, + PRBool search_for_entire_word, + PRBool search_in_frames, + PRBool *didFind) +{ + if (!interactive) + { + nsresult rv; + nsCOMPtr<nsITypeAheadFind> tAFinder + (do_GetService(NS_TYPEAHEADFIND_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr<nsIDOMWindow> aFocusedWindow; + rv = GetFocusedDOMWindow(getter_AddRefs(aFocusedWindow)); + if (NS_SUCCEEDED(rv)) + { + nsSupportsInterfacePointerImpl windowPtr; + windowPtr.SetData(aFocusedWindow); + + tAFinder->FindNext(search_backwards, &windowPtr); + + nsCOMPtr<nsISupports> retValue; + rv = windowPtr.GetData(getter_AddRefs(retValue)); + if (NS_SUCCEEDED(rv) && !retValue) + { + *didFind = PR_TRUE; + return NS_OK; + } + } + } + + } + + nsCOMPtr<nsIWebBrowserFind> finder (do_GetInterface(mWebBrowser)); + + finder->SetSearchString (search_string); + finder->SetFindBackwards (search_backwards); + finder->SetWrapFind (search_wrap_around); + finder->SetEntireWord (search_for_entire_word); + finder->SetMatchCase (matchcase); + finder->SetSearchFrames (search_in_frames); + return finder->FindNext(didFind); +} + +nsresult EphyWrapper::GetWebNavigation(nsIWebNavigation **aWebNavigation) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIScriptGlobalObject> scriptGlobal = do_QueryInterface(DOMWindow); + if (!scriptGlobal) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocShell> docshell; + if (NS_FAILED(scriptGlobal->GetDocShell(getter_AddRefs(docshell)))) + return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> wn = do_QueryInterface (docshell, &result); + if (!wn || !NS_SUCCEEDED (result)) return NS_ERROR_FAILURE; + + NS_IF_ADDREF(*aWebNavigation = wn); + return NS_OK; +} + +nsresult EphyWrapper::ReloadDocument () +{ + nsresult result; + + nsCOMPtr<nsIWebNavigation> wn; + result = GetWebNavigation(getter_AddRefs(wn)); + if (!wn || !NS_SUCCEEDED (result)) return NS_ERROR_FAILURE; + + result = wn->Reload (nsIWebNavigation::LOAD_FLAGS_BYPASS_CACHE | + nsIWebNavigation::LOAD_FLAGS_BYPASS_PROXY); + if (!NS_SUCCEEDED (result)) return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult EphyWrapper::LoadDocument(nsISupports *aPageDescriptor, + PRUint32 aDisplayType) +{ + nsresult rv; + + nsCOMPtr<nsIWebNavigation> wn; + rv = GetWebNavigation(getter_AddRefs(wn)); + if (!wn || !NS_SUCCEEDED(rv)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebPageDescriptor> wpd = do_QueryInterface(wn, &rv); + if (!wpd || !NS_SUCCEEDED(rv)) return NS_ERROR_FAILURE; + + return wpd->LoadPage(aPageDescriptor, aDisplayType); +} + +nsresult EphyWrapper::GetPageDescriptor(nsISupports **aPageDescriptor) +{ + nsresult rv; + + nsCOMPtr<nsIWebNavigation> wn; + rv = GetWebNavigation(getter_AddRefs(wn)); + if (!wn || !NS_SUCCEEDED(rv)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebPageDescriptor> wpd = do_QueryInterface(wn, &rv); + if (!wpd || !NS_SUCCEEDED(rv)) return NS_ERROR_FAILURE; + + return wpd->GetCurrentDescriptor(aPageDescriptor); +} + +nsresult EphyWrapper::GetMainDocumentUrl (nsCString &url) +{ + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetMainDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + return uri->GetSpec (url); +} + +nsresult EphyWrapper::GetDocumentUrl (nsCString &url) +{ + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + uri->GetSpec (url); + + return NS_OK; +} + +nsresult EphyWrapper::GetDocumentTitle (char **title) +{ + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + const nsString* t; + t = doc->GetDocumentTitle(); + + *title = g_strdup (NS_ConvertUCS2toUTF8(*t).get()); + + return NS_OK; +} + +nsresult EphyWrapper::CopyHistoryTo (EphyWrapper *dest) +{ + nsresult result; + int count,index; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> wn_src = do_QueryInterface (DocShell, + &result); + if (!wn_src) return NS_ERROR_FAILURE; + + nsCOMPtr<nsISHistory> h_src; + result = wn_src->GetSessionHistory (getter_AddRefs (h_src)); + if (!NS_SUCCEEDED(result) || (!h_src)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDocShell> destDocShell; + result = dest->GetDocShell (getter_AddRefs(destDocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> wn_dest = do_QueryInterface (destDocShell, + &result); + if (!wn_dest) return NS_ERROR_FAILURE; + + nsCOMPtr<nsISHistory> h_dest; + result = wn_dest->GetSessionHistory (getter_AddRefs (h_dest)); + if (!NS_SUCCEEDED (result) || (!h_dest)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsISHistoryInternal> hi_dest = do_QueryInterface (h_dest); + if (!hi_dest) return NS_ERROR_FAILURE; + + h_src->GetCount (&count); + h_src->GetIndex (&index); + + if (count) { + nsCOMPtr<nsIHistoryEntry> he; + nsCOMPtr<nsISHEntry> she; + + for (PRInt32 i = 0; i < count; i++) { + + result = h_src->GetEntryAtIndex (i, PR_FALSE, + getter_AddRefs (he)); + if (!NS_SUCCEEDED(result) || (!he)) + return NS_ERROR_FAILURE; + + she = do_QueryInterface (he); + if (!she) return NS_ERROR_FAILURE; + + result = hi_dest->AddEntry (she, PR_TRUE); + if (!NS_SUCCEEDED(result) || (!she)) + return NS_ERROR_FAILURE; + } + + result = wn_dest->GotoIndex(index); + if (!NS_SUCCEEDED(result)) return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult EphyWrapper::ForceCharacterSet (char *charset) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIContentViewer> contentViewer; + result = DocShell->GetContentViewer (getter_AddRefs(contentViewer)); + if (!NS_SUCCEEDED (result) || !contentViewer) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIMarkupDocumentViewer> mdv = do_QueryInterface(contentViewer, + &result); + if (NS_FAILED(result) || !mdv) return NS_ERROR_FAILURE; + + result = mdv->SetForceCharacterSet (NS_ConvertUTF8toUCS2(charset).get()); + + return result; +} + +nsresult EphyWrapper::CanCutSelection(PRBool *result) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->CanCutSelection (result); +} + +nsresult EphyWrapper::CanCopySelection(PRBool *result) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->CanCopySelection (result); +} + +nsresult EphyWrapper::CanPaste(PRBool *result) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->CanPaste (result); +} + +nsresult EphyWrapper::CutSelection(void) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->CutSelection (); +} + +nsresult EphyWrapper::CopySelection(void) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->CopySelection (); +} + +nsresult EphyWrapper::Paste(void) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->Paste (); +} + +nsresult EphyWrapper::GetLinkInterfaceItems (GList **list) +{ +#ifdef NOT_PORTED + nsresult result; + PRUint32 links_count; + + /* we accept these rel=.. elements, specified by the w3c */ + const gchar *rel_types[] = { + "START", "NEXT", "PREV", "PREVIOUS", "CONTENTS", "TOC", "INDEX", + "GLOSSARY", "COPYRIGHT", "CHAPTER", "SECTION", + "SUBSECTION", "APPENDIX", "HELP", "TOP", "SEARCH", "MADE", + "BOOKMARK", "HOME", + NULL /* terminator, must be last */ + }; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + result = GetMainDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + /* get list of link elements*/ + NS_NAMED_LITERAL_STRING(strname, "LINK"); + + nsCOMPtr<nsIDOMNodeList> links; + result = aDOMDocument->GetElementsByTagName (strname, + getter_AddRefs (links)); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + result = links->GetLength (&links_count); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + for (PRUint32 i = 0; i < links_count; i++) + { + /* get to the link element */ + nsCOMPtr<nsIDOMNode> link; + result = links->Item (i, getter_AddRefs (link)); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMElement> linkElement; + linkElement = do_QueryInterface (aLink); + if (!linkElement) return NS_ERROR_FAILURE; + + /* get rel=.. element */ + NS_NAMED_LITERAL_STRING(attr_rel, "rel"); + nsAutoString value; + linkElement->GetAttribute (attr_rel, value); + + if (value.IsEmpty()) + { + NS_NAMED_LITERAL_STRING(attr_rev, "rev"); + linkElement->GetAttribute (attr_rev, value); + if (value.IsEmpty()) continue; + } + + nsCString relstr = NS_ConvertUCS2toUTF8(value); + ToUpperCase(relstr); + + /* check for elements we want */ + for (gint j = 0; (rel_types[j] != NULL); j++) + { + if (strcmp (relstr.get(), rel_types[j]) == 0) + { + /* found one! */ + LinkInterfaceItem *lti = + g_new0 (LinkInterfaceItem, 1); + + /* fill in struct */ + lti->type = (LinkInterfaceItemType) j; + + /* get href=.. element */ + NS_NAMED_LITERAL_STRING(attr_href, "href"); + nsAutoString value; + linkElement->GetAttribute (attr_href, value); + + if (value.IsEmpty()) + { + g_free (lti); + continue; + } + + /* resolve uri */ + nsCOMPtr<nsIDocument> doc = + do_QueryInterface (aDOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + const nsACString &link = NS_ConvertUCS2toUTF8(value); + nsCAutoString href; + result = uri->Resolve (link, href); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + lti->href = g_strdup (href.get()); + + /* append to list of items */ + *list = g_list_append (*list, lti); + + /* get optional title=... element */ + NS_NAMED_LITERAL_STRING(attr_title, "title"); + linkElement->GetAttribute (attr_title, value); + if (value.IsEmpty()) continue; + + const nsACString &title = NS_ConvertUCS2toUTF8 (value); + lti->title = gul_string_strip_newline (PromiseFlatCString(title).get()); + } + } + } +#endif + return NS_OK; +} + +nsresult EphyWrapper::GetRealURL (nsCString &ret) +{ + nsresult result; + + nsCOMPtr<nsIDocShell> DocShell; + result = GetDocShell (getter_AddRefs(DocShell)); + if (NS_FAILED(result) || !DocShell) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIWebNavigation> ContentNav = do_QueryInterface (DocShell, + &result); + if (!ContentNav) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + result = ContentNav->GetCurrentURI (getter_AddRefs(uri)); + if (!NS_SUCCEEDED(result) || (!uri)) return NS_ERROR_FAILURE; + + result = uri->GetSpec(ret); + if (!NS_SUCCEEDED(result) || ret.IsEmpty()) return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult EphyWrapper::SelectAll (void) +{ + nsCOMPtr<nsIClipboardCommands> clipboard (do_GetInterface(mWebBrowser)); + return clipboard->SelectAll (); +} + +nsresult EphyWrapper::ScrollUp (void) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + DOMWindow->ScrollByLines(-1); + + return NS_OK; +} + +nsresult EphyWrapper::ScrollDown (void) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + DOMWindow->ScrollByLines(1); + + return NS_OK; +} + +nsresult EphyWrapper::ScrollLeft (void) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + DOMWindow->ScrollBy(-16, 0); + + return NS_OK; +} + +nsresult EphyWrapper::ScrollRight (void) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + DOMWindow->ScrollBy(16, 0); + + return NS_OK; +} + +nsresult EphyWrapper::FineScroll (int horiz, int vert) +{ + nsresult result; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + result = GetFocusedDOMWindow (getter_AddRefs(DOMWindow)); + if (NS_FAILED(result) || !DOMWindow) return NS_ERROR_FAILURE; + + DOMWindow->ScrollBy(horiz, vert); + + return NS_OK; +} + +nsresult EphyWrapper::GetLastModified (gchar **ret) +{ + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMNSHTMLDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsAutoString value; + doc->GetLastModified(value); + + *ret = g_strdup (NS_ConvertUCS2toUTF8(value).get()); + + return NS_OK; +} + +nsresult EphyWrapper::GetImages (GList **ret) +{ +#ifdef NOT_PORTED + nsresult result; + GHashTable *hash = g_hash_table_new (g_str_hash, g_str_equal); + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLCollection> col; + doc->GetImages(getter_AddRefs(col)); + + PRUint32 count, i; + col->GetLength(&count); + for (i = 0; i < count; i++) + { + nsCOMPtr<nsIDOMNode> node; + col->Item(i, getter_AddRefs(node)); + if (!node) continue; + + nsCOMPtr<nsIDOMHTMLElement> element; + element = do_QueryInterface(node); + if (!element) continue; + + nsCOMPtr<nsIDOMHTMLImageElement> img; + img = do_QueryInterface(element); + if (!img) continue; + + ImageListItem *item = g_new0 (ImageListItem, 1); + + nsAutoString tmp; + result = img->GetSrc (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + if (g_hash_table_lookup (hash, PromiseFlatCString(c).get())) + { + g_free (item); + continue; + } + item->url = g_strdup (c.get()); + g_hash_table_insert (hash, item->url, + GINT_TO_POINTER (TRUE)); + } + result = img->GetAlt (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + item->alt = gul_string_strip_newline (PromiseFlatCString(c).get()); + } + result = element->GetTitle (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + item->title = gul_string_strip_newline (PromiseFlatCString(c).get()); + } + result = img->GetWidth (&(item->width)); + result = img->GetHeight (&(item->height)); + + *ret = g_list_append (*ret, item); + } + + g_hash_table_destroy (hash); +#endif + return NS_OK; +} + +nsresult EphyWrapper::GetForms (GList **ret) +{ +#ifdef NOT_PORTED + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + result = GetDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLDocument> doc = do_QueryInterface(DOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLCollection> col; + doc->GetForms(getter_AddRefs(col)); + + PRUint32 count, i; + col->GetLength(&count); + for (i = 0; i < count; i++) + { + nsCOMPtr<nsIDOMNode> node; + col->Item(i, getter_AddRefs(node)); + if (!node) continue; + + nsCOMPtr<nsIDOMHTMLElement> element; + element = do_QueryInterface(node); + if (!element) continue; + + nsCOMPtr<nsIDOMHTMLFormElement> form; + form = do_QueryInterface(element); + if (!form) continue; + + FormListItem *item = g_new0 (FormListItem, 1); + + nsAutoString tmp; + result = form->GetAction (tmp); + if (NS_SUCCEEDED(result)) + { + nsCOMPtr<nsIDocument> doc = + do_QueryInterface (aDOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + const nsACString &s = NS_ConvertUTF8toUCS2(tmp); + nsCAutoString c; + result = uri->Resolve (c, s); + + item->action = s.Length() ? g_strdup (s.get()) : g_strdup (c.get()); + } + result = form->GetMethod (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUTF8toUCS2(tmp); + item->method = g_strdup (PromiseFlatCString(c).get()); + } + result = form->GetName (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUTF8toUCS2(tmp); + item->name = g_strdup (PromiseFlatCString(c).get()); + } + + *ret = g_list_append (*ret, item); + } +#endif + return NS_OK; +} + +nsresult EphyWrapper::GetLinks (GList **ret) +{ +#ifdef NOT_PORTED + nsresult result; + + nsCOMPtr<nsIDOMDocument> DOMDocument; + result = GetMainDOMDocument (getter_AddRefs(DOMDocument)); + if (NS_FAILED(result) || !DOMDocument) return NS_ERROR_FAILURE; + + /* first, get a list of <link> elements */ + PRUint32 links_count; + + NS_NAMED_LITERAL_STRING(strname, "LINK"); + + nsCOMPtr<nsIDOMNodeList> links; + result = DOMDocument->GetElementsByTagName (strname, + getter_AddRefs (links)); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + result = aLinks->GetLength (&links_count); + if (NS_FAILED (result)) return NS_ERROR_FAILURE; + + for (PRUint32 i = 0; i < links_count; i++) + { + nsCOMPtr<nsIDOMNode> link; + result = links->Item (i, getter_AddRefs (link)); + if (NS_FAILED (result)) continue; + + nsCOMPtr<nsIDOMElement> linkElement; + linkElement = do_QueryInterface (link); + if (!linkElement) continue; + + NS_NAMED_LITERAL_STRING(attr_href, "href"); + nsAutoString value; + linkElement->GetAttribute (attr_href, value); + if (value.IsEmpty()) continue; + + const nsACString &link = NS_ConvertUCS2toUTF8(value); + + if (link.IsEmpty()) continue; + + nsCOMPtr<nsIDocument> doc = + do_QueryInterface (aDOMDocument); + if(!doc) continue; + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + nsCAutoString tmp; + result = uri->Resolve (link, tmp); + + LinkListItem *i = g_new0 (LinkListItem, 1); + + if (!tmp.IsEmpty()) + { + i->url = g_strdup (tmp.get()); + } + else + { + i->url = g_strdup (link.get()); + } + + NS_NAMED_LITERAL_STRING(attr_title, "title"); + linkElement->GetAttribute (attr_title, value); + if (!value.IsEmpty()) + { + const nsACString &s = NS_ConvertUCS2toUTF8(value); + i->title = gul_string_strip_newline (PromiseFlatCString(s).get()); + } + + NS_NAMED_LITERAL_STRING(attr_rel, "rel"); + linkElement->GetAttribute (attr_rel, value); + if (!value.IsEmpty()) + { + const nsACString &s = NS_ConvertUCS2toUTF8(value); + i->rel = g_strdup (PromiseFlatCString(s).get()); + g_strdown (i->rel); + } + if (!i->rel || strlen (i->rel) == 0) + { + NS_NAMED_LITERAL_STRING(attr_rev, "rev"); + linkElement->GetAttribute (attr_rev, value); + if (!value.IsEmpty()) + { + const nsACString &s = NS_ConvertUCS2toUTF8(value); + i->rel = g_strdup (PromiseFlatCString(s).get()); + g_strdown (i->rel); + } + } + + *ret = g_list_append (*ret, i); + } + + /* next, get a list of anchors */ + nsCOMPtr<nsIDOMHTMLDocument> doc = do_QueryInterface(aDOMDocument); + if(!doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLCollection> col; + doc->GetLinks(getter_AddRefs(col)); + + PRUint32 count, i; + col->GetLength(&count); + for (i = 0; i < count; i++) + { + nsCOMPtr<nsIDOMNode> node; + col->Item(i, getter_AddRefs(node)); + if (!node) continue; + + nsCOMPtr<nsIDOMHTMLElement> element; + element = do_QueryInterface(node); + if (!element) continue; + + nsCOMPtr<nsIDOMHTMLAnchorElement> lnk; + lnk = do_QueryInterface(element); + if (!lnk) continue; + + LinkListItem *i = g_new0 (LinkListItem, 1); + + nsAutoString tmp; + + result = lnk->GetHref (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + i->url = g_strdup (PromiseFlatCString(c).get()); + } + + result = lnk->GetRel (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + i->rel = g_strdup (PromiseFlatCString(c).get()); + g_strdown (i->rel); + } + + if (!i->rel || strlen (i->rel) == 0) + { + result = lnk->GetRev (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + i->rel = g_strdup (PromiseFlatCString(c).get()); + g_strdown (i->rel); + } + } + + i->title = mozilla_get_link_text (node); + if (i->title == NULL) + { + result = element->GetTitle (tmp); + if (NS_SUCCEEDED(result)) + { + const nsACString &c = NS_ConvertUCS2toUTF8(tmp); + i->title = gul_string_strip_newline (PromiseFlatCString(c).get()); + } + } + + + *ret = g_list_append (*ret, i); + } +#endif + return NS_OK; +} + +nsresult EphyWrapper::EvaluateJS (char *script) +{ + nsresult rv; + + nsCOMPtr<nsIDOMWindow> DOMWindow; + rv = mWebBrowser->GetContentDOMWindow(getter_AddRefs(DOMWindow)); + + nsCOMPtr<nsIScriptGlobalObject> globalObject; + globalObject = do_QueryInterface (DOMWindow); + if (!globalObject) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIScriptContext> context; + rv = globalObject->GetContext(getter_AddRefs(context)); + if (NS_FAILED(rv) || !context) { + return NS_ERROR_FAILURE; + } + + context->SetProcessingScriptTag(PR_TRUE); + + PRBool isUndefined; + nsAutoString ret; + const nsAString &aScript = NS_ConvertUTF8toUCS2(script); + context->EvaluateString(aScript, nsnull, nsnull, nsnull, + 0, nsnull, + ret, &isUndefined); + + context->SetProcessingScriptTag(PR_FALSE); + + return NS_OK; +} + +nsresult EphyWrapper::PushTargetDocument (nsIDOMDocument *domDoc) +{ + mTargetDocument = domDoc; + + return NS_OK; +} + +nsresult EphyWrapper::PopTargetDocument () +{ + mTargetDocument = nsnull; + + return NS_OK; +} diff --git a/embed/mozilla/EphyWrapper.h b/embed/mozilla/EphyWrapper.h new file mode 100644 index 000000000..04379546c --- /dev/null +++ b/embed/mozilla/EphyWrapper.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EPHY_WRAPPER_H +#define EPHY_WRAPPER_H + +#include "nsIDocShell.h" +#include "ProgressListener.h" +#include "nsIWebNavigation.h" +#include "nsIWebPageDescriptor.h" +#include "nsISHistory.h" +#include "nsIWebBrowser.h" +#include "nsIWebProgressListener.h" +#include "nsCOMPtr.h" +#include "nsIDOMEventReceiver.h" +#include "nsIDOMDocument.h" +#include "nsPIDOMWindow.h" +#include <gtkmozembed.h> + +#include "nsIPrintSettings.h" + +class EphyEventListener; + +class EphyWrapper +{ +public: + EphyWrapper(); + ~EphyWrapper(); + + nsresult Init (GtkMozEmbed *mozembed); + nsresult Destroy (void); + + nsresult SetZoom (float aTextZoom, PRBool reflow); + nsresult GetZoom (float *aTextZoom); + + nsresult Print (nsIPrintSettings *options, PRBool preview); + nsresult GetPrintSettings (nsIPrintSettings * *options); + nsresult PrintPreviewClose (void); + nsresult PrintPreviewNumPages (int *numPages); + nsresult PrintPreviewNavigate(PRInt16 navType, PRInt32 pageNum); + + nsresult Find (const PRUnichar *search_string, + PRBool matchcase, PRBool interactive, + PRBool search_backwards, PRBool search_wrap_around, + PRBool search_for_entire_word, PRBool search_in_frames, + PRBool *didFind); + + nsresult GetMainDocumentUrl (nsCString &url); + nsresult GetDocumentUrl (nsCString &url); + nsresult GetDocumentTitle (char **title); + + nsresult ReloadDocument (); + nsresult LoadDocument(nsISupports *aPageDescriptor, PRUint32 aDisplayType); + nsresult GetPageDescriptor(nsISupports **aPageDescriptor); + + nsresult GetSHInfo (PRInt32 *count, PRInt32 *index); + nsresult GetSHTitleAtIndex (PRInt32 index, PRUnichar **title); + nsresult GetSHUrlAtIndex (PRInt32 index, nsCString &url); + + nsresult CopyHistoryTo (EphyWrapper *embed); + + nsresult GoToHistoryIndex (PRInt16 index); + + nsresult ForceCharacterSet (char *charset); + + nsresult CanCutSelection(PRBool *result); + + nsresult CanCopySelection(PRBool *result); + + nsresult CanPaste(PRBool *result); + + nsresult CutSelection(void); + + nsresult CopySelection(void); + + nsresult Paste(void); + + nsresult Activate (); + nsresult Deactivate (); + + nsresult GetMainDOMDocument (nsIDOMDocument **aDOMDocument); + + nsresult GetLinkInterfaceItems (GList **list); + + nsresult GetRealURL (nsCString &ret); + + nsresult SelectAll (void); + + nsresult ScrollUp (void); + nsresult ScrollDown (void); + nsresult ScrollLeft (void); + nsresult ScrollRight (void); + + nsresult FineScroll (int horiz, int vert); + + nsresult GetLastModified (gchar **ret); + nsresult GetImages (GList **ret); + nsresult GetForms (GList **ret); + nsresult GetLinks (GList **ret); + nsresult EvaluateJS (char *script); + + nsresult PushTargetDocument (nsIDOMDocument *domDoc); + nsresult PopTargetDocument (); + + nsresult GetDOMDocument (nsIDOMDocument **aDOMDocument); + nsresult GetDOMWindow (nsIDOMWindow **aDOMWindow); + + nsCOMPtr<nsIWebBrowser> mWebBrowser; + + nsCOMPtr<nsIWebNavigation> mChromeNav; + + GtkMozEmbed *mGtkMozEmbed; +private: + nsCOMPtr<nsIDOMDocument> mTargetDocument; + nsCOMPtr<nsIWebProgressListener> mProgress; + nsCOMPtr<nsIDOMEventReceiver> mEventReceiver; + EphyEventListener *mEventListener; + PRBool mListenersAttached; + + void GetListener (void); + void AttachListeners (void); + void DetachListeners (void); + nsresult SetZoomOnDocshell (float aZoom, nsIDocShell *DocShell); + nsresult GetDocShell (nsIDocShell **aDocShell); + nsresult GetCSSBackground (nsIDOMNode *node, nsAutoString& url); + nsresult GetFocusedDOMWindow (nsIDOMWindow **aDOMWindow); + nsresult GetSHistory (nsISHistory **aSHistory); + nsresult GetPIDOMWindow(nsPIDOMWindow **aPIWin); + nsresult GetWebNavigation(nsIWebNavigation **aWebNavigation); +}; + +#endif diff --git a/embed/mozilla/EventContext.cpp b/embed/mozilla/EventContext.cpp new file mode 100644 index 000000000..9d4e312b6 --- /dev/null +++ b/embed/mozilla/EventContext.cpp @@ -0,0 +1,669 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "EventContext.h" +#include "nsIDOMEventTarget.h" +#include "nsIDocument.h" +#include "nsIDOMHTMLInputElement.h" +#include "nsIDOMHTMLObjectElement.h" +#include "nsIInterfaceRequestor.h" +#include "nsIDOMHTMLImageElement.h" +#include "nsIDOMElement.h" +#include "nsIDOMXULDocument.h" +#include "nsIURI.h" +#include "nsIDOMNSDocument.h" +#include "nsReadableUtils.h" +#include "nsUnicharUtils.h" +#include "nsGUIEvent.h" +#include "nsIDOMNSEvent.h" +#include "nsIDOMCharacterData.h" +#include "nsIDOMHTMLButtonElement.h" +#include "nsIDOMHTMLLabelElement.h" +#include "nsIDOMHTMLLegendElement.h" +#include "nsIDOMHTMLTextAreaElement.h" +#include <gdk/gdkkeysyms.h> +#include "nsIPrivateDOMEvent.h" +#include "nsIDOMNSUIEvent.h" + +#define KEY_CODE 256 + +EventContext::EventContext () +{ +} + +EventContext::~EventContext () +{ +} + +nsresult EventContext::Init (nsIDOMEvent *event, EphyWrapper *wrapper) +{ + mEvent = event; + mWrapper = wrapper; + mDOMDocument = nsnull; + + return NS_OK; +} + +nsresult EventContext::GetEventContext (nsIDOMEventTarget *EventTarget, + EphyEmbedEvent *info) +{ + nsresult rv; + + mEmbedEvent = info; + + info->context = EMBED_CONTEXT_DOCUMENT; + + nsCOMPtr<nsIDOMNode> node = do_QueryInterface(EventTarget, &rv); + if (NS_FAILED(rv) || !node) return NS_ERROR_FAILURE; + + /* Is page xul ? then do not display context menus + * FIXME I guess there is an easier way ... */ + /* From philipl: This test needs to be here otherwise we + * arrogantly assume we can QI to a HTMLElement, which is + * not true for xul content. */ + + nsCOMPtr<nsIDOMDocument> domDoc; + rv = node->GetOwnerDocument(getter_AddRefs(domDoc)); + if (NS_FAILED(rv) || !domDoc) return NS_ERROR_FAILURE; + + mDOMDocument = domDoc; + + nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc, &rv); + if (NS_FAILED(rv) || !doc) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMXULDocument> xul_document = do_QueryInterface(domDoc); + if (xul_document) + { + info->context = EMBED_CONTEXT_NONE; + return NS_ERROR_FAILURE; + } + + // Now we know that the page isn't a xul window, we can try and + // do something useful with it. + + PRUint16 type; + rv = node->GetNodeType(&type); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMHTMLElement> element = do_QueryInterface(node); + if ((nsIDOMNode::ELEMENT_NODE == type) && element) + { + nsAutoString tag; + rv = element->GetTagName(tag); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + if (tag.Equals(NS_LITERAL_STRING("img"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_IMAGE; + + nsAutoString img; + nsCOMPtr <nsIDOMHTMLImageElement> image = + do_QueryInterface(node, &rv); + if (NS_FAILED(rv) || !image) return NS_ERROR_FAILURE; + + rv = image->GetSrc (img); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + SetStringProperty ("image", img); + + rv = image->GetAlt (img); + if (NS_SUCCEEDED(rv)) + { + SetStringProperty ("image_alt", img); + } + + rv = image->GetLongDesc (img); + if (NS_SUCCEEDED(rv) && !img.IsEmpty()) + { + nsCAutoString imglongdesc; + const nsACString &src = NS_ConvertUCS2toUTF8(img); + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + + rv = uri->Resolve (src, imglongdesc); + + SetStringProperty ("image_long_desc", + NS_ConvertUTF8toUCS2(imglongdesc)); + } + + int imgwidth, imgheight; + rv = image->GetWidth (&imgwidth); + rv = image->GetHeight (&imgheight); + SetIntProperty ("image_width", imgwidth); + SetIntProperty ("image_height", imgheight); + + rv = element->GetTitle (img); + if (NS_SUCCEEDED(rv)) + { + SetStringProperty ("image_title", + img); + } + } + else if (tag.Equals(NS_LITERAL_STRING("input"), + nsCaseInsensitiveStringComparator())) + { + nsCOMPtr<nsIDOMElement> element; + element = do_QueryInterface (node); + if (!element) return NS_ERROR_FAILURE; + + NS_NAMED_LITERAL_STRING(attr, "type"); + nsAutoString value; + element->GetAttribute (attr, value); + + if (value.Equals(NS_LITERAL_STRING("image"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_IMAGE; + nsCOMPtr<nsIDOMHTMLInputElement> input; + input = do_QueryInterface (node); + if (!input) return NS_ERROR_FAILURE; + + nsAutoString img; + rv = input->GetSrc (img); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCAutoString cImg; + const nsACString &src = NS_ConvertUCS2toUTF8(img); + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + rv = uri->Resolve (src, cImg); + SetStringProperty ("image", + NS_ConvertUTF8toUCS2(cImg)); + + if (NS_FAILED (rv)) return NS_ERROR_FAILURE; + } + else if (!value.Equals(NS_LITERAL_STRING("radio"), + nsCaseInsensitiveStringComparator()) && + !value.Equals(NS_LITERAL_STRING("submit"), + nsCaseInsensitiveStringComparator()) && + !value.Equals(NS_LITERAL_STRING("reset"), + nsCaseInsensitiveStringComparator()) && + !value.Equals(NS_LITERAL_STRING("hidden"), + nsCaseInsensitiveStringComparator()) && + !value.Equals(NS_LITERAL_STRING("button"), + nsCaseInsensitiveStringComparator()) && + !value.Equals(NS_LITERAL_STRING("checkbox"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_INPUT; + } + } + else if (tag.Equals(NS_LITERAL_STRING("textarea"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_INPUT; + } + else if (tag.Equals(NS_LITERAL_STRING("object"), + nsCaseInsensitiveStringComparator())) + { + nsCOMPtr<nsIDOMHTMLObjectElement> object; + object = do_QueryInterface (node); + if (!element) return NS_ERROR_FAILURE; + + nsAutoString value; + object->GetType(value); + + //Forming a substring and confirming it's contents + //is quicker than doing a Find on the full string + //and then checking that "image/" is at the beginning + if (Substring(value, 0, 6).Equals(NS_LITERAL_STRING("image/"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_IMAGE; + + nsAutoString img; + + rv = object->GetData (img); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCAutoString cImg; + const nsACString &src = NS_ConvertUCS2toUTF8(img); + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + rv = uri->Resolve (src, cImg); + SetStringProperty ("image", + NS_ConvertUTF8toUCS2(cImg)); + + if (NS_FAILED (rv)) return NS_ERROR_FAILURE; + } + else + { + info->context = EMBED_CONTEXT_NONE; + return NS_OK; + } + } + } + + /* Is page framed ? */ + PRBool framed; + IsPageFramed (node, &framed); + SetIntProperty ("framed_page", framed); + + /* Bubble out, looking for items of interest */ + while (node) + { + nsCOMPtr <nsIDOMElement> dom_elem = do_QueryInterface(node); + if (dom_elem) + { + NS_NAMED_LITERAL_STRING(nspace, "http://www.w3.org/1999/xlink"); + NS_NAMED_LITERAL_STRING(localname_type, "type"); + + nsAutoString value; + dom_elem->GetAttributeNS (nspace, localname_type, value); + + if (value.Equals(NS_LITERAL_STRING("simple"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_LINK; + NS_NAMED_LITERAL_STRING (localname_href, "href"); + dom_elem->GetAttributeNS (nspace, localname_href, value); + + SetStringProperty ("link", value); + } + } + + PRUint16 type; + rv = node->GetNodeType(&type); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + element = do_QueryInterface(node); + if ((nsIDOMNode::ELEMENT_NODE == type) && element) + { + nsAutoString tag; + rv = element->GetTagName(tag); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + /* Link */ + if (tag.Equals(NS_LITERAL_STRING("a"), + nsCaseInsensitiveStringComparator())) + { + nsCOMPtr <nsIDOMHTMLAnchorElement> anchor = + do_QueryInterface(node); + nsAutoString tmp; + rv = anchor->GetHref (tmp); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + if (Substring(tmp, 0, 7).Equals(NS_LITERAL_STRING("mailto:"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_EMAIL_LINK; + const nsAString &address = Substring(tmp, 7, tmp.Length()-7); + SetStringProperty ("email", address); + } + + if (anchor && !tmp.IsEmpty()) + { + info->context |= EMBED_CONTEXT_LINK; + + SetStringProperty ("link", tmp); + rv = anchor->GetHreflang (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_lang", tmp); + rv = anchor->GetTarget (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_target", tmp); + rv = anchor->GetRel (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_rel", tmp); + rv = anchor->GetRev (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_rev", tmp); + rv = element->GetTitle (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_title", tmp); + rv = anchor->GetType (tmp); + if (NS_SUCCEEDED(rv)) + SetStringProperty ("link_type", tmp); + + if (tmp.Equals(NS_LITERAL_STRING("text/smartbookmark"), + nsCaseInsensitiveStringComparator())) + { + SetIntProperty ("link_is_smart", TRUE); + + nsCOMPtr<nsIDOMNode> childNode; + node->GetFirstChild (getter_AddRefs(childNode)); + if (childNode) + { + nsCOMPtr <nsIDOMHTMLImageElement> image = + do_QueryInterface(childNode, &rv); + + if (image) + { + nsAutoString img; + rv = image->GetSrc (img); + if (!NS_FAILED(rv)) + { + SetStringProperty ("image", img); + } + } + } + } +#ifdef NOT_PORTED + /* Get the text of the link */ + info->linktext = mozilla_get_link_text (node); +#endif + } + + } + else if (tag.Equals(NS_LITERAL_STRING("option"), + nsCaseInsensitiveStringComparator())) + { + info->context = EMBED_CONTEXT_NONE; + return NS_OK; + } + if (tag.Equals(NS_LITERAL_STRING("area"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_LINK; + nsCOMPtr <nsIDOMHTMLAreaElement> area = + do_QueryInterface(node, &rv); + if (NS_SUCCEEDED(rv) && area) + { + nsAutoString href; + rv = area->GetHref (href); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + + SetStringProperty ("link", href); + } + } + else if (tag.Equals(NS_LITERAL_STRING("textarea"), + nsCaseInsensitiveStringComparator()) || + tag.Equals(NS_LITERAL_STRING("input"), + nsCaseInsensitiveStringComparator())) + { + info->context |= EMBED_CONTEXT_INPUT; + } + + nsCOMPtr<nsIDOMElement> domelement; + domelement = do_QueryInterface (node); + if (!domelement) return NS_ERROR_FAILURE; + + PRBool has_background = PR_FALSE; + + NS_NAMED_LITERAL_STRING(attr, "background"); + nsAutoString value; + domelement->GetAttribute (attr, value); + + if (!value.IsEmpty()) + { + nsCAutoString bgimg; + const nsACString &tmp = + NS_ConvertUCS2toUTF8(value); + + nsCOMPtr<nsIURI> uri; + doc->GetDocumentURL(getter_AddRefs(uri)); + rv = uri->Resolve (tmp, bgimg); + if (NS_FAILED (rv)) + return NS_ERROR_FAILURE; + SetStringProperty ("background_image", + NS_ConvertUTF8toUCS2(bgimg)); + } + else + { + nsCOMPtr<nsIDOMHTMLBodyElement> bgelement; + bgelement = do_QueryInterface (node); + if (bgelement) + { + nsAutoString value; + bgelement->GetBackground (value); + + if (!value.IsEmpty()) + { + nsCAutoString bgimg; + const nsACString &tmp = + NS_ConvertUCS2toUTF8(value); + + nsIURI *uri; + doc->GetBaseURL(uri); + rv = uri->Resolve + (tmp, bgimg); + SetStringProperty ("background_image", + NS_ConvertUTF8toUCS2(bgimg)); + if (NS_FAILED (rv)) + return NS_ERROR_FAILURE; + has_background = PR_TRUE; + } + } + } + + if (!has_background) + { + nsAutoString cssurl; + rv = GetCSSBackground (node, cssurl); + if (NS_SUCCEEDED (rv)) + { + nsCAutoString bgimg; + const nsACString &tmp = + NS_ConvertUCS2toUTF8(cssurl); + + nsIURI *uri; + doc->GetBaseURL(uri); + rv = uri->Resolve + (tmp, bgimg); + SetStringProperty ("background_image", + NS_ConvertUTF8toUCS2(bgimg)); + if (NS_FAILED (rv)) + return NS_ERROR_FAILURE; + } + } + } + + nsCOMPtr<nsIDOMNode> parentNode; + node->GetParentNode (getter_AddRefs(parentNode)); + node = parentNode; + } + + return NS_OK; +} + +nsresult EventContext::GetCSSBackground (nsIDOMNode *node, nsAutoString& url) +{ + nsresult result; + + nsCOMPtr<nsIDOMElementCSSInlineStyle> style; + style = do_QueryInterface (node); + if (!style) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMCSSStyleDeclaration> decl; + result = style->GetStyle (getter_AddRefs(decl)); + if (NS_FAILED(result)) return NS_ERROR_FAILURE; + + nsAutoString value; + NS_NAMED_LITERAL_STRING(prop_bgi, "background-image"); + decl->GetPropertyValue (prop_bgi, value); + + if (value.IsEmpty()) + { + NS_NAMED_LITERAL_STRING(prop_bg, "background"); + decl->GetPropertyValue (prop_bg, value); + if (value.IsEmpty()) + { + NS_NAMED_LITERAL_STRING(prop_bgr, "background-repeat"); + decl->GetPropertyValue (prop_bgr, value); + if (value.IsEmpty()) + return NS_ERROR_FAILURE; + } + } + + PRInt32 start, end; + nsAutoString cssurl; + + NS_NAMED_LITERAL_STRING(startsub, "url("); + NS_NAMED_LITERAL_STRING(endsub, ")"); + + start = value.Find (startsub) + 4; + end = value.Find (endsub); + + if (start == -1 || end == -1) + return NS_ERROR_FAILURE; + + url.Assign(Substring (value, start, end - start)); + + return NS_OK; +} + +nsresult EventContext::GetMouseEventInfo (EphyEmbedEvent *info) +{ + nsresult result; + DOMTimeStamp ts; + nsIDOMMouseEvent *aMouseEvent = (nsIDOMMouseEvent*)mEvent; + + aMouseEvent->GetButton ((PRUint16*)&info->mouse_button); + aMouseEvent->GetScreenX ((PRInt32*)&info->mouse_x); + aMouseEvent->GetScreenY ((PRInt32*)&info->mouse_y); + + aMouseEvent->GetTimeStamp(&ts); + info->timestamp = ts; + + /* be sure we are not clicking on the scroolbars */ + + nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(aMouseEvent, &result); + if (NS_FAILED(result) || !nsEvent) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMEventTarget> OriginalTarget; + result = nsEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget)); + if (NS_FAILED(result) || !OriginalTarget) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget); + if (!OriginalNode) return NS_ERROR_FAILURE; + + nsAutoString nodename; + OriginalNode->GetNodeName(nodename); + + if (nodename.Equals(NS_LITERAL_STRING("xul:scrollbarbutton"), + nsCaseInsensitiveStringComparator()) || + nodename.Equals(NS_LITERAL_STRING("xul:thumb"), + nsCaseInsensitiveStringComparator()) || + nodename.Equals(NS_LITERAL_STRING("xul:vbox"), + nsCaseInsensitiveStringComparator()) || + nodename.Equals(NS_LITERAL_STRING("xul:spacer"), + nsCaseInsensitiveStringComparator()) || + nodename.Equals(NS_LITERAL_STRING("xul:slider"), + nsCaseInsensitiveStringComparator())) + return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMEventTarget> EventTarget; + result = aMouseEvent->GetTarget(getter_AddRefs(EventTarget)); + if (NS_FAILED(result) || !EventTarget) return NS_ERROR_FAILURE; + + result = GetEventContext (EventTarget, info); + if (NS_FAILED(result)) return result; + + /* Get the modifier */ + + PRBool mod_key; + + info->modifier = 0; + + aMouseEvent->GetAltKey(&mod_key); + if (mod_key) info->modifier |= GDK_MOD1_MASK; + + aMouseEvent->GetShiftKey(&mod_key); + if (mod_key) info->modifier |= GDK_SHIFT_MASK; + + aMouseEvent->GetMetaKey(&mod_key); + if (mod_key) info->modifier |= GDK_Meta_L; + + aMouseEvent->GetCtrlKey(&mod_key); + if (mod_key) info->modifier |= GDK_CONTROL_MASK; + + return NS_OK; +} + +nsresult EventContext::IsPageFramed (nsIDOMNode *node, PRBool *Framed) +{ + nsresult result; + + nsCOMPtr<nsIDOMDocument> mainDocument; + result = mWrapper->GetMainDOMDocument (getter_AddRefs(mainDocument)); + if (NS_FAILED(result) || !mainDocument) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIDOMDocument> nodeDocument; + result = node->GetOwnerDocument (getter_AddRefs(nodeDocument)); + if (NS_FAILED(result) || !nodeDocument) return NS_ERROR_FAILURE; + + *Framed = (mainDocument != nodeDocument); + + return NS_OK; +} + +nsresult EventContext::GetTargetDocument (nsIDOMDocument **domDoc) +{ + if (!mDOMDocument) return NS_ERROR_FAILURE; + + *domDoc = mDOMDocument.get(); + + NS_IF_ADDREF(*domDoc); + + return NS_OK; +} + +nsresult EventContext::SetIntProperty (const char *name, int value) +{ + + GValue *val = g_new0 (GValue, 1); + + g_value_init (val, G_TYPE_INT); + + g_value_set_int (val, value); + + ephy_embed_event_set_property (mEmbedEvent, + g_strdup (name), + val); + + return NS_OK; +} + +nsresult EventContext::SetStringProperty (const char *name, const char *value) +{ + GValue *val = g_new0 (GValue, 1); + + g_value_init (val, G_TYPE_STRING); + + g_value_set_string (val, value); + + ephy_embed_event_set_property (mEmbedEvent, + g_strdup (name), + val); + + return NS_OK; +} + +nsresult EventContext::SetStringProperty (const char *name, const nsAString &value) +{ + GValue *val = g_new0 (GValue, 1);; + char *tmp; + + tmp = ToNewCString (NS_ConvertUCS2toUTF8(value)); + + g_value_init (val, G_TYPE_STRING); + + g_value_set_string (val, tmp); + + ephy_embed_event_set_property (mEmbedEvent, + g_strdup (name), + val); + nsMemory::Free (tmp); + + return NS_OK; +} diff --git a/embed/mozilla/EventContext.h b/embed/mozilla/EventContext.h new file mode 100644 index 000000000..432bd1f53 --- /dev/null +++ b/embed/mozilla/EventContext.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef EVENT_CONTEXT_H +#define EVENT_CONTEXT_H + +#include "nsIDOMMouseEvent.h" +#include "nsIDOMKeyEvent.h" +#include "nsIDOMEvent.h" +#include "nsIDOMNode.h" +#include "nsString.h" +#include "nsIDOMHTMLAnchorElement.h" +#include "nsIDOMNSHTMLElement.h" +#include "nsIDOMHTMLAreaElement.h" +#include "nsIDOMHTMLBodyElement.h" +#include "nsIDOMElementCSSInlineStyle.h" +#include "nsIDOMCSSStyleDeclaration.h" +#include "nsIDOMDocument.h" +#include "EphyWrapper.h" + +#include "ephy-embed.h" +#include "ephy-embed-event.h" + +class EventContext +{ +public: + EventContext(); + ~EventContext(); + + nsresult Init (nsIDOMEvent *event, EphyWrapper *wrapper); + + nsresult GetMouseEventInfo (EphyEmbedEvent *info); + nsresult GetTargetDocument (nsIDOMDocument **domDoc); + +private: + nsIDOMEvent *mEvent; + EphyWrapper *mWrapper; + nsCOMPtr<nsIDOMDocument> mDOMDocument; + + nsresult GetEventContext (nsIDOMEventTarget *EventTarget, + EphyEmbedEvent *info); + nsresult GetCSSBackground (nsIDOMNode *node, nsAutoString& url); + nsresult IsPageFramed (nsIDOMNode *node, PRBool *Framed); + nsresult SetIntProperty (const char *name, int value); + nsresult SetStringProperty (const char *name, const char *value); + nsresult SetStringProperty (const char *name, const nsAString &value); + EphyEmbedEvent *mEmbedEvent; +}; + +#endif diff --git a/embed/mozilla/ExternalProtocolService.cpp b/embed/mozilla/ExternalProtocolService.cpp new file mode 100644 index 000000000..728cd0f5c --- /dev/null +++ b/embed/mozilla/ExternalProtocolService.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <gtk/gtk.h> +#include <libgnome/gnome-exec.h> +#include <libgnome/gnome-i18n.h> +#include <libgnome/gnome-url.h> + +#include <nsString.h> +#include <nsXPIDLString.h> +#include <nsCOMPtr.h> +#include <nsIURI.h> +#include <nsIDOMWindow.h> +#include <nsIWindowWatcher.h> +#include <nsIServiceManager.h> +#include <nsXPComFactory.h> + +#include "ephy-prefs.h" +#include "eel-gconf-extensions.h" + +#include "ExternalProtocolService.h" + +#define WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1" + +/* Implementation file */ +NS_IMPL_ISUPPORTS1(GExternalProtocolService, nsIExternalProtocolService) + +GExternalProtocolService::GExternalProtocolService() +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ +} + +GExternalProtocolService::~GExternalProtocolService() +{ + /* destructor code */ +} + +/* boolean externalProtocolHandlerExists (in string aProtocolScheme); */ +NS_IMETHODIMP GExternalProtocolService:: + ExternalProtocolHandlerExists(const char *aProtocolScheme, + PRBool *_retval) +{ + /* build the config key */ + char *key = g_strconcat ("/desktop/gnome/url-handlers/", + aProtocolScheme, + "/command", NULL); + + char *tmp = eel_gconf_get_string(key); + g_free (key); + + *_retval = (tmp != NULL); + g_free (tmp); + + return NS_OK; +} + +/* void loadUrl (in nsIURI aURL); */ +NS_IMETHODIMP GExternalProtocolService::LoadUrl(nsIURI *aURL) +{ + nsCAutoString cSpec; + aURL->GetSpec (cSpec); + nsCAutoString cScheme; + aURL->GetScheme (cScheme); + + if (cScheme.Equals("http")) + { + nsresult rv; + nsCOMPtr<nsIWindowWatcher> ww; + ww = do_GetService(WINDOWWATCHER_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr<nsIDOMWindow> newWin; + rv = ww->OpenWindow(nsnull, cSpec.get(), + nsnull, nsnull, nsnull, + getter_AddRefs(newWin)); + if (NS_SUCCEEDED(rv)) return NS_OK; + } + } + + /* build the config key */ + const nsCAutoString key(NS_LITERAL_CSTRING("/desktop/gnome/url-handlers/") + + cScheme + NS_LITERAL_CSTRING("/command")); + + /* find it */ + char *result = eel_gconf_get_string(key.get()); + if (result) + { + gnome_url_show(cSpec.get(), NULL); + g_free (result); + return NS_OK; + } + + /* no luck, so offer the user the option of trying the + * default handler -- we don't do this automatically in + * case the default handler is erroneously set to epiphany */ + result = eel_gconf_get_string("/desktop/gnome/url-handlers/unknown/command"); + + /* check there is a default */ + { + GtkWidget *dialog; + + /* throw the error */ + dialog = gtk_message_dialog_new (NULL, (GtkDialogFlags)0, + GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, + _("Galeon cannot handle this protocol,\n" + "and no GNOME default handler is set")); + gtk_dialog_run (GTK_DIALOG(dialog)); + gtk_widget_destroy (dialog); + + /* don't let mozilla try blindly */ + return NS_ERROR_FAILURE; + } + g_free (result); + + /* offer the choice */ + GtkWidget *dialog = gtk_message_dialog_new (NULL, (GtkDialogFlags)0, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + _("The protocol specified " + "is not recognised.\n\n" + "Would you like to try " + "the GNOME default?")); + + int ret = gtk_dialog_run (GTK_DIALOG(dialog)); + gtk_widget_destroy (dialog); + + if (ret == 0) + { + gnome_url_show(cSpec.get(), NULL); + return NS_OK; + } + else + { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_DEF_FACTORY (GExternalProtocolService, GExternalProtocolService); + +/** + * NS_NewExternalProtocolServiceFactory: + */ +nsresult NS_NewExternalProtocolServiceFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGExternalProtocolServiceFactory *result = new nsGExternalProtocolServiceFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/ExternalProtocolService.h b/embed/mozilla/ExternalProtocolService.h new file mode 100644 index 000000000..3c49d61e7 --- /dev/null +++ b/embed/mozilla/ExternalProtocolService.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __ExternalProtocolService_h__ +#define __ExternalProtocolService_h__ + +#include "nsError.h" +#include "nsCExternalHandlerService.h" +#include "nsIExternalProtocolService.h" + +class GExternalProtocolService : public nsIExternalProtocolService +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIEXTERNALPROTOCOLSERVICE + + GExternalProtocolService(); + virtual ~GExternalProtocolService(); + /* additional members */ +}; + +#define G_EXTERNALPROTOCOLSERVICE_CID \ +{ /* d2a2f743-f126-4f1f-8921-d4e50490f112 */ \ + 0xd2a2f743, \ + 0xf126, \ + 0x4f1f, \ + {0x89, 0x21, 0xd4, 0xe5, 0x04, 0x90, 0xf1, 0x12} \ +} +#define G_EXTERNALPROTOCOLSERVICE_CLASSNAME "Galeon's ExternalProtocolService" + +class nsIFactory; + +extern nsresult NS_NewExternalProtocolServiceFactory(nsIFactory** aFactory); + +#endif // __ExternalProtocolService_h__ diff --git a/embed/mozilla/FilePicker.cpp b/embed/mozilla/FilePicker.cpp new file mode 100644 index 000000000..baae069ef --- /dev/null +++ b/embed/mozilla/FilePicker.cpp @@ -0,0 +1,505 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* Things to be aware of: + * + * This filepicker, like the mozilla one, does not make an attempt + * to verify the validity of the initial directory you pass it. + * It does check that the user doesn't give it a garbage path + * during use, but it is the caller's responsibility to give a + * sensible initial path. + * + * At the current moment, we instantiate the filepicker directly + * in our contenthandler where there is path verification code + * and else where through our C wrapper, which also does verification. + * If, at a future date, you need to instantiate filepicker without + * using the C wrapper, please verify the initial path. See + * ContentHandler for a way to do this. + */ + +#include "ephy-string.h" +#include "ephy-gui.h" +#include "eel-gconf-extensions.h" + +#include <gtk/gtkmain.h> +#include <gtk/gtksignal.h> +#include <gtk/gtkmenu.h> +#include <gtk/gtkmenuitem.h> +#include <gtk/gtkcheckbutton.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtkfilesel.h> +#include <gtk/gtkhbbox.h> +#include <gtk/gtkoptionmenu.h> +#include <gtk/gtkmessagedialog.h> +#include <libgnome/gnome-i18n.h> + +#include "nsIFilePicker.h" + +#include "nsCRT.h" +#include "nsCOMPtr.h" +#include "nsIFactory.h" +#include "nsISupportsArray.h" +#include "nsIServiceManager.h" +#include "nsXPComFactory.h" + +#include "nsString.h" +#include "nsXPIDLString.h" +#include "nsIPrefService.h" +#include "nsIURI.h" +#include "nsIFileURL.h" +#include "nsIChannel.h" +#include "nsIFileChannel.h" +#include "nsNetCID.h" +#include "nsILocalFile.h" +#include "nsIPromptService.h" +#include "nsReadableUtils.h" + +#include <libgnome/gnome-util.h> + +#include "FilePicker.h" +#include "MozillaPrivate.h" + +void filePicker_save_content_cb(GtkToggleButton *aButton, + GFilePicker *aFilePicker); + +/* Implementation file */ +NS_IMPL_ISUPPORTS1(GFilePicker, nsIFilePicker) + +GFilePicker::GFilePicker(PRBool showContentCheck, FileFormat *fileFormats) : + mSaveContent(PR_FALSE) +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ + + mShowContentCheck = showContentCheck; + mFileFormats = fileFormats; + mFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + mDisplayDirectory = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + mDisplayDirectory->InitWithNativePath(nsDependentCString(g_get_home_dir())); +} + +GFilePicker::~GFilePicker() +{ + /* destructor code */ +} + +//////////////////////////////////////////////////////////////////////////////// +// begin nsIFilePicker impl +//////////////////////////////////////////////////////////////////////////////// + +/* void init (in nsIDOMWindowInternal parent, in wstring title, in short mode); */ +NS_IMETHODIMP GFilePicker::Init(nsIDOMWindowInternal *aParent, + const PRUnichar *aTitle, PRInt16 aMode) +{ + mParent = do_QueryInterface(aParent); + mParentWidget = MozillaFindGtkParent(mParent); + mTitle = NS_ConvertUCS2toUTF8(aTitle); + mMode = aMode; + + return NS_OK; +} + +/* void appendFilters (in long filterMask); */ +NS_IMETHODIMP GFilePicker::AppendFilters(PRInt32 aFilterMask) +{ + //This function cannot be implemented due to the crippled + //nature of GtkFileSelection, but NS_ERROR_NOT_IMPLEMENTED + //is interpreted as a terminal error by some callers. + return NS_OK; +} + +/* void appendFilter (in wstring title, in wstring filter); */ +NS_IMETHODIMP GFilePicker::AppendFilter(const PRUnichar *aTitle, + const PRUnichar *aFilter) +{ + //GtkFileSelection is crippled, so we can't provide a short-list + //of filters to choose from. We provide minimal functionality + //by using the most recent AppendFilter call as the active filter. + mFilter = NS_ConvertUCS2toUTF8(aFilter); + return NS_OK; +} + +/* attribute long filterIndex; */ +NS_IMETHODIMP GFilePicker::GetFilterIndex(PRInt32 *aFilterIndex) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP GFilePicker::SetFilterIndex(PRInt32 aFilterIndex) +{ + return NS_OK; +} + +/* attribute wstring defaultString; */ +NS_IMETHODIMP GFilePicker::GetDefaultString(PRUnichar * *aDefaultString) +{ + *aDefaultString = ToNewUnicode(NS_ConvertUTF8toUCS2(mDefaultString)); + return NS_OK; +} +NS_IMETHODIMP GFilePicker::SetDefaultString(const PRUnichar *aDefaultString) +{ + if (aDefaultString) + mDefaultString = NS_ConvertUCS2toUTF8(aDefaultString); + else + mDefaultString = ""; + return NS_OK; +} + +/* attribute wstring defaultExtension; */ +// Again, due to the crippled file selector, we can't really +// do anything here. +NS_IMETHODIMP GFilePicker::GetDefaultExtension(PRUnichar * *aDefaultExtension) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} +NS_IMETHODIMP GFilePicker::SetDefaultExtension(const PRUnichar *aDefaultExtension) +{ + return NS_OK; +} + +/* attribute nsILocalFile displayDirectory; */ +NS_IMETHODIMP GFilePicker::GetDisplayDirectory(nsILocalFile * *aDisplayDirectory) +{ + NS_IF_ADDREF(*aDisplayDirectory = mDisplayDirectory); + return NS_OK; +} +NS_IMETHODIMP GFilePicker::SetDisplayDirectory(nsILocalFile * aDisplayDirectory) +{ + mDisplayDirectory = aDisplayDirectory; + return NS_OK; +} + +/* readonly attribute nsILocalFile file; */ +NS_IMETHODIMP GFilePicker::GetFile(nsILocalFile * *aFile) +{ + NS_IF_ADDREF(*aFile = mFile); + return NS_OK; +} + +/* readonly attribute nsIFileURL fileURL; */ +NS_IMETHODIMP GFilePicker::GetFileURL(nsIFileURL * *aFileURL) +{ + nsCOMPtr<nsIFileURL> fileURL = + do_CreateInstance(NS_STANDARDURL_CONTRACTID); + fileURL->SetFile(mFile); + NS_IF_ADDREF(*aFileURL = fileURL); + return NS_OK; +} + +/* readonly attribute nsISimpleEnumerator files; */ +NS_IMETHODIMP GFilePicker::GetFiles(nsISimpleEnumerator * *aFiles) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* short show (); */ +NS_IMETHODIMP GFilePicker::Show(PRInt16 *_retval) +{ + mFileSelector = gtk_file_selection_new(mTitle.get()); + + nsCAutoString cFileName; + if(mMode == nsIFilePicker::modeGetFolder) + cFileName.Assign(""); + else + cFileName = mDefaultString; + + nsCAutoString cDirName; + mDisplayDirectory->GetNativePath(cDirName); + + nsCAutoString cFullPath; + cFullPath.Assign(cDirName + NS_LITERAL_CSTRING("/") + cFileName); + gtk_file_selection_set_filename(GTK_FILE_SELECTION(mFileSelector), + cFullPath.get()); + + if (!mFilter.IsEmpty()) + { + gtk_file_selection_complete(GTK_FILE_SELECTION(mFileSelector), + mFilter.get()); + } + + if (mParentWidget) + gtk_window_set_transient_for(GTK_WINDOW(mFileSelector), + GTK_WINDOW(mParentWidget)); + + if (mShowContentCheck) + { + GtkWidget *bbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), + GTK_BUTTONBOX_END); + gtk_box_set_spacing(GTK_BOX(bbox), 0); + gtk_box_pack_end(GTK_BOX(GTK_FILE_SELECTION(mFileSelector)->action_area), + bbox, TRUE, TRUE, 0); + + GtkWidget *saveContent = + gtk_check_button_new_with_label(_("Save with content")); + g_signal_connect(G_OBJECT(saveContent), + "clicked", + G_CALLBACK(filePicker_save_content_cb), + (gpointer)this); + + gtk_box_pack_start(GTK_BOX(bbox), saveContent, + FALSE, FALSE, 0); + + gtk_widget_show_all(bbox); + } + + if (mFileFormats) + { + mFormatChooser = gtk_option_menu_new(); + GtkMenu *options = GTK_MENU(gtk_menu_new()); + + FileFormat *current = mFileFormats; + while (current->description != NULL) + { + /* FIXME: the label should include the extensions too */ + gchar *label = current->description; + GtkWidget *item = gtk_menu_item_new_with_label(label); + gtk_widget_show(item); + gtk_menu_shell_append(GTK_MENU_SHELL(options), item); + current++; + } + gtk_option_menu_set_menu(GTK_OPTION_MENU(mFormatChooser), + GTK_WIDGET(options)); + gtk_widget_show(mFormatChooser); + gtk_box_pack_start(GTK_BOX(GTK_FILE_SELECTION (mFileSelector)->action_area), + mFormatChooser, + FALSE, TRUE, 0); + } + else + { + mFormatChooser = NULL; + } + + if (mMode == nsIFilePicker::modeGetFolder) + { + gtk_widget_set_sensitive(GTK_FILE_SELECTION(mFileSelector) + ->file_list, FALSE); + } + + gtk_window_set_modal(GTK_WINDOW(mFileSelector), TRUE); + + gint retVal = gtk_dialog_run(GTK_DIALOG(mFileSelector)); + + if (retVal == GTK_RESPONSE_OK) + { + HandleFilePickerResult(_retval); + } + else + { + *_retval = returnCancel; + } + + gtk_widget_hide(mFileSelector); + gtk_widget_destroy(mFileSelector); + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin local public methods impl +//////////////////////////////////////////////////////////////////////////////// + +NS_METHOD GFilePicker::InitWithGtkWidget (GtkWidget *aParentWidget, + const char *aTitle, PRInt16 aMode) +{ + mParentWidget = aParentWidget; + + mTitle = nsDependentCString(aTitle); + + mMode = mMode; + + mFile = do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + + return NS_OK; +} + +NS_METHOD GFilePicker::SanityCheck (PRBool *retIsSane) +{ + *retIsSane = PR_TRUE; + + PRBool dirExists, fileExists = PR_TRUE; + + if (mDisplayDirectory) + { + mDisplayDirectory->Exists (&dirExists); + } + else + { + dirExists = PR_FALSE; + } + + if (mMode == nsIFilePicker::modeOpen) + { + mFile->Exists (&fileExists); + } + + if (!dirExists || !fileExists) + { + GtkWidget *errorDialog = gtk_message_dialog_new ( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + _("The specified path does not exist.")); + + if (mParentWidget) + gtk_window_set_transient_for(GTK_WINDOW(errorDialog), + GTK_WINDOW(mFileSelector)); + + gtk_window_set_modal (GTK_WINDOW(errorDialog), TRUE); + gtk_dialog_run (GTK_DIALOG(errorDialog)); + *retIsSane = PR_FALSE; + return NS_OK; + } + + PRBool correctType; + char *errorText; + if (mMode == nsIFilePicker::modeGetFolder) + { + mDisplayDirectory->IsDirectory (&correctType); + errorText = g_strdup (_("A file was selected when a " + "folder was expected.")); + } + else + { + mFile->IsFile (&correctType); + errorText = g_strdup (_("A folder was selected when a " + "file was expected.")); + } + + if(!correctType) + { + GtkWidget *errorDialog = gtk_message_dialog_new ( + NULL, + GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + errorText); + + if (mParentWidget) + gtk_window_set_transient_for(GTK_WINDOW(errorDialog), + GTK_WINDOW(mFileSelector)); + + gtk_window_set_modal (GTK_WINDOW(errorDialog), TRUE); + gtk_dialog_run (GTK_DIALOG(errorDialog)); + *retIsSane = PR_FALSE; + } + g_free (errorText); + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin local private methods impl +//////////////////////////////////////////////////////////////////////////////// + +NS_METHOD GFilePicker::HandleFilePickerResult(PRInt16 *retval) +{ + *retval = returnCancel; + nsresult rv; + + const char *fileName = gtk_file_selection_get_filename(GTK_FILE_SELECTION(mFileSelector)); + + if (!fileName || strlen(fileName) == 0) return NS_ERROR_FAILURE; + + if (mMode == nsIFilePicker::modeSave) + { + if (!ephy_gui_confirm_overwrite_file (mFileSelector, + fileName)) + { + return NS_OK; + } + } + + const nsACString &cFileName = nsDependentCString(fileName); + mFile->InitWithNativePath(cFileName); + + if (mMode == nsIFilePicker::modeGetFolder) + { + mDisplayDirectory->InitWithNativePath(cFileName); + mDefaultString = ""; + } + else + { + nsCOMPtr<nsIFile> directory; + mFile->GetParent(getter_AddRefs(directory)); + mDisplayDirectory = do_QueryInterface(directory); + mFile->GetNativeLeafName(mDefaultString); + } + + PRBool passesSanityCheck; + rv = SanityCheck(&passesSanityCheck); + if (NS_SUCCEEDED(rv) && !passesSanityCheck) return NS_ERROR_FAILURE; + + if (mFormatChooser) + { + gint i = 0; + GtkWidget *menu = gtk_option_menu_get_menu + (GTK_OPTION_MENU(mFormatChooser)); + GList *iterator = GTK_MENU_SHELL(menu)->children; + GtkWidget *selected = gtk_menu_get_active (GTK_MENU(menu)); + + while (iterator) + { + if (iterator->data == selected) + { + mSelectedFileFormat = i; + break; + } + iterator = iterator->next; + i++; + } + } + + *retval = mSaveContent ? returnOKSaveContent : returnOK; + return NS_OK; +} + +//------------------------------------------------------------------------------ + +NS_DEF_FACTORY (GFilePicker, GFilePicker); + +/** + * NS_NewFilePickerFactory: + */ +nsresult NS_NewFilePickerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGFilePickerFactory *result = new nsGFilePickerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} + +//////////////////////////////////////////////////////////////////////////////// +// begin FileSelector callbacks. +//////////////////////////////////////////////////////////////////////////////// + +void filePicker_save_content_cb(GtkToggleButton *aButton, + GFilePicker *aFilePicker) +{ + aFilePicker->mSaveContent = gtk_toggle_button_get_active (aButton) ? + PR_TRUE : PR_FALSE; +} diff --git a/embed/mozilla/FilePicker.h b/embed/mozilla/FilePicker.h new file mode 100644 index 000000000..93c025637 --- /dev/null +++ b/embed/mozilla/FilePicker.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef FILE_PICKER_H +#define FILE_PICKER_H + +#include "nsIFilePicker.h" +#include "nsError.h" +#include "nsIDOMWindow.h" +#include "nsIDOMWindowInternal.h" +#include "nsCOMPtr.h" +#include "nsString.h" +#include "nsILocalFile.h" +#include <gtk/gtktogglebutton.h> +#include "ephy-embed-shell.h" + +#define G_FILEPICKER_CID \ +{ /* 3636dc79-0b42-4bad-8a3f-ae15d3671d17 */ \ + 0x3636dc79, \ + 0x0b42, \ + 0x4bad, \ + {0x8a, 0x3f, 0xae, 0x15, 0xd3, 0x67, 0x1d, 0x17} \ +} + +#define G_FILEPICKER_CONTRACTID "@mozilla.org/filepicker;1" +#define G_FILEPICKER_CLASSNAME "Galeon's File Picker Implementation" + +class nsIFactory; + +extern nsresult NS_NewFilePickerFactory(nsIFactory** aFactory); + +/* Header file */ +class GFilePicker : public nsIFilePicker +{ + friend void filePicker_save_content_cb(GtkToggleButton *aButton, + GFilePicker *aFilePicker); + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIFILEPICKER + enum { returnOK = nsIFilePicker::returnOK, + returnCancel = nsIFilePicker::returnCancel, + returnReplace = nsIFilePicker::returnReplace, + returnOKSaveContent = 256 }; + + GFilePicker(PRBool aShowContentCheck = PR_FALSE, FileFormat *aFileFormats = NULL); + virtual ~GFilePicker(); + + /* additional members */ + NS_METHOD InitWithGtkWidget(GtkWidget *aParentWidget, + const char *aTitle, PRInt16 aMode); + NS_METHOD SanityCheck(PRBool *retIsSane); + + PRInt16 mSelectedFileFormat; + + private: + NS_METHOD HandleFilePickerResult(PRInt16 *retval); + + nsCOMPtr<nsIDOMWindow> mParent; + + nsCString mTitle; + nsCString mFilter; + nsCString mDefaultString; + + nsCOMPtr<nsILocalFile> mFile; + nsCOMPtr<nsILocalFile> mDisplayDirectory; + + PRInt16 mMode; + + PRBool mShowContentCheck; + PRBool mSaveContent; + + GtkWidget *mParentWidget; + GtkWidget *mFileSelector; + GtkWidget *mFormatChooser; + + FileFormat *mFileFormats; +}; + +#endif diff --git a/embed/mozilla/FtpProtocolHandler.cpp b/embed/mozilla/FtpProtocolHandler.cpp new file mode 100644 index 000000000..a9b299095 --- /dev/null +++ b/embed/mozilla/FtpProtocolHandler.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "nsIFactory.h" +#include "nsXPComFactory.h" + +#include "BaseProtocolContentHandler.h" + +class GFtpProtocolHandler : public GBaseProtocolContentHandler +{ + public: + NS_DECL_ISUPPORTS + GFtpProtocolHandler() : GBaseProtocolContentHandler("ftp") + {NS_INIT_ISUPPORTS();}; + virtual ~GFtpProtocolHandler() {}; + /* additional members */ +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS2 (GFtpProtocolHandler, nsIProtocolHandler, nsIContentHandler) + +NS_DEF_FACTORY (GFtpProtocolHandler, GFtpProtocolHandler); + +/** + * NS_NewFtpHandlerFactory: + */ +nsresult NS_NewFtpHandlerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGFtpProtocolHandlerFactory *result = + new nsGFtpProtocolHandlerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/FtpProtocolHandler.h b/embed/mozilla/FtpProtocolHandler.h new file mode 100644 index 000000000..d305501d5 --- /dev/null +++ b/embed/mozilla/FtpProtocolHandler.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __FtpProtocolHandler_h__ +#define __FtpProtocolHandler_h__ + +#include "nsError.h" +#include "nsIProtocolHandler.h" +#include "nsCURILoader.h" + +#define G_FTP_PROTOCOL_CID \ +{ /* 5a48bdf4-a422-4eb4-b073-0fc3bee8e670 */ \ + 0x5a48bdf4, \ + 0xa422, \ + 0x4eb4, \ + {0xb0, 0x73, 0x0f, 0xc3, 0xbe, 0xe8, 0xe6, 0x70} \ +} +#define G_FTP_PROTOCOL_CONTRACTID NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "ftp" +#define G_FTP_PROTOCOL_CLASSNAME "Galeon's FTP Protocol Handler" +#define G_FTP_CONTENT_CONTRACTID NS_CONTENT_HANDLER_CONTRACTID_PREFIX \ + "application-x-gnome-ftp" +#define G_FTP_CONTENT_CLASSNAME "Galeon's FTP Content Handler" + +#define NS_FTPPROTOCOLHANDLER_CID \ +{ \ + 0x25029490, \ + 0xf132, \ + 0x11d2, \ + {0x95, 0x88, 0x0, 0x80, 0x5f, 0x36, 0x9f, 0x95} \ +} +#define NS_FTPPROTOCOLHANDLER_CLASSNAME "The FTP Protocol Handler" + +class nsIFactory; + +extern nsresult NS_NewFtpHandlerFactory(nsIFactory** aFactory); + +#endif // __FtpProtocolHandler_h__ diff --git a/embed/mozilla/GlobalHistory.cpp b/embed/mozilla/GlobalHistory.cpp new file mode 100644 index 000000000..a559dbc10 --- /dev/null +++ b/embed/mozilla/GlobalHistory.cpp @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "mozilla-embed-shell.h" + +#include "nsCOMPtr.h" +#include "nsISupportsArray.h" +#include "nsIFactory.h" +#include "nsIServiceManager.h" +#include "nsXPComFactory.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsIGlobalHistory.h" +#include "nsIBrowserHistory.h" +#include "nsIRequestObserver.h" + +/** + * class GlobalHistory: + * + */ +class MozGlobalHistory: public nsIGlobalHistory, + public nsIBrowserHistory +{ + public: + MozGlobalHistory (); + virtual ~MozGlobalHistory(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIGLOBALHISTORY + NS_DECL_NSIBROWSERHISTORY + + private: + EphyHistory *mGlobalHistory; +}; + +NS_IMPL_ADDREF(MozGlobalHistory) +NS_IMPL_RELEASE(MozGlobalHistory) +NS_INTERFACE_MAP_BEGIN(MozGlobalHistory) + NS_INTERFACE_MAP_ENTRY(nsIGlobalHistory) + NS_INTERFACE_MAP_ENTRY(nsIBrowserHistory) +NS_INTERFACE_MAP_END + +MozGlobalHistory::MozGlobalHistory () +{ + NS_INIT_ISUPPORTS(); + + mGlobalHistory = ephy_embed_shell_get_global_history (embed_shell); +} + +MozGlobalHistory::~MozGlobalHistory () +{ +} + +/* void addPage (in string aURL); */ +NS_IMETHODIMP MozGlobalHistory::AddPage (const char *aURL) +{ + ephy_history_add_page (mGlobalHistory, aURL); + + return NS_OK; +} + +/* boolean isVisited (in string aURL); */ +NS_IMETHODIMP MozGlobalHistory::IsVisited (const char *aURL, PRBool *_retval) +{ + *_retval = ephy_history_is_page_visited (mGlobalHistory, aURL); + + return NS_OK; +} + +/* void setPageTitle (in string aURL, in wstring aTitle); */ +NS_IMETHODIMP MozGlobalHistory::SetPageTitle (const char *aURL, + const PRUnichar *aTitle) +{ + const nsACString &title = NS_ConvertUCS2toUTF8 (aTitle); + + ephy_history_set_page_title (mGlobalHistory, aURL, PromiseFlatCString(title).get()); + + /* done */ + return NS_OK; +} + +/* void removePage (in string aURL); */ +NS_IMETHODIMP MozGlobalHistory::RemovePage(const char *aURL) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void removePagesFromHost (in string aHost, in boolean aEntireDomain); */ +NS_IMETHODIMP MozGlobalHistory::RemovePagesFromHost(const char *aHost, + PRBool aEntireDomain) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void removeAllPages (); */ +NS_IMETHODIMP MozGlobalHistory::RemoveAllPages() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* readonly attribute string lastPageVisited; */ +NS_IMETHODIMP MozGlobalHistory::GetLastPageVisited(char **aLastPageVisited) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP MozGlobalHistory::HidePage(const char *url) +{ + return NS_ERROR_NOT_IMPLEMENTED; + +} + +/* readonly attribute PRUint32 count; */ +NS_IMETHODIMP MozGlobalHistory::GetCount(PRUint32 *aCount) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void startBatchUpdate (); */ +NS_IMETHODIMP MozGlobalHistory::StartBatchUpdate() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void endBatchUpdate (); */ +NS_IMETHODIMP MozGlobalHistory::EndBatchUpdate() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void markPageAsTyped (in string url); */ +NS_IMETHODIMP MozGlobalHistory::MarkPageAsTyped(const char *url) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_DEF_FACTORY (MozGlobalHistory, MozGlobalHistory); + +nsresult NS_NewGlobalHistoryFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsMozGlobalHistoryFactory *result = new nsMozGlobalHistoryFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/GlobalHistory.h b/embed/mozilla/GlobalHistory.h new file mode 100644 index 000000000..5b2e615a1 --- /dev/null +++ b/embed/mozilla/GlobalHistory.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __GlobalHistory_h +#define __GlobalHistory_h + +#include "nsError.h" + +#define GALEON_GLOBALHISTORY_CID \ + { 0xbe0c42c1, 0x39d4, 0x4271, { 0xb7, 0x9e, 0xf7, 0xaa, 0x49, 0xeb, 0x6a, 0x15}} + +class nsIFactory; + +extern nsresult NS_NewGlobalHistoryFactory(nsIFactory** aFactory); + +#endif diff --git a/embed/mozilla/IRCProtocolHandler.cpp b/embed/mozilla/IRCProtocolHandler.cpp new file mode 100644 index 000000000..b1c4d7f68 --- /dev/null +++ b/embed/mozilla/IRCProtocolHandler.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "nsIFactory.h" +#include "nsXPComFactory.h" + +#include "BaseProtocolContentHandler.h" + +class GIRCProtocolHandler : public GBaseProtocolContentHandler +{ + public: + NS_DECL_ISUPPORTS + GIRCProtocolHandler() : GBaseProtocolContentHandler("irc") + {NS_INIT_ISUPPORTS();}; + virtual ~GIRCProtocolHandler() {}; + /* additional members */ +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS2 (GIRCProtocolHandler, nsIProtocolHandler, nsIContentHandler) + +NS_DEF_FACTORY (GIRCProtocolHandler, GIRCProtocolHandler); + +/** + * NS_NewIRCHandlerFactory: + */ +nsresult NS_NewIRCHandlerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGIRCProtocolHandlerFactory *result = + new nsGIRCProtocolHandlerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/IRCProtocolHandler.h b/embed/mozilla/IRCProtocolHandler.h new file mode 100644 index 000000000..149daa121 --- /dev/null +++ b/embed/mozilla/IRCProtocolHandler.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __IRCProtocolHandler_h__ +#define __IRCProtocolHandler_h__ + +#include "nsError.h" +#include "nsIProtocolHandler.h" +#include "nsCURILoader.h" + +#define G_IRC_PROTOCOL_CID \ +{ /* aabe33d3-7455-4d8f-87e7-43e4541ace4e */ \ + 0xaabe33d3, \ + 0x7455, \ + 0x4d8f, \ + {0x87, 0xe7, 0x43, 0xe4, 0x54, 0x1a, 0xce, 0x4e} \ +} +#define G_IRC_PROTOCOL_CONTRACTID NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "irc" +#define G_IRC_PROTOCOL_CLASSNAME "Galeon's irc Protocol Handler" +#define G_IRC_CONTENT_CONTRACTID NS_CONTENT_HANDLER_CONTRACTID_PREFIX \ + "application-x-gnome-irc" +#define G_IRC_CONTENT_CLASSNAME "Galeon's irc Content Handler" + +class nsIFactory; + +extern nsresult NS_NewIRCHandlerFactory(nsIFactory** aFactory); + +#endif // __IRCProtocolHandler_h__ diff --git a/embed/mozilla/MailtoProtocolHandler.cpp b/embed/mozilla/MailtoProtocolHandler.cpp new file mode 100644 index 000000000..946f14aff --- /dev/null +++ b/embed/mozilla/MailtoProtocolHandler.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "nsIFactory.h" +#include "nsXPComFactory.h" +#include "nsString.h" +#include "nsIURI.h" +#include "nsNetUtil.h" +#include "nsIExternalProtocolService.h" +#include "nsCExternalHandlerService.h" +#include "nsCRT.h" + +#include "BaseProtocolContentHandler.h" + +class GMailtoProtocolHandler : public GBaseProtocolContentHandler +{ + public: + NS_DECL_ISUPPORTS + GMailtoProtocolHandler() : GBaseProtocolContentHandler("mailto") + {NS_INIT_ISUPPORTS();}; + virtual ~GMailtoProtocolHandler() {}; + private: +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS2 (GMailtoProtocolHandler, nsIProtocolHandler, nsIContentHandler) + +NS_DEF_FACTORY (GMailtoProtocolHandler, GMailtoProtocolHandler); + +/** + * NS_NewMailtoHandlerFactory: + */ +nsresult NS_NewMailtoHandlerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGMailtoProtocolHandlerFactory *result = + new nsGMailtoProtocolHandlerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/MailtoProtocolHandler.h b/embed/mozilla/MailtoProtocolHandler.h new file mode 100644 index 000000000..961f42c42 --- /dev/null +++ b/embed/mozilla/MailtoProtocolHandler.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __MailtoProtocolHandler_h__ +#define __MailtoProtocolHandler_h__ + +#include "nsError.h" +#include "nsIProtocolHandler.h" +#include "nsCURILoader.h" + +#define G_MAILTO_PROTOCOL_CID \ +{ /* aabe33d3-7455-4d8f-87e7-43e4541ace4d */ \ + 0xaabe33d3, \ + 0x7455, \ + 0x4d8f, \ + {0x87, 0xe7, 0x43, 0xe4, 0x54, 0x1a, 0xce, 0x4d} \ +} +#define G_MAILTO_PROTOCOL_CONTRACTID NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "mailto" +#define G_MAILTO_PROTOCOL_CLASSNAME "Galeon's mailto Protocol Handler" +#define G_MAILTO_CONTENT_CONTRACTID NS_CONTENT_HANDLER_CONTRACTID_PREFIX \ + "application-x-gnome-mailto" +#define G_MAILTO_CONTENT_CLASSNAME "Galeon's mailto Content Handler" + +class nsIFactory; + +extern nsresult NS_NewMailtoHandlerFactory(nsIFactory** aFactory); + +#endif // __MailtoProtocolHandler_h__ diff --git a/embed/mozilla/Makefile.am b/embed/mozilla/Makefile.am new file mode 100644 index 000000000..ef7ef9dfa --- /dev/null +++ b/embed/mozilla/Makefile.am @@ -0,0 +1,108 @@ +#MOZILLA_ACDEFINES = -include $(MOZILLA_INCLUDE_ROOT)/mozilla-config.h +MOZILLA_ACDEFINES=-DNEW_H=\<new\> + +INCLUDES = \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/embed \ + -I$(top_srcdir) \ + $(WARN_CFLAGS) \ + $(MOZILLA_COMPONENT_CFLAGS) \ + -I$(MOZILLA_INCLUDE_ROOT) \ + -I$(MOZILLA_INCLUDE_ROOT)/appcomps \ + -I$(MOZILLA_INCLUDE_ROOT)/content \ + -I$(MOZILLA_INCLUDE_ROOT)/cookie \ + -I$(MOZILLA_INCLUDE_ROOT)/docshell \ + -I$(MOZILLA_INCLUDE_ROOT)/dom \ + -I$(MOZILLA_INCLUDE_ROOT)/exthandler \ + -I$(MOZILLA_INCLUDE_ROOT)/find \ + -I$(MOZILLA_INCLUDE_ROOT)/gfx \ + -I$(MOZILLA_INCLUDE_ROOT)/helperAppDlg \ + -I$(MOZILLA_INCLUDE_ROOT)/java \ + -I$(MOZILLA_INCLUDE_ROOT)/jsconsole \ + -I$(MOZILLA_INCLUDE_ROOT)/layout \ + -I$(MOZILLA_INCLUDE_ROOT)/mimetype \ + -I$(MOZILLA_INCLUDE_ROOT)/mozxfer \ + -I$(MOZILLA_INCLUDE_ROOT)/necko \ + -I$(MOZILLA_INCLUDE_ROOT)/necko2 \ + -I$(MOZILLA_INCLUDE_ROOT)/nkcache \ + -I$(MOZILLA_INCLUDE_ROOT)/oji \ + -I$(MOZILLA_INCLUDE_ROOT)/pref \ + -I$(MOZILLA_INCLUDE_ROOT)/progressDlg \ + -I$(MOZILLA_INCLUDE_ROOT)/sidebar \ + -I$(MOZILLA_INCLUDE_ROOT)/shistory \ + -I$(MOZILLA_INCLUDE_ROOT)/uconv \ + -I$(MOZILLA_INCLUDE_ROOT)/uriloader \ + -I$(MOZILLA_INCLUDE_ROOT)/unicharutil \ + -I$(MOZILLA_INCLUDE_ROOT)/wallet \ + -I$(MOZILLA_INCLUDE_ROOT)/webbrowserpersist \ + -I$(MOZILLA_INCLUDE_ROOT)/webbrwsr \ + -I$(MOZILLA_INCLUDE_ROOT)/webshell \ + -I$(MOZILLA_INCLUDE_ROOT)/widget \ + -I$(MOZILLA_INCLUDE_ROOT)/windowwatcher \ + -I$(MOZILLA_INCLUDE_ROOT)/typeaheadfind \ + $(GCONF_CFLAGS) \ + $(EPIPHANY_DEPENDENCY_CFLAGS) \ + -DLIB_DIR=\"$(pkglibdir)\" \ + -DG_DISABLE_DEPRECATED \ + -DGDK_DISABLE_DEPRECATED \ + -DGTK_DISABLE_DEPRECATED \ + -DGDK_PIXBUF_DISABLE_DEPRECATED \ + -DGNOME_DISABLE_DEPRECATED \ + -DSHARE_DIR=\"$(pkgdatadir)\" \ + $(MOZILLA_ACDEFINES) + +noinst_LTLIBRARIES = libephymozillaembed.la + +libephymozillaembed_la_SOURCES = \ + mozilla-embed.cpp \ + mozilla-embed.h \ + mozilla-embed-shell.cpp \ + mozilla-embed-shell.h \ + mozilla-embed-persist.cpp \ + mozilla-embed-persist.h \ + mozilla-prefs.cpp \ + mozilla-prefs.h \ + mozilla-notifiers.cpp \ + mozilla-notifiers.h \ + mozilla-i18n.c \ + mozilla-i18n.h \ + BaseProtocolHandler.cpp \ + BaseProtocolHandler.h \ + BaseProtocolContentHandler.cpp \ + BaseProtocolContentHandler.h \ + ContentHandler.cpp \ + ContentHandler.h \ + EventContext.cpp \ + EventContext.h \ + FilePicker.cpp \ + FilePicker.h \ + FtpProtocolHandler.cpp \ + FtpProtocolHandler.h \ + EphyWrapper.cpp \ + EphyWrapper.h \ + GlobalHistory.cpp \ + GlobalHistory.h \ + IRCProtocolHandler.cpp \ + IRCProtocolHandler.h \ + MailtoProtocolHandler.cpp \ + MailtoProtocolHandler.h \ + MozillaPrivate.cpp \ + MozillaPrivate.h \ + MozRegisterComponents.cpp \ + MozRegisterComponents.h \ + PrintingPromptService.cpp \ + PrintingPromptService.h \ + PrintProgressListener.cpp \ + PrintProgressListener.h \ + PromptService.cpp \ + PromptService.h \ + ProgressListener.cpp \ + ProgressListener.h \ + nsUnicharUtils.cpp \ + nsUnicharUtils.h \ + ExternalProtocolService.cpp \ + ExternalProtocolService.h \ + StartHereProtocolHandler.cpp \ + StartHereProtocolHandler.h \ + EphyEventListener.cpp \ + EphyEventListener.h diff --git a/embed/mozilla/MozRegisterComponents.cpp b/embed/mozilla/MozRegisterComponents.cpp new file mode 100644 index 000000000..3c5e64be7 --- /dev/null +++ b/embed/mozilla/MozRegisterComponents.cpp @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "StartHereProtocolHandler.h" +#include "ContentHandler.h" +#include "ExternalProtocolService.h" +#include "FilePicker.h" +#include "FtpProtocolHandler.h" +#include "IRCProtocolHandler.h" +#include "MailtoProtocolHandler.h" +#include "PromptService.h" +#include "PrintingPromptService.h" +#include "ProgressListener.h" + +#include <nsIFactory.h> +#include <nsIComponentManager.h> +#include <nsCOMPtr.h> +#include <nsILocalFile.h> + +#include <glib.h> + +static NS_DEFINE_CID(kContentHandlerCID, G_CONTENTHANDLER_CID); +static NS_DEFINE_CID(kProtocolServiceCID, G_EXTERNALPROTOCOLSERVICE_CID); +static NS_DEFINE_CID(kFilePickerCID, G_FILEPICKER_CID); +static NS_DEFINE_CID(kStartHereProcotolHandlerCID, G_START_HERE_PROTOCOLHANDLER_CID); +static NS_DEFINE_CID(knsFtpProtocolHandlerCID, NS_FTPPROTOCOLHANDLER_CID); +static NS_DEFINE_CID(kFtpHandlerCID, G_FTP_PROTOCOL_CID); +static NS_DEFINE_CID(kIRCHandlerCID, G_IRC_PROTOCOL_CID); +static NS_DEFINE_CID(kMailtoHandlerCID, G_MAILTO_PROTOCOL_CID); +static NS_DEFINE_CID(kPromptServiceCID, G_PROMPTSERVICE_CID); +static NS_DEFINE_CID(kPrintingPromptServiceCID, G_PRINTINGPROMPTSERVICE_CID); +static NS_DEFINE_CID(kProgressDialogCID, G_PROGRESSDIALOG_CID); + +//RegisterFactory is local +NS_METHOD RegisterFactory (nsresult (aFactoryFunc)(nsIFactory** aFactory), + const nsCID & aClass, const char *aClassName, + const char *aContractID, PRBool aReplace); + +NS_METHOD RegisterComponent (const nsCID & aClass, const char *aClassName, + const char *aContractID, const char *aDLLPath, + PRBool aReplace); + +//Annoying globals to track the mozilla ftp handler so it can be restored. +static PRBool ftpRegistered = PR_FALSE; +static nsCOMPtr<nsIFactory> nsFtpFactory; + +/* FIXME why we need to use "C" here ???? */ + +extern "C" gboolean +mozilla_register_components (void) +{ + gboolean ret = TRUE; + nsresult rv; + + rv = RegisterFactory (NS_NewProgressListenerFactory, kProgressDialogCID, + G_PROGRESSDIALOG_CLASSNAME, + NS_DOWNLOAD_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewContentHandlerFactory, kContentHandlerCID, + NS_IHELPERAPPLAUNCHERDLG_CLASSNAME, + NS_IHELPERAPPLAUNCHERDLG_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewExternalProtocolServiceFactory, + kProtocolServiceCID, + G_EXTERNALPROTOCOLSERVICE_CLASSNAME, + NS_EXTERNALPROTOCOLSERVICE_CONTRACTID, + PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewFilePickerFactory, kFilePickerCID, + G_FILEPICKER_CLASSNAME, G_FILEPICKER_CONTRACTID, + PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewStartHereHandlerFactory, + kStartHereProcotolHandlerCID, + G_START_HERE_PROTOCOLHANDLER_CLASSNAME, + G_START_HERE_PROTOCOLHANDLER_CONTRACTID, + PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewFtpHandlerFactory, kFtpHandlerCID, + G_FTP_CONTENT_CLASSNAME, G_FTP_CONTENT_CONTRACTID, + PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewIRCHandlerFactory, kIRCHandlerCID, + G_IRC_PROTOCOL_CLASSNAME, + G_IRC_PROTOCOL_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewIRCHandlerFactory, kIRCHandlerCID, + G_IRC_CONTENT_CLASSNAME, + G_IRC_CONTENT_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewPromptServiceFactory, kPromptServiceCID, + G_PROMPTSERVICE_CLASSNAME, + G_PROMPTSERVICE_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + rv = RegisterFactory (NS_NewPrintingPromptServiceFactory, + kPrintingPromptServiceCID, + G_PRINTINGPROMPTSERVICE_CLASSNAME, + G_PRINTINGPROMPTSERVICE_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) ret = FALSE; + + return ret; +} + +NS_METHOD RegisterFactory (nsresult (aFactoryFunc)(nsIFactory** aFactory), + const nsCID & aClass, const char *aClassName, + const char *aContractID, PRBool aReplace) +{ + nsresult rv = NS_OK; + + nsCOMPtr<nsIFactory> factory; + rv = aFactoryFunc(getter_AddRefs(factory)); + if (NS_FAILED(rv)) return rv; + rv = nsComponentManager::RegisterFactory(aClass, aClassName, + aContractID, + factory, aReplace); + return rv; +} + +NS_METHOD RegisterComponent (const nsCID & aClass, const char *aClassName, + const char *aContractID, const char *aDLLPath, + PRBool aReplace) +{ + nsresult rv = NS_OK; + + nsCOMPtr<nsILocalFile> dllFile; + rv = NS_NewLocalFile (NS_ConvertUTF8toUCS2(aDLLPath), PR_TRUE, getter_AddRefs (dllFile)); + if (NS_FAILED(rv)) return NS_ERROR_FAILURE; + + rv = nsComponentManager::RegisterComponentSpec (aClass, + aClassName, + aContractID, + dllFile, + aReplace, + PR_FALSE); + return rv; +} + +/** + * mozilla_register_FtpProtocolHandler: Register Ftp Protocol Handler + */ +extern "C" gboolean +mozilla_register_FtpProtocolHandler (void) +{ + if (ftpRegistered == PR_TRUE) return TRUE; + + nsresult rv = NS_OK; + + rv = nsComponentManager::FindFactory (knsFtpProtocolHandlerCID, + getter_AddRefs(nsFtpFactory)); + if (NS_FAILED(rv)) return FALSE; + + rv = RegisterFactory (NS_NewFtpHandlerFactory, kFtpHandlerCID, + G_FTP_PROTOCOL_CLASSNAME, + G_FTP_PROTOCOL_CONTRACTID, PR_TRUE); + + if (NS_FAILED(rv)) return FALSE; + + ftpRegistered = PR_TRUE; + return NS_SUCCEEDED (rv) ? TRUE : FALSE; +} + +/** + * mozilla_unregister_FtpProtocolHandler: Unregister Ftp Protocol Handler + */ +extern "C" gboolean +mozilla_unregister_FtpProtocolHandler (void) +{ + if (ftpRegistered == PR_FALSE) return FALSE; + + nsresult rv = NS_OK; + + rv = nsComponentManager::RegisterFactory(knsFtpProtocolHandlerCID, + NS_FTPPROTOCOLHANDLER_CLASSNAME, + G_FTP_PROTOCOL_CONTRACTID, + nsFtpFactory, PR_TRUE); + + ftpRegistered = PR_FALSE; + return NS_SUCCEEDED (rv) ? TRUE : FALSE; +} + +/** + * mozilla_register_MailtoProtocolHandler: Register Mailto Protocol Handler + */ +extern "C" gboolean +mozilla_register_MailtoProtocolHandler (void) +{ + nsresult rv = NS_OK; + + rv = RegisterFactory (NS_NewMailtoHandlerFactory, kMailtoHandlerCID, + G_MAILTO_PROTOCOL_CLASSNAME, + G_MAILTO_PROTOCOL_CONTRACTID, PR_TRUE); + if (NS_FAILED(rv)) return FALSE; + + rv = RegisterFactory (NS_NewMailtoHandlerFactory, kMailtoHandlerCID, + G_MAILTO_CONTENT_CLASSNAME, + G_MAILTO_CONTENT_CONTRACTID, PR_TRUE); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; +} diff --git a/embed/mozilla/MozRegisterComponents.h b/embed/mozilla/MozRegisterComponents.h new file mode 100644 index 000000000..a263d9b74 --- /dev/null +++ b/embed/mozilla/MozRegisterComponents.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __MozRegisterComponents_h +#define __MozRegisterComponents_h + +#include <glib.h> + +G_BEGIN_DECLS + +gboolean mozilla_register_components (void); +gboolean mozilla_register_FtpProtocolHandler (void); +gboolean mozilla_unregister_FtpProtocolHandler (void); +gboolean mozilla_register_MailtoProtocolHandler (void); + +G_END_DECLS + +#endif // __MozRegisterComponents_h diff --git a/embed/mozilla/MozillaPrivate.cpp b/embed/mozilla/MozillaPrivate.cpp new file mode 100644 index 000000000..a7bc50a6c --- /dev/null +++ b/embed/mozilla/MozillaPrivate.cpp @@ -0,0 +1,105 @@ +#include "MozillaPrivate.h" + +#include <nsIServiceManagerUtils.h> +#include <nsIWindowWatcher.h> +#include <nsIEmbeddingSiteWindow.h> +#include <nsIWebBrowserChrome.h> +#include <gtkmozembed.h> + +GtkWidget *MozillaFindGtkParent (nsIDOMWindow *aDOMWindow) +{ + nsresult result; + + nsCOMPtr<nsIWindowWatcher> wwatch + (do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (!wwatch) return nsnull; + + nsCOMPtr<nsIDOMWindow> domWindow(aDOMWindow); + if (!domWindow) + { + result = wwatch->GetActiveWindow(getter_AddRefs(domWindow)); + if (NS_FAILED(result) || !domWindow) return nsnull; + } + + nsCOMPtr<nsIWebBrowserChrome> windowChrome; + result = wwatch->GetChromeForWindow (domWindow, + getter_AddRefs(windowChrome)); + if (NS_FAILED(result)) return nsnull; + + nsCOMPtr<nsIEmbeddingSiteWindow> window + (do_QueryInterface(windowChrome, &result)); + if (NS_FAILED(result)) return nsnull; + + GtkWidget *mozembed; + result = window->GetSiteWindow ((void **)&mozembed); + if (NS_FAILED(result)) return nsnull; + + return gtk_widget_get_toplevel (GTK_WIDGET(mozembed)); +} + + +NS_METHOD MozillaCollatePrintSettings (const EmbedPrintInfo *info, + nsIPrintSettings *options) +{ + const static int frame_types[] = { + nsIPrintSettings::kFramesAsIs, + nsIPrintSettings::kSelectedFrame, + nsIPrintSettings::kEachFrameSep + }; + /* these should match the order of the radiobuttons in the dialog + * and the paper names in the default print provider PS*/ + const static char *PaperSizeNames[] = { + "Letter","Legal","Executive","A4" + }; + + + switch (info->pages) + { + case 0: + break; + case 1: + options->SetPrintRange (nsIPrintSettings::kRangeSpecifiedPageRange); + options->SetStartPageRange (info->from_page); + options->SetEndPageRange (info->to_page); + break; + case 2: + options->SetPrintRange (nsIPrintSettings::kRangeSelection); + break; + } + + options->SetMarginTop (info->top_margin); + options->SetMarginBottom (info->bottom_margin); + options->SetMarginLeft (info->left_margin); + options->SetMarginRight (info->right_margin); + + options->SetPrinterName(NS_LITERAL_STRING("PostScript/default").get()); + + options->SetHeaderStrLeft(NS_ConvertUTF8toUCS2(info->header_left_string).get()); + + options->SetHeaderStrCenter(NS_ConvertUTF8toUCS2(info->header_center_string).get()); + + options->SetHeaderStrRight(NS_ConvertUTF8toUCS2(info->header_right_string).get()); + + options->SetFooterStrLeft(NS_ConvertUTF8toUCS2(info->footer_left_string).get()); + + options->SetFooterStrCenter(NS_ConvertUTF8toUCS2(info->footer_center_string).get()); + + options->SetFooterStrRight(NS_ConvertUTF8toUCS2(info->footer_right_string).get()); + + options->SetToFileName (NS_ConvertUTF8toUCS2(info->file).get()); + + options->SetPrintCommand (NS_ConvertUTF8toUCS2(info->printer).get()); + + options->SetPrintToFile (info->print_to_file); + + /* native paper size formats. Our dialog does not support custom yet */ + options->SetPaperSize (nsIPrintSettings::kPaperSizeNativeData); + int tps = (info->paper >= 0 || info->paper < 4) ? info->paper : 0; + options->SetPaperName (NS_ConvertUTF8toUCS2(PaperSizeNames[tps]).get()); + + options->SetPrintInColor (info->print_color); + options->SetOrientation (info->orientation); + options->SetPrintFrameType (frame_types[info->frame_type]); + + return NS_OK; +} diff --git a/embed/mozilla/MozillaPrivate.h b/embed/mozilla/MozillaPrivate.h new file mode 100644 index 000000000..be9ab4905 --- /dev/null +++ b/embed/mozilla/MozillaPrivate.h @@ -0,0 +1,9 @@ +#include <nsIPrintSettings.h> +#include <nsIDOMWindow.h> + +#include "ephy-embed.h" + +GtkWidget *MozillaFindGtkParent (nsIDOMWindow *aDOMWindow); + +NS_METHOD MozillaCollatePrintSettings (const EmbedPrintInfo *info, + nsIPrintSettings *settings); diff --git a/embed/mozilla/PrintProgressListener.cpp b/embed/mozilla/PrintProgressListener.cpp new file mode 100644 index 000000000..b4cf7b701 --- /dev/null +++ b/embed/mozilla/PrintProgressListener.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2002 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "libgnomevfs/gnome-vfs-mime-handlers.h" + +/* see the FIXME below */ +#include <locale.h> + +#include <libgnome/gnome-exec.h> + +#include "PrintProgressListener.h" + + +NS_IMPL_ISUPPORTS1(GPrintListener, nsIWebProgressListener) + +GPrintListener::GPrintListener() +{ + NS_INIT_ISUPPORTS(); + mFilename = NULL; +} + +GPrintListener::GPrintListener(char *filename) +{ + GPrintListener (); + mFilename = filename ? g_strdup (filename) : NULL; +} + +GPrintListener::~GPrintListener() +{ + g_free (mFilename); +} + +/* void onStateChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aStateFlags, in unsigned long aStatus); */ +NS_IMETHODIMP GPrintListener::OnStateChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 aStateFlags, + PRUint32 aStatus) +{ + if (aStateFlags & nsIWebProgressListener::STATE_STOP) + { + GnomeVFSMimeApplication *app; + gchar *command; + + /* FIXME(MOZILLA) ugly workaround for a mozilla problem with + * reseting the LC_* environment when printing */ + setlocale(LC_ALL,""); + if (!mFilename) return NS_OK; + + /* get the postscript handler */ + app = gnome_vfs_mime_get_default_application + ("application/postscript"); + if (app) + { + command = g_strconcat (app->command, " ", + mFilename, NULL); + gnome_execute_shell (g_get_home_dir(), command); + gnome_vfs_mime_application_free (app); + g_free (command); + } + else return NS_ERROR_FAILURE; + } + return NS_OK; +} + +/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */ +NS_IMETHODIMP GPrintListener::OnProgressChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRInt32 aCurSelfProgress, + PRInt32 aMaxSelfProgress, + PRInt32 aCurTotalProgress, + PRInt32 aMaxTotalProgress) +{ + return NS_OK; +} + +/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ +NS_IMETHODIMP GPrintListener::OnLocationChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsIURI *location) +{ + return NS_OK; +} + +/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ +NS_IMETHODIMP GPrintListener::OnStatusChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + nsresult aStatus, + const PRUnichar *aMessage) +{ + return NS_OK; +} + +/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */ +NS_IMETHODIMP GPrintListener::OnSecurityChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 state) +{ + return NS_OK; +} + + diff --git a/embed/mozilla/PrintProgressListener.h b/embed/mozilla/PrintProgressListener.h new file mode 100644 index 000000000..82577d8ea --- /dev/null +++ b/embed/mozilla/PrintProgressListener.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2002 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PrintProgressListener_h_ +#define __PrintProgressListener_h_ + +#include "nsIWebProgressListener.h" + +class GPrintListener : public nsIWebProgressListener +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIWEBPROGRESSLISTENER + + GPrintListener(); + GPrintListener(char *filename); + virtual ~GPrintListener(); + +private: + char *mFilename; +}; + +#endif //__PrintProgressListener_h_ diff --git a/embed/mozilla/PrintingPromptService.cpp b/embed/mozilla/PrintingPromptService.cpp new file mode 100644 index 000000000..6d1430ddc --- /dev/null +++ b/embed/mozilla/PrintingPromptService.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2002 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtk/gtkdialog.h> + +#include "print-dialog.h" +#include "ephy-embed.h" +#include "MozillaPrivate.h" + +#include <nsIPrintSettings.h> +#include <nsCOMPtr.h> +#include <nsIFactory.h> +#include <nsString.h> +#include <nsIServiceManager.h> +#include <nsXPComFactory.h> + +#include <nsIPrintingPromptService.h> + +/* Header file */ +class GPrintingPromptService : public nsIPrintingPromptService +{ +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPRINTINGPROMPTSERVICE + + GPrintingPromptService(); + virtual ~GPrintingPromptService(); + /* additional members */ +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS1(GPrintingPromptService, nsIPrintingPromptService) + +GPrintingPromptService::GPrintingPromptService() +{ + NS_INIT_ISUPPORTS(); + /* member initializers and constructor code */ +} + +GPrintingPromptService::~GPrintingPromptService() +{ + /* destructor code */ +} + +/* void showPrintDialog (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings); */ +NS_IMETHODIMP GPrintingPromptService::ShowPrintDialog(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings) +{ + EphyDialog *dialog; + EmbedPrintInfo *info; + + GtkWidget *gtkParent = MozillaFindGtkParent(parent); + + dialog = print_dialog_new_with_parent (gtkParent, NULL, &info); + ephy_dialog_set_modal (dialog, TRUE); + + gint ret = ephy_dialog_run (dialog); + if(ret == GTK_RESPONSE_OK) + { + MozillaCollatePrintSettings(info, printSettings); + print_free_info(info); + + return NS_OK; + } + else + return NS_ERROR_FAILURE; +} + +/* void showProgress (in nsIDOMWindow parent, in nsIWebBrowserPrint webBrowserPrint, in nsIPrintSettings printSettings, in nsIObserver openDialogObserver, in boolean isForPrinting, out nsIWebProgressListener webProgressListener, out nsIPrintProgressParams printProgressParams, out boolean notifyOnOpen); */ +NS_IMETHODIMP GPrintingPromptService::ShowProgress(nsIDOMWindow *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings, nsIObserver *openDialogObserver, PRBool isForPrinting, nsIWebProgressListener **webProgressListener, nsIPrintProgressParams **printProgressParams, PRBool *notifyOnOpen) +{ + printf("GPrintingPromptService::ShowProgress called\n"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void showPageSetup (in nsIDOMWindow parent, in nsIPrintSettings printSettings, in nsIObserver printObserver); */ +NS_IMETHODIMP GPrintingPromptService::ShowPageSetup(nsIDOMWindow *parent, nsIPrintSettings *printSettings, + nsIObserver *printObserver) +{ + printf("GPrintingPromptService::ShowPageSetup called\n"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void showPrinterProperties (in nsIDOMWindow parent, in wstring printerName, in nsIPrintSettings printSettings); */ +NS_IMETHODIMP GPrintingPromptService::ShowPrinterProperties(nsIDOMWindow *parent, const PRUnichar *printerName, nsIPrintSettings *printSettings) +{ + printf("GPrintingPromptService::ShowPrinterProperties called\n"); + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_DEF_FACTORY (GPrintingPromptService, GPrintingPromptService); + +/** + * NS_NewPromptServiceFactory: + */ +nsresult NS_NewPrintingPromptServiceFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGPrintingPromptServiceFactory *result = new nsGPrintingPromptServiceFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/PrintingPromptService.h b/embed/mozilla/PrintingPromptService.h new file mode 100644 index 000000000..08024c632 --- /dev/null +++ b/embed/mozilla/PrintingPromptService.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PrintingPromptService_h +#define __PrintingPromptService_h + +#include "nsError.h" + +#define G_PRINTINGPROMPTSERVICE_CID \ +{ /* 5998a2d3-88ea-4c52-b4bb-4e7abd0d35e0 */ \ + 0x5998a2d3, \ + 0x88ea, \ + 0x4c52, \ + {0xb4, 0xbb, 0x4e, 0x7a, 0xbd, 0x0d, 0x35, 0xe0} \ +} + +#define G_PRINTINGPROMPTSERVICE_CLASSNAME "Galeon's Printing Prompt Service" +#define G_PRINTINGPROMPTSERVICE_CONTRACTID "@mozilla.org/embedcomp/printingprompt-service;1" +class nsIFactory; + +extern nsresult NS_NewPrintingPromptServiceFactory(nsIFactory** aFactory); + +#endif diff --git a/embed/mozilla/ProgressListener.cpp b/embed/mozilla/ProgressListener.cpp new file mode 100644 index 000000000..aed42d97a --- /dev/null +++ b/embed/mozilla/ProgressListener.cpp @@ -0,0 +1,718 @@ +/* + * Copyright (C) 2001 Philip Langdale, Matthew Aubury + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "ProgressListener.h" + +#include "eel-gconf-extensions.h" +#include "ephy-file-helpers.h" + +#include <unistd.h> +#include <libgnome/gnome-exec.h> +#include <libgnome/gnome-i18n.h> + +#include "nsXPIDLString.h" +#include "nsIChannel.h" +#include "nsIFTPChannel.h" +#include "nsIFactory.h" +#include "nsXPComFactory.h" +#include "nsIMIMEInfo.h" +#include "nsCOMPtr.h" + +static void +download_remove_cb (DownloaderView *dv, GProgressListener *Progress); +static void +download_resume_cb (DownloaderView *dv, GProgressListener *Progress); +static void +download_pause_cb (DownloaderView *dv, GProgressListener *Progress); + +NS_IMPL_ISUPPORTS4 (GProgressListener, nsIDownload, nsIWebProgressListener, + nsIProgressDialog, nsISupportsWeakReference) + +//--------------------------------------------------------------------------- + +//--------------------------------------------------------------------------- + +GProgressListener::GProgressListener () : mLauncher(nsnull), + mPersist(nsnull), + mHandler(nsnull), + mObserver(nsnull), + mMIMEInfo(nsnull), + mPercentComplete(0) +{ + NS_INIT_ISUPPORTS (); +} + +GProgressListener::~GProgressListener () +{ + /* destructor code */ +} + +NS_METHOD GProgressListener::InitForPersist (nsIWebBrowserPersist *aPersist, + nsIDOMWindow *aParent, + nsIURI *aURI, + nsIFile *aFile, + DownloadAction aAction, + EphyEmbedPersist *ephyPersist, + PRBool noDialog, + PRInt64 aTimeDownloadStarted) +{ + nsresult rv; + + /* fill in download details */ + mAction = aAction; + mParent = aParent; + mNoDialog = noDialog; + mUri = aURI; + mFile = aFile; + mPersist = aPersist; + mTimeDownloadStarted = aTimeDownloadStarted; + mEphyPersist = ephyPersist; + + /* do remaining init */ + rv = PrivateInit (); + + /* pick up progress messages */ + mPersist->SetProgressListener (this); + + /* done */ + return rv; +} + +NS_METHOD GProgressListener::InitForDownload (nsIHelperAppLauncher *aLauncher, + nsISupports *aContext, + GContentHandler *aHandler, + DownloadAction aAction) +{ + nsresult rv; + + mNoDialog = 0; + + /* fill in download details */ + mAction = aAction; + mParent = do_QueryInterface (aContext); + mNoDialog = PR_TRUE; + mHandler = aHandler; + mLauncher = aLauncher; + rv = mLauncher->GetDownloadInfo (getter_AddRefs (mUri), + &mTimeDownloadStarted, + getter_AddRefs (mFile)); + + /* do remaining init */ + rv = PrivateInit (); + + /* pick up progress messages */ + mLauncher->SetWebProgressListener (this); + + /* done */ + return rv; +} + +NS_METHOD GProgressListener::PrivateInit (void) +{ + nsresult rv; + + /* setup this download */ + mInterval = 500000; /* in microsecs == 500ms == 0.5s */ + mPriorKRate = 0; + mRateChanges = 0; + mRateChangeLimit = 2; /* only update rate every second */ + mCheckedCanPause = PR_FALSE; + mCanPause = PR_FALSE; + mIsPaused = PR_FALSE; + mAbort = PR_FALSE; + PRInt64 now = PR_Now (); + mLastUpdate = now; + +// mStartTime = (mTimeDownloadStarted != 0 ? +// mTimeDownloadStarted : now); + mStartTime = now; //Stupid mozilla race condition + + mElapsed = now - mStartTime; + + if (!mNoDialog) + { + gchar *filename, *source, *dest; + nsAutoString uTmp; + nsCAutoString cTmp; + + rv = mFile->GetLeafName (uTmp); + filename = g_strdup (NS_ConvertUCS2toUTF8(uTmp).get()); + + rv = mFile->GetPath (uTmp); + dest = g_strdup (NS_ConvertUCS2toUTF8(uTmp).get()); + + rv = mUri->GetSpec (cTmp); + source = g_strdup (cTmp.get()); + DownloaderView *dv; + dv = ephy_embed_shell_get_downloader_view (embed_shell); + downloader_view_add_download (dv, filename, source, dest, (gpointer)this); + g_signal_connect (G_OBJECT (dv), + "download_remove", + G_CALLBACK (download_remove_cb), + this); + g_signal_connect (G_OBJECT (dv), + "download_pause", + G_CALLBACK (download_pause_cb), + this); + g_signal_connect (G_OBJECT (dv), + "download_resume", + G_CALLBACK (download_resume_cb), + this); + mDownloaderView = dv; + } + + /* done */ + return NS_OK; +} + +NS_IMETHODIMP GProgressListener::Init(nsIURI *aSource, + nsILocalFile *aTarget, + const PRUnichar *aDisplayName, + nsIMIMEInfo *aMIMEInfo, + PRInt64 aStartTime, + nsIWebBrowserPersist *aPersist) +{ + mUri = aSource; + mFile = aTarget; + mTimeDownloadStarted = aStartTime; + mStartTime = aStartTime; + mPersist = aPersist; + mMIMEInfo = aMIMEInfo; + mAction = ACTION_NONE; + if(mMIMEInfo) + { + nsMIMEInfoHandleAction mimeAction; + if(NS_SUCCEEDED(mMIMEInfo->GetPreferredAction(&mimeAction))) + { + mAction = (mimeAction == nsIMIMEInfo::useHelperApp) ? + ACTION_SAVEFORHELPER : ACTION_NONE; + } + } + mNoDialog = 0; + + return PrivateInit(); +} + +NS_IMETHODIMP GProgressListener::Open(nsIDOMWindow *aParent) +{ + mParent = aParent; + mNoDialog = 0; + + return NS_OK; +} + +/* attribute long long startTime; */ +NS_IMETHODIMP GProgressListener::GetStartTime(PRInt64 *aStartTime) +{ + *aStartTime = mStartTime; + return NS_OK; +} + +/* attribute nsIURI source; */ +NS_IMETHODIMP GProgressListener::GetSource(nsIURI * *aSource) +{ + NS_IF_ADDREF(*aSource = mUri); + return NS_OK; +} + +/* attribute nsILocalFile target; */ +NS_IMETHODIMP GProgressListener::GetTarget(nsILocalFile * *aTarget) +{ + nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(mFile); + NS_IF_ADDREF(*aTarget = localFile); + return NS_OK; +} + +NS_IMETHODIMP GProgressListener::GetMIMEInfo(nsIMIMEInfo * *aMIMEInfo) +{ + NS_IF_ADDREF(*aMIMEInfo = mMIMEInfo); + return NS_OK; +} + +/* attribute nsIObserver observer; */ +NS_IMETHODIMP GProgressListener::GetObserver(nsIObserver * *aObserver) +{ + NS_IF_ADDREF(*aObserver = mObserver); + return NS_OK; +} +NS_IMETHODIMP GProgressListener::SetObserver(nsIObserver * aObserver) +{ + mObserver = aObserver; + return NS_OK; +} + +/* attribute nsIWebProgressListener listener; */ +NS_IMETHODIMP GProgressListener::GetListener(nsIWebProgressListener * *aListener) +{ + *aListener = nsnull; + return NS_OK; +} +NS_IMETHODIMP GProgressListener::SetListener(nsIWebProgressListener * aListener) +{ + return NS_OK; +} + +/* readonly attribute PRInt32 percentComplete; */ +NS_IMETHODIMP GProgressListener::GetPercentComplete(PRInt32 *aPercentComplete) +{ + return *aPercentComplete = mPercentComplete; +} + +/* attribute wstring displayName; */ +NS_IMETHODIMP GProgressListener::GetDisplayName(PRUnichar * *aDisplayName) +{ + *aDisplayName = nsnull; + return NS_OK; +} +NS_IMETHODIMP GProgressListener::SetDisplayName(const PRUnichar * aDisplayName) +{ + return NS_OK; +} + +NS_IMETHODIMP GProgressListener::GetPersist(nsIWebBrowserPersist * *aPersist) +{ + NS_IF_ADDREF(*aPersist = mPersist); + return NS_OK; +} + +NS_IMETHODIMP GProgressListener::SetDialog(nsIDOMWindow *aDialog) +{ + return NS_OK; +} + +NS_IMETHODIMP GProgressListener::GetDialog(nsIDOMWindow * *aDialog) +{ + *aDialog = nsnull; + return NS_OK; +} + +/* attribute PRBool cancelDownloadOnClose; */ +NS_IMETHODIMP GProgressListener::GetCancelDownloadOnClose(PRBool *aCancelDownloadOnClose) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP GProgressListener::SetCancelDownloadOnClose(PRBool aCancelDownloadOnClose) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP GProgressListener::LaunchHandler (PersistHandlerInfo *handler) +{ + nsresult rv; + nsCOMPtr<nsIExternalHelperAppService> helperService = + do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID); + + nsCOMPtr<nsPIExternalAppLauncher> appLauncher = + do_QueryInterface (helperService, &rv); + if (NS_SUCCEEDED(rv)) + { + appLauncher->DeleteTemporaryFileOnExit(mFile); + } + + nsAutoString uFileName; + + mFile->GetPath(uFileName); + const nsACString &cFileName = NS_ConvertUCS2toUTF8(uFileName); + + char *fname = g_strdup(PromiseFlatCString(cFileName).get()); + ephy_file_launch_application (handler->command, + fname, + handler->need_terminal); + g_free (fname); + + return NS_OK; +} + +/* + * void onStateChange (in nsIWebProgress aWebProgress, + * in nsIRequest aRequest, + * in long aStateFlags, + * in unsigned long aStatus); + */ +NS_IMETHODIMP GProgressListener::OnStateChange (nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 aStateFlags, + PRUint32 aStatus) +{ + if (mAbort) return NS_ERROR_FAILURE; + + if (aStateFlags & nsIWebProgressListener::STATE_STOP) + { + switch (mAction) + { + case ACTION_SAVEFORHELPER: + LaunchHelperApp(); + break; + + case ACTION_NONE: + if (mLauncher) + { + mLauncher->CloseProgressWindow (); + } + break; + case ACTION_OBJECT_NOTIFY: + + g_return_val_if_fail (IS_EPHY_EMBED_PERSIST (mEphyPersist), + NS_ERROR_FAILURE); + + PersistHandlerInfo *handler; + + g_object_get (mEphyPersist, + "handler", &handler, + NULL); + + if (handler) + { + LaunchHandler (handler); + } + + g_signal_emit_by_name (mEphyPersist, "completed"); + } + + if (!mNoDialog) + { + downloader_view_set_download_status (mDownloaderView, + DOWNLOAD_STATUS_COMPLETED, + (gpointer)this); + } + } + + /* done */ + return NS_OK; +} + +/* + * void onProgressChange (in nsIWebProgress aWebProgress, + * in nsIRequest aRequest, + * in long aCurSelfProgress, + * in long aMaxSelfProgress, + * in long aCurTotalProgress, + * in long aMaxTotalProgress); + */ +NS_IMETHODIMP GProgressListener:: + OnProgressChange (nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRInt32 aCurSelfProgress, + PRInt32 aMaxSelfProgress, + PRInt32 aCurTotalProgress, + PRInt32 aMaxTotalProgress) +{ + if (mAbort) return NS_ERROR_FAILURE; + + /* FIXME maxsize check here */ + + if (mNoDialog) return NS_OK; + + if (!mCheckedCanPause) + { + mCheckedCanPause = PR_TRUE; + + nsresult rv; + nsCOMPtr<nsIFTPChannel> channel = + do_QueryInterface (aRequest, &rv); + + mCanPause = (NS_SUCCEEDED (rv) ? PR_TRUE : PR_FALSE); + } + mRequest = aRequest; + + PRInt64 now = PR_Now (); + + /* get out if we're updating too quickly */ + if ((now - mLastUpdate < mInterval) && + (aMaxTotalProgress != -1) && + (aCurTotalProgress < aMaxTotalProgress)) + { + return NS_OK; + } + + /* compute elapsed time */ + mLastUpdate = now; + mElapsed = now - mStartTime; + + /* compute size done */ + PRInt32 currentKBytes = (PRInt32)(aCurTotalProgress / 1024.0 + 0.5); + + /* compute total size */ + PRInt32 totalKBytes = (PRInt32)(aMaxTotalProgress / 1024.0 + 0.5); + + /* compute progress value */ + gfloat progress = -1; + if (aMaxTotalProgress > 0) + { + progress = (gfloat)aCurTotalProgress / + (gfloat)aMaxTotalProgress; + } + + /* compute download rate */ + gfloat speed = -1; + PRInt64 currentRate; + if (mElapsed) + { + currentRate = ((PRInt64)(aCurTotalProgress)) * 1000000 / + mElapsed; + } + else + { + currentRate = 0; + } + + if (!mIsPaused) + { + if (currentRate) + { + PRFloat64 currentKRate = ((PRFloat64)currentRate)/1024; + if (currentKRate != mPriorKRate) + { + if (mRateChanges++ == mRateChangeLimit) + { + mPriorKRate = currentKRate; + mRateChanges = 0; + } + else + { + currentKRate = mPriorKRate; + } + } + else + { + mRateChanges = 0; + } + + speed = currentKRate; + } + } + + /* compute time remaining */ + gint remaining = -1; + if (currentRate && (aMaxTotalProgress > 0)) + { + remaining = + (gint)((aMaxTotalProgress - aCurTotalProgress) + /currentRate +.5); + } + + downloader_view_set_download_progress (mDownloaderView, + mElapsed, + remaining, + speed, + totalKBytes, + currentKBytes, + progress, + mCanPause, + (gpointer)this); + + /* done */ + return NS_OK; +} + +/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location); */ +NS_IMETHODIMP GProgressListener:: + OnLocationChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, nsIURI *location) +{ + return NS_OK; +} + +/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */ +NS_IMETHODIMP GProgressListener:: + OnStatusChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, nsresult aStatus, + const PRUnichar *aMessage) +{ + return NS_OK; +} + +/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long state); */ +NS_IMETHODIMP GProgressListener:: + OnSecurityChange(nsIWebProgress *aWebProgress, + nsIRequest *aRequest, + PRUint32 state) +{ + return NS_OK; +} + +//--------------------------------------------------------------------------- + +NS_METHOD GProgressListener::LaunchHelperApp (void) +{ + if (!mMIMEInfo) + return NS_ERROR_FAILURE; + + nsresult rv; + + nsCOMPtr<nsIFile> helperFile; + rv = mMIMEInfo->GetPreferredApplicationHandler(getter_AddRefs(helperFile)); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCAutoString helperFileName; + rv = helperFile->GetNativePath(helperFileName); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsMIMEInfoHandleAction mimeAction; + rv = mMIMEInfo->GetPreferredAction(&mimeAction); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsCOMPtr<nsIExternalHelperAppService> helperService = + do_GetService (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr<nsPIExternalAppLauncher> appLauncher = + do_QueryInterface (helperService, &rv); + if (NS_SUCCEEDED(rv)) + { + appLauncher->DeleteTemporaryFileOnExit(mFile); + } + } + + nsCAutoString cFileName; + mFile->GetNativePath(cFileName); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + nsXPIDLString helperDesc; + rv = mMIMEInfo->GetApplicationDescription(getter_Copies(helperDesc)); + if(NS_FAILED(rv)) return NS_ERROR_FAILURE; + + gboolean terminalHelper = + helperDesc.Equals(NS_LITERAL_STRING("runInTerminal")) ? + TRUE : FALSE; + + ephy_file_launch_application (helperFileName.get(), + cFileName.get(), + terminalHelper); + + return NS_OK; +} + +nsresult GProgressListener::Pause (void) +{ + nsresult rv; + + if (mCanPause && !mIsPaused) + { + rv = mRequest->Suspend (); + if (NS_SUCCEEDED (rv)) + { + mIsPaused = PR_TRUE; + } + } + else + { + rv = NS_ERROR_FAILURE; + } + + return rv; +} + +nsresult GProgressListener::Resume (void) +{ + nsresult rv; + + if (mCanPause && mIsPaused) + { + rv = mRequest->Resume (); + if (NS_SUCCEEDED (rv)) + { + mIsPaused = PR_FALSE; + } + } + else + { + rv = NS_ERROR_FAILURE; + } + + return rv; +} + +nsresult GProgressListener::Abort (void) +{ + mAction = ACTION_NONE; + + if (mIsPaused) + { + Resume (); + } + + mAbort = PR_TRUE; + + if (mObserver) + { + mObserver->Observe(NS_ISUPPORTS_CAST(nsIProgressDialog*, this), + "oncancel", nsnull); + OnStateChange(nsnull, nsnull, + nsIWebProgressListener::STATE_STOP, 0); + } + + if (mPersist) + { + return mPersist->CancelSave (); + } + + if (mLauncher) + { + return mLauncher->Cancel (); + } + else + { + return NS_ERROR_FAILURE; + } +} + +NS_DEF_FACTORY (GProgressListener, GProgressListener); + +/** + * NS_NewProgressListenerFactory: + */ +nsresult NS_NewProgressListenerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGProgressListenerFactory *result = new nsGProgressListenerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} + +static void +download_remove_cb (DownloaderView *dv, GProgressListener *Progress) +{ + Progress->Abort(); +} + +static void +download_resume_cb (DownloaderView *dv, GProgressListener *Progress) +{ + Progress->Resume(); +} + +static void +download_pause_cb (DownloaderView *dv, GProgressListener *Progress) +{ + Progress->Pause(); +} diff --git a/embed/mozilla/ProgressListener.h b/embed/mozilla/ProgressListener.h new file mode 100644 index 000000000..459643194 --- /dev/null +++ b/embed/mozilla/ProgressListener.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2001 Philip Langdale, Matthew Aubury + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PROGRESSLISTENER2_H__ +#define PROGRESSLISTENER2_H__ + +#include "downloader-view.h" +#include "ephy-embed-persist.h" +#include "ephy-embed-shell.h" + +#include <gtk/gtkwidget.h> +#include "nsIWebProgressListener.h" +#include "nsIHelperAppLauncherDialog.h" +#include "nsIExternalHelperAppService.h" +#include "nsCExternalHandlerService.h" +#include "nsIWebBrowserPersist.h" +#include "nsCOMPtr.h" +#include "nsWeakReference.h" +#include "nsIURI.h" +#include "nsILocalFile.h" +#include "nsIDOMWindow.h" +#include "nsIRequest.h" +#include "nsIMIMEInfo.h" +#include "nsIDownload.h" +#include "nsIObserver.h" +#include "nsIProgressDialog.h" + +#include "ContentHandler.h" + +#define G_PROGRESSDIALOG_CID \ +{ /* d2a2f743-f126-4f1f-1234-d4e50490f112 */ \ + 0xd2a2f743, \ + 0xf126, \ + 0x4f1f, \ + {0x12, 0x34, 0xd4, 0xe5, 0x04, 0x90, 0xf1, 0x12} \ +} + +#define G_PROGRESSDIALOG_CLASSNAME "Ephy's Download Progress Dialog" +#define G_PROGRESSDIALOG_CONTRACTID "@mozilla.org/progressdialog;1" + +class GProgressListener : public nsIProgressDialog, + public nsIWebProgressListener, + public nsSupportsWeakReference +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIWEBPROGRESSLISTENER + NS_DECL_NSIPROGRESSDIALOG + NS_DECL_NSIDOWNLOAD + + GProgressListener (); + virtual ~GProgressListener (); + + NS_METHOD InitForPersist (nsIWebBrowserPersist *aPersist, + nsIDOMWindow *aParent, nsIURI *aURI, + nsIFile *aFile, + DownloadAction aAction, + EphyEmbedPersist *ephyPersist, + PRBool noDialog, + PRInt64 aTimeDownloadStarted = 0); + NS_METHOD InitForDownload (nsIHelperAppLauncher *aLauncher, + nsISupports *aContext, + GContentHandler *aHandler, + DownloadAction aDownload); + + nsresult Pause (void); + nsresult Resume (void); + nsresult Abort (void); + + GTimer *mTimer; + + private: + NS_METHOD PrivateInit (void); + NS_METHOD LaunchHelperApp (void); + + NS_METHOD LaunchHandler (PersistHandlerInfo *handler); + + nsCOMPtr<nsIHelperAppLauncher> mLauncher; + nsCOMPtr<nsIWebBrowserPersist> mPersist; + nsCOMPtr<GContentHandler> mHandler; + nsCOMPtr<nsIDOMWindow> mParent; + nsCOMPtr<nsIRequest> mRequest; + + EphyEmbedPersist *mEphyPersist; + + nsCOMPtr<nsIURI> mUri; + PRInt64 mTimeDownloadStarted; + nsCOMPtr<nsIFile> mFile; + + PRInt64 mStartTime; + PRInt64 mElapsed; + + PRInt64 mLastUpdate; + PRInt32 mInterval; + + PRFloat64 mPriorKRate; + PRInt32 mRateChanges; + PRInt32 mRateChangeLimit; + + PRBool mCheckedCanPause; + PRBool mCanPause; + PRBool mIsPaused; + gboolean mNoDialog; + PRBool mAbort; + + DownloadAction mAction; + + DownloaderView *mDownloaderView; + + EphyEmbedShell *ephy_shell; + + guint mTimeoutFunc; + + nsCOMPtr<nsIObserver> mObserver; + + nsCOMPtr<nsIMIMEInfo> mMIMEInfo; + + PRInt32 mPercentComplete; +}; + +extern nsresult NS_NewProgressListenerFactory(nsIFactory** aFactory); + +#endif // PROGRESSLISTENER2_H__ + diff --git a/embed/mozilla/PromptService.cpp b/embed/mozilla/PromptService.cpp new file mode 100644 index 000000000..c9244dd32 --- /dev/null +++ b/embed/mozilla/PromptService.cpp @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-glade.h" +#include "PromptService.h" + +#include "nsCOMPtr.h" +#include "nsIFactory.h" +#include "nsString.h" +#include "nsReadableUtils.h" +#include "nsIServiceManager.h" +#include "nsXPComFactory.h" +#include "MozillaPrivate.h" + +#include "nsIPromptService.h" +#include "nsIUnicodeEncoder.h" + +#include <gtk/gtkentry.h> +#include <gtk/gtktogglebutton.h> +#include <gtk/gtklist.h> +#include <libgnomeui/gnome-dialog.h> +#include <libgnome/gnome-i18n.h> +#include <libgnome/gnome-triggers.h> + +/* local function prototypes */ +static void set_title (GtkWidget *dialog, const PRUnichar *title); +static void set_label_text (GtkWidget *label, const PRUnichar *text); +static void set_check_button_text (GtkWidget *check_button, + const PRUnichar *text); +static void set_check_button (GtkWidget *button, PRBool *value); +static void set_check_button_size_to_label (GtkWidget *check_button, + GtkWidget *label); +static void set_editable (GtkWidget *entry, PRUnichar **text); +static void get_check_button (GtkWidget *button, PRBool *value); +static void get_editable (GtkWidget *editable, PRUnichar **text); + +/** + * class CPromptService: an GNOME implementation of prompt dialogs for + * Mozilla + */ +class CPromptService: public nsIPromptService +{ + public: + CPromptService(); + virtual ~CPromptService(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIPROMPTSERVICE + private: + nsresult AddButton (GtkWidget *dialog, + char type, + const PRUnichar *title, + int id); +}; + +NS_IMPL_ISUPPORTS1 (CPromptService, nsIPromptService) + +/** + * CPromptService::CPromptService: constructor + */ +CPromptService::CPromptService () +{ + NS_INIT_ISUPPORTS(); +} + +/** + * CPromptService::~CPromptService: destructor + */ +CPromptService::~CPromptService () +{ +} + +/** + * CPromptService::Alert: show an alert box + */ +NS_IMETHODIMP CPromptService::Alert (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text) +{ + GtkWidget *dialog; + GtkWidget *gparent; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "%s", + PromiseFlatCString(msg).get ()); + set_title (dialog, dialogTitle); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::AlertCheck: show an alert box with a checkbutton, + * (typically for things like "dont show this warning again") + */ +NS_IMETHODIMP CPromptService::AlertCheck (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + const PRUnichar *checkMsg, + PRBool *checkValue) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_WARNING, + GTK_BUTTONS_OK, + "%s", + PromiseFlatCString(msg).get ()); + + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + + set_title (dialog, dialogTitle); + + gtk_dialog_run (GTK_DIALOG (dialog)); + get_check_button (check_button, checkValue); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::Confirm: for simple yes/no dialogs + */ +NS_IMETHODIMP CPromptService::Confirm (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + int res; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "%s", PromiseFlatCString(msg).get ()); + set_title (dialog, dialogTitle); + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + *_retval = (res == GTK_RESPONSE_YES); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +/** + * CPromptService::Confirm: for simple yes/no dialogs, with an additional + * check button + */ +NS_IMETHODIMP CPromptService::ConfirmCheck (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button; + int res; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_YES_NO, + "%s", PromiseFlatCString(msg).get ()); + + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + + set_title (dialog, dialogTitle); + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + *_retval = (res == GTK_RESPONSE_YES); + get_check_button (check_button, checkValue); + gtk_widget_destroy (dialog); + + return NS_OK; +} + +NS_IMETHODIMP CPromptService::AddButton (GtkWidget *dialog, + char type, + const PRUnichar *title, + int id) +{ + const char *btitle; + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (title); + + g_print ("%d", type); + + switch (type) + { + case BUTTON_TITLE_OK: + btitle = GTK_STOCK_OK; + break; + case BUTTON_TITLE_CANCEL: + btitle = GTK_STOCK_CANCEL; + break; + case BUTTON_TITLE_YES: + btitle = GTK_STOCK_YES; + break; + case BUTTON_TITLE_NO: + btitle = GTK_STOCK_NO; + break; + case BUTTON_TITLE_SAVE: + btitle = _("Save"); + break; + case BUTTON_TITLE_REVERT: + btitle = _("Revert"); + break; + case BUTTON_TITLE_DONT_SAVE: + btitle = _("Don't save"); + break; + case BUTTON_TITLE_IS_STRING: + btitle = NULL; + break; + + default: + return NS_ERROR_FAILURE; + } + + gtk_dialog_add_button (GTK_DIALOG(dialog), + btitle ? btitle : + PromiseFlatCString(utf8string).get(), + id); + + return NS_OK; +} + +/** + * CPromptService::ConfirmEx: For fancy confirmation dialogs + */ +NS_IMETHODIMP CPromptService::ConfirmEx (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUint32 buttonFlags, + const PRUnichar *button0Title, + const PRUnichar *button1Title, + const PRUnichar *button2Title, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRInt32 *buttonPressed) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *check_button = NULL; + int ret; + + gparent = MozillaFindGtkParent (parent); + const nsACString &msg = NS_ConvertUCS2toUTF8 (text); + dialog = gtk_message_dialog_new (GTK_WINDOW(gparent), + GTK_DIALOG_MODAL, + GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, + "%s", PromiseFlatCString(msg).get ()); + + set_title (dialog, dialogTitle); + + if (checkMsg) + { + check_button = gtk_check_button_new_with_label (""); + gtk_widget_show (check_button); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG(dialog)->vbox), + check_button, FALSE, FALSE, 5); + + set_check_button_text (check_button, checkMsg); + set_check_button (check_button, checkValue); + } + + AddButton (dialog, (buttonFlags >> 16) & 0xFF, + button2Title, 2); + AddButton (dialog, (buttonFlags >> 8) & 0xFF, + button1Title, 1); + AddButton (dialog, buttonFlags & 0xFF, + button0Title, 0); + + gtk_dialog_set_default_response (GTK_DIALOG(dialog), 0); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "generic", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + if (checkMsg) + { + get_check_button (check_button, checkValue); + } + + *buttonPressed = ret; + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::Prompt: show a prompt for text, with a checkbutton + */ +NS_IMETHODIMP CPromptService::Prompt (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **value, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *entry; + GtkWidget *label; + GtkWidget *check_button; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_dialog", + &dialog, NULL); + entry = glade_xml_get_widget (gxml, "entry"); + label = glade_xml_get_widget (gxml, "label"); + check_button = glade_xml_get_widget (gxml, "check_button"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_label_text (label, text); + set_check_button_text (check_button, checkMsg); + set_editable (entry, value); + set_check_button (check_button, checkValue); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + /* NB: should be question, but this is missing in many + * of the current gnome sound packages that I've tried... */ + gnome_triggers_vdo ("", "generic", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (entry, value); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::PromptUsernameAndPassword: show a prompt for username + * and password with an additional check button. + */ +NS_IMETHODIMP CPromptService::PromptUsernameAndPassword + (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **username, + PRUnichar **password, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *check_button; + GtkWidget *label; + GtkWidget *username_entry; + GtkWidget *password_entry; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_user_pass_dialog", + &dialog, NULL); + check_button = glade_xml_get_widget (gxml, "check_button"); + label = glade_xml_get_widget (gxml, "label"); + username_entry = glade_xml_get_widget (gxml, "username_entry"); + password_entry = glade_xml_get_widget (gxml, "password_entry"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_check_button_text (check_button, checkMsg); + set_editable (username_entry, username); + set_editable (password_entry, password); + set_check_button (check_button, checkValue); + set_label_text (label, text); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (username_entry, username); + get_editable (password_entry, password); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + +/** + * CPromptService::PromptPassword: show a prompt for just + * a password with an additional check button. + */ +NS_IMETHODIMP CPromptService::PromptPassword (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, + PRUnichar **password, + const PRUnichar *checkMsg, + PRBool *checkValue, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *label; + GtkWidget *check_button; + GtkWidget *password_entry; + GtkWidget *gparent; + GladeXML *gxml; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "prompt_pass_dialog", + &dialog, NULL); + check_button = glade_xml_get_widget (gxml, "check_button"); + label = glade_xml_get_widget (gxml, "label"); + password_entry = glade_xml_get_widget (gxml, "password_entry"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_check_button_text (check_button, checkMsg); + set_editable (password_entry, password); + set_check_button (check_button, checkValue); + set_label_text (label, text); + set_check_button_size_to_label (check_button, label); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + get_check_button (check_button, checkValue); + get_editable (password_entry, password); + *_retval = (ret == GTK_RESPONSE_OK); + + /* done */ + gtk_widget_destroy (dialog); + return NS_OK; +} + + +/** + * CPromptService::Select: + */ +NS_IMETHODIMP CPromptService::Select (nsIDOMWindow *parent, + const PRUnichar *dialogTitle, + const PRUnichar *text, PRUint32 count, + const PRUnichar **selectList, + PRInt32 *outSelection, + PRBool *_retval) +{ + GtkWidget *dialog; + GtkWidget *gparent; + GtkWidget *label; + GladeXML *gxml; + GtkWidget *treeview; + gint ret; + + /* build and show the dialog */ + gxml = ephy_glade_widget_new ("prompts.glade", "select_dialog", + &dialog, NULL); + treeview = glade_xml_get_widget (gxml, "treeview"); + label = glade_xml_get_widget (gxml, "label"); + g_object_unref (G_OBJECT (gxml)); + + /* parent the dialog */ + gparent = MozillaFindGtkParent (parent); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (gparent)); + + /* set dynamic attributes */ + set_title (dialog, dialogTitle); + set_label_text (label, text); + + /* setup treeview */ + GtkCellRenderer *renderer; + GtkListStore *liststore; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + + gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview), TRUE); + + liststore = gtk_list_store_new (2, + G_TYPE_STRING, + G_TYPE_INT); + + model = GTK_TREE_MODEL (liststore); + + gtk_tree_view_set_model (GTK_TREE_VIEW(treeview), + model); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), + FALSE); + + renderer = gtk_cell_renderer_text_new (); + + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW(treeview), + 0, "Items", + renderer, + "text", 0, + NULL); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(treeview)); + + for (PRUint32 i = 0 ; i < count ; i++) + { + char *itemText = + ToNewCString(NS_ConvertUCS2toUTF8 (selectList[i])); + gtk_list_store_append (GTK_LIST_STORE (model), + &iter); + gtk_list_store_set (GTK_LIST_STORE (model), + &iter, + 0, itemText, + 1, i, + -1); + nsMemory::Free(itemText); + } + + gtk_tree_model_get_iter_first (model, &iter); + gtk_tree_selection_select_iter (selection, &iter); + + /* make a suitable sound */ + gnome_triggers_vdo ("", "question", NULL); + + /* run dialog and capture return values */ + ret = gtk_dialog_run (GTK_DIALOG (dialog)); + + /* handle return values */ + if (gtk_tree_selection_get_selected (selection, + &model, + &iter)) + { + GValue val = {0, }; + gtk_tree_model_get_value (model, &iter, 1, &val); + *outSelection = g_value_get_int (&val); + + *_retval = (ret == GTK_RESPONSE_OK) ? PR_TRUE : PR_FALSE; + } + else + { + *_retval = PR_FALSE; + } + + gtk_widget_destroy (dialog); + + return NS_OK; +} + +NS_DEF_FACTORY (CPromptService, CPromptService); + +/** + * NS_NewPromptServiceFactory: + */ +nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsCPromptServiceFactory *result = new nsCPromptServiceFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} + +/** + * set_title: set a dialog title to a unicode string + */ +static void +set_title (GtkWidget *dialog, const PRUnichar *title) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (title); + + /* set it */ + gtk_window_set_title (GTK_WINDOW (dialog), + (title == NULL ? N_("Galeon") : + PromiseFlatCString(utf8string).get())); +} + +/** + * set_label_text: set a labels text to a unicode string + */ +static void +set_label_text (GtkWidget *label, const PRUnichar *text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (text); + + /* set it */ + gtk_label_set_text (GTK_LABEL (label), + PromiseFlatCString(utf8string).get()); +} + +/** + * set_check_button_text: set a check buttons text to a unicode string + */ +static void +set_check_button_text (GtkWidget *check_button, const PRUnichar *text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (text); + + /* set it */ + gtk_label_set_text (GTK_LABEL (GTK_BIN (check_button)->child), + PromiseFlatCString(utf8string).get()); +} + +/** + * set_check_button: set a togglebutton to an initial state + */ +static void +set_check_button (GtkWidget *button, PRBool *value) +{ + /* check pointer is valid */ + if (value == NULL) + { + gtk_widget_hide (GTK_WIDGET (button)); + return; + } + + /* set the value of the check button */ + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), *value); +} + +/** + * se_check_button_size_to_label: sync text widgets sizes + */ +static void +set_check_button_size_to_label (GtkWidget *check_button, + GtkWidget *label) +{ + GtkRequisition r, label_r; + + gtk_widget_size_request (check_button, &r); + gtk_widget_size_request (label, &label_r); + + if (r.width <= label_r.width) return; + + gtk_widget_set_size_request (label, r.width, 0); +} + +/** + * set_editable: set an editable to a unicode string + */ +static void +set_editable (GtkWidget *entry, PRUnichar **text) +{ + const nsACString &utf8string = NS_ConvertUCS2toUTF8 (*text); + + /* set this string value in the widget */ + gtk_entry_set_text (GTK_ENTRY (entry), + PromiseFlatCString(utf8string).get()); +} + +/** + * get_check_button: get value of a toggle button and store it in a PRBool + */ +static void +get_check_button (GtkWidget *button, PRBool *value) +{ + /* check we can write */ + if (value == NULL) + { + return; + } + + /* set the value from the check button */ + *value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); +} + +/** + * get_editable: get a string from an editable and store it as unicode + */ +static void +get_editable (GtkWidget *editable, PRUnichar **text) +{ + char *edited; + + /* check we can write */ + if (text == NULL) + { + return; + } + + /* get the text */ + edited = gtk_editable_get_chars (GTK_EDITABLE (editable), 0, -1); + + /* decode and set it as the return value */ + *text = ToNewUnicode(NS_ConvertUTF8toUCS2(edited)); +} diff --git a/embed/mozilla/PromptService.h b/embed/mozilla/PromptService.h new file mode 100644 index 000000000..98d8d0c46 --- /dev/null +++ b/embed/mozilla/PromptService.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __PromptService_h +#define __PromptService_h + +#include "nsError.h" + +#define G_PROMPTSERVICE_CID \ +{ /* c5a77759-a07a-4025-8f74-ae89153ee6c2 */ \ + 0xc5a77759, \ + 0xa07a, \ + 0x4025, \ + {0x8f, 0x74, 0xae, 0x89, 0x15, 0x3e, 0xe6, 0xc2} \ +} + +#define G_PROMPTSERVICE_CLASSNAME "Galeon's Prompt Service" +#define G_PROMPTSERVICE_CONTRACTID "@mozilla.org/embedcomp/prompt-service;1" + +class nsIFactory; + +extern nsresult NS_NewPromptServiceFactory(nsIFactory** aFactory); + +#endif diff --git a/embed/mozilla/StartHereProtocolHandler.cpp b/embed/mozilla/StartHereProtocolHandler.cpp new file mode 100644 index 000000000..47a1af310 --- /dev/null +++ b/embed/mozilla/StartHereProtocolHandler.cpp @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2001 Matt Aubury, Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ephy-file-helpers.h" + +#include "nsCOMPtr.h" +#include "nsIFactory.h" +#include "nsIIOService.h" +#include "nsIServiceManager.h" +#include "nsIURI.h" +#include "nsNetCID.h" +#include "nsNetUtil.h" +#include "nsXPComFactory.h" + +static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID); + +class GStartHereProtocolHandler : public nsIProtocolHandler +{ + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPROTOCOLHANDLER + + GStartHereProtocolHandler (void); + virtual ~GStartHereProtocolHandler(); + + nsCOMPtr<nsIChannel> mChannel; + nsCOMPtr<nsIURI> mURI; +}; + +/* Implementation file */ +NS_IMPL_ISUPPORTS1 (GStartHereProtocolHandler, nsIProtocolHandler) + +GStartHereProtocolHandler::GStartHereProtocolHandler (void) +{ + NS_INIT_ISUPPORTS(); + +} + +GStartHereProtocolHandler::~GStartHereProtocolHandler() +{ + /* destructor code */ +} + +/* readonly attribute string scheme; */ +NS_IMETHODIMP GStartHereProtocolHandler::GetScheme(nsACString &aScheme) +{ + aScheme = NS_LITERAL_CSTRING("start-here"); + return NS_OK; +} + +/* readonly attribute long defaultPort; */ +NS_IMETHODIMP GStartHereProtocolHandler::GetDefaultPort(PRInt32 *aDefaultPort) +{ + nsresult rv = NS_OK; + if (aDefaultPort) + *aDefaultPort = -1; + else + rv = NS_ERROR_NULL_POINTER; + return rv; +} + +/* readonly attribute short protocolFlags; */ +NS_IMETHODIMP GStartHereProtocolHandler::GetProtocolFlags(PRUint32 *aProtocolFlags) +{ + if (aProtocolFlags) + *aProtocolFlags = nsIProtocolHandler::URI_STD; + else + return NS_ERROR_NULL_POINTER; + return NS_OK; +} + +/* nsIURI newURI (in string aSpec, in nsIURI aBaseURI); */ +NS_IMETHODIMP GStartHereProtocolHandler::NewURI(const nsACString &aSpec, + const char *aOriginCharset, + nsIURI *aBaseURI, + nsIURI **_retval) +{ + nsresult rv = NS_OK; + nsCOMPtr <nsIURI> newUri; + + rv = nsComponentManager::CreateInstance(kSimpleURICID, NULL, + NS_GET_IID(nsIURI), + getter_AddRefs(newUri)); + + if (NS_SUCCEEDED(rv)) + { + newUri->SetSpec(aSpec); + rv = newUri->QueryInterface(NS_GET_IID(nsIURI), + (void **) _retval); + } + return rv; +} + +/* nsIChannel newChannel (in nsIURI aURI); */ +NS_IMETHODIMP GStartHereProtocolHandler::NewChannel(nsIURI *aURI, + nsIChannel **_retval) +{ + nsresult rv; + + nsCAutoString path; + rv = aURI->GetPath(path); + if (NS_FAILED(rv)) return rv; + + char *httpSpec = g_strconcat ("file:///", + ephy_file ("start_here.html"), + NULL); + + if (!httpSpec) return NS_ERROR_OUT_OF_MEMORY; + + nsCOMPtr<nsIIOService> serv(do_GetIOService(&rv)); + if (NS_FAILED(rv)) return rv; + + // now we have an HTTP url, give the user an HTTP channel + rv = serv->NewChannel(nsDependentCString(httpSpec), nsnull, nsnull, _retval); + + return rv; +} + +/* boolean allowPort (in long port, in string scheme); */ +NS_IMETHODIMP GStartHereProtocolHandler::AllowPort(PRInt32 port, const char *scheme, + PRBool *_retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + +NS_DEF_FACTORY (GStartHereProtocolHandler, GStartHereProtocolHandler); + +/** + * NS_NewStartHereProtocolHandlerFactory: + */ +nsresult NS_NewStartHereHandlerFactory(nsIFactory** aFactory) +{ + NS_ENSURE_ARG_POINTER(aFactory); + *aFactory = nsnull; + + nsGStartHereProtocolHandlerFactory *result = new nsGStartHereProtocolHandlerFactory; + if (result == NULL) + { + return NS_ERROR_OUT_OF_MEMORY; + } + + NS_ADDREF(result); + *aFactory = result; + + return NS_OK; +} diff --git a/embed/mozilla/StartHereProtocolHandler.h b/embed/mozilla/StartHereProtocolHandler.h new file mode 100644 index 000000000..82c74774b --- /dev/null +++ b/embed/mozilla/StartHereProtocolHandler.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2001 Philip Langdale + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef StartHereProtocolHandler_h__ +#define StartHereProtocolHandler_h__ + +#include "nsError.h" + +#define G_START_HERE_PROTOCOLHANDLER_CID \ +{ /* a3a7b6e5-7a92-431d-87e6-3bef8e7ada51*/ \ + 0xa3a7b6e5, \ + 0x7a92, \ + 0x431d, \ + {0x87, 0xe6, 0x3b, 0xef, 0x8e, 0x7a, 0xda, 0x51} \ +} +#define G_START_HERE_PROTOCOLHANDLER_CONTRACTID NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "start-here" +#define G_START_HERE_PROTOCOLHANDLER_CLASSNAME "Galeon's start here protocol handler" + +class nsIFactory; + +extern nsresult NS_NewStartHereHandlerFactory(nsIFactory** aFactory); + +#endif // MyportalProtocolHandler_h__ diff --git a/embed/mozilla/mozilla-embed-persist.cpp b/embed/mozilla/mozilla-embed-persist.cpp new file mode 100644 index 000000000..abfcacd57 --- /dev/null +++ b/embed/mozilla/mozilla-embed-persist.cpp @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "ProgressListener.h" +#include "EphyWrapper.h" +#include "mozilla-embed.h" +#include "mozilla-embed-persist.h" + +#include <stddef.h> +#include <nsIWebBrowserPersist.h> +#include <nsString.h> +#include <nsCWebBrowserPersist.h> +#include <nsNetUtil.h> + +static void +mozilla_embed_persist_class_init (MozillaEmbedPersistClass *klass); +static void +mozilla_embed_persist_init (MozillaEmbedPersist *ges); +static void +mozilla_embed_persist_finalize (GObject *object); + +static gresult +impl_save (EphyEmbedPersist *persist); + +struct MozillaEmbedPersistPrivate +{ + gpointer dummy; +}; + +static GObjectClass *parent_class = NULL; + +GType +mozilla_embed_persist_get_type (void) +{ + static GType mozilla_embed_persist_type = 0; + + if (mozilla_embed_persist_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (MozillaEmbedPersistClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) mozilla_embed_persist_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (MozillaEmbedPersist), + 0, /* n_preallocs */ + (GInstanceInitFunc) mozilla_embed_persist_init + }; + + mozilla_embed_persist_type = + g_type_register_static (EPHY_EMBED_PERSIST_TYPE, + "MozillaEmbedPersist", + &our_info, (GTypeFlags)0); + } + + return mozilla_embed_persist_type; +} + +static void +mozilla_embed_persist_class_init (MozillaEmbedPersistClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + EphyEmbedPersistClass *persist_class; + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + persist_class = EPHY_EMBED_PERSIST_CLASS (klass); + + object_class->finalize = mozilla_embed_persist_finalize; + + persist_class->save = impl_save; +} + +static void +mozilla_embed_persist_init (MozillaEmbedPersist *persist) +{ + persist->priv = g_new0 (MozillaEmbedPersistPrivate, 1); +} + +static void +mozilla_embed_persist_finalize (GObject *object) +{ + MozillaEmbedPersist *persist; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MOZILLA_EMBED_PERSIST (object)); + + persist = MOZILLA_EMBED_PERSIST (object); + + g_return_if_fail (persist->priv != NULL); + + g_free (persist->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gresult +impl_save (EphyEmbedPersist *persist) +{ + nsresult rv; + nsAutoString s; + char *filename; + char *uri; + int max_size; + EphyEmbed *embed; + EmbedPersistFlags flags; + EphyWrapper *wrapper = NULL; + + g_object_get (persist, + "source", &uri, + "dest", &filename, + "flags", &flags, + "embed", &embed, + "max_size", &max_size, + NULL); + + g_return_val_if_fail (filename != NULL, G_FAILED); + + nsCOMPtr<nsIURI> linkURI; + linkURI = nsnull; + if (uri) + { + s.AssignWithConversion(uri); + rv = NS_NewURI(getter_AddRefs(linkURI), s); + if (NS_FAILED(rv) || !linkURI) return G_FAILED; + } + + nsCOMPtr<nsIWebBrowserPersist> bpersist = + do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID, &rv); + if (NS_FAILED(rv) || !persist) return G_FAILED; + + nsCOMPtr<nsILocalFile> file; + NS_NewLocalFile(NS_ConvertUTF8toUCS2(filename), PR_TRUE, getter_AddRefs(file)); + if (NS_FAILED(rv) || !file) return G_FAILED; + + nsCOMPtr<nsILocalFile> path; + if (flags & EMBED_PERSIST_SAVE_CONTENT) + { + char *datapath; + datapath = g_strconcat (filename, "content", NULL); + NS_NewLocalFile(NS_ConvertUTF8toUCS2(datapath), PR_TRUE, getter_AddRefs(path)); + g_free (datapath); + } + else + { + path = nsnull; + } + + nsCOMPtr<nsIDOMWindow> parent; + parent = nsnull; + + if (embed) + { + wrapper = (EphyWrapper *) mozilla_embed_get_galeon_wrapper (MOZILLA_EMBED(embed)); + wrapper->GetDOMWindow (getter_AddRefs (parent)); + } + + size_t len = strlen(filename); + if((filename[len-1] == 'z' && filename[len-2] == 'g') || + (filename[len-1] == 'Z' && filename[len-2] == 'G')) + { + bpersist->SetPersistFlags (nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION); + } + else + { + bpersist->SetPersistFlags (nsIWebBrowserPersist::PERSIST_FLAGS_NONE); + } + + if (flags & EMBED_PERSIST_BYPASSCACHE) + { + bpersist->SetPersistFlags (nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE); + } + + if (flags & EMBED_PERSIST_FROMCACHE) + { + bpersist->SetPersistFlags (nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE); + } + + GProgressListener *aProgress = new GProgressListener (); + + if (uri == NULL) + { + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + nsCOMPtr<nsIDOMDocument> DOMDocument; + + if (flags & EMBED_PERSIST_MAINDOC) + { + rv = wrapper->GetMainDOMDocument (getter_AddRefs(DOMDocument)); + } + else + { + rv = wrapper->GetDOMDocument (getter_AddRefs(DOMDocument)); + } + if (NS_FAILED(rv) || !DOMDocument) return G_FAILED; + + nsCOMPtr<nsIDocument> document = + do_QueryInterface (DOMDocument, &rv); + if (NS_FAILED(rv) || !document) return G_FAILED; + + nsCOMPtr<nsIURI> uri; + rv = document->GetDocumentURL (getter_AddRefs(uri)); + if (NS_FAILED(rv) || !uri) return G_FAILED; + + aProgress->InitForPersist (bpersist, parent, + uri, file, + ACTION_OBJECT_NOTIFY, + persist, + !(flags & EMBED_PERSIST_SHOW_PROGRESS)); + + rv = bpersist->SaveDocument (DOMDocument, file, path, nsnull, 0, 0); + if (NS_FAILED(rv)) return G_FAILED; + } + else + { + aProgress->InitForPersist (bpersist, parent, + linkURI, file, + ACTION_OBJECT_NOTIFY, + persist, + !(flags & EMBED_PERSIST_SHOW_PROGRESS)); + + rv = bpersist->SaveURI (linkURI, nsnull, file); + if (NS_FAILED(rv)) return G_FAILED; + } + + return G_OK; +} + diff --git a/embed/mozilla/mozilla-embed-persist.h b/embed/mozilla/mozilla-embed-persist.h new file mode 100644 index 000000000..bcd073ca3 --- /dev/null +++ b/embed/mozilla/mozilla-embed-persist.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_EMBED_PERSIST_H +#define MOZILLA_EMBED_PERSIST_H + +#include "ephy-embed-persist.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct MozillaEmbedPersistClass MozillaEmbedPersistClass; + +#define MOZILLA_EMBED_PERSIST_TYPE (mozilla_embed_persist_get_type ()) +#define MOZILLA_EMBED_PERSIST(obj) (GTK_CHECK_CAST ((obj), MOZILLA_EMBED_PERSIST_TYPE, MozillaEmbedPersist)) +#define MOZILLA_EMBED_PERSIST_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), MOZILLA_EMBED_PERSIST_TYPE, MozillaEmbedPersistClass)) +#define IS_MOZILLA_EMBED_PERSIST(obj) (GTK_CHECK_TYPE ((obj), MOZILLA_EMBED_PERSIST_TYPE)) +#define IS_MOZILLA_EMBED_PERSIST_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), MOZILLA_EMBED_PERSIST)) +#define MOZILLA_EMBED_PERSIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_EMBED_PERSIST_TYPE, MozillaEmbedPersistClass)) + +typedef struct MozillaEmbedPersist MozillaEmbedPersist; +typedef struct MozillaEmbedPersistPrivate MozillaEmbedPersistPrivate; + +struct MozillaEmbedPersist +{ + EphyEmbedPersist parent; + MozillaEmbedPersistPrivate *priv; +}; + +struct MozillaEmbedPersistClass +{ + EphyEmbedPersistClass parent_class; +}; + +GType mozilla_embed_persist_get_type (void); + +G_END_DECLS + +#endif diff --git a/embed/mozilla/mozilla-embed-shell.cpp b/embed/mozilla/mozilla-embed-shell.cpp new file mode 100644 index 000000000..00b3c390d --- /dev/null +++ b/embed/mozilla/mozilla-embed-shell.cpp @@ -0,0 +1,1106 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "glib.h" +#include "ephy-string.h" +#include "gtkmozembed.h" +#include "mozilla-embed-shell.h" +#include "mozilla-prefs.h" +#include "ephy-prefs.h" +#include "ephy-file-helpers.h" +#include "mozilla-notifiers.h" +#include "mozilla-i18n.h" +#include "eel-gconf-extensions.h" +#include "ephy-embed-prefs.h" +#include "MozRegisterComponents.h" +#include "FilePicker.h" + +#include <time.h> +#include <libgnome/gnome-i18n.h> +#include <string.h> +#include <nsICacheService.h> +#include <nsCOMPtr.h> +#include <nsNetCID.h> +#include <nsIServiceManager.h> +#include <nsIIOService.h> +#include <nsIProtocolProxyService.h> +#include <nsIJVMManager.h> +#include <nsIAtom.h> +#include <nsICharsetConverterManager.h> +#include <nsICharsetConverterManager2.h> +#include <nsIFontList.h> +#include <nsISupportsPrimitives.h> +#include <nsReadableUtils.h> +#include <nsIPermissionManager.h> +#include <nsICookieManager.h> +#include <nsIPermission.h> +#include <nsIPasswordManager.h> +#include <nsIPassword.h> +#include <nsICookie.h> +#include <nsCCookieManager.h> +#include <nsCPasswordManager.h> + +#define MOZILLA_PROFILE_DIR "/mozilla" +#define MOZILLA_PROFILE_NAME "epiphany" +#define MOZILLA_PROFILE_FILE "prefs.js" + +static void +mozilla_embed_shell_class_init (MozillaEmbedShellClass *klass); +static void +mozilla_embed_shell_init (MozillaEmbedShell *ges); +static void +mozilla_embed_shell_finalize (GObject *object); + +static void +impl_get_capabilities (EphyEmbedShell *shell, + EmbedShellCapabilities *caps); +static gresult +impl_clear_cache (EphyEmbedShell *shell, + CacheType type); +static gresult +impl_set_offline_mode (EphyEmbedShell *shell, + gboolean offline); +static gresult +impl_load_proxy_autoconf (EphyEmbedShell *shell, + const char* url); +static gresult +impl_get_charset_titles (EphyEmbedShell *shell, + const char *group, + GList **charsets); +static gresult +impl_get_charset_groups (EphyEmbedShell *shell, + GList **groups); +static gresult +impl_get_font_list (EphyEmbedShell *shell, + const char *langGroup, + const char *fontType, + GList **fontList, + char **default_font); +static gresult +impl_set_permission (EphyEmbedShell *shell, + const char *url, + PermissionType type, + gboolean allow); +static gresult +impl_list_permissions (EphyEmbedShell *shell, + PermissionType type, + GList **permissions); +static gresult +impl_remove_permissions (EphyEmbedShell *shell, + PermissionType type, + GList *permissions); +static gresult +impl_list_cookies (EphyEmbedShell *shell, + GList **cookies); +static gresult +impl_remove_cookies (EphyEmbedShell *shell, + GList *cookies); +static gresult +impl_list_passwords (EphyEmbedShell *shell, + PasswordType type, + GList **passwords); +static gresult +impl_remove_passwords (EphyEmbedShell *shell, + GList *passwords, + PasswordType type); +static gresult +impl_show_file_picker (EphyEmbedShell *shell, + GtkWidget *parentWidget, + const char *title, + const char *directory, + const char *file, + FilePickerMode mode, + char **ret_fullpath, + gboolean *ret_save_content, + FileFormat *file_formats, + int *ret_file_format); + +static void mozilla_embed_shell_new_window_orphan_cb (GtkMozEmbedSingle *embed, + GtkMozEmbed **retval, + guint chrome_mask, + EphyEmbedShell *shell); + +struct MozillaEmbedShellPrivate +{ + GHashTable *charsets_hash; + GList *sorted_charsets_titles; +}; + +static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID); + +static GObjectClass *parent_class = NULL; + +GType +mozilla_embed_shell_get_type (void) +{ + static GType mozilla_embed_shell_type = 0; + + if (mozilla_embed_shell_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (MozillaEmbedShellClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) mozilla_embed_shell_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (MozillaEmbedShell), + 0, /* n_preallocs */ + (GInstanceInitFunc) mozilla_embed_shell_init + }; + + mozilla_embed_shell_type = g_type_register_static (EPHY_EMBED_SHELL_TYPE, + "MozillaEmbedShell", + &our_info, (GTypeFlags)0); + } + + return mozilla_embed_shell_type; +} + +static void +mozilla_embed_shell_class_init (MozillaEmbedShellClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + EphyEmbedShellClass *shell_class; + + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + shell_class = EPHY_EMBED_SHELL_CLASS (klass); + + object_class->finalize = mozilla_embed_shell_finalize; + + shell_class->get_capabilities = impl_get_capabilities; + shell_class->clear_cache = impl_clear_cache; + shell_class->set_offline_mode = impl_set_offline_mode; + shell_class->load_proxy_autoconf = impl_load_proxy_autoconf; + shell_class->get_charset_titles = impl_get_charset_titles; + shell_class->get_charset_groups = impl_get_charset_groups; + shell_class->get_font_list = impl_get_font_list; + shell_class->set_permission = impl_set_permission; + shell_class->list_permissions = impl_list_permissions; + shell_class->remove_permissions = impl_remove_permissions; + shell_class->list_cookies = impl_list_cookies; + shell_class->remove_cookies = impl_remove_cookies; + shell_class->list_passwords = impl_list_passwords; + shell_class->remove_passwords = impl_remove_passwords; + shell_class->show_file_picker = impl_show_file_picker; +} + +static void +mozilla_load_proxy_prefs (MozillaEmbedShell *shell) +{ + char *tmp; + int i, mozilla_mode = 0; + + /* Proxy mode */ + tmp = eel_gconf_get_string (CONF_NETWORK_PROXY_MODE); + g_return_if_fail (tmp != NULL); + + if (strcmp (tmp, "manual") == 0) + { + mozilla_mode = 1; + } + else if (strcmp (tmp, "auto") == 0) + { + mozilla_mode = 2; + } + + mozilla_prefs_set_int ("network.proxy.type", mozilla_mode); + g_free (tmp); + + /* Http proxy */ + tmp = eel_gconf_get_string (CONF_NETWORK_HTTP_PROXY); + g_return_if_fail (tmp != NULL); + mozilla_prefs_set_string ("network.proxy.http", tmp); + g_free (tmp); + + i = eel_gconf_get_integer (CONF_NETWORK_HTTP_PROXY_PORT); + mozilla_prefs_set_int ("network.proxy.http_port", i); + + /* Ftp proxy */ + tmp = eel_gconf_get_string (CONF_NETWORK_FTP_PROXY); + g_return_if_fail (tmp != NULL); + mozilla_prefs_set_string ("network.proxy.ftp", tmp); + g_free (tmp); + + i = eel_gconf_get_integer (CONF_NETWORK_FTP_PROXY_PORT); + mozilla_prefs_set_int ("network.proxy.ftp_port", i); + + /* Secure proxy */ + tmp = eel_gconf_get_string (CONF_NETWORK_SSL_PROXY); + g_return_if_fail (tmp != NULL); + mozilla_prefs_set_string ("network.proxy.ssl", tmp); + g_free (tmp); + + i = eel_gconf_get_integer (CONF_NETWORK_SSL_PROXY_PORT); + mozilla_prefs_set_int ("network.proxy.ssl_port", i); + + /* Socks proxy */ + tmp = eel_gconf_get_string (CONF_NETWORK_SOCKS_PROXY); + g_return_if_fail (tmp != NULL); + mozilla_prefs_set_string ("network.proxy.socks", tmp); + g_free (tmp); + + i = eel_gconf_get_integer (CONF_NETWORK_SOCKS_PROXY_PORT); + mozilla_prefs_set_int ("network.proxy.socks_port", i); + + /* Autoconfiguration */ + tmp = eel_gconf_get_string (CONF_NETWORK_PROXY_AUTO_URL); + g_return_if_fail (tmp != NULL); + ephy_embed_shell_load_proxy_autoconf + (EPHY_EMBED_SHELL (shell), tmp); + g_free (tmp); +} + +static void +mozilla_set_default_prefs (void) +{ + mozilla_prefs_set_boolean ("mozilla.widget.raise-on-setfocus", + FALSE); + mozilla_prefs_set_boolean ("browser.display.use_system_colors", + FALSE); + + /* set default search engine */ + mozilla_prefs_set_string ("keyword.URL",_("http://www.google.com/search?q=")); + mozilla_prefs_set_boolean ("keyword.enabled", TRUE); + mozilla_prefs_set_boolean ("security.checkloaduri", FALSE); + + /* while we have no UI */ + mozilla_prefs_set_boolean ("wallet.captureForms", FALSE); + + /* deactivate mailcap and mime.types support */ + mozilla_prefs_set_string ("helpers.global_mime_types_file", ""); + mozilla_prefs_set_string ("helpers.global_mailcap_file", ""); + mozilla_prefs_set_string ("helpers.private_mime_types_file", ""); + mozilla_prefs_set_string ("helpers.private_mailcap_file", ""); + + /* dont allow xpi installs from epiphany, there are crashes */ + mozilla_prefs_set_boolean ("xpinstall.enabled", FALSE); + + /* disable sucky XUL ftp view, have nice ns4-like html page instead */ + mozilla_prefs_set_boolean ("network.dir.generate_html", TRUE); + + /* set the right accept encoding flags */ + mozilla_prefs_set_string ("network.http.accept-encoding" , + "gzip, deflate, compress;q=0.9"); + + mozilla_prefs_save (); +} + +static void +mozilla_init_single (MozillaEmbedShell *mes) +{ + GtkMozEmbedSingle *single; + + /* get single */ + single = gtk_moz_embed_single_get (); + if (single == NULL) + { + g_warning ("Failed to get singleton embed object!\n"); + } + + /* allow creation of orphan windows */ + g_signal_connect (G_OBJECT (single), "new_window_orphan", + GTK_SIGNAL_FUNC (mozilla_embed_shell_new_window_orphan_cb), + mes); +} + +static void +mozilla_init_home (void) +{ + char *mozilla_five_home; + mozilla_five_home = g_strdup (g_getenv ("MOZILLA_FIVE_HOME")); + gtk_moz_embed_set_comp_path (mozilla_five_home); + g_free (mozilla_five_home); +} + +void +mozilla_init_profile (void) +{ + char *profile_path; + profile_path = g_build_filename (ephy_dot_dir (), + MOZILLA_PROFILE_DIR, + NULL); + gtk_moz_embed_set_profile_path (profile_path, MOZILLA_PROFILE_NAME); + g_free (profile_path); +} + +static gboolean +is_new_build (void) +{ + gboolean new_build = FALSE; + char *mozprefs, *build_test; + + mozprefs = g_build_filename (ephy_dot_dir (), + MOZILLA_PROFILE_DIR, + MOZILLA_PROFILE_NAME, + MOZILLA_PROFILE_FILE, + NULL); + + /* no mozilla prefs ? or new epiphany build */ + build_test = eel_gconf_get_string ("/apps/epiphany/gconf_test"); + if (!g_file_test(mozprefs, G_FILE_TEST_EXISTS) || + build_test == NULL || + strncmp (build_test, __TIME__, 8) != 0) + { + new_build = TRUE; + eel_gconf_set_string ("/apps/epiphany/gconf_test", __TIME__); + } + + g_free (mozprefs); + g_free (build_test); + + return new_build; +} + +static void +mozilla_init_prefs (void) +{ + mozilla_set_default_prefs (); + mozilla_notifiers_set_defaults (); +} + +static gboolean +have_gnome_url_handler (const gchar *protocol) +{ + gchar *key, *cmd; + gboolean rv; + + key = g_strdup_printf ("/desktop/gnome/url-handlers/%s/command", + protocol); + cmd = eel_gconf_get_string (key); + g_free (key); + + rv = (cmd != NULL); + g_free (cmd); + + if (!rv) return rv; + + key = g_strdup_printf ("/desktop/gnome/url-handlers/%s/enabled", + protocol); + rv = eel_gconf_get_boolean (key); + g_free (key); + + return rv; +} + +static void +mozilla_register_external_protocols (void) +{ + /* FIXME register only when needed */ + if (have_gnome_url_handler ("ftp")) + { + mozilla_register_FtpProtocolHandler (); + } + else + { + mozilla_unregister_FtpProtocolHandler (); + } + + mozilla_register_MailtoProtocolHandler (); +} + +static void +mozilla_embed_shell_init (MozillaEmbedShell *mes) +{ + gboolean new_build; + + mes->priv = g_new0 (MozillaEmbedShellPrivate, 1); + + mes->priv->charsets_hash = NULL; + mes->priv->sorted_charsets_titles = NULL; + + new_build = is_new_build (); + + /* Pre initialization */ + mozilla_notifiers_init (mes); + mozilla_init_home (); + mozilla_init_profile (); + + /* Fire up the best */ + gtk_moz_embed_push_startup (); + + /* Post initialization */ + if (new_build) + { + mozilla_init_prefs (); + } + + mozilla_load_proxy_prefs (mes); + + mozilla_init_single (mes); + + mozilla_register_components (); + + mozilla_register_external_protocols (); + + /* FIXME alert if fails */ +} + +static void +mozilla_embed_shell_new_window_orphan_cb (GtkMozEmbedSingle *embed, + GtkMozEmbed **retval, + guint chrome_mask, + EphyEmbedShell *shell) +{ + /* FIXME conversion duped in mozilla_embed */ + EphyEmbed *new_embed; + int i; + EmbedChromeMask mask = EMBED_CHROME_OPENASPOPUP; + + struct + { + guint chromemask; + EmbedChromeMask embed_mask; + } + conversion_map [] = + { + { GTK_MOZ_EMBED_FLAG_DEFAULTCHROME, EMBED_CHROME_DEFAULT }, + { GTK_MOZ_EMBED_FLAG_MENUBARON, EMBED_CHROME_MENUBARON }, + { GTK_MOZ_EMBED_FLAG_TOOLBARON, EMBED_CHROME_TOOLBARON }, + { GTK_MOZ_EMBED_FLAG_STATUSBARON, EMBED_CHROME_STATUSBARON }, + { GTK_MOZ_EMBED_FLAG_WINDOWRAISED, EMBED_CHROME_WINDOWRAISED }, + { GTK_MOZ_EMBED_FLAG_WINDOWLOWERED, EMBED_CHROME_WINDOWLOWERED }, + { GTK_MOZ_EMBED_FLAG_CENTERSCREEN, EMBED_CHROME_CENTERSCREEN }, + { GTK_MOZ_EMBED_FLAG_OPENASDIALOG, EMBED_CHROME_OPENASDIALOG }, + { GTK_MOZ_EMBED_FLAG_OPENASCHROME, EMBED_CHROME_OPENASCHROME }, + { 0, EMBED_CHROME_NONE } + }; + + for (i = 0; conversion_map[i].chromemask != 0; i++) + { + if (chrome_mask & conversion_map[i].chromemask) + { + mask = (EmbedChromeMask) (mask | conversion_map[i].embed_mask); + } + } + + g_signal_emit_by_name (shell, "new_window_orphan", &new_embed, mask); + + g_assert (new_embed != NULL); + + *retval = GTK_MOZ_EMBED(EPHY_EMBED(new_embed)); +} + +static void +mozilla_embed_shell_finalize (GObject *object) +{ + MozillaEmbedShell *mes; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MOZILLA_EMBED_SHELL (object)); + + mes = MOZILLA_EMBED_SHELL (object); + + g_return_if_fail (mes->priv != NULL); + + mozilla_notifiers_free (); + + mozilla_prefs_save (); + + gtk_moz_embed_pop_startup (); + + g_free (mes->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +impl_get_capabilities (EphyEmbedShell *shell, + EmbedShellCapabilities *caps) +{ + EmbedShellCapabilities mycaps; + + mycaps = (EmbedShellCapabilities) + (CACHE_CLEAR_CAP | + OFFLINE_CAP | + PROXY_AUTOCONF_CAP | + JAVA_CONSOLE_CAP | + JS_CONSOLE_CAP | + CHARSETS_CAP | + PERMISSIONS_CAP | + COOKIES_CAP | + PASSWORDS_CAP); + + *caps = mycaps; +} + +static gresult +impl_clear_cache (EphyEmbedShell *shell, + CacheType type) +{ + nsresult rv; + + nsCOMPtr<nsICacheService> CacheService = + do_GetService (NS_CACHESERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return G_FAILED; + + CacheService->EvictEntries((guint)type); + + return G_OK; +} + +static gresult +impl_set_offline_mode (EphyEmbedShell *shell, + gboolean offline) +{ + nsresult rv; + + nsCOMPtr<nsIIOService> io = do_GetService(NS_IOSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) + return G_FAILED; + + rv = io->SetOffline(offline); + if (NS_SUCCEEDED(rv)) return G_FAILED; + + return G_OK; +} + +static gresult +impl_load_proxy_autoconf (EphyEmbedShell *shell, + const char* url) +{ + nsresult rv; + + nsCOMPtr<nsIProtocolProxyService> pps = + do_GetService ("@mozilla.org/network/protocol-proxy-service;1", + &rv); + if (NS_FAILED(rv) || !pps) return G_FAILED; + + rv = pps->ConfigureFromPAC (url); + if (NS_FAILED(rv)) return G_FAILED; + + return G_OK; +} + +static gresult +fill_charsets_lists (MozillaEmbedShellPrivate *priv) +{ + nsresult rv; + char *tmp; + PRUint32 cscount; + PRUint32 translated_cscount = get_translated_cscount (); + char *charset_str, *charset_title_str; + + nsCOMPtr<nsIAtom> docCharsetAtom; + nsCOMPtr<nsICharsetConverterManager2> ccm2 = + do_GetService (NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); + if (!NS_SUCCEEDED(rv)) return G_FAILED; + + nsCOMPtr <nsISupportsArray> cs_list; + rv = ccm2->GetDecoderList (getter_AddRefs(cs_list)); + if (!NS_SUCCEEDED(rv)) return G_FAILED; + + rv = cs_list->Count(&cscount); + priv->charsets_hash = g_hash_table_new (g_str_hash, g_str_equal); + for (PRUint32 i = 0; i < cscount; i++) + { + nsCOMPtr<nsISupports> cssupports = + (dont_AddRef)(cs_list->ElementAt(i)); + nsCOMPtr<nsIAtom> csatom ( do_QueryInterface(cssupports) ); + nsAutoString charset_ns, charset_title_ns; + + /* charset name */ + rv = csatom->ToString(charset_ns); + tmp = ToNewCString (charset_ns); + if (tmp == NULL || strlen (tmp) == 0) + { + continue; + } + charset_str = g_strdup (tmp); + nsMemory::Free (tmp); + tmp = nsnull; + + /* charset readable title */ + rv = ccm2->GetCharsetTitle2(csatom, &charset_title_ns); + tmp = ToNewCString (charset_title_ns); + if (tmp == NULL || + strlen (tmp) == 0) + { + if (tmp) nsMemory::Free (tmp); + charset_title_str = g_strdup (charset_str); + } + else + { + charset_title_str = g_strdup (tmp); + nsMemory::Free (tmp); + tmp = nsnull; + } + + for (PRUint32 j = 0; j < translated_cscount; j++) + { + if (g_ascii_strcasecmp ( + charset_str, + charset_trans_array[j].charset_name) == 0) + { + g_free (charset_title_str); + charset_title_str = (char *) + _(charset_trans_array[j].charset_title); + break; + } + } + + /* fill the hash and the sorted list */ + g_hash_table_insert (priv->charsets_hash, charset_title_str, charset_str); + priv->sorted_charsets_titles = + g_list_insert_sorted (priv->sorted_charsets_titles, + (gpointer)charset_title_str, + (GCompareFunc)g_ascii_strcasecmp); + } + + return G_OK; +} + +static void +ensure_charsets_tables (MozillaEmbedShell *shell) +{ + if (!shell->priv->charsets_hash) + { + fill_charsets_lists (shell->priv); + } +} + +static gresult +impl_get_charset_titles (EphyEmbedShell *shell, + const char *group, + GList **charsets) +{ + MozillaEmbedShell *mshell = MOZILLA_EMBED_SHELL(shell); + int count = get_translated_cscount (); + GList *l = NULL; + int j; + + ensure_charsets_tables (mshell); + g_return_val_if_fail (mshell->priv->charsets_hash != NULL, G_FAILED); + + for (j = 0; j < count; j++) + { + if (group == NULL || + strcmp (group, lgroups[charset_trans_array[j].lgroup]) == 0) + { + CharsetInfo *info; + info = g_new0 (CharsetInfo, 1); + info->name = charset_trans_array[j].charset_name; + info->title = charset_trans_array[j].charset_title; + l = g_list_append (l, info); + + /* FIXME check that the encoding exists in mozilla before + * adding it */ + } + } + + *charsets = l; + + return G_OK; +} + +static gresult +impl_get_charset_groups (EphyEmbedShell *shell, + GList **groups) +{ + GList *l = NULL; + int i; + + for (i = 0; lgroups[i] != NULL; i++) + { + l = g_list_append (l, (gpointer)lgroups[i]); + } + + *groups = l; + + return G_OK; +} + +static gresult +impl_get_font_list (EphyEmbedShell *shell, + const char *langGroup, + const char *fontType, + GList **fontList, + char **default_font) +{ + nsresult rv; + + nsCOMPtr<nsIFontList> mozFontList; + mozFontList = do_CreateInstance("@mozilla.org/gfx/fontlist;1", &rv); + if(NS_FAILED(rv)) return G_FAILED; + + nsCOMPtr<nsISimpleEnumerator> fontEnum; + mozFontList->AvailableFonts(NS_ConvertUTF8toUCS2(langGroup).get(), + NS_ConvertUTF8toUCS2(fontType).get(), + getter_AddRefs(fontEnum)); + if(NS_FAILED(rv)) return G_FAILED; + + GList *l = NULL; + PRBool enumResult; + for(fontEnum->HasMoreElements(&enumResult) ; + enumResult == PR_TRUE; + fontEnum->HasMoreElements(&enumResult)) + { + nsCOMPtr<nsISupportsString> fontName; + fontEnum->GetNext(getter_AddRefs(fontName)); + if(NS_FAILED(rv)) return G_FAILED; + + nsString fontString; + fontName->GetData(fontString); + + char *gFontString; + gFontString = g_strdup(NS_ConvertUCS2toUTF8(fontString).get()); + l = g_list_append(l, gFontString); + } + *fontList = l; + + if (default_font != NULL) + { + char key [255]; + + sprintf (key, "font.name.%s.%s", fontType, langGroup); + + *default_font = mozilla_prefs_get_string (key); + } + + return G_OK; +} + +static gresult +impl_set_permission (EphyEmbedShell *shell, + const char *url, + PermissionType type, + gboolean allow) +{ + nsresult rv; + nsCOMPtr<nsIPermissionManager> permissionManager = + do_CreateInstance (NS_PERMISSIONMANAGER_CONTRACTID); + + rv = permissionManager->Add (nsDependentCString(url), + allow ? PR_TRUE : PR_FALSE, type); + if (NS_FAILED(rv)) return G_FAILED; + + return G_OK; +} + +static gresult +impl_list_permissions (EphyEmbedShell *shell, + PermissionType type, + GList **permissions) +{ + nsresult result; + + *permissions = NULL; + + nsCOMPtr<nsIPermissionManager> permissionManager = + do_CreateInstance (NS_PERMISSIONMANAGER_CONTRACTID); + nsCOMPtr<nsISimpleEnumerator> permissionEnumerator; + result = permissionManager->GetEnumerator (getter_AddRefs(permissionEnumerator)); + if (NS_FAILED(result)) return G_FAILED; + + PRBool enumResult; + for (permissionEnumerator->HasMoreElements(&enumResult) ; + enumResult == PR_TRUE ; + permissionEnumerator->HasMoreElements(&enumResult)) + { + nsCOMPtr<nsIPermission> nsPermission; + result = permissionEnumerator->GetNext (getter_AddRefs(nsPermission)); + if (NS_FAILED(result)) return G_FAILED; + + PRInt32 cType; + nsPermission->GetType (&cType); + if (cType == type) + { + PermissionInfo *b = g_new0 (PermissionInfo, 1); + gchar *tmp = NULL; + + nsPermission->GetHost (&tmp); + b->domain = g_strdup (tmp); + nsMemory::Free (tmp); + + PRBool cap; + nsPermission->GetCapability (&cap); + if (cap == PR_TRUE) + b->type = g_strdup (_("Allowed")); + else + b->type = g_strdup (_("Blocked")); + + *permissions = g_list_prepend (*permissions, b); + } + } + + *permissions = g_list_reverse (*permissions); + + return G_OK; +} + +static gresult +impl_remove_permissions (EphyEmbedShell *shell, + PermissionType type, + GList *permissions) +{ + nsresult result; + nsCOMPtr<nsIPermissionManager> permissionManager = + do_CreateInstance (NS_PERMISSIONMANAGER_CONTRACTID); + + for (GList *permissions = g_list_first(permissions); permissions != NULL; + permissions = g_list_next(permissions)) + { + PermissionInfo *b = (PermissionInfo *)permissions->data; + result = permissionManager->Remove (nsDependentCString(b->domain), + type); + if (NS_FAILED(result)) return G_FAILED; + }; + + return G_OK; +} + +static gresult +impl_list_cookies (EphyEmbedShell *shell, + GList **cookies) +{ + nsresult result; + + nsCOMPtr<nsICookieManager> cookieManager = + do_CreateInstance (NS_COOKIEMANAGER_CONTRACTID); + nsCOMPtr<nsISimpleEnumerator> cookieEnumerator; + result = + cookieManager->GetEnumerator (getter_AddRefs(cookieEnumerator)); + if (NS_FAILED(result)) return G_FAILED; + + PRBool enumResult; + for (cookieEnumerator->HasMoreElements(&enumResult) ; + enumResult == PR_TRUE ; + cookieEnumerator->HasMoreElements(&enumResult)) + { + CookieInfo *c; + + nsCOMPtr<nsICookie> nsCookie; + result = cookieEnumerator->GetNext (getter_AddRefs(nsCookie)); + if (NS_FAILED(result)) return G_FAILED; + + c = g_new0 (CookieInfo, 1); + + nsCAutoString transfer; + + nsCookie->GetHost (transfer); + c->base.domain = g_strdup (transfer.get()); + nsCookie->GetName (transfer); + c->name = g_strdup (transfer.get()); + nsCookie->GetValue (transfer); + c->value = g_strdup (transfer.get()); + nsCookie->GetPath (transfer); + c->path = g_strdup (transfer.get()); + + PRBool isSecure; + nsCookie->GetIsSecure (&isSecure); + if (isSecure == PR_TRUE) + c->secure = g_strdup (_("Yes")); + else + c->secure = g_strdup (_("No")); + + PRUint64 dateTime; + nsCookie->GetExpires (&dateTime); + if(dateTime == 0) + c->expire = g_strdup (_("End of current session")); + else + c->expire = g_strdup_printf ("%s",ctime((time_t*)&dateTime)); + + *cookies = g_list_prepend (*cookies, c); + } + + *cookies = g_list_reverse (*cookies); + + return G_OK; +} + +static gresult +impl_remove_cookies (EphyEmbedShell *shell, + GList *cookies) +{ + nsresult result; + GList *cl; + nsCOMPtr<nsICookieManager> cookieManager = + do_CreateInstance (NS_COOKIEMANAGER_CONTRACTID); + + for (cl = g_list_first(cookies) ; cl != NULL ; + cl = g_list_next (cl)) + { + CookieInfo *c = (CookieInfo *)cl->data; + + result = cookieManager->Remove (NS_LITERAL_CSTRING(c->base.domain), + NS_LITERAL_CSTRING(c->name), + NS_LITERAL_CSTRING(c->path), + PR_FALSE); + if (NS_FAILED(result)) return G_FAILED; + }; + + return G_OK; +} + +static gresult +impl_list_passwords (EphyEmbedShell *shell, + PasswordType type, + GList **passwords) +{ + nsresult result = NS_ERROR_FAILURE; + + nsCOMPtr<nsIPasswordManager> passwordManager = + do_CreateInstance (NS_PASSWORDMANAGER_CONTRACTID); + nsCOMPtr<nsISimpleEnumerator> passwordEnumerator; + if (type == PASSWORD_PASSWORD) + result = passwordManager->GetEnumerator + (getter_AddRefs(passwordEnumerator)); + else if (type == PASSWORD_REJECT) + result = passwordManager->GetRejectEnumerator + (getter_AddRefs(passwordEnumerator)); + if (NS_FAILED(result)) return G_FAILED; + + PRBool enumResult; + for (passwordEnumerator->HasMoreElements(&enumResult) ; + enumResult == PR_TRUE ; + passwordEnumerator->HasMoreElements(&enumResult)) + { + nsCOMPtr<nsIPassword> nsPassword; + result = passwordEnumerator->GetNext + (getter_AddRefs(nsPassword)); + if (NS_FAILED(result)) return G_FAILED; + + PasswordInfo *p = g_new0 (PasswordInfo, 1); + + nsCAutoString transfer; + nsPassword->GetHost (transfer); + p->host = g_strdup (transfer.get()); + + if (type == PASSWORD_PASSWORD) + { + nsAutoString unicodeName; + nsPassword->GetUser (unicodeName); + p->username = g_strdup(NS_ConvertUCS2toUTF8(unicodeName).get()); + } + + *passwords = g_list_prepend (*passwords, p); + } + + *passwords = g_list_reverse (*passwords); + + return G_OK; +} + +static gresult +impl_remove_passwords (EphyEmbedShell *shell, + GList *passwords, + PasswordType type) +{ + nsresult result = NS_ERROR_FAILURE; + nsCOMPtr<nsIPasswordManager> passwordManager = + do_CreateInstance (NS_PASSWORDMANAGER_CONTRACTID); + + for (GList *l = g_list_first(passwords) ; l !=NULL ; + l = g_list_next(l)) + { + PasswordInfo *p = (PasswordInfo *)l->data; + if (type == PASSWORD_PASSWORD) + { + result = passwordManager->RemoveUser (NS_LITERAL_CSTRING(p->host), + NS_ConvertUTF8toUCS2(nsDependentCString(p->username))); + } + else if (type == PASSWORD_REJECT) + { + result = passwordManager->RemoveReject + (nsDependentCString(p->host)); + }; + + if (NS_FAILED(result)) return G_FAILED; + }; + + return G_OK; +} + +static gresult +impl_show_file_picker (EphyEmbedShell *shell, + GtkWidget *parentWidget, + const char *title, + const char *directory, + const char *file, + FilePickerMode mode, + char **ret_fullpath, + gboolean *ret_save_content, + FileFormat *file_formats, + int *ret_file_format) +{ + PRBool showContentCheck; + gchar *expanded_directory; + + if (ret_save_content == NULL) + showContentCheck = PR_FALSE; + else + showContentCheck = PR_TRUE; + + GFilePicker *filePicker = new GFilePicker (showContentCheck, + file_formats); + + /* FIXME sane path: expand tilde ... */ + expanded_directory = g_strdup (directory); + + /* make sure the directory exists, and use the home directory + * otherwise */ + if (!expanded_directory || + !g_file_test (expanded_directory, G_FILE_TEST_IS_DIR)) + { + if (expanded_directory) g_free (expanded_directory); + expanded_directory = g_strdup (g_get_home_dir()); + } + + nsCOMPtr<nsILocalFile> dir = + do_CreateInstance (NS_LOCAL_FILE_CONTRACTID); + dir->InitWithPath (NS_ConvertUTF8toUCS2(expanded_directory)); + g_free (expanded_directory); + + filePicker->InitWithGtkWidget (parentWidget, title, mode); + filePicker->SetDefaultString (NS_ConvertUTF8toUCS2(file).get()); + filePicker->SetDisplayDirectory (dir); + + PRInt16 retval; + filePicker->Show (&retval); + + if (ret_save_content != NULL) + { + if (retval == GFilePicker::returnOKSaveContent) + *ret_save_content = TRUE; + else + *ret_save_content = FALSE; + } + if (ret_file_format != NULL) + { + *ret_file_format = filePicker->mSelectedFileFormat; + } + + if (retval == nsIFilePicker::returnCancel) + { + delete filePicker; + return G_FAILED; + } + else + { + if (*ret_fullpath) + g_free (*ret_fullpath); + nsCOMPtr<nsILocalFile> file; + filePicker->GetFile (getter_AddRefs(file)); + nsAutoString tempFullPathStr; + file->GetPath (tempFullPathStr); + *ret_fullpath = g_strdup (NS_ConvertUCS2toUTF8(tempFullPathStr).get()); + delete filePicker; + return G_OK; + } +} diff --git a/embed/mozilla/mozilla-embed-shell.h b/embed/mozilla/mozilla-embed-shell.h new file mode 100644 index 000000000..daedb2948 --- /dev/null +++ b/embed/mozilla/mozilla-embed-shell.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_EMBED_SHELL_H +#define MOZILLA_EMBED_SHELL_H + +#include "glib.h" +#include "ephy-embed-shell.h" +#include <glib-object.h> + +G_BEGIN_DECLS + +#define MOZILLA_EMBED_SHELL_TYPE (mozilla_embed_shell_get_type ()) +#define MOZILLA_EMBED_SHELL(obj) (GTK_CHECK_CAST ((obj), MOZILLA_EMBED_SHELL_TYPE, MozillaEmbedShell)) +#define MOZILLA_EMBED_SHELL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), MOZILLA_EMBED_SHELL_TYPE, MozillaEmbedShellClass)) +#define IS_MOZILLA_EMBED_SHELL(obj) (GTK_CHECK_TYPE ((obj), MOZILLA_EMBED_SHELL_TYPE)) +#define IS_MOZILLA_EMBED_SHELL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), MOZILLA_EMBED_SHELL)) +#define MOZILLA_EMBED_SHELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_EMBED_SHELL_TYPE, MozillaEmbedShellClass)) + +typedef struct MozillaEmbedShell MozillaEmbedShell; +typedef struct MozillaEmbedShellPrivate MozillaEmbedShellPrivate; + +extern GObject *mozilla_js_console; + +struct MozillaEmbedShell +{ + EphyEmbedShell parent; + MozillaEmbedShellPrivate *priv; +}; + +struct MozillaEmbedShellClass +{ + EphyEmbedShellClass parent_class; +}; + +GType mozilla_embed_shell_get_type (void); + +G_END_DECLS + +#endif diff --git a/embed/mozilla/mozilla-embed.cpp b/embed/mozilla/mozilla-embed.cpp new file mode 100644 index 000000000..d3d2277b0 --- /dev/null +++ b/embed/mozilla/mozilla-embed.cpp @@ -0,0 +1,1585 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "gtkmozembed.h" +#include "gtkmozembed_internal.h" +#include "ephy-string.h" +#include "ephy-embed.h" +#include "mozilla-embed.h" +#include "MozillaPrivate.h" +#include "EphyWrapper.h" +#include "EventContext.h" +#include "nsIWindowWatcher.h" + +#include <nsIURI.h> +#include <nsIURL.h> +#include <nsNetUtil.h> +#include <nsString.h> +#include <nsIRequest.h> +#include <nsIWebProgressListener.h> +#include <nsITransportSecurityInfo.h> +#include <nsIPrintOptions.h> +#include <nsGfxCIID.h> + +#include <math.h> + +static void +mozilla_embed_class_init (MozillaEmbedClass *klass); +static void +mozilla_embed_init (MozillaEmbed *gs); +static void +mozilla_embed_finalize (GObject *object); +static void +mozilla_embed_destroy (GtkObject *object); +static void +ephy_embed_init (EphyEmbedClass *embed_class); + +static void +impl_get_capabilities (EphyEmbed *embed, + EmbedCapabilities *caps); +static gresult +impl_load_url (EphyEmbed *embed, + const char *url); +static gresult +impl_stop_load (EphyEmbed *embed); +static gresult +impl_can_go_back (EphyEmbed *embed); +static gresult +impl_can_go_forward (EphyEmbed *embed); +static gresult +impl_can_go_up (EphyEmbed *embed); +static gresult +impl_get_go_up_list (EphyEmbed *embed, GSList **l); +static gresult +impl_go_back (EphyEmbed *embed); +static gresult +impl_go_forward (EphyEmbed *embed); +static gresult +impl_go_up (EphyEmbed *embed); +static gresult +impl_render_data (EphyEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type); +static gresult +impl_open_stream (EphyEmbed *embed, + const char *base_uri, + const char *mime_type); +static gresult +impl_append_data (EphyEmbed *embed, + const char *data, + guint32 len); +static gresult +impl_close_stream (EphyEmbed *embed); +static gresult +impl_get_title (EphyEmbed *embed, + char **title); +static gresult +impl_get_location (EphyEmbed *embed, + gboolean toplevel, + gboolean requested, + char **location); +static gresult +impl_reload (EphyEmbed *embed, + EmbedReloadFlags flags); +static gresult +impl_copy_page (EphyEmbed *dest, + EphyEmbed *source, + EmbedDisplayType display_type); +static gresult +impl_grab_focus (EphyEmbed *embed); +static gresult +impl_get_link_tags (EphyEmbed *embed, + const char *link_type, + GList **tags); +static gresult +impl_zoom_set (EphyEmbed *embed, + int zoom, + gboolean reflow); +static gresult +impl_zoom_get (EphyEmbed *embed, + int *zoom); +static gresult +impl_selection_can_cut (EphyEmbed *embed); +static gresult +impl_selection_can_copy (EphyEmbed *embed); +static gresult +impl_can_paste (EphyEmbed *embed); +static gresult +impl_select_all (EphyEmbed *embed); +static gresult +impl_selection_cut (EphyEmbed *embed); +static gresult +impl_selection_copy (EphyEmbed *embed); +static gresult +impl_paste (EphyEmbed *embed); +static gresult +impl_shistory_count (EphyEmbed *embed, + int *count); +static gresult +impl_shistory_get_nth (EphyEmbed *embed, + int nth, + gboolean is_relative, + char **url, + char **title); +static gresult +impl_shistory_get_pos (EphyEmbed *embed, + int *pos); +static gresult +impl_shistory_go_nth (EphyEmbed *embed, + int nth); +static gboolean +impl_shistory_copy (EphyEmbed *source, + EphyEmbed *dest); +static gresult +impl_scroll (EphyEmbed *embed, + EmbedScrollDirection direction); +static gresult +impl_fine_scroll (EphyEmbed *embed, + int horiz, int vert); +static gresult +impl_get_security_level (EphyEmbed *embed, + EmbedSecurityLevel *level, + char **description); +static gresult +impl_find (EphyEmbed *embed, + EmbedFindInfo *info); + +static gresult +impl_set_charset (EphyEmbed *embed, + const char *charset); + +static gresult +impl_print (EphyEmbed *embed, + EmbedPrintInfo *info); + +static gresult +impl_print_preview_close (EphyEmbed *embed); + +static gresult +impl_print_preview_num_pages (EphyEmbed *embed, + gint *retNum); +static gresult +impl_print_preview_navigate (EphyEmbed *embed, + EmbedPrintPreviewNavType navType, + gint pageNum); + +static void +mozilla_embed_connect_signals (MozillaEmbed *membed); +static char * +mozilla_embed_get_uri_parent (const char *uri); +static void +mozilla_embed_location_changed_cb (GtkMozEmbed *embed, MozillaEmbed *membed); +static void +mozilla_embed_title_changed_cb (GtkMozEmbed *embed, MozillaEmbed *membed); +static void +mozilla_embed_net_state_all_cb (GtkMozEmbed *embed, const char *aURI, + gint state, guint status, MozillaEmbed *membed); +static void +mozilla_embed_progress_cb (GtkMozEmbed *embed, const char *aURI, + gint curprogress, gint maxprogress, MozillaEmbed *membed); +static void +mozilla_embed_link_message_cb (GtkMozEmbed *embed, MozillaEmbed *membed); +static void +mozilla_embed_js_status_cb (GtkMozEmbed *embed, MozillaEmbed *membed); +static void +mozilla_embed_visibility_cb (GtkMozEmbed *embed, gboolean visibility, MozillaEmbed *membed); +static void +mozilla_embed_destroy_brsr_cb (GtkMozEmbed *embed, MozillaEmbed *embed); +static gint +mozilla_embed_dom_mouse_click_cb (GtkMozEmbed *embed, gpointer dom_event, MozillaEmbed *membed); +static gint +mozilla_embed_dom_mouse_down_cb (GtkMozEmbed *embed, gpointer dom_event, + MozillaEmbed *membed); +static void +mozilla_embed_size_to_cb (GtkMozEmbed *embed, gint width, gint height, MozillaEmbed *membed); +static void +mozilla_embed_new_window_cb (GtkMozEmbed *embed, + GtkMozEmbed **newEmbed, + guint chromemask, MozillaEmbed *membed); +static void +mozilla_embed_security_change_cb (GtkMozEmbed *embed, + gpointer request, + guint state, MozillaEmbed *membed); +static EmbedSecurityLevel +mozilla_embed_security_level (MozillaEmbed *membed); + +/* signals to connect on each embed widget */ +static const struct +{ + char *event; + void *func; /* should be a GtkSignalFunc or similar */ +} +signal_connections[] = +{ + { "location", (void *) mozilla_embed_location_changed_cb }, + { "title", (void *) mozilla_embed_title_changed_cb }, + { "net_state_all", (void *) mozilla_embed_net_state_all_cb }, + { "progress_all", (void *) mozilla_embed_progress_cb }, + { "link_message", (void *) mozilla_embed_link_message_cb }, + { "js_status", (void *) mozilla_embed_js_status_cb }, + { "visibility", (void *) mozilla_embed_visibility_cb }, + { "destroy_browser", (void *) mozilla_embed_destroy_brsr_cb }, + { "dom_mouse_click", (void *) mozilla_embed_dom_mouse_click_cb }, + { "dom_mouse_down", (void *) mozilla_embed_dom_mouse_down_cb }, + { "size_to", (void *) mozilla_embed_size_to_cb }, + { "new_window", (void *) mozilla_embed_new_window_cb }, + { "security_change", (void *) mozilla_embed_security_change_cb }, + + /* terminator -- must be last in the list! */ + { NULL, NULL } +}; + +struct MozillaEmbedPrivate +{ + MozillaEmbedPrivate() : wrapper(NULL), security_state(-1), no_page(1) + { /* nothing */ } + + EphyWrapper *wrapper; + nsCOMPtr<nsIRequest> request; + gint security_state; + + /* HACK 1: No page loaded, 0: Loading an empty page, -1: Page loaded */ + gint no_page; +}; + +#define WINDOWWATCHER_CONTRACTID "@mozilla.org/embedcomp/window-watcher;1" + +static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID); + +static GObjectClass *parent_class = NULL; + +GType +mozilla_embed_get_type (void) +{ + static GType mozilla_embed_type = 0; + + if (mozilla_embed_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (MozillaEmbedClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) mozilla_embed_class_init, + NULL, + NULL, /* class_data */ + sizeof (MozillaEmbed), + 0, /* n_preallocs */ + (GInstanceInitFunc) mozilla_embed_init + }; + + static const GInterfaceInfo embed_info = + { + (GInterfaceInitFunc) ephy_embed_init, /* interface_init */ + NULL, /* interface_finalize */ + NULL /* interface_data */ + }; + + mozilla_embed_type = g_type_register_static (GTK_TYPE_MOZ_EMBED, + "MozillaEmbed", + &our_info, + (GTypeFlags)0); + g_type_add_interface_static (mozilla_embed_type, + EPHY_EMBED_TYPE, + &embed_info); + } + + return mozilla_embed_type; +} + +static void +ephy_embed_init (EphyEmbedClass *embed_class) +{ + embed_class->get_capabilities = impl_get_capabilities; + embed_class->load_url = impl_load_url; + embed_class->stop_load = impl_stop_load; + embed_class->can_go_back = impl_can_go_back; + embed_class->can_go_forward =impl_can_go_forward; + embed_class->can_go_up = impl_can_go_up; + embed_class->get_go_up_list = impl_get_go_up_list; + embed_class->go_back = impl_go_back; + embed_class->go_forward = impl_go_forward; + embed_class->go_up = impl_go_up; + embed_class->render_data = impl_render_data; + embed_class->open_stream = impl_open_stream; + embed_class->append_data = impl_append_data; + embed_class->close_stream = impl_close_stream; + embed_class->get_title = impl_get_title; + embed_class->get_location = impl_get_location; + embed_class->reload = impl_reload; + embed_class->copy_page = impl_copy_page; + embed_class->grab_focus = impl_grab_focus; + embed_class->get_link_tags = impl_get_link_tags; + embed_class->zoom_set = impl_zoom_set; + embed_class->zoom_get = impl_zoom_get; + embed_class->selection_can_cut = impl_selection_can_cut; + embed_class->selection_can_copy = impl_selection_can_copy; + embed_class->can_paste = impl_can_paste; + embed_class->selection_cut = impl_selection_cut; + embed_class->selection_copy = impl_selection_copy; + embed_class->paste = impl_paste; + embed_class->shistory_count = impl_shistory_count; + embed_class->shistory_get_nth = impl_shistory_get_nth; + embed_class->shistory_get_pos = impl_shistory_get_pos; + embed_class->shistory_go_nth = impl_shistory_go_nth; + embed_class->shistory_copy = impl_shistory_copy; + embed_class->scroll = impl_scroll; + embed_class->fine_scroll = impl_fine_scroll; + embed_class->get_security_level = impl_get_security_level; + embed_class->find = impl_find; + embed_class->set_charset = impl_set_charset; + embed_class->select_all = impl_select_all; + embed_class->print = impl_print; + embed_class->print_preview_close = impl_print_preview_close; + embed_class->print_preview_num_pages = impl_print_preview_num_pages; + embed_class->print_preview_navigate = impl_print_preview_navigate; +} + +static void +mozilla_embed_class_init (MozillaEmbedClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass); + parent_class = (GObjectClass *) g_type_class_peek_parent (klass); + + gtk_object_class->destroy = mozilla_embed_destroy; + object_class->finalize = mozilla_embed_finalize; +} + +static void +mozilla_embed_init (MozillaEmbed *embed) +{ + embed->priv = new MozillaEmbedPrivate; + + mozilla_embed_connect_signals (embed); +} + +gpointer +mozilla_embed_get_galeon_wrapper (MozillaEmbed *embed) +{ + g_return_val_if_fail (embed->priv->wrapper != NULL, NULL); + + return embed->priv->wrapper; +} + +static void +mozilla_embed_connect_signals (MozillaEmbed *embed) +{ + gint i; + EphyEmbed *gembed; + + gembed = EPHY_EMBED (embed); + + /* connect signals */ + for (i = 0; signal_connections[i].event != NULL; i++) + { + g_signal_connect (G_OBJECT(embed), + signal_connections[i].event, + G_CALLBACK(signal_connections[i].func), + embed); + } +} + +static void +mozilla_embed_destroy (GtkObject *object) +{ + int i; + + for (i = 0; signal_connections[i].event != NULL; i++) + { + g_signal_handlers_disconnect_by_func + (G_OBJECT(object), + (gpointer)signal_connections[i].func, + (void *)object); + } + + GTK_OBJECT_CLASS (parent_class)->destroy (object); +} + +static void +mozilla_embed_finalize (GObject *object) +{ + MozillaEmbed *embed; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_MOZILLA_EMBED (object)); + + embed = MOZILLA_EMBED (object); + + g_return_if_fail (embed->priv != NULL); + + if (embed->priv->wrapper) + { + embed->priv->wrapper->Destroy(); + delete embed->priv->wrapper; + embed->priv->wrapper = NULL; + } + + delete embed->priv; + + G_OBJECT_CLASS (parent_class)->finalize (object); + +#ifdef DEBUG_MARCO + g_print ("MozillaEmbed finalized %p\n", embed); +#endif +} + +gpointer +mozilla_embed_get_ephy_wrapper (MozillaEmbed *embed) +{ + g_return_val_if_fail (embed->priv->wrapper != NULL, NULL); + + return embed->priv->wrapper; +} + +static void +impl_get_capabilities (EphyEmbed *embed, + EmbedCapabilities *caps) +{ + EmbedCapabilities mozilla_caps; + + mozilla_caps = (EmbedCapabilities) ( + EMBED_CLIPBOARD_CAP | + EMBED_COOKIES_CAP | + EMBED_LINKS_CAP | + EMBED_ZOOM_CAP | + EMBED_PRINT_CAP | + EMBED_FIND_CAP | + EMBED_SCROLL_CAP | + EMBED_FINE_SCROLL_CAP | + EMBED_SECURITY_CAP | + EMBED_CHARSET_CAP | + EMBED_SHISTORY_CAP ); + + *caps = mozilla_caps; +} + +static gresult +impl_load_url (EphyEmbed *embed, + const char *url) +{ + gtk_moz_embed_load_url (GTK_MOZ_EMBED(embed), + url); + + return G_OK; +} + +static gresult +impl_stop_load (EphyEmbed *embed) +{ + gtk_moz_embed_stop_load (GTK_MOZ_EMBED(embed)); + + return G_OK; +} + +static gresult +impl_can_go_back (EphyEmbed *embed) +{ + if (gtk_moz_embed_can_go_back (GTK_MOZ_EMBED(embed))) + { + return G_OK; + } + else + { + return G_FAILED; + } +} + +static gresult +impl_can_go_forward (EphyEmbed *embed) +{ + if (gtk_moz_embed_can_go_forward (GTK_MOZ_EMBED(embed))) + { + return G_OK; + } + else + { + return G_FAILED; + } + +} + +static gresult +impl_can_go_up (EphyEmbed *embed) +{ + char *location; + char *s; + gresult result; + + if (ephy_embed_get_location (embed, TRUE, FALSE, &location) != G_OK) + return G_FAILED; + g_return_val_if_fail (location != NULL, G_FAILED); + if ((s = mozilla_embed_get_uri_parent (location)) != NULL) + { + g_free (s); + result = G_OK; + } + else + { + result = G_FAILED; + } + + g_free (location); + + return result; +} + +static gresult +impl_get_go_up_list (EphyEmbed *embed, GSList **l) +{ + char *location; + char *s; + + if (ephy_embed_get_location (embed, TRUE, FALSE, &location) != G_OK) + return G_FAILED; + g_return_val_if_fail (location != NULL, G_FAILED); + + *l = NULL; + s = location; + while ((s = mozilla_embed_get_uri_parent (s)) != NULL) + { + *l = g_slist_prepend (*l, s); + } + + g_free (location); + *l = g_slist_reverse (*l); + + return G_OK; +} + +static gresult +impl_go_back (EphyEmbed *embed) +{ + gtk_moz_embed_go_back (GTK_MOZ_EMBED(embed)); + + return G_OK; +} + +static gresult +impl_go_forward (EphyEmbed *embed) +{ + gtk_moz_embed_go_forward (GTK_MOZ_EMBED(embed)); + + return G_OK; +} + +static gresult +impl_go_up (EphyEmbed *embed) +{ + char *uri; + char *parent_uri; + + ephy_embed_get_location (embed, TRUE, FALSE, &uri); + g_return_val_if_fail (uri != NULL, G_FAILED); + + parent_uri = mozilla_embed_get_uri_parent (uri); + g_return_val_if_fail (parent_uri != NULL, G_FAILED); + + ephy_embed_load_url (embed, parent_uri); + + g_free (parent_uri); + + return G_OK; +} + +static char * +mozilla_embed_get_uri_parent (const char *aUri) +{ + nsresult rv; + + nsCOMPtr<nsIURI> uri; + rv = NS_NewURI (getter_AddRefs(uri), aUri); + if (NS_FAILED(rv) || !uri) return NULL; + + nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv); + if (NS_FAILED(rv) || !url) return NULL; + + nsCAutoString dirPath; + rv = url->GetDirectory (dirPath); + if (NS_FAILED(rv) || !dirPath.Length()) return NULL; + + nsCAutoString filePath; + rv = url->GetFilePath (filePath); + if (NS_FAILED(rv) || !filePath.Length()) return NULL; + + PRInt32 pathLength = filePath.Length(); + PRInt32 trailingSlash = filePath.RFind("/"); + + if(pathLength < 2 || trailingSlash == -1) + { + return NULL; + } + + if(trailingSlash != (pathLength-1)) + { + uri->SetPath(dirPath); + } + else + { + PRInt32 nextSlash = filePath.RFind("/",PR_FALSE,trailingSlash-1); + nsCAutoString parentPath; + filePath.Left(parentPath, nextSlash); + uri->SetPath(parentPath); + } + + nsCAutoString spec; + uri->GetSpec(spec); + + return !spec.IsEmpty() ? g_strdup(spec.get()) : NULL; +} + +static gresult +impl_render_data (EphyEmbed *embed, + const char *data, + guint32 len, + const char *base_uri, + const char *mime_type) +{ + gtk_moz_embed_render_data (GTK_MOZ_EMBED(embed), + data, + len, + base_uri, + mime_type); + + return G_OK; +} + +static gresult +impl_open_stream (EphyEmbed *embed, + const char *base_uri, + const char *mime_type) +{ + gtk_moz_embed_open_stream (GTK_MOZ_EMBED(embed), + base_uri, mime_type); + + return G_OK; +} + +static gresult +impl_append_data (EphyEmbed *embed, + const char *data, + guint32 len) +{ + gtk_moz_embed_append_data (GTK_MOZ_EMBED(embed), + data, len); + + return G_OK; +} + +static gresult +impl_close_stream (EphyEmbed *embed) +{ + gtk_moz_embed_close_stream (GTK_MOZ_EMBED(embed)); + + return G_OK; +} + +static gresult +impl_get_title (EphyEmbed *embed, + char **title) +{ + nsXPIDLString uTitle; + + *getter_Copies(uTitle) = + gtk_moz_embed_get_title_unichar (GTK_MOZ_EMBED(embed)); + + *title = g_strdup (NS_ConvertUCS2toUTF8(uTitle).get()); + + return G_OK; +} + +static gresult +impl_get_location (EphyEmbed *embed, + gboolean toplevel, + gboolean requested, + char **location) +{ + char *l; + nsresult rv; + nsCAutoString url; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + + /* if the wrapper is NULL than we have no location, + * in fact the wrapper is initialized on net start */ + if (!wrapper) + { + *location = NULL; + return G_FAILED; + } + + /* FIXME !toplevel requested not implemented */ + + if (toplevel) + { + l = gtk_moz_embed_get_location + (GTK_MOZ_EMBED(embed)); + } + else if (!toplevel) + { + rv = wrapper->GetDocumentUrl (url); + l = (NS_SUCCEEDED (rv) && !url.IsEmpty()) ? + g_strdup (url.get()) : NULL; + } + else if (requested) + { + rv = wrapper->GetRealURL (url); + l = (NS_SUCCEEDED (rv) && !url.IsEmpty()) ? + g_strdup (url.get()) : NULL; + } + + *location = l; + + return G_OK; +} + +static gresult +impl_reload (EphyEmbed *embed, + EmbedReloadFlags flags) +{ + guint32 mflags; + + mflags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL; + + if ((flags & EMBED_RELOAD_BYPASSCACHE) && + (flags & EMBED_RELOAD_BYPASSPROXY)) + { + mflags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE; + } + else if (flags & EMBED_RELOAD_BYPASSCACHE) + { + mflags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE; + } + else if (flags & EMBED_RELOAD_BYPASSPROXY) + { + mflags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY; + } + + gtk_moz_embed_reload (GTK_MOZ_EMBED(embed), + mflags); + + return G_OK; +} + +static gresult +impl_copy_page (EphyEmbed *dest, + EphyEmbed *source, + EmbedDisplayType display_type) +{ + EphyWrapper *dWrapper; + dWrapper = MOZILLA_EMBED(dest)->priv->wrapper; + g_return_val_if_fail (dWrapper != NULL, G_FAILED); + + EphyWrapper *sWrapper; + sWrapper = MOZILLA_EMBED(source)->priv->wrapper; + g_return_val_if_fail (sWrapper != NULL, G_FAILED); + + nsresult rv; + + nsCOMPtr<nsISupports> pageDescriptor; + rv = sWrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor)); + if (!pageDescriptor || NS_FAILED(rv)) return G_FAILED; + + rv = dWrapper->LoadDocument(pageDescriptor, static_cast<PRUint32>(display_type)); + if (NS_FAILED(rv)) return G_FAILED; + + return G_OK; +} + +static gresult +impl_grab_focus (EphyEmbed *embed) +{ + gtk_widget_grab_focus (GTK_BIN (embed)->child); + + return G_OK; +} + +static gresult +impl_get_link_tags (EphyEmbed *embed, + const char *link_type, + GList **tags) +{ + return G_NOT_IMPLEMENTED; +} + +static gresult +impl_zoom_set (EphyEmbed *embed, + int zoom, + gboolean reflow) +{ + EphyWrapper *wrapper; + nsresult result; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + result = wrapper->SetZoom ((float)(zoom) / 100, reflow); + + if (NS_SUCCEEDED (result)) + { + g_signal_emit_by_name (embed, "ge_zoom_change", zoom); + } + + return NS_SUCCEEDED(result) ? G_OK : G_FAILED; +} + +static gresult +impl_zoom_get (EphyEmbed *embed, + int *zoom) +{ + float f; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + if (!wrapper) + { + *zoom = 100; + return G_OK; + } + + nsresult result = wrapper->GetZoom (&f); + + if (NS_SUCCEEDED (result)) + { + *zoom = (int) rint (f * 100); + + return G_OK; + } + else + { + return G_FAILED; + } +} + +static gresult +impl_selection_can_cut (EphyEmbed *embed) +{ + gboolean result; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + wrapper->CanCutSelection (&result); + + return result ? G_OK : G_FAILED; +} + +static gresult +impl_selection_can_copy (EphyEmbed *embed) +{ + gboolean result; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + wrapper->CanCopySelection (&result); + + return result ? G_OK : G_FAILED; +} + +static gresult +impl_can_paste (EphyEmbed *embed) +{ + gboolean result; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + wrapper->CanPaste (&result); + + return result ? G_OK : G_FAILED; +} + +static gresult +impl_select_all (EphyEmbed *embed) +{ + nsresult result; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + result = wrapper->SelectAll (); + + return result ? G_OK : G_FAILED; +} + +static gresult +impl_selection_cut (EphyEmbed *embed) +{ + nsresult rv; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->CutSelection (); + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_selection_copy (EphyEmbed *embed) +{ + nsresult rv; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->CopySelection (); + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_paste (EphyEmbed *embed) +{ + nsresult rv; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->Paste (); + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_shistory_count (EphyEmbed *embed, + int *count) +{ + nsresult rv; + EphyWrapper *wrapper; + int c, index; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->GetSHInfo (&c, &index); + + *count = c; + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_shistory_get_nth (EphyEmbed *embed, + int nth, + gboolean is_relative, + char **aUrl, + char **aTitle) +{ + nsresult rv; + nsCAutoString url; + PRUnichar *title; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + if (is_relative) + { + int pos; + + if (ephy_embed_shistory_get_pos + (EPHY_EMBED(embed), &pos) == G_OK) + { + pos += nth; + } + else + { + return G_FAILED; + } + } + + rv = wrapper->GetSHUrlAtIndex(nth, url); + + *aUrl = (NS_SUCCEEDED (rv) && !url.IsEmpty()) ? g_strdup(url.get()) : NULL; + + rv = wrapper->GetSHTitleAtIndex(nth, &title); + + *aTitle = g_strdup (NS_ConvertUCS2toUTF8(title).get()); + + return G_OK; +} + +static gresult +impl_shistory_get_pos (EphyEmbed *embed, + int *pos) +{ + nsresult rv; + EphyWrapper *wrapper; + int count, index; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->GetSHInfo (&count, &index); + + *pos = index; + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_shistory_go_nth (EphyEmbed *embed, + int nth) +{ + nsresult rv; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + rv = wrapper->GoToHistoryIndex (nth); + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gboolean +impl_shistory_copy (EphyEmbed *source, + EphyEmbed *dest) +{ + nsresult rv; + EphyWrapper *s_wrapper; + EphyWrapper *d_wrapper; + + s_wrapper = MOZILLA_EMBED(source)->priv->wrapper; + g_return_val_if_fail (s_wrapper != NULL, G_FAILED); + + d_wrapper = MOZILLA_EMBED(dest)->priv->wrapper; + g_return_val_if_fail (d_wrapper != NULL, G_FAILED); + + rv = s_wrapper->CopyHistoryTo (d_wrapper); + + return NS_SUCCEEDED(rv) ? G_OK : G_FAILED; +} + +static gresult +impl_scroll (EphyEmbed *embed, + EmbedScrollDirection direction) +{ + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + switch (direction) + { + case EMBED_SCROLL_UP: + wrapper->ScrollUp (); + break; + case EMBED_SCROLL_DOWN: + wrapper->ScrollDown (); + break; + case EMBED_SCROLL_LEFT: + wrapper->ScrollLeft (); + break; + case EMBED_SCROLL_RIGHT: + wrapper->ScrollRight (); + break; + } + + return G_OK; +} + +static gresult +impl_fine_scroll (EphyEmbed *embed, int horiz, int vert) +{ + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + wrapper->FineScroll (horiz, vert); + + return G_OK; +} + +static gresult +impl_get_security_level (EphyEmbed *embed, + EmbedSecurityLevel *level, + char **description) +{ + nsresult result; + + nsCOMPtr<nsIChannel> channel; + channel = do_QueryInterface (MOZILLA_EMBED(embed)->priv->request, + &result); + if (NS_FAILED (result)) return G_FAILED; + + nsCOMPtr<nsISupports> info; + result = channel->GetSecurityInfo(getter_AddRefs(info)); + if (NS_FAILED (result)) return G_FAILED; + + *description = NULL; + if (info) + { + nsCOMPtr<nsITransportSecurityInfo> secInfo(do_QueryInterface(info)); + if (!secInfo) return G_FAILED; + + nsXPIDLString tooltip; + result = secInfo->GetShortSecurityDescription(getter_Copies(tooltip)); + if (NS_FAILED (result)) return G_FAILED; + + if (tooltip) + { + const nsString &string = nsString(tooltip); + char *tmp; + tmp = ToNewCString (string); + + *description = g_strdup (tmp); + + nsMemory::Free (tmp); + } + } + + *level = mozilla_embed_security_level (MOZILLA_EMBED (embed)); + return G_OK; +} + +static gresult +impl_print (EphyEmbed *embed, + EmbedPrintInfo *info) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + nsCOMPtr<nsIPrintSettings> options; + result = wrapper->GetPrintSettings(getter_AddRefs(options)); + g_assert (NS_SUCCEEDED (result)); + + MozillaCollatePrintSettings(info, options); + + options->SetPrintSilent (PR_TRUE); + + result = wrapper->Print(options, info->preview); + + return NS_SUCCEEDED (result) ? G_OK : G_FAILED; +} + +static gresult +impl_print_preview_close (EphyEmbed *embed) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + result = wrapper->PrintPreviewClose(); + return NS_SUCCEEDED(result) ? G_OK : G_FAILED; +} + +static gresult +impl_print_preview_num_pages (EphyEmbed *embed, + gint *retNum) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + result = wrapper->PrintPreviewNumPages(retNum); + return NS_SUCCEEDED(result) ? G_OK : G_FAILED; +} + +static gresult +impl_print_preview_navigate (EphyEmbed *embed, + EmbedPrintPreviewNavType navType, + gint pageNum) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + result = wrapper->PrintPreviewNavigate(navType, pageNum); + return NS_SUCCEEDED(result) ? G_OK : G_FAILED; +} + +static gresult +impl_find (EphyEmbed *embed, + EmbedFindInfo *info) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + PRBool didFind; + + result = wrapper->Find ((NS_ConvertUTF8toUCS2(info->search_string)).get(), + info->interactive, + info->match_case, + info->backwards, info->wrap, + info->entire_word, info->search_frames, + &didFind); + + return didFind ? G_OK : G_FAILED; +} + +static gresult +impl_set_charset (EphyEmbed *embed, + const char *charset) +{ + nsresult result = NS_OK; + EphyWrapper *wrapper; + char *cset; + + cset = g_strdup (charset); + + wrapper = MOZILLA_EMBED(embed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + wrapper->ForceCharacterSet (cset); + + g_free (cset); + + return NS_SUCCEEDED(result) ? G_OK : G_FAILED; +} + +static void +mozilla_embed_location_changed_cb (GtkMozEmbed *embed, + MozillaEmbed *membed) +{ + /* Do not emit signal if we are loading the + * fallback about:blank. We dont want the user + * to know about it. */ + if (membed->priv->no_page != 0) + { + g_signal_emit_by_name (membed, "ge_location"); + } + + membed->priv->no_page = -1; +} + +static void +mozilla_embed_title_changed_cb (GtkMozEmbed *embed, + MozillaEmbed *membed) +{ + g_return_if_fail (IS_MOZILLA_EMBED (membed)); + g_return_if_fail (GTK_IS_WIDGET (embed)); + g_signal_emit_by_name (membed, "ge_title"); +} + +static void +mozilla_embed_net_state_all_cb (GtkMozEmbed *embed, const char *aURI, + gint state, guint status, + MozillaEmbed *membed) +{ + EmbedState estate = EMBED_STATE_UNKNOWN; + int i; + + struct + { + guint state; + EmbedState embed_state; + } + conversion_map [] = + { + { GTK_MOZ_EMBED_FLAG_START, EMBED_STATE_START }, + { GTK_MOZ_EMBED_FLAG_STOP, EMBED_STATE_STOP }, + { GTK_MOZ_EMBED_FLAG_REDIRECTING, EMBED_STATE_REDIRECTING }, + { GTK_MOZ_EMBED_FLAG_TRANSFERRING, EMBED_STATE_TRANSFERRING }, + { GTK_MOZ_EMBED_FLAG_NEGOTIATING, EMBED_STATE_NEGOTIATING }, + { GTK_MOZ_EMBED_FLAG_IS_REQUEST, EMBED_STATE_IS_REQUEST }, + { GTK_MOZ_EMBED_FLAG_IS_DOCUMENT, EMBED_STATE_IS_DOCUMENT }, + { GTK_MOZ_EMBED_FLAG_IS_NETWORK, EMBED_STATE_IS_NETWORK }, + { 0, EMBED_STATE_UNKNOWN } + }; + + /* No page loaded, default to about:blank */ + if (membed->priv->no_page > 0 && + (state & GTK_MOZ_EMBED_FLAG_STOP) && + (state & GTK_MOZ_EMBED_FLAG_IS_DOCUMENT)) + { + ephy_embed_load_url (EPHY_EMBED(membed), "about:blank"); + membed->priv->no_page = 0; + } + + if (!membed->priv->wrapper) + { + membed->priv->wrapper = new EphyWrapper (); + + nsresult result; + result = membed->priv->wrapper->Init (GTK_MOZ_EMBED(embed)); + if (NS_FAILED(result)) + { + g_warning ("Wrapper initialization failed"); + } + } + + for (i = 0; conversion_map[i].state != 0; i++) + { + if (state & conversion_map[i].state) + { + estate = (EmbedState) (estate | conversion_map[i].embed_state); + } + } + + g_signal_emit_by_name (membed, "ge_net_state", aURI, estate); +} + +static void +mozilla_embed_progress_cb (GtkMozEmbed *embed, const char *aURI, + gint curprogress, gint maxprogress, + MozillaEmbed *membed) +{ + g_signal_emit_by_name (membed, "ge_progress", aURI, + curprogress, maxprogress); +} + +static void +mozilla_embed_link_message_cb (GtkMozEmbed *embed, + MozillaEmbed *membed) +{ + nsXPIDLString message; + + *getter_Copies(message) = gtk_moz_embed_get_link_message_unichar (embed); + + g_signal_emit_by_name (membed, "ge_link_message", + g_strdup(NS_ConvertUCS2toUTF8(message).get())); +} + +static void +mozilla_embed_js_status_cb (GtkMozEmbed *embed, + MozillaEmbed *membed) +{ + nsXPIDLString status; + + *getter_Copies(status) = gtk_moz_embed_get_js_status_unichar (embed); + + g_signal_emit_by_name (membed, "ge_js_status", + g_strdup(NS_ConvertUCS2toUTF8(status).get())); +} + +static void +mozilla_embed_visibility_cb (GtkMozEmbed *embed, gboolean visibility, + MozillaEmbed *membed) +{ + g_signal_emit_by_name (membed, "ge_visibility", visibility); + + nsresult rv; + nsCOMPtr<nsIWindowWatcher> wwatch + (do_GetService(WINDOWWATCHER_CONTRACTID, &rv)); + if (NS_FAILED(rv) || !wwatch) return; + + EphyWrapper *wrapper = (EphyWrapper *)mozilla_embed_get_galeon_wrapper(membed); + if(!wrapper) return; + + nsCOMPtr<nsIDOMWindow> domWindow; + rv = wrapper->GetDOMWindow(getter_AddRefs(domWindow)); + if(NS_FAILED(rv) || !domWindow) return; + + rv = wwatch->SetActiveWindow(domWindow); +} + +static void +mozilla_embed_destroy_brsr_cb (GtkMozEmbed *embed, + MozillaEmbed *membed) +{ + g_signal_emit_by_name (membed, "ge_destroy_brsr"); +} + +static gint +mozilla_embed_dom_mouse_click_cb (GtkMozEmbed *embed, gpointer dom_event, + MozillaEmbed *membed) +{ + EphyEmbedEvent *info; + EventContext event_context; + gint return_value = 0; + EphyWrapper *wrapper; + nsresult result; + + info = ephy_embed_event_new (); + + wrapper = MOZILLA_EMBED(membed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + event_context.Init ((nsIDOMEvent*)dom_event, wrapper); + result = event_context.GetMouseEventInfo (info); + + nsCOMPtr<nsIDOMDocument> domDoc; + result = event_context.GetTargetDocument (getter_AddRefs(domDoc)); + if (NS_SUCCEEDED(result)) + { + result = wrapper->PushTargetDocument (domDoc); + } + + g_signal_emit_by_name (membed, "ge_dom_mouse_click", info, &return_value); + + wrapper->PopTargetDocument (); + + g_object_unref (info); + + return return_value; +} + +static gint +mozilla_embed_dom_mouse_down_cb (GtkMozEmbed *embed, gpointer dom_event, + MozillaEmbed *membed) +{ + EphyEmbedEvent *info; + EventContext event_context; + gint return_value = 0; + EphyWrapper *wrapper; + nsresult result; + + info = ephy_embed_event_new (); + + wrapper = MOZILLA_EMBED(membed)->priv->wrapper; + g_return_val_if_fail (wrapper != NULL, G_FAILED); + + event_context.Init ((nsIDOMEvent*)dom_event, wrapper); + result = event_context.GetMouseEventInfo (info); + if (NS_SUCCEEDED(result)) + { + nsCOMPtr<nsIDOMDocument> domDoc; + result = event_context.GetTargetDocument (getter_AddRefs(domDoc)); + if (NS_SUCCEEDED(result)) + { + result = wrapper->PushTargetDocument (domDoc); + if (NS_SUCCEEDED(result)) + { + g_signal_emit_by_name (membed, "ge_dom_mouse_down", + info, &return_value); + wrapper->PopTargetDocument (); + } + } + + } + + g_object_unref (info); + + return return_value; +} + +static void +mozilla_embed_size_to_cb (GtkMozEmbed *embed, gint width, gint height, + MozillaEmbed *membed) +{ + g_signal_emit_by_name (membed, "ge_size_to", width, height); +} + +static void +mozilla_embed_new_window_cb (GtkMozEmbed *embed, + GtkMozEmbed **newEmbed, + guint chromemask, + MozillaEmbed *membed) +{ + int i; + EmbedChromeMask mask = EMBED_CHROME_OPENASPOPUP; + EphyEmbed *new_embed = NULL; + + struct + { + guint chromemask; + EmbedChromeMask embed_mask; + } + conversion_map [] = + { + { GTK_MOZ_EMBED_FLAG_DEFAULTCHROME, EMBED_CHROME_DEFAULT }, + { GTK_MOZ_EMBED_FLAG_MENUBARON, EMBED_CHROME_MENUBARON }, + { GTK_MOZ_EMBED_FLAG_TOOLBARON, EMBED_CHROME_TOOLBARON }, + { GTK_MOZ_EMBED_FLAG_PERSONALTOOLBARON, EMBED_CHROME_PERSONALTOOLBARON }, + { GTK_MOZ_EMBED_FLAG_STATUSBARON, EMBED_CHROME_STATUSBARON }, + { GTK_MOZ_EMBED_FLAG_WINDOWRAISED, EMBED_CHROME_WINDOWRAISED }, + { GTK_MOZ_EMBED_FLAG_WINDOWLOWERED, EMBED_CHROME_WINDOWLOWERED }, + { GTK_MOZ_EMBED_FLAG_CENTERSCREEN, EMBED_CHROME_CENTERSCREEN }, + { GTK_MOZ_EMBED_FLAG_OPENASDIALOG, EMBED_CHROME_OPENASDIALOG }, + { GTK_MOZ_EMBED_FLAG_OPENASCHROME, EMBED_CHROME_OPENASCHROME }, + { 0, EMBED_CHROME_NONE } + }; + + for (i = 0; conversion_map[i].chromemask != 0; i++) + { + if (chromemask & conversion_map[i].chromemask) + { + mask = (EmbedChromeMask) (mask | conversion_map[i].embed_mask); + } + } + + g_signal_emit_by_name (membed, "ge_new_window", &new_embed, mask); + + g_assert (new_embed != NULL); + + *newEmbed = GTK_MOZ_EMBED(new_embed); +} + +static void +mozilla_embed_security_change_cb (GtkMozEmbed *embed, + gpointer request, + guint state, + MozillaEmbed *membed) +{ + EmbedSecurityLevel level; + + membed->priv->request = (nsIRequest *) request; + membed->priv->security_state = state; + level = mozilla_embed_security_level (membed); + + g_signal_emit_by_name (membed, "ge_security_change", level); +} + +static EmbedSecurityLevel +mozilla_embed_security_level (MozillaEmbed *membed) +{ + EmbedSecurityLevel level; + + switch (membed->priv->security_state) + { + case nsIWebProgressListener::STATE_IS_INSECURE: + level = STATE_IS_INSECURE; + break; + case nsIWebProgressListener::STATE_IS_BROKEN: + level = STATE_IS_BROKEN; + break; + case nsIWebProgressListener::STATE_IS_SECURE| + nsIWebProgressListener::STATE_SECURE_HIGH: + level = STATE_IS_SECURE_HIGH; + break; + case nsIWebProgressListener::STATE_IS_SECURE| + nsIWebProgressListener::STATE_SECURE_MED: + level = STATE_IS_SECURE_MED; + break; + case nsIWebProgressListener::STATE_IS_SECURE| + nsIWebProgressListener::STATE_SECURE_LOW: + level = STATE_IS_SECURE_LOW; + break; + default: + level = STATE_IS_UNKNOWN; + break; + } + return level; +} + diff --git a/embed/mozilla/mozilla-embed.h b/embed/mozilla/mozilla-embed.h new file mode 100644 index 000000000..b8ebca4c8 --- /dev/null +++ b/embed/mozilla/mozilla-embed.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_EMBED_H +#define MOZILLA_EMBED_H + +#include "ephy-embed-types.h" +#include "ephy-embed.h" + +#include <gtkmozembed.h> + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct MozillaEmbedClass MozillaEmbedClass; + +#define MOZILLA_EMBED_TYPE (mozilla_embed_get_type ()) +#define MOZILLA_EMBED(obj) (GTK_CHECK_CAST ((obj), MOZILLA_EMBED_TYPE, MozillaEmbed)) +#define MOZILLA_EMBED_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), MOZILLA_EMBED_TYPE, MozillaEmbedClass)) +#define IS_MOZILLA_EMBED(obj) (GTK_CHECK_TYPE ((obj), MOZILLA_EMBED_TYPE)) +#define IS_MOZILLA_EMBED_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), MOZILLA_EMBED)) +#define MOZILLA_EMBED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MOZILLA_EMBED_TYPE, MozillaEmbedClass)) + +typedef struct MozillaEmbed MozillaEmbed; +typedef struct MozillaEmbedPrivate MozillaEmbedPrivate; + +struct MozillaEmbed +{ + GtkMozEmbed parent; + MozillaEmbedPrivate *priv; +}; + +struct MozillaEmbedClass +{ + GtkMozEmbedClass parent_class; +}; + +GType mozilla_embed_get_type (void); + +gpointer mozilla_embed_get_galeon_wrapper (MozillaEmbed *embed); + +G_END_DECLS + +#endif diff --git a/embed/mozilla/mozilla-i18n.c b/embed/mozilla/mozilla-i18n.c new file mode 100644 index 000000000..c974d9765 --- /dev/null +++ b/embed/mozilla/mozilla-i18n.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "mozilla-i18n.h" + +#include <libgnome/gnome-i18n.h> + +const char *lgroups[] = { + N_("Arabic"), + N_("Baltic"), + N_("Central European"), + N_("Chinese"), + N_("Cyrillic"), + N_("Greek"), + N_("Hebrew"), + N_("Indian"), + N_("Japanese"), + N_("Korean"), + N_("Turkish"), + N_("Unicode"), + N_("Vietnamese"), + N_("Western"), + N_("Other"), + NULL +}; + +const CharsetInfoPriv charset_trans_array[] = { + {N_("Arabic (IBM-864)"), "IBM864", LG_ARABIC}, + {N_("Arabic (IBM-864-I)"), "IBM864i", LG_ARABIC}, + {N_("Arabic (ISO-8859-6)"), "ISO-8859-6", LG_ARABIC}, + {N_("Arabic (ISO-8859-6-E)"), "ISO-8859-6-E", LG_ARABIC}, + {N_("Arabic (ISO-8859-6-I)"), "ISO-8859-6-I", LG_ARABIC}, + {N_("Arabic (MacArabic)"), "x-mac-arabic", LG_ARABIC}, + {N_("Arabic (Windows-1256)"), "windows-1256", LG_ARABIC}, + {N_("Armenian (ARMSCII-8)"), "armscii-8", LG_OTHER}, + {N_("Baltic (ISO-8859-13)"), "ISO-8859-13", LG_BALTIC}, + {N_("Baltic (ISO-8859-4)"), "ISO-8859-4", LG_BALTIC}, + {N_("Baltic (Windows-1257)"), "windows-1257", LG_BALTIC}, + {N_("Celtic (ISO-8859-14)"), "ISO-8859-14", LG_OTHER}, + {N_("Central European (IBM-852)"), "IBM852", LG_CENTRAL_EUROPEAN}, + {N_("Central European (ISO-8859-2)"), "ISO-8859-2", LG_CENTRAL_EUROPEAN}, + {N_("Central European (MacCE)"), "x-mac-ce", LG_CENTRAL_EUROPEAN}, + {N_("Central European (Windows-1250)"), "windows-1250", LG_CENTRAL_EUROPEAN}, + {N_("Chinese Simplified (GB18030)"), "gb18030", LG_CHINESE}, + {N_("Chinese Simplified (GB2312)"), "GB2312", LG_CHINESE}, + {N_("Chinese Simplified (GBK)"), "x-gbk", LG_CHINESE}, + {N_("Chinese Simplified (HZ)"), "HZ-GB-2312", LG_CHINESE}, + {N_("Chinese Simplified (Windows-936)"), "windows-936", LG_CHINESE}, + {N_("Chinese Traditional (Big5)"), "Big5", LG_CHINESE}, + {N_("Chinese Traditional (Big5-HKSCS)"), "Big5-HKSCS", LG_CHINESE}, + {N_("Chinese Traditional (EUC-TW)"), "x-euc-tw", LG_CHINESE}, + {N_("Croatian (MacCroatian)"), "x-mac-croatian", LG_CENTRAL_EUROPEAN}, + {N_("Cyrillic (IBM-855)"), "IBM855", LG_CYRILLIC}, + {N_("Cyrillic (ISO-8859-5)"), "ISO-8859-5", LG_CYRILLIC}, + {N_("Cyrillic (ISO-IR-111)"), "ISO-IR-111", LG_CYRILLIC}, + {N_("Cyrillic (KOI8-R)"), "KOI8-R", LG_CYRILLIC}, + {N_("Cyrillic (MacCyrillic)"), "x-mac-cyrillic", LG_CYRILLIC}, + {N_("Cyrillic (Windows-1251)"), "windows-1251", LG_CYRILLIC}, + {N_("Cyrillic/Russian (CP-866)"), "IBM866", LG_CYRILLIC}, + {N_("Cyrillic/Ukrainian (KOI8-U)"), "KOI8-U", LG_CYRILLIC}, + {N_("Cyrillic/Ukrainian (MacUkrainian)"), "x-mac-ukrainian", LG_CYRILLIC}, + {N_("English (US-ASCII)"), "us-ascii", LG_WESTERN}, + {N_("Farsi (MacFarsi)"), "x-mac-farsi", LG_OTHER}, + {N_("Georgian (GEOSTD8)"), "geostd8", LG_OTHER}, + {N_("Greek (ISO-8859-7)"), "ISO-8859-7", LG_GREEK}, + {N_("Greek (MacGreek)"), "x-mac-greek", LG_GREEK}, + {N_("Greek (Windows-1253)"), "windows-1253", LG_GREEK}, + {N_("Gujarati (MacGujarati)"), "x-mac-gujarati", LG_INDIAN}, + {N_("Gurmukhi (MacGurmukhi)"), "x-mac-gurmukhi", LG_INDIAN}, + {N_("Hebrew (IBM-862)"), "IBM862", LG_HEBREW}, + {N_("Hebrew (ISO-8859-8-E)"), "ISO-8859-8-E", LG_HEBREW}, + {N_("Hebrew (ISO-8859-8-I)"), "ISO-8859-8-I", LG_HEBREW}, + {N_("Hebrew (MacHebrew)"), "x-mac-hebrew", LG_HEBREW}, + {N_("Hebrew (Windows-1255)"), "windows-1255", LG_HEBREW}, + {N_("Hindi (MacDevanagari)"), "x-mac-devanagari", LG_INDIAN}, + {N_("Icelandic (MacIcelandic)"), "x-mac-icelandic", LG_OTHER}, + {N_("Japanese (EUC-JP)"), "EUC-JP", LG_JAPANESE}, + {N_("Japanese (ISO-2022-JP)"), "ISO-2022-JP", LG_JAPANESE}, + {N_("Japanese (Shift_JIS)"), "Shift_JIS", LG_JAPANESE}, + {N_("Korean (EUC-KR)"), "EUC-KR", LG_KOREAN}, + {N_("Korean (ISO-2022-KR)"), "ISO-2022-KR", LG_KOREAN}, + {N_("Korean (JOHAB)"), "x-johab", LG_KOREAN}, + {N_("Korean (UHC)"), "x-windows-949", LG_KOREAN}, + {N_("Nordic (ISO-8859-10)"), "ISO-8859-10", LG_OTHER}, + {N_("Romanian (MacRomanian)"), "x-mac-romanian", LG_OTHER}, + {N_("Romanian (ISO-8859-16)"), "ISO-8859-16", LG_OTHER}, + {N_("South European (ISO-8859-3)"), "ISO-8859-3", LG_OTHER}, + {N_("Thai (TIS-620)"), "TIS-620", LG_OTHER}, + {N_("Turkish (IBM-857)"), "IBM857", LG_TURKISH}, + {N_("Turkish (ISO-8859-9)"), "ISO-8859-9", LG_TURKISH}, + {N_("Turkish (MacTurkish)"), "x-mac-turkish", LG_TURKISH}, + {N_("Turkish (Windows-1254)"), "windows-1254", LG_TURKISH}, + {N_("Unicode (UTF-7)"), "UTF-7", LG_UNICODE}, + {N_("Unicode (UTF-8)"), "UTF-8", LG_UNICODE}, + {N_("Unicode (UTF-16BE)"), "UTF-16BE", LG_UNICODE}, + {N_("Unicode (UTF-16LE)"), "UTF-16LE", LG_UNICODE}, + {N_("Unicode (UTF-32BE)"), "UTF-32BE", LG_UNICODE}, + {N_("Unicode (UTF-32LE)"), "UTF-32LE", LG_UNICODE}, + {N_("User Defined"), "x-user-defined", LG_OTHER}, + {N_("Vietnamese (TCVN)"), "x-viet-tcvn5712", LG_VIETNAMESE}, + {N_("Vietnamese (VISCII)"), "VISCII", LG_VIETNAMESE}, + {N_("Vietnamese (VPS)"), "x-viet-vps", LG_VIETNAMESE}, + {N_("Vietnamese (Windows-1258)"), "windows-1258", LG_VIETNAMESE}, + {N_("Visual Hebrew (ISO-8859-8)"), "ISO-8859-8", LG_HEBREW}, + {N_("Western (IBM-850)"), "IBM850", LG_WESTERN}, + {N_("Western (ISO-8859-1)"), "ISO-8859-1", LG_WESTERN}, + {N_("Western (ISO-8859-15)"), "ISO-8859-15", LG_WESTERN}, + {N_("Western (MacRoman)"), "x-mac-roman", LG_WESTERN}, + {N_("Western (Windows-1252)"), "windows-1252", LG_WESTERN}, + /* charsets whithout posibly translatable names */ + {"T61.8bit", "T61.8bit", LG_OTHER}, + {"x-imap4-modified-utf7", "x-imap4-modified-utf7", LG_UNICODE}, + {"x-u-escaped", "x-u-escaped", LG_OTHER} +}; + +const gchar *lang_encode_item[LANG_ENC_NUM] = +{ + "x-western", + "x-central-euro", + "ja", + "zh-TW", + "zh-CN", + "ko", + "x-cyrillic", + "x-baltic", + "el", + "tr", + "x-unicode", + "th", + "he", + "ar" +}; + +const gchar *font_types[] = +{ + "serif", + "sans-serif", + "cursive", + "fantasy", + "monospace" +}; + +extern gint +get_translated_cscount(void) +{ + return sizeof (charset_trans_array) / sizeof ((charset_trans_array)[0]); +} diff --git a/embed/mozilla/mozilla-i18n.h b/embed/mozilla/mozilla-i18n.h new file mode 100644 index 000000000..5b5dbc321 --- /dev/null +++ b/embed/mozilla/mozilla-i18n.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2000 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include <glib.h> + +G_BEGIN_DECLS + +#define LANG_ENC_NUM 14 + +typedef enum { + LG_ARABIC, + LG_BALTIC, + LG_CENTRAL_EUROPEAN, + LG_CHINESE, + LG_CYRILLIC, + LG_GREEK, + LG_HEBREW, + LG_INDIAN, + LG_JAPANESE, + LG_KOREAN, + LG_TURKISH, + LG_UNICODE, + LG_VIETNAMESE, + LG_WESTERN, + LG_OTHER +} LanguageGroup; + +typedef struct { + char *charset_title; + char *charset_name; + LanguageGroup lgroup; +} CharsetInfoPriv; + +/* language groups names */ +extern const char *lgroups[]; +/* translated charset titles */ +extern const CharsetInfoPriv charset_trans_array[]; + +/* FIXME */ +extern const char *lang_encode_name[LANG_ENC_NUM]; +extern const char *lang_encode_item[LANG_ENC_NUM]; + +gint get_translated_cscount (void); + +G_END_DECLS diff --git a/embed/mozilla/mozilla-notifiers.cpp b/embed/mozilla/mozilla-notifiers.cpp new file mode 100644 index 000000000..24dfbb7a5 --- /dev/null +++ b/embed/mozilla/mozilla-notifiers.cpp @@ -0,0 +1,710 @@ +/* + * Copyright (C) 2000 Nate Case + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, OR (AT YOUR OPTION) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "ephy-embed-shell.h" +#include "mozilla-notifiers.h" +#include "eel-gconf-extensions.h" +#include "mozilla-prefs.h" +#include "MozRegisterComponents.h" +#include "ephy-prefs.h" +#include "ephy-embed-prefs.h" +#include "mozilla-i18n.h" + +#include <stdio.h> +#include <string.h> +#include <locale.h> +#include <libgnome/gnome-i18n.h> +#include <stdlib.h> +#include <sys/utsname.h> +#include "nsBuildID.h" + +static void +mozilla_own_colors_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); +static void +mozilla_own_fonts_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +static void +mozilla_animate_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); +static void +generic_mozilla_string_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name); +static void +generic_mozilla_int_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name); +static void +generic_mozilla_bool_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name); +static void +mozilla_allow_popups_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +static void +mozilla_language_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +static void +mozilla_autodetect_charset_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyEmbedShell *shell); + +static void +mozilla_default_font_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +static void +mozilla_proxy_mode_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref); +static void +mozilla_proxy_autoconfig_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref); + +static void +mozilla_user_agent_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +static void +mozilla_default_charset_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyEmbedShell *shell); +static void +mozilla_socks_version_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data); + +/* Keeps the list of the notifiers we installed for mozilla prefs */ +/* to be able to remove them when exiting */ +GList *mozilla_notifiers = NULL; +GList *font_infos = NULL; + +enum +{ + BOOL_PREF, + INT_PREF, + STRING_PREF +}; + +static const struct +{ + char *gconf_key; + guint pref_type; + const char *mozilla_key; +} +conversion_table [] = +{ + { CONF_FILTERING_JAVA_ENABLED, BOOL_PREF, "security.enable_java"}, + { CONF_FILTERING_JAVASCRIPT_ENABLED, BOOL_PREF, "javascript.enabled"}, + { CONF_FILTERING_IMAGE_LOADING_TYPE, INT_PREF, "network.image.imageBehavior"}, + { CONF_RENDERING_BG_COLOR, STRING_PREF, "browser.display.background_color"}, + { CONF_RENDERING_TEXT_COLOR, STRING_PREF, "browser.display.foreground_color"}, + { CONF_RENDERING_UNVISITED_LINKS, STRING_PREF, "browser.anchor_color"}, + { CONF_RENDERING_VISITED_LINKS, STRING_PREF, "browser.visited_color"}, + { CONF_RENDERING_UNDERLINE_LINKS, BOOL_PREF, "browser.underline_anchors"}, + { CONF_NETWORK_PROXY_AUTO_URL, STRING_PREF, "network.proxy.autoconfig_url"}, + { CONF_NETWORK_HTTP_PROXY, STRING_PREF, "network.proxy.http"}, + { CONF_NETWORK_FTP_PROXY, STRING_PREF, "network.proxy.ftp"}, + { CONF_NETWORK_SSL_PROXY, STRING_PREF, "network.proxy.ssl"}, + { CONF_NETWORK_SOCKS_PROXY, STRING_PREF, "network.proxy.socks"}, + { CONF_NETWORK_HTTP_PROXY_PORT, INT_PREF, "network.proxy.http_port"}, + { CONF_NETWORK_FTP_PROXY_PORT, INT_PREF, "network.proxy.ftp_port"}, + { CONF_NETWORK_SSL_PROXY_PORT, INT_PREF, "network.proxy.ssl_port"}, + { CONF_NETWORK_SOCKS_PROXY_PORT, INT_PREF, "network.proxy.socks_port"}, + { CONF_NETWORK_NO_PROXIES_FOR, STRING_PREF, "network.proxy.no_proxies_on"}, + { CONF_NETWORK_MEMORY_CACHE, INT_PREF, "browser.cache.memory.capacity"}, + { CONF_NETWORK_DISK_CACHE, INT_PREF, "browser.cache.disk.capacity"}, + { CONF_NETWORK_CACHE_COMPARE, INT_PREF, "browser.cache.check_doc_frequency"}, + { CONF_PERSISTENT_COOKIE_WARN, BOOL_PREF, "network.cookie.warnAboutCookies"}, + { CONF_PERSISTENT_COOKIES_BEHAVIOR, INT_PREF, "network.cookie.cookieBehavior"}, + { CONF_PERSISTENT_COOKIE_LIFETIME, BOOL_PREF, "network.cookie.lifetime.enabled"}, + { CONF_PERSISTENT_PASSWORDS_SAVE, BOOL_PREF, "signon.rememberSignons"}, + { CONF_RENDERING_USE_SYSTEM_COLORS, BOOL_PREF, "browser.display.use_system_colors"}, + { NULL, 0, NULL } +}; + +static const struct +{ + const char *gconf_key; + GConfClientNotifyFunc func; +} +custom_notifiers [] = +{ + { CONF_NETWORK_USER_AGENT, + (GConfClientNotifyFunc) mozilla_user_agent_notifier }, + { CONF_FILTERING_ANIMATE_TYPE, + (GConfClientNotifyFunc) mozilla_animate_notifier }, + { CONF_RENDERING_USE_OWN_COLORS, + (GConfClientNotifyFunc) mozilla_own_colors_notifier }, + { CONF_RENDERING_USE_OWN_FONTS, + (GConfClientNotifyFunc) mozilla_own_fonts_notifier }, + { CONF_FILTERING_ALLOW_POPUPS, + (GConfClientNotifyFunc) mozilla_allow_popups_notifier }, + { CONF_LANGUAGE_DEFAULT_CHARSET, + (GConfClientNotifyFunc) mozilla_default_charset_notifier }, + { CONF_RENDERING_LANGUAGE, + (GConfClientNotifyFunc) mozilla_language_notifier }, + { CONF_LANGUAGE_AUTODETECT_CHARSET, + (GConfClientNotifyFunc) mozilla_autodetect_charset_notifier }, + { CONF_RENDERING_DEFAULT_FONT, + (GConfClientNotifyFunc) mozilla_default_font_notifier }, + { CONF_NETWORK_SOCKS_PROXY_VERSION, + (GConfClientNotifyFunc) mozilla_socks_version_notifier }, + { CONF_NETWORK_PROXY_MODE, + (GConfClientNotifyFunc) mozilla_proxy_mode_notifier }, + { CONF_NETWORK_PROXY_AUTO_URL, + (GConfClientNotifyFunc) mozilla_proxy_autoconfig_notifier }, + {NULL, NULL} +}; + +static void +mozilla_font_size_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref) +{ + char key[255]; + + sprintf (key, "font.%s", pref); + + mozilla_prefs_set_int (key, gconf_value_get_int(entry->value)); +} + +static void +mozilla_proxy_mode_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref) +{ + const char *mode; + int mozilla_mode = 0; + + mode = gconf_value_get_string(entry->value); + + if (strcmp (mode, "manual") == 0) + { + mozilla_mode = 1; + } + else if (strcmp (mode, "auto") == 0) + { + mozilla_mode = 2; + } + + mozilla_prefs_set_int ("network.proxy.type", mozilla_mode); +} + +static void +mozilla_font_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref) +{ + char key[255]; + + sprintf (key, "font.name.%s", pref); + + mozilla_prefs_set_string (key, gconf_value_get_string(entry->value)); +} + +static void +mozilla_proxy_autoconfig_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + char *pref) +{ + ephy_embed_shell_load_proxy_autoconf + (embed_shell, gconf_value_get_string(entry->value)); +} + +void +mozilla_notifiers_init(MozillaEmbedShell *shell) +{ + int i; + + for (i = 0; conversion_table[i].gconf_key != NULL; i++) + { + GConfClientNotifyFunc func = NULL; + + switch (conversion_table[i].pref_type) + { + case INT_PREF: + func = (GConfClientNotifyFunc) generic_mozilla_int_notifier; + break; + case BOOL_PREF: + func = (GConfClientNotifyFunc) generic_mozilla_bool_notifier; + break; + case STRING_PREF: + func = (GConfClientNotifyFunc) generic_mozilla_string_notifier; + break; + } + + g_assert (func != NULL); + + ephy_notification_add( + conversion_table[i].gconf_key, + func, + (gpointer)conversion_table[i].mozilla_key, + &mozilla_notifiers); + } + + for (i = 0; custom_notifiers[i].gconf_key != NULL; i++) + { + ephy_notification_add( + custom_notifiers[i].gconf_key, + custom_notifiers[i].func, + (gpointer)shell, + &mozilla_notifiers); + } + + /* fonts notifiers */ + for (i = 0; i < LANG_ENC_NUM; i++) + { + int k; + char *types [] = { "serif", "sans-serif", "cursive", "fantasy", "monospace" }; + char key[255]; + char *info; + + for (k = 0; k < 5; k++) + { + info = g_strconcat (types[k], ".", lang_encode_item[i], NULL); + + sprintf (key, "%s_%s_%s", CONF_RENDERING_FONT, + types[k], + lang_encode_item[i]); + ephy_notification_add (key, + (GConfClientNotifyFunc)mozilla_font_notifier, + info, + &mozilla_notifiers); + font_infos = g_list_append (font_infos, info); + } + + sprintf (key, "%s_%s", CONF_RENDERING_FONT_MIN_SIZE, lang_encode_item[i]); + info = g_strconcat ("minimum-size", ".", lang_encode_item[i], NULL); + ephy_notification_add (key, + (GConfClientNotifyFunc)mozilla_font_size_notifier, + info, + &mozilla_notifiers); + font_infos = g_list_append (font_infos, info); + + sprintf (key, "%s_%s", CONF_RENDERING_FONT_FIXED_SIZE, lang_encode_item[i]); + info = g_strconcat ("size.fixed", ".", lang_encode_item[i], NULL); + ephy_notification_add (key, + (GConfClientNotifyFunc)mozilla_font_size_notifier, + info, + &mozilla_notifiers); + font_infos = g_list_append (font_infos, info); + + sprintf (key, "%s_%s", CONF_RENDERING_FONT_VAR_SIZE, lang_encode_item[i]); + info = g_strconcat ("size.variable", ".", lang_encode_item[i], NULL); + ephy_notification_add (key, + (GConfClientNotifyFunc)mozilla_font_size_notifier, + info, + &mozilla_notifiers); + font_infos = g_list_append (font_infos, info); + } +} + +void +mozilla_notifiers_free (void) +{ + GList *l; + + ephy_notification_remove (&mozilla_notifiers); + + for (l = font_infos; l != NULL; l = l->next) + { + g_free (l->data); + } + + g_list_free (font_infos); +} + +void +mozilla_notifiers_set_defaults(void) +{ + GConfClient* client = eel_gconf_client_get_global(); + GConfValue* value; + int i; + + for (i = 0; conversion_table[i].gconf_key != NULL; i++) + { + value = gconf_client_get + (client, conversion_table[i].gconf_key, NULL); + if (value) + { + gconf_client_set (client, + conversion_table[i].gconf_key, + value, NULL); + gconf_value_free (value); + } + } + + for (i = 0; custom_notifiers[i].gconf_key != NULL; i++) + { + value = gconf_client_get + (client, custom_notifiers[i].gconf_key, NULL); + if (value) + { + gconf_client_set (client, + custom_notifiers[i].gconf_key, + value, NULL); + gconf_value_free (value); + } + } +} + +/** + * generic_mozilla_string_notify: update mozilla pref to match epiphany prefs. + * user_data should match the mozilla key + */ +static void +generic_mozilla_string_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name) +{ + const gchar *value; + + /* determine type of gconf key, in order of likelyhood */ + switch (entry->value->type) + { + case GCONF_VALUE_STRING: + value = gconf_value_get_string(entry->value); + if (value) + { + mozilla_prefs_set_string + (pref_name, + gconf_value_get_string(entry->value)); + } + break; + + default: + g_warning("Unsupported variable type"); + } +} + + +/** + * generic_mozilla_int_notify: update mozilla pref to match epiphany prefs. + * user_data should match the mozilla key + */ +static void +generic_mozilla_int_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name) +{ + /* determine type of gconf key, in order of likelyhood */ + switch (entry->value->type) + { + case GCONF_VALUE_INT: mozilla_prefs_set_int(pref_name, + gconf_value_get_int(entry->value)); + break; + case GCONF_VALUE_BOOL: mozilla_prefs_set_boolean(pref_name, + gconf_value_get_bool(entry->value)); + break; + case GCONF_VALUE_STRING: mozilla_prefs_set_string(pref_name, + gconf_value_get_string(entry->value)); + break; + default: g_warning("Unsupported variable type"); + } +} + + +/** + * generic_mozilla_bool_notify: update mozilla pref to match epiphany prefs. + * user_data should match the mozilla key + */ +static void +generic_mozilla_bool_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + const char *pref_name) +{ + /* determine type of gconf key, in order of likelyhood */ + switch (entry->value->type) + { + case GCONF_VALUE_BOOL: mozilla_prefs_set_boolean(pref_name, + gconf_value_get_bool(entry->value)); + break; + case GCONF_VALUE_INT: mozilla_prefs_set_int(pref_name, + gconf_value_get_int(entry->value)); + break; + default: g_warning("Unsupported variable type"); + } +} + +static void +mozilla_default_charset_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyEmbedShell *shell) +{ + /* FIXME */ +} + + +static void +mozilla_own_colors_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + mozilla_prefs_set_boolean("browser.display.use_document_colors", + !gconf_value_get_bool(entry->value)); +} + +static void +mozilla_own_fonts_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + mozilla_prefs_set_int("browser.display.use_document_fonts", + !gconf_value_get_bool(entry->value)); +} + +static void +mozilla_animate_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + static const gchar *type[] = + { + "normal", + "once", + "none" + }; + + mozilla_prefs_set_string ("image.animation_mode", + type[gconf_value_get_int(entry->value)]); +} + +static void +mozilla_allow_popups_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + gboolean new_val = eel_gconf_get_boolean(CONF_FILTERING_ALLOW_POPUPS); + mozilla_prefs_set_boolean ("dom.disable_open_during_load", + !new_val); +} + +static void +mozilla_language_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + gchar *languages; + GSList *language_list ,*cur_lang_list; + + language_list = eel_gconf_get_string_list (CONF_RENDERING_LANGUAGE); + + languages = NULL; + cur_lang_list = language_list; + while (cur_lang_list != NULL) { + char *lang, *tmp; + + lang = g_strdup((char *)cur_lang_list->data); + + if (languages == NULL) + languages = lang; + else { + tmp = languages; + languages = g_strconcat(languages, ",", lang, NULL); + g_free(lang); + g_free(tmp); + } + g_free(cur_lang_list->data); + cur_lang_list = cur_lang_list->next; + } + + if (languages == NULL) + { + languages = g_strdup (""); + } + + mozilla_prefs_set_string ("intl.accept_languages", languages); + g_free (languages); + + g_slist_free(language_list); +} + +static char *autodetect_charset_prefs[] = +{ + "", + "zh_parallel_state_machine", + "cjk_parallel_state_machine", + "ja_parallel_state_machine", + "ko_parallel_state_machine", + "ruprob", + "zhcn_parallel_state_machine", + "zhtw_parallel_state_machine", + "ukprob" +}; + +static void +mozilla_autodetect_charset_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + EphyEmbedShell *shell) +{ + int charset = eel_gconf_get_integer (CONF_LANGUAGE_AUTODETECT_CHARSET); + if (charset < 0 || + charset >= (int)(sizeof(autodetect_charset_prefs) + / sizeof(autodetect_charset_prefs[0]))) + { + g_warning ("mozilla_autodetect_charset_notifier: " + "unsupported value: %d", charset); + return; + } + mozilla_prefs_set_string ("intl.charset.detector", + autodetect_charset_prefs[charset]); +} + +static void +mozilla_default_font_notifier(GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + const gchar *font_types [] = {"serif","sans-serif"}; + int default_font; + + default_font = eel_gconf_get_integer (CONF_RENDERING_DEFAULT_FONT); + if (default_font < 0 || + default_font >= (int)(sizeof(font_types) / sizeof(font_types[0]))) + { + g_warning ("mozilla_default_font_notifier: " + "unsupported value: %d", default_font); + return; + } + mozilla_prefs_set_string ("font.default", font_types[default_font]); +} + +static void +mozilla_prefs_set_user_agent () +{ + static gchar *default_user_agent = NULL; + gchar *value; + gchar *user_agent = NULL; + struct utsname name; + gchar *system; + + if (!default_user_agent) + { + if (uname (&name) == 0) + { + system = g_strdup_printf ("%s %s", + name.sysname, + name.machine); + } + else + { + system = g_strdup ("Unknown"); + } + + default_user_agent = g_strdup_printf + ("Mozilla/5.0 Ephy/" VERSION " (X11; %s; U;) Gecko/%d", + system, + NS_BUILD_ID/100); + + g_free (system); + } + + value = eel_gconf_get_string (CONF_NETWORK_USER_AGENT); + + /* now, build a valid user agent string */ + if (!value || !strcmp ("", value) + || !strcmp ("default", value) + || !strcmp ("Ephy", value) + || !strcmp (_("Default (recommended)"), value) + || !strcmp ("Default (recommended)", value)) + { + user_agent = g_strdup (default_user_agent); + } + else + { + user_agent = g_strdup (value); + } + + mozilla_prefs_set_string ("general.useragent.override", user_agent); + g_free (user_agent); +} + +static void +mozilla_user_agent_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + switch (entry->value->type) + { + case GCONF_VALUE_STRING: + mozilla_prefs_set_user_agent (); + break; + + default: + g_warning ("Unsupported variable type"); + break; + } +} + +static void +mozilla_socks_version_notifier (GConfClient *client, + guint cnxn_id, + GConfEntry *entry, + gpointer user_data) +{ + int version; + version = gconf_value_get_int(entry->value) + 4; + mozilla_prefs_set_int ("network.proxy.socks_version", + version); +} diff --git a/embed/mozilla/mozilla-notifiers.h b/embed/mozilla/mozilla-notifiers.h new file mode 100644 index 000000000..6718365f7 --- /dev/null +++ b/embed/mozilla/mozilla-notifiers.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2000 Nate Case + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_NOTIFIERS_H +#define MOZILLA_NOTIFIERS_H + +#include "mozilla-embed-shell.h" + +void mozilla_notifiers_init (MozillaEmbedShell *shell); + +void mozilla_notifiers_set_defaults (void); + +void mozilla_notifiers_free (void); + +#endif diff --git a/embed/mozilla/mozilla-prefs.cpp b/embed/mozilla/mozilla-prefs.cpp new file mode 100644 index 000000000..e5b8c68e2 --- /dev/null +++ b/embed/mozilla/mozilla-prefs.cpp @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2000-2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "mozilla-prefs.h" + +#include <nsCOMPtr.h> +#include <nsIPrefService.h> +#include <nsIServiceManager.h> +#include <nsMemory.h> +#include <glib/gmessages.h> +#include <glib/gstrfuncs.h> + +gboolean +mozilla_prefs_save (void) +{ + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + g_return_val_if_fail (prefService != nsnull, FALSE); + + nsresult rv = prefService->SavePrefFile (nsnull); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; +} + +gboolean +mozilla_prefs_set_string(const char *preference_name, const char *new_value) +{ + g_return_val_if_fail (preference_name != NULL, FALSE); + g_return_val_if_fail (new_value != NULL, FALSE); + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + nsresult rv = pref->SetCharPref (preference_name, new_value); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; + } + + return FALSE; +} + +gboolean +mozilla_prefs_set_boolean (const char *preference_name, + gboolean new_boolean_value) +{ + g_return_val_if_fail (preference_name != NULL, FALSE); + + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + nsresult rv = pref->SetBoolPref (preference_name, + new_boolean_value ? PR_TRUE : PR_FALSE); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; + } + return FALSE; +} + +gboolean +mozilla_prefs_set_int (const char *preference_name, int new_int_value) +{ + g_return_val_if_fail (preference_name != NULL, FALSE); + + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + nsresult rv = pref->SetIntPref (preference_name, new_int_value); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; + } + + return FALSE; +} + +gboolean +mozilla_prefs_get_boolean (const char *preference_name, + gboolean default_value) +{ + PRBool value; + + g_return_val_if_fail (preference_name != NULL, FALSE); + + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + nsresult result; + + result = pref->GetBoolPref (preference_name, &value); + if (NS_FAILED (result)) return default_value; + } + + return (value == PR_TRUE) ? TRUE : FALSE; +} + +gint +mozilla_prefs_get_int (const char *preference_name) +{ + int value = -1; + + g_return_val_if_fail (preference_name != NULL, FALSE); + + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + pref->GetIntPref (preference_name, &value); + } + + return value; +} + +gchar * +mozilla_prefs_get_string(const char *preference_name) +{ + gchar *value = NULL; + gchar *result = NULL; + + g_return_val_if_fail (preference_name != NULL, FALSE); + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + pref->GetCharPref (preference_name, &value); + } + + /* it's allocated by mozilla, so I could not g_free it */ + if (value) + { + result = g_strdup (value); + nsMemory::Free (value); + } + + return result; +} + +gboolean +mozilla_prefs_remove (const char *preference_name) +{ + g_return_val_if_fail (preference_name != NULL, FALSE); + + nsCOMPtr<nsIPrefService> prefService = + do_GetService (NS_PREFSERVICE_CONTRACTID); + nsCOMPtr<nsIPrefBranch> pref; + prefService->GetBranch ("", getter_AddRefs(pref)); + + if (pref) + { + nsresult rv = pref->ClearUserPref (preference_name); + return NS_SUCCEEDED (rv) ? TRUE : FALSE; + } + + return FALSE; +} diff --git a/embed/mozilla/mozilla-prefs.h b/embed/mozilla/mozilla-prefs.h new file mode 100644 index 000000000..82055c4a7 --- /dev/null +++ b/embed/mozilla/mozilla-prefs.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2000-2002 Marco Pesenti Gritti + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef MOZILLA_PREFS_H +#define MOZILLA_PREFS_H + +#include "glib/gtypes.h" + +gboolean mozilla_prefs_save (void); + +gboolean mozilla_prefs_set_string (const char *preference_name, + const char *new_value); + +gboolean mozilla_prefs_set_boolean (const char *preference_name, + gboolean new_boolean_value); + +gboolean mozilla_prefs_set_int (const char *preference_name, + int new_int_value); + +gboolean mozilla_prefs_get_boolean (const char *preference_name, + gboolean default_value); + +int mozilla_prefs_get_int (const char *preference_name); + +gchar *mozilla_prefs_get_string (const char *preference_name); + +gboolean mozilla_prefs_remove (const char *preference_name); + +#endif diff --git a/embed/mozilla/nsUnicharUtils.cpp b/embed/mozilla/nsUnicharUtils.cpp new file mode 100644 index 000000000..d70619303 --- /dev/null +++ b/embed/mozilla/nsUnicharUtils.cpp @@ -0,0 +1,344 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Unicode case conversion helpers. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp.. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alec Flett <alecf@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsString.h" +#include "nsUnicharUtils.h" +#include "nsReadableUtils.h" +#include "nsUnicharUtilCIID.h" +#include "nsICaseConversion.h" +#include "nsIServiceManager.h" +#include "nsCRT.h" + +#include "nsIObserver.h" +#include "nsIObserverService.h" + +// global cache of the case conversion service +static nsICaseConversion *gCaseConv = nsnull; + +class nsShutdownObserver : public nsIObserver +{ +public: + nsShutdownObserver() { NS_INIT_ISUPPORTS(); } + virtual ~nsShutdownObserver() {} + NS_DECL_ISUPPORTS + + NS_IMETHOD Observe(nsISupports *aSubject, const char *aTopic, + const PRUnichar *aData) + { + if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)==0) { + NS_IF_RELEASE(gCaseConv); + } + + return NS_OK; + } + +}; + +NS_IMPL_ISUPPORTS1(nsShutdownObserver, nsIObserver) + +static nsresult NS_InitCaseConversion() { + if (gCaseConv) return NS_OK; + + nsresult rv; + + rv = CallGetService(NS_UNICHARUTIL_CONTRACTID, &gCaseConv); + + if (NS_SUCCEEDED(rv)) { + nsCOMPtr<nsIObserverService> obs = + do_GetService("@mozilla.org/observer-service;1", &rv); + if (NS_SUCCEEDED(rv)) { + nsShutdownObserver *observer = new nsShutdownObserver(); + if (observer) + obs->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE); + } + } + + return NS_OK; +} + +class ConvertToLowerCase +{ +public: + typedef PRUnichar value_type; + + ConvertToLowerCase() + { + NS_InitCaseConversion(); + } + + PRUint32 write( const PRUnichar* aSource, PRUint32 aSourceLength) + { + if (gCaseConv) + gCaseConv->ToLower(aSource, NS_CONST_CAST(PRUnichar*,aSource), aSourceLength); + else + NS_WARNING("No case converter: no conversion done"); + + return aSourceLength; + } +}; + +void +ToLowerCase( nsAString& aString ) + { + nsAString::iterator fromBegin, fromEnd; + ConvertToLowerCase converter; + copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter); + } + +void +ToLowerCase( nsASingleFragmentString& aString ) + { + ConvertToLowerCase converter; + PRUnichar* start; + converter.write(aString.BeginWriting(start), aString.Length()); + } + +void +ToLowerCase( nsString& aString ) + { + ConvertToLowerCase converter; + converter.write(aString.mUStr, aString.mLength); + } + +class CopyToLowerCase + { + public: + typedef PRUnichar value_type; + + CopyToLowerCase( nsAString::iterator& aDestIter ) + : mIter(aDestIter) + { + NS_InitCaseConversion(); + } + + PRUint32 write( const PRUnichar* aSource, PRUint32 aSourceLength ) + { + PRUint32 len = PR_MIN(PRUint32(mIter.size_forward()), aSourceLength); + PRUnichar* dest = NS_CONST_CAST(PRUnichar*, mIter.get()); + if (gCaseConv) + gCaseConv->ToLower(aSource, dest, len); + else { + NS_WARNING("No case converter: only copying"); + memcpy((void*)aSource, (void*)dest, len * sizeof(*aSource)); + } + mIter.advance(len); + return len; + } + + protected: + nsAString::iterator& mIter; + }; + +void +ToLowerCase( const nsAString& aSource, nsAString& aDest ) + { + nsAString::const_iterator fromBegin, fromEnd; + nsAString::iterator toBegin; + aDest.SetLength(aSource.Length()); + CopyToLowerCase converter(aDest.BeginWriting(toBegin)); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter); + } + +class ConvertToUpperCase +{ +public: + typedef PRUnichar value_type; + + ConvertToUpperCase() + { + NS_InitCaseConversion(); + } + + PRUint32 write( const PRUnichar* aSource, PRUint32 aSourceLength) + { + if (gCaseConv) + gCaseConv->ToUpper(aSource, NS_CONST_CAST(PRUnichar*,aSource), aSourceLength); + else + NS_WARNING("No case converter: no conversion done"); + + return aSourceLength; + } +}; + +void +ToUpperCase( nsAString& aString ) + { + nsAString::iterator fromBegin, fromEnd; + ConvertToUpperCase converter; + copy_string(aString.BeginWriting(fromBegin), aString.EndWriting(fromEnd), converter); + } + +void +ToUpperCase( nsASingleFragmentString& aString ) + { + ConvertToUpperCase converter; + PRUnichar* start; + converter.write(aString.BeginWriting(start), aString.Length()); + } + +void +ToUpperCase( nsString& aString ) + { + ConvertToUpperCase converter; + converter.write(aString.mUStr, aString.mLength); + } + +class CopyToUpperCase + { + public: + typedef PRUnichar value_type; + + CopyToUpperCase( nsAString::iterator& aDestIter ) + : mIter(aDestIter) + { + NS_InitCaseConversion(); + } + + PRUint32 write( const PRUnichar* aSource, PRUint32 aSourceLength ) + { + PRUint32 len = PR_MIN(PRUint32(mIter.size_forward()), aSourceLength); + PRUnichar* dest = NS_CONST_CAST(PRUnichar*, mIter.get()); + if (gCaseConv) + gCaseConv->ToUpper(aSource, dest, len); + else { + NS_WARNING("No case converter: only copying"); + memcpy((void*)aSource, (void*)dest, len * sizeof(*aSource)); + } + mIter.advance(len); + return len; + } + + protected: + nsAString::iterator& mIter; + }; + +void +ToUpperCase( const nsAString& aSource, nsAString& aDest ) + { + nsAString::const_iterator fromBegin, fromEnd; + nsAString::iterator toBegin; + aDest.SetLength(aSource.Length()); + CopyToUpperCase converter(aDest.BeginWriting(toBegin)); + copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter); + } + +PRBool +CaseInsensitiveFindInReadable( const nsAString& aPattern, nsAString::const_iterator& aSearchStart, nsAString::const_iterator& aSearchEnd ) +{ + return FindInReadable(aPattern, aSearchStart, aSearchEnd, nsCaseInsensitiveStringComparator()); +} + + +int +nsCaseInsensitiveStringComparator::operator()( const PRUnichar* lhs, const PRUnichar* rhs, PRUint32 aLength ) const + { + NS_InitCaseConversion(); + PRInt32 result; + if (gCaseConv) { + gCaseConv->CaseInsensitiveCompare(lhs, rhs, aLength, &result); + } + else { + NS_WARNING("No case converter: using default"); + nsDefaultStringComparator comparator; + result = comparator(lhs, rhs, aLength); + } + return result; + } + +int +nsCaseInsensitiveStringComparator::operator()( PRUnichar lhs, PRUnichar rhs ) const + { + // see if they're an exact match first + if (lhs == rhs) return 0; + + NS_InitCaseConversion(); + + if (gCaseConv) { + gCaseConv->ToLower(lhs, &lhs); + gCaseConv->ToLower(rhs, &rhs); + } else { + if (lhs < 256) + lhs = tolower(char(lhs)); + if (rhs < 256) + rhs = tolower(char(rhs)); + NS_WARNING("No case converter: no conversion done"); + } + + if (lhs == rhs) return 0; + if (lhs < rhs) return -1; + return 1; + } + +PRUnichar +ToLowerCase(PRUnichar aChar) +{ + PRUnichar result; + if (NS_FAILED(NS_InitCaseConversion())) + return aChar; + + if (gCaseConv) + gCaseConv->ToLower(aChar, &result); + else { + NS_WARNING("No case converter: no conversion done"); + if (aChar < 256) + result = tolower(char(aChar)); + else + result = aChar; + } + return result; +} + +PRUnichar +ToUpperCase(PRUnichar aChar) +{ + PRUnichar result; + if (NS_FAILED(NS_InitCaseConversion())) + return aChar; + + if (gCaseConv) + gCaseConv->ToUpper(aChar, &result); + else { + NS_WARNING("No case converter: no conversion done"); + if (aChar < 256) + result = toupper(char(aChar)); + else + result = aChar; + } + return result; +} + diff --git a/embed/mozilla/nsUnicharUtils.h b/embed/mozilla/nsUnicharUtils.h new file mode 100644 index 000000000..6ae9a238d --- /dev/null +++ b/embed/mozilla/nsUnicharUtils.h @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Unicode case conversion helpers. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corp.. + * Portions created by the Initial Developer are Copyright (C) 2002 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Alec Flett <alecf@netscape.com> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsUnicharUtils_h__ +#define nsUnicharUtils_h__ +#ifndef nsAString_h___ +#include "nsAString.h" +#endif + +class nsASingleFragmentString; +class nsString; + +void ToLowerCase( nsAString& ); +void ToUpperCase( nsAString& ); + +void ToLowerCase( nsASingleFragmentString& ); +void ToUpperCase( nsASingleFragmentString& ); + +void ToLowerCase( nsString& ); +void ToUpperCase( nsString& ); + +void ToLowerCase( const nsAString& aSource, nsAString& aDest ); +void ToUpperCase( const nsAString& aSource, nsAString& aDest ); + +PRBool CaseInsensitiveFindInReadable( const nsAString& aPattern, nsAString::const_iterator&, nsAString::const_iterator& ); + +class nsCaseInsensitiveStringComparator + : public nsStringComparator + { + public: + virtual int operator()( const PRUnichar*, const PRUnichar*, PRUint32 aLength ) const; + virtual int operator()( PRUnichar, PRUnichar ) const; + }; + + +PRUnichar ToUpperCase(PRUnichar); +PRUnichar ToLowerCase(PRUnichar); + +inline PRBool IsUpperCase(PRUnichar c) { + return ToLowerCase(c) != c; +} + +inline PRBool IsLowerCase(PRUnichar c) { + return ToUpperCase(c) != c; +} + +#define IS_HIGH_SURROGATE(u) ((PRUnichar)(u) >= (PRUnichar)0xd800 && (PRUnichar)(u) <= (PRUnichar)0xdbff) +#define IS_LOW_SURROGATE(u) ((PRUnichar)(u) >= (PRUnichar)0xdc00 && (PRUnichar)(u) <= (PRUnichar)0xdfff) + +#define SURROGATE_TO_UCS4(h, l) ((((PRUint32)(h)-(PRUint32)0xd800) << 10) + \ + (PRUint32)(l) - (PRUint32)(0xdc00) + 0x10000) + +/* (0x3131u <= (u) && (u) <= 0x318eu) => Hangul Compatibility Jamo */ +/* (0xac00u <= (u) && (u) <= 0xd7a3u) => Hangul Syllables */ +#define IS_CJ_CHAR(u) \ + ((0x2e80u <= (u) && (u) <= 0x312fu) || \ + (0x3190u <= (u) && (u) <= 0xabffu) || \ + (0xf900u <= (u) && (u) <= 0xfaffu) || \ + (0xff00u <= (u) && (u) <= 0xffffu) ) + +#endif /* nsUnicharUtils_h__ */ diff --git a/embed/print-dialog.c b/embed/print-dialog.c new file mode 100755 index 000000000..09929376c --- /dev/null +++ b/embed/print-dialog.c @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "print-dialog.h" +#include "ephy-prefs.h" +#include <gtk/gtkdialog.h> + +#define CONF_PRINT_BOTTOM_MARGIN "/apps/epiphany/print/bottom_margin" +#define CONF_PRINT_TOP_MARGIN "/apps/epiphany/print/top_margin" +#define CONF_PRINT_LEFT_MARGIN "/apps/epiphany/print/left_margin" +#define CONF_PRINT_RIGHT_MARGIN "/apps/epiphany/print/right_margin" +#define CONF_PRINT_PAGE_TITLE "/apps/epiphany/print/page_title_toggle" +#define CONF_PRINT_PAGE_URL "/apps/epiphany/print/page_url_toggle" +#define CONF_PRINT_DATE "/apps/epiphany/print/date_toggle" +#define CONF_PRINT_PAGE_NUMBERS "/apps/epiphany/print/page_numbers_toggle" +#define CONF_PRINT_PRINTER "/apps/epiphany/print/printer" +#define CONF_PRINT_FILE "/apps/epiphany/print/file" +#define CONF_PRINT_PRINTON "/apps/epiphany/print/printon" +#define CONF_PRINT_PAPER "/apps/epiphany/print/paper" +#define CONF_PRINT_ALL_PAGES "/apps/epiphany/print/all_pages" +#define CONF_PRINT_START_FROM_LAST "/apps/epiphany/print/start_from_last" +#define CONF_PRINT_COLOR "/apps/epiphany/print/color" +#define CONF_PRINT_ORIENTATION "/apps/epiphany/print/orientation" + +static void print_dialog_class_init (PrintDialogClass *klass); +static void print_dialog_init (PrintDialog *dialog); +static void print_dialog_finalize (GObject *object); + +/* Glade callbacks */ +void +print_cancel_button_cb (GtkWidget *widget, + EphyDialog *dialog); +void +print_ok_button_cb (GtkWidget *widget, + EphyDialog *dialog); +void +print_preview_button_cb (GtkWidget *widget, + EphyDialog *dialog); + +static GObjectClass *parent_class = NULL; + +struct PrintDialogPrivate +{ + gpointer dummy; +}; + +enum +{ + PRINTON_PROP, + PRINTER_PROP, + FILE_PROP, + PAPER_PROP, + TOP_PROP, + BOTTOM_PROP, + LEFT_PROP, + RIGHT_PROP, + PAGE_TITLE_PROP, + PAGE_URL_PROP, + PAGE_NUMBERS_PROP, + DATE_PROP, + ALL_PAGES_PROP, + TO_PROP, + FROM_PROP, + COLOR_PROP, + ORIENTATION_PROP +}; + +enum +{ + PREVIEW, + LAST_SIGNAL +}; + +static const +EphyDialogProperty properties [] = +{ + { PRINTON_PROP, "printer_radiobutton", CONF_PRINT_PRINTON, PT_NORMAL, NULL }, + { PRINTER_PROP, "printer_entry", CONF_PRINT_PRINTER, PT_NORMAL, NULL }, + { FILE_PROP, "file_entry", CONF_PRINT_FILE, PT_NORMAL, NULL }, + { PAPER_PROP,"letter_radiobutton", CONF_PRINT_PAPER, PT_NORMAL, NULL }, + { TOP_PROP, "top_spinbutton", CONF_PRINT_TOP_MARGIN, PT_NORMAL, NULL }, + { BOTTOM_PROP, "bottom_spinbutton", CONF_PRINT_BOTTOM_MARGIN, PT_NORMAL, NULL }, + { LEFT_PROP,"left_spinbutton", CONF_PRINT_LEFT_MARGIN, PT_NORMAL, NULL }, + { RIGHT_PROP, "right_spinbutton", CONF_PRINT_RIGHT_MARGIN, PT_NORMAL, NULL }, + { PAGE_TITLE_PROP, "print_page_title_checkbutton", CONF_PRINT_PAGE_TITLE, PT_NORMAL, NULL }, + { PAGE_URL_PROP, "print_page_url_checkbutton", CONF_PRINT_PAGE_URL, PT_NORMAL, NULL }, + { PAGE_NUMBERS_PROP, "print_page_numbers_checkbutton", CONF_PRINT_PAGE_NUMBERS, PT_NORMAL, NULL }, + { DATE_PROP, "print_date_checkbutton", CONF_PRINT_DATE, PT_NORMAL, NULL }, + { ALL_PAGES_PROP, "all_pages_radiobutton", CONF_PRINT_ALL_PAGES, PT_NORMAL, NULL }, + { TO_PROP, "to_spinbutton", NULL, PT_NORMAL, NULL }, + { FROM_PROP, "from_spinbutton", NULL, PT_NORMAL, NULL }, + { COLOR_PROP, "print_color_radiobutton", CONF_PRINT_COLOR, PT_NORMAL, NULL }, + { ORIENTATION_PROP, "orient_p_radiobutton", CONF_PRINT_ORIENTATION, PT_NORMAL, NULL }, + + { -1, NULL, NULL } +}; + +static guint print_dialog_signals[LAST_SIGNAL] = { 0 }; + +GType +print_dialog_get_type (void) +{ + static GType print_dialog_type = 0; + + if (print_dialog_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (PrintDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) print_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (PrintDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) print_dialog_init + }; + + print_dialog_type = g_type_register_static (EPHY_EMBED_DIALOG_TYPE, + "PrintDialog", + &our_info, 0); + } + + return print_dialog_type; + +} + +static void +print_dialog_class_init (PrintDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = print_dialog_finalize; + + print_dialog_signals[PREVIEW] = + g_signal_new ("preview", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (PrintDialogClass, preview), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); +} + +static void +print_dialog_init (PrintDialog *dialog) +{ + dialog->priv = g_new0 (PrintDialogPrivate, 1); + + dialog->only_collect_info = FALSE; + + dialog->ret_info = NULL; + + ephy_dialog_construct (EPHY_DIALOG(dialog), + properties, + "print.glade", "print_dialog"); +} + +static void +print_dialog_finalize (GObject *object) +{ + PrintDialog *dialog; + + g_return_if_fail (object != NULL); + g_return_if_fail (IS_PRINT_DIALOG (object)); + + dialog = PRINT_DIALOG (object); + + g_return_if_fail (dialog->priv != NULL); + + g_free (dialog->priv); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +EphyDialog * +print_dialog_new (EphyEmbed *embed, + EmbedPrintInfo **ret_info) +{ + PrintDialog *dialog; + + dialog = PRINT_DIALOG (g_object_new (PRINT_DIALOG_TYPE, + "EphyEmbed", embed, + NULL)); + + if (!embed) dialog->only_collect_info = TRUE; + dialog->ret_info = ret_info; + + return EPHY_DIALOG(dialog); +} + +EphyDialog * +print_dialog_new_with_parent (GtkWidget *window, + EphyEmbed *embed, + EmbedPrintInfo **ret_info) +{ + PrintDialog *dialog; + + dialog = PRINT_DIALOG (g_object_new (PRINT_DIALOG_TYPE, + "EphyEmbed", embed, + "ParentWindow", window, + NULL)); + + if (!embed) dialog->only_collect_info = TRUE; + dialog->ret_info = ret_info; + + return EPHY_DIALOG(dialog); +} + +void +print_free_info (EmbedPrintInfo *info) +{ + g_free (info->printer); + g_free (info->file); + g_free (info->header_left_string); + g_free (info->header_right_string); + g_free (info->footer_left_string); + g_free (info->footer_right_string); + g_free (info); +} + +static EmbedPrintInfo * +print_get_info (EphyDialog *dialog) +{ + EmbedPrintInfo *info; + GValue print_to_file = {0, }; + GValue printer = {0, }; + GValue file = {0, }; + GValue top_margin = {0, }; + GValue bottom_margin = {0, }; + GValue left_margin = {0, }; + GValue right_margin = {0, }; + GValue from_page = {0, }; + GValue to_page = {0, }; + GValue paper = {0, }; + GValue pages = {0, }; + GValue print_color = {0, }; + GValue orientation = {0, }; + GValue page_title = {0, }; + GValue page_url = {0, }; + GValue date = {0, }; + GValue page_numbers = {0, }; + + info = g_new0 (EmbedPrintInfo, 1); + + ephy_dialog_get_value (dialog, PRINTON_PROP, &print_to_file); + info->print_to_file = g_value_get_int (&print_to_file); + + ephy_dialog_get_value (dialog, PRINTER_PROP, &printer); + info->printer = g_strdup (g_value_get_string (&printer)); + + ephy_dialog_get_value (dialog, FILE_PROP, &file); + info->file = g_strdup (g_value_get_string (&file)); + + ephy_dialog_get_value (dialog, BOTTOM_PROP, &bottom_margin); + info->bottom_margin = g_value_get_float (&bottom_margin); + + ephy_dialog_get_value (dialog, LEFT_PROP, &left_margin); + info->left_margin = g_value_get_float (&left_margin); + + ephy_dialog_get_value (dialog, TOP_PROP, &top_margin); + info->top_margin = g_value_get_float (&top_margin); + + ephy_dialog_get_value (dialog, RIGHT_PROP, &right_margin); + info->right_margin = g_value_get_float (&right_margin); + + ephy_dialog_get_value (dialog, FROM_PROP, &from_page); + info->from_page = g_value_get_float (&from_page); + + ephy_dialog_get_value (dialog, TO_PROP, &to_page); + info->to_page = g_value_get_float (&to_page); + + ephy_dialog_get_value (dialog, PAPER_PROP, &paper); + info->paper = g_value_get_int (&paper); + + ephy_dialog_get_value (dialog, ALL_PAGES_PROP, &pages); + info->pages = g_value_get_int (&pages); + + ephy_dialog_get_value (dialog, COLOR_PROP, &print_color); + info->print_color = g_value_get_int (&print_color); + + ephy_dialog_get_value (dialog, ORIENTATION_PROP, &orientation); + info->orientation = g_value_get_int (&orientation); + + info->frame_type = 0; + + ephy_dialog_get_value (dialog, PAGE_TITLE_PROP, &page_title); + info->header_left_string = g_value_get_boolean (&page_title) ? + g_strdup ("&T") : g_strdup (""); + + ephy_dialog_get_value (dialog, PAGE_URL_PROP, &page_url); + info->header_right_string = g_value_get_boolean (&page_url) ? + g_strdup ("&U") : g_strdup (""); + + ephy_dialog_get_value (dialog, PAGE_NUMBERS_PROP, &page_numbers); + info->footer_left_string = g_value_get_boolean (&page_numbers) ? + g_strdup ("&PT") : g_strdup (""); + + ephy_dialog_get_value (dialog, DATE_PROP, &date); + info->footer_right_string = g_value_get_boolean (&date) ? + g_strdup ("&D") : g_strdup (""); + + info->header_center_string = g_strdup(""); + info->footer_center_string = g_strdup(""); + + return info; +} + +static void +print_dialog_print (EphyDialog *dialog) +{ + EmbedPrintInfo *info; + EphyEmbed *embed; + + info = print_get_info (dialog); + + if(PRINT_DIALOG(dialog)->only_collect_info && PRINT_DIALOG(dialog)->ret_info) + { + *(PRINT_DIALOG(dialog)->ret_info) = info; + } + else + { + embed = ephy_embed_dialog_get_embed + (EPHY_EMBED_DIALOG(dialog)); + + info->preview = FALSE; + ephy_embed_print (embed, info); + print_free_info (info); + } + + g_object_unref (G_OBJECT(dialog)); +} + +static void +print_dialog_preview (EphyDialog *dialog) +{ + EmbedPrintInfo *info; + EphyEmbed *embed; + + info = print_get_info (dialog); + + if(PRINT_DIALOG(dialog)->only_collect_info && PRINT_DIALOG(dialog)->ret_info) + { + *(PRINT_DIALOG(dialog)->ret_info) = info; + } + else + { + embed = ephy_embed_dialog_get_embed + (EPHY_EMBED_DIALOG(dialog)); + + info->preview = TRUE; + ephy_embed_print (embed, info); + print_free_info (info); + } + g_signal_emit (G_OBJECT (dialog), print_dialog_signals[PREVIEW], 0); + + g_object_unref (G_OBJECT(dialog)); +} + +void +print_cancel_button_cb (GtkWidget *widget, + EphyDialog *dialog) +{ + g_object_unref (G_OBJECT(dialog)); +} + +void +print_ok_button_cb (GtkWidget *widget, + EphyDialog *dialog) +{ + print_dialog_print (dialog); +} + +void +print_preview_button_cb (GtkWidget *widget, + EphyDialog *dialog) +{ + //FIXME: Don't show preview button at all. + if(!(PRINT_DIALOG(dialog)->only_collect_info)) + print_dialog_preview (dialog); +} + + diff --git a/embed/print-dialog.h b/embed/print-dialog.h new file mode 100644 index 000000000..5342f0223 --- /dev/null +++ b/embed/print-dialog.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2002 Jorn Baayen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef PRINT_DIALOG_H +#define PRINT_DIALOG_H + +#include "ephy-embed-dialog.h" +#include "ephy-embed.h" + +#include <glib-object.h> +#include <glib.h> + +G_BEGIN_DECLS + +typedef struct PrintDialog PrintDialog; +typedef struct PrintDialogClass PrintDialogClass; + +#define PRINT_DIALOG_TYPE (print_dialog_get_type ()) +#define PRINT_DIALOG(obj) (GTK_CHECK_CAST ((obj), PRINT_DIALOG_TYPE, PrintDialog)) +#define PRINT_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), PRINT_DIALOG, PrintDialogClass)) +#define IS_PRINT_DIALOG(obj) (GTK_CHECK_TYPE ((obj), PRINT_DIALOG_TYPE)) +#define IS_PRINT_DIALOG_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), PRINT_DIALOG)) + +typedef struct PrintDialogPrivate PrintDialogPrivate; + +struct PrintDialog +{ + EphyEmbedDialog parent; + PrintDialogPrivate *priv; + //FIXME: These should be gobject properties + gboolean only_collect_info; + EmbedPrintInfo **ret_info; +}; + +struct PrintDialogClass +{ + EphyEmbedDialogClass parent_class; + + void (* preview) (PrintDialog *dialog); +}; + +GType print_dialog_get_type (void); + +EphyDialog *print_dialog_new (EphyEmbed *embed, + EmbedPrintInfo **ret_info); + +EphyDialog *print_dialog_new_with_parent (GtkWidget *window, + EphyEmbed *embed, + EmbedPrintInfo **ret_info); + +gboolean print_dialog_is_preview (PrintDialog *dialog); + +void print_free_info (EmbedPrintInfo *info); + +G_END_DECLS + +#endif + |