<div dir="ltr">Hi Patrick,<br><div><div class="gmail_extra"><br><div class="gmail_quote">2017-11-10 16:40 GMT+01:00  <span dir="ltr"><<a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Patrick Rein uploaded a new version of Network to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Network-pre.207.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/<wbr>trunk/Network-pre.207.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Network-pre.207<br>
Author: pre<br>
Time: 10 November 2017, 4:40:14.388812 pm<br>
UUID: 85f492c1-3470-bb43-afe5-<wbr>bea036995824<br>
Ancestors: Network-pre.206<br>
<br>
A new MailComposition window allowing a more structured access to the underlying mail message.<br>
<br>
=============== Diff against Network-pre.206 ===============<br>
<br>
Item was changed:<br>
  Model subclass: #MailComposition<br>
+       instanceVariableNames: 'mailMessage'<br>
-       instanceVariableNames: 'messageText textEditor morphicWindow mvcWindow'<br></blockquote><div><br></div><div>It seems that the methods using this instance variables have not been removed.</div><div>See Undeclared.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
        classVariableNames: ''<br>
        poolDictionaries: ''<br>
        category: 'Network-MailSending'!<br>
<br>
+ !MailComposition commentStamp: 'pre 5/16/2017 20:00' prior: 0!<br>
+ a message being composed in a fancy way. The mail is send via the registered MailSender by default. Fields do not have to be saved, they are saved automatically on send. !<br>
- !MailComposition commentStamp: '<historical>' prior: 0!<br>
- a message being composed.  When finished, it will be submitted via a Celeste.!<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition class>>initialize (in category 'class initialization') -----<br>
- ----- Method: MailComposition class>>initialize (in category 'instance creation') -----<br>
  initialize<br>
+<br>
+       MailSender register: self !<br>
-       super initialize.<br></blockquote><div><br></div><div>Even if super initialize does not do anything, it does not hurt to leave it as is IMO.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
-       MailSender register: self.!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition class>>open (in category 'opening') -----<br>
+ open<br>
+<br>
+       ^ ToolBuilder default open: self!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition class>>openOn: (in category 'opening') -----<br>
+ openOn: aMessage<br>
+<br>
+       ^ ToolBuilder default open: (self new on: aMessage; yourself)!<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition class>>sendMailMessage: (in category 'MailSender interface') -----<br>
+ sendMailMessage: aMessage<br>
+<br>
+       self openOn: aMessage!<br>
- ----- Method: MailComposition class>>sendMailMessage: (in category 'instance creation') -----<br>
- sendMailMessage: aMailMessage<br>
-       | newComposition |<br>
-       newComposition := self new.<br>
-       newComposition messageText: aMailMessage text; open!<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition class>>unload (in category 'initialize-release') -----<br>
- ----- Method: MailComposition class>>unload (in category 'instance creation') -----<br>
  unload<br>
<br>
        MailSender unregister: self !<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>addAttachment (in category 'actions') -----<br>
+ addAttachment<br>
+       | file fileResult fileName |<br>
+<br>
+       self saveFields.<br>
+<br>
+       (fileResult := StandardFileMenu oldFile)<br>
+               ifNotNil:<br>
+                       [fileName := fileResult directory fullNameFor: fileResult name.<br>
+                       file := FileStream readOnlyFileNamed: fileName.<br>
+                       file ifNotNil:<br>
+                               [file binary.<br>
+                               mailMessage addAttachmentFrom: file withName: fileResult name.<br>
+                               file close.<br>
+                               self changed: #messageText]] !<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>addAttachmentButtonLabel (in category 'ui constants') -----<br>
+ addAttachmentButtonLabel<br>
+<br>
+       ^ 'add attachment' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>bccLabel (in category 'ui constants') -----<br>
+ bccLabel<br>
+<br>
+       ^ 'BCC' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>buildButtonBarSpecWith: (in category 'toolbuilder') -----<br>
+ buildButtonBarSpecWith: aBuilder<br>
+<br>
+       | buttonBarSpec |<br>
+       buttonBarSpec := aBuilder pluggablePanelSpec new<br>
+               children: OrderedCollection new;<br>
+               layout: #horizontal;<br>
+               frame: (LayoutFrame new<br>
+                       leftFraction: 0 offset: 0;<br>
+                       topFraction: 0 offset: 0;<br>
+                       rightFraction: 1 offset: 0;<br>
+                       bottomFraction: 0 offset: self buttonBarHeight);<br>
+               yourself.<br>
+<br>
+       buttonBarSpec children add: (aBuilder pluggableButtonSpec new<br>
+               model: self;<br>
+               action: #sendMail;<br>
+               label: #sendMailButtonLabel;<br>
+               yourself).<br>
+<br>
+       buttonBarSpec children add: (aBuilder pluggableButtonSpec new<br>
+               model: self;<br>
+               action: #addAttachment;<br>
+               label: #addAttachmentButtonLabel;<br>
+               yourself).<br>
+<br>
+       buttonBarSpec children add: (aBuilder pluggableButtonSpec new<br>
+               model: self;<br>
+               action: #removeAttachment;<br>
+               label: #removeAttachmentButtonLabel;<br>
+               yourself).<br>
+<br>
+       ^ buttonBarSpec!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>buildWith: (in category 'toolbuilder') -----<br>
+ buildWith: aBuilder<br>
+<br>
+       | windowSpec detailsPanelSpec textSpec |<br>
+<br>
+       windowSpec := aBuilder pluggableWindowSpec new<br>
+               model: self;<br>
+               label: self dialogTitle;<br>
+               children: OrderedCollection new.<br>
+<br>
+       windowSpec children add: (self buildButtonBarSpecWith: aBuilder).<br>
+<br>
+       detailsPanelSpec := aBuilder pluggablePanelSpec new<br>
+               children: OrderedCollection new;<br>
+               layout: #vertical;<br>
+               yourself.<br>
+       windowSpec children add: detailsPanelSpec.<br>
+<br>
+       self createDetailsFieldsIn: detailsPanelSpec by: aBuilder.<br>
+<br>
+       detailsPanelSpec children: detailsPanelSpec children reversed.<br>
+       detailsPanelSpec frame: (LayoutFrame new<br>
+                       leftFraction: 0 offset: 0;<br>
+                       topFraction: 0 offset: self buttonBarHeight;<br>
+                       rightFraction: 1 offset: 0;<br>
+                       bottomFraction: 0 offset: self buttonBarHeight + (detailsPanelSpec children size * self lineHeight)).<br>
+<br>
+       textSpec := aBuilder pluggableTextSpec new<br>
+               model: self;<br>
+               indicateUnacceptedChanges: true;<br>
+               getText: #messageText;<br>
+               setText: #messageText:;<br>
+               frame: (LayoutFrame new<br>
+                       leftFraction: 0 offset: 0;<br>
+                       topFraction: 0 offset: self buttonBarHeight + (detailsPanelSpec children size * self lineHeight);<br>
+                       rightFraction: 1 offset: 0;<br>
+                       bottomFraction: 1 offset: 0);<br>
+               yourself.<br>
+       windowSpec children add: textSpec.<br>
+<br>
+       ^ aBuilder build: windowSpec!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>buttonBarHeight (in category 'ui constants') -----<br>
+ buttonBarHeight<br>
+<br>
+       ^ 25 "pixel"!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>ccLabel (in category 'ui constants') -----<br>
+ ccLabel<br>
+<br>
+       ^ 'CC' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>createDetailsFieldsIn:by: (in category 'toolbuilder') -----<br>
+ createDetailsFieldsIn: detailsPanelSpec by: aBuilder<br>
+<br>
+    #((senderLabel messageSender messageSender:)<br>
+       (recipientLabel messageRecipient messageRecipient:)<br>
+       (ccLabel messageCC messageCC:)<br>
+       (bccLabel messageBCC messageBCC:)<br>
+       (subjectLabel messageSubject messageSubject:))<br>
+               do: [:config | detailsPanelSpec children add:<br>
+                               (self createFieldInputNamed: config first<br>
+                                       getter: config second<br>
+                                       setter: config third<br>
+                                       with: aBuilder)]<br>
+       !<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>createFieldInputNamed:getter:<wbr>setter:with: (in category 'toolbuilder') -----<br>
+ createFieldInputNamed: fieldLabelGetter getter: fieldGetter setter: fieldSetter with: aBuilder<br>
+<br>
+       ^ aBuilder pluggableInputFieldSpec new<br>
+               model: self;<br>
+               indicateUnacceptedChanges: false;<br>
+               getText: fieldGetter;<br>
+               setText: fieldSetter;<br>
+               frame: (LayoutFrame new<br>
+                       leftFraction: 0 offset: 0;<br>
+                       topFraction: 0 offset: 0;<br>
+                       rightFraction: 1 offset: 0;<br>
+                       bottomFraction: 0 offset: self lineHeight);<br>
+               help: fieldLabelGetter;<br>
+               yourself!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>dialogTitle (in category 'toolbuilder') -----<br>
+ dialogTitle<br>
+<br>
+       ^ 'mail editor' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>doSendMail (in category 'private') -----<br>
+ doSendMail<br>
+<br>
+       (SMTPClient openOnHostNamed: self smtpServer port: self smtpServerPort)<br>
+               user: self smtpUser;<br>
+               password: self smtpPassword;<br>
+               login;<br>
+               mailFrom: mailMessage from to: (mailMessage to findTokens: ',') text: mailMessage asSendableText.!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>initialize (in category 'initialize-release') -----<br>
+ initialize<br>
+<br>
+       mailMessage := MailMessage empty!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>lineHeight (in category 'ui constants') -----<br>
+ lineHeight<br>
+<br>
+       ^ 25 "pixel"!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>messageBCC (in category 'access to mail object') -----<br>
+ messageBCC<br>
+<br>
+       ^ mailMessage bcc!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>messageBCC: (in category 'access to mail object') -----<br>
+ messageBCC: emailAddresses<br>
+<br>
+       self flag: #TODO. "add validation"<br>
+       mailMessage bcc: emailAddresses asString.<br>
+       ^ true!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>messageCC (in category 'access to mail object') -----<br>
+ messageCC<br>
+<br>
+       ^ mailMessage cc!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>messageCC: (in category 'access to mail object') -----<br>
+ messageCC: emailAddresses<br>
+<br>
+       self flag: #TODO. "add validation"<br>
+       mailMessage cc: emailAddresses asString.<br>
+       ^ true!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>messageRecipient (in category 'access to mail object') -----<br>
+ messageRecipient<br>
+<br>
+       ^ mailMessage to!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>messageRecipient: (in category 'access to mail object') -----<br>
+ messageRecipient: emailAddresses<br>
+<br>
+       self flag: #TODO. "add validation"<br>
+       mailMessage to: emailAddresses asString.<br>
+       ^ true!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>messageSender (in category 'access to mail object') -----<br>
+ messageSender<br>
+<br>
+       ^ mailMessage from!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>messageSender: (in category 'access to mail object') -----<br>
+ messageSender: emailAddress<br>
+<br>
+       self flag: #TODO. "add validation"<br>
+       mailMessage from: emailAddress asString.<br>
+       ^ true!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>messageSubject (in category 'access to mail object') -----<br>
+ messageSubject<br>
+<br>
+       ^ mailMessage subject!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>messageSubject: (in category 'access to mail object') -----<br>
+ messageSubject: aSubject<br>
+<br>
+       self flag: #TODO. "add validation"<br>
+       mailMessage subject: aSubject asString.<br>
+       ^ true!<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition>>messageText (in category 'access to mail object') -----<br>
- ----- Method: MailComposition>>messageText (in category 'access') -----<br>
  messageText<br>
+<br>
+       ^ mailMessage bodyTextFormatted!<br>
-       "return the current text"<br>
-       ^messageText.<br>
- !<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition>>messageText: (in category 'access to mail object') -----<br>
- ----- Method: MailComposition>>messageText: (in category 'access') -----<br>
  messageText: aText<br>
+<br>
+       mailMessage body: ((MIMEDocument<br>
+               contentType: MIMEDocument contentTypePlainText<br>
+               content: aText asString)<br>
+                       charset: 'UTF-8';<br>
+                       yourself).<br>
+       ^ true!<br>
-       "change the current text"<br>
-       messageText := aText.<br>
-       self changed: #messageText.<br>
-       ^true!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>on: (in category 'initialize-release') -----<br>
+ on: aMessage<br>
+<br>
+       mailMessage := aMessage!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>recipientLabel (in category 'ui constants') -----<br>
+ recipientLabel<br>
+<br>
+       ^ 'Recipients' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>removeAttachment (in category 'actions') -----<br>
+ removeAttachment<br>
+<br>
+       | attachmentToBeRemoved |<br>
+<br>
+       self saveFields.<br>
+       attachmentToBeRemoved := UIManager default<br>
+               chooseFrom: (mailMessage attachments collect: [:m | m attachmentFileName ])<br>
+               values: mailMessage attachments<br>
+               title: 'Choose attachment to be removed' translated.<br>
+       mailMessage removeAttachment: attachmentToBeRemoved.<br>
+       self changed: #messageText.!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>removeAttachmentButtonLabel (in category 'ui constants') -----<br>
+ removeAttachmentButtonLabel<br>
+<br>
+       ^ 'remove attachment' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>saveFields (in category 'private') -----<br>
+ saveFields<br>
+<br>
+       (self dependents select: [:d | d hasUnacceptedEdits]) do: [:d | d accept].!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>sendMail (in category 'actions') -----<br>
+ sendMail<br>
+<br>
+       self saveFields.<br>
+<br>
+       [self doSendMail.<br>
+       Project current addDeferredUIMessage: [self changed: #close]]<br>
+               forkAt: 30!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>sendMailButtonLabel (in category 'ui constants') -----<br>
+ sendMailButtonLabel<br>
+<br>
+       ^ 'send mail' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>senderLabel (in category 'ui constants') -----<br>
+ senderLabel<br>
+<br>
+       ^ 'Sender' translated!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>smtpPassword (in category 'MailSender interface') -----<br>
+ smtpPassword<br>
+<br>
+       ^ MailSender userPassword!<br>
<br>
Item was changed:<br>
+ ----- Method: MailComposition>>smtpServer (in category 'MailSender interface') -----<br>
- ----- Method: MailComposition>>smtpServer (in category 'access') -----<br>
  smtpServer<br>
+<br>
+       ^ MailSender smtpServer!<br>
-       ^MailSender smtpServer!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>><wbr>smtpServerPort (in category 'MailSender interface') -----<br>
+ smtpServerPort<br>
+<br>
+       ^ MailSender smtpServerPort!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>smtpUser (in category 'MailSender interface') -----<br>
+ smtpUser<br>
+<br>
+       ^ MailSender userName!<br>
<br>
Item was added:<br>
+ ----- Method: MailComposition>>subjectLabel (in category 'ui constants') -----<br>
+ subjectLabel<br>
+<br>
+       ^ 'Subject' translated!<br>
<br>
<br>
</blockquote></div><br></div></div></div>