[Spambayes-checkins] spambayes/Outlook2000 addin.py,1.27,1.28

Mark Hammond mhammond@users.sourceforge.net
Thu Nov 7 05:05:06 2002


Update of /cvsroot/spambayes/spambayes/Outlook2000
In directory usw-pr-cvs1:/tmp/cvs-serv3431

Modified Files:
	addin.py 
Log Message:
Revamp the "delete as spam" and "recover from spam" buttons - now 2
buttons, and the visibility state changes depending on the folder.  The
"unsure" folder now has both buttons available.  Probably lighter on
Outlook too, as all we do now is toggle a Visible property on a folder
change event.


Index: addin.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/Outlook2000/addin.py,v
retrieving revision 1.27
retrieving revision 1.28
diff -C2 -d -r1.27 -r1.28
*** addin.py	4 Nov 2002 22:50:41 -0000	1.27
--- addin.py	7 Nov 2002 05:05:03 -0000	1.28
***************
*** 239,278 ****
      new_msg.Display()
  
! # The "Delete As Spam" and "Recover Spam" button
! # The event from Outlook's explorer that our folder has changed.
! class ButtonDeleteAsExplorerEvent:
!     def Init(self, but):
!         self.but = but
!     def Close(self):
!         self.but = None
!     def OnFolderSwitch(self):
!         self.but._UpdateForFolderChange()
! 
! class ButtonDeleteAsEvent:
!     def Init(self, manager, application, explorer):
!         # NOTE - keeping a reference to 'explorer' in this event
!         # appears to cause an Outlook circular reference, and outlook
!         # never terminates (it does close, but the process remains alive)
!         # This is why we needed to use WithEvents, so the event class
!         # itself doesnt keep such a reference (and we need to keep a ref
!         # to the event class so it doesn't auto-disconnect!)
          self.manager = manager
          self.application = application
!         self.explorer_events = WithEvents(explorer,
!                                            ButtonDeleteAsExplorerEvent)
!         self.set_for_as_spam = None
!         self.explorer_events.Init(self)
!         self._UpdateForFolderChange()
! 
      def Close(self):
!         self.manager = self.application = self.explorer = None
! 
!     def _UpdateForFolderChange(self):
          explorer = self.application.ActiveExplorer()
          if explorer is None:
              print "** Folder Change, but don't have an explorer"
              return
          outlook_folder = explorer.CurrentFolder
!         is_spam = False
          if outlook_folder is not None:
              mapi_folder = self.manager.message_store.GetFolder(outlook_folder)
--- 239,262 ----
      new_msg.Display()
  
! # Events from our Explorer instance - currently used to enable/disable
! # controls
! class ExplorerEvent:
!     def Init(self, manager, application, but_delete_as, but_recover_as):
          self.manager = manager
          self.application = application
!         self.but_delete_as = but_delete_as
!         self.but_recover_as = but_recover_as
      def Close(self):
!         self.but_delete_as = self.but_recover_as = None
!     def OnFolderSwitch(self):
!         # Work out what folder we are in.
          explorer = self.application.ActiveExplorer()
          if explorer is None:
              print "** Folder Change, but don't have an explorer"
              return
+ 
          outlook_folder = explorer.CurrentFolder
!         show_delete_as = True
!         show_recover_as = False
          if outlook_folder is not None:
              mapi_folder = self.manager.message_store.GetFolder(outlook_folder)
***************
*** 281,314 ****
                  look_folder = self.manager.message_store.GetFolder(look_id)
                  if mapi_folder == look_folder:
!                     is_spam = True
!             if not is_spam:
!                 look_id = self.manager.config.filter.unsure_folder_id
!                 if look_id:
!                     look_folder = self.manager.message_store.GetFolder(look_id)
!                     if mapi_folder == look_folder:
!                         is_spam = True
!         if is_spam:
!             set_for_as_spam = False
!         else:
!             set_for_as_spam = True
!         if set_for_as_spam != self.set_for_as_spam:
!             if set_for_as_spam:
!                 image = "delete_as_spam.bmp"
!                 self.Caption = "Delete As Spam"
!                 self.TooltipText = \
                          "Move the selected message to the Spam folder,\n" \
                          "and train the system that this is Spam."
              else:
!                 image = "recover_ham.bmp"
!                 self.Caption = "Recover from Spam"
!                 self.TooltipText = \
!                         "Recovers the selected item back to the folder\n" \
!                         "it was filtered from (or to the Inbox if this\n" \
!                         "folder is not known), and trains the system that\n" \
!                         "this is a good message\n"
!             # Set the image.
!             print "Setting image to", image
!             SetButtonImage(self, image)
!             self.set_for_as_spam = set_for_as_spam
  
      def OnClick(self, button, cancel):
--- 265,341 ----
                  look_folder = self.manager.message_store.GetFolder(look_id)
                  if mapi_folder == look_folder:
!                     # This is the Spam folder - only show "recover"
!                     show_recover_as = True
!                     show_delete_as = False
!             # Check if uncertain
!             look_id = self.manager.config.filter.unsure_folder_id
!             if look_id:
!                 look_folder = self.manager.message_store.GetFolder(look_id)
!                 if mapi_folder == look_folder:
!                     show_recover_as = True
!                     show_delete_as = True
!         self.but_recover_as.Visible = show_recover_as
!         self.but_delete_as.Visible = show_delete_as
! 
! # The "Delete As Spam" and "Recover Spam" button
! # The event from Outlook's explorer that our folder has changed.
! class ButtonDeleteAsEventBase:
!     def Init(self, manager, application):
!         # NOTE - keeping a reference to 'explorer' in this event
!         # appears to cause an Outlook circular reference, and outlook
!         # never terminates (it does close, but the process remains alive)
!         # This is why we needed to use WithEvents, so the event class
!         # itself doesnt keep such a reference (and we need to keep a ref
!         # to the event class so it doesn't auto-disconnect!)
!         self.manager = manager
!         self.application = application
! 
!     def Close(self):
!         self.manager = self.application = None
! 
! class ButtonDeleteAsSpamEvent(ButtonDeleteAsEventBase):
!     def Init(self, manager, application):
!         ButtonDeleteAsEventBase.Init(self, manager, application)
!         image = "delete_as_spam.bmp"
!         self.Caption = "Delete As Spam"
!         self.TooltipText = \
                          "Move the selected message to the Spam folder,\n" \
                          "and train the system that this is Spam."
+         SetButtonImage(self, image)
+ 
+     def OnClick(self, button, cancel):
+         msgstore = self.manager.message_store
+         msgstore_messages = self.manager.addin.GetSelectedMessages(True)
+         if not msgstore_messages:
+             return
+         # Delete this item as spam.
+         spam_folder_id = self.manager.config.filter.spam_folder_id
+         spam_folder = msgstore.GetFolder(spam_folder_id)
+         if not spam_folder:
+             win32ui.MessageBox("You must configure the Spam folder",
+                                "Invalid Configuration")
+             return
+         import train
+         for msgstore_message in msgstore_messages:
+             # Must train before moving, else we lose the message!
+             print "Training on message - ",
+             if train.train_message(msgstore_message, True, self.manager, rescore = True):
+                 print "trained as spam"
              else:
!                 print "already was trained as spam"
!             # Now move it.
!             msgstore_message.MoveTo(spam_folder)
! 
! class ButtonRecoverFromSpamEvent(ButtonDeleteAsEventBase):
!     def Init(self, manager, application):
!         ButtonDeleteAsEventBase.Init(self, manager, application)
!         image = "recover_ham.bmp"
!         self.Caption = "Recover from Spam"
!         self.TooltipText = \
!                 "Recovers the selected item back to the folder\n" \
!                 "it was filtered from (or to the Inbox if this\n" \
!                 "folder is not known), and trains the system that\n" \
!                 "this is a good message\n"
!         SetButtonImage(self, image)
  
      def OnClick(self, button, cancel):
***************
*** 317,340 ****
          if not msgstore_messages:
              return
!         if self.set_for_as_spam:
!             # Delete this item as spam.
!             spam_folder_id = self.manager.config.filter.spam_folder_id
!             spam_folder = msgstore.GetFolder(spam_folder_id)
!             if not spam_folder:
!                 win32ui.MessageBox("You must configure the Spam folder",
!                                    "Invalid Configuration")
!                 return
!             import train
!             for msgstore_message in msgstore_messages:
!                 # Must train before moving, else we lose the message!
!                 print "Training on message - ",
!                 if train.train_message(msgstore_message, True, self.manager, rescore = True):
!                     print "trained as spam"
!                 else:
!                     print "already was trained as spam"
!                 # Now move it.
!                 msgstore_message.MoveTo(spam_folder)
!         else:
!             win32ui.MessageBox("Please be patient <wink>")
  
  # Helpers to work with images on buttons/toolbars.
--- 344,364 ----
          if not msgstore_messages:
              return
!         # Recover to where they were moved from
!         # Get the inbox as the default place to restore to
!         # (incase we dont know (early code) or folder removed etc
!         inbox_folder = msgstore.GetFolder(
!                     self.application.Session.GetDefaultFolder(
!                         constants.olFolderInbox))
!         import train
!         for msgstore_message in msgstore_messages:
!             # Must train before moving, else we lose the message!
!             print "Training on message - ",
!             if train.train_message(msgstore_message, False, self.manager, rescore = True):
!                 print "trained as ham"
!             else:
!                 print "already was trained as ham"
!             # Now move it.
!             # XXX - still don't write the source, so no point looking :(
!             msgstore_message.MoveTo(inbox_folder)
  
  # Helpers to work with images on buttons/toolbars.
***************
*** 379,382 ****
--- 403,407 ----
          assert self.manager.addin is None, "Should not already have an addin"
          self.manager.addin = self
+         self.explorer_events = None
  
          # ActiveExplorer may be none when started without a UI (eg, WinCE synchronisation)
***************
*** 385,414 ****
              bars = activeExplorer.CommandBars
              toolbar = bars.Item("Standard")
!             # Add our "Delete as ..." button
!             button = toolbar.Controls.Add(Type=constants.msoControlButton, Temporary=True)
              # Hook events for the item
              button.BeginGroup = True
!             button = DispatchWithEvents(button, ButtonDeleteAsEvent)
!             button.Init(self.manager, application, activeExplorer)
              self.buttons.append(button)
  
              # Add a pop-up menu to the toolbar
!             popup = toolbar.Controls.Add(Type=constants.msoControlPopup, Temporary=True)
              popup.Caption="Anti-Spam"
              popup.TooltipText = "Anti-Spam filters and functions"
              popup.Enabled = True
!             # Convert from "CommandBarItem" to derived "CommandBarPopup"
!             # Not sure if we should be able to work this out ourselves, but no
!             # introspection I tried seemed to indicate we can.  VB does it via
!             # strongly-typed declarations.
              popup = CastTo(popup, "CommandBarPopup")
              # And add our children.
-             self._AddPopup(popup, ShowClues, (self.manager, application),
-                            Caption="Show spam clues for current message",
-                            Enabled=True)
              self._AddPopup(popup, manager.ShowManager, (self.manager,),
                             Caption="Anti-Spam Manager...",
                             TooltipText = "Show the Anti-Spam manager dialog.",
                             Enabled = True)
  
          self.FiltersChanged()
--- 410,460 ----
              bars = activeExplorer.CommandBars
              toolbar = bars.Item("Standard")
!             # Add our "Delete as ..." and "Recover as" buttons
!             but_delete_as = button = toolbar.Controls.Add(
!                                     Type=constants.msoControlButton,
!                                     Temporary=True)
              # Hook events for the item
              button.BeginGroup = True
!             button = DispatchWithEvents(button, ButtonDeleteAsSpamEvent)
!             button.Init(self.manager, application)
              self.buttons.append(button)
+             # And again for "Recover as"
+             but_recover_as = button = toolbar.Controls.Add(
+                                     Type=constants.msoControlButton,
+                                     Temporary=True)
+             button = DispatchWithEvents(button, ButtonRecoverFromSpamEvent)
+             self.buttons.append(button)
+             # Hook our explorer events, and pass the buttons.
+             button.Init(self.manager, application)
+ 
+             self.explorer_events = WithEvents(activeExplorer,
+                                                ExplorerEvent)
  
+             self.explorer_events.Init(self.manager, application, but_delete_as, but_recover_as)
+             # And prime the event handler.
+             self.explorer_events.OnFolderSwitch()
+ 
+             # The main tool-bar dropdown with all out entries.
              # Add a pop-up menu to the toolbar
!             popup = toolbar.Controls.Add(
!                                 Type=constants.msoControlPopup,
!                                 Temporary=True)
              popup.Caption="Anti-Spam"
              popup.TooltipText = "Anti-Spam filters and functions"
              popup.Enabled = True
!             # Convert from "CommandBarItem" to derived
!             # "CommandBarPopup" Not sure if we should be able to work
!             # this out ourselves, but no introspection I tried seemed
!             # to indicate we can.  VB does it via strongly-typed
!             # declarations.
              popup = CastTo(popup, "CommandBarPopup")
              # And add our children.
              self._AddPopup(popup, manager.ShowManager, (self.manager,),
                             Caption="Anti-Spam Manager...",
                             TooltipText = "Show the Anti-Spam manager dialog.",
                             Enabled = True)
+             self._AddPopup(popup, ShowClues, (self.manager, application),
+                            Caption="Show spam clues for current message",
+                            Enabled=True)
  
          self.FiltersChanged()
***************
*** 499,506 ****
--- 545,556 ----
              self.manager.Close()
              self.manager = None
+ 
+         if self.explorer_events is not None:
+             self.explorer_events = None
          if self.buttons:
              for button in self.buttons:
                  button.Close()
              self.buttons = None
+ 
          print "Addin terminating: %d COM client and %d COM servers exist." \
                % (pythoncom._GetInterfaceCount(), pythoncom._GetGatewayCount())
***************
*** 514,522 ****
  
      def OnAddInsUpdate(self, custom):
!         print "SpamAddin - OnAddInsUpdate", custom
      def OnStartupComplete(self, custom):
!         print "SpamAddin - OnStartupComplete", custom
      def OnBeginShutdown(self, custom):
!         print "SpamAddin - OnBeginShutdown", custom
  
  def RegisterAddin(klass):
--- 564,572 ----
  
      def OnAddInsUpdate(self, custom):
!         pass
      def OnStartupComplete(self, custom):
!         pass
      def OnBeginShutdown(self, custom):
!         pass
  
  def RegisterAddin(klass):