<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">
                                        
                                        
                                            
                                        
                                        
                                        Hi Christoph,<div><br></div><div>I see #userHasEdited as an extension to #hasUnacceptedEdits and #hasEditingConflicts, which is already in PluggableTextMorph. It seemed better to keep all together. Especially since the entire reason - #textEdited: - is only implemented in PluggableTextMorph. This way, we can keep TextMorphForEditView as small as possible. Maybe also because I don't like having <span style="font-size: 13.3333px;line-height: 1.5">TextMorphForEditView at all. I would prefer being able to use a regular TextMorph.</span></div><div><span style="font-size: 13.3333px;line-height: 1.5"><br></span></div><div><span style="font-size: 13.3333px;line-height: 1.5">Just some thoughts. :-)</span></div><div><br></div><div>Best,</div><div>Marcel</div><div class="mb_sig"></div>
                                        
                                        <blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 20.07.2019 21:03:10 schrieb Christoph Thiede <christoph.thiede@outlook.de>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
Hi Marcel,</div>
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
thank your for taking up my proposal! Allow me one question, why did you decide not to track hasUnacceptedEdits directly in the TextMorphForEditView? I think this would keep the changes small and not even require additional accessors, and in Editor>>#userHasEdited,
 #hasUnacceptedEdits: apparently is always called on the TextMorphForEditView. Also, aren't there any other possible clients of TextMorphForEditView beside PluggableTextMorph? Would be great to here the reasons!</div>
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
<br>
</div>
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
Have a nice weekend,</div>
<div style="font-family: Calibri, Helvetica, sans-serif;font-size: 12pt;color: rgb(0, 0, 0)">
Christoph</div>
<div id="appendonsend"></div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><span style="font-family: Calibri, sans-serif;color: #000000"><b>Von:</b> Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von commits@source.squeak.org <commits@source.squeak.org><br>
<b>Gesendet:</b> Samstag, 20. Juli 2019 09:59 Uhr<br>
<b>An:</b> squeak-dev@lists.squeakfoundation.org <squeak-dev@lists.squeakfoundation.org><br>
<b>Betreff:</b> [squeak-dev] The Inbox: Morphic-mt.1493.mcz</span>
<div> </div>
</div>
<div class="BodyFragment"><span style="font-size: 10pt"><span style="font-size: 11pt">
<div class="PlainText">A new version of Morphic was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Morphic-mt.1493.mcz">http://source.squeak.org/inbox/Morphic-mt.1493.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Morphic-mt.1493<br>
Author: mt<br>
Time: 20 July 2019, 9:59:23.026728 am<br>
UUID: 22c8cff7-de9c-8348-9a19-4cdd14621253<br>
Ancestors: Morphic-mt.1492<br>
<br>
Finally have a robust version for the #textEdited: callback in pluggable text morphs.<br>
<br>
Thanks to Christoph Thiede for the idea!<br>
<br>
=============== Diff against Morphic-mt.1492 ===============<br>
<br>
Item was changed:<br>
  ScrollPane subclass: #PluggableTextMorph<br>
+        instanceVariableNames: 'textMorph getTextSelector setTextSelector getSelectionSelector hasUnacceptedEdits hasUserEdited askBeforeDiscardingEdits selectionInterval hasEditingConflicts editTextSelector wantsWrapBorder'<br>
-        instanceVariableNames: 'textMorph getTextSelector setTextSelector getSelectionSelector hasUnacceptedEdits askBeforeDiscardingEdits selectionInterval hasEditingConflicts editTextSelector wantsWrapBorder'<br>
         classVariableNames: 'AdornmentCache SimpleFrameAdornments SoftLineWrap VisualWrapBorder VisualWrapBorderLimit'<br>
         poolDictionaries: ''<br>
         category: 'Morphic-Pluggable Widgets'!<br>
<br>
Item was changed:<br>
+ ----- Method: PluggableTextMorph>>hasUnacceptedEdits (in category 'unaccepted edits') -----<br>
- ----- Method: PluggableTextMorph>>hasUnacceptedEdits (in category 'dependents access') -----<br>
  hasUnacceptedEdits<br>
         "Return true if this view has unaccepted edits."<br>
  <br>
         ^ hasUnacceptedEdits!<br>
<br>
Item was changed:<br>
  ----- Method: PluggableTextMorph>>hasUnacceptedEdits: (in category 'unaccepted edits') -----<br>
+ hasUnacceptedEdits: wasJustEdited<br>
+ <br>
+        wasJustEdited = hasUnacceptedEdits ifFalse: [<br>
+                hasUnacceptedEdits := wasJustEdited.<br>
- hasUnacceptedEdits: aBoolean<br>
-        "Set the hasUnacceptedEdits flag to the given value. "<br>
-        aBoolean == hasUnacceptedEdits ifFalse:<br>
-                [hasUnacceptedEdits := aBoolean.<br>
                 self changed].<br>
+ <br>
+        wasJustEdited<br>
+                ifTrue: [self hasUserEdited: true]<br>
+                ifFalse: [self hasEditingConflicts: false].!<br>
-        aBoolean ifFalse: [hasEditingConflicts := false]!<br>
<br>
Item was added:<br>
+ ----- Method: PluggableTextMorph>>hasUserEdited (in category 'unaccepted edits') -----<br>
+ hasUserEdited <br>
+        <br>
+        ^ hasUserEdited!<br>
<br>
Item was added:<br>
+ ----- Method: PluggableTextMorph>>hasUserEdited: (in category 'unaccepted edits') -----<br>
+ hasUserEdited: aBoolean<br>
+        <br>
+        hasUserEdited := aBoolean.!<br>
<br>
Item was changed:<br>
  ----- Method: TextMorphForEditView>>keyStroke: (in category 'event handling') -----<br>
  keyStroke: evt<br>
         | view |<br>
         <br>
         editView deleteBalloon.<br>
         self editor model: editView model.  "For evaluateSelection"<br>
         view := editView.  "Copy into temp for case of a self-mutating doit"<br>
         (acceptOnCR and: [evt keyCharacter = Character cr])<br>
                 ifTrue: [^ self editor accept].<br>
+ <br>
+        view hasUserEdited: false.<br>
         super keyStroke: evt.<br>
         view scrollSelectionIntoView.<br>
         <br>
+        view hasUserEdited<br>
+                ifTrue: [       view textEdited: self contents].!<br>
-        "Make a cheap check and guess editing. (Alternative would be to copy the old contents and then compare them against the new ones. Maybe add a better hook in the TextEditor."<br>
-        (self readOnly not and: [self eventCharacterModifiesText: evt keyCharacter])<br>
-                ifTrue: [view textEdited: self contents]!<br>
<br>
<br>
</div>
</span></span></div>
</div></blockquote></div>