Ejemplo n.º 1
0
gboolean
e_composer_paste_uris (EMsgComposer *composer,
                       GtkClipboard *clipboard)
{
	EAttachmentStore *store;
	EAttachmentView *view;
	gchar **uris;
	gint ii;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
	g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);

	view = e_msg_composer_get_attachment_view (composer);
	store = e_attachment_view_get_store (view);

	/* Extract the URI data from the clipboard. */
	uris = gtk_clipboard_wait_for_uris (clipboard);
	g_return_val_if_fail (uris != NULL, FALSE);

	/* Add the URIs to the attachment store. */
	for (ii = 0; uris[ii] != NULL; ii++) {
		EAttachment *attachment;

		attachment = e_attachment_new_for_uri (uris[ii]);
		e_attachment_store_add_attachment (store, attachment);
		e_attachment_load_async (
			attachment, (GAsyncReadyCallback)
			e_attachment_load_handle_error, composer);
		g_object_unref (attachment);
	}

	return TRUE;
}
Ejemplo n.º 2
0
gboolean
e_composer_selection_is_base64_uris (EMsgComposer *composer,
                                     GtkSelectionData *selection)
{
	gboolean all_base64_uris = TRUE;
	gchar **uris;
	guint ii;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
	g_return_val_if_fail (selection != NULL, FALSE);

	uris = gtk_selection_data_get_uris (selection);

	if (!uris)
		return FALSE;

	for (ii = 0; uris[ii] != NULL; ii++) {
		if (!((g_str_has_prefix (uris[ii], "data:") || strstr (uris[ii], ";data:"))
		    && strstr (uris[ii], ";base64,"))) {
			all_base64_uris = FALSE;
			break;
		}
	}

	g_strfreev (uris);

	return all_base64_uris;
}
Ejemplo n.º 3
0
static void
enable_disable_composer (EMsgComposer *composer,
                         gboolean enable)
{
	EHTMLEditor *editor;
	EHTMLEditorView *view;
	GtkAction *action;
	GtkActionGroup *action_group;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	editor = e_msg_composer_get_editor (composer);
	view = e_html_editor_get_view (editor);

	webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), enable);

	action = E_HTML_EDITOR_ACTION_EDIT_MENU (editor);
	gtk_action_set_sensitive (action, enable);

	action = E_HTML_EDITOR_ACTION_FORMAT_MENU (editor);
	gtk_action_set_sensitive (action, enable);

	action = E_HTML_EDITOR_ACTION_INSERT_MENU (editor);
	gtk_action_set_sensitive (action, enable);

	action_group = e_html_editor_get_action_group (editor, "composer");
	gtk_action_group_set_sensitive (action_group, enable);
}
Ejemplo n.º 4
0
GFile *
e_composer_get_snapshot_file (EMsgComposer *composer)
{
	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);

	return g_object_get_data (G_OBJECT (composer), SNAPSHOT_FILE_KEY);
}
Ejemplo n.º 5
0
gboolean
e_composer_paste_text (EMsgComposer *composer,
                       GtkClipboard *clipboard)
{
	EHTMLEditor *editor;
	EHTMLEditorView *view;
	EHTMLEditorSelection *editor_selection;
	gchar *text;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
	g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);

	if (!(text = gtk_clipboard_wait_for_text (clipboard)))
		return FALSE;

	editor = e_msg_composer_get_editor (composer);
	view = e_html_editor_get_view (editor);
	editor_selection = e_html_editor_view_get_selection (view);
	/* If WebView doesn't have focus, focus it */
	if (!gtk_widget_has_focus (GTK_WIDGET (view)))
		gtk_widget_grab_focus (GTK_WIDGET (view));

	e_html_editor_selection_insert_text (editor_selection, text);

	g_free (text);

	return TRUE;
}
Ejemplo n.º 6
0
static void
enable_disable_composer (EMsgComposer *composer,
                         gboolean enable)
{
	GtkhtmlEditor *editor;
	GtkAction *action;
	GtkActionGroup *action_group;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	editor = GTKHTML_EDITOR (composer);

	if (enable)
		gtkhtml_editor_run_command (editor, "editable-on");
	else
		gtkhtml_editor_run_command (editor, "editable-off");

	action = GTKHTML_EDITOR_ACTION_EDIT_MENU (composer);
	gtk_action_set_sensitive (action, enable);

	action = GTKHTML_EDITOR_ACTION_FORMAT_MENU (composer);
	gtk_action_set_sensitive (action, enable);

	action = GTKHTML_EDITOR_ACTION_INSERT_MENU (composer);
	gtk_action_set_sensitive (action, enable);

	action_group = gtkhtml_editor_get_action_group (editor, "composer");
	gtk_action_group_set_sensitive (action_group, enable);
}
Ejemplo n.º 7
0
static void
composer_autosave_foreach (EMsgComposer *composer)
{
	/* Make sure the composer is still alive. */
	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	if (e_composer_autosave_get_enabled (composer))
		e_composer_autosave_snapshot (composer);
}
Ejemplo n.º 8
0
gint
e_composer_autosave_get_fd (EMsgComposer *composer)
{
	AutosaveState *state;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), -1);

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_val_if_fail (state != NULL, -1);

	return state->fd;
}
Ejemplo n.º 9
0
gboolean
e_composer_autosave_get_saved (EMsgComposer *composer)
{
	AutosaveState *state;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_val_if_fail (state != NULL, FALSE);

	return state->saved;
}
Ejemplo n.º 10
0
const gchar *
e_composer_autosave_get_filename (EMsgComposer *composer)
{
	AutosaveState *state;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL);

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_val_if_fail (state != NULL, NULL);

	return state->filename;
}
Ejemplo n.º 11
0
void
e_composer_autosave_set_saved (EMsgComposer *composer,
                               gboolean saved)
{
	AutosaveState *state;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_if_fail (state != NULL);

	state->saved = saved;
}
Ejemplo n.º 12
0
void
e_composer_save_snapshot (EMsgComposer *composer,
                          GCancellable *cancellable,
                          GAsyncReadyCallback callback,
                          gpointer user_data)
{
	GSimpleAsyncResult *simple;
	SaveContext *context;
	GFile *snapshot_file;
	GError *local_error = NULL;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	context = g_slice_new0 (SaveContext);

	if (G_IS_CANCELLABLE (cancellable))
		context->cancellable = g_object_ref (cancellable);

	simple = g_simple_async_result_new (
		G_OBJECT (composer), callback, user_data,
		e_composer_save_snapshot);

	g_simple_async_result_set_check_cancellable (simple, cancellable);

	g_simple_async_result_set_op_res_gpointer (
		simple, context, (GDestroyNotify) save_context_free);

	snapshot_file = e_composer_get_snapshot_file (composer);

	if (!G_IS_FILE (snapshot_file))
		snapshot_file = create_snapshot_file (composer, &local_error);

	if (local_error != NULL) {
		g_warn_if_fail (snapshot_file == NULL);
		g_simple_async_result_take_error (simple, local_error);
		g_simple_async_result_complete (simple);
		g_object_unref (simple);
		return;
	}

	g_return_if_fail (G_IS_FILE (snapshot_file));

	g_file_replace_async (
		snapshot_file, NULL, FALSE,
		G_FILE_CREATE_PRIVATE, G_PRIORITY_DEFAULT,
		context->cancellable, (GAsyncReadyCallback)
		save_snapshot_replace_cb, simple);
}
Ejemplo n.º 13
0
void
e_composer_update_signature (EMsgComposer *composer)
{
	EComposerHeaderTable *table;
	EMailSignatureComboBox *combo_box;
	EHTMLEditor *editor;
	EHTMLEditorView *view;
	WebKitLoadStatus status;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	/* Do nothing if we're redirecting a message or we disabled
	 * the signature on purpose */
	if (composer->priv->redirect || composer->priv->disable_signature)
		return;

	table = e_msg_composer_get_header_table (composer);
	combo_box = e_composer_header_table_get_signature_combo_box (table);
	editor = e_msg_composer_get_editor (composer);
	view = e_html_editor_get_view (editor);

	status = webkit_web_view_get_load_status (WEBKIT_WEB_VIEW (view));
	/* If document is not loaded, we will wait for him */
	if (status != WEBKIT_LOAD_FINISHED) {
		/* Disconnect previous handlers */
		g_signal_handlers_disconnect_by_func (
			WEBKIT_WEB_VIEW (view),
			G_CALLBACK (composer_web_view_load_status_changed_cb),
			composer);
		g_signal_connect (
			WEBKIT_WEB_VIEW(view), "notify::load-status",
			G_CALLBACK (composer_web_view_load_status_changed_cb),
			composer);
		return;
	}

	/* XXX Signature files should be local and therefore load quickly,
	 *     so while we do load them asynchronously we don't allow for
	 *     user cancellation and we keep the composer alive until the
	 *     asynchronous loading is complete. */
	e_mail_signature_combo_box_load_selected (
		combo_box, G_PRIORITY_DEFAULT, NULL,
		(GAsyncReadyCallback) composer_load_signature_cb,
		g_object_ref (composer));
}
Ejemplo n.º 14
0
void
e_composer_autosave_unregister (EMsgComposer *composer,
                                gboolean delete_file)
{
	AutosaveState *state;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	if (state == NULL || state->filename == NULL)
		return;

	close (state->fd);

	if (delete_file)
		g_unlink (state->filename);

	g_object_set_data (G_OBJECT (composer), "autosave", NULL);
}
Ejemplo n.º 15
0
void
e_composer_autosave_register (EMsgComposer *composer)
{
	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	g_object_set_data_full (
		G_OBJECT (composer), "autosave",
		composer_autosave_state_new (),
		(GDestroyNotify) composer_autosave_state_free);

	autosave_registry = g_list_prepend (autosave_registry, composer);

	g_object_weak_ref (
		G_OBJECT (composer), (GWeakNotify)
		composer_autosave_notify, NULL);

	if (autosave_source_id == 0)
		autosave_source_id = g_timeout_add (
			AUTOSAVE_INTERVAL, (GSourceFunc)
			composer_autosave_timeout, NULL);
}
Ejemplo n.º 16
0
static void
composer_web_view_load_status_changed_cb (WebKitWebView *webkit_web_view,
					  GParamSpec *pspec,
					  EMsgComposer *composer)
{
	WebKitLoadStatus status;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	status = webkit_web_view_get_load_status (webkit_web_view);

	if (status != WEBKIT_LOAD_FINISHED)
		return;

	g_signal_handlers_disconnect_by_func (
		webkit_web_view,
		G_CALLBACK (composer_web_view_load_status_changed_cb),
		NULL);

	e_composer_update_signature (composer);
}
Ejemplo n.º 17
0
EMsgComposer *
e_composer_load_snapshot_finish (EShell *shell,
                                 GAsyncResult *result,
                                 GError **error)
{
	GSimpleAsyncResult *simple;
	LoadContext *context;

	g_return_val_if_fail (
		g_simple_async_result_is_valid (
			result, G_OBJECT (shell),
			e_composer_load_snapshot), NULL);

	simple = G_SIMPLE_ASYNC_RESULT (result);
	context = g_simple_async_result_get_op_res_gpointer (simple);

	if (g_simple_async_result_propagate_error (simple, error))
		return NULL;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (context->composer), NULL);

	return g_object_ref (context->composer);
}
Ejemplo n.º 18
0
gboolean
e_composer_paste_image (EMsgComposer *composer,
                        GtkClipboard *clipboard)
{
	EHTMLEditor *editor;
	EHTMLEditorView *html_editor_view;
	EAttachmentStore *store;
	EAttachmentView *view;
	GdkPixbuf *pixbuf = NULL;
	gchar *filename = NULL;
	gchar *uri = NULL;
	gboolean success = FALSE;
	GError *error = NULL;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
	g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE);

	view = e_msg_composer_get_attachment_view (composer);
	store = e_attachment_view_get_store (view);

	/* Extract the image data from the clipboard. */
	pixbuf = gtk_clipboard_wait_for_image (clipboard);
	g_return_val_if_fail (pixbuf != NULL, FALSE);

	/* Reserve a temporary file. */
	filename = e_mktemp (NULL);
	if (filename == NULL) {
		g_set_error (
			&error, G_FILE_ERROR,
			g_file_error_from_errno (errno),
			"Could not create temporary file: %s",
			g_strerror (errno));
		goto exit;
	}

	/* Save the pixbuf as a temporary file in image/png format. */
	if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL))
		goto exit;

	/* Convert the filename to a URI. */
	uri = g_filename_to_uri (filename, NULL, &error);
	if (uri == NULL)
		goto exit;

	/* In HTML mode, paste the image into the message body.
	 * In text mode, add the image to the attachment store. */
	editor = e_msg_composer_get_editor (composer);
	html_editor_view = e_html_editor_get_view (editor);
	if (e_html_editor_view_get_html_mode (html_editor_view)) {
		EHTMLEditorSelection *selection;

		selection = e_html_editor_view_get_selection (html_editor_view);
		e_html_editor_selection_insert_image (selection, uri);
		e_html_editor_selection_scroll_to_caret (selection);
	} else {
		EAttachment *attachment;

		attachment = e_attachment_new_for_uri (uri);
		e_attachment_store_add_attachment (store, attachment);
		e_attachment_load_async (
			attachment, (GAsyncReadyCallback)
			e_attachment_load_handle_error, composer);
		g_object_unref (attachment);
	}

	success = TRUE;

exit:
	if (error != NULL) {
		g_warning ("%s", error->message);
		g_error_free (error);
	}

	g_object_unref (pixbuf);
	g_free (filename);
	g_free (uri);

	return success;
}
Ejemplo n.º 19
0
gboolean
e_composer_autosave_snapshot (EMsgComposer *composer)
{
	GtkhtmlEditor *editor;
	CamelMimeMessage *message;
	AutosaveState *state;
	CamelStream *stream;
	gint camelfd;
	const gchar *errmsg;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);

	editor = GTKHTML_EDITOR (composer);

	/* If the contents are unchanged, exit early. */
	if (!gtkhtml_editor_get_changed (editor))
		return TRUE;

	state = g_object_get_data (G_OBJECT (composer), "autosave");
	g_return_val_if_fail (state != NULL, FALSE);

	/* Open the autosave file on-demand. */
	if (!composer_autosave_state_open (state, NULL)) {
		errmsg = _("Could not open autosave file");
		goto fail;
	}

	/* Extract a MIME message from the composer. */
	message = e_msg_composer_get_message_draft (composer);
	if (message == NULL) {
		errmsg = _("Unable to retrieve message from editor");
		goto fail;
	}

	/* Move to the beginning of the autosave file. */
	if (lseek (state->fd, (off_t) 0, SEEK_SET) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Destroy the contents of the autosave file. */
	if (ftruncate (state->fd, (off_t) 0) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Duplicate the file descriptor for Camel. */
	if ((camelfd = dup (state->fd)) < 0) {
		camel_object_unref (message);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Open a CamelStream to the autosave file. */
	stream = camel_stream_fs_new_with_fd (camelfd);

	/* Write the message to the CamelStream. */
	if (camel_data_wrapper_write_to_stream (CAMEL_DATA_WRAPPER (message), stream) < 0) {
		camel_object_unref (message);
		camel_object_unref (stream);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Close the CamelStream. */
	if (camel_stream_close (CAMEL_STREAM (stream)) < 0) {
		camel_object_unref (message);
		camel_object_unref (stream);
		errmsg = g_strerror (errno);
		goto fail;
	}

	/* Snapshot was successful; set various flags. */
	gtkhtml_editor_set_changed (editor, FALSE);
	e_composer_autosave_set_saved (composer, TRUE);

	camel_object_unref (message);
	camel_object_unref (stream);

	return TRUE;

fail:
	e_error_run (
		GTK_WINDOW (composer), "mail-composer:no-autosave",
		(state->filename != NULL) ? state->filename : "",
		errmsg, NULL);

	return FALSE;
}
Ejemplo n.º 20
0
void
e_composer_actions_init (EMsgComposer *composer)
{
	GtkActionGroup *action_group;
	GtkAccelGroup *accel_group;
	GtkUIManager *ui_manager;
	EHTMLEditor *editor;
	EContentEditor *cnt_editor;
	gboolean visible;
	GIcon *gcr_gnupg_icon;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	editor = e_msg_composer_get_editor (composer);
	cnt_editor = e_html_editor_get_content_editor (editor);
	ui_manager = e_html_editor_get_ui_manager (editor);

	/* Composer Actions */
	action_group = composer->priv->composer_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	gtk_action_group_add_actions (
		action_group, entries,
		G_N_ELEMENTS (entries), composer);
	gtk_action_group_add_toggle_actions (
		action_group, toggle_entries,
		G_N_ELEMENTS (toggle_entries), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Asynchronous Actions */
	action_group = composer->priv->async_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	gtk_action_group_add_actions (
		action_group, async_entries,
		G_N_ELEMENTS (async_entries), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Character Set Actions */
	action_group = composer->priv->charset_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	e_charset_add_radio_actions (
		action_group, "charset-", composer->priv->charset,
		G_CALLBACK (action_charset_cb), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Fine Tuning */

	g_object_set (
		ACTION (ATTACH), "short-label", _("Attach"), NULL);

	g_object_set (
		ACTION (PICTURE_GALLERY), "is-important", TRUE, NULL);

	g_object_set (
		ACTION (SAVE_DRAFT), "short-label", _("Save Draft"), NULL);

	#define init_toolbar_option(x, always_visible)	\
		gtk_action_set_visible (ACTION (TOOLBAR_ ## x), always_visible); \
		e_binding_bind_property ( \
			ACTION (x), "active", \
			ACTION (TOOLBAR_ ## x), "active", \
			G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); \
		e_binding_bind_property ( \
			ACTION (x), "label", \
			ACTION (TOOLBAR_ ## x), "label", \
			G_BINDING_SYNC_CREATE); \
		e_binding_bind_property ( \
			ACTION (x), "tooltip", \
			ACTION (TOOLBAR_ ## x), "tooltip", \
			G_BINDING_SYNC_CREATE); \
		e_binding_bind_property ( \
			ACTION (x), "sensitive", \
			ACTION (TOOLBAR_ ## x), "sensitive", \
			G_BINDING_SYNC_CREATE); \
		g_signal_connect (ACTION (TOOLBAR_ ## x), "toggled", \
			G_CALLBACK (composer_actions_toolbar_option_toggled_cb), composer);

	init_toolbar_option (PGP_SIGN, FALSE);
	init_toolbar_option (PGP_ENCRYPT, FALSE);
	init_toolbar_option (PRIORITIZE_MESSAGE, TRUE);
	init_toolbar_option (REQUEST_READ_RECEIPT, TRUE);
	init_toolbar_option (SMIME_SIGN, FALSE);
	init_toolbar_option (SMIME_ENCRYPT, FALSE);

	#undef init_toolbar_option

	/* Borrow a GnuPG icon from gcr to distinguish between GPG and S/MIME Sign/Encrypt actions */
	gcr_gnupg_icon = g_themed_icon_new ("gcr-gnupg");
	if (gcr_gnupg_icon) {
		GIcon *temp_icon;
		GIcon *action_icon;
		GEmblem *emblem;
		GtkAction *action;

		emblem = g_emblem_new (gcr_gnupg_icon);

		action = ACTION (TOOLBAR_PGP_SIGN);
		action_icon = g_themed_icon_new (gtk_action_get_icon_name (action));
		temp_icon = g_emblemed_icon_new (action_icon, emblem);
		g_object_unref (action_icon);

		gtk_action_set_gicon (action, temp_icon);
		g_object_unref (temp_icon);

		action = ACTION (TOOLBAR_PGP_ENCRYPT);
		action_icon = g_themed_icon_new (gtk_action_get_icon_name (action));
		temp_icon = g_emblemed_icon_new (action_icon, emblem);
		g_object_unref (action_icon);

		gtk_action_set_gicon (action, temp_icon);
		g_object_unref (temp_icon);

		g_object_unref (emblem);
		g_object_unref (gcr_gnupg_icon);
	}

	e_binding_bind_property (
		cnt_editor, "html-mode",
		ACTION (PICTURE_GALLERY), "sensitive",
		G_BINDING_SYNC_CREATE);

	e_binding_bind_property (
		cnt_editor, "editable",
		e_html_editor_get_action (editor, "edit-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	e_binding_bind_property (
		cnt_editor, "editable",
		e_html_editor_get_action (editor, "format-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	e_binding_bind_property (
		cnt_editor, "editable",
		e_html_editor_get_action (editor, "insert-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	e_binding_bind_property (
		cnt_editor, "editable",
		e_html_editor_get_action (editor, "options-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	e_binding_bind_property (
		cnt_editor, "editable",
		e_html_editor_get_action (editor, "picture-gallery"), "sensitive",
		G_BINDING_SYNC_CREATE);

#if defined (ENABLE_SMIME)
	visible = TRUE;
#else
	visible = FALSE;
#endif

	gtk_action_set_visible (ACTION (SMIME_ENCRYPT), visible);
	gtk_action_set_visible (ACTION (SMIME_SIGN), visible);

	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
	g_signal_connect (accel_group, "accel-activate",
		G_CALLBACK (composer_actions_accel_activate_cb), composer);
}
Ejemplo n.º 21
0
gboolean
e_composer_selection_is_image_uris (EMsgComposer *composer,
                                    GtkSelectionData *selection)
{
	gboolean all_image_uris = TRUE;
	gchar **uris;
	guint ii;

	g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE);
	g_return_val_if_fail (selection != NULL, FALSE);

	uris = gtk_selection_data_get_uris (selection);

	if (!uris)
		return FALSE;

	for (ii = 0; uris[ii] != NULL; ii++) {
		GFile *file;
		GFileInfo *file_info;
		GdkPixbufLoader *loader;
		const gchar *attribute;
		const gchar *content_type;
		gchar *mime_type = NULL;

		file = g_file_new_for_uri (uris[ii]);
		attribute = G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE;

		/* XXX This blocks, but we're requesting the fast content
		 *     type (which only inspects filenames), so hopefully
		 *     it won't be noticeable.  Also, this is best effort
		 *     so we don't really care if it fails. */
		file_info = g_file_query_info (
			file, attribute, G_FILE_QUERY_INFO_NONE, NULL, NULL);

		if (file_info == NULL) {
			g_object_unref (file);
			all_image_uris = FALSE;
			break;
		}

		content_type = g_file_info_get_attribute_string (
			file_info, attribute);
		mime_type = g_content_type_get_mime_type (content_type);

		g_object_unref (file_info);
		g_object_unref (file);

		if (mime_type == NULL) {
			all_image_uris = FALSE;
			break;
		}

		/* Easy way to determine if a MIME type is a supported
		 * image format: try creating a GdkPixbufLoader for it. */
		loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, NULL);

		g_free (mime_type);

		if (loader == NULL) {
			all_image_uris = FALSE;
			break;
		}

		gdk_pixbuf_loader_close (loader, NULL);
		g_object_unref (loader);
	}

	g_strfreev (uris);

	return all_image_uris;
}
Ejemplo n.º 22
0
void
e_composer_actions_init (EMsgComposer *composer)
{
	GtkActionGroup *action_group;
	GtkAccelGroup *accel_group;
	GtkUIManager *ui_manager;
	EHTMLEditor *editor;
	EHTMLEditorView *view;
	gboolean visible;

	g_return_if_fail (E_IS_MSG_COMPOSER (composer));

	editor = e_msg_composer_get_editor (composer);
	view = e_html_editor_get_view (editor);
	ui_manager = e_html_editor_get_ui_manager (editor);

	/* Composer Actions */
	action_group = composer->priv->composer_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	gtk_action_group_add_actions (
		action_group, entries,
		G_N_ELEMENTS (entries), composer);
	gtk_action_group_add_toggle_actions (
		action_group, toggle_entries,
		G_N_ELEMENTS (toggle_entries), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Asynchronous Actions */
	action_group = composer->priv->async_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	gtk_action_group_add_actions (
		action_group, async_entries,
		G_N_ELEMENTS (async_entries), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Character Set Actions */
	action_group = composer->priv->charset_actions;
	gtk_action_group_set_translation_domain (
		action_group, GETTEXT_PACKAGE);
	e_charset_add_radio_actions (
		action_group, "charset-", composer->priv->charset,
		G_CALLBACK (action_charset_cb), composer);
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);

	/* Fine Tuning */

	g_object_set (
		ACTION (ATTACH), "short-label", _("Attach"), NULL);

	g_object_set (
		ACTION (PICTURE_GALLERY), "is-important", TRUE, NULL);

	g_object_set (
		ACTION (SAVE_DRAFT), "short-label", _("Save Draft"), NULL);

	g_object_bind_property (
		view, "html-mode",
		ACTION (PICTURE_GALLERY), "sensitive",
		G_BINDING_SYNC_CREATE);

	g_object_bind_property (
		view, "editable",
		e_html_editor_get_action (editor, "edit-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	g_object_bind_property (
		view, "editable",
		e_html_editor_get_action (editor, "format-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	g_object_bind_property (
		view, "editable",
		e_html_editor_get_action (editor, "insert-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	g_object_bind_property (
		view, "editable",
		e_html_editor_get_action (editor, "options-menu"), "sensitive",
		G_BINDING_SYNC_CREATE);

	g_object_bind_property (
		view, "editable",
		e_html_editor_get_action (editor, "picture-gallery"), "sensitive",
		G_BINDING_SYNC_CREATE);

#if defined (HAVE_NSS)
	visible = TRUE;
#else
	visible = FALSE;
#endif

	gtk_action_set_visible (ACTION (SMIME_ENCRYPT), visible);
	gtk_action_set_visible (ACTION (SMIME_SIGN), visible);

	accel_group = gtk_ui_manager_get_accel_group (ui_manager);
	g_signal_connect (accel_group, "accel-activate",
		G_CALLBACK (composer_actions_accel_activate_cb), composer);
}