4
* Copyright (C) 2005 Adam Schreiber <sadam@clemson.edu>
5
* Copyright (C) 1999 Dave Camp
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
#include <panel-applet.h>
26
#include <dbus/dbus-glib-bindings.h>
30
#include "seahorse-applet.h"
31
#include "seahorse-gtkstock.h"
32
#include "seahorse-context.h"
33
#include "seahorse-pgp-key.h"
34
#include "seahorse-libdialogs.h"
35
#include "seahorse-widget.h"
36
#include "seahorse-util.h"
37
#include "seahorse-gconf.h"
38
#include "seahorse-secure-memory.h"
39
#include "seahorse-check-button-control.h"
41
#define APPLET_SCHEMAS SEAHORSE_SCHEMAS "/applet"
42
#define SHOW_CLIPBOARD_STATE_KEY APPLET_SCHEMAS "/show_clipboard_state"
43
#define DISPLAY_CLIPBOARD_ENC_KEY APPLET_SCHEMAS "/display_encrypted_clipboard"
44
#define DISPLAY_CLIPBOARD_DEC_KEY APPLET_SCHEMAS "/display_decrypted_clipboard"
46
/* -----------------------------------------------------------------------------
50
/* Setup in init_crypt */
51
DBusGConnection *dbus_connection = NULL;
52
DBusGProxy *dbus_key_proxy = NULL;
53
DBusGProxy *dbus_crypto_proxy = NULL;
54
CryptUIKeyset *dbus_keyset = NULL;
61
if (!dbus_connection) {
62
dbus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
63
if (!dbus_connection) {
68
dbus_key_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
69
"/org/gnome/seahorse/keys",
70
"org.gnome.seahorse.KeyService");
72
dbus_crypto_proxy = dbus_g_proxy_new_for_name (dbus_connection, "org.gnome.seahorse",
73
"/org/gnome/seahorse/crypto",
74
"org.gnome.seahorse.CryptoService");
76
dbus_keyset = cryptui_keyset_new ("openpgp", TRUE);
81
/* -----------------------------------------------------------------------------
85
#define ICON_CLIPBOARD_UNKNOWN "seahorse-applet-unknown"
86
#define ICON_CLIPBOARD_TEXT "seahorse-applet-text"
87
#define ICON_CLIPBOARD_ENCRYPTED "seahorse-applet-encrypted"
88
#define ICON_CLIPBOARD_SIGNED "seahorse-applet-signed"
89
#define ICON_CLIPBOARD_KEY "seahorse-applet-key"
90
#define ICON_CLIPBOARD_DEFAULT ICON_CLIPBOARD_ENCRYPTED
92
static const gchar *clipboard_icons[] = {
93
ICON_CLIPBOARD_UNKNOWN,
95
ICON_CLIPBOARD_ENCRYPTED,
96
ICON_CLIPBOARD_SIGNED,
102
SEAHORSE_TEXT_TYPE_NONE,
103
SEAHORSE_TEXT_TYPE_PLAIN,
104
SEAHORSE_TEXT_TYPE_KEY,
105
SEAHORSE_TEXT_TYPE_MESSAGE,
106
SEAHORSE_TEXT_TYPE_SIGNED
109
typedef struct _SeahorsePGPHeader {
112
SeahorseTextType type;
115
static const SeahorsePGPHeader seahorse_pgp_headers[] = {
117
"-----BEGIN PGP MESSAGE-----",
118
"-----END PGP MESSAGE-----",
119
SEAHORSE_TEXT_TYPE_MESSAGE
122
"-----BEGIN PGP SIGNED MESSAGE-----",
123
"-----END PGP SIGNATURE-----",
124
SEAHORSE_TEXT_TYPE_SIGNED
127
"-----BEGIN PGP PUBLIC KEY BLOCK-----",
128
"-----END PGP PUBLIC KEY BLOCK-----",
129
SEAHORSE_TEXT_TYPE_KEY
132
"-----BEGIN PGP PRIVATE KEY BLOCK-----",
133
"-----END PGP PRIVATE KEY BLOCK-----",
134
SEAHORSE_TEXT_TYPE_KEY
138
/* -----------------------------------------------------------------------------
142
typedef struct _SeahorseAppletPrivate {
144
GtkTooltips *tooltips;
145
SeahorseContext *context;
148
SeahorseTextType clipboard_contents;
149
} SeahorseAppletPrivate;
151
#define SEAHORSE_APPLET_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), SEAHORSE_TYPE_APPLET, SeahorseAppletPrivate))
153
G_DEFINE_TYPE (SeahorseApplet, seahorse_applet, PANEL_TYPE_APPLET);
155
/* -----------------------------------------------------------------------------
160
init_context (SeahorseApplet *sapplet)
162
SeahorseAppletPrivate *priv;
164
priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
165
if (!priv->context) {
166
priv->context = seahorse_context_new (SEAHORSE_CONTEXT_APP, SKEY_PGP);
167
seahorse_context_load_local_keys_async (priv->context);
172
detect_text_type (const gchar *text, gint len, const gchar **start, const gchar **end)
174
const SeahorsePGPHeader *header;
175
const gchar *pos = NULL;
182
/* Find the first of the headers */
183
for (i = 0; i < (sizeof (seahorse_pgp_headers) / sizeof (seahorse_pgp_headers[0])); i++) {
184
t = g_strstr_len (text, len, seahorse_pgp_headers[i].header);
186
if (pos == NULL || (t < pos)) {
187
header = &(seahorse_pgp_headers[i]);
198
/* Find the end of that block */
199
t = g_strstr_len (pos, len - (pos - text), header->footer);
200
if (t != NULL && end)
201
*end = t + strlen(header->footer);
208
return SEAHORSE_TEXT_TYPE_PLAIN;
212
update_icon (SeahorseApplet *sapplet)
214
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
215
const char *stock = NULL;
217
if (seahorse_gconf_get_boolean (SHOW_CLIPBOARD_STATE_KEY)) {
218
switch (priv->clipboard_contents) {
219
case SEAHORSE_TEXT_TYPE_NONE:
220
stock = ICON_CLIPBOARD_UNKNOWN;
222
case SEAHORSE_TEXT_TYPE_PLAIN:
223
stock = ICON_CLIPBOARD_TEXT;
225
case SEAHORSE_TEXT_TYPE_KEY:
226
stock = ICON_CLIPBOARD_KEY;
228
case SEAHORSE_TEXT_TYPE_MESSAGE:
229
stock = ICON_CLIPBOARD_ENCRYPTED;
231
case SEAHORSE_TEXT_TYPE_SIGNED:
232
stock = ICON_CLIPBOARD_SIGNED;
235
g_assert_not_reached ();
240
stock = ICON_CLIPBOARD_DEFAULT;
243
gtk_image_set_from_stock (GTK_IMAGE (priv->image), stock, GTK_ICON_SIZE_LARGE_TOOLBAR);
247
detect_received(GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
249
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
252
priv->clipboard_contents = SEAHORSE_TEXT_TYPE_NONE;
254
priv->clipboard_contents = detect_text_type (text, -1, NULL, NULL);
256
update_icon (sapplet);
260
handle_clipboard_owner_change(GtkClipboard *clipboard, GdkEvent *event,
261
SeahorseApplet *sapplet)
263
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
264
priv->board = clipboard;
266
if (seahorse_gconf_get_boolean (SHOW_CLIPBOARD_STATE_KEY))
267
gtk_clipboard_request_text (clipboard,
268
(GtkClipboardTextReceivedFunc)detect_received, sapplet);
270
update_icon (sapplet);
273
/* Makes URL in About Dialog Clickable */
274
static void about_dialog_activate_link_cb (GtkAboutDialog *about,
278
gnome_url_show (url, NULL);
282
about_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const gchar *verbname)
284
static gboolean been_here = FALSE;
286
static const gchar *authors [] = {
287
"Adam Schreiber <sadam@clemson.edu>",
288
"Stef Walter <stef@memberwebs.com>",
292
static const gchar *documenters[] = {
293
"Adam Schreiber <sadam@clemson.edu>",
297
static const gchar *artists[] = {
298
"Stef Walter <stef@memberwebs.com>",
305
gtk_about_dialog_set_url_hook (about_dialog_activate_link_cb, NULL, NULL);
308
gtk_show_about_dialog (NULL,
309
"name", _("seahorse-applet"),
311
"comments", _("Use PGP/GPG to encrypt/decrypt/sign/verify/import the clipboard."),
312
"copyright", "\xC2\xA9 2005, 2006 Adam Schreiber",
314
"documenters", documenters,
316
"translator-credits", _("translator-credits"),
317
"logo-icon-name", "seahorse-applet",
318
"website", "http://www.gnome.org/projects/seahorse",
319
"website-label", _("Seahorse Project Homepage"),
324
display_text (gchar *title, gchar *text, gboolean editable)
326
GtkWidget *dialog, *scrolled_window, *text_view;
327
GtkTextBuffer *buffer;
330
dialog = gtk_dialog_new_with_buttons (title, NULL, 0,
331
GTK_STOCK_CLOSE, GTK_RESPONSE_NONE, NULL);
333
gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 450);
334
g_signal_connect_swapped (dialog, "response",
335
G_CALLBACK (gtk_widget_destroy), dialog);
337
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
338
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), scrolled_window);
340
text_view = gtk_text_view_new ();
341
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), editable);
342
gtk_text_view_set_left_margin (GTK_TEXT_VIEW (text_view), 8);
343
gtk_text_view_set_right_margin (GTK_TEXT_VIEW (text_view), 8);
344
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), GTK_WRAP_WORD);
345
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
347
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
348
gtk_text_buffer_set_text (buffer, text, strlen (text));
350
pixbuf = gtk_widget_render_icon (dialog,
351
ICON_CLIPBOARD_DEFAULT,
355
gtk_window_set_icon (GTK_WINDOW (dialog), pixbuf);
357
g_object_unref(pixbuf);
359
gtk_widget_show_all (dialog);
363
encrypt_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
365
gchar *signer = NULL;
366
gchar *enctext = NULL;
370
/* No text on clipboard */
374
/* Get the recipient list */
375
keys = cryptui_prompt_recipients (dbus_keyset, _("Choose Recipient Keys"), &signer);
377
/* User may have cancelled */
379
ret = dbus_g_proxy_call (dbus_crypto_proxy, "EncryptText", NULL,
381
G_TYPE_STRING, signer,
385
G_TYPE_STRING, &enctext,
390
gtk_clipboard_set_text (board, enctext, strlen (enctext));
391
detect_received (board, enctext, sapplet);
393
if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_ENC_KEY) == TRUE)
394
display_text (_("Encrypted Text"), enctext, FALSE);
396
seahorse_notification_display(_("Encryption Failed"),
397
_("The clipboard could not be encrypted."),
400
GTK_WIDGET(sapplet));
409
encrypt_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
411
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
416
gtk_clipboard_request_text (priv->board,
417
(GtkClipboardTextReceivedFunc)encrypt_received, sapplet);
421
sign_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
423
gchar *signer = NULL;
424
gchar *enctext = NULL;
427
/* No text on clipboard */
431
signer = cryptui_prompt_signer (dbus_keyset, _("Choose Key to Sign with"));
435
/* Perform the signing */
436
ret = dbus_g_proxy_call (dbus_crypto_proxy, "SignText", NULL,
437
G_TYPE_STRING, signer,
441
G_TYPE_STRING, &enctext,
446
gtk_clipboard_set_text (board, enctext, strlen (enctext));
447
detect_received (board, enctext, sapplet);
449
if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_ENC_KEY) == TRUE)
450
display_text (_("Signed Text"), enctext, FALSE);
452
seahorse_notification_display(_("Signing Failed"),
453
_("The clipboard could not be Signed."),
456
GTK_WIDGET(sapplet));
464
sign_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
466
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
471
gtk_clipboard_request_text (priv->board,
472
(GtkClipboardTextReceivedFunc)sign_received, sapplet);
475
/* When we try to 'decrypt' a key, this gets called */
477
import_keys (const gchar *text, SeahorseApplet *sapplet)
483
ret = dbus_g_proxy_call (dbus_key_proxy, "ImportKeys", NULL,
484
G_TYPE_STRING, "openpgp",
491
for (k = keys, nkeys = 0; *k; k++)
496
seahorse_notification_display(_("Import Failed"),
497
_("Keys were found but not imported."),
500
GTK_WIDGET(sapplet));
506
/* Decrypt an encrypted message */
508
decrypt_text (const gchar *text, SeahorseApplet *sapplet)
510
gchar *rawtext = NULL;
511
gchar *signer = NULL;
514
ret = dbus_g_proxy_call (dbus_crypto_proxy, "DecryptText", NULL,
515
G_TYPE_STRING, "openpgp",
519
G_TYPE_STRING, &rawtext,
520
G_TYPE_STRING, &signer,
528
seahorse_notification_display(_("Decrypting Failed"),
529
_("Text may be malformed."),
532
GTK_WIDGET(sapplet));
537
/* Verify a signed message */
539
verify_text (const gchar *text, SeahorseApplet *sapplet)
541
gchar *rawtext = NULL;
545
ret = dbus_g_proxy_call (dbus_crypto_proxy, "VerifyText", NULL,
546
G_TYPE_STRING, "openpgp",
550
G_TYPE_STRING, &rawtext,
551
G_TYPE_STRING, &signer,
555
/* Not interested in the signer */
565
dvi_received (GtkClipboard *board, const gchar *text, SeahorseApplet *sapplet)
567
SeahorseTextType type; /* Type of the current block */
568
gchar *rawtext = NULL; /* Replacement text */
569
guint keys = 0; /* Number of keys imported */
570
const gchar *start; /* Pointer to start of the block */
571
const gchar *end; /* Pointer to end of the block */
573
/* Try to figure out what clipboard contains */
575
type = SEAHORSE_TEXT_TYPE_NONE;
577
type = detect_text_type (text, -1, &start, &end);
579
if (type == SEAHORSE_TEXT_TYPE_NONE || type == SEAHORSE_TEXT_TYPE_PLAIN) {
580
seahorse_notification_display(_("No PGP key or message was found on clipboard"),
581
_("No PGP data found."), FALSE, NULL, GTK_WIDGET(sapplet));
587
/* A key, import it */
588
case SEAHORSE_TEXT_TYPE_KEY:
589
keys = import_keys (text, sapplet);
592
/* A message decrypt it */
593
case SEAHORSE_TEXT_TYPE_MESSAGE:
594
rawtext = decrypt_text (text, sapplet);
597
/* A message verify it */
598
case SEAHORSE_TEXT_TYPE_SIGNED:
599
rawtext = verify_text (text, sapplet);
603
g_assert_not_reached ();
607
/* We got replacement text */
610
gtk_clipboard_set_text (board, rawtext, strlen (rawtext));
611
detect_received (board, rawtext, sapplet);
613
if (seahorse_gconf_get_boolean (DISPLAY_CLIPBOARD_DEC_KEY) == TRUE)
615
/* TRANSLATORS: This means 'The text that was decrypted' */
616
display_text (_("Decrypted Text"), rawtext, TRUE);
625
dvi_cb (GtkMenuItem *menuitem, SeahorseApplet *sapplet)
627
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (sapplet);
632
gtk_clipboard_request_text (priv->board,
633
(GtkClipboardTextReceivedFunc)dvi_received, sapplet);
637
properties_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const char *verbname)
639
SeahorseWidget *swidget;
643
/* SeahorseWidget needs a SeahorseContext initialized */
644
init_context (sapplet);
646
swidget = seahorse_widget_new ("applet-preferences", NULL);
648
widget = glade_xml_get_widget (swidget->xml, swidget->name);
650
pixbuf = gtk_widget_render_icon (widget,
651
ICON_CLIPBOARD_DEFAULT,
655
gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
657
g_object_unref(pixbuf);
659
/* Preferences window is already open */
663
widget = glade_xml_get_widget (swidget->xml, "show-clipboard-state");
664
if (widget && GTK_IS_CHECK_BUTTON (widget))
665
seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), SHOW_CLIPBOARD_STATE_KEY);
667
widget = glade_xml_get_widget (swidget->xml, "display-encrypted-clipboard");
668
if (widget && GTK_IS_CHECK_BUTTON (widget))
669
seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), DISPLAY_CLIPBOARD_ENC_KEY);
671
widget = glade_xml_get_widget (swidget->xml, "display-decrypted-clipboard");
672
if (widget && GTK_IS_CHECK_BUTTON (widget))
673
seahorse_check_button_gconf_attach (GTK_CHECK_BUTTON (widget), DISPLAY_CLIPBOARD_DEC_KEY);
675
seahorse_widget_show (swidget);
679
help_cb (BonoboUIComponent *uic, SeahorseApplet *sapplet, const char *verbname)
683
gnome_help_display ("seahorse-applet", NULL, &err);
685
seahorse_util_handle_error(err, _("Could not display the help file"));
689
seahorse_popup_position_menu (GtkMenu *menu, int *x, int *y, gboolean *push_in,
693
GtkRequisition requisition;
697
widget = GTK_WIDGET (gdata);
699
gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
700
gdk_window_get_origin (widget->window, &menu_xpos, &menu_ypos);
702
menu_xpos += widget->allocation.x;
703
menu_ypos += widget->allocation.y;
705
switch (panel_applet_get_orient (PANEL_APPLET (widget))) {
706
case PANEL_APPLET_ORIENT_DOWN:
707
case PANEL_APPLET_ORIENT_UP:
708
if (menu_ypos > gdk_screen_get_height (gtk_widget_get_screen (widget)) / 2)
709
menu_ypos -= requisition.height;
711
menu_ypos += widget->allocation.height;
713
case PANEL_APPLET_ORIENT_RIGHT:
714
case PANEL_APPLET_ORIENT_LEFT:
715
if (menu_xpos > gdk_screen_get_width (gtk_widget_get_screen (widget)) / 2)
716
menu_xpos -= requisition.width;
718
menu_xpos += widget->allocation.width;
721
g_assert_not_reached ();
730
handle_button_press (GtkWidget *widget, GdkEventButton *event)
733
SeahorseApplet *applet = SEAHORSE_APPLET (widget);
734
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (applet);
736
if (event->button == 1) {
739
gtk_widget_destroy (priv->menu);
744
priv->menu = gtk_menu_new ();
746
if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_PLAIN ||
747
priv->clipboard_contents == SEAHORSE_TEXT_TYPE_NONE) {
748
item = gtk_image_menu_item_new_with_mnemonic (_("_Encrypt Clipboard"));
749
g_signal_connect (item, "activate", G_CALLBACK (encrypt_cb), applet);
750
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
753
if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_PLAIN ||
754
priv->clipboard_contents == SEAHORSE_TEXT_TYPE_NONE) {
755
item = gtk_image_menu_item_new_with_mnemonic (_("_Sign Clipboard"));
756
g_signal_connect (item, "activate", G_CALLBACK (sign_cb), applet);
757
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
760
if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_MESSAGE ||
761
priv->clipboard_contents == SEAHORSE_TEXT_TYPE_SIGNED) {
762
item = gtk_image_menu_item_new_with_mnemonic (_("_Decrypt/Verify Clipboard"));
763
g_signal_connect (item, "activate", G_CALLBACK (dvi_cb), applet);
764
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
767
if (priv->clipboard_contents == SEAHORSE_TEXT_TYPE_KEY) {
768
item = gtk_image_menu_item_new_with_mnemonic (_("_Import Keys from Clipboard"));
769
g_signal_connect (item, "activate", G_CALLBACK (dvi_cb), applet);
770
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), item);
773
gtk_widget_show_all (priv->menu);
775
gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, seahorse_popup_position_menu,
776
(gpointer)applet, event->button, event->time);
780
if (GTK_WIDGET_CLASS (seahorse_applet_parent_class)->button_press_event)
781
return (* GTK_WIDGET_CLASS (seahorse_applet_parent_class)->button_press_event) (widget, event);
787
set_atk_name_description (GtkWidget *widget, const gchar *name, const gchar *description)
789
AtkObject *aobj = gtk_widget_get_accessible (widget);
791
/* Check if gail is loaded */
792
if (GTK_IS_ACCESSIBLE (aobj) == FALSE)
795
atk_object_set_name (aobj, name);
796
atk_object_set_description (aobj, description);
800
gconf_notify (GConfClient *client, guint id, GConfEntry *entry, gpointer *data)
802
update_icon (SEAHORSE_APPLET (data));
805
/* -----------------------------------------------------------------------------
810
seahorse_applet_init (SeahorseApplet *applet)
812
SeahorseAppletPrivate *priv;
816
priv = SEAHORSE_APPLET_GET_PRIVATE (applet);
819
* We initialize the context on first operation to avoid
820
* problems with slowing down gnome-panel loading at
824
priv->clipboard_contents = SEAHORSE_TEXT_TYPE_NONE;
826
priv->image = gtk_image_new ();
827
priv->tooltips = gtk_tooltips_new ();
829
gtk_container_add (GTK_CONTAINER (applet), priv->image);
831
g_object_ref (priv->tooltips);
832
gtk_object_sink (GTK_OBJECT (priv->tooltips));
833
gtk_tooltips_set_tip (priv->tooltips, GTK_WIDGET (applet), _("Encryption Applet"), NULL);
835
set_atk_name_description (GTK_WIDGET (applet), _("Encryption Applet"),
836
_("Use PGP/GPG to encrypt/decrypt/sign/verify/import the clipboard."));
838
/* Setup Clipboard Handling */
839
atom = gdk_atom_intern ("CLIPBOARD", FALSE);
840
board = gtk_clipboard_get (atom);
841
handle_clipboard_owner_change (board, NULL, applet);
842
g_signal_connect (board, "owner-change",
843
G_CALLBACK (handle_clipboard_owner_change), applet);
845
atom = gdk_atom_intern ("PRIMARY", FALSE);
846
board = gtk_clipboard_get (atom);
847
g_signal_connect (board, "owner-change",
848
G_CALLBACK (handle_clipboard_owner_change), applet);
853
seahorse_applet_change_background (PanelApplet *applet, PanelAppletBackgroundType type,
854
GdkColor *colour, GdkPixmap *pixmap)
856
GtkRcStyle *rc_style;
860
gtk_widget_set_style (GTK_WIDGET (applet), NULL);
861
rc_style = gtk_rc_style_new ();
862
gtk_widget_modify_style (GTK_WIDGET (applet), rc_style);
863
gtk_rc_style_unref (rc_style);
866
case PANEL_NO_BACKGROUND:
868
case PANEL_COLOR_BACKGROUND:
869
gtk_widget_modify_bg (GTK_WIDGET (applet), GTK_STATE_NORMAL, colour);
871
case PANEL_PIXMAP_BACKGROUND:
872
style = gtk_style_copy (GTK_WIDGET (applet)->style);
874
if (style->bg_pixmap[GTK_STATE_NORMAL])
875
g_object_unref (style->bg_pixmap[GTK_STATE_NORMAL]);
877
style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref (pixmap);
878
gtk_widget_set_style (GTK_WIDGET (applet), style);
879
g_object_unref (style);
885
seahorse_applet_finalize (GObject *object)
887
SeahorseAppletPrivate *priv = SEAHORSE_APPLET_GET_PRIVATE (object);
891
seahorse_context_destroy (priv->context);
892
priv->context = NULL;
895
gtk_widget_destroy (priv->menu);
899
g_object_unref (G_OBJECT (priv->tooltips));
900
priv->tooltips = NULL;
903
if (G_OBJECT_CLASS (seahorse_applet_parent_class)->finalize)
904
(* G_OBJECT_CLASS (seahorse_applet_parent_class)->finalize) (object);
907
g_object_unref (dbus_key_proxy);
908
dbus_key_proxy = NULL;
910
if (dbus_crypto_proxy)
911
g_object_unref (dbus_crypto_proxy);
912
dbus_crypto_proxy = NULL;
915
dbus_g_connection_unref (dbus_connection);
916
dbus_connection = NULL;
920
seahorse_applet_class_init (SeahorseAppletClass *klass)
922
GObjectClass *object_class;
923
PanelAppletClass *applet_class;
924
GtkWidgetClass *widget_class;
926
object_class = G_OBJECT_CLASS (klass);
927
applet_class = PANEL_APPLET_CLASS (klass);
928
widget_class = GTK_WIDGET_CLASS(klass);
930
object_class->finalize = seahorse_applet_finalize;
931
applet_class->change_background = seahorse_applet_change_background;
932
widget_class->button_press_event = handle_button_press;
934
g_type_class_add_private (object_class, sizeof (SeahorseAppletPrivate));
939
/* -----------------------------------------------------------------------------
943
static const BonoboUIVerb seahorse_applet_menu_verbs [] = {
944
BONOBO_UI_UNSAFE_VERB ("Props", properties_cb),
945
BONOBO_UI_UNSAFE_VERB ("Help", help_cb),
946
BONOBO_UI_UNSAFE_VERB ("About", about_cb),
951
seahorse_applet_fill (PanelApplet *applet)
953
SeahorseApplet *sapplet = SEAHORSE_APPLET (applet);
954
BonoboUIComponent *pcomp;
956
/* Insert Icons into Stock */
957
seahorse_gtkstock_init ();
958
seahorse_gtkstock_add_icons (clipboard_icons);
959
g_return_val_if_fail (PANEL_IS_APPLET (applet), FALSE);
960
gtk_widget_show_all (GTK_WIDGET (applet));
962
panel_applet_setup_menu_from_file (applet, UIDIR, "GNOME_SeahorseApplet.xml",
963
NULL, seahorse_applet_menu_verbs, sapplet);
965
pcomp = panel_applet_get_popup_component (applet);
967
if (panel_applet_get_locked_down (applet))
968
bonobo_ui_component_set_prop (pcomp, "/commands/Props", "hidden", "1", NULL);
970
update_icon (sapplet);
971
seahorse_gconf_notify_lazy (APPLET_SCHEMAS, (GConfClientNotifyFunc)gconf_notify,
972
sapplet, GTK_WIDGET (applet));
978
seahorse_applet_factory (PanelApplet *applet, const gchar *iid, gpointer data)
980
gboolean retval = FALSE;
982
if (!strcmp (iid, "OAFIID:GNOME_SeahorseApplet"))
983
retval = seahorse_applet_fill (applet);
992
* We define our own main() since we have to do prior initialization.
993
* This is copied from panel-applet.h
997
main (int argc, char *argv [])
999
bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
1000
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1001
textdomain (GETTEXT_PACKAGE);
1003
seahorse_secure_memory_init ();
1005
gnome_program_init ("seahorse-applet", VERSION, LIBGNOMEUI_MODULE, argc, argv,
1006
GNOME_CLIENT_PARAM_SM_CONNECT, FALSE,
1007
GNOME_PROGRAM_STANDARD_PROPERTIES, GNOME_PARAM_NONE);
1009
return panel_applet_factory_main ("OAFIID:GNOME_SeahorseApplet_Factory",
1010
SEAHORSE_TYPE_APPLET, seahorse_applet_factory, NULL);