[gtkhtml] Bug 598567 - Can only insert local image files
- From: Matthew Barnes <mbarnes src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gtkhtml] Bug 598567 - Can only insert local image files
- Date: Tue, 20 Oct 2009 20:38:29 +0000 (UTC)
commit 44be36ff903d507194e21051737f3f1aa0aa2228
Author: Matthew Barnes <mbarnes redhat com>
Date: Tue Oct 20 16:37:18 2009 -0400
Bug 598567 - Can only insert local image files
components/editor/gtkhtml-editor-builder.ui | 1 +
components/editor/gtkhtml-editor-private.c | 214 ++++++++++++++++++++++++++-
components/editor/gtkhtml-editor-private.h | 26 ++++
components/editor/gtkhtml-editor-signals.c | 8 +-
components/editor/gtkhtml-editor.c | 87 +++++++-----
components/editor/gtkhtml-editor.h | 4 +-
6 files changed, 295 insertions(+), 45 deletions(-)
---
diff --git a/components/editor/gtkhtml-editor-builder.ui b/components/editor/gtkhtml-editor-builder.ui
index 05afc91..939d36e 100644
--- a/components/editor/gtkhtml-editor-builder.ui
+++ b/components/editor/gtkhtml-editor-builder.ui
@@ -3094,6 +3094,7 @@
<object class="GtkFileChooserButton" id="image-properties-source-file-chooser">
<property name="visible">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+ <property name="local_only">False</property>
<signal handler="gtkhtml_editor_image_properties_source_file_set_cb" name="file_set" object="image-properties-window"/>
</object>
<packing>
diff --git a/components/editor/gtkhtml-editor-private.c b/components/editor/gtkhtml-editor-private.c
index 14b8509..8a44207 100644
--- a/components/editor/gtkhtml-editor-private.c
+++ b/components/editor/gtkhtml-editor-private.c
@@ -153,6 +153,166 @@ editor_replace_all_cb (GtkhtmlEditor *editor,
/************************* End Spell Dialog Callbacks ************************/
+/************************ Begin URI Request Callbacks ************************/
+
+static GtkhtmlEditorRequest *
+editor_request_new (GtkhtmlEditor *editor,
+ const gchar *uri,
+ GtkHTMLStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple;
+ GtkhtmlEditorRequest *request;
+ GList *list;
+
+ request = g_slice_new (GtkhtmlEditorRequest);
+
+ simple = g_simple_async_result_new (
+ G_OBJECT (editor), callback,
+ user_data, gtkhtml_editor_request_async);
+
+ if (cancellable != NULL)
+ g_object_ref (cancellable);
+
+ /* Try to detect file paths posing as URIs. */
+ if (*uri == '/')
+ request->file = g_file_new_for_path (uri);
+ else
+ request->file = g_file_new_for_uri (uri);
+
+ request->editor = g_object_ref (editor);
+ request->cancellable = cancellable;
+ request->simple = simple;
+ request->input_stream = NULL;
+ request->output_stream = stream;
+
+ list = request->editor->priv->requests;
+ list = g_list_prepend (list, request);
+ request->editor->priv->requests = list;
+
+ return request;
+}
+
+static void
+editor_request_free (GtkhtmlEditorRequest *request)
+{
+ GList *list;
+
+ /* Do not free the GSimpleAsyncResult. */
+
+ list = request->editor->priv->requests;
+ list = g_list_remove (list, request);
+ request->editor->priv->requests = list;
+
+ g_object_unref (request->file);
+ g_object_unref (request->editor);
+
+ if (request->cancellable != NULL)
+ g_object_unref (request->cancellable);
+
+ if (request->input_stream != NULL)
+ g_object_unref (request->input_stream);
+
+ g_slice_free (GtkhtmlEditorRequest, request);
+}
+
+static gboolean
+editor_request_check_for_error (GtkhtmlEditorRequest *request,
+ GError *error)
+{
+ GtkHTML *html;
+ GtkHTMLStream *stream;
+ GSimpleAsyncResult *simple;
+
+ if (error == NULL)
+ return FALSE;
+
+ stream = request->output_stream;
+ html = gtkhtml_editor_get_html (request->editor);
+ gtk_html_end (html, stream, GTK_HTML_STREAM_ERROR);
+
+ /* Steal the result. */
+ simple = request->simple;
+ request->simple = NULL;
+
+ g_simple_async_result_set_from_error (simple, error);
+ g_simple_async_result_complete (simple);
+ g_error_free (error);
+
+ editor_request_free (request);
+
+ return TRUE;
+}
+
+static void
+editor_request_stream_read_cb (GInputStream *input_stream,
+ GAsyncResult *result,
+ GtkhtmlEditorRequest *request)
+{
+ GtkHTML *html;
+ GtkHTMLStream *stream;
+ gssize bytes_read;
+ GError *error = NULL;
+
+ stream = request->output_stream;
+ html = gtkhtml_editor_get_html (request->editor);
+
+ bytes_read = g_input_stream_read_finish (input_stream, result, &error);
+
+ if (editor_request_check_for_error (request, error))
+ return;
+
+ if (bytes_read == 0) {
+ GSimpleAsyncResult *simple;
+
+ /* Steal the result. */
+ simple = request->simple;
+ request->simple = NULL;
+
+ gtk_html_end (html, stream, GTK_HTML_STREAM_OK);
+
+ g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_complete (simple);
+ editor_request_free (request);
+
+ return;
+ }
+
+ gtk_html_write (html, stream, request->buffer, bytes_read);
+
+ g_input_stream_read_async (
+ request->input_stream, request->buffer,
+ sizeof (request->buffer), G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ editor_request_stream_read_cb, request);
+}
+
+static void
+editor_request_read_cb (GFile *file,
+ GAsyncResult *result,
+ GtkhtmlEditorRequest *request)
+{
+ GFileInputStream *input_stream;
+ GError *error = NULL;
+
+ /* Input stream might be NULL, so don't use cast macro. */
+ input_stream = g_file_read_finish (file, result, &error);
+ request->input_stream = (GInputStream *) input_stream;
+
+ if (editor_request_check_for_error (request, error))
+ return;
+
+ g_input_stream_read_async (
+ request->input_stream, request->buffer,
+ sizeof (request->buffer), G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ editor_request_stream_read_cb, request);
+}
+
+/************************* End URI Request Callbacks *************************/
+
void
gtkhtml_editor_private_init (GtkhtmlEditor *editor)
{
@@ -412,6 +572,10 @@ gtkhtml_editor_private_finalize (GtkhtmlEditor *editor)
{
GtkhtmlEditorPrivate *priv = editor->priv;
+ /* All URI requests should be complete or cancelled by now. */
+ if (priv->requests != NULL)
+ g_warning ("Finalizing GtkhtmlEditor with active URI requests");
+
g_hash_table_destroy (priv->available_spell_checkers);
g_hash_table_destroy (priv->spell_suggestion_menus);
@@ -561,8 +725,8 @@ gtkhtml_editor_insert_file (GtkhtmlEditor *editor,
GTK_STOCK_OPEN, GTK_RESPONSE_OK,
NULL);
- gtk_dialog_set_default_response (
- GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
g_signal_connect (dialog, "response", response_cb, editor);
@@ -574,6 +738,52 @@ gtkhtml_editor_insert_file (GtkhtmlEditor *editor,
}
void
+gtkhtml_editor_request_async (GtkhtmlEditor *editor,
+ const gchar *uri,
+ GtkHTMLStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GtkhtmlEditorRequest *request;
+
+ g_return_if_fail (GTKHTML_IS_EDITOR (editor));
+ g_return_if_fail (uri != NULL);
+ g_return_if_fail (stream != NULL);
+ g_return_if_fail (callback != NULL);
+
+ if (cancellable != NULL)
+ g_return_if_fail (G_IS_CANCELLABLE (cancellable));
+
+ request = editor_request_new (
+ editor, uri, stream, cancellable, callback, user_data);
+
+ g_file_read_async (
+ request->file, G_PRIORITY_DEFAULT,
+ request->cancellable, (GAsyncReadyCallback)
+ editor_request_read_cb, request);
+}
+
+gboolean
+gtkhtml_editor_request_finish (GtkhtmlEditor *editor,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ gboolean success;
+
+ g_return_val_if_fail (GTKHTML_IS_EDITOR (editor), FALSE);
+ g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), FALSE);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+ success = g_simple_async_result_get_op_res_gboolean (simple);
+ g_simple_async_result_propagate_error (simple, error);
+ g_object_unref (simple);
+
+ return success;
+}
+
+void
gtkhtml_editor_show_uri (GtkWindow *parent,
const gchar *uri)
{
diff --git a/components/editor/gtkhtml-editor-private.h b/components/editor/gtkhtml-editor-private.h
index df3cb6b..a9df794 100644
--- a/components/editor/gtkhtml-editor-private.h
+++ b/components/editor/gtkhtml-editor-private.h
@@ -84,6 +84,8 @@
G_BEGIN_DECLS
+typedef struct _GtkhtmlEditorRequest GtkhtmlEditorRequest;
+
typedef enum {
EDITOR_MODE_HTML,
EDITOR_MODE_TEXT
@@ -161,6 +163,10 @@ struct _GtkhtmlEditorPrivate {
HTMLObject *table_object;
+ /* Active URI Requests */
+
+ GList *requests;
+
/*** Miscellaneous ***/
/* Note, 'filename' is not used by GtkhtmlEditor itself but is here
@@ -175,6 +181,17 @@ struct _GtkhtmlEditorPrivate {
gboolean changed;
};
+struct _GtkhtmlEditorRequest {
+ GtkhtmlEditor *editor;
+ GCancellable *cancellable;
+ GSimpleAsyncResult *simple;
+
+ GFile *file;
+ GInputStream *input_stream;
+ GtkHTMLStream *output_stream;
+ gchar buffer[4096];
+};
+
void gtkhtml_editor_private_init (GtkhtmlEditor *editor);
void gtkhtml_editor_private_dispose (GtkhtmlEditor *editor);
void gtkhtml_editor_private_finalize (GtkhtmlEditor *editor);
@@ -192,6 +209,15 @@ gboolean gtkhtml_editor_get_file_contents (const gchar *filename,
gint gtkhtml_editor_insert_file (GtkhtmlEditor *editor,
const gchar *title,
GCallback response_cb);
+void gtkhtml_editor_request_async (GtkhtmlEditor *editor,
+ const gchar *uri,
+ GtkHTMLStream *stream,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+gboolean gtkhtml_editor_request_finish (GtkhtmlEditor *editor,
+ GAsyncResult *result,
+ GError **error);
void gtkhtml_editor_show_uri (GtkWindow *parent,
const gchar *uri);
void gtkhtml_editor_spell_check (GtkhtmlEditor *editor,
diff --git a/components/editor/gtkhtml-editor-signals.c b/components/editor/gtkhtml-editor-signals.c
index 20a0446..3cafd98 100644
--- a/components/editor/gtkhtml-editor-signals.c
+++ b/components/editor/gtkhtml-editor-signals.c
@@ -784,12 +784,8 @@ gtkhtml_editor_image_properties_show_window_cb (GtkWidget *window))
|| html_object_get_data (parent, "template_image") == NULL)
&& image->image_ptr->url != NULL) {
- gchar *filename;
-
- filename = gtk_html_filename_from_uri (image->image_ptr->url);
- gtk_file_chooser_set_filename (
- GTK_FILE_CHOOSER (widget), filename);
- g_free (filename);
+ gtk_file_chooser_set_uri (
+ GTK_FILE_CHOOSER (widget), image->image_ptr->url);
} else
gtk_file_chooser_unselect_all (GTK_FILE_CHOOSER (widget));
diff --git a/components/editor/gtkhtml-editor.c b/components/editor/gtkhtml-editor.c
index fad0cee..737af53 100644
--- a/components/editor/gtkhtml-editor.c
+++ b/components/editor/gtkhtml-editor.c
@@ -473,30 +473,6 @@ static GtkHTMLEditorAPI editor_api = {
editor_method_set_language
};
-static void
-editor_cut_clipboard (GtkhtmlEditor *editor)
-{
- gtk_html_command (gtkhtml_editor_get_html (editor), "cut");
-}
-
-static void
-editor_copy_clipboard (GtkhtmlEditor *editor)
-{
- gtk_html_command (gtkhtml_editor_get_html (editor), "copy");
-}
-
-static void
-editor_paste_clipboard (GtkhtmlEditor *editor)
-{
- gtk_html_command (gtkhtml_editor_get_html (editor), "paste");
-}
-
-static void
-editor_select_all (GtkhtmlEditor *editor)
-{
- gtk_html_command (gtkhtml_editor_get_html (editor), "select-all");
-}
-
static GObject *
editor_constructor (GType type,
guint n_construct_properties,
@@ -727,6 +703,49 @@ editor_finalize (GObject *object)
}
static void
+editor_cut_clipboard (GtkhtmlEditor *editor)
+{
+ gtk_html_command (gtkhtml_editor_get_html (editor), "cut");
+}
+
+static void
+editor_copy_clipboard (GtkhtmlEditor *editor)
+{
+ gtk_html_command (gtkhtml_editor_get_html (editor), "copy");
+}
+
+static void
+editor_paste_clipboard (GtkhtmlEditor *editor)
+{
+ gtk_html_command (gtkhtml_editor_get_html (editor), "paste");
+}
+
+static void
+editor_select_all (GtkhtmlEditor *editor)
+{
+ gtk_html_command (gtkhtml_editor_get_html (editor), "select-all");
+}
+
+static void
+editor_uri_requested_ready_cb (GtkhtmlEditor *editor,
+ GAsyncResult *result)
+{
+ /* XXX Do something in the event of an error? */
+ gtkhtml_editor_request_finish (editor, result, NULL);
+}
+
+static void
+editor_uri_requested (GtkhtmlEditor *editor,
+ const gchar *uri,
+ GtkHTMLStream *stream)
+{
+ /* XXX Currently no way to cancel this. */
+ gtkhtml_editor_request_async (
+ editor, uri, stream, NULL, (GAsyncReadyCallback)
+ editor_uri_requested_ready_cb, NULL);
+}
+
+static void
editor_class_init (GtkhtmlEditorClass *class)
{
GObjectClass *object_class;
@@ -745,6 +764,7 @@ editor_class_init (GtkhtmlEditorClass *class)
class->copy_clipboard = editor_copy_clipboard;
class->paste_clipboard = editor_paste_clipboard;
class->select_all = editor_select_all;
+ class->uri_requested = editor_uri_requested;
g_object_class_install_property (
object_class,
@@ -1608,26 +1628,23 @@ gtkhtml_editor_insert_html (GtkhtmlEditor *editor,
gtk_html_insert_html (html, html_text);
}
-/* inserts local files only, as inlined */
void
-gtkhtml_editor_insert_image (GtkhtmlEditor *editor,
- const gchar *filename_uri)
+gtkhtml_editor_insert_image (GtkhtmlEditor *editor,
+ const gchar *image_uri)
{
GtkHTML *html;
+ HTMLObject *image;
g_return_if_fail (GTKHTML_IS_EDITOR (editor));
- g_return_if_fail (filename_uri != NULL);
+ g_return_if_fail (image_uri != NULL);
html = gtkhtml_editor_get_html (editor);
- if (html) {
- HTMLObject *image;
+ image = html_image_new (
+ html_engine_get_image_factory (html->engine), image_uri,
+ NULL, NULL, 0, 0, 0, 0, 0, NULL, HTML_VALIGN_NONE, FALSE);
- image = html_image_new (
- html_engine_get_image_factory (html->engine), filename_uri,
- NULL, NULL, 0, 0, 0, 0, 0, NULL, HTML_VALIGN_NONE, FALSE);
- html_engine_paste_object (html->engine, image, 1);
- }
+ html_engine_paste_object (html->engine, image, 1);
}
gboolean
diff --git a/components/editor/gtkhtml-editor.h b/components/editor/gtkhtml-editor.h
index 57f8831..6973352 100644
--- a/components/editor/gtkhtml-editor.h
+++ b/components/editor/gtkhtml-editor.h
@@ -83,7 +83,7 @@ struct _GtkhtmlEditorClass {
void (*object_deleted) (GtkhtmlEditor *editor);
void (*uri_requested) (GtkhtmlEditor *editor,
const gchar *uri,
- GtkHTMLStream *output);
+ GtkHTMLStream *stream);
};
GType gtkhtml_editor_get_type (void);
@@ -165,7 +165,7 @@ gboolean gtkhtml_editor_is_previous_paragraph_empty
void gtkhtml_editor_insert_html (GtkhtmlEditor *editor,
const gchar *html_text);
void gtkhtml_editor_insert_image (GtkhtmlEditor *editor,
- const gchar *filename_uri);
+ const gchar *image_uri);
gboolean gtkhtml_editor_search_by_data (GtkhtmlEditor *editor,
glong level,
const gchar *klass,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]