user2834566
user2834566

Reputation: 805

How do I insert new, unformatted, lines at the top of a TRichEdit

I am using TRichEdit to hold the body of an emailing client. I've given the user simple formatting capabilities (bold, italic, underline, left, centre and right paragraph alignment and bullets. This works well to email formatted text as html using Indy following Remy's code here.

I extract the TRichEdit text as html using

function GetHTML(RichEdit:TRichEdit): string;
var
    htmlstrings : Tstringlist;
    JvRichEditToHtml1  :TJvRichEditToHtml;
begin
 htmlstrings := Tstringlist.create;
 JvRichEditToHtml1 := TJvRichEditToHtml.create(nil);
 try
   JvRichEditToHtml1.ConvertToHtmlStrings(RichEdit,htmlstrings);
   result := htmlstrings.Text;
 finally
   htmlstrings.free ;
   JvRichEditToHtml1.free;
 end;
end;

Just before I send the email I use code to insert a salutation string as a new top line in the TRichEdit, followed by two blank lines. This is used by the email system to personalise the email and also works well.

The problem is that if the user formats the first lines of their body text when they enter it, for example suppose they make the first few lines a bulleted list, then the salutation line I add under code is also shown bulleted when the email arrives.

How can I use code to insert a line at the top of a TRichEdit with no paragraph or font formatting and yet preserve any formatting that the user might have applied to (what was) the first lines of their manual input?

The code I am using at the moment to insert my salutation string is below but my salutation still gets the formatting style that the user applies. (Originally I only had the three insert lines but added the other code following ideas in a similar question here ). Identifiers in upper case are constants defined elsewhere.

procedure AddRecipientVarableToBody( var Body: TRichEdit);
  begin  
  //remove formatting from the (new) first paragraph
  Thebody.Paragraph.Numbering := nsnone;
  Thebody.Paragraph.Alignment := taLeftJustify;

  //add the three new top lines (two blank plus a recipient)
  //done backwards as we insert a new line zero each time
  TheBody.lines.Insert(0,EMPTY_STRING);  // two blank lines
  TheBody.lines.Insert(0,EMPTY_STRING);
  TheBody.lines.Insert(0,'To: ' + RECIPIENT_VARIABLE_SALUTATION); 

 //Remove any formatting from first three lines
   TheBody.SelStart:=0;
   TheBody.SelLength:= length(TheBody.Lines[0]) + length(TheBody.Lines[1]) + length(TheBody.Lines[2]);
   TheBody.SelAttributes.Style  :=  [];
   end;

Addendum:

I managed a workaround to get the result I wanted by delaying the salutation insertion until I set up the parameters ready to pass to Indy and appending the entire TRichEdit HTML to a simple text string ie instead of

Params.Add('html=' +  GetHTML(body));

I used

Params.Add('html=' +  'To: ' + RECIPIENT_VARIABLE_SALUTATION + GetHTML(body)); 

where body is the TRichEdit.

However, I'd still like to know if my prioblem can be solved through the insertion of new lines into the TRichEdit directly.

Upvotes: 1

Views: 1283

Answers (1)

Tom Brunberg
Tom Brunberg

Reputation: 21045

You can define DefAttributes for your RichEdit. Then you can easily return to use this setup simply by

RE.SelAttributes := RE.DefAttributes;

So, here's a test of your situation. First defining the DefAttributes, e.g. in OnFormCreate():

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Initialize to what you want to return to, or use as default
  RE.DefAttributes.Charset := ANSI_CHARSET;
  RE.DefAttributes.Color := clBlack;
  RE.DefAttributes.Height := -16;
  RE.DefAttributes.Name := 'Segoe UI';
  RE.DefAttributes.Size := 12;
  RE.DefAttributes.Style := [];
end;

Note that above doesn't deal with bullets, they are handled separately.

In following code we simulate what a user might have written ...

procedure TForm1.Button1Click(Sender: TObject);
begin
  RE.Lines.Add('Final reminder');
  RE.Lines.Add('Please, fill the form below, and send it immediately.');

  RE.SelStart := 0;
  RE.SelLength := Length(RE.Lines[0]);
  RE.SelAttributes.Color := clRed;
  RE.SelAttributes.Name := 'Algerian';
  RE.SelAttributes.Size := 15;

  RE.SelStart :=  Length(RE.Lines[0]);
  RE.SelLength :=  Length(RE.Lines[1]);
  RE.SelAttributes := RE.DefAttributes;
end;

... and what special attributes, Bold, Italic, Underline and Strikeout they might have added as well as a bullet for the first line. These are added with buttons in my test form.

enter image description here

Finally how to add the three lines to the beginning and assure an independent formatting.

procedure AltAddRecipientVarableToBody( var RE: TRichEdit);
begin
  RE.lines.Insert(0,EMPTY_STRING);  // two blank lines
  RE.lines.Insert(0,EMPTY_STRING);
  RE.lines.Insert(0,'To: ' + RECIPIENT_VARIABLE_SALUTATION);

  // Select
  RE.SelStart := 0;
  RE.SelLength:= length(RE.Lines[0]) + 1
               + length(RE.Lines[1]) + 1
               + length(RE.Lines[2]) + 1;
  // Clear attributes
  RE.SelAttributes := RE.DefAttributes;
  // Clear bullets
  RE.Paragraph.Numbering := nsNone;
end;

The addition of 1 char per line is for the new line characters. Note that, since bullets are properties of paragraphs, they can not be defined in DefAttributes and must be dealt with separately.

enter image description here

And the result, with the three added lines formatted with DefAttributes and the original text maintaining whatever formatting it had.

Upvotes: 1

Related Questions