View Issue Details

IDProjectCategoryView StatusLast Update
0016267LazarusWidgetsetpublic2010-04-15 11:42
ReporterJonas MaebeAssigned ToDmitry Boyarintsev 
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
PlatformPowerPCOSMac OS XOS Version10.5.8
Product Version0.9.29 (SVN)Product Build23942 
Target VersionFixed in Version 
Summary0016267: Fix for newlines inserted in the middle of a Carbon memo
DescriptionCarbon's classic Mac OS heritage means that it inserts a 0000013 character if you press "return" inside a text field.

FPC/Lazarus treat Mac OS X as a unix platform and hence use 0000010 as a newline separator.

The result is that
a) if text is assigned to a memo, FPC/Lazarus use 0000010 as line separator (Carbon properly interprets the 0000010 characters as newline characters)
b) if you press "return" in the middle of a text, Carbon will insert a 0000013
c) if this character is inserted right before an existing 0000010 character, the resulting 0000013#10 will be interpreted by Lazarus later on as a single Dos-style newline, so the inserted newline is lost

I've included a patch that replaces all 0000013 characters in the results obtained from Carbon edit controls with 0000010 characters.
Steps To Reproduce1) Open the attached project
2) Select Memo1 in the inspector, and then edit the "Lines" property
3) Place the cursor at the end of the third line (i.e., after "line."
4) Press "return" to insert an empty line
5) Click the "OK" button
6) Open the "Lines" property editor again

You will see in step 6 that the newline you inserted in step 4 has disappeared
TagsNo tags attached.
Fixed in Revision24618
LazTarget-
WidgetsetCarbon
Attached Files
  • carbonmemonewlines.patch (1,419 bytes)
    Index: lcl/interfaces/carbon/carbonedits.pp
    ===================================================================
    --- lcl/interfaces/carbon/carbonedits.pp	(revision 23942)
    +++ lcl/interfaces/carbon/carbonedits.pp	(working copy)
    @@ -482,6 +482,7 @@
     function TCarbonControlWithEdit.GetText(var S: String): Boolean;
     var
       CFString: CFStringRef;
    +  I       : Longint;
     begin
       Result := False;
       S := '';
    @@ -493,6 +494,24 @@
         Self, SGetText, SGetData) then Exit;
       try
         S := CFStringToStr(CFString);
    +    { Carbon returns newly inserted newline characters as #13, while
    +      FPC/Lazarus default to #10 for Mac OS X (as a unix platform). This means
    +      that an edit with existing text that contains newline characters will
    +      use #10 for that purpose.
    +
    +      If someone then inserts an empty line before an existing newline
    +      character, the result will be #13#10. This is the newline combination
    +      used by Dos/Windows, and is therefore replaced by a single newline (so
    +      you lose a line) by generic Lazarus code later on (in the TTextStrings
    +      methods).
    +
    +      Workaround: replace all #13 characters returned by Carbon with #10
    +      (#13 always means cariage return in UTF-8, it cannot be part of a
    +       composite character)
    +    }
    +    for I := 1 to Length(S) do
    +      if S[I] = #13 then
    +        S[I] := #10;
         Result := True;
       finally
         FreeCFString(CFString);
    
    carbonmemonewlines.patch (1,419 bytes)
  • memonewlines.zip (65,070 bytes)
  • testChar.zip (130,899 bytes)

Activities

2010-04-13 14:24

 

carbonmemonewlines.patch (1,419 bytes)
Index: lcl/interfaces/carbon/carbonedits.pp
===================================================================
--- lcl/interfaces/carbon/carbonedits.pp	(revision 23942)
+++ lcl/interfaces/carbon/carbonedits.pp	(working copy)
@@ -482,6 +482,7 @@
 function TCarbonControlWithEdit.GetText(var S: String): Boolean;
 var
   CFString: CFStringRef;
+  I       : Longint;
 begin
   Result := False;
   S := '';
@@ -493,6 +494,24 @@
     Self, SGetText, SGetData) then Exit;
   try
     S := CFStringToStr(CFString);
+    { Carbon returns newly inserted newline characters as #13, while
+      FPC/Lazarus default to #10 for Mac OS X (as a unix platform). This means
+      that an edit with existing text that contains newline characters will
+      use #10 for that purpose.
+
+      If someone then inserts an empty line before an existing newline
+      character, the result will be #13#10. This is the newline combination
+      used by Dos/Windows, and is therefore replaced by a single newline (so
+      you lose a line) by generic Lazarus code later on (in the TTextStrings
+      methods).
+
+      Workaround: replace all #13 characters returned by Carbon with #10
+      (#13 always means cariage return in UTF-8, it cannot be part of a
+       composite character)
+    }
+    for I := 1 to Length(S) do
+      if S[I] = #13 then
+        S[I] := #10;
     Result := True;
   finally
     FreeCFString(CFString);
carbonmemonewlines.patch (1,419 bytes)

2010-04-13 14:26

 

memonewlines.zip (65,070 bytes)

Dmitry Boyarintsev

2010-04-13 18:42

developer   ~0036672

Jonas, it feels like the test is somehow incomplete. (TMemo is in readonly state and there's no "Ok" button as it should according to the text).

Anyway, playing with the test shows that Carbon actually "hides" the last line of text if a line added (as you described). But it doesn't seem to be LCL related.

Anyway, could you review the test attached?!


I don't really like the solution. Even it fixes the mentioned bug, it might cause another, by introducing additional lines!

If input line is 'abc'0000013#10'def', the returned carbon text would be 3 lines, instead of 2.

Jonas Maebe

2010-04-13 21:51

reporter   ~0036676

Last edited: 2010-04-13 22:22

> Jonas, it feels like the test is somehow incomplete. (TMemo is in readonly
> state and there's no "Ok" button as it should according to the text).

The test has been constructed for testing inside Lazarus itself, not by running it!

> If input line is 'abc'0000013#10'def', the returned carbon text would be 3 lines,
> instead of 2.

There are two ways to create input in this case:
a) set the text programmatically: I think that the user (or the LCL, where applicable) should make sure that the text is "normalised" (i.e., that it uses the native line ending)
b) type text into the edit field: I'm not sure whether it is possible to type # 10 into a Carbon edit field

Dmitry Boyarintsev

2010-04-14 08:18

developer   ~0036688

Last edited: 2010-04-14 08:19

the bug is reproduced from the strings editor dialog (editing Lines property)

Dmitry Boyarintsev

2010-04-14 09:59

developer   ~0036690

another way to fix is to insert 0000013#10 instead of 0000013 on pressing enter

2010-04-14 10:57

 

testChar.zip (130,899 bytes)

Jonas Maebe

2010-04-14 11:00

reporter   ~0036692

> another way to fix is to insert # 13#10 instead of # 13 on pressing enter

That's indeed also a possibility.

Dmitry Boyarintsev

2010-04-14 11:28

developer   ~0036693

please test and close if ok.

the bug was caused by the widgetset itself.

Jonas Maebe

2010-04-15 11:42

reporter   ~0036719

Your patch is indeed a much better solution, thanks.

Issue History

Date Modified Username Field Change
2010-04-13 14:24 Jonas Maebe New Issue
2010-04-13 14:24 Jonas Maebe File Added: carbonmemonewlines.patch
2010-04-13 14:24 Jonas Maebe Widgetset => Carbon
2010-04-13 14:26 Jonas Maebe File Added: memonewlines.zip
2010-04-13 14:33 Dmitry Boyarintsev Status new => assigned
2010-04-13 14:33 Dmitry Boyarintsev Assigned To => Dmitry Boyarintsev
2010-04-13 18:42 Dmitry Boyarintsev LazTarget => -
2010-04-13 18:42 Dmitry Boyarintsev Note Added: 0036672
2010-04-13 18:42 Dmitry Boyarintsev Status assigned => feedback
2010-04-13 21:51 Jonas Maebe Note Added: 0036676
2010-04-13 22:13 Dmitry Boyarintsev Status feedback => assigned
2010-04-13 22:22 Jonas Maebe Note Edited: 0036676
2010-04-14 08:18 Dmitry Boyarintsev Note Added: 0036688
2010-04-14 08:19 Dmitry Boyarintsev Note Edited: 0036688
2010-04-14 08:19 Dmitry Boyarintsev Note Edited: 0036688
2010-04-14 09:59 Dmitry Boyarintsev Note Added: 0036690
2010-04-14 10:21 Dmitry Boyarintsev File Added: testChar.zip
2010-04-14 10:31 Dmitry Boyarintsev File Deleted: testChar.zip
2010-04-14 10:57 Dmitry Boyarintsev File Added: testChar.zip
2010-04-14 11:00 Jonas Maebe Note Added: 0036692
2010-04-14 11:28 Dmitry Boyarintsev Fixed in Revision => 24618
2010-04-14 11:28 Dmitry Boyarintsev Status assigned => resolved
2010-04-14 11:28 Dmitry Boyarintsev Resolution open => fixed
2010-04-14 11:28 Dmitry Boyarintsev Note Added: 0036693
2010-04-15 11:42 Jonas Maebe Status resolved => closed
2010-04-15 11:42 Jonas Maebe Note Added: 0036719