Archive of RubyForge sup-devel mailing list
 help / color / mirror / Atom feed
From: Damien Leone <damien.leone@fensalir.fr>
To: sup-devel <sup-devel@rubyforge.org>
Subject: [sup-devel] [PATCHES] Add an account selector in edit-mode
Date: Sun, 13 Mar 2011 17:13:05 +0100	[thread overview]
Message-ID: <1300032642-sup-9716@mailer> (raw)

[-- Attachment #1: Type: text/plain, Size: 159 bytes --]

Sup guys,

Please see commit messages for detailed informations.

-- 
Damien Leone <damien.leone@fensalir.fr>

Web: http://dleone.fensalir.fr/
GPG: 0x82EB4DDF

[-- Attachment #2: 0001-reply-mode-improve-the-way-headers-are-handled.patch --]
[-- Type: application/octet-stream, Size: 5389 bytes --]

From d30d6136ebe14657a9b4530d80eb9e24ce9555ab Mon Sep 17 00:00:00 2001
From: Damien Leone <damien.leone@fensalir.fr>
Date: Wed, 9 Jun 2010 12:38:52 +0200
Subject: [PATCH 1/3] reply-mode: improve the way headers are handled

I noticed that changing the Reply-to selector was also changing the
other headers such as From even if you edited it. I guess it is an
unwanted behaviour since this selector should only behave on the To
and Cc fields.

This commit splits the headers in two "types", those handled by
Reply-To selector and those that are only merged with the first ones
at initialization of the edit-mode.

It also gives a better support of the Customized choice by saving back
the fields for later use.
---
 lib/sup/modes/reply-mode.rb |   60 ++++++++++++++++++++++--------------------
 1 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/lib/sup/modes/reply-mode.rb b/lib/sup/modes/reply-mode.rb
index ccdf371..d7d914f 100644
--- a/lib/sup/modes/reply-mode.rb
+++ b/lib/sup/modes/reply-mode.rb
@@ -48,6 +48,7 @@ EOS
     ## the full headers (most importantly the list-post header, if
     ## any)
     body = reply_body_lines message
+    @body_orig = body
 
     ## first, determine the address at which we received this email. this will
     ## become our From: address in the reply.
@@ -97,14 +98,21 @@ EOS
     @headers = {}
     @headers[:recipient] = {
       "To" => cc.map { |p| p.full_address },
+      "Cc" => [],
     } if useful_recipient
 
     ## typically we don't want to have a reply-to-sender option if the sender
     ## is a user account. however, if the cc is empty, it's a message to
     ## ourselves, so for the lack of any other options, we'll add it.
-    @headers[:sender] = { "To" => [to.full_address], } if !AccountManager.is_account?(to) || !useful_recipient
+    @headers[:sender] = {
+      "To" => [to.full_address],
+      "Cc" => [],
+    } if !AccountManager.is_account?(to) || !useful_recipient
 
-    @headers[:user] = {}
+    @headers[:user] = {
+      "To" => [],
+      "Cc" => [],
+    }
 
     not_me_ccs = cc.select { |p| !AccountManager.is_account?(p) }
     @headers[:all] = {
@@ -114,22 +122,11 @@ EOS
 
     @headers[:list] = {
       "To" => [@m.list_address.full_address],
+      "Cc" => [],
     } if @m.is_list_message?
 
     refs = gen_references
 
-    @headers.each do |k, v|
-      @headers[k] = {
-               "From" => from.full_address,
-               "To" => [],
-               "Cc" => [],
-               "Bcc" => [],
-               "In-reply-to" => "<#{@m.id}>",
-               "Subject" => Message.reify_subj(@m.subj),
-               "References" => refs,
-             }.merge v
-    end
-
     types = REPLY_TYPES.select { |t| @headers.member?(t) }
     @type_selector = HorizontalSelector.new "Reply to:", types, types.map { |x| TYPE_DESCRIPTIONS[x] }
 
@@ -148,13 +145,17 @@ EOS
         :recipient
       end)
 
-    @bodies = {}
-    @headers.each do |k, v|
-      @bodies[k] = body
-      HookManager.run "before-edit", :header => v, :body => @bodies[k]
-    end
+    headers_full = {
+      "From" => from.full_address,
+      "Bcc" => [],
+      "In-reply-to" => "<#{@m.id}>",
+      "Subject" => Message.reify_subj(@m.subj),
+      "References" => refs,
+    }.merge @headers[@type_selector.val]
+
+    HookManager.run "before-edit", :header => headers_full, :body => body
 
-    super :header => @headers[@type_selector.val], :body => @bodies[@type_selector.val], :twiddles => false
+    super :header => headers_full, :body => body, :twiddles => false
     add_selector @type_selector
   end
 
@@ -163,8 +164,7 @@ protected
   def move_cursor_right
     super
     if @headers[@type_selector.val] != self.header
-      self.header = @headers[@type_selector.val]
-      self.body = @bodies[@type_selector.val] unless @edited
+      self.header = self.header.merge @headers[@type_selector.val]
       rerun_crypto_selector_hook
       update
     end
@@ -173,8 +173,7 @@ protected
   def move_cursor_left
     super
     if @headers[@type_selector.val] != self.header
-      self.header = @headers[@type_selector.val]
-      self.body = @bodies[@type_selector.val] unless @edited
+      self.header = self.header.merge @headers[@type_selector.val]
       rerun_crypto_selector_hook
       update
     end
@@ -192,14 +191,15 @@ protected
   end
 
   def handle_new_text new_header, new_body
-    if new_body != @bodies[@type_selector.val]
-      @bodies[@type_selector.val] = new_body
+    if new_body != @body_orig
+      @body_orig = new_body
       @edited = true
     end
     old_header = @headers[@type_selector.val]
-    if new_header.size != old_header.size || old_header.any? { |k, v| new_header[k] != v }
+    if old_header.any? { |k, v| new_header[k] != v }
       @type_selector.set_to :user
-      self.header = @headers[:user] = new_header
+      self.header["To"] = @headers[:user]["To"] = new_header["To"]
+      self.header["Cc"] = @headers[:user]["Cc"] = new_header["Cc"]
       update
     end
   end
@@ -210,8 +210,10 @@ protected
 
   def edit_field field
     edited_field = super
-    if edited_field && edited_field != "Subject"
+    if edited_field and (field == "To" or field == "Cc")
       @type_selector.set_to :user
+      @headers[:user]["To"] = self.header["To"]
+      @headers[:user]["Cc"] = self.header["Cc"]
       update
     end
   end
-- 
1.7.2.3


[-- Attachment #3: 0002-edit-message-mode-Add-an-optional-account-selector.patch --]
[-- Type: application/octet-stream, Size: 4018 bytes --]

From 401b9e43b049e9d8c54b6ebbd73305fa7a9d99c5 Mon Sep 17 00:00:00 2001
From: Damien Leone <damien.leone@fensalir.fr>
Date: Sun, 27 Feb 2011 19:05:35 +0100
Subject: [PATCH 2/3] edit-message-mode: Add an optional account selector

Set to true by default, it allows you to change your account in
edit-mode using a horizontal selector. It doesn't change any of the
previous behaviour since the proper account is selected by default, it
also handles customized choice in case the user edited the From field
manually.
---
 lib/sup.rb                         |    1 +
 lib/sup/modes/edit-message-mode.rb |   42 ++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 0 deletions(-)

diff --git a/lib/sup.rb b/lib/sup.rb
index 67e834e..41709f1 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -297,6 +297,7 @@ EOS
         :ask_for_cc => true,
         :ask_for_bcc => false,
         :ask_for_subject => true,
+        :account_selector => true,
         :confirm_no_attachments => true,
         :confirm_top_posting => true,
         :jump_to_open_message => true,
diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
index a374197..8e0e9c3 100644
--- a/lib/sup/modes/edit-message-mode.rb
+++ b/lib/sup/modes/edit-message-mode.rb
@@ -116,6 +116,27 @@ EOS
     @selector_label_width = 0
     @async_mode = nil
 
+    if $config[:account_selector]
+      ## Duplicate e-mail strings to prevent a "can't modify frozen
+      ## object" crash triggered by the String::display_length()
+      ## method in util.rb
+      user_emails_copy = []
+      AccountManager.user_emails.each { |e| user_emails_copy.push e.dup }
+
+      @account_selector =
+        HorizontalSelector.new "Account:", AccountManager.user_accounts + [nil], user_emails_copy + ["Customized"]
+
+      if @header["From"] =~ /<?(\S+@(\S+?))>?$/
+        @account_selector.set_to AccountManager.account_for($1)
+        @account_user = ""
+      else
+        @account_selector.set_to nil
+        @account_user = @header["From"]
+      end
+
+      add_selector @account_selector
+    end
+
     @crypto_selector =
       if CryptoManager.have_crypto?
         HorizontalSelector.new "Crypto:", [:none] + CryptoManager::OUTGOING_MESSAGE_OPERATIONS.keys, ["None"] + CryptoManager::OUTGOING_MESSAGE_OPERATIONS.values
@@ -164,6 +185,8 @@ EOS
   def edit_subject; edit_field "Subject" end
 
   def edit_message
+    old_from = @header["From"] if @account_selector
+
     @file = Tempfile.new "sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}"
     @file.puts format_headers(@header - NON_EDITABLE_HEADERS).first
     @file.puts
@@ -180,6 +203,12 @@ EOS
 
     header, @body = parse_file @file.path
     @header = header - NON_EDITABLE_HEADERS
+
+    if @account_selector and @header["From"] != old_from
+      @account_user = @header["From"]
+      @account_selector.set_to nil
+    end
+
     handle_new_text @header, @body
     rerun_crypto_selector_hook
     update
@@ -295,6 +324,7 @@ protected
     if curpos < @selectors.length
       @selectors[curpos].roll_left
       buffer.mark_dirty
+      update if @account_selector
     else
       col_left
     end
@@ -304,6 +334,7 @@ protected
     if curpos < @selectors.length
       @selectors[curpos].roll_right
       buffer.mark_dirty
+      update if @account_selector
     else
       col_right
     end
@@ -315,6 +346,11 @@ protected
   end
 
   def update
+    if @account_selector
+      account = @account_selector.val
+      @header["From"] = account && account.full_address || @account_user
+    end
+
     regen_text
     buffer.mark_dirty if buffer
   end
@@ -532,6 +568,12 @@ protected
       if contacts
         text = contacts.map { |s| s.full_address }.join(", ")
         @header[field] = parse_header field, text
+
+        if @account_selector and field == "From"
+          @account_user = @header["From"]
+          @account_selector.set_to nil
+        end
+
         rerun_crypto_selector_hook
         update
       end
-- 
1.7.2.3


[-- Attachment #4: 0003-edit-message-mode-Fix-the-way-signatures-are-handled.patch --]
[-- Type: application/octet-stream, Size: 3266 bytes --]

From fa0af2b2f2792a535d46b608ebef6beb009bb1ca Mon Sep 17 00:00:00 2001
From: Damien Leone <damien.leone@fensalir.fr>
Date: Sun, 27 Feb 2011 19:07:53 +0100
Subject: [PATCH 3/3] edit-message-mode: Fix the way signatures are handled

The current signatures handling is not suitable for account changing
in edit-message-mode. It is working fine when the edit_signature
option is false, but it could have a better behavior when this option
is enabled.

This commit tries to do this by appending the signature to the body
text if the edit_signature is true, then after editing the message it
checks if the signature has been modified by comparing the end of the
file to the current account's signature. If it has been edited then we
stick to it by setting @sig_edited to true, otherwise the signature
will still be automatically changed if another account is selected.
---
 lib/sup/modes/edit-message-mode.rb |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
index 8e0e9c3..9341d82 100644
--- a/lib/sup/modes/edit-message-mode.rb
+++ b/lib/sup/modes/edit-message-mode.rb
@@ -93,7 +93,7 @@ EOS
     @header_lines = []
 
     @body = opts.delete(:body) || []
-    @body += sig_lines if $config[:edit_signature] && !opts.delete(:have_signature)
+    @sig_edited = false
 
     if opts[:attachments]
       @attachments = opts[:attachments].values
@@ -185,12 +185,14 @@ EOS
   def edit_subject; edit_field "Subject" end
 
   def edit_message
+    sig = sig_lines.join("\n")
     old_from = @header["From"] if @account_selector
 
     @file = Tempfile.new "sup.#{self.class.name.gsub(/.*::/, '').camel_to_hyphy}"
     @file.puts format_headers(@header - NON_EDITABLE_HEADERS).first
     @file.puts
     @file.puts @body.join("\n")
+    @file.puts sig if ($config[:edit_signature] and !@sig_edited)
     @file.close
 
     editor = $config[:editor] || ENV['EDITOR'] || "/usr/bin/vi"
@@ -204,6 +206,19 @@ EOS
     header, @body = parse_file @file.path
     @header = header - NON_EDITABLE_HEADERS
 
+    if $config[:edit_signature]
+      pbody = @body.join("\n")
+      blen = pbody.length
+      slen = sig.length
+
+      if blen > slen and pbody[blen-slen..blen] == sig
+        @sig_edited = false
+        @body = pbody[0..blen-slen].split("\n")
+      else
+        @sig_edited = true
+      end
+    end
+
     if @account_selector and @header["From"] != old_from
       @account_user = @header["From"]
       @account_selector.set_to nil
@@ -358,7 +373,7 @@ protected
   def regen_text
     header, @header_lines = format_headers(@header - NON_EDITABLE_HEADERS) + [""]
     @text = header + [""] + @body
-    @text += sig_lines unless $config[:edit_signature]
+    @text += sig_lines unless @sig_edited
 
     @attachment_lines_offset = 0
 
@@ -473,7 +488,7 @@ protected
     m = RMail::Message.new
     m.header["Content-Type"] = "text/plain; charset=#{$encoding}"
     m.body = @body.join("\n")
-    m.body += sig_lines.join("\n") unless $config[:edit_signature]
+    m.body += "\n" + sig_lines.join("\n") unless @sig_edited
     ## body must end in a newline or GPG signatures will be WRONG!
     m.body += "\n" unless m.body =~ /\n\Z/
 
-- 
1.7.2.3


[-- Attachment #5: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Sup-devel mailing list
Sup-devel@rubyforge.org
http://rubyforge.org/mailman/listinfo/sup-devel

             reply	other threads:[~2011-03-13 17:38 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-13 16:13 Damien Leone [this message]
2011-03-13 20:21 ` Sascha Silbe
2011-05-30 17:23 ` Hamish
2011-06-19 21:48   ` Hamish
2011-06-20  8:08     ` Damien Leone
2011-06-20 13:47     ` Sascha Silbe
2011-06-20 21:38       ` Hamish Downer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1300032642-sup-9716@mailer \
    --to=damien.leone@fensalir.fr \
    --cc=sup-devel@rubyforge.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox