The new icon code is ready. However the whiole module needs a lot
authorWerner Koch <wk@gnupg.org>
Tue, 3 Nov 2009 12:01:24 +0000 (12:01 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 3 Nov 2009 12:01:24 +0000 (12:01 +0000)
more testing because I rewrote a lot of code.

30 files changed:
ChangeLog
NEWS
TODO
forms/Makefile.am
forms/gpgol-cs_en.cfg [new file with mode: 0644]
forms/gpgol-ms_en.cfg [new file with mode: 0644]
forms/gpgol_en.cfg [new file with mode: 0644]
po/de.po
po/sv.po
src/ChangeLog
src/Makefile.am
src/cmdbarcontrols.h
src/common.h
src/display.cpp
src/display.h
src/ext-commands.cpp
src/inspectors.cpp
src/inspectors.h
src/item-events.cpp
src/mailitem.cpp [new file with mode: 0644]
src/mailitem.h [new file with mode: 0644]
src/main.c
src/message-events.cpp
src/message.cpp
src/message.h
src/myexchext.h
src/olflange.cpp
src/oomhelp.cpp
src/oomhelp.h
src/revert.cpp

index d4c7221..941ffa3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-02  Werner Koch  <wk@g10code.com>
+
+       * forms/Makefile.am (cfg_english): New.
+
 2009-10-30  Werner Koch  <wk@g10code.com>
 
        * forms/Makefile.am (icons): Udpate all icons.
diff --git a/NEWS b/NEWS
index 4cfd55b..049aa48 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,7 @@
 Noteworthy changes for version 1.1.0
 ===================================================
 
- * Replaced some ECF code by direct OOM code.  This was required to
+ * Replaced most ECE code by direct OOM code.  This was required to
    support better icons; i.e. icons not limited to a 16 color palette.
 
  * New icons.
diff --git a/TODO b/TODO
index f4f7c77..20ff33a 100644 (file)
--- a/TODO
+++ b/TODO
@@ -15,5 +15,3 @@
   presented file names and decrypt them only on OpenSzFile.  Need to
   find some documentation first.
 
-* We need to use the micalg as returned by the UI-server.
-
index 2c51f3c..564c604 100644 (file)
 
 icons = encr-l.ico encr-s.ico sign-l.ico sign-s.ico
 
-cfg_german = gpgol_de.cfg gpgol-ms_de.cfg gpgol-cs_de.cfg 
+cfg_german  = gpgol_de.cfg gpgol-ms_de.cfg gpgol-cs_de.cfg 
+cfg_english = gpgol_en.cfg gpgol-ms_en.cfg gpgol-cs_en.cfg 
+
+dist_pkgdata_DATA = $(icons) $(cfg_german) $(cfg_english)
 
-dist_pkgdata_DATA = $(icons) $(cfg_german)
 
 
 
diff --git a/forms/gpgol-cs_en.cfg b/forms/gpgol-cs_en.cfg
new file mode 100644 (file)
index 0000000..8a8a351
--- /dev/null
@@ -0,0 +1,35 @@
+[Description]
+MessageClass=IPM.Note.GpgOL.ClearSigned
+DesignerRuntimeGuid={0006F020-0000-0000-C000-000000000046}
+CLSID={00061033-0000-0000-C000-000000000046}
+DisplayName=Form for class IPM.Note.GpgOL.MultipartSigned
+Category=Standard
+Subcategory=Formular
+Comment=
+LargeIcon=sign-l.ico
+SmallIcon=sign-s.ico
+VersionMajor=1
+VersionMinor=0
+Locale=eng
+Hidden=1
+Owner=Public Domain
+
+[Properties]
+
+[Verbs]
+Verb1=1
+
+[Verb.1]
+DisplayName=&Open
+Code=0
+Flags=0
+Attribs=2
+
+[Extensions]
+Extensions1=1
+
+[Extension.1]
+Type=30
+NmidPropset={00020D0C-0000-0000-C000-000000000046}
+NmidInteger=1
+Value=1011111111111111
diff --git a/forms/gpgol-ms_en.cfg b/forms/gpgol-ms_en.cfg
new file mode 100644 (file)
index 0000000..329be32
--- /dev/null
@@ -0,0 +1,35 @@
+[Description]
+MessageClass=IPM.Note.GpgOL.MultipartSigned
+DesignerRuntimeGuid={0006F020-0000-0000-C000-000000000046}
+CLSID={00061033-0000-0000-C000-000000000046}
+DisplayName=Form for class IPM.Note.GpgOL.MultipartSigned
+Category=Standard
+Subcategory=Formular
+Comment=
+LargeIcon=sign-l.ico
+SmallIcon=sign-s.ico
+VersionMajor=1
+VersionMinor=0
+Locale=eng
+Hidden=1
+Owner=Public Domain
+
+[Properties]
+
+[Verbs]
+Verb1=1
+
+[Verb.1]
+DisplayName=&Open
+Code=0
+Flags=0
+Attribs=2
+
+[Extensions]
+Extensions1=1
+
+[Extension.1]
+Type=30
+NmidPropset={00020D0C-0000-0000-C000-000000000046}
+NmidInteger=1
+Value=1011111111111111
diff --git a/forms/gpgol_en.cfg b/forms/gpgol_en.cfg
new file mode 100644 (file)
index 0000000..823dca4
--- /dev/null
@@ -0,0 +1,36 @@
+[Description]
+MessageClass=IPM.Note.GpgOL
+DesignerRuntimeGuid={0006F020-0000-0000-C000-000000000046}
+CLSID={00061033-0000-0000-C000-000000000046}
+DisplayName=Form for class IPM.Note.GpgOL
+Category=Standard
+Subcategory=Formular
+Comment=
+LargeIcon=encr-l.ico
+SmallIcon=encr-s.ico
+VersionMajor=1
+VersionMinor=0
+Locale=eng
+Hidden=1
+Owner=Public Domain
+
+[Properties]
+
+[Verbs]
+Verb1=1
+
+[Verb.1]
+DisplayName=&Open
+Code=0
+Flags=0
+Attribs=2
+
+[Extensions]
+Extensions1=1
+
+[Extension.1]
+Type=30
+NmidPropset={00020D0C-0000-0000-C000-000000000046}
+NmidInteger=1
+Value=1011111111111111
+
index 8504401..9b48b5e 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GpgOL 1.0.0\n"
 "Report-Msgid-Bugs-To: bug-gpgol@g10code.com\n"
-"POT-Creation-Date: 2009-10-29 18:27+0100\n"
+"POT-Creation-Date: 2009-11-03 11:39+0100\n"
 "PO-Revision-Date: 2009-06-18 19:18+0200\n"
 "Last-Translator: Werner Koch <wk@gnupg.org>\n"
 "Language-Team: de\n"
@@ -56,8 +56,8 @@ msgstr ""
 "Die GnuPG Benutzeroberfläche \"Kleopatra\" konnte nicht gefunden oder "
 "rechtzeitig gestartet werden.  Sie sollten es noch einmal versuchen."
 
-#: src/engine.c:395 src/engine.c:405 src/main.c:689 src/main.c:695
-#: src/message.cpp:321
+#: src/engine.c:395 src/engine.c:405 src/main.c:692 src/main.c:698
+#: src/message.cpp:303
 msgid "GpgOL"
 msgstr "GpgOL"
 
@@ -215,12 +215,12 @@ msgstr "*** Anfang Notation (Signatur von: "
 msgid "*** End Notation ***\n"
 msgstr "*** Ende Notation ***\n"
 
-#: src/main.c:688
+#: src/main.c:691
 #, c-format
 msgid "Note: Using compatibility flags: %s"
 msgstr "Notiz: Diese Kompatibilitätsflags werden verwendet: %s"
 
-#: src/main.c:694
+#: src/main.c:697
 #, c-format
 msgid ""
 "Note: Writing debug logs to\n"
@@ -255,7 +255,7 @@ msgstr ""
 "[Aufgrund eines Verarbeitungsfehlers in GpgOL ist der Inhalt dieser "
 "Nachricht nicht sichtbar.]"
 
-#: src/message-events.cpp:254
+#: src/message-events.cpp:282
 msgid ""
 "Sorry, we can only encrypt plain text messages and\n"
 "no RTF messages. Please make sure that only the text\n"
@@ -266,13 +266,13 @@ msgstr ""
 "Sie sicher, daß lediglich das Text Format ausgewählt wurde.\n"
 "(In der Menüleiste: \"Format\" => \"Nur Text\")"
 
-#: src/message.cpp:193
+#: src/message.cpp:181
 msgid "[Crypto operation failed - can't show the body of the message]"
 msgstr ""
 "[Krypto-Operation ist fehlgeschlagen - Der Text der Nachricht kann nicht "
 "angezeigt werden.]"
 
-#: src/message.cpp:301
+#: src/message.cpp:283
 #, c-format
 msgid ""
 "Signature status: %s\n"
@@ -285,22 +285,22 @@ msgstr ""
 "Struktur der Nachricht :\n"
 "%s"
 
-#: src/message.cpp:309
+#: src/message.cpp:291
 msgid "GpgOL - Message Information"
 msgstr "GpgOL - Informationen zu der Nachricht"
 
-#: src/message.cpp:541
+#: src/message.cpp:523
 msgid "Signature verification of an encrypted message is not possible."
 msgstr ""
 "Die Prüfung der Signatur ist bei einer verschlüsselten Nachrichten nicht "
 "möglich."
 
-#: src/message.cpp:552
+#: src/message.cpp:534
 msgid "Signature verification of this message class is not possible."
 msgstr ""
 "Die Prüfung der Signatur ist bei dieser Nachrichtenklasse nicht möglich."
 
-#: src/message.cpp:555
+#: src/message.cpp:537
 msgid ""
 "Signature verification of this S/MIME message is not possible.  Please check "
 "that S/MIME processing has been enabled."
@@ -309,15 +309,15 @@ msgstr ""
 "Bitte überprüfen Sie in den Einstellungen, daß die Verarbeitung von S/MIME "
 "eingeschaltet ist."
 
-#: src/message.cpp:559
+#: src/message.cpp:541
 msgid "This message has no signature."
 msgstr "Diese Nachricht hat keine Signatur."
 
-#: src/message.cpp:857
+#: src/message.cpp:839
 msgid "This message is not encrypted."
 msgstr "Diese Nachricht ist nicht verschlüsselt."
 
-#: src/message.cpp:1084
+#: src/message.cpp:1066
 #, c-format
 msgid ""
 "Decryption failed\n"
@@ -326,20 +326,20 @@ msgstr ""
 "Entschlüsselungsfehler\n"
 "(%s)"
 
-#: src/message.cpp:1231
+#: src/message.cpp:1213
 msgid "No recipients to encrypt to are given"
 msgstr "Empfänger zum Verschlüsseln wurde nicht angegeben"
 
-#: src/message.cpp:1244 src/message.cpp:1271
+#: src/message.cpp:1226 src/message.cpp:1253
 msgid "Encrypting or signing an empty message is not possible."
 msgstr "Eine leere Nachricht kann nicht signiert oder verschlüsselt werden."
 
-#: src/message.cpp:1253
+#: src/message.cpp:1235
 #, c-format
 msgid "Encryption failed (%s)"
 msgstr "Verschlüsselungsfehler (%s)"
 
-#: src/message.cpp:1280
+#: src/message.cpp:1262
 #, c-format
 msgid "Signing failed (%s)"
 msgstr "Signaturerstellungsfehler (%s)"
@@ -352,44 +352,44 @@ msgstr "Dateischreibfehler"
 msgid "I/O-Error"
 msgstr "Ein-/Ausgabefehler"
 
-#: src/olflange-dlgs.cpp:44
+#: src/olflange-dlgs.cpp:43
 msgid "General"
 msgstr "Allgemein"
 
-#: src/olflange-dlgs.cpp:45
+#: src/olflange-dlgs.cpp:44
 msgid "Enable the S/MIME support"
 msgstr "S/MIME Unterstützung einschalten"
 
-#: src/olflange-dlgs.cpp:47
+#: src/olflange-dlgs.cpp:46
 msgid "Message sending"
 msgstr "Senden von Nachrichten"
 
-#: src/olflange-dlgs.cpp:48
+#: src/olflange-dlgs.cpp:47
 msgid "&Encrypt new messages by default"
 msgstr "Neue Nachrichten per Voreinstellung verschlüsseln"
 
-#: src/olflange-dlgs.cpp:49
+#: src/olflange-dlgs.cpp:48
 msgid "&Sign new messages by default"
 msgstr "Neue Nachrichten per Voreinstellung signieren"
 
-#: src/olflange-dlgs.cpp:51
+#: src/olflange-dlgs.cpp:50
 msgid "Message receiving"
 msgstr "Lesen von Nachrichten"
 
-#: src/olflange-dlgs.cpp:53
+#: src/olflange-dlgs.cpp:52
 msgid "Show HTML view if possible"
 msgstr "HTML Darstellung anzeigen wenn möglich"
 
-#: src/olflange-dlgs.cpp:54
+#: src/olflange-dlgs.cpp:53
 msgid "Present encrypted message as attachment"
 msgstr "Verschlüsselte Nachricht als Anlage anzeigen"
 
-#: src/olflange-dlgs.cpp:57
+#: src/olflange-dlgs.cpp:56
 msgid "Crypto Engine"
 msgstr "Zertifikatsserver ..."
 
 #. TRANSLATORS: See the source for the full english text.
-#: src/olflange-dlgs.cpp:257
+#: src/olflange-dlgs.cpp:256
 msgid "-#GpgOLFullHelpText#-"
 msgstr ""
 "GpgOL ist ein Plugin für Microsoft Outlook, welches es ermöglicht\n"
@@ -415,12 +415,12 @@ msgstr ""
 "Public License erhalten haben.  Falls nicht, finden Sie diese\n"
 "unter der Webadresse <http://www.gnu.org/licenses/>."
 
-#: src/olflange-dlgs.cpp:263
+#: src/olflange-dlgs.cpp:262
 #, c-format
 msgid "This is GpgOL version %s"
 msgstr "Dies ist GpgOL Version %s"
 
-#: src/olflange.cpp:447
+#: src/olflange.cpp:444
 msgid ""
 "Welcome to GpgOL 1.0\n"
 "\n"
@@ -459,7 +459,7 @@ msgstr ""
 "Konto nicht.  Wird GpgOL zusammen mit anderen Outlook Plugins benutzt, kann "
 "es möglicherweise nicht richtig arbeiten.\n"
 
-#: src/olflange.cpp:475
+#: src/olflange.cpp:472
 msgid ""
 "You have installed a new version of GpgOL.\n"
 "\n"
@@ -473,7 +473,7 @@ msgstr ""
 "die Einstellungen für Sie noch stimmen.  Sie finden die Einstellungen im "
 "Hauptmenu unter:  Extras->Optionen->GpgOL.\n"
 
-#: src/olflange.cpp:663
+#: src/olflange.cpp:672
 msgid ""
 "This version of Outlook is too old!\n"
 "\n"
index 8b6ec2c..efd910d 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: GPGol\n"
 "Report-Msgid-Bugs-To: bug-gpgol@g10code.com\n"
-"POT-Creation-Date: 2009-10-29 18:27+0100\n"
+"POT-Creation-Date: 2009-11-03 11:39+0100\n"
 "PO-Revision-Date: 2006-12-12 23:52+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -54,8 +54,8 @@ msgid ""
 "You may want to try again."
 msgstr ""
 
-#: src/engine.c:395 src/engine.c:405 src/main.c:689 src/main.c:695
-#: src/message.cpp:321
+#: src/engine.c:395 src/engine.c:405 src/main.c:692 src/main.c:698
+#: src/message.cpp:303
 msgid "GpgOL"
 msgstr ""
 
@@ -205,12 +205,12 @@ msgstr "*** Notation start (signatur av: "
 msgid "*** End Notation ***\n"
 msgstr "*** Notation slut ***\n"
 
-#: src/main.c:688
+#: src/main.c:691
 #, c-format
 msgid "Note: Using compatibility flags: %s"
 msgstr ""
 
-#: src/main.c:694
+#: src/main.c:697
 #, c-format
 msgid ""
 "Note: Writing debug logs to\n"
@@ -236,7 +236,7 @@ msgid ""
 msgstr ""
 
 # A bit unclear in the original text
-#: src/message-events.cpp:254
+#: src/message-events.cpp:282
 msgid ""
 "Sorry, we can only encrypt plain text messages and\n"
 "no RTF messages. Please make sure that only the text\n"
@@ -246,11 +246,11 @@ msgstr ""
 "och inte RTF-meddelanden. Se till att endast textformatet\n"
 "har valts i inställningarna."
 
-#: src/message.cpp:193
+#: src/message.cpp:181
 msgid "[Crypto operation failed - can't show the body of the message]"
 msgstr ""
 
-#: src/message.cpp:301
+#: src/message.cpp:283
 #, c-format
 msgid ""
 "Signature status: %s\n"
@@ -259,54 +259,54 @@ msgid ""
 "%s"
 msgstr ""
 
-#: src/message.cpp:309
+#: src/message.cpp:291
 msgid "GpgOL - Message Information"
 msgstr ""
 
-#: src/message.cpp:541
+#: src/message.cpp:523
 msgid "Signature verification of an encrypted message is not possible."
 msgstr ""
 
-#: src/message.cpp:552
+#: src/message.cpp:534
 msgid "Signature verification of this message class is not possible."
 msgstr ""
 
-#: src/message.cpp:555
+#: src/message.cpp:537
 msgid ""
 "Signature verification of this S/MIME message is not possible.  Please check "
 "that S/MIME processing has been enabled."
 msgstr ""
 
-#: src/message.cpp:559
+#: src/message.cpp:541
 #, fuzzy
 msgid "This message has no signature."
 msgstr "Dekryptera meddelandet och validera signaturen"
 
-#: src/message.cpp:857
+#: src/message.cpp:839
 msgid "This message is not encrypted."
 msgstr ""
 
-#: src/message.cpp:1084
+#: src/message.cpp:1066
 #, fuzzy, c-format
 msgid ""
 "Decryption failed\n"
 "(%s)"
 msgstr "Kryptering misslyckades"
 
-#: src/message.cpp:1231
+#: src/message.cpp:1213
 msgid "No recipients to encrypt to are given"
 msgstr ""
 
-#: src/message.cpp:1244 src/message.cpp:1271
+#: src/message.cpp:1226 src/message.cpp:1253
 msgid "Encrypting or signing an empty message is not possible."
 msgstr ""
 
-#: src/message.cpp:1253
+#: src/message.cpp:1235
 #, fuzzy, c-format
 msgid "Encryption failed (%s)"
 msgstr "Kryptering misslyckades"
 
-#: src/message.cpp:1280
+#: src/message.cpp:1262
 #, fuzzy, c-format
 msgid "Signing failed (%s)"
 msgstr "Signering misslyckades"
@@ -320,54 +320,54 @@ msgstr "Fel vid skrivning av fil"
 msgid "I/O-Error"
 msgstr "In-/Ut-fel"
 
-#: src/olflange-dlgs.cpp:44
+#: src/olflange-dlgs.cpp:43
 msgid "General"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:45
+#: src/olflange-dlgs.cpp:44
 msgid "Enable the S/MIME support"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:47
+#: src/olflange-dlgs.cpp:46
 msgid "Message sending"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:48
+#: src/olflange-dlgs.cpp:47
 #, fuzzy
 msgid "&Encrypt new messages by default"
 msgstr "Kryptera meddelandet med GPG"
 
-#: src/olflange-dlgs.cpp:49
+#: src/olflange-dlgs.cpp:48
 msgid "&Sign new messages by default"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:51
+#: src/olflange-dlgs.cpp:50
 msgid "Message receiving"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:53
+#: src/olflange-dlgs.cpp:52
 msgid "Show HTML view if possible"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:54
+#: src/olflange-dlgs.cpp:53
 msgid "Present encrypted message as attachment"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:57
+#: src/olflange-dlgs.cpp:56
 msgid "Crypto Engine"
 msgstr ""
 
 #. TRANSLATORS: See the source for the full english text.
-#: src/olflange-dlgs.cpp:257
+#: src/olflange-dlgs.cpp:256
 msgid "-#GpgOLFullHelpText#-"
 msgstr ""
 
-#: src/olflange-dlgs.cpp:263
+#: src/olflange-dlgs.cpp:262
 #, c-format
 msgid "This is GpgOL version %s"
 msgstr ""
 
-#: src/olflange.cpp:447
+#: src/olflange.cpp:444
 msgid ""
 "Welcome to GpgOL 1.0\n"
 "\n"
@@ -388,7 +388,7 @@ msgid ""
 "along with other Outlook plugins may in some cases not work.\n"
 msgstr ""
 
-#: src/olflange.cpp:475
+#: src/olflange.cpp:472
 msgid ""
 "You have installed a new version of GpgOL.\n"
 "\n"
@@ -397,7 +397,7 @@ msgid ""
 ">Options->GpgOL.\n"
 msgstr ""
 
-#: src/olflange.cpp:663
+#: src/olflange.cpp:672
 msgid ""
 "This version of Outlook is too old!\n"
 "\n"
index f6fcf29..0dc60b1 100644 (file)
@@ -1,3 +1,27 @@
+2009-11-03  Werner Koch  <wk@g10code.com>
+
+       * inspectors.cpp (deregister_inspector): Delete the buttons.
+       (set_one_button): New.
+       (set_inspector_composer_flags): Also set toolbar buttons.
+       * oomhelp.cpp (del_oom_button): New.
+
+2009-11-02  Werner Koch  <wk@g10code.com>
+
+       * mailitem.cpp, mailitem.h: New.
+
+       * inspectors.cpp (get_message_from_button): New.
+       (get_inspector_from_instid): New.
+       (proc_inspector_button_click): Implement missing commands.
+
+       * message.cpp (message_display_handler): Change to take an
+       LPMESSAGE argument.
+       * display.cpp (update_display): Replace the eecb arg by an
+       inspector object.
+       * message-events.cpp (OnReadComplete): Adjust for changes.
+
+       * oomhelp.cpp (get_oom_iunknown): New.
+       * revert.cpp (gpgol_folder_revert): Change to work without an eecb.
+
 2009-10-30  Werner Koch  <wk@g10code.com>
 
        * oomhelp.cpp (get_oom_control_bytag): Fix silly bug.
index efb023a..c881d11 100644 (file)
@@ -71,6 +71,7 @@ gpgol_SOURCES = \
        oomhelp.cpp oomhelp.h eventsink.h \
        explorers.cpp explorers.h \
        inspectors.cpp inspectors.h \
+       mailitem.cpp mailitem.h \
        cmdbarcontrols.cpp cmdbarcontrols.h \
        w32-gettext.c w32-gettext.h 
 
index 7c8e1ed..5d49edb 100644 (file)
@@ -31,6 +31,9 @@ typedef IOOMCommandBarButtonEvents *LPOOMCOMMANDBARBUTTONEVENTS;
 struct IOOMCommandBarButton;
 typedef IOOMCommandBarButton *LPOOMCOMMANDBARBUTTON;
 
+struct GpgolCommandBarButtonEvents;
+typedef GpgolCommandBarButtonEvents *LPGPGOLCOMMANDBARBUTTONEVENTS;
+
 
 EXTERN_C const IID IID_IOOMCommandBarButtonEvents;
 #undef INTERFACE
@@ -57,6 +60,7 @@ DECLARE_INTERFACE_(IOOMCommandBarButtonEvents, IDispatch)
 
 
 LPDISPATCH install_GpgolCommandBarButtonEvents_sink (LPDISPATCH button);
+void       detach_GpgolCommandBarButtonEvents_sink (LPDISPATCH sink);
 
 
 
index 0fb11ed..a5e20b9 100644 (file)
@@ -169,6 +169,7 @@ typedef struct b64_state_s b64_state_t;
 #define DBG_COMMANDS       (1<<6)
 #define DBG_MIME_PARSER    (1<<7)
 #define DBG_MIME_DATA      (1<<8)
+#define DBG_OOM            (1<<9)
 
 /* Macros to used in conditionals to enable debug output.  */
 #define debug_commands    (opt.enable_debug & DBG_COMMANDS)
index 1b8b9e3..f2dd8bc 100644 (file)
@@ -215,7 +215,7 @@ is_inspector_display (HWND hwnd)
 /* Update the display with TEXT using the message MSG.  Return 0 on
    success. */
 int
-update_display (HWND hwnd, void *exchange_cb, int is_sensitive,
+update_display (HWND hwnd, LPDISPATCH inspector, int is_sensitive,
                 bool is_html, const char *text)
 {
   HWND window;
@@ -245,28 +245,27 @@ update_display (HWND hwnd, void *exchange_cb, int is_sensitive,
         SetWindowTextA (window, text);
       return 0;
     }
-  else if (exchange_cb && !opt.compat.no_oom_write)
+  else if (inspector && !opt.compat.no_oom_write)
     {
-      LPDISPATCH obj;
       int rc;
+      LPDISPATCH item;
 
       log_debug ("%s:%s: updating display using OOM\n", SRCNAME, __func__);
       
-      obj = get_eecb_object ((LPEXCHEXTCALLBACK)exchange_cb);
-      if (!obj)
+      item = get_oom_object (inspector, "get_CurrentItem");
+      if (item)
         {
-          log_error ("%s:%s: Object not found via EECB\n", SRCNAME, __func__);
-          return -1;
+          if (is_html)
+            {
+              /* Bug in OL 2002 and 2003 - as a workaround set the body
+                 first to empty. */
+              put_oom_string (item, "Body", "");
+            }
+          rc = put_oom_string (item, is_html? "HTMLBody":"Body", text);
+          item->Release ();
         }
-
-      if (is_html)
-        {
-          /* Bug in OL 2002 and 2003 - as a workaround set the body
-             first to empty. */
-          put_oom_string (obj, "Body", "");
-        }
-      rc = put_oom_string (obj, is_html? "HTMLBody":"Body", text);
-      obj->Release ();
+      else
+        rc = -1;
       return rc;
     }
   else
index 613fec5..4b77a87 100644 (file)
@@ -25,7 +25,7 @@ int is_html_body (const char *body);
 char *add_html_line_endings (const char *body);
 
 int is_inspector_display (HWND hwnd);
-int update_display (HWND hwnd, void *exchange_cb, int is_sensitive,
+int update_display (HWND hwnd, LPDISPATCH inspector, int is_sensitive,
                     bool is_html, const char *text);
 
 int set_message_body (LPMESSAGE message, const char *string, bool is_html);
index 3fc079b..84003f2 100644 (file)
@@ -37,7 +37,6 @@
 #include "olflange.h"
 #include "message.h"
 #include "engine.h"
-#include "revert.h"
 #include "ext-commands.h"
 #include "explorers.h"
 #include "inspectors.h"
@@ -283,8 +282,7 @@ GpgolExtCommands::InstallCommands (
           if (force_encrypt)
             encrypt = true;
           
-          /* FIXME:  ove that to the inspector activation.  */
-          //set_crypto_flags (eecb, sign, encrypt);
+          set_crypto_flags (eecb, sign, encrypt);
         }
       xfree (draft_info);
     }
index 08cf80d..834b10d 100644 (file)
 #include "common.h"
 #include "oomhelp.h"
 #include "myexchext.h"
-#include "inspectors.h"
+#include "mapihelp.h"
+#include "message.h"
 #include "dialogs.h"  /* IDB_xxx */
 #include "cmdbarcontrols.h"
-
 #include "eventsink.h"
+#include "inspectors.h"
+#include "mailitem.h"
+#include "revert.h"
 
 \f
 /* Event sink for an Inspectors collection object.  */
@@ -72,7 +75,6 @@ BEGIN_EVENT_SINK(GpgolInspectorEvents, IOOMInspectorEvents)
   STDMETHOD_ (void, Close) (THIS_);
   STDMETHOD_ (void, Deactivate) (THIS_);
   bool m_first_activate_seen;
-  unsigned long m_serialno;
 EVENT_SINK_CTOR(GpgolInspectorEvents)
 {
   m_first_activate_seen = false;
@@ -109,7 +111,6 @@ END_EVENT_SINK(GpgolInspectorEvents, IID_IOOMInspectorEvents)
 struct button_list_s
 {
   struct button_list_s *next;
-  unsigned long serialno; /* of the inspector.  */
   LPDISPATCH sink;
   LPDISPATCH button;
   int instid;
@@ -126,15 +127,12 @@ struct inspector_info_s
   /* We are pretty lame and keep all inspectors in a linked list.  */
   struct inspector_info_s *next;
 
-  /* The inspector object.  */
-  LPOOMINSPECTOR inspector;
-
-  /* Our serial number for the inspector.  */
-  unsigned long serialno;
-
   /* The event sink object.  This is used by the event methods to
      locate the inspector object.  */
-  LPOOMINSPECTOREVENTS eventsink;
+  LPGPGOLINSPECTOREVENTS eventsink;
+
+  /* The inspector object.  */
+  LPOOMINSPECTOR inspector;
 
   /* A list of all the buttons.  */
   button_list_t buttons;
@@ -147,9 +145,8 @@ static inspector_info_t all_inspectors;
 static HANDLE all_inspectors_lock;
 
 
-static void add_inspector_controls (LPOOMINSPECTOR inspector, 
-                                    unsigned long serialno);
-static void update_crypto_info (LPDISPATCH button);
+static void add_inspector_controls (LPOOMINSPECTOR inspector);
+static void update_crypto_info (LPDISPATCH inspector);
 
 
 \f
@@ -197,30 +194,13 @@ unlock_all_inspectors (void)
 }
 
 
-/* Return a new serial number for an inspector.  These serial numbers
-   are used to make the button tags unique.  */
-static unsigned long
-create_inspector_serial (void)
-{
-  static long serial;
-  long n;
-
-  /* Avoid returning 0 because we use that value as Nil.  */
-  while (!(n = InterlockedIncrement (&serial)))
-    ;
-  return (unsigned long)n;
-}
-
-
 /* Add SINK and BUTTON to the list at LISTADDR.  The list takes
    ownership of SINK and BUTTON, thus the caller may not use OBJ or
-   OBJ2 after this call.  If TAG must be given without the
-   serialnumber suffix.  SERIALNO is the serialno of the correspnding
-   inspector.  */
+   OBJ2 after this call.  TAG must be given without the '#' marked
+   suffix.  */
 static void
 move_to_button_list (button_list_t *listaddr, 
-                     LPDISPATCH sink, LPDISPATCH button, 
-                     const char *tag, unsigned long serialno)
+                     LPDISPATCH sink, LPDISPATCH button, const char *tag)
 {
   button_list_t item;
   int instid;
@@ -237,28 +217,29 @@ move_to_button_list (button_list_t *listaddr,
   item->sink = sink;
   item->button = button;
   item->instid = instid;
-  item->serialno = serialno;
   strcpy (item->tag, tag);
   item->next = *listaddr;
   *listaddr = item;
 }
 
 
-/* Register the inspector object INSPECTOR along with its event SINK.  */
+/* Register the inspector object INSPECTOR with its event SINK.  */
 static void
-register_inspector (LPOOMINSPECTOR inspector, LPGPGOLINSPECTOREVENTS sink)
+register_inspector (LPGPGOLINSPECTOREVENTS sink, LPOOMINSPECTOR inspector)
 {
   inspector_info_t item;
 
+  log_debug ("%s:%s: Called (sink=%p, inspector=%p)",
+             SRCNAME, __func__, sink, inspector);
   item = (inspector_info_t)xcalloc (1, sizeof *item);
   lock_all_inspectors ();
-  inspector->AddRef ();
-  item->inspector = inspector;
-  item->serialno = sink->m_serialno = create_inspector_serial ();
 
   sink->AddRef ();
   item->eventsink = sink;
 
+  inspector->AddRef ();
+  item->inspector = inspector;
+
   item->next = all_inspectors;
   all_inspectors = item;
 
@@ -268,11 +249,13 @@ register_inspector (LPOOMINSPECTOR inspector, LPGPGOLINSPECTOREVENTS sink)
 
 /* Deregister the inspector with the event SINK.  */
 static void
-deregister_inspector (LPOOMINSPECTOREVENTS sink)
+deregister_inspector (LPGPGOLINSPECTOREVENTS sink)
 {
   inspector_info_t r, rprev;
   button_list_t ol, ol2;
 
+  log_debug ("%s:%s: Called (sink=%p)", SRCNAME, __func__, sink);
+
   if (!sink)
     return;
 
@@ -293,21 +276,28 @@ deregister_inspector (LPOOMINSPECTOREVENTS sink)
       log_error ("%s:%s: inspector not registered", SRCNAME, __func__);
       return;
     }
-  r->eventsink->Release ();
-  r->eventsink = NULL;
-  if (r->inspector)
-    r->inspector->Release ();
+
+  detach_GpgolInspectorEvents_sink (r->eventsink);
 
   for (ol = r->buttons; ol; ol = ol2)
     {
       ol2 = ol->next;
       if (ol->sink)
-        ol->sink->Release ();
+        {
+          detach_GpgolCommandBarButtonEvents_sink (ol->sink);
+          ol->sink->Release ();
+        }
       if (ol->button)
-        ol->button->Release ();
+        {
+          del_oom_button (ol->button);
+          ol->button->Release ();
+        }
       xfree (ol);
     }
 
+  r->inspector->Release ();
+  r->eventsink->Release ();
+
   xfree (r);
 }
 
@@ -333,39 +323,40 @@ get_inspector_info (LPOOMINSPECTOR inspector)
 }
 
 
-/* Return the serialno of INSPECTOR or 0 if not found.  */
-static unsigned long
-get_serialno (LPDISPATCH inspector)
+/* Return the button with TAG and assigned to INSPECTOR.  TAG must be
+   given without the suffix.  Returns NULL if not found.  */
+static LPDISPATCH
+get_button (LPDISPATCH inspector, const char *tag)
 {
-  unsigned int result = 0;
+  LPDISPATCH result = NULL;
   inspector_info_t iinfo;
+  button_list_t ol;
 
-  /* FIXME: This might not bet reliable.  We merely compare the
-     pointer and not something like an Instance Id.  We should check
-     whether this is sufficient or whether to track the inspectors
-     with different hack.  For example we could add an invisible menu
-     entry and scan for that entry to get the serial number serial
-     number of it.  A better option would be to add a custom property
-     to the inspector, but that seems not supported - we could of
-     course add it to a button then. */ 
   lock_all_inspectors ();
 
   for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next)
     if (iinfo->inspector == inspector)
       {
-        result = iinfo->serialno;
+        for (ol = iinfo->buttons; ol; ol = ol->next)
+          if (ol->tag && !strcmp (ol->tag, tag))
+            {
+              result = ol->button;
+              if (result)
+                result->AddRef ();
+              break;
+            }
         break;
       }
-
+  
   unlock_all_inspectors ();
   return result;
 }
 
 
-/* Return the button with TAG and assigned to the isnpector with
-   SERIALNO.  Return NULL if not found.  */
+/* Search through all objects and find the inspector which has a
+   button with the instance id INSTID.  Returns NULL if not found.  */
 static LPDISPATCH
-get_button (unsigned long serialno, const char *tag)
+get_inspector_from_instid (int instid)
 {
   LPDISPATCH result = NULL;
   inspector_info_t iinfo;
@@ -374,18 +365,14 @@ get_button (unsigned long serialno, const char *tag)
   lock_all_inspectors ();
 
   for (iinfo = all_inspectors; iinfo; iinfo = iinfo->next)
-    if (iinfo->serialno == serialno)
-      {
-        for (ol = iinfo->buttons; ol; ol = ol->next)
-          if (ol->tag && !strcmp (ol->tag, tag))
-            {
-              result = ol->button;
-              if (result)
-                result->AddRef ();
-              break;
-            }
-        break;
-      }
+    for (ol = iinfo->buttons; ol; ol = ol->next)
+      if (ol->instid == instid)
+        {
+          result = iinfo->inspector;
+          if (result)
+            result->AddRef ();
+          break;
+        }
   
   unlock_all_inspectors ();
   return result;
@@ -393,9 +380,8 @@ get_button (unsigned long serialno, const char *tag)
 
 
 /* Search through all objects and find the inspector which has a
-   button with the instanceId INSTID.  The find the button with TAG in
-   that inspector and return it.  Caller must release the returned
-   button.  Returns NULL if not found.  */
+   button with the instanceId INSTID.  Theb find the button with TAG
+   in that inspector and return it.  Returns NULL if not found.  */
 static LPDISPATCH
 get_button_by_instid_and_tag (int instid, const char *tag)
 {
@@ -428,8 +414,6 @@ get_button_by_instid_and_tag (int instid, const char *tag)
 }
 
 
-
-
 /* The method called by outlook for each new inspector.  Note that
    Outlook sometimes reuses Inspectro objects thus this event is not
    an indication for a newly opened Inspector.  */
@@ -437,16 +421,19 @@ STDMETHODIMP
 GpgolInspectorsEvents::NewInspector (LPOOMINSPECTOR inspector)
 {
   LPDISPATCH obj;
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+
+  log_debug ("%s:%s: Called (this=%p, inspector=%p)",
+             SRCNAME, __func__, this, inspector);
 
   /* It has been said that INSPECTOR here a "weak" reference. This may
      mean that the object has not been fully initialized.  So better
      take some care here and also take an additional reference.  */
+
   inspector->AddRef ();
   obj = install_GpgolInspectorEvents_sink ((LPDISPATCH)inspector);
   if (obj)
     {
-      register_inspector (inspector, (LPGPGOLINSPECTOREVENTS)obj);
+      register_inspector ((LPGPGOLINSPECTOREVENTS)obj, inspector);
       obj->Release ();
     }
   inspector->Release ();
@@ -458,10 +445,12 @@ GpgolInspectorsEvents::NewInspector (LPOOMINSPECTOR inspector)
 STDMETHODIMP_(void)
 GpgolInspectorEvents::Close (void)
 {
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
-  /* Deregister the inspector and free outself.  */
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this );
+
+  /* Deregister the inspector.  */
   deregister_inspector (this);
-  this->Release ();
+  /* We don't release ourself because we already dropped the initial
+     reference after doing a register_inspector.  */
 }
 
 
@@ -469,11 +458,11 @@ GpgolInspectorEvents::Close (void)
 STDMETHODIMP_(void)
 GpgolInspectorEvents::Activate (void)
 {
-  LPDISPATCH obj, button;
   LPOOMINSPECTOR inspector;
+  // LPDISPATCH obj, obj2;
 
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
-
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
+  
   /* Note: It is easier to use the registered inspector object than to
      find the inspector object in the ALL_INSPECTORS list.  The
      ALL_INSPECTORS list primarly useful to keep track of additional
@@ -484,6 +473,7 @@ GpgolInspectorEvents::Activate (void)
       return;
     }
   inspector = (LPOOMINSPECTOR)m_object;
+  inspector->AddRef ();
 
   /* If this is the first activate for the inspector, we add the
      controls.  We do it only now to be sure that everything has been
@@ -492,23 +482,19 @@ GpgolInspectorEvents::Activate (void)
   if (!m_first_activate_seen)
     {
       m_first_activate_seen = true;
-      add_inspector_controls (inspector, m_serialno);
+      add_inspector_controls (inspector);
+      // obj = get_oom_object (inspector, "get_CurrentItem");
+      // if (obj)
+      //   {
+      //     obj2 = install_GpgolItemEvents_sink (obj);
+      //     if (obj2)
+      //       obj2->Release ();
+      //     obj->Release ();
+      //   }
     }
   
-  /* Update the crypt info.  */
-  obj = get_oom_object (inspector, "CommandBars");
-  if (!obj)
-    log_error ("%s:%s: CommandBars not found", SRCNAME, __func__);
-  else
-    {
-      button = get_button (m_serialno, "GpgOL_Inspector_Crypto_Info");
-      obj->Release ();
-      if (button)
-        {
-          update_crypto_info (button);
-          button->Release ();
-        }
-    }
+  update_crypto_info (inspector);
+  inspector->Release ();
 }
 
 
@@ -516,7 +502,7 @@ GpgolInspectorEvents::Activate (void)
 STDMETHODIMP_(void)
 GpgolInspectorEvents::Deactivate (void)
 {
-  log_debug ("%s:%s: Called", SRCNAME, __func__);
+  log_debug ("%s:%s: Called (this=%p)", SRCNAME, __func__, this);
 
 }
 
@@ -551,16 +537,8 @@ get_inspector_composer_flags (LPDISPATCH inspector,
 {
   LPDISPATCH button;
   int rc = 0;
-  unsigned long serialno;
-
-  serialno = get_serialno (inspector);
-  if (!serialno)
-    {
-      log_error ("%s:%s: S/n not found", SRCNAME, __func__);
-      return -1;
-    }
 
-  button = get_button (serialno, "GpgOL_Inspector_Sign");
+  button = get_button (inspector, "GpgOL_Inspector_Sign");
   if (!button)
     {
       log_error ("%s:%s: Sign button not found", SRCNAME, __func__);
@@ -572,7 +550,7 @@ get_inspector_composer_flags (LPDISPATCH inspector,
       button->Release ();
     }
 
-  button = get_button (serialno, "GpgOL_Inspector_Encrypt");
+  button = get_button (inspector, "GpgOL_Inspector_Encrypt");
   if (!button)
     {
       log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__);
@@ -591,59 +569,59 @@ get_inspector_composer_flags (LPDISPATCH inspector,
 }
 
 
-/* Set the flags for the inspector; i.e. whether to sign or encrypt a
-   message.  Returns 0 on success.  */
-int
-set_inspector_composer_flags (LPDISPATCH inspector, bool sign, bool encrypt)
+static int
+set_one_button (LPDISPATCH inspector, const char *tag, bool down)
 {
   LPDISPATCH button;
   int rc = 0;
-  unsigned long serialno;
 
-  serialno = get_serialno (inspector);
-  if (!serialno)
-    {
-      log_error ("%s:%s: S/n not found", SRCNAME, __func__);
-      return -1;
-    }
-
-  button = get_button (serialno, "GpgOL_Inspector_Sign");
+  button = get_button (inspector, tag);
   if (!button)
     {
-      log_error ("%s:%s: Sign button not found", SRCNAME, __func__);
+      log_error ("%s:%s: `%s' not found", SRCNAME, __func__, tag);
       rc = -1;
     }
   else
     {
-      if (put_oom_int (button, "State", sign? msoButtonDown : msoButtonUp))
+      if (put_oom_int (button, "State", down? msoButtonDown : msoButtonUp))
         rc = -1;
       button->Release ();
     }
+  return rc;
+}
+
+
+
+/* Set the flags for the inspector; i.e. whether to sign or encrypt a
+   message.  Returns 0 on success.  */
+int
+set_inspector_composer_flags (LPDISPATCH inspector, bool sign, bool encrypt)
+{
+  int rc = 0;
+
+  if (set_one_button (inspector, "GpgOL_Inspector_Sign", sign))
+    rc = -1;
+  if (set_one_button (inspector, "GpgOL_Inspector_Sign@t", sign))
+    rc = -1;
+  if (set_one_button (inspector, "GpgOL_Inspector_Encrypt", encrypt))
+    rc = -1;
+  if (set_one_button (inspector, "GpgOL_Inspector_Encrypt@t", encrypt))
+    rc = -1;
 
-  button = get_button (serialno, "GpgOL_Inspector_Encrypt");
-  if (!button)
-    {
-      log_error ("%s:%s: Encrypt button not found", SRCNAME, __func__);
-      rc = -1;
-    }
-  else
-    {
-      if (put_oom_int (button, "State", encrypt? msoButtonDown : msoButtonUp))
-        rc = -1;
-      button->Release ();
-    }
-  
   return rc;
 }
 
 
 /* Helper to make the tag unique.  */
 static const char *
-add_tag (LPDISPATCH control, unsigned long serialno, const char *value)
+add_tag (LPDISPATCH control, const char *value)
 {
+  int instid;
+  
   char buf[256];
   
-  snprintf (buf, sizeof buf, "%s#%lu", value, serialno);
+  instid = get_oom_int (control, "InstanceId");
+  snprintf (buf, sizeof buf, "%s#%d", value, instid);
   put_oom_string (control, "Tag", buf);
   return value;
 }
@@ -651,7 +629,7 @@ add_tag (LPDISPATCH control, unsigned long serialno, const char *value)
 
 /* Add all the controls.  */
 static void
-add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
+add_inspector_controls (LPOOMINSPECTOR inspector)
 {
   static
   LPDISPATCH obj, controls, button;
@@ -660,7 +638,6 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
   const char *tag;
   int in_composer;
 
-
   log_debug ("%s:%s: Enter", SRCNAME, __func__);
 
   /* Check whether we are in composer or read mode.  */
@@ -678,7 +655,7 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
           button = opt.disable_gpgol? NULL : add_oom_button (controls);
           if (button)
             {
-              tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt");
+              tag = add_tag (button, "GpgOL_Inspector_Encrypt");
               put_oom_bool (button, "BeginGroup", true);
               put_oom_int (button, "Style", msoButtonIconAndCaption );
               put_oom_string (button, "Caption",
@@ -686,19 +663,19 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
               put_oom_icon (button, IDB_ENCRYPT, 16);
               
               obj = install_GpgolCommandBarButtonEvents_sink (button);
-              move_to_button_list (&buttonlist, obj, button, tag, serialno);
+              move_to_button_list (&buttonlist, obj, button, tag);
             }
           
           button = opt.disable_gpgol? NULL : add_oom_button (controls);
           if (button)
             {
-              tag = add_tag (button, serialno, "GpgOL_Inspector_Sign");
+              tag = add_tag (button, "GpgOL_Inspector_Sign");
               put_oom_int (button, "Style", msoButtonIconAndCaption );
               put_oom_string (button, "Caption", _("&sign message with GnuPG"));
               put_oom_icon (button, IDB_SIGN, 16);
               
               obj = install_GpgolCommandBarButtonEvents_sink (button);
-              move_to_button_list (&buttonlist, obj, button, tag, serialno);
+              move_to_button_list (&buttonlist, obj, button, tag);
             }
           
           controls->Release ();
@@ -716,49 +693,49 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
       button = in_composer? NULL : add_oom_button (controls);
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Verify");
+          tag = add_tag (button, "GpgOL_Inspector_Verify");
           put_oom_int (button, "Style", msoButtonIconAndCaption );
           put_oom_string (button, "Caption", _("GpgOL Decrypt/Verify"));
           put_oom_icon (button, IDB_DECRYPT_VERIFY, 16);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-0");
+          tag = add_tag (button, "GpgOL_Inspector_Debug-0");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
                           "GpgOL Debug-0 (display crypto info)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Debug-1");
+          tag = add_tag (button, "GpgOL_Inspector_Debug-1");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
-                          "GpgOL Debug-1 (open_inspector)");
+                          "GpgOL Debug-1 (not used)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       button = opt.enable_debug? add_oom_button (controls) : NULL;
       if (button)
         {
-          tag = add_tag (button, serialno,"GpgOL_Inspector_Debug-2");
+          tag = add_tag (button, "GpgOL_Inspector_Debug-2");
           put_oom_int (button, "Style", msoButtonCaption );
           put_oom_string (button, "Caption",
                           "GpgOL Debug-2 (change message class)");
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       controls->Release ();
@@ -777,38 +754,38 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
                 ? NULL : add_oom_button (controls));
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Encrypt@t");
+          tag = add_tag (button, "GpgOL_Inspector_Encrypt@t");
           put_oom_int (button, "Style", msoButtonIcon );
           put_oom_string (button, "Caption", _("Encrypt message with GnuPG"));
           put_oom_icon (button, IDB_ENCRYPT, 16);
           put_oom_int (button, "State", msoButtonMixed );
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       button = (opt.disable_gpgol || !in_composer
                 ? NULL : add_oom_button (controls));
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Sign@t");
+          tag = add_tag (button, "GpgOL_Inspector_Sign@t");
           put_oom_int (button, "Style", msoButtonIcon);
           put_oom_string (button, "Caption", _("Sign message with GnuPG"));
           put_oom_icon (button, IDB_SIGN, 16);
           put_oom_int (button, "State", msoButtonDown);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       button = in_composer? NULL : add_oom_button (controls);
       if (button)
         {
-          tag = add_tag (button, serialno, "GpgOL_Inspector_Crypto_Info");
+          tag = add_tag (button, "GpgOL_Inspector_Crypto_Info");
           put_oom_int (button, "Style", msoButtonIcon);
           
           obj = install_GpgolCommandBarButtonEvents_sink (button);
-          move_to_button_list (&buttonlist, obj, button, tag, serialno);
+          move_to_button_list (&buttonlist, obj, button, tag);
         }
 
       controls->Release ();
@@ -844,91 +821,141 @@ add_inspector_controls (LPOOMINSPECTOR inspector, unsigned long serialno)
 
 /* Update the crypto info icon.  */
 static void
-update_crypto_info (LPDISPATCH button)
+update_crypto_info (LPDISPATCH inspector)
 {
-  LPDISPATCH inspector;
-  char *msgcls = NULL;;
-  const char *s;
-  int in_composer = 0;
-  int is_encrypted = 0;
-  int is_signed = 0;
-  const char *tooltip;
-  int iconrc;
-
-  /* FIXME: We should store the information retrieved by old
-     versions via mapi_get_message_type and mapi_test_sig_status
-     in UserProperties and use them instead of a direct lookup of
-     the messageClass.  */
-
-  inspector = get_oom_object (button, "get_Parent.get_Parent.get_CurrentItem");
-  if (inspector)
+  HRESULT hr;
+  LPDISPATCH button;
+  const char *tooltip = "";
+  int iconrc = -1;
+
+  button = get_button (inspector, "GpgOL_Inspector_Crypto_Info");
+  if (!button)
     {
-      msgcls = get_oom_string (inspector, "MessageClass");
-      in_composer = is_inspector_in_composer_mode (inspector);
-      inspector->Release ();
+      log_error ("%s:%s: Crypto Info button not found", SRCNAME, __func__);
+      return;
     }
-  if (msgcls)
+
+  if (!is_inspector_in_composer_mode (inspector))
     {
-      log_debug ("%s:%s: message class is `%s'", SRCNAME, __func__, msgcls);
-      if (!strncmp (msgcls, "IPM.Note.GpgOL", 14) 
-          && (!msgcls[14] || msgcls[14] == '.'))
-        {
-          s = msgcls + 14;
-          if (!*s)
-            ;
-          else if (!strcmp (s, ".MultipartSigned"))
-            is_signed = 1;
-          else if (!strcmp (s, ".MultipartEncrypted"))
-            is_encrypted = 1;
-          else if (!strcmp (s, ".OpaqueSigned"))
-            is_signed = 1;
-          else if (!strcmp (s, ".OpaqueEncrypted"))
-            is_encrypted = 1;
-          else if (!strcmp (s, ".ClearSigned"))
-            is_signed = 1;
-          else if (!strcmp (s, ".PGPMessage"))
-            is_encrypted = 1;
-        }
-      
-      /*FIXME: check something like mail_test_sig_status to see
-        whether it is an encrypted and signed message.  */
-      
-      if (in_composer)
-        {
-          tooltip = "";
-          iconrc = -1;
-        }
-      else if (is_signed && is_encrypted)
-        {
-          tooltip =  _("This is a signed and encrypted message.\n"
-                       "Click for more information. ");
-          iconrc = IDB_DECRYPT_VERIFY;
-        }
-      else if (is_signed)
+      LPDISPATCH obj;
+      LPUNKNOWN unknown;
+      LPMESSAGE message = NULL;
+
+      obj = get_oom_object (inspector, "get_CurrentItem");
+      if (obj)
         {
-          tooltip =  _("This is a signed message.\n"
-                       "Click for more information. ");
-          iconrc = IDB_VERIFY;
+          unknown = get_oom_iunknown (obj, "MAPIOBJECT");
+          if (!unknown)
+            log_error ("%s:%s: error getting MAPI object", SRCNAME, __func__);
+          else
+            {
+              hr = unknown->QueryInterface (IID_IMessage, (void**)&message);
+              if (hr != S_OK || !message)
+                {
+                  message = NULL;
+                  log_error ("%s:%s: error getting IMESSAGE: hr=%#lx",
+                             SRCNAME, __func__, hr);
+                }
+              unknown->Release ();
+            }
+          obj->Release ();
         }
-      else if (is_encrypted)
+      if (message)
         {
-          tooltip =  _("This is an encrypted message.\n"
-                       "Click for more information. ");
-          iconrc = IDB_DECRYPT;
+          int is_encrypted = 0;
+          int is_signed = 0;
+          
+          switch (mapi_get_message_type (message))
+            {
+            case MSGTYPE_GPGOL_MULTIPART_ENCRYPTED:
+            case MSGTYPE_GPGOL_OPAQUE_ENCRYPTED:
+            case MSGTYPE_GPGOL_PGP_MESSAGE:
+              is_encrypted = 1;
+              if ( mapi_test_sig_status (message) )
+                is_signed = 1;
+              break;
+            case MSGTYPE_GPGOL:
+            case MSGTYPE_SMIME:
+            case MSGTYPE_UNKNOWN:
+              break;
+            default:
+              is_signed = 1;
+              break;
+            }
+          
+          if (is_signed && is_encrypted)
+            {
+              tooltip =  _("This is a signed and encrypted message.\n"
+                           "Click for more information. ");
+              iconrc = IDB_DECRYPT_VERIFY;
+            }
+          else if (is_signed)
+            {
+              tooltip =  _("This is a signed message.\n"
+                           "Click for more information. ");
+              iconrc = IDB_VERIFY;
+            }
+          else if (is_encrypted)
+            {
+              tooltip =  _("This is an encrypted message.\n"
+                           "Click for more information. ");
+              iconrc = IDB_DECRYPT;
+            }
+          
+          message->Release ();
         }
+    }
+
+  put_oom_string (button, "TooltipText", tooltip);
+  if (iconrc != -1)
+    put_oom_icon (button, iconrc, 16);
+  put_oom_bool (button, "Visible", (iconrc != -1));
+  button->Release ();
+}
+
+
+/* Return the MAPI message object of then inspector from a button's
+   instance id. */
+static LPMESSAGE
+get_message_from_button (unsigned long instid, LPDISPATCH *r_inspector)
+{
+  HRESULT hr;
+  LPDISPATCH inspector, obj;
+  LPUNKNOWN  unknown;
+  LPMESSAGE message = NULL;
+  
+  if (r_inspector)
+    *r_inspector = NULL;
+  inspector = get_inspector_from_instid (instid);
+  if (inspector)
+    {
+      obj = get_oom_object (inspector, "get_CurrentItem");
+      if (!obj)
+        log_error ("%s:%s: error getting CurrentItem", SRCNAME, __func__);
       else
         {
-          tooltip = "";
-          iconrc = -1;
+          unknown = get_oom_iunknown (obj, "MAPIOBJECT");
+          if (!unknown)
+            log_error ("%s:%s: error getting MAPI object", SRCNAME, __func__);
+          else
+            {
+              hr = unknown->QueryInterface (IID_IMessage, (void**)&message);
+              if (hr != S_OK || !message)
+                {
+                  message = NULL;
+                  log_error ("%s:%s: error getting IMESSAGE: hr=%#lx",
+                             SRCNAME, __func__, hr);
+                }
+              unknown->Release ();
+            }
+          obj->Release ();
         }
-      
-      put_oom_string (button, "TooltipText", tooltip);
-      if (iconrc != -1)
-        put_oom_icon (button, iconrc, 16);
-      put_oom_bool (button, "Visible", (iconrc != -1));
-      
-      xfree (msgcls);
+      if (r_inspector)
+        *r_inspector = inspector;
+      else
+        inspector->Release ();
     }
+  return message;
 }
 
 
@@ -949,7 +976,7 @@ toggle_button (LPDISPATCH button, const char *tag, int instid)
   mem2str (tag2, tag, sizeof tag2 - 2);
   p = strchr (tag2, '#');
   if (p)
-    *p = 0;  /* Strip the serialno suffix.  */
+    *p = 0;  /* Strip the instance id suffix.  */
   if (*tag2 && tag2[1] && !strcmp (tag2+strlen(tag2)-2, "@t"))
     tag2[strlen(tag2)-2] = 0; /* Remove the "@t".  */
   else
@@ -973,6 +1000,9 @@ toggle_button (LPDISPATCH button, const char *tag, int instid)
 void
 proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid)
 {
+  LPMESSAGE message;
+  HWND hwnd = NULL; /* Fixme  */
+
   if (!tagcmp (tag, "GpgOL_Inspector_Encrypt"))
     {  
       toggle_button (button, tag, instid);
@@ -981,85 +1011,65 @@ proc_inspector_button_click (LPDISPATCH button, const char *tag, int instid)
     {  
       toggle_button (button, tag, instid);
     }
-  else if (!tagcmp (tag, "GpgOL_Inspector_Verify"))
-    {
-      /* FIXME: We need to invoke decrypt/verify again. */
-    }
-  else if (!tagcmp (tag, "GpgOL_Inspector_Crypto_Info"))
+  else if (!tagcmp (tag, "GpgOL_Inspector_Verify")
+           || !tagcmp (tag, "GpgOL_Inspector_Crypto_Info"))
     {
-      /* FIXME: We should invoke the decrypt/verify again. */
-      update_crypto_info (button);
-#if 0 /* This is the code we used to use.  */
-      log_debug ("%s:%s: command CryptoState called\n", SRCNAME, __func__);
-      hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-      if (SUCCEEDED (hr))
+      LPDISPATCH inspector;
+
+      message = get_message_from_button (instid, &inspector);
+      if (message)
         {
           if (message_incoming_handler (message, hwnd, true))
-            message_display_handler (eecb, hwnd);
-       }
-      else
-        log_debug_w32 (hr, "%s:%s: command CryptoState failed", 
-                       SRCNAME, __func__);
-      ul_release (message, __func__, __LINE__);
-      ul_release (mdb, __func__, __LINE__);
-#endif
+            message_display_handler (message, inspector, hwnd);
+          message->Release ();
+        }
+      if (inspector)
+        {
+          update_crypto_info (inspector);
+          inspector->Release ();
+        }
     }
   else if (!tagcmp (tag, "GpgOL_Inspector_Debug-0"))
     {
-      /* Show crypto info.  */
       log_debug ("%s:%s: command Debug0 (showInfo) called\n",
                  SRCNAME, __func__);
-      // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-      // if (SUCCEEDED (hr))
-      //   {
-      //     message_show_info (message, hwnd);
-      //   }
-      // ul_release (message, __func__, __LINE__);
-      // ul_release (mdb, __func__, __LINE__);
+      message = get_message_from_button (instid, NULL);
+      if (message)
+        {
+          message_show_info (message, hwnd);
+          message->Release ();
+        }
     }
   else if (!tagcmp (tag, "GpgOL_Inspector_Debug-1"))
     {
-      /* Open inspector.  */
-      log_debug ("%s:%s: command Debug1 (open inspector) called\n",
+      log_debug ("%s:%s: command Debug1 (not used) called\n",
                  SRCNAME, __func__);
-      // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-      // if (SUCCEEDED (hr))
-      //   {
-      //     open_inspector (eecb, message);
-      //   }
-      // ul_release (message, __func__, __LINE__);
-      // ul_release (mdb, __func__, __LINE__);
     }
   else if (!tagcmp (tag, "GpgOL_Inspector_Debug-2"))
     {
-      /* Change message class.  */
       log_debug ("%s:%s: command Debug2 (change message class) called", 
                  SRCNAME, __func__);
-      // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-      // if (SUCCEEDED (hr))
-      //   {
-      //     /* We sync here. */
-      //     mapi_change_message_class (message, 1);
-      //   }
-      // ul_release (message, __func__, __LINE__);
-      // ul_release (mdb, __func__, __LINE__);
+      message = get_message_from_button (instid, NULL);
+      if (message)
+        {
+          /* We sync here. */
+          mapi_change_message_class (message, 1);
+          message->Release ();
+        }
     }
   else if (!tagcmp (tag, "GpgOL_Inspector_Debug-3"))
     {
       log_debug ("%s:%s: command Debug3 (revert_message_class) called", 
                  SRCNAME, __func__);
-      // hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-      // if (SUCCEEDED (hr))
-      //   {
-      //     int rc = gpgol_message_revert (message, 1, 
-      //                                    KEEP_OPEN_READWRITE|FORCE_SAVE);
-      //     log_debug ("%s:%s: gpgol_message_revert returns %d\n", 
-      //                SRCNAME, __func__, rc);
-      //   }
-      // ul_release (message, __func__, __LINE__);
-      // ul_release (mdb, __func__, __LINE__);
+      message = get_message_from_button (instid, NULL);
+      if (message)
+        {
+          int rc = gpgol_message_revert (message, 1, 
+                                         KEEP_OPEN_READWRITE|FORCE_SAVE);
+          log_debug ("%s:%s: gpgol_message_revert returns %d\n", 
+                     SRCNAME, __func__, rc);
+          message->Release ();
+        }
     }
 
-
-
 }
index 31d0331..dbb5037 100644 (file)
@@ -118,9 +118,11 @@ DECLARE_INTERFACE_(IOOMInspectorsEvents, IDispatch)
 };
 
 
+/* Create a new sink and attach it to OBJECT.  */
 LPDISPATCH install_GpgolInspectorsEvents_sink (LPDISPATCH object);
 
 LPDISPATCH install_GpgolInspectorEvents_sink (LPDISPATCH object);
+void detach_GpgolInspectorEvents_sink (LPDISPATCH sink);
 
 
 void proc_inspector_button_click (LPDISPATCH button,
index 58723ff..7ac0cae 100644 (file)
@@ -135,18 +135,33 @@ GpgolItemEvents::OnOpen (LPEXCHEXTCALLBACK eecb)
 STDMETHODIMP 
 GpgolItemEvents::OnOpenComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
 {
+  HRESULT hr;
+  
   log_debug ("%s:%s: received, flags=%#lx", SRCNAME, __func__, flags);
 
   /* If the message has been processed by us (i.e. in OnOpen), we now
      use our own display code.  */
   if (!flags && m_processed)
     {
+      LPMDB mdb = NULL;
+      LPMESSAGE message = NULL;
       HWND hwnd = NULL;
 
       if (FAILED (eecb->GetWindow (&hwnd)))
         hwnd = NULL;
-      if (message_display_handler (eecb, hwnd))
-        m_wasencrypted = true;
+      hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
+      if (hr != S_OK || !message) 
+        log_error ("%s:%s: error getting message: hr=%#lx",
+                   SRCNAME, __func__, hr);
+      else
+        {
+          if (message_display_handler (message, hwnd))
+            m_wasencrypted = true;
+        }
+      if (message)
+        message->Release ();
+      if (mdb)
+        mdb->Release ();
     }
   
   return S_FALSE;
diff --git a/src/mailitem.cpp b/src/mailitem.cpp
new file mode 100644 (file)
index 0000000..dfa5886
--- /dev/null
@@ -0,0 +1,133 @@
+/* mailitem.cpp - Code to handle the Outlook MailItem
+ *     Copyright (C) 2009 g10 Code GmbH
+ * 
+ * This file is part of GpgOL.
+ * 
+ * GpgOL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * GpgOL 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 Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <windows.h>
+#include <olectl.h>
+
+#include "common.h"
+#include "oomhelp.h"
+#include "eventsink.h"
+#include "mailitem.h"
+
+
+/* Subclass of ItemEvents so that we can hook into the events.  */
+BEGIN_EVENT_SINK(GpgolItemEvents, IOOMItemEvents)
+  STDMETHOD(Read)(THIS_ );
+  STDMETHOD(Write)(THIS_ PBOOL cancel);
+  STDMETHOD(Open)(THIS_ PBOOL cancel);
+  STDMETHOD(Close)(THIS_ PBOOL cancel);
+EVENT_SINK_DEFAULT_CTOR(GpgolItemEvents)
+EVENT_SINK_DEFAULT_DTOR(GpgolItemEvents)
+EVENT_SINK_INVOKE(GpgolItemEvents)
+{
+  HRESULT hr;
+  (void)lcid; (void)riid; (void)result; (void)exepinfo; (void)argerr;
+
+  switch (dispid)
+    {
+    case 0xf001:
+      if (!(flags & DISPATCH_METHOD))
+        goto badflags;
+      if (parms->cArgs != 0)
+        hr = DISP_E_BADPARAMCOUNT;
+      else
+        {
+          Read ();
+          hr = S_OK;
+        }
+      break;
+
+    case 0xf004:
+      if (!(flags & DISPATCH_METHOD))
+        goto badflags;
+      if (!parms) 
+        hr = DISP_E_PARAMNOTOPTIONAL;
+      else if (parms->cArgs != 1)
+        hr = DISP_E_BADPARAMCOUNT;
+      else if (parms->rgvarg[0].vt != (VT_BOOL|VT_BYREF))
+        hr = DISP_E_BADVARTYPE;
+      else
+        {
+          BOOL cancel_default = !!*parms->rgvarg[0].pboolVal;
+          switch (dispid)
+            {
+            case 0xf002: Write (&cancel_default); break;
+            case 0xf003: Open (&cancel_default); break;
+            case 0xf004: Close (&cancel_default); break;
+            }
+          *parms->rgvarg[0].pboolVal = (cancel_default 
+                                        ? VARIANT_TRUE:VARIANT_FALSE);
+          hr = S_OK;
+        }
+      break;
+
+    badflags:
+    default:
+      hr = DISP_E_MEMBERNOTFOUND;
+    }
+  return hr;
+}
+END_EVENT_SINK(GpgolItemEvents, IID_IOOMItemEvents)
+
+
+/* This is the event sink for a read event.  */
+STDMETHODIMP
+GpgolItemEvents::Read (void)
+{
+  log_debug ("%s:%s: Called", SRCNAME, __func__);
+
+  return S_OK;
+}
+
+
+/* This is the event sink for a write event.  */
+STDMETHODIMP
+GpgolItemEvents::Write (PBOOL cancel_default)
+{
+  (void)cancel_default;
+  log_debug ("%s:%s: Called", SRCNAME, __func__);
+
+  return S_OK;
+}
+
+
+/* This is the event sink for an open event.  */
+STDMETHODIMP
+GpgolItemEvents::Open (PBOOL cancel_default)
+{
+  (void)cancel_default;
+  log_debug ("%s:%s: Called", SRCNAME, __func__);
+
+  return S_OK;
+}
+
+/* This is the event sink for a close event.  */
+STDMETHODIMP
+GpgolItemEvents::Close (PBOOL cancel_default)
+{
+  (void)cancel_default;
+  log_debug ("%s:%s: Called", SRCNAME, __func__);
+
+  return S_OK;
+}
+
diff --git a/src/mailitem.h b/src/mailitem.h
new file mode 100644 (file)
index 0000000..fc13ee3
--- /dev/null
@@ -0,0 +1,98 @@
+/* mailitem.h - Defs to handle the MailItem
+ *     Copyright (C) 2009 g10 Code GmbH
+ * 
+ * This file is part of GpgOL.
+ * 
+ * GpgOL is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * GpgOL 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 Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAILITEM_H
+#define MAILITEM_H
+
+#include <commctrl.h>
+#include "oomhelp.h"
+
+DEFINE_OLEGUID(IID_IOOMItemEvents,            0x0006302B, 0, 0);
+DEFINE_OLEGUID(IID_IOOMMailItem,              0x00063034, 0, 0);
+
+
+typedef struct IOOMItemEvents IOOMItemEvents;
+typedef IOOMItemEvents *LPOOMITEMEVENTS;
+
+struct IOOMMailItem;
+typedef IOOMMailItem *LPOOMMAILITEM;
+
+
+EXTERN_C const IID IID_IOOMItemEvents;
+#undef INTERFACE
+#define INTERFACE  IOOMItemEvents
+DECLARE_INTERFACE_(IOOMItemEvents, IDispatch)
+{
+  /*** IUnknown methods ***/
+  STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * lppvObj) PURE;
+  STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+  STDMETHOD_(ULONG,Release) (THIS) PURE;
+
+  /*** IDispatch methods ***/
+  STDMETHOD(GetTypeInfoCount)(THIS_ UINT*) PURE;
+  STDMETHOD(GetTypeInfo)(THIS_ UINT, LCID, LPTYPEINFO*) PURE;
+  STDMETHOD(GetIDsOfNames)(THIS_ REFIID, LPOLESTR*, UINT, LCID, DISPID*) PURE;
+  STDMETHOD(Invoke)(THIS_ DISPID, REFIID, LCID, WORD,
+                    DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*) PURE;
+
+  /*** IOOMItemEvents methods ***/
+  /* WARNING: This is for documentation only; I have no idea about the
+     vtable layout.  However it doesn't matter because we only use it
+     via the IDispatch interface.  */
+  /* dispid=0xf001 */
+  STDMETHOD(Read)(THIS_ );
+  /* dispid=0xf002 */
+  STDMETHOD(Write)(THIS_ PBOOL cancel);
+  /* dispid=0xf003 */
+  STDMETHOD(Open)(THIS_ PBOOL cancel);
+  /* dispid=0xf004 */
+  STDMETHOD(Close)(THIS_ PBOOL cancel);
+  /* dispid=0xf005 */
+  //STDMETHOD(Send)(THIS_ PBOOL cancel);
+  /* dispid=0xf006 */
+  //STDMETHOD(CustomAction)(THIS_ LPDISPATCH action, LPDISPATCH response,
+  //                        PBOOL cancel);
+  /* dispid=0xf008 */
+  //STDMETHOD(CustomPropertyChange)(THIS_ VARIANT name);
+  /* dispid=0xf009 */
+  //STDMETHOD(PropertyChange)(THIS_ VARIANT name);
+  /* dispid=0xf00a */
+  //STDMETHOD(BeforeCheckName)(THIS_ PBOOL cancel);
+  /* dispid=0xf00b */
+  //STDMETHOD(AttachmentAdd)(THIS_ LPDISPATCH att);
+  /* dispid=0xf00c */
+  //STDMETHOD(AttachmentRead)(THIS_ LPDISPATCH att);
+  /* dispid=0xf00d */
+  //STDMETHOD(BeforeAttachmentSave)(THIS_ LPDISPATCH att, PBOOL cancel);
+  /* dispid=0xf468 */
+  //STDMETHOD(Forward)(THIS_ LPDISPATCH forward, PBOOL cancel);
+  /* dispid=0xf466 */
+  //STDMETHOD(Reply)(THIS_ LPDISPATCH response, PBOOL cancel);
+  /* dispid=0xf467 */
+  //STDMETHOD(ReplyAll)(THIS_ LPDISPATCH response, PBOOL cancel);
+  /* dispid=0xfa75 */
+  //STDMETHOD(BeforeDelete)(THIS_ LPDISPATCH item, PBOOL cancel);
+};
+
+
+LPDISPATCH install_GpgolItemEvents_sink (LPDISPATCH item);
+
+
+
+#endif /*MAILITEM_H*/
index 8960f39..ab18dc1 100644 (file)
@@ -559,6 +559,8 @@ read_options (void)
             opt.enable_debug |= DBG_MIME_PARSER;
           else if (!strcmp (p, "mime-data"))
             opt.enable_debug |= DBG_MIME_DATA;
+          else if (!strcmp (p, "oom"))
+            opt.enable_debug |= DBG_OOM;
           else
             log_debug ("invalid debug flag `%s' ignored", p);
         }
@@ -572,7 +574,7 @@ read_options (void)
     }
   xfree (val); val = NULL;
   if (opt.enable_debug)
-    log_debug ("enabled debug flags:%s%s%s%s%s%s%s%s\n",
+    log_debug ("enabled debug flags:%s%s%s%s%s%s%s%s%s\n",
                (opt.enable_debug & DBG_IOWORKER)? " ioworker":"",
                (opt.enable_debug & DBG_IOWORKER_EXTRA)? " ioworker-extra":"",
                (opt.enable_debug & DBG_FILTER)? " filter":"",
@@ -580,7 +582,8 @@ read_options (void)
                (opt.enable_debug & DBG_MEMORY)? " memory":"",
                (opt.enable_debug & DBG_COMMANDS)? " commands":"",
                (opt.enable_debug & DBG_MIME_PARSER)? " mime-parser":"",
-               (opt.enable_debug & DBG_MIME_DATA)? " mime-data":""
+               (opt.enable_debug & DBG_MIME_DATA)? " mime-data":"",
+               (opt.enable_debug & DBG_OOM)? " oom":""
                );
 
 
index 0b5b9df..eca0db3 100644 (file)
@@ -210,12 +210,28 @@ GpgolMessageEvents::OnReadComplete (LPEXCHEXTCALLBACK eecb, ULONG flags)
      use our own display code.  */
   if (!flags && m_processed && !opt.disable_gpgol)
     {
+      HRESULT hr;
+      LPMDB mdb = NULL;
+      LPMESSAGE message = NULL;
       HWND hwnd = NULL;
 
       if (FAILED (eecb->GetWindow (&hwnd)))
         hwnd = NULL;
-      log_debug ("%s:%s: (hwnd=%p)\n", SRCNAME, __func__, hwnd);
-      message_display_handler (eecb, hwnd);
+      hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
+      if (hr != S_OK || !message) 
+        log_error ("%s:%s: error getting message: hr=%#lx",
+                   SRCNAME, __func__, hr);
+      else
+        {
+          LPDISPATCH inspector = get_inspector (eecb);
+          message_display_handler (message, inspector, hwnd);
+          if (inspector)
+            inspector->Release ();
+        }
+      if (message)
+        message->Release ();
+      if (mdb)
+        mdb->Release ();
     }
   
 
index 51d64fd..38b095e 100644 (file)
@@ -146,60 +146,43 @@ message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force)
 /* Common Code used by OnReadComplete and OnOpenComplete to display a
    modified message.   Returns true if the message was encrypted.  */
 bool
-message_display_handler (LPEXCHEXTCALLBACK eecb, HWND hwnd)
+message_display_handler (LPMESSAGE message, LPDISPATCH inspector, HWND hwnd)
 {
   int err;
-  HRESULT hr;
-  LPMESSAGE message = NULL;
-  LPMDB mdb = NULL;
   int ishtml, wasprotected = false;
   char *body;
 
-  hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message);
-  if (SUCCEEDED (hr))
+  if (mapi_get_message_type (message) == MSGTYPE_GPGOL_CLEAR_SIGNED)
+    {
+      /* We used to display the clearsigned data in the processed
+         form, that is without the PGP lines and without the dash
+         escaping.  However, this poses the problem that the user does
+         not notice that he is viewing a mail which was signed using a
+         deprecated method and - far worse - it might update the
+         PR_BODY and thus all signature information will get lost.  Of
+         course we could save the body away first like we do it with
+         encrypted mails, but that is too much overhead and GpgOL will
+         always be required to show such a message, which contrdicts
+         the very reason of clearsigned messages.  */
+      log_debug ("%s:%s: skipping display update for ClearSigned\n",
+                 SRCNAME, __func__);
+    }
+  else
     {
-      if (mapi_get_message_type (message) == MSGTYPE_GPGOL_CLEAR_SIGNED)
+      err = mapi_get_gpgol_body_attachment (message, &body, NULL, 
+                                            &ishtml, &wasprotected);
+      if (!err && body)
         {
-          /* We used to display the clearsigned data in the processed
-             form, that is without the PGP lines and without the dash
-             escaping.  However, this poses the problem that the user
-             does not notice that he is viewing a mail which was
-             signed using a deprecated method and - far worse - it
-             might update the PR_BODY and thus all signature
-             information will get lost.  Of course we could save the
-             body away first like we do it with encrypted mails, but
-             that is too much overhead and GpgOL will always be
-             required to show such a message, which contrdicts the
-             very reason of clearsigned messages.  */
-          log_debug ("%s:%s: skipping display update for ClearSigned\n",
-                     SRCNAME, __func__);
+          update_display (hwnd, inspector, wasprotected, ishtml, body);
         }
       else
         {
-          err = mapi_get_gpgol_body_attachment (message, &body, NULL, 
-                                                &ishtml, &wasprotected);
-          if (!err && body)
-            {
-              /* put_outlook_property (eecb, "GpgOLStatus",            */
-              /*                       mapi_get_sig_status (message)); */
-              
-              update_display (hwnd, eecb, wasprotected, ishtml, body);
-            }
-          else
-            {
-              /* put_outlook_property (eecb, "GpgOLStatus", "?"); */
-              update_display (hwnd, NULL, 0, 0, 
-                              _("[Crypto operation failed - "
-                                "can't show the body of the message]"));
-            }
-          xfree (body);
+          update_display (hwnd, NULL, 0, 0, 
+                          _("[Crypto operation failed - "
+                            "can't show the body of the message]"));
         }
+      xfree (body);
     }
-  else
-    log_debug_w32 (hr, "%s:%s: error getting message", SRCNAME, __func__);
-
-  ul_release (message, __func__, __LINE__);
-  ul_release (mdb, __func__, __LINE__);
 
   return !!wasprotected;
 }
index 0307334..4b46139 100644 (file)
@@ -22,7 +22,8 @@
 
 
 int message_incoming_handler (LPMESSAGE message, HWND hwnd, bool force);
-bool message_display_handler (LPEXCHEXTCALLBACK eecb, HWND hwnd);
+bool message_display_handler (LPMESSAGE message, LPDISPATCH inspector, 
+                              HWND hwnd);
 void message_wipe_body_cruft (LPEXCHEXTCALLBACK eecb);
 void message_show_info (LPMESSAGE message, HWND hwnd);
 
index 6c4f7d2..b968b52 100644 (file)
@@ -105,9 +105,6 @@ DEFINE_OLEGUID(IID_IExchExtModelessCallback,  0x00020d1a, 0, 0);
 DEFINE_OLEGUID(IID_IOutlookExtCallback,       0x0006720d, 0, 0);
 DEFINE_OLEGUID(IID_IOutlookExtItemEvents,     0x0006723A, 0, 0);
 
-DEFINE_OLEGUID(IID_IOOMMailItem,              0x00063034, 0, 0);
-DEFINE_OLEGUID(IID_IOOMItemEvents,            0x0006302B, 0, 0);
-
 
 /* Type definitions. */
 
index e6be7eb..ff1bba8 100644 (file)
@@ -50,6 +50,7 @@
 #include "item-events.h"
 #include "explorers.h"
 #include "inspectors.h"
+#include "mailitem.h"
 #include "cmdbarcontrols.h"
 
 /* The GUID for this plugin.  */
@@ -727,7 +728,8 @@ install_forms (void)
   langid = PRIMARYLANGID (LANGIDFROMLCID (GetThreadLocale ()));
   switch (langid)
     {
-    case LANG_GERMAN: langsuffix = "de"; break;
+    case LANG_ENGLISH: langsuffix = "en"; break;
+    case LANG_GERMAN:  langsuffix = "de"; break;
     default: 
       log_debug ("%s:%s: No forms available for primary language %d\n",
                  SRCNAME, __func__, (int)langid);
index 683ce6c..7ee9108 100644 (file)
@@ -578,6 +578,40 @@ get_oom_string (LPDISPATCH pDisp, const char *name)
 }
 
 
+/* Get the object property NAME of the object PDISP.  Returns NULL if
+   not found or if it is not an object perty.  */
+LPUNKNOWN
+get_oom_iunknown (LPDISPATCH pDisp, const char *name)
+{
+  HRESULT hr;      
+  DISPID dispid;
+  
+  dispid = lookup_oom_dispid (pDisp, name);
+  if (dispid != DISPID_UNKNOWN)
+    {
+      DISPPARAMS dispparams = {NULL, NULL, 0, 0};
+      VARIANT rVariant;
+
+      VariantInit (&rVariant);
+      hr = pDisp->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                          DISPATCH_PROPERTYGET, &dispparams,
+                          &rVariant, NULL, NULL);
+      if (hr != S_OK)
+        log_debug ("%s:%s: Property '%s' not found: %#lx",
+                   SRCNAME, __func__, name, hr);
+      else if (rVariant.vt != VT_UNKNOWN)
+        log_debug ("%s:%s: Property `%s' is not of class IUnknown (vt=%d)",
+                   SRCNAME, __func__, name, rVariant.vt);
+      else
+        return rVariant.punkVal;
+
+      VariantClear (&rVariant);
+    }
+
+  return NULL;
+}
+
+
 /* Return the control object described by the tag property with value
    TAG. The object POBJ must support the FindControl method.  Returns
    NULL if not found.  */
@@ -677,7 +711,7 @@ add_oom_button (LPDISPATCH pObj)
                      &rVariant, NULL, NULL);
   if (hr != S_OK || rVariant.vt != VT_DISPATCH || !rVariant.pdispVal)
     {
-      log_debug ("%s:%s: Adding Control failed: %#lx - vt=%d",
+      log_error ("%s:%s: Adding Control failed: %#lx - vt=%d",
                  SRCNAME, __func__, hr, rVariant.vt);
       VariantClear (&rVariant);
       return NULL;
@@ -685,3 +719,29 @@ add_oom_button (LPDISPATCH pObj)
   return rVariant.pdispVal;
 }
 
+
+/* Add a new button to an object which supports the add method.
+   Returns the new object or NULL on error.  */
+void
+del_oom_button (LPDISPATCH pObj)
+{
+  HRESULT hr;      
+  DISPID dispid;
+  DISPPARAMS dispparams;
+  VARIANT aVariant[5];
+
+  dispid = lookup_oom_dispid (pObj, "Delete");
+
+  dispparams.rgvarg = aVariant;
+  dispparams.rgvarg[0].vt = VT_BOOL;  /* Temporary */
+  dispparams.rgvarg[0].boolVal = VARIANT_FALSE;
+  dispparams.cArgs = 1;
+  dispparams.cNamedArgs = 0;
+  hr = pObj->Invoke (dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,
+                     DISPATCH_METHOD, &dispparams,
+                     NULL, NULL, NULL);
+  if (hr != S_OK)
+    log_error ("%s:%s: Deleting Control failed: %#lx",
+               SRCNAME, __func__, hr);
+}
+
index 9b82bac..24b4e65 100644 (file)
@@ -102,6 +102,9 @@ int get_oom_int (LPDISPATCH pDisp, const char *name);
 /* Get the string property NAME of the object PDISP.  */
 char *get_oom_string (LPDISPATCH pDisp, const char *name);
 
+/* Get an IUnknown object from property NAME of PDISP.  */
+LPUNKNOWN get_oom_iunknown (LPDISPATCH pDisp, const char *name);
+
 /* Return the control object with tag property value TAG.  */
 LPDISPATCH get_oom_control_bytag (LPDISPATCH pObj, const char *tag);
 
@@ -109,6 +112,9 @@ LPDISPATCH get_oom_control_bytag (LPDISPATCH pObj, const char *tag);
    Returns the new object or NULL on error.  */
 LPDISPATCH add_oom_button (LPDISPATCH pObj);
 
+/* Delete a button.  */
+void del_oom_button (LPDISPATCH button);
+
 
 #ifdef __cplusplus
 }
index 59c6c43..e76f782 100644 (file)
 #include "mymapitags.h"
 #include "myexchext.h"
 #include "common.h"
+#include "oomhelp.h"
 #include "mapihelp.h"
 #include "message.h"
 
+
 #define TRACEPOINT() do { log_debug ("%s:%s:%d: tracepoint\n", \
                                      SRCNAME, __func__, __LINE__); \
                         } while (0)
@@ -240,55 +242,121 @@ gpgol_message_revert (LPMESSAGE message, LONG do_save, ULONG save_flags)
 EXTERN_C LONG __stdcall
 gpgol_folder_revert (LPDISPATCH mapifolderobj)
 {
-#if 0
   HRESULT hr;
-  LPMAPIFOLDER folder = NULL;
+  LPDISPATCH disp;
+  LPUNKNOWN unknown;
+  LPMDB mdb;
+  LPMAPIFOLDER folder;
   LONG proptype;
+  char *store_entryid;
+  size_t store_entryidlen;
+  LPMAPISESSION session;
   LPMAPITABLE contents;
   SizedSPropTagArray (1L, proparr_entryid) = { 1L, {PR_ENTRYID} };
   LPSRowSet rows;
   ULONG mtype;
   LPMESSAGE message;
-  
 
   log_debug ("%s:%s: Enter", SRCNAME, __func__);
   
-  hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&folder);
-  if (FAILED (hr) )
+  unknown = get_oom_iunknown (mapifolderobj, "MAPIOBJECT");
+  if (!unknown)
+    {
+      log_error ("%s:%s: error getting MAPI object", SRCNAME, __func__);
+      return -1;
+    }
+  folder = NULL;
+  hr = unknown->QueryInterface (IID_IMAPIFolder, (void**)&folder);
+  unknown->Release ();
+  if (hr != S_OK || !folder)
     {
-      log_error ("%s:%s: error getting object: hr=%#lx\n", 
+      log_error ("%s:%s: error getting IMAPIFolder: hr=%#lx",
                  SRCNAME, __func__, hr);
       return -1;
     }
+
   mapi_get_int_prop ( folder, PR_OBJECT_TYPE, &proptype);
   if (proptype != MAPI_FOLDER)
     {
-      log_error ("%s:%s: not called for a folder but an object of type %ld\n", 
+      log_error ("%s:%s: not called for a folder but an object of type %ld", 
                  SRCNAME, __func__, (long)proptype);
       ul_release (folder, __func__, __LINE__);
-      ul_release (mdb, __func__, __LINE__);
       return -1;
     }
 
+  disp = get_oom_object (mapifolderobj, "Session");
+  if (!disp)
+    {
+      log_error ("%s:%s: session object not found", SRCNAME, __func__);
+      ul_release (folder, __func__, __LINE__);
+      return -1;
+    }
+  unknown = get_oom_iunknown (disp, "MAPIOBJECT");
+  disp->Release ();
+  if (!unknown)
+    {
+      log_error ("%s:%s: error getting Session.MAPIOBJECT", SRCNAME, __func__);
+      ul_release (folder, __func__, __LINE__);
+      return -1;
+    }
+  session = NULL;
+  hr = unknown->QueryInterface (IID_IMAPISession, (void**)&session);
+  unknown->Release ();
+  if (hr != S_OK || !session)
+    {
+      log_error ("%s:%s: error getting IMAPISession: hr=%#lx",
+                 SRCNAME, __func__, hr);
+      ul_release (folder, __func__, __LINE__);
+      return -1;
+    }
+      
+  /* Open the message store.  */
+  store_entryid = mapi_get_binary_prop ((LPMESSAGE)folder, PR_STORE_ENTRYID,
+                                        &store_entryidlen);
+  if (!store_entryid)
+    {
+      log_error ("%s:%s: PR_STORE_ENTRYID missing\n",  SRCNAME, __func__);
+      session->Release ();
+      ul_release (folder, __func__, __LINE__);
+      return -1;
+    }
+  mdb = NULL;
+  hr = session->OpenMsgStore (0, store_entryidlen, (LPENTRYID)store_entryid,
+                              NULL,  MAPI_BEST_ACCESS | MDB_NO_DIALOG, 
+                              &mdb);
+  xfree (store_entryid);
+  if (FAILED (hr) || !mdb)
+    {
+      log_error ("%s:%s: OpenMsgStore failed: hr=%#lx\n", 
+                 SRCNAME, __func__, hr);
+      session->Release ();
+      ul_release (folder, __func__, __LINE__);
+      return -1;
+    }
+
+  /* Get the contents.  */
   contents = NULL;
   hr = folder->GetContentsTable ((ULONG)0, &contents);
-  if (FAILED (hr) )
+  if (FAILED (hr) || !contents)
     {
       log_error ("%s:%s: error getting contents table: hr=%#lx\n", 
                  SRCNAME, __func__, hr);
-      ul_release (folder, __func__, __LINE__);
       ul_release (mdb, __func__, __LINE__);
+      session->Release ();
+      ul_release (folder, __func__, __LINE__);
       return -1;
     }
-  
+
+
   hr = contents->SetColumns ((LPSPropTagArray)&proparr_entryid, 0);
   if (FAILED (hr) )
     {
       log_error ("%s:%s: error setting contents table column: hr=%#lx\n", 
                  SRCNAME, __func__, hr);
       contents->Release ();
-      ul_release (folder, __func__, __LINE__);
       ul_release (mdb, __func__, __LINE__);
+      session->Release ();
+      ul_release (folder, __func__, __LINE__);
       return -1;
     }
 
@@ -318,7 +386,7 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj)
           hr = mdb->OpenEntry (entrylen, entry,
                                &IID_IMessage, MAPI_BEST_ACCESS, 
                                &mtype, (IUnknown**)&message);
-          if (hr)
+          if (hr || !message)
             {
               log_debug ("%s:%s: failed to open entry of this row: hr=%#lx"
                          " - skipped\n",  SRCNAME, __func__, hr);
@@ -351,8 +419,8 @@ gpgol_folder_revert (LPDISPATCH mapifolderobj)
     }
 
   contents->Release ();
-  ul_release (folder, __func__, __LINE__);
   ul_release (mdb, __func__, __LINE__);
-#endif
+  session->Release ();
+  ul_release (folder, __func__, __LINE__);
   return 0;
 }