[Gpa-commits] r801 - in trunk: . po src

scm-commit@wald.intevation.org scm-commit at wald.intevation.org
Mon Feb 4 21:53:40 CET 2008


Author: marcus
Date: 2008-02-04 21:53:39 +0100 (Mon, 04 Feb 2008)
New Revision: 801

Added:
   trunk/src/clipboard.c
   trunk/src/clipboard.h
Modified:
   trunk/TODO
   trunk/po/ChangeLog
   trunk/po/POTFILES.in
   trunk/src/ChangeLog
   trunk/src/Makefile.am
   trunk/src/encryptdlg.c
   trunk/src/encryptdlg.h
   trunk/src/fileman.c
   trunk/src/filesigndlg.c
   trunk/src/filesigndlg.h
   trunk/src/gpa.c
   trunk/src/gpa.h
   trunk/src/gpafiledecryptop.c
   trunk/src/gpafiledecryptop.h
   trunk/src/gpafileencryptop.c
   trunk/src/gpafileencryptop.h
   trunk/src/gpafileop.c
   trunk/src/gpafileop.h
   trunk/src/gpafilesignop.c
   trunk/src/gpafilesignop.h
   trunk/src/gpafileverifyop.c
   trunk/src/gpastreamencryptop.c
   trunk/src/gpawidgets.c
   trunk/src/helpmenu.c
   trunk/src/keyimpseldlg.c
   trunk/src/keyring.c
   trunk/src/settingsdlg.c
Log:
po/
2008-02-04  Marcus Brinkmann  <marcus at g10code.de>

	* POTFILES.in: Add clipboard.h and clipboard.c.

src/
2008-02-04  Marcus Brinkmann  <marcus at g10code.de>

	* Makefile.am (gpa_SOURCES): Add clipboard.h and clipboard.c.
	* clipboard.h, clipboard.c: New files.
	* gpa.h (gpa_open_clipboard): New prototype.
	* gpa.c: Include "clipboard.h".
	(quit_if_no_window): Also check for clipboard window).
	(gpa_open_clipboard): New window.
	* keyring.c (win_menu): Add clipboard window.
	(keyring_toolbar_new): Add clipboard window.
	* fileman.c (get_selected_files): Use file_item.
	(file_created_cb): Change type of second argument to gpa_file_item_t.
	(sign_files): Add new argument to gpa_file_sign_operation_new.
	(encrypt_files): Add new argument to gpa_file_encrypt_operation_new.
	(windows_menu): Add clipboard window.
	(fileman_toolbar_new): Add clipboard window.
	(gpa_file_manager_constructor): Use gtk_window_set_default_size
	rather than gtk_widget_set_usize.
	* encryptdlg.h (struct _GpaFileEncryptDialog): New members
	scroller_who and force_armor.
	(gpa_file_encrypt_dialog_new): Add new argument force_armor to
	prototype.
	* encryptdlg.c: Add property PROP_FORCE_ARMOR to property enum.
	(gpa_file_encrypt_dialog_get_property)
	(gpa_file_encrypt_dialog_set_property): Support it.
	(gpa_file_encrypt_dialog_init): Move bunch of it to ...
	(gpa_file_encrypt_dialog_constructor): ... this new function.  Use
	gtk_window_set_default_size rather than gtk_widget_set_usize.
	Support force_armor.  Desensitize scrolled window instead of
	keylisting to fix a bug.
	(changed_select_row_cb): Likewise.
	(gpa_file_encrypt_dialog_class_init): Install new property.
	(gpa_file_encrypt_dialog_new): New argument force_armor, use it.
	* filesigndlg.h (struct _GpaFileSignDialog): New members
	scroller_who and force_armor.
	(gpa_file_sign_dialog_new): Add new argument force_armor to
	prototype.
	* filesigndlg.c: Add property PROP_FORCE_ARMOR to property enum.
	(gpa_file_sign_dialog_get_property)
	(gpa_file_sign_dialog_set_property): Support it.
	(gpa_file_sign_dialog_constructor): Use	gtk_window_set_default_size
	rather than gtk_widget_set_usize.  Support force_armor.
	(gpa_file_sign_dialog_class_init): Install new property.
	(gpa_file_sign_dialog_new): New argument force_armor, use it.
	* gpafileop.h (struct gpa_file_item_s): New structure.
	(gpa_file_item_t): New type.
	* gpafileop.c (free_file_item): New function
	(gpa_file_operation_finalize): Use it instead of g_free.
	(gpa_file_operation_class_init): Change argument type of callback
	to pointer.
	(gpa_file_operation_current_file): Use file_item.
	* gpafileverifyop.c (gpa_file_verify_operation_start): Change
	second argument to type file_item.  Use it to support direct memory.
	(gpa_file_verify_operation_done_cb): Use file_item.
	(gpa_file_verify_operation_done_error_cb): Use file_item.
	* gpafiledecryptop.h (_GpaFileDecryptOperation): Remove member
	plain_filename.
	* gpafiledecryptop.c (gpa_file_decrypt_operation_init): Do not
	reset OP->plain_filename.
	(gpa_file_decrypt_operation_start): Change second argument to type
	file_item.  Use it to support direct mode.
	(gpa_file_decrypt_operation_done_cb): Use file_item.
	(gpa_file_decrypt_operation_done_error_cb): Use file_item.
	* gpafilesignop.h (_GpaFileSignOperation): Add member force_armor.
	(gpa_file_sign_operation_new): Add new argument force_armor to
	prototype.
	* gpafilesignop.c: New properties enum.
	(gpa_file_sign_operation_get_property)
	(gpa_file_sign_operation_set_property): New functions.
	(gpa_file_sign_operation_init): Initialize OP->force_armor.
	(gpa_file_sign_operation_new): Add new argument force_armor, use it.
	(gpa_file_sign_operation_constructor): Add new argument to
	gpa_file_sign_dialog_new invocation.
	(gpa_file_sign_operation_class_init): Set class properties.
	(gpa_file_sign_operation_start): Change second argument to type
	gpa_file_item_t.  Support direct memory use.
	(gpa_file_sign_operation_done_cb): Use file_item.
	(gpa_file_sign_operation_done_error_cb): Use file_item.
	* gpafileencryptop.h (_GpaFileEncryptOperation): Add member force_armor,
	and remove member cipher_filename.
	(gpa_file_encrypt_operation_new): Add new argument force_armor to
	prototype.
	* gpafileencryptop.c: New properties enum.
	(gpa_file_encrypt_operation_get_property)
	(gpa_file_encrypt_operation_set_property): New functions.
	(gpa_file_encrypt_operation_init): Initialize OP->force_armor, do
	not initialize OP->cipher_filename.
	(gpa_file_encrypt_operation_new): Add new argument force_armor,	use it.
	(gpa_file_encrypt_operation_constructor): Add new argument to
	gpa_file_encrypt_dialog_new invocation.
	(gpa_file_encrypt_operation_class_init): Set class properties.
	(gpa_file_encrypt_operation_start): Change second argument to type
	gpa_file_item_t.  Support direct memory use.
	(gpa_file_encrypt_operation_done_cb): Use file_item.
	(gpa_file_encrypt_operation_done_error_cb): Use file_item.
	* gpastreamencryptop.c (gpa_stream_encrypt_operation_constructor):
	Add new argument to gpa_file_encrypt_dialog_new.
	* keyimpseldlg.c (gpa_key_import_selection_dialog_run): Use
	gtk_widget_set_size_request instead of gtk_widget_set_usize.
	* gpawidgets.c (gpa_expiry_frame_new): Likewise.
	* helpmenu.c (help_license): Likewise.
	* helpmenu.c (gpa_help_menu_add_to_factory): Use stock item for
	about menu.
	* settingsdlg.c (default_key_frame): Likewise.


Modified: trunk/TODO
===================================================================
--- trunk/TODO	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/TODO	2008-02-04 20:53:39 UTC (rev 801)
@@ -41,6 +41,18 @@
 * MB:
 ** Add a beauty bar to filemanager (requires an icon corresponding to
    keyring.xpm).
+** Add frame around filemanager list.
 ** Support receiving keys from keyservers for unknown certificates, by
    right click in "Signatures" tab of keyring manager and for all unknown
    keys in that list at once.
+** Support getting plaintext from verify operation (should emit "created file"
+   then).  NEEDED FOR CLIPBOARD of non clear text.
+** Make signer selection list a bit larger than one row.
+** clipboard: handle sensitivity of menu and toolbar items.
+   Force armor.
+** Change gpa_window_error to use gtk_label_set_line_wrap and remove
+   all those newlines. 
+** The sign, encrypt dialog and progress bar is not centered over the
+   parent.  Maybe it is realized too early due to init vs constructor?
+   It does get the right parent window parameter (checked that).
+** Use GtkAction instead of manual GLists for update sensitivity and stuff.

Modified: trunk/po/ChangeLog
===================================================================
--- trunk/po/ChangeLog	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/po/ChangeLog	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,7 @@
 2008-02-04  Marcus Brinkmann  <marcus at g10code.de>
 
+	* POTFILES.in: Add clipboard.h and clipboard.c.
+
 	* POTFILES.in: Add confdialog.c.
 
 2007-06-05  Marcus Brinkmann  <marcus at g10code.de>

Modified: trunk/po/POTFILES.in
===================================================================
--- trunk/po/POTFILES.in	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/po/POTFILES.in	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,3 +1,5 @@
+src/clipboard.h
+src/clipboard.c
 src/confdialog.c
 src/encryptdlg.c
 src/expirydlg.c

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/ChangeLog	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,108 @@
 2008-02-04  Marcus Brinkmann  <marcus at g10code.de>
 
+	* Makefile.am (gpa_SOURCES): Add clipboard.h and clipboard.c.
+	* clipboard.h, clipboard.c: New files.
+	* gpa.h (gpa_open_clipboard): New prototype.
+	* gpa.c: Include "clipboard.h".
+	(quit_if_no_window): Also check for clipboard window).
+	(gpa_open_clipboard): New window.
+	* keyring.c (win_menu): Add clipboard window.
+	(keyring_toolbar_new): Add clipboard window.
+	* fileman.c (get_selected_files): Use file_item.
+	(file_created_cb): Change type of second argument to gpa_file_item_t.
+	(sign_files): Add new argument to gpa_file_sign_operation_new.
+	(encrypt_files): Add new argument to gpa_file_encrypt_operation_new.
+	(windows_menu): Add clipboard window.
+	(fileman_toolbar_new): Add clipboard window.
+	(gpa_file_manager_constructor): Use gtk_window_set_default_size
+	rather than gtk_widget_set_usize.
+	* encryptdlg.h (struct _GpaFileEncryptDialog): New members
+	scroller_who and force_armor.
+	(gpa_file_encrypt_dialog_new): Add new argument force_armor to
+	prototype.
+	* encryptdlg.c: Add property PROP_FORCE_ARMOR to property enum.
+	(gpa_file_encrypt_dialog_get_property)
+	(gpa_file_encrypt_dialog_set_property): Support it.
+	(gpa_file_encrypt_dialog_init): Move bunch of it to ...
+	(gpa_file_encrypt_dialog_constructor): ... this new function.  Use
+	gtk_window_set_default_size rather than gtk_widget_set_usize.
+	Support force_armor.  Desensitize scrolled window instead of
+	keylisting to fix a bug.
+	(changed_select_row_cb): Likewise.
+	(gpa_file_encrypt_dialog_class_init): Install new property.
+	(gpa_file_encrypt_dialog_new): New argument force_armor, use it.
+	* filesigndlg.h (struct _GpaFileSignDialog): New members
+	scroller_who and force_armor.
+	(gpa_file_sign_dialog_new): Add new argument force_armor to
+	prototype.
+	* filesigndlg.c: Add property PROP_FORCE_ARMOR to property enum.
+	(gpa_file_sign_dialog_get_property)
+	(gpa_file_sign_dialog_set_property): Support it.
+	(gpa_file_sign_dialog_constructor): Use	gtk_window_set_default_size
+	rather than gtk_widget_set_usize.  Support force_armor.
+	(gpa_file_sign_dialog_class_init): Install new property.
+	(gpa_file_sign_dialog_new): New argument force_armor, use it.
+	* gpafileop.h (struct gpa_file_item_s): New structure.
+	(gpa_file_item_t): New type.
+	* gpafileop.c (free_file_item): New function
+	(gpa_file_operation_finalize): Use it instead of g_free.
+	(gpa_file_operation_class_init): Change argument type of callback
+	to pointer.
+	(gpa_file_operation_current_file): Use file_item.
+	* gpafileverifyop.c (gpa_file_verify_operation_start): Change
+	second argument to type file_item.  Use it to support direct memory.
+	(gpa_file_verify_operation_done_cb): Use file_item.
+	(gpa_file_verify_operation_done_error_cb): Use file_item.
+	* gpafiledecryptop.h (_GpaFileDecryptOperation): Remove member
+	plain_filename.
+	* gpafiledecryptop.c (gpa_file_decrypt_operation_init): Do not
+	reset OP->plain_filename.
+	(gpa_file_decrypt_operation_start): Change second argument to type
+	file_item.  Use it to support direct mode.
+	(gpa_file_decrypt_operation_done_cb): Use file_item.
+	(gpa_file_decrypt_operation_done_error_cb): Use file_item.
+	* gpafilesignop.h (_GpaFileSignOperation): Add member force_armor.
+	(gpa_file_sign_operation_new): Add new argument force_armor to
+	prototype.
+	* gpafilesignop.c: New properties enum.
+	(gpa_file_sign_operation_get_property)
+	(gpa_file_sign_operation_set_property): New functions.
+	(gpa_file_sign_operation_init): Initialize OP->force_armor.
+	(gpa_file_sign_operation_new): Add new argument force_armor, use it.
+	(gpa_file_sign_operation_constructor): Add new argument to
+	gpa_file_sign_dialog_new invocation.
+	(gpa_file_sign_operation_class_init): Set class properties.
+	(gpa_file_sign_operation_start): Change second argument to type
+	gpa_file_item_t.  Support direct memory use.
+	(gpa_file_sign_operation_done_cb): Use file_item.
+	(gpa_file_sign_operation_done_error_cb): Use file_item.
+	* gpafileencryptop.h (_GpaFileEncryptOperation): Add member force_armor,
+	and remove member cipher_filename.
+	(gpa_file_encrypt_operation_new): Add new argument force_armor to
+	prototype.
+	* gpafileencryptop.c: New properties enum.
+	(gpa_file_encrypt_operation_get_property)
+	(gpa_file_encrypt_operation_set_property): New functions.
+	(gpa_file_encrypt_operation_init): Initialize OP->force_armor, do
+	not initialize OP->cipher_filename.
+	(gpa_file_encrypt_operation_new): Add new argument force_armor,	use it.
+	(gpa_file_encrypt_operation_constructor): Add new argument to
+	gpa_file_encrypt_dialog_new invocation.
+	(gpa_file_encrypt_operation_class_init): Set class properties.
+	(gpa_file_encrypt_operation_start): Change second argument to type
+	gpa_file_item_t.  Support direct memory use.
+	(gpa_file_encrypt_operation_done_cb): Use file_item.
+	(gpa_file_encrypt_operation_done_error_cb): Use file_item.
+	* gpastreamencryptop.c (gpa_stream_encrypt_operation_constructor):
+	Add new argument to gpa_file_encrypt_dialog_new.
+	* keyimpseldlg.c (gpa_key_import_selection_dialog_run): Use
+	gtk_widget_set_size_request instead of gtk_widget_set_usize.
+	* gpawidgets.c (gpa_expiry_frame_new): Likewise.
+	* helpmenu.c (help_license): Likewise.
+	* helpmenu.c (gpa_help_menu_add_to_factory): Use stock item for
+	about menu.
+	* settingsdlg.c (default_key_frame): Likewise.
+
 	* confdialog.c (dialog_level): New global variable.
 	(comp_has_options, group_has_options): New functions.
 	(create_dialog_tabs_2): Skip groups with no displayable options.

Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/Makefile.am	2008-02-04 20:53:39 UTC (rev 801)
@@ -42,6 +42,7 @@
 	      icons.c icons.h \
 	      gpawidgets.c gpawidgets.h \
 	      fileman.c fileman.h \
+	      clipboard.h clipboard.c \
 	      filesigndlg.c filesigndlg.h \
 	      encryptdlg.c encryptdlg.h \
 	      verifydlg.c verifydlg.h \

Added: trunk/src/clipboard.c
===================================================================
--- trunk/src/clipboard.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/clipboard.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -0,0 +1,1103 @@
+/* clipboard.c  -  The GNU Privacy Assistant
+ * Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2007, 2008 g10 Code GmbH
+ *
+ * This file is part of GPA
+ *
+ * GPA 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.
+ *
+ * GPA 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+/*
+ *	The file encryption/decryption/sign window
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <time.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+
+#include "gpa.h"   
+#include "gpapastrings.h"
+
+#include "gtktools.h"
+#include "gpawidgets.h"
+#include "siglist.h"
+#include "helpmenu.h"
+#include "icons.h"
+#include "clipboard.h"
+
+#include "gpafiledecryptop.h"
+#include "gpafileencryptop.h"
+#include "gpafilesignop.h"
+#include "gpafileverifyop.h"
+
+
+/* FIXME:  Move to a global file.  */
+#ifndef DIM
+#define DIM(array) (sizeof (array) / sizeof (*array))
+#endif
+
+
+
+/* Object and class definition.  */
+struct _GpaClipboard
+{
+  GtkWindow parent;
+
+  GtkWidget *text_view;
+  GtkTextBuffer *text_buffer;
+
+  /* List of sensitive widgets. See below */
+  GList *selection_sensitive_widgets;
+  GList *paste_sensitive_widgets;
+  gboolean paste_p;
+};
+
+struct _GpaClipboardClass 
+{
+  GtkWindowClass parent_class;
+};
+
+
+
+/* There is only one instance of the clipboard class.  Use a global
+   variable to keep track of it.  */
+static GpaClipboard *instance;
+
+/* We also need to save the parent class.  */
+static GObjectClass *parent_class;
+
+
+/* Local prototypes */
+static GObject *gpa_clipboard_constructor 
+                         (GType type,
+                          guint n_construct_properties,
+                          GObjectConstructParam *construct_properties);
+
+
+/*
+ * GtkWidget boilerplate.
+ */
+static void
+gpa_clipboard_finalize (GObject *object)
+{  
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gpa_clipboard_init (GpaClipboard *clipboard)
+{
+  clipboard->selection_sensitive_widgets = NULL;
+  clipboard->paste_sensitive_widgets = NULL;
+}
+
+static void
+gpa_clipboard_class_init (GpaClipboardClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  parent_class = g_type_class_peek_parent (klass);
+  
+  object_class->constructor = gpa_clipboard_constructor;
+  object_class->finalize = gpa_clipboard_finalize;
+}
+
+GType
+gpa_clipboard_get_type (void)
+{
+  static GType clipboard_type = 0;
+  
+  if (!clipboard_type)
+    {
+      static const GTypeInfo clipboard_info =
+	{
+	  sizeof (GpaClipboardClass),
+	  (GBaseInitFunc) NULL,
+	  (GBaseFinalizeFunc) NULL,
+	  (GClassInitFunc) gpa_clipboard_class_init,
+	  NULL,           /* class_finalize */
+	  NULL,           /* class_data */
+	  sizeof (GpaClipboard),
+	  0,              /* n_preallocs */
+	  (GInstanceInitFunc) gpa_clipboard_init,
+	};
+      
+      clipboard_type = g_type_register_static (GTK_TYPE_WINDOW,
+					     "GpaClipboard",
+					     &clipboard_info, 0);
+    }
+  
+  return clipboard_type;
+}
+
+
+
+/* Definition of the sensitivity function type.  */
+typedef gboolean (*sensitivity_func_t)(gpointer);
+
+
+/* Add widget to the list of sensitive widgets of editor.  */
+static void
+add_selection_sensitive_widget (GpaClipboard *clipboard,
+                                GtkWidget *widget,
+                                sensitivity_func_t callback)
+{
+  gtk_object_set_data (GTK_OBJECT (widget), "gpa_sensitivity", callback);
+  clipboard->selection_sensitive_widgets
+    = g_list_append (clipboard->selection_sensitive_widgets, widget);
+}
+
+
+/* Return true if a selection is active.  */
+static gboolean
+has_selection (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  return gtk_text_buffer_get_has_selection
+    (GTK_TEXT_BUFFER (clipboard->text_buffer));
+}
+
+
+/* Update the sensitivity of the widget DATA and pass PARAM through to
+   the sensitivity callback. Usable as an iterator function in
+   g_list_foreach. */
+static void
+update_selection_sensitive_widget (gpointer data, gpointer param)
+{
+  sensitivity_func_t func;
+
+  func = gtk_object_get_data (GTK_OBJECT (data), "gpa_sensitivity");
+  gtk_widget_set_sensitive (GTK_WIDGET (data), func (param));
+}
+
+
+/* Call update_selection_sensitive_widget for all widgets in the list
+   of sensitive widgets and pass CLIPBOARD through as the user data
+   parameter.  */
+static void
+update_selection_sensitive_widgets (GpaClipboard *clipboard)
+{
+  g_list_foreach (clipboard->selection_sensitive_widgets,
+                  update_selection_sensitive_widget,
+                  (gpointer) clipboard);
+}
+
+
+/* Add widget to the list of sensitive widgets of editor.  */
+static void
+add_paste_sensitive_widget (GpaClipboard *clipboard, GtkWidget *widget)
+{
+  clipboard->paste_sensitive_widgets
+    = g_list_append (clipboard->paste_sensitive_widgets, widget);
+}
+
+
+static void
+update_paste_sensitive_widget (gpointer data, gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  gtk_widget_set_sensitive (GTK_WIDGET (data), clipboard->paste_p);
+}
+
+
+static void
+update_paste_sensitive_widgets (GtkClipboard *clip,
+				GtkSelectionData *selection_data,
+				GpaClipboard *clipboard)
+{
+  clipboard->paste_p = gtk_selection_data_targets_include_text (selection_data);
+
+  g_list_foreach (clipboard->paste_sensitive_widgets,
+                  update_paste_sensitive_widget, (gpointer) clipboard);
+}
+
+
+static void
+set_paste_sensitivity (GpaClipboard *clipboard, GtkClipboard *clip)
+{
+  GdkDisplay *display;
+
+  display = gtk_clipboard_get_display (clip);
+  
+  if (gdk_display_supports_selection_notification (display))
+    gtk_clipboard_request_contents
+      (clip, gdk_atom_intern_static_string ("TARGETS"),
+       (GtkClipboardReceivedFunc) update_paste_sensitive_widgets,
+       clipboard);
+}
+
+
+static void
+clipboard_owner_change_cb (GtkClipboard *clip, GdkEventOwnerChange *event,
+			   GpaClipboard *clipboard)
+{
+  set_paste_sensitivity (clipboard, clip);
+}
+
+
+/* Add a file created by an operation to the list */
+static void
+file_created_cb (GpaFileOperation *op, gpa_file_item_t item, gpointer data)
+{
+  GpaClipboard *clipboard = data;
+  gboolean suc;
+  const gchar *end;
+  
+  suc = g_utf8_validate (item->direct_out, item->direct_out_len, &end);
+  if (! suc)
+    {
+      gchar *str;
+      str = g_strdup_printf ("Error in operation result:\n"
+			     "No valid UTF-8 at position %i.",
+			     ((int) (end - item->direct_out)));
+      gpa_window_error (str, GTK_WIDGET (clipboard));
+      g_free (str);
+      return;
+    }
+
+  
+  gtk_text_buffer_set_text (clipboard->text_buffer,
+			    item->direct_out, item->direct_out_len);
+}
+
+
+/* Do whatever is required with a file operation, to ensure proper clean up */
+static void
+register_operation (GpaClipboard *clipboard, GpaFileOperation *op)
+{
+  g_signal_connect (G_OBJECT (op), "created_file",
+		    G_CALLBACK (file_created_cb), clipboard);
+  g_signal_connect (G_OBJECT (op), "completed",
+		    G_CALLBACK (g_object_unref), NULL);
+}
+
+
+
+/* Actions as called by the menu items.  */
+
+
+/* Handle menu item "File/Clear".  */
+static void
+file_clear (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  gtk_text_buffer_set_text (clipboard->text_buffer, "", -1);
+}
+
+
+/* Handle menu item "File/Open".  */
+static void
+file_open (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+  gchar *filename;
+  struct stat buf;
+  int res;
+  gboolean suc;
+  gchar *contents;
+  gsize length;
+  GError *err = NULL;
+  const gchar *end;
+
+  filename = gpa_get_load_file_name (GTK_WIDGET (clipboard),
+                                     _("Open File"), NULL);
+  if (! filename)
+    return;
+
+  res = g_stat (filename, &buf);
+  if (res < 0)
+    {
+      gchar *str;
+      str = g_strdup_printf ("Error determining size of file %s:\n%s",
+			     filename, strerror (errno));
+      gpa_window_error (str, GTK_WIDGET (clipboard));
+      g_free (str);
+      g_free (filename);
+      return;
+   }
+
+#define MAX_CLIPBOARD_SIZE (2*1024*1024)
+
+  if (buf.st_size > MAX_CLIPBOARD_SIZE)
+    {
+      GtkWidget *window;
+      GtkWidget *hbox;
+      GtkWidget *labelMessage;
+      GtkWidget *pixmap;
+      gint result;
+      gchar *str;
+
+      window = gtk_dialog_new_with_buttons
+	(_("GPA Message"), GTK_WINDOW (clipboard), GTK_DIALOG_MODAL,
+	 GTK_STOCK_OPEN, GTK_RESPONSE_OK,
+	 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
+
+      gtk_container_set_border_width (GTK_CONTAINER (window), 5);
+      gtk_dialog_set_default_response (GTK_DIALOG (window),
+				       GTK_RESPONSE_CANCEL);
+
+      hbox = gtk_hbox_new (FALSE, 0);
+      gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+      gtk_box_pack_start_defaults (GTK_BOX (GTK_DIALOG (window)->vbox), hbox);
+      pixmap = gtk_image_new_from_stock (GTK_STOCK_DIALOG_INFO,
+					 GTK_ICON_SIZE_DIALOG);
+      gtk_box_pack_start (GTK_BOX (hbox), pixmap, TRUE, FALSE, 10);
+
+      str = g_strdup_printf (_("The file %s is %li%s large.  Do you really "
+			       " want to open it?"), filename, 
+			       buf.st_size / 1024 / 1024, "MB");
+      labelMessage = gtk_label_new (str);
+      g_free (str);
+      gtk_label_set_line_wrap (GTK_LABEL (labelMessage), TRUE);
+      gtk_box_pack_start (GTK_BOX (hbox), labelMessage, TRUE, FALSE, 10);
+      
+      gtk_widget_show_all (window);
+      result = gtk_dialog_run (GTK_DIALOG (window));
+      gtk_widget_destroy (window);
+
+      if (result != GTK_RESPONSE_OK)
+	{
+	  g_free (filename);
+	  return;
+	}
+    }
+  
+  suc = g_file_get_contents (filename, &contents, &length, &err);
+  if (! suc)
+    {
+      gchar *str;
+      str = g_strdup_printf ("Error loading content of file %s:\n%s",
+			     filename, err->message);
+      gpa_window_error (str, GTK_WIDGET (clipboard));
+      g_free (str);
+      g_error_free (err);
+      g_free (filename);
+      return;
+    }
+
+  suc = g_utf8_validate (contents, length, &end);
+  if (! suc)
+    {
+      gchar *str;
+      str = g_strdup_printf ("Error opening file %s:\n"
+			     "No valid UTF-8 at position %i.",
+			     filename, ((int) (end - contents)));
+      gpa_window_error (str, GTK_WIDGET (clipboard));
+      g_free (str);
+      g_free (contents);
+      g_free (filename);
+      return;
+    }
+  
+  gtk_text_buffer_set_text (clipboard->text_buffer, contents, length);
+  g_free (contents);
+}
+
+
+/* Handle menu item "File/Save As...".  */
+static void
+file_save_as (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+  gchar *filename;
+  GError *err = NULL;
+  gchar *contents;
+  gssize length;
+  gboolean suc;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  filename = gpa_get_save_file_name (GTK_WIDGET (clipboard),
+				     _("Save As..."), NULL);
+  if (! filename)
+    return;
+
+  gtk_text_buffer_get_bounds (clipboard->text_buffer, &begin, &end);
+  contents = gtk_text_buffer_get_text (clipboard->text_buffer, &begin, &end,
+				       FALSE);
+  length = strlen (contents);
+
+  suc = g_file_set_contents (filename, contents, length, &err);
+  g_free (contents);
+  if (! suc)
+    {
+      gchar *str;
+      str = g_strdup_printf ("Error saving content to file %s:\n%s",
+			     filename, err->message);
+      gpa_window_error (str, GTK_WIDGET (clipboard));
+      g_free (str);
+      g_error_free (err);
+      g_free (filename);
+      return;
+    }
+  
+  g_free (filename);
+}
+
+
+/* Handle menu item "File/Verify".  */
+static void
+file_verify (gpointer param)
+{
+  GpaClipboard *clipboard = (GpaClipboard *) param;
+  GpaFileVerifyOperation *op;
+  GList *files = NULL;
+  gpa_file_item_t file_item;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  gtk_text_buffer_get_bounds (clipboard->text_buffer, &begin, &end);
+
+  file_item = g_malloc0 (sizeof (*file_item));
+  file_item->direct_name = g_strdup (_("Clipboard"));
+  file_item->direct_in
+    = gtk_text_buffer_get_slice (clipboard->text_buffer, &begin, &end, TRUE);
+  /* FIXME: One would think there exists a function to get the number
+     of bytes between two GtkTextIter, but no, that's too obvious.  */
+  file_item->direct_in_len = strlen (file_item->direct_in);
+  printf ("Region: %i  %i %i %i\n", file_item->direct_in_len,
+	  gtk_text_iter_get_offset (&begin),
+	  gtk_text_iter_get_offset (&end),
+	  gtk_text_iter_get_offset (&end) - gtk_text_iter_get_offset (&begin));
+
+  files = g_list_append (files, file_item);
+  
+  /* Start the operation.  */
+  op = gpa_file_verify_operation_new (GTK_WIDGET (clipboard), files);
+  
+  register_operation (clipboard, GPA_FILE_OPERATION (op));
+}
+
+
+/* Handle menu item "File/Sign".  */
+static void
+file_sign (gpointer param)
+{
+  GpaClipboard *clipboard = (GpaClipboard *) param;
+  GpaFileSignOperation *op;
+  GList *files = NULL;
+  gpa_file_item_t file_item;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  gtk_text_buffer_get_bounds (clipboard->text_buffer, &begin, &end);
+
+  file_item = g_malloc0 (sizeof (*file_item));
+  file_item->direct_name = g_strdup (_("Clipboard"));
+  file_item->direct_in
+    = gtk_text_buffer_get_text (clipboard->text_buffer, &begin, &end, FALSE);
+  /* FIXME: One would think there exists a function to get the number
+     of bytes between two GtkTextIter, but no, that's too obvious.  */
+  file_item->direct_in_len = strlen (file_item->direct_in);
+
+  files = g_list_append (files, file_item);
+  
+  /* Start the operation.  */
+  op = gpa_file_sign_operation_new (GTK_WIDGET (clipboard), files, TRUE);
+  
+  register_operation (clipboard, GPA_FILE_OPERATION (op));
+}
+
+
+/* Handle menu item "File/Encrypt".  */
+static void
+file_encrypt (gpointer param)
+{
+  GpaClipboard *clipboard = (GpaClipboard *) param;
+  GpaFileEncryptOperation *op;
+  GList *files = NULL;
+  gpa_file_item_t file_item;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  gtk_text_buffer_get_bounds (clipboard->text_buffer, &begin, &end);
+
+  file_item = g_malloc0 (sizeof (*file_item));
+  file_item->direct_name = g_strdup (_("Clipboard"));
+  file_item->direct_in
+    = gtk_text_buffer_get_text (clipboard->text_buffer, &begin, &end, FALSE);
+  /* FIXME: One would think there exists a function to get the number
+     of bytes between two GtkTextIter, but no, that's too obvious.  */
+  file_item->direct_in_len = strlen (file_item->direct_in);
+
+  files = g_list_append (files, file_item);
+  
+  /* Start the operation.  */
+  op = gpa_file_encrypt_operation_new (GTK_WIDGET (clipboard), files, TRUE);
+
+  register_operation (clipboard, GPA_FILE_OPERATION (op));
+}
+
+
+/* Handle menu item "File/Decrypt".  */
+static void
+file_decrypt (gpointer param)
+{
+  GpaClipboard *clipboard = (GpaClipboard *) param;
+  GpaFileDecryptOperation *op;
+  GList *files = NULL;
+  gpa_file_item_t file_item;
+  GtkTextIter begin;
+  GtkTextIter end;
+
+  gtk_text_buffer_get_bounds (clipboard->text_buffer, &begin, &end);
+
+  file_item = g_malloc0 (sizeof (*file_item));
+  file_item->direct_name = g_strdup (_("Clipboard"));
+  file_item->direct_in
+    = gtk_text_buffer_get_text (clipboard->text_buffer, &begin, &end, FALSE);
+  /* FIXME: One would think there exists a function to get the number
+     of bytes between two GtkTextIter, but no, that's too obvious.  */
+  file_item->direct_in_len = strlen (file_item->direct_in);
+
+  files = g_list_append (files, file_item);
+  
+  /* Start the operation.  */
+  op = gpa_file_decrypt_operation_new (GTK_WIDGET (clipboard), files);
+  
+  register_operation (clipboard, GPA_FILE_OPERATION (op));
+}
+
+
+/* Handle menu item "File/Close".  */
+static void
+file_close (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+  gtk_widget_destroy (GTK_WIDGET (clipboard));
+}
+
+
+static void
+edit_cut (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  g_signal_emit_by_name (GTK_TEXT_VIEW (clipboard->text_view),
+			 "cut-clipboard");
+}
+
+
+static void
+edit_copy (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  g_signal_emit_by_name (GTK_TEXT_VIEW (clipboard->text_view),
+			 "copy-clipboard");
+}
+
+
+static void
+edit_paste (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  g_signal_emit_by_name (GTK_TEXT_VIEW (clipboard->text_view),
+			 "paste-clipboard");
+}
+
+
+static void
+edit_delete (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  g_signal_emit_by_name (GTK_TEXT_VIEW (clipboard->text_view), "backspace");
+}
+
+
+/* Handle menu item "Edit/Select All".  */
+static void
+edit_select_all (gpointer param)
+{
+  GpaClipboard *clipboard = param;
+
+  g_signal_emit_by_name (GTK_TEXT_VIEW (clipboard->text_view), "select-all");
+}
+
+
+/* Construct the file manager menu window and return that object. */
+static GtkWidget *
+clipboard_menu_new (GpaClipboard *clipboard)
+{
+  GtkItemFactory *factory;
+  GtkItemFactoryEntry file_menu[] = {
+    {_("/_File"), NULL, NULL, 0, "<Branch>"},
+    {_("/File/C_lear"), NULL, file_clear, 0, "<StockItem>", GTK_STOCK_CLEAR},
+    {_("/File/_Open"), NULL, file_open, 0, "<StockItem>", GTK_STOCK_OPEN},
+    {_("/File/Save _As"), NULL, file_save_as, 0, "<StockItem>",
+     GTK_STOCK_SAVE_AS},
+    {_("/File/sep1"), NULL, NULL, 0, "<Separator>"},
+    {_("/File/_Sign"), NULL, file_sign, 0, NULL},
+    {_("/File/_Verify"), "<control>P", file_verify, 0, NULL},
+    {_("/File/_Encrypt"), NULL, file_encrypt, 0, NULL},
+    {_("/File/_Decrypt"), NULL, file_decrypt, 0, NULL},
+    {_("/File/sep2"), NULL, NULL, 0, "<Separator>"},
+    {_("/File/_Close"), NULL, file_close, 0, "<StockItem>", GTK_STOCK_CLOSE},
+    {_("/File/_Quit"), NULL, gtk_main_quit, 0, "<StockItem>", GTK_STOCK_QUIT},
+  };
+  GtkItemFactoryEntry edit_menu[] = {
+    {_("/_Edit"), NULL, NULL, 0, "<Branch>"},
+#if 0
+    /* Not implemented yet.  */
+    {_("/Edit/_Undo"), NULL, edit_undo, 0, "<StockItem>", GTK_STOCK_UNDO },
+    {_("/Edit/_Redo"), NULL, edit_redo, 0, "<StockItem>", GTK_STOCK_REDO },
+    {_("/Edit/sep0"), NULL, NULL, 0, "<Separator>"},
+#endif
+    {_("/Edit/Cut"), NULL, edit_cut, 0, "<StockItem>", GTK_STOCK_CUT },
+    {_("/Edit/_Copy"), NULL, edit_copy, 0, "<StockItem>", GTK_STOCK_COPY},
+    {_("/Edit/_Paste"), NULL, edit_paste, 0, "<StockItem>", GTK_STOCK_PASTE},
+    {_("/Edit/_Delete"), NULL, edit_delete, 0, "<StockItem>", GTK_STOCK_DELETE},
+    {_("/Edit/sep1"), NULL, NULL, 0, "<Separator>"},
+    {_("/Edit/Select _All"), "<control>A", edit_select_all, 0,
+     "<StockItem>", GTK_STOCK_SELECT_ALL },
+    {_("/Edit/sep2"), NULL, NULL, 0, "<Separator>"},
+    {_("/Edit/Pr_eferences..."), NULL, gpa_open_settings_dialog, 0,
+     "<StockItem>", GTK_STOCK_PREFERENCES},
+    {_("/Edit/_Backend Preferences..."), NULL,
+     gpa_open_backend_config_dialog, 0, "<StockItem>", GTK_STOCK_PREFERENCES},
+  };
+  GtkItemFactoryEntry windows_menu[] = {
+    {_("/_Windows"), NULL, NULL, 0, "<Branch>"},
+    {_("/Windows/_Keyring Editor"), NULL, gpa_open_keyring_editor, 0, NULL},
+    {_("/Windows/_Filemanager"), NULL, gpa_open_filemanager, 0, NULL},
+    {_("/Windows/_Clipboard"), NULL, gpa_open_clipboard, 0, NULL},
+  };
+  GtkAccelGroup *accel_group;
+  GtkWidget *item;
+
+  accel_group = gtk_accel_group_new ();
+  factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", accel_group);
+  gtk_item_factory_create_items (factory,
+				 sizeof (file_menu) / sizeof (file_menu[0]),
+				 file_menu, clipboard);
+  gtk_item_factory_create_items (factory,
+				 sizeof (edit_menu) / sizeof (edit_menu[0]),
+				 edit_menu, clipboard);
+  gtk_item_factory_create_items (factory,
+				 sizeof(windows_menu) /sizeof(windows_menu[0]),
+				 windows_menu, clipboard);
+
+  /* Disable buttons when no file is selected.   */
+  item = gtk_item_factory_get_widget (GTK_ITEM_FACTORY(factory),
+                                      _("/Edit/Cut"));
+  if (item)
+    {
+      gtk_widget_set_sensitive (item, has_selection (clipboard));
+      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+
+  item = gtk_item_factory_get_widget (GTK_ITEM_FACTORY(factory),
+                                      _("/Edit/Copy"));
+  if (item)
+    {
+      gtk_widget_set_sensitive (item, has_selection (clipboard));
+      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+  
+  item = gtk_item_factory_get_widget (GTK_ITEM_FACTORY(factory),
+                                      _("/Edit/Delete"));
+  if (item)
+    {
+      gtk_widget_set_sensitive (item, has_selection (clipboard));
+      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+
+  item = gtk_item_factory_get_widget (GTK_ITEM_FACTORY (factory),
+                                      _("/Edit/Paste"));
+  if (item)
+    /* Initialized later.  */
+    add_paste_sensitive_widget (clipboard, item);
+
+  gpa_help_menu_add_to_factory (factory, GTK_WIDGET (clipboard));
+  gtk_window_add_accel_group (GTK_WINDOW (clipboard), accel_group);
+
+  return gtk_item_factory_get_widget (factory, "<main>");
+}
+
+
+
+/* Toolbar actions.  */
+
+static void
+toolbar_file_clear (GtkWidget *widget, gpointer param)
+{
+  file_clear (param);
+}
+
+
+static void
+toolbar_file_open (GtkWidget *widget, gpointer param)
+{
+  file_open (param);
+}
+
+
+static void
+toolbar_file_save_as (GtkWidget *widget, gpointer param)
+{
+  file_save_as (param);
+}
+
+
+static void
+toolbar_file_sign (GtkWidget *widget, gpointer param)
+{
+  file_sign (param);
+}
+
+
+static void
+toolbar_file_verify (GtkWidget *widget, gpointer param)
+{
+  file_verify (param);
+}
+
+
+static void
+toolbar_file_encrypt (GtkWidget *widget, gpointer param)
+{
+  file_encrypt (param);
+}
+
+
+static void
+toolbar_file_decrypt (GtkWidget *widget, gpointer param)
+{
+  file_decrypt (param);
+}
+
+
+static void
+toolbar_edit_cut (GtkWidget *widget, gpointer param)
+{
+  edit_cut (param);
+}
+
+
+static void
+toolbar_edit_copy (GtkWidget *widget, gpointer param)
+{
+  edit_copy (param);
+}
+
+
+static void
+toolbar_edit_paste (GtkWidget *widget, gpointer param)
+{
+  edit_paste (param);
+}
+
+
+static void
+toolbar_edit_preferences (GtkWidget *widget, gpointer param)
+{
+  gpa_open_settings_dialog ();
+}
+
+
+/* Construct the new toolbar object and return it.  Takes the file
+   manage object.  */
+static GtkWidget *
+clipboard_toolbar_new (GpaClipboard *clipboard)
+{
+  GtkWidget *toolbar, *icon, *item;
+
+  toolbar = gtk_toolbar_new ();
+
+  gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_CLEAR,
+                            _("Clear buffer"), _("clear buffer"),
+                            GTK_SIGNAL_FUNC (toolbar_file_clear),
+                            clipboard, -1);
+
+  /* Disabled because the toolbar arrow mode doesn't work, and the
+     toolbar takes up too much space otherwise.  */
+#if 0
+  gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_OPEN,
+                            _("Open a file"), _("open file"),
+                            GTK_SIGNAL_FUNC (toolbar_file_open),
+                            clipboard, -1);
+
+  gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_SAVE_AS,
+                            _("Save to a file"), _("save file as"),
+                            GTK_SIGNAL_FUNC (toolbar_file_save_as),
+                            clipboard, -1);
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+#endif
+
+  item = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_CUT,
+				   _("Cut the selection"),
+				   _("cut the selection"),
+				   GTK_SIGNAL_FUNC (toolbar_edit_cut),
+				   clipboard, -1);
+  add_selection_sensitive_widget (clipboard, item, has_selection);
+
+  item = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_COPY,
+				   _("Copy the selection"),
+				   _("copy the selection"),
+				   GTK_SIGNAL_FUNC (toolbar_edit_copy),
+				   clipboard, -1);
+  add_selection_sensitive_widget (clipboard, item, has_selection);
+
+  item = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), GTK_STOCK_PASTE,
+				   _("Paste the clipboard"),
+				   _("paste the clipboard"),
+				   GTK_SIGNAL_FUNC (toolbar_edit_paste),
+				   clipboard, -1);
+  add_paste_sensitive_widget (clipboard, item);
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+
+  /* Build the "Sign" button.  */
+  if ((icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "sign")))
+    {
+      item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Sign"),
+				      _("Sign the selected file"),
+                                      _("sign file"),
+				      icon,
+				      GTK_SIGNAL_FUNC (toolbar_file_sign),
+				      clipboard);
+      //      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+  /* Build the "Verify" button.  */
+  if ((icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "verify")))
+    {
+      item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Verify"),
+				      _("Check signatures of selected file"), 
+				      _("verify file"),
+                                      icon,
+				      GTK_SIGNAL_FUNC (toolbar_file_verify), 
+				      clipboard);
+      //      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+  /* Build the "Encrypt" button.  */
+  if ((icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "encrypt")))
+    {
+      item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Encrypt"),
+				      _("Encrypt the selected file"),
+				      _("encrypt file"),
+				      icon,
+                                      GTK_SIGNAL_FUNC (toolbar_file_encrypt),
+				      clipboard);
+    }
+  /* Build the "Decrypt" button.  */
+  if ((icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "decrypt")))
+    {
+      item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Decrypt"),
+				      _("Decrypt the selected file"),
+				      _("decrypt file"),
+				      icon, 
+                                      GTK_SIGNAL_FUNC (toolbar_file_decrypt),
+				      clipboard);
+      //      add_selection_sensitive_widget (clipboard, item, has_selection);
+    }
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+  
+  gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar), 
+                            GTK_STOCK_PREFERENCES,
+                            _("Open the Preferences dialog"),
+                            _("preferences"),
+                            GTK_SIGNAL_FUNC (toolbar_edit_preferences),
+                            clipboard, -1);
+
+  gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
+
+  icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "keyringeditor");
+  item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Keyring"),
+                                  _("Open the Keyring Editor"),
+                                  _("keyring editor"), icon,
+				  GTK_SIGNAL_FUNC (gpa_open_keyring_editor),
+                                  NULL);
+
+  icon = gtk_image_new_from_stock ("gtk-directory",
+				   GTK_ICON_SIZE_SMALL_TOOLBAR);
+  item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Files"),
+				  _("Open the File Manager"),
+				  _("file manager"), icon,
+				  GTK_SIGNAL_FUNC (gpa_open_filemanager),
+				  NULL);
+
+#if 0  /* FIXME: Help is not available yet. :-( */
+  /* Help */
+  if ((icon = gpa_create_icon_widget (GTK_WIDGET (clipboard), "help")))
+    gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Help"),
+			     _("Understanding the GNU Privacy Assistant"),
+			     _("help"), icon,
+			     GTK_SIGNAL_FUNC (help_help), NULL);
+#endif
+
+  gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), TRUE);
+
+  return toolbar;
+}
+
+
+/* Callback for the destroy signal.  */
+static void
+clipboard_closed (GtkWidget *widget, gpointer param)
+{
+  instance = NULL;
+}
+
+
+/* Construct the clipboard text.  */
+static GtkWidget *
+clipboard_text_new (GpaClipboard *clipboard)
+{
+  GtkWidget *scroller;
+
+  clipboard->text_view = gtk_text_view_new ();
+  gtk_widget_grab_focus (clipboard->text_view);
+
+  gtk_text_view_set_left_margin (GTK_TEXT_VIEW (clipboard->text_view), 4);
+  gtk_text_view_set_right_margin (GTK_TEXT_VIEW (clipboard->text_view), 4);
+
+  clipboard->text_buffer
+    = gtk_text_view_get_buffer (GTK_TEXT_VIEW (clipboard->text_view));
+
+  /* A change in selection status causes a property change, which we
+     can listen in on.  */
+  g_signal_connect_swapped (clipboard->text_buffer, "notify::has-selection",
+			    G_CALLBACK (update_selection_sensitive_widgets),
+			    clipboard);
+
+  /* Connect a bunch of signals for selection.  */
+
+  scroller = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroller),
+				   GTK_POLICY_AUTOMATIC,
+				   GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroller),
+				       GTK_SHADOW_IN);
+  gtk_container_add (GTK_CONTAINER (scroller), clipboard->text_view);
+
+  return scroller;
+} 
+
+
+/* Construct a new class object of GpaClipboard.  */
+static GObject*
+gpa_clipboard_constructor (GType type,
+			   guint n_construct_properties,
+			   GObjectConstructParam *construct_properties)
+{
+  GObject *object;
+  GpaClipboard *clipboard;
+  GtkWidget *vbox;
+  GtkWidget *menubar;
+  GtkWidget *text_box;
+  GtkWidget *text_frame;
+  GtkWidget *toolbar;
+
+  /* Invoke parent's constructor.  */
+  object = parent_class->constructor (type,
+				      n_construct_properties,
+				      construct_properties);
+  clipboard = GPA_CLIPBOARD (object);
+
+  /* Initialize.  */
+  gtk_window_set_title (GTK_WINDOW (clipboard),
+			_("GNU Privacy Assistant - Clipboard"));
+  gtk_window_set_default_size (GTK_WINDOW (clipboard), 640, 480);
+
+  /* Realize the window so that we can create pixmaps without warnings
+     and also access the clipboard.  */
+  gtk_widget_realize (GTK_WIDGET (clipboard));
+
+  /* Use a vbox to show the menu, toolbar and the text container.  */
+  vbox = gtk_vbox_new (FALSE, 0);
+
+  /* First comes the menu.  */
+  menubar = clipboard_menu_new (clipboard);
+  gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, TRUE, 0);
+
+  /* Second the toolbar.  */
+  toolbar = clipboard_toolbar_new (clipboard);
+  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, TRUE, 0);
+
+  /* Third a text entry.  */
+  text_box = gtk_hbox_new (TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (text_box), 5);
+  text_frame = clipboard_text_new (clipboard);
+  gtk_box_pack_start (GTK_BOX (text_box), text_frame, TRUE, TRUE, 0);
+  gtk_box_pack_end (GTK_BOX (vbox), text_box, TRUE, TRUE, 0);
+  gtk_container_add (GTK_CONTAINER (clipboard), vbox);
+
+  g_signal_connect (object, "destroy",
+                    G_CALLBACK (clipboard_closed), object);
+
+  /* Update the sensitivity of paste items.  */
+  {
+    GtkClipboard *clip;
+    
+    /* Do this once for all paste sensitive items.  Note that the
+       window is realized already.  */
+    clip = gtk_widget_get_clipboard (GTK_WIDGET (clipboard),
+				     GDK_SELECTION_CLIPBOARD);
+    g_signal_connect (clip, "owner_change",
+		      G_CALLBACK (clipboard_owner_change_cb), clipboard);
+    set_paste_sensitivity (clipboard, clip);
+  }
+
+  return object;
+}
+
+
+
+static GpaClipboard *
+gpa_clipboard_new ()
+{
+  GpaClipboard *clipboard;
+
+  clipboard = g_object_new (GPA_CLIPBOARD_TYPE, NULL);  
+  // FIXME  update_selection_sensitive_widgets (clipboard);
+
+  return clipboard;
+}
+
+
+/* API */
+
+GtkWidget *
+gpa_clipboard_get_instance (void)
+{
+  if (!instance)
+    {
+      instance = gpa_clipboard_new ();
+    }
+  return GTK_WIDGET (instance);
+}
+
+gboolean gpa_clipboard_is_open (void)
+{
+  return (instance != NULL);
+}

Added: trunk/src/clipboard.h
===================================================================
--- trunk/src/clipboard.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/clipboard.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -0,0 +1,61 @@
+/* clipboard.h  -  The GNU Privacy Assistant
+ * Copyright (C) 2000 G-N-U GmbH.
+ * Copyright (C) 2007, 2008 g10 Code GmbH
+ *
+ * This file is part of GPA
+ *
+ * GPA 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.
+ *
+ * GPA 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#ifndef CLIPBOARD_H
+#define CLIPBOARD_H
+
+#include <gtk/gtk.h>
+
+/* Declare the Object. */
+typedef struct _GpaClipboard GpaClipboard;
+typedef struct _GpaClipboardClass GpaClipboardClass;
+
+GType gpa_clipboard_get_type (void) G_GNUC_CONST;
+
+#define GPA_CLIPBOARD_TYPE	  (gpa_clipboard_get_type ())
+
+#define GPA_CLIPBOARD(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GPA_CLIPBOARD_TYPE, GpaClipboard))
+
+#define GPA_CLIPBOARD_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass),  \
+                            GPA_CLIPBOARD_TYPE, GpaClipboardClass))
+
+#define GPA_IS_CLIPBOARD(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GPA_CLIPBOARD_TYPE))
+
+#define GPA_IS_CLIPBOARD_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), GPA_CLIPBOARD_TYPE))
+
+#define GPA_CLIPBOARD_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj),    \
+                              GPA_CLIPBOARD_TYPE, GpaClipboardClass))
+
+
+
+/*  Our own API.  */
+
+GtkWidget *gpa_clipboard_get_instance (void);
+
+gboolean gpa_clipboard_is_open (void);
+
+#endif /*CLIPBOARD_H*/

Modified: trunk/src/encryptdlg.c
===================================================================
--- trunk/src/encryptdlg.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/encryptdlg.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,6 +1,7 @@
 /* encryptdlg.c  -  The GNU Privacy Assistant
- *	Copyright (C) 2000, 2001 G-N-U GmbH.
- *      Copyright (C) 2002, 2003 Miguel Coca.
+ * Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2002, 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -45,6 +46,7 @@
 {
   PROP_0,
   PROP_WINDOW,
+  PROP_FORCE_ARMOR
 };
 
 static GObjectClass *parent_class = NULL;
@@ -63,6 +65,9 @@
       g_value_set_object (value,
 			  gtk_window_get_transient_for (GTK_WINDOW (dialog)));
       break;
+    case PROP_FORCE_ARMOR:
+      g_value_set_boolean (value, dialog->force_armor);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -84,6 +89,10 @@
       gtk_window_set_transient_for (GTK_WINDOW (dialog),
 				    g_value_get_object (value));
       break;
+    case PROP_FORCE_ARMOR:
+      dialog->force_armor = g_value_get_boolean (value);
+      g_print ("YYY: set to %i\n", dialog->force_armor);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -99,29 +108,17 @@
 
 
 static void
-gpa_file_encrypt_dialog_class_init (GpaFileEncryptDialogClass *klass)
+gpa_file_encrypt_dialog_init (GpaFileEncryptDialog *dialog)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  
-  parent_class = g_type_class_peek_parent (klass);
-  
-  object_class->finalize = gpa_file_encrypt_dialog_finalize;
-  object_class->set_property = gpa_file_encrypt_dialog_set_property;
-  object_class->get_property = gpa_file_encrypt_dialog_get_property;
-
-  /* Properties */
-  g_object_class_install_property (object_class,
-				   PROP_WINDOW,
-				   g_param_spec_object 
-				   ("window", "Parent window",
-				    "Parent window", GTK_TYPE_WIDGET,
-				    G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 
-static void
-gpa_file_encrypt_dialog_init (GpaFileEncryptDialog *dialog)
+static GObject*
+gpa_file_encrypt_dialog_constructor (GType type, guint n_construct_properties,
+				     GObjectConstructParam *construct_properties)
 {
+  GObject *object;
+  GpaFileEncryptDialog *dialog;
   GtkAccelGroup *accelGroup;
   GtkWidget *vboxEncrypt;
   GtkWidget *labelKeys;
@@ -133,6 +130,13 @@
   GtkWidget *scrollerWho;
   GtkWidget *clistWho;
 
+  /* Invoke parent's constructor */
+  object = parent_class->constructor (type,
+				      n_construct_properties,
+				      construct_properties);
+  dialog = GPA_FILE_ENCRYPT_DIALOG (object);
+  /* Initialize */
+
   /* Set up the dialog */
   gtk_dialog_add_buttons (GTK_DIALOG (dialog),
 			  GTK_STOCK_OK, GTK_RESPONSE_OK,
@@ -158,7 +162,7 @@
 				   GTK_POLICY_AUTOMATIC,
 				   GTK_POLICY_AUTOMATIC);
   gtk_box_pack_start (GTK_BOX (vboxEncrypt), scrollerKeys, TRUE, TRUE, 0);
-  gtk_widget_set_usize (scrollerKeys, 350, 120);
+  gtk_widget_set_size_request (scrollerKeys, 400, 200);
 
   clistKeys = gpa_key_selector_new (FALSE);
   g_signal_connect (G_OBJECT (gtk_tree_view_get_selection 
@@ -172,6 +176,7 @@
 
  
   checkerSign = gpa_check_button_new (accelGroup, _("_Sign"));
+
   gtk_box_pack_start (GTK_BOX (vboxEncrypt), checkerSign, FALSE, FALSE, 0);
   dialog->check_sign = checkerSign;
   gtk_signal_connect (GTK_OBJECT (checkerSign), "toggled",
@@ -185,23 +190,73 @@
   gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scrollerWho),
 				   GTK_POLICY_AUTOMATIC,
 				   GTK_POLICY_AUTOMATIC);
-  gtk_widget_set_usize (scrollerWho, 350, 75);
+  gtk_widget_set_size_request (scrollerWho, 400, 200);
+  gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrollerWho),
+				       GTK_SHADOW_IN);
   gtk_box_pack_start (GTK_BOX (vboxEncrypt), scrollerWho, TRUE, TRUE, 0);
 
-  clistWho =  gpa_key_selector_new (TRUE);
+  clistWho = gpa_key_selector_new (TRUE);
   dialog->clist_who = clistWho;
   gtk_container_add (GTK_CONTAINER (scrollerWho), clistWho);
   gpa_connect_by_accelerator (GTK_LABEL (labelWho), clistWho, accelGroup,
 			      _("Sign _as "));
+  /* FIXME: We can't make the key selector insensitive, as it will
+     make itself sensitive again automatically after the keyloading.
+     So we make the whole scroller insensitive.  This is a bit
+     overzealous, but should not affect usability too much.
+     Eventually we could add a property to the key selector to force
+     insensitivity even across key reloads.  */
+#if 0
   gtk_widget_set_sensitive (clistWho, FALSE);
+#else
+  dialog->scroller_who = scrollerWho;
+  gtk_widget_set_sensitive (scrollerWho, FALSE);
+#endif
 
   checkerArmor = gpa_check_button_new (accelGroup, _("A_rmor"));
   gtk_box_pack_start (GTK_BOX (vboxEncrypt), checkerArmor, FALSE, FALSE, 0);
   dialog->check_armor = checkerArmor;
 
+  if (dialog->force_armor)
+    {
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->check_armor),
+				    TRUE);
+      gtk_widget_set_sensitive (dialog->check_armor, FALSE);
+    }
+
+  return object;
 }
 
 
+static void
+gpa_file_encrypt_dialog_class_init (GpaFileEncryptDialogClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  
+  parent_class = g_type_class_peek_parent (klass);
+  
+  object_class->constructor = gpa_file_encrypt_dialog_constructor;
+  object_class->finalize = gpa_file_encrypt_dialog_finalize;
+  object_class->set_property = gpa_file_encrypt_dialog_set_property;
+  object_class->get_property = gpa_file_encrypt_dialog_get_property;
+
+  /* Properties */
+  g_object_class_install_property (object_class,
+				   PROP_WINDOW,
+				   g_param_spec_object 
+				   ("window", "Parent window",
+				    "Parent window", GTK_TYPE_WIDGET,
+				    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class,
+				   PROP_FORCE_ARMOR,
+				   g_param_spec_boolean
+				   ("force-armor", "Force armor",
+				    "Force armor mode", FALSE,
+				    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+
 GType
 gpa_file_encrypt_dialog_get_type (void)
 {
@@ -232,12 +287,13 @@
 
 /* API */
 
-GtkWidget *gpa_file_encrypt_dialog_new (GtkWidget *parent)
+GtkWidget *gpa_file_encrypt_dialog_new (GtkWidget *parent, gboolean force_armor)
 {
   GpaFileEncryptDialog *dialog;
   
   dialog = g_object_new (GPA_FILE_ENCRYPT_DIALOG_TYPE,
 			 "window", parent,
+			 "force-armor", force_armor,
 			 NULL);
 
   return GTK_WIDGET(dialog);
@@ -258,11 +314,13 @@
   return gpa_key_selector_get_selected_keys (GPA_KEY_SELECTOR (dialog->clist_who));
 }
 
+
 gboolean gpa_file_encrypt_dialog_get_armor (GpaFileEncryptDialog *dialog)
 {
   return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dialog->check_armor));
 }
 
+
 static void
 changed_select_row_cb (GtkTreeSelection *treeselection, gpointer user_data)
 {
@@ -284,7 +342,13 @@
 toggle_sign_cb (GtkToggleButton *togglebutton, gpointer user_data)
 {
   GpaFileEncryptDialog *dialog = user_data;
+
+  /* FIXME: See above.  */
+#if 0
   gtk_widget_set_sensitive (dialog->clist_who,
                             gtk_toggle_button_get_active (togglebutton));
+#else
+  gtk_widget_set_sensitive (dialog->scroller_who,
+                            gtk_toggle_button_get_active (togglebutton));
+#endif
 }
-

Modified: trunk/src/encryptdlg.h
===================================================================
--- trunk/src/encryptdlg.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/encryptdlg.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* encryptdlg.h  -  The GNU Privacy Assistant
- *	Copyright (C) 2000 G-N-U GmbH.
+ * Copyright (C) 2000 G-N-U GmbH.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -41,6 +42,10 @@
   GtkWidget *check_sign;
   GtkWidget *check_armor;
   GtkWidget *clist_who;
+  /* FIXME: See comment in encryptdlg.h.  */
+  GtkWidget *scroller_who;
+
+  gboolean force_armor;
 };
 
 struct _GpaFileEncryptDialogClass {
@@ -51,7 +56,8 @@
 
 /* API */
 
-GtkWidget *gpa_file_encrypt_dialog_new (GtkWidget *parent);
+GtkWidget *gpa_file_encrypt_dialog_new (GtkWidget *parent,
+					gboolean force_armor);
 
 GList *gpa_file_encrypt_dialog_recipients (GpaFileEncryptDialog *dialog);
 
@@ -61,4 +67,5 @@
 
 gboolean gpa_file_encrypt_dialog_get_armor (GpaFileEncryptDialog *dialog);
 
+
 #endif /* ENCRYPTDLG_H */

Modified: trunk/src/fileman.c
===================================================================
--- trunk/src/fileman.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/fileman.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,6 +1,6 @@
 /* fileman.c  -  The GNU Privacy Assistant
- *	Copyright (C) 2000, 2001 G-N-U GmbH.
- *      Copyright (C) 2007 g10 Code GmbH
+ * Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2007, 2008 g10 Code GmbH
  *
  * This file is part of GPA
  *
@@ -59,6 +59,7 @@
 #endif
 
 
+
 /* Object and class definition.  */
 struct _GpaFileManager
 {
@@ -189,13 +190,17 @@
 
   while (selection)
     {
+      gpa_file_item_t file_item;
       gchar *filename;
       GtkTreeIter iter;
 
       gtk_tree_model_get_iter (model, &iter, (GtkTreePath*) selection->data);
       gtk_tree_model_get (model, &iter, FILE_NAME_COLUMN, &filename, -1);
 
-      files = g_list_append (files, filename);
+      file_item = g_malloc0 (sizeof (*file_item));
+      file_item->filename_in = filename;
+
+      files = g_list_append (files, file_item);
       selection = g_list_next (selection);
     }
 
@@ -255,11 +260,11 @@
 
 /* Add a file created by an operation to the list */
 static void
-file_created_cb (GpaFileOperation *op, const gchar *filename, gpointer data)
+file_created_cb (GpaFileOperation *op, gpa_file_item_t item, gpointer data)
 {
   GpaFileManager *fileman = data;
   
-  add_file (fileman, filename);  
+  add_file (fileman, item->filename_out);
 }
 
 
@@ -395,7 +400,7 @@
   if (!files)
     return;
 
-  op = gpa_file_sign_operation_new (GTK_WIDGET (fileman), files);
+  op = gpa_file_sign_operation_new (GTK_WIDGET (fileman), files, FALSE);
 
   register_operation (fileman, GPA_FILE_OPERATION (op));
 }
@@ -413,7 +418,7 @@
   if (!files)
     return;
 
-  op = gpa_file_encrypt_operation_new (GTK_WIDGET (fileman), files);
+  op = gpa_file_encrypt_operation_new (GTK_WIDGET (fileman), files, FALSE);
 
   register_operation (fileman, GPA_FILE_OPERATION (op));
 }
@@ -487,8 +492,9 @@
   };
   GtkItemFactoryEntry windows_menu[] = {
     {_("/_Windows"), NULL, NULL, 0, "<Branch>"},
+    {_("/Windows/_Keyring Editor"), NULL, gpa_open_keyring_editor, 0, NULL},
     {_("/Windows/_Filemanager"), NULL, gpa_open_filemanager, 0, NULL},
-    {_("/Windows/_Keyring Editor"), NULL, gpa_open_keyring_editor, 0, NULL},
+    {_("/Windows/_Clipboard"), NULL, gpa_open_clipboard, 0, NULL},
   };
   GtkAccelGroup *accel_group;
   GtkWidget *item;
@@ -663,6 +669,15 @@
 				  GTK_SIGNAL_FUNC (gpa_open_keyring_editor),
                                   NULL);
 
+  /* FIXME: Should be just the clipboard.  */
+  icon = gtk_image_new_from_stock ("gtk-paste",
+				   GTK_ICON_SIZE_SMALL_TOOLBAR);
+  item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Clipboard"),
+				  _("Open the clipboard"),
+				  _("clipboard"), icon,
+				  GTK_SIGNAL_FUNC (gpa_open_clipboard),
+				  NULL);
+
 #if 0  /* FIXME: Help is not available yet. :-( */
   /* Help */
   if ((icon = gpa_create_icon_widget (GTK_WIDGET (fileman), "help")))
@@ -825,7 +840,7 @@
   /* Initialize.  */
   gtk_window_set_title (GTK_WINDOW (fileman),
 			_("GNU Privacy Assistant - File Manager"));
-  gtk_widget_set_usize (GTK_WIDGET (fileman), 640, 480);
+  gtk_window_set_default_size (GTK_WINDOW (fileman), 640, 480);
   /* Realize the window so that we can create pixmaps without warnings.  */
   gtk_widget_realize (GTK_WIDGET (fileman));
 
@@ -904,4 +919,5 @@
   if (!add_file (fileman, filename))
     gpa_window_error (_("The file is already open."),
 		      GTK_WIDGET (fileman));
+  /* FIXME: Release filename?  */
 }

Modified: trunk/src/filesigndlg.c
===================================================================
--- trunk/src/filesigndlg.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/filesigndlg.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* filesigndlg.c  -  The GNU Privacy Assistant
- *	Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -34,15 +35,16 @@
 {
   PROP_0,
   PROP_WINDOW,
+  PROP_FORCE_ARMOR
 };
 
 static GObjectClass *parent_class = NULL;
 
 static void
 gpa_file_sign_dialog_get_property (GObject     *object,
-				      guint        prop_id,
-				      GValue      *value,
-				      GParamSpec  *pspec)
+				   guint        prop_id,
+				   GValue      *value,
+				   GParamSpec  *pspec)
 {
   GpaFileSignDialog *dialog = GPA_FILE_SIGN_DIALOG (object);
   
@@ -52,6 +54,9 @@
       g_value_set_object (value,
 			  gtk_window_get_transient_for (GTK_WINDOW (dialog)));
       break;
+    case PROP_FORCE_ARMOR:
+      g_value_set_boolean (value, dialog->force_armor);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -72,12 +77,16 @@
       gtk_window_set_transient_for (GTK_WINDOW (dialog),
 				    g_value_get_object (value));
       break;
+    case PROP_FORCE_ARMOR:
+      dialog->force_armor = g_value_get_boolean (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
     }
 }
 
+
 static void
 gpa_file_sign_dialog_finalize (GObject *object)
 {  
@@ -90,6 +99,7 @@
 {
 }
 
+
 static GObject*
 gpa_file_sign_dialog_constructor (GType type,
 				  guint n_construct_properties,
@@ -156,11 +166,6 @@
   gtk_box_pack_start (GTK_BOX (vboxMode), radio_sign_sep, FALSE, FALSE, 0);
   dialog->radio_sep = radio_sign_sep;
 
-  checkerArmor = gpa_check_button_new (accelGroup, _("a_rmor"));
-  gtk_container_set_border_width (GTK_CONTAINER (checkerArmor), 5);
-  gtk_box_pack_start (GTK_BOX (vboxSign), checkerArmor, FALSE, FALSE, 0);
-  dialog->check_armor = checkerArmor;
-    
   vboxWho = gtk_vbox_new (FALSE, 0);
   gtk_container_set_border_width (GTK_CONTAINER (vboxWho), 5);
   gtk_box_pack_start (GTK_BOX (vboxSign), vboxWho, TRUE, TRUE, 0);
@@ -170,7 +175,7 @@
   gtk_box_pack_start (GTK_BOX (vboxWho), labelWho, FALSE, TRUE, 0);
 
   scrollerWho = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_set_usize (scrollerWho, 260, 75);
+  gtk_widget_set_size_request (scrollerWho, 400, 200);
   gtk_box_pack_start (GTK_BOX (vboxWho), scrollerWho, TRUE, TRUE, 0);
 
   clistWho = gpa_key_selector_new (TRUE);
@@ -179,6 +184,18 @@
   gpa_connect_by_accelerator (GTK_LABEL (labelWho), clistWho, accelGroup,
 			      _("Sign _as "));
 
+  checkerArmor = gpa_check_button_new (accelGroup, _("A_rmor"));
+  gtk_container_set_border_width (GTK_CONTAINER (checkerArmor), 5);
+  gtk_box_pack_start (GTK_BOX (vboxSign), checkerArmor, FALSE, FALSE, 0);
+  dialog->check_armor = checkerArmor;
+  if (dialog->force_armor)
+    {
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->check_armor),
+				    TRUE);
+      gtk_widget_set_sensitive (dialog->check_armor, FALSE);
+    }
+
+  /* FIXME: Doesn't even work, as caller uses gtk_widget_show_all.  */
   if (gpa_options_get_simplified_ui (gpa_options_get_instance ()))
     {
       gtk_widget_hide (dialog->radio_comp);
@@ -212,6 +229,12 @@
 				   ("window", "Parent window",
 				    "Parent window", GTK_TYPE_WIDGET,
 				    G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property (object_class,
+				   PROP_FORCE_ARMOR,
+				   g_param_spec_boolean
+				   ("force-armor", "Force armor",
+				    "Force armor mode", FALSE,
+				    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
 GType
@@ -244,12 +267,14 @@
 
 /* API */
 
-GtkWidget *gpa_file_sign_dialog_new (GtkWidget *parent)
+GtkWidget *
+gpa_file_sign_dialog_new (GtkWidget *parent, gboolean force_armor)
 {
   GpaFileSignDialog *dialog;
   
   dialog = g_object_new (GPA_FILE_SIGN_DIALOG_TYPE,
 			 "window", parent,
+			 "force-armor", force_armor,
 			 NULL);
 
   return GTK_WIDGET(dialog);

Modified: trunk/src/filesigndlg.h
===================================================================
--- trunk/src/filesigndlg.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/filesigndlg.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -46,6 +46,8 @@
   GtkWidget *radio_sep;
   GtkWidget *check_armor;
   GtkWidget *clist_who;
+
+  gboolean force_armor;
 };
 
 struct _GpaFileSignDialogClass {
@@ -56,7 +58,7 @@
 
 /* API */
 
-GtkWidget *gpa_file_sign_dialog_new (GtkWidget *parent);
+GtkWidget *gpa_file_sign_dialog_new (GtkWidget *parent, gboolean force_armor);
 
 GList *gpa_file_sign_dialog_signers (GpaFileSignDialog *dialog);
 

Modified: trunk/src/gpa.c
===================================================================
--- trunk/src/gpa.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpa.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -34,6 +34,7 @@
 #include "gpa.h"
 #include "keyring.h"
 #include "fileman.h"
+#include "clipboard.h"
 #include "keyserver.h"
 #include "settingsdlg.h"
 #include "confdialog.h"
@@ -108,10 +109,9 @@
 static void
 quit_if_no_window (void)
 {
-  if (!keyringeditor && !gpa_file_manager_is_open ())
-    {
-      gtk_main_quit ();
-    }
+  if (! keyringeditor && ! gpa_file_manager_is_open ()
+      && ! gpa_clipboard_is_open ())
+    gtk_main_quit ();
 }
 
 
@@ -141,6 +141,20 @@
 }
 
 
+/* Show the clipboard dialog.  */
+void
+gpa_open_clipboard (void)
+{
+  /* FIXME: Shouldn't this connect only happen if the instance is
+     created the first time?  Looks like a memory leak to me.  */
+  gtk_signal_connect (GTK_OBJECT (gpa_clipboard_get_instance ()), "destroy",
+		      GTK_SIGNAL_FUNC (quit_if_no_window), NULL);
+  gtk_widget_show_all (gpa_clipboard_get_instance ());
+
+  gtk_window_present (GTK_WINDOW (gpa_clipboard_get_instance ()));
+}
+
+
 /* Show the filemanager dialog.  */
 void
 gpa_open_filemanager (void)

Modified: trunk/src/gpa.h
===================================================================
--- trunk/src/gpa.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpa.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -61,6 +61,9 @@
 /* Show the filemanager dialog.  */
 void gpa_open_filemanager (void);
 
+/* Show the filemanager dialog.  */
+void gpa_open_clipboard (void);
+
 /* Show the settings dialog.  */
 void gpa_open_settings_dialog (void);
 

Modified: trunk/src/gpafiledecryptop.c
===================================================================
--- trunk/src/gpafiledecryptop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafiledecryptop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafiledecryptop.c - The GpaOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -62,7 +63,6 @@
   op->plain_fd = -1;
   op->cipher = NULL;
   op->plain = NULL;
-  op->plain_filename = NULL;
 }
 
 
@@ -177,39 +177,77 @@
 
 static gboolean
 gpa_file_decrypt_operation_start (GpaFileDecryptOperation *op,
-				  const gchar *cipher_filename)
+				  gpa_file_item_t file_item)
 {
   gpg_error_t err;
-  
-  op->plain_filename = destination_filename (cipher_filename);
-  /* Open the files */
-  op->cipher_fd = gpa_open_input (cipher_filename, &op->cipher, 
-				  GPA_OPERATION (op)->window);
-  if (op->cipher_fd == -1)
+
+  if (file_item->direct_in)
     {
-      return FALSE;
+      /* No copy is made.  */
+      err = gpgme_data_new_from_mem (&op->cipher, file_item->direct_in,
+				     file_item->direct_in_len, 0);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  return FALSE;
+	}
+      
+      err = gpgme_data_new (&op->plain);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  gpgme_data_release (op->cipher);
+	  op->plain = NULL;
+	  return FALSE;
+	}
     }
-  op->plain_fd = gpa_open_output (op->plain_filename, &op->plain,
+  else
+    {
+      gchar *cipher_filename = file_item->filename_in;
+
+      file_item->filename_out = destination_filename (cipher_filename);
+      /* Open the files */
+      op->cipher_fd = gpa_open_input (cipher_filename, &op->cipher, 
 				  GPA_OPERATION (op)->window);
-  if (op->plain_fd == -1)
-    {
-      gpgme_data_release (op->cipher);
-      close (op->cipher_fd);
-      return FALSE;
+      if (op->cipher_fd == -1)
+	{
+	  return FALSE;
+	}
+      op->plain_fd = gpa_open_output (file_item->filename_out, &op->plain,
+				      GPA_OPERATION (op)->window);
+      if (op->plain_fd == -1)
+	{
+	  gpgme_data_release (op->cipher);
+	  close (op->cipher_fd);
+	  return FALSE;
+	}
     }
+
   /* Start the operation */
   err = gpgme_op_decrypt_start (GPA_OPERATION (op)->context->ctx, op->cipher, 
 				op->plain);
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
     {
       gpa_gpgme_warning (err);
+
+      gpgme_data_release (op->plain);
+      op->plain = NULL;
+      close (op->plain_fd);
+      op->plain_fd = -1;
+      gpgme_data_release (op->cipher);
+      op->cipher = NULL;
+      close (op->cipher_fd);
+      op->cipher_fd = -1;
+
       return FALSE;
     }
   /* Show and update the progress dialog */
   gtk_widget_show_all (GPA_FILE_OPERATION (op)->progress_dialog);
   gpa_progress_dialog_set_label (GPA_PROGRESS_DIALOG 
 				 (GPA_FILE_OPERATION (op)->progress_dialog),
-				 op->plain_filename);
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
   return TRUE;
 }
 
@@ -229,28 +267,61 @@
 				    gpg_error_t err,
 				    GpaFileDecryptOperation *op)
 {
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
+
+  if (file_item->direct_in)
+    {
+      size_t len;
+      char *plain_gpgme = gpgme_data_release_and_get_mem (op->plain, &len);
+      op->plain = NULL;
+      /* Do the memory allocation dance.  */
+
+      if (plain_gpgme)
+	{
+	  /* Conveniently make ASCII stuff into a string.  */
+	  file_item->direct_out = g_malloc (len + 1);
+	  memcpy (file_item->direct_out, plain_gpgme, len);
+	  gpgme_free (plain_gpgme);
+	  file_item->direct_out[len] = '\0';
+	  /* Yep, excluding the trailing zero.  */
+	  file_item->direct_out_len = len;
+	}
+      else
+	{
+	  file_item->direct_out = NULL;
+	  file_item->direct_out_len = 0;
+	}
+    }
+
   /* Do clean up on the operation */
   gpgme_data_release (op->plain);
+  op->plain = NULL;
   close (op->plain_fd);
+  op->plain_fd = -1;
   gpgme_data_release (op->cipher);
+  op->cipher = NULL;
   close (op->cipher_fd);
+  op->cipher_fd = -1;
   gtk_widget_hide (GPA_FILE_OPERATION (op)->progress_dialog);
   /* Check for error */
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
     {
-      /* If an error happened, (or the user canceled) delete the created file
-       * and abort further decryptions
-       */
-      unlink (op->plain_filename);
-      g_free (op->plain_filename);
+      if (! file_item->direct_in)
+	{
+	  /* If an error happened, (or the user canceled) delete the
+	     created file and abort further decryptions.  */
+	  unlink (file_item->filename_out);
+	  g_free (file_item->filename_out);
+	  file_item->filename_out = NULL;
+	}
+      /* FIXME:CLIPBOARD: Server finish?  */
       g_signal_emit_by_name (GPA_OPERATION (op), "completed"); 
     }
   else
     {
       /* We've just created a file */
-      g_signal_emit_by_name (GPA_OPERATION (op), "created_file",
-			     op->plain_filename);
-      g_free (op->plain_filename);
+      g_signal_emit_by_name (GPA_OPERATION (op), "created_file", file_item);
+
       /* Go to the next file in the list and decrypt it */
       GPA_FILE_OPERATION (op)->current = g_list_next 
 	(GPA_FILE_OPERATION (op)->current);
@@ -272,6 +343,7 @@
 gpa_file_decrypt_operation_done_error_cb (GpaContext *context, gpg_error_t err,
 					  GpaFileDecryptOperation *op)
 {
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
   gchar *message;
 
   switch (gpg_err_code (err))
@@ -281,18 +353,25 @@
       /* Ignore these */
       break;
     case GPG_ERR_NO_DATA:
-      message = g_strdup_printf (_("The file \"%s\" contained no OpenPGP "
-				   "data."),
-				 gpa_file_operation_current_file 
-				 (GPA_FILE_OPERATION(op)));
+      message = g_strdup_printf (file_item->direct_name
+				 ? _("\"%s\" contained no OpenPGP data.")
+				 : _("The file \"%s\" contained no OpenPGP"
+				     "data."),
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
       gpa_window_error (message, GPA_OPERATION (op)->window);
       g_free (message);
       break;
     case GPG_ERR_DECRYPT_FAILED:
-      message = g_strdup_printf (_("The file \"%s\" contained no "
-				   "valid encrypted data."),
-				 gpa_file_operation_current_file
-				 (GPA_FILE_OPERATION(op)));
+      message = g_strdup_printf (file_item->direct_name
+				 ? _("\"%s\" contained no valid "
+				     "encrypted data.")
+				 : _("The file \"%s\" contained no valid"
+				     "encrypted data."),
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
       gpa_window_error (message, GPA_OPERATION (op)->window);
       g_free (message);
       break;

Modified: trunk/src/gpafiledecryptop.h
===================================================================
--- trunk/src/gpafiledecryptop.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafiledecryptop.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafiledecryptop.h - The GpaFileDecryptOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -41,7 +42,6 @@
 
   int cipher_fd, plain_fd;
   gpgme_data_t cipher, plain;
-  gchar *plain_filename;
 };
 
 struct _GpaFileDecryptOperationClass {

Modified: trunk/src/gpafileencryptop.c
===================================================================
--- trunk/src/gpafileencryptop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafileencryptop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafiledecryptop.c - The GpaOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -53,7 +54,50 @@
 
 static GObjectClass *parent_class = NULL;
 
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_FORCE_ARMOR
+};
+
+
 static void
+gpa_file_encrypt_operation_get_property (GObject *object, guint prop_id,
+					 GValue *value, GParamSpec *pspec)
+{
+  GpaFileEncryptOperation *op = GPA_FILE_ENCRYPT_OPERATION (object);
+  
+  switch (prop_id)
+    {
+    case PROP_FORCE_ARMOR:
+      g_value_set_boolean (value, op->force_armor);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gpa_file_encrypt_operation_set_property (GObject *object, guint prop_id,
+				      const GValue *value, GParamSpec *pspec)
+{
+  GpaFileEncryptOperation *op = GPA_FILE_ENCRYPT_OPERATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_FORCE_ARMOR:
+      op->force_armor = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+static void
 gpa_file_encrypt_operation_finalize (GObject *object)
 {  
   GpaFileEncryptOperation *op = GPA_FILE_ENCRYPT_OPERATION (object);
@@ -76,8 +120,8 @@
   op->plain_fd = -1;
   op->cipher = NULL;
   op->plain = NULL;
-  op->cipher_filename = NULL;
   op->encrypt_dialog = NULL;
+  op->force_armor = FALSE;
 }
 
 static GObject*
@@ -97,7 +141,7 @@
   /* Initialize */
   /* Create the "Encrypt" dialog */
   op->encrypt_dialog = gpa_file_encrypt_dialog_new
-    (GPA_OPERATION (op)->window);
+    (GPA_OPERATION (op)->window, op->force_armor);
   g_signal_connect (G_OBJECT (op->encrypt_dialog), "response",
 		    G_CALLBACK (gpa_file_encrypt_operation_response_cb), op);
   /* Connect to the "done" signal */
@@ -123,8 +167,18 @@
 
   object_class->constructor = gpa_file_encrypt_operation_constructor;
   object_class->finalize = gpa_file_encrypt_operation_finalize;
+  object_class->set_property = gpa_file_encrypt_operation_set_property;
+  object_class->get_property = gpa_file_encrypt_operation_get_property;
+
+  g_object_class_install_property (object_class,
+				   PROP_FORCE_ARMOR,
+				   g_param_spec_boolean
+				   ("force-armor", "Force armor",
+				    "Force armor mode", FALSE,
+				    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
+
 GType
 gpa_file_encrypt_operation_get_type (void)
 {
@@ -156,14 +210,15 @@
 /* API */
 
 GpaFileEncryptOperation*
-gpa_file_encrypt_operation_new (GtkWidget *window,
-				GList *files)
+gpa_file_encrypt_operation_new (GtkWidget *window, GList *files,
+				gboolean force_armor)
 {
   GpaFileEncryptOperation *op;
   
   op = g_object_new (GPA_FILE_ENCRYPT_OPERATION_TYPE,
 		     "window", window,
 		     "input_files", files,
+		     "force-armor", force_armor,
 		     NULL);
 
   return op;
@@ -207,27 +262,56 @@
 
 static gboolean
 gpa_file_encrypt_operation_start (GpaFileEncryptOperation *op,
-				  const gchar *plain_filename)
+				  gpa_file_item_t file_item)
 {
   gpg_error_t err;
-  
-  op->cipher_filename = destination_filename 
-    (plain_filename, gpgme_get_armor (GPA_OPERATION (op)->context->ctx));
-  /* Open the files */
-  op->plain_fd = gpa_open_input (plain_filename, &op->plain, 
-				 GPA_OPERATION (op)->window);
-  if (op->plain_fd == -1)
+
+  if (file_item->direct_in)
     {
-      return FALSE;
+      gpgme_error_t err;
+
+      /* No copy is made.  */
+      err = gpgme_data_new_from_mem (&op->plain, file_item->direct_in,
+				     file_item->direct_in_len, 0);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  return FALSE;
+	}
+      
+      err = gpgme_data_new (&op->cipher);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  gpgme_data_release (op->plain);
+	  op->plain = NULL;
+	  return FALSE;
+	}
     }
-  op->cipher_fd = gpa_open_output (op->cipher_filename, &op->cipher,
-				   GPA_OPERATION (op)->window);
-  if (op->cipher_fd == -1)
+  else
     {
-      gpgme_data_release (op->plain);
-      close (op->plain_fd);
-      return FALSE;
+      gchar *plain_filename = file_item->filename_in;
+  
+      file_item->filename_out = destination_filename 
+	(plain_filename, gpgme_get_armor (GPA_OPERATION (op)->context->ctx));
+      /* Open the files */
+      op->plain_fd = gpa_open_input (plain_filename, &op->plain, 
+				     GPA_OPERATION (op)->window);
+      if (op->plain_fd == -1)
+	{
+	  return FALSE;
+	}
+      op->cipher_fd = gpa_open_output (file_item->filename_out, &op->cipher,
+				       GPA_OPERATION (op)->window);
+      if (op->cipher_fd == -1)
+	{
+	  gpgme_data_release (op->plain);
+	  close (op->plain_fd);
+	  op->plain_fd = -1;
+	  return FALSE;
+	}
     }
+
   /* Start the operation */
   /* Always trust keys, because any untrusted keys were already confirmed
    * by the user.
@@ -248,13 +332,25 @@
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
     {
       gpa_gpgme_warning (err);
+
+      gpgme_data_release (op->plain);
+      op->plain = NULL;
+      close (op->plain_fd);
+      op->plain_fd = -1;
+      gpgme_data_release (op->cipher);
+      op->cipher = NULL;
+      close (op->cipher_fd);
+      op->cipher_fd = -1;
+
       return FALSE;
     }
   /* Show and update the progress dialog */
   gtk_widget_show_all (GPA_FILE_OPERATION (op)->progress_dialog);
   gpa_progress_dialog_set_label (GPA_PROGRESS_DIALOG 
 				 (GPA_FILE_OPERATION (op)->progress_dialog),
-				 op->cipher_filename);
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
   return TRUE;
 }
 
@@ -275,6 +371,33 @@
 				    gpg_error_t err,
 				    GpaFileEncryptOperation *op)
 {
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
+
+  if (file_item->direct_in)
+    {
+      size_t len;
+      char *cipher_gpgme = gpgme_data_release_and_get_mem (op->cipher,
+							   &len);
+      op->cipher = NULL;
+      /* Do the memory allocation dance.  */
+
+      if (cipher_gpgme)
+	{
+	  /* Conveniently make ASCII stuff into a string.  */
+	  file_item->direct_out = g_malloc (len + 1);
+	  memcpy (file_item->direct_out, cipher_gpgme, len);
+	  gpgme_free (cipher_gpgme);
+	  file_item->direct_out[len] = '\0';
+	  /* Yep, excluding the trailing zero.  */
+	  file_item->direct_out_len = len;
+	}
+      else
+	{
+	  file_item->direct_out = NULL;
+	  file_item->direct_out_len = 0;
+	}
+    }
+
   /* Do clean up on the operation */
   gpgme_data_release (op->plain);
   op->plain = NULL;
@@ -288,22 +411,22 @@
 
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR) 
     {
-      /* If an error happened, (or the user canceled) delete the created file
-       * and abort further encryptions
-       */
-      unlink (op->cipher_filename);
-      g_free (op->cipher_filename);
-      op->cipher_filename = NULL;
+      if (! file_item->direct_in)
+	{
+	  /* If an error happened, (or the user canceled) delete the
+	    created file and abort further encryptions.  */
+	  unlink (file_item->filename_out);
+	  g_free (file_item->filename_out);
+	  file_item->filename_out = NULL;
+	}
       gpa_operation_server_finish (GPA_OPERATION (op), err);
       g_signal_emit_by_name (GPA_OPERATION (op), "completed");
     }
   else
     {
       /* We've just created a file */
-      g_signal_emit_by_name (GPA_OPERATION (op), "created_file",
-			     op->cipher_filename);
-      g_free (op->cipher_filename);
-      op->cipher_filename = NULL;
+      g_signal_emit_by_name (GPA_OPERATION (op), "created_file", file_item);
+
       /* Go to the next file in the list and encrypt it */
       GPA_FILE_OPERATION (op)->current = g_list_next 
 	(GPA_FILE_OPERATION (op)->current);

Modified: trunk/src/gpafileencryptop.h
===================================================================
--- trunk/src/gpafileencryptop.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafileencryptop.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -59,7 +59,8 @@
   gpgme_key_t *rset;
   int cipher_fd, plain_fd;
   gpgme_data_t cipher, plain;
-  gchar *cipher_filename;
+
+  gboolean force_armor;
 };
 
 
@@ -75,7 +76,8 @@
 
 /* Creates a new encryption operation. */
 GpaFileEncryptOperation *
-gpa_file_encrypt_operation_new (GtkWidget *window, GList *files);
+gpa_file_encrypt_operation_new (GtkWidget *window, GList *files,
+				gboolean force_armor);
 
 /* Create a new encryption operaion for the UI server.  */
 GpaFileEncryptOperation*

Modified: trunk/src/gpafileop.c
===================================================================
--- trunk/src/gpafileop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafileop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafileop.c - The GpaFileOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -80,12 +81,29 @@
     }
 }
 
+
 static void
+free_file_item (gpa_file_item_t item)
+{
+  if (item->filename_in)
+    g_free (item->filename_in);
+  if (item->filename_out)
+    g_free (item->filename_out);
+  if (item->direct_name)
+    g_free (item->direct_name);
+  if (item->direct_in)
+    g_free (item->direct_in);
+  if (item->direct_out)
+    g_free (item->direct_out);
+}
+
+
+static void
 gpa_file_operation_finalize (GObject *object)
 {
   GpaFileOperation *op = GPA_FILE_OPERATION (object);
 
-  g_list_foreach (op->input_files, (GFunc) g_free, NULL);
+  g_list_foreach (op->input_files, (GFunc) free_file_item, NULL);
   g_list_free (op->input_files);
   gtk_widget_destroy (op->progress_dialog);
   
@@ -141,9 +159,9 @@
 		  G_SIGNAL_RUN_FIRST,
 		  G_STRUCT_OFFSET (GpaFileOperationClass, created_file),
 		  NULL, NULL,
-		  g_cclosure_marshal_VOID__STRING,
+		  g_cclosure_marshal_VOID__POINTER,
 		  G_TYPE_NONE, 1,
-		  G_TYPE_STRING);
+		  G_TYPE_POINTER);
   /* Properties */
   g_object_class_install_property (object_class,
 				   PROP_INPUT_FILES,
@@ -181,10 +199,10 @@
   return file_operation_type;
 }
 
+
 /* API */
 
-/* Returns the list of files on which the operation has been called. 
- */
+/* Returns the list of files on which the operation has been called.  */
 GList*
 gpa_file_operation_input_files (GpaFileOperation *op)
 {
@@ -194,8 +212,8 @@
   return op->input_files;
 }
 
-/* Returns the file the operation is currently being applied to.
- */
+
+/* Returns the file the operation is currently being applied to.  */
 const gchar *
 gpa_file_operation_current_file (GpaFileOperation *op)
 {
@@ -204,10 +222,11 @@
 
   if (op->current)
     {
-      return op->current->data;
+      gpa_file_item_t file_item;
+
+      file_item = op->current->data; 
+      return file_item->filename_in;
     }
   else
-    {
-      return NULL;
-    }
+    return NULL;
 }

Modified: trunk/src/gpafileop.h
===================================================================
--- trunk/src/gpafileop.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafileop.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafileop.h - The GpaFileOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -38,6 +39,24 @@
 typedef struct _GpaFileOperation GpaFileOperation;
 typedef struct _GpaFileOperationClass GpaFileOperationClass;
 
+struct gpa_file_item_s
+{
+  /* If not NULL, the text to operate on.  */
+  gchar *direct_in;
+  gsize direct_in_len;
+  gchar *direct_out;
+  /* Length of DIRECT_OUT (minus trailing zero).  */
+  gsize direct_out_len;
+  /* A displayable string identifying the text.  */
+  gchar *direct_name;
+
+  /* The filename to operate on (if DIRECT_IN is NULL).  */
+  gchar *filename_in;
+  gchar *filename_out;
+};
+typedef struct gpa_file_item_s *gpa_file_item_t; 
+
+
 struct _GpaFileOperation {
   GpaOperation parent;
 

Modified: trunk/src/gpafilesignop.c
===================================================================
--- trunk/src/gpafilesignop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafilesignop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafiledecryptop.c - The GpaOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -53,12 +54,56 @@
 
 static GObjectClass *parent_class = NULL;
 
+/* Properties */
+enum
+{
+  PROP_0,
+  PROP_FORCE_ARMOR
+};
+
+
 static void
+gpa_file_sign_operation_get_property (GObject *object, guint prop_id,
+				      GValue *value, GParamSpec *pspec)
+{
+  GpaFileSignOperation *op = GPA_FILE_SIGN_OPERATION (object);
+  
+  switch (prop_id)
+    {
+    case PROP_FORCE_ARMOR:
+      g_value_set_boolean (value, op->force_armor);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gpa_file_sign_operation_set_property (GObject *object, guint prop_id,
+				      const GValue *value, GParamSpec *pspec)
+{
+  GpaFileSignOperation *op = GPA_FILE_SIGN_OPERATION (object);
+
+  switch (prop_id)
+    {
+    case PROP_FORCE_ARMOR:
+      op->force_armor = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+static void
 gpa_file_sign_operation_finalize (GObject *object)
 {  
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
+
 static void
 gpa_file_sign_operation_init (GpaFileSignOperation *op)
 {
@@ -69,8 +114,10 @@
   op->sig = NULL;
   op->plain = NULL;
   op->sig_filename = NULL;
+  op->force_armor = FALSE;
 }
 
+
 static GObject*
 gpa_file_sign_operation_constructor (GType type,
 				     guint n_construct_properties,
@@ -86,7 +133,8 @@
   op = GPA_FILE_SIGN_OPERATION (object);
   /* Initialize */
   /* Create the "Sign" dialog */
-  op->sign_dialog = gpa_file_sign_dialog_new (GPA_OPERATION (op)->window);
+  op->sign_dialog = gpa_file_sign_dialog_new (GPA_OPERATION (op)->window,
+					      op->force_armor);
   g_signal_connect (G_OBJECT (op->sign_dialog), "response",
 		    G_CALLBACK (gpa_file_sign_operation_response_cb), op);
   /* Connect to the "done" signal */
@@ -103,6 +151,7 @@
   return object;
 }
 
+
 static void
 gpa_file_sign_operation_class_init (GpaFileSignOperationClass *klass)
 {
@@ -112,8 +161,19 @@
 
   object_class->constructor = gpa_file_sign_operation_constructor;
   object_class->finalize = gpa_file_sign_operation_finalize;
+  object_class->set_property = gpa_file_sign_operation_set_property;
+  object_class->get_property = gpa_file_sign_operation_get_property;
+
+  /* Properties */
+  g_object_class_install_property (object_class,
+				   PROP_FORCE_ARMOR,
+				   g_param_spec_boolean
+				   ("force-armor", "Force armor",
+				    "Force armor mode", FALSE,
+				    G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 }
 
+
 GType
 gpa_file_sign_operation_get_type (void)
 {
@@ -145,13 +205,15 @@
 /* API */
 
 GpaFileSignOperation*
-gpa_file_sign_operation_new (GtkWidget *window, GList *files)
+gpa_file_sign_operation_new (GtkWidget *window, GList *files,
+			     gboolean force_armor)
 {
   GpaFileSignOperation *op;
   
   op = g_object_new (GPA_FILE_SIGN_OPERATION_TYPE,
 		     "window", window,
 		     "input_files", files,
+		     "force-armor", force_armor,
 		     NULL);
 
   return op;
@@ -185,28 +247,57 @@
 
 static gboolean
 gpa_file_sign_operation_start (GpaFileSignOperation *op,
-			       const gchar *plain_filename)
+			       gpa_file_item_t file_item)
 {
   gpg_error_t err;
-  
-  op->sig_filename = destination_filename 
-    (plain_filename, gpgme_get_armor (GPA_OPERATION (op)->context->ctx),
-     op->sign_type);
-  /* Open the files */
-  op->plain_fd = gpa_open_input (plain_filename, &op->plain, 
-				 GPA_OPERATION (op)->window);
-  if (op->plain_fd == -1)
+
+  if (file_item->direct_in)
     {
-      return FALSE;
+      gpgme_error_t err;
+
+      /* No copy is made.  */
+      err = gpgme_data_new_from_mem (&op->plain, file_item->direct_in,
+				     file_item->direct_in_len, 0);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  return FALSE;
+	}
+      
+      err = gpgme_data_new (&op->sig);
+      if (err)
+	{
+	  gpa_gpgme_warning (err);
+	  gpgme_data_release (op->plain);
+	  op->plain = NULL;
+	  return FALSE;
+	}
     }
-  op->sig_fd = gpa_open_output (op->sig_filename, &op->sig,
-				GPA_OPERATION (op)->window);
-  if (op->sig_fd == -1)
+  else
     {
-      gpgme_data_release (op->plain);
-      close (op->plain_fd);
-      return FALSE;
+      gchar *plain_filename = file_item->filename_in;
+
+      file_item->filename_out = destination_filename 
+	(plain_filename, gpgme_get_armor (GPA_OPERATION (op)->context->ctx),
+	 op->sign_type);
+
+      /* Open the files */
+      op->plain_fd = gpa_open_input (plain_filename, &op->plain, 
+				     GPA_OPERATION (op)->window);
+      if (op->plain_fd == -1)
+	{
+	  return FALSE;
+	}
+      op->sig_fd = gpa_open_output (file_item->filename_out, &op->sig,
+				    GPA_OPERATION (op)->window);
+      if (op->sig_fd == -1)
+	{
+	  gpgme_data_release (op->plain);
+	  close (op->plain_fd);
+	  return FALSE;
+	}
     }
+  
   /* Start the operation */
   err = gpgme_op_sign_start (GPA_OPERATION (op)->context->ctx, op->plain,
 			     op->sig, op->sign_type);
@@ -219,7 +310,10 @@
   gtk_widget_show_all (GPA_FILE_OPERATION (op)->progress_dialog);
   gpa_progress_dialog_set_label (GPA_PROGRESS_DIALOG 
 				 (GPA_FILE_OPERATION (op)->progress_dialog),
-				 op->sig_filename);
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
+
   return TRUE;
 }
 
@@ -236,30 +330,62 @@
 
 static void
 gpa_file_sign_operation_done_cb (GpaContext *context, 
-				    gpg_error_t err,
-				    GpaFileSignOperation *op)
+				 gpg_error_t err,
+				 GpaFileSignOperation *op)
 {
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
+
+  if (file_item->direct_in)
+    {
+      size_t len;
+      char *sig_gpgme = gpgme_data_release_and_get_mem (op->sig, &len);
+      op->sig = NULL;
+      /* Do the memory allocation dance.  */
+
+      if (sig_gpgme)
+	{
+	  /* Conveniently make ASCII stuff into a string.  */
+	  file_item->direct_out = g_malloc (len + 1);
+	  memcpy (file_item->direct_out, sig_gpgme, len);
+	  gpgme_free (sig_gpgme);
+	  file_item->direct_out[len] = '\0';
+	  /* Yep, excluding the trailing zero.  */
+	  file_item->direct_out_len = len;
+	}
+      else
+	{
+	  file_item->direct_out = NULL;
+	  file_item->direct_out_len = 0;
+	}
+    }
+
   /* Do clean up on the operation */
   gpgme_data_release (op->plain);
+  op->plain = NULL;
   close (op->plain_fd);
+  op->plain_fd = -1;
   gpgme_data_release (op->sig);
+  op->sig = NULL;
   close (op->sig_fd);
+  op->sig_fd = -1;
   gtk_widget_hide (GPA_FILE_OPERATION (op)->progress_dialog);
+
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
     {
-      /* If an error happened, (or the user canceled) delete the created file
-       * and abort further signions
-       */
-      unlink (op->sig_filename);
-      g_free (op->sig_filename);
+      if (! file_item->direct_in)
+	{
+	  /* If an error happened, (or the user canceled) delete the
+	     created file and abort further signions.  */
+	  unlink (op->sig_filename);
+	  g_free (op->sig_filename);
+	}
       g_signal_emit_by_name (GPA_OPERATION (op), "completed");
     }
   else
     {
       /* We've just created a file */
       g_signal_emit_by_name (GPA_OPERATION (op), "created_file",
-			     op->sig_filename);
-      g_free (op->sig_filename);
+			     file_item);
       /* Go to the next file in the list and sign it */
       GPA_FILE_OPERATION (op)->current = g_list_next 
 	(GPA_FILE_OPERATION (op)->current);

Modified: trunk/src/gpafilesignop.h
===================================================================
--- trunk/src/gpafilesignop.h	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafilesignop.h	2008-02-04 20:53:39 UTC (rev 801)
@@ -44,6 +44,7 @@
   int sig_fd, plain_fd;
   gpgme_data_t sig, plain;
   gchar *sig_filename;
+  gboolean force_armor;
 };
 
 struct _GpaFileSignOperationClass {
@@ -58,6 +59,6 @@
  */
 GpaFileSignOperation*
 gpa_file_sign_operation_new (GtkWidget *window,
-			     GList *files);
+			     GList *files, gboolean force_armor);
 
 #endif

Modified: trunk/src/gpafileverifyop.c
===================================================================
--- trunk/src/gpafileverifyop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpafileverifyop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* gpafileverifyop.c - The GpaOperation object.
- *	Copyright (C) 2003, Miguel Coca.
+ * Copyright (C) 2003 Miguel Coca.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -233,47 +234,73 @@
 
 static gboolean
 gpa_file_verify_operation_start (GpaFileVerifyOperation *op,
-				 const gchar *sig_filename)
+				 gpa_file_item_t file_item)
 {
-  gpg_error_t err;
+  gpgme_error_t err;
 
-  if (is_detached_sig (sig_filename, &op->signature_file, &op->signed_file,
-		       GPA_OPERATION (op)->window))
+  if (file_item->direct_in)
     {
-      /* Allocate data objects for a detached signature */
-      op->sig_fd = gpa_open_input (op->signature_file, &op->sig, 
-				   GPA_OPERATION (op)->window);
-      if (op->sig_fd == -1)
+      /* No copy is made.  */
+      err = gpgme_data_new_from_mem (&op->sig, file_item->direct_in,
+				     file_item->direct_in_len, 0);
+      if (err)
 	{
+	  gpa_gpgme_warning (err);
 	  return FALSE;
 	}
-      op->signed_text_fd = gpa_open_input (op->signed_file, &op->signed_text,
-					   GPA_OPERATION (op)->window);
-      if (op->signed_text_fd == -1)
+      
+      err = gpgme_data_new (&op->plain);
+      if (err)
 	{
+	  gpa_gpgme_warning (err);
 	  gpgme_data_release (op->sig);
-	  close (op->sig_fd);
+	  op->sig = NULL;
 	  return FALSE;
 	}
-      op->plain = NULL;
     }
   else
     {
-      /* Allocate data object for non-detached signatures */
-      op->sig_fd = gpa_open_input (sig_filename, &op->sig, 
-				   GPA_OPERATION (op)->window);
-      if (op->sig_fd == -1)
+      const gchar *sig_filename = file_item->filename_in;
+      
+      if (is_detached_sig (sig_filename, &op->signature_file, &op->signed_file,
+			   GPA_OPERATION (op)->window))
 	{
-	  return FALSE;
+	  /* Allocate data objects for a detached signature */
+	  op->sig_fd = gpa_open_input (op->signature_file, &op->sig, 
+				       GPA_OPERATION (op)->window);
+	  if (op->sig_fd == -1)
+	    {
+	      return FALSE;
+	    }
+	  op->signed_text_fd = gpa_open_input (op->signed_file, &op->signed_text,
+					       GPA_OPERATION (op)->window);
+	  if (op->signed_text_fd == -1)
+	    {
+	      gpgme_data_release (op->sig);
+	      close (op->sig_fd);
+	      return FALSE;
+	    }
+	  op->plain = NULL;
 	}
-      if (gpg_err_code (gpgme_data_new (&op->plain)) != GPG_ERR_NO_ERROR)
+      else
 	{
-	  gpgme_data_release (op->sig);
-	  close (op->sig_fd);
-	  return FALSE;
+	  /* Allocate data object for non-detached signatures */
+	  op->sig_fd = gpa_open_input (sig_filename, &op->sig, 
+				       GPA_OPERATION (op)->window);
+	  if (op->sig_fd == -1)
+	    {
+	      return FALSE;
+	    }
+	  err = gpgme_data_new (&op->plain);
+	  if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
+	    {
+	      gpgme_data_release (op->sig);
+	      close (op->sig_fd);
+	      return FALSE;
+	    }
+	  op->signed_text_fd = -1;
+	  op->signed_text = NULL;
 	}
-      op->signed_text_fd = -1;
-      op->signed_text = NULL;
     }
 
   /* Start the operation */
@@ -288,7 +315,10 @@
   gtk_widget_show_all (GPA_FILE_OPERATION (op)->progress_dialog);
   gpa_progress_dialog_set_label (GPA_PROGRESS_DIALOG 
 				 (GPA_FILE_OPERATION (op)->progress_dialog),
-				 sig_filename);
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
+
   return TRUE;
 }
 
@@ -309,18 +339,45 @@
 				    gpg_error_t err,
 				    GpaFileVerifyOperation *op)
 {
-  /* Do clean up on the operation */
-  if (op->plain) 
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
+
+  if (file_item->direct_in)
     {
-      gpgme_data_release (op->plain);
+      size_t len;
+      char *plain_gpgme = gpgme_data_release_and_get_mem (op->plain,
+							   &len);
+      op->plain = NULL;
+      /* Do the memory allocation dance.  */
+
+      if (plain_gpgme)
+	{
+	  /* Conveniently make ASCII stuff into a string.  */
+	  file_item->direct_out = g_malloc (len + 1);
+	  memcpy (file_item->direct_out, plain_gpgme, len);
+	  gpgme_free (plain_gpgme);
+	  file_item->direct_out[len] = '\0';
+	  /* Yep, excluding the trailing zero.  */
+	  file_item->direct_out_len = len;
+	}
+      else
+	{
+	  file_item->direct_out = NULL;
+	  file_item->direct_out_len = 0;
+	}
     }
-  if (op->signed_text)
-    {
-      gpgme_data_release (op->signed_text);
-      close (op->signed_text_fd);
-    }
+
+  /* Do clean up on the operation */
+  gpgme_data_release (op->plain);
+  op->plain = NULL;
+  gpgme_data_release (op->signed_text);
+  op->signed_text = NULL;
+  close (op->signed_text_fd);
+  op->signed_text_fd = -1;
   gpgme_data_release (op->sig);
+  op->sig = NULL;
   close (op->sig_fd);
+  op->sig_fd = -1;
+
   gtk_widget_hide (GPA_FILE_OPERATION (op)->progress_dialog);
   /* Check for error */
   if (gpg_err_code (err) != GPG_ERR_NO_ERROR)
@@ -334,7 +391,9 @@
       result = gpgme_op_verify_result (GPA_OPERATION (op)->context->ctx);
       /* Add the file to the result dialog */
       gpa_file_verify_dialog_add_file (GPA_FILE_VERIFY_DIALOG (op->dialog),
-				       GPA_FILE_OPERATION (op)->current->data,
+				       file_item->direct_name
+				       ? file_item->direct_name
+				       : file_item->filename_out,
 				       op->signed_file, op->signature_file,
 				       result->signatures);
       /* If this was a dettached sig, reset the signed file */
@@ -375,6 +434,7 @@
 gpa_file_verify_operation_done_error_cb (GpaContext *context, gpg_error_t err,
 					 GpaFileVerifyOperation *op)
 {
+  gpa_file_item_t file_item = GPA_FILE_OPERATION (op)->current->data;
   gchar *message;
 
   switch (gpg_err_code (err))
@@ -384,10 +444,14 @@
       /* Ignore these */
       break;
     case GPG_ERR_NO_DATA:
-      message = g_strdup_printf (_("The file \"%s\" contained no OpenPGP "
-				   "data."),
-				 gpa_file_operation_current_file 
-				 (GPA_FILE_OPERATION(op)));
+      message = g_strdup_printf (file_item->direct_name
+				 ? _("\"%s\" contained no OpenPGP data.")
+				 : _("The file \"%s\" contained no OpenPGP"
+				     "data."),
+				 file_item->direct_name
+				 ? file_item->direct_name
+				 : file_item->filename_in);
+
       gpa_window_error (message, GPA_OPERATION (op)->window);
       g_free (message);
       break;

Modified: trunk/src/gpastreamencryptop.c
===================================================================
--- trunk/src/gpastreamencryptop.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpastreamencryptop.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,5 @@
 /* gpastreamdecryptop.c - The GpaOperation object.
- *	Copyright (C) 2007 g10 Code GmbH
+ * Copyright (C) 2007, 2008 g10 Code GmbH
  *
  * This file is part of GPA.
  *
@@ -88,7 +88,7 @@
 
   /* Create the "Encrypt" dialog */
   op->encrypt_dialog = gpa_file_encrypt_dialog_new
-    (GPA_OPERATION (op)->window);
+    (GPA_OPERATION (op)->window, FALSE);
 
   g_signal_connect (G_OBJECT (op->encrypt_dialog), "response",
 		    G_CALLBACK (response_cb), op);

Modified: trunk/src/gpawidgets.c
===================================================================
--- trunk/src/gpawidgets.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/gpawidgets.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,6 +1,6 @@
 /* gpawidgets.c  -  The GNU Privacy Assistant
    Copyright (C) 2000, 2001 G-N-U GmbH.
-   Copyright (C) 2005 g10 Code GmbH.
+   Copyright (C) 2005, 2008 g10 Code GmbH.
 
    This file is part of GPA.
 
@@ -212,7 +212,7 @@
   gtk_box_pack_start (GTK_BOX (hboxAfter), radioAfter, FALSE, FALSE, 0);
   entryAfter = gtk_entry_new ();
   frame->entryAfter = entryAfter;
-  gtk_widget_set_usize (entryAfter,
+  gtk_widget_set_size_request (entryAfter,
     gdk_string_width (gtk_style_get_font (entryAfter->style), " 00000 "), 0);
   gtk_box_pack_start (GTK_BOX (hboxAfter), entryAfter, FALSE, FALSE, 0);
 

Modified: trunk/src/helpmenu.c
===================================================================
--- trunk/src/helpmenu.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/helpmenu.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,6 +1,7 @@
 /* helpmenu.c  -  The GNU Privacy Assistant
- *	Copyright (C) 2000, 2001 G-N-U GmbH.
- *	Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ * Copyright (C) 2000, 2001 G-N-U GmbH.
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -396,7 +397,7 @@
   gtk_text_view_set_editable (GTK_TEXT_VIEW (textGPL), FALSE);
   gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (textGPL)),
 			    gpa_license_text, -1);
-  gtk_widget_set_usize (textGPL, 500, 300);
+  gtk_widget_set_size_request (textGPL, 500, 300);
   licenseScrolled = gtk_scrolled_window_new (NULL, NULL);
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (licenseScrolled),
 				  GTK_POLICY_AUTOMATIC,
@@ -446,7 +447,8 @@
      "<StockItem>", GTK_STOCK_HELP}
 #endif
     {_("/Help/_License"), NULL, (GtkItemFactoryCallback)help_license, 0, NULL},
-    {_("/Help/_About"), NULL, (GtkItemFactoryCallback)help_about, 0, NULL}
+    {_("/Help/_About"), NULL, (GtkItemFactoryCallback)help_about, 0,
+     "<StockItem>", GTK_STOCK_ABOUT }
   };
 
   gtk_item_factory_create_items (factory, sizeof (menu) / sizeof (menu[0]),

Modified: trunk/src/keyimpseldlg.c
===================================================================
--- trunk/src/keyimpseldlg.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/keyimpseldlg.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* keyimpseldlg.c - The GNU Privacy Assistant - Key import selection dialog
  * Copyright (C) 2002 G-N-U GmbH
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA.
  *
@@ -134,7 +135,7 @@
   gtk_box_pack_start (GTK_BOX (vboxWhich), labelWhich, FALSE, TRUE, 0);
 
   scrollerWhich = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_set_usize (scrollerWhich, 260, 75);
+  gtk_widget_set_size_request (scrollerWhich, 260, 75);
   gtk_box_pack_start (GTK_BOX (vboxWhich), scrollerWhich, TRUE, TRUE, 0);
 
   clistWhich = gpa_key_list_new_from_glist (parent, dialog.keys);

Modified: trunk/src/keyring.c
===================================================================
--- trunk/src/keyring.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/keyring.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -889,8 +889,9 @@
   };
   GtkItemFactoryEntry win_menu[] = {
     {_("/_Windows"), NULL, NULL, 0, "<Branch>"},
+    {_("/Windows/_Keyring Editor"), NULL, gpa_open_keyring_editor, 0, NULL},
     {_("/Windows/_Filemanager"), NULL, gpa_open_filemanager, 0, NULL},
-    {_("/Windows/_Keyring Editor"), NULL, gpa_open_keyring_editor, 0, NULL},
+    {_("/Windows/_Clipboard"), NULL, gpa_open_clipboard, 0, NULL},
   };
   GtkWidget *item;
 
@@ -1654,6 +1655,15 @@
 				  GTK_SIGNAL_FUNC (gpa_open_filemanager),
 				  NULL);
 
+  /* FIXME: Should be just the clipboard icon.  */
+  icon = gtk_image_new_from_stock ("gtk-paste",
+				   GTK_ICON_SIZE_SMALL_TOOLBAR);
+  item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Clipboard"),
+				  _("Open the clipboard"),
+				  _("clipboard"), icon,
+				  GTK_SIGNAL_FUNC (gpa_open_clipboard),
+				  NULL);
+
 #if 0  /* Help is not available yet. :-( */
   icon = gpa_create_icon_widget (window, "help");
   item = gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), _("Help"),

Modified: trunk/src/settingsdlg.c
===================================================================
--- trunk/src/settingsdlg.c	2008-02-04 14:36:03 UTC (rev 800)
+++ trunk/src/settingsdlg.c	2008-02-04 20:53:39 UTC (rev 801)
@@ -1,5 +1,6 @@
 /* settingsdlg.c - The GNU Privacy Assistant
- *	Copyright (C) 2002, Miguel Coca
+ * Copyright (C) 2002, Miguel Coca
+ * Copyright (C) 2008 g10 Code GmbH.
  *
  * This file is part of GPA
  *
@@ -54,7 +55,7 @@
   gtk_scrolled_window_set_policy  (GTK_SCROLLED_WINDOW (scroller),
 				   GTK_POLICY_AUTOMATIC,
 				   GTK_POLICY_AUTOMATIC);
-  gtk_widget_set_usize (scroller, 320, 120);
+  gtk_widget_set_size_request (scroller, 320, 120);
   gtk_container_set_border_width (GTK_CONTAINER (scroller), 5);
   gtk_container_add (GTK_CONTAINER (scroller), list);
   gtk_container_add (GTK_CONTAINER (frame), scroller);



More information about the Gpa-commits mailing list