RTF not formatted in RichView Editor

General TRichView support forum. Please post your questions here
Post Reply
jfleming
Posts: 19
Joined: Tue May 25, 2010 4:58 pm

RTF not formatted in RichView Editor

Post by jfleming »

Hi.
This worked using D2007 + TRichView V12.3 but I am having trouble getting it to work with Delphi XE2 and TRichView V13.5 (Unicode).

My code is as follows:

{------------------------------------------------------------------------------}
{ Transfer the Text into the Memory Stream object within the Rich }
{ View Editor so that it may display it in the OnShow event. Then call the }
{ editor. }
{ On return from the editor, transfer the modified RTF text to the database. }
{------------------------------------------------------------------------------}
procedure TRichViewEditorTest.StandaloneDBRichEditDblClick (Sender: TObject);
begin
RichViewEditor := TRichViewEditor.Create (RichViewEditorTest);
try
RichViewEditor.Text_Memory_Stream := TMemoryStream.Create;
try
StandAloneDBRichEdit.Lines.SaveToStream(RichViewEditor.Text_Memory_Stream, TEncoding.Unicode);

RichViewEditor.PopupParent := RichViewEditorTest;

RichViewEditor.ShowModal;

if (RichViewEditor.Text_Changed) then
begin
if ((QryRawData.State <> dsEdit) and
(QryRawData.State <> dsInsert)) then
QryRawData.Edit;

RichViewEditor.Text_Memory_Stream.Position := 0;

StandAloneDBRichEdit.Lines.LoadFromStream(RichViewEditor.Text_Memory_Stream);
StandAloneDBRichEdit.CopyRichEdittoBlob(QryRawDataCLOB_FIELD);

QryRawData.Post;
end;
finally
RichViewEditor.Text_Memory_Stream.Free;
end;
finally
RichViewEditor.Free;
end;
end;

----------------------------------------------------------------
Inside the editor:

{------------------------------------------------------------------------------}
{ Load the Definition Text into the RichViewEdit object. }
{------------------------------------------------------------------------------}
procedure TRichViewEditor.FormShow (Sender: TObject);
begin
Text_Memory_Stream.Position := 0;

RichTextRichViewEdit.Clear;
RichTextRichViewEdit.LoadRTFFromStream(Text_Memory_Stream);
RichTextRichViewEdit.Format;

RTF_Modified := False;
Text_Changed := False;
end;

{------------------------------------------------------------------------------}
{ Implement Save differently to the standard action -- save to the database, }
{ as follows: }
{ - Get text into a local string variable. }
{ - Change all instances of "\chcbpat<N>" to "\highlight<N>". }
{ - Transfer the string into the (output) TMemoryStream. }
{------------------------------------------------------------------------------}
procedure TRichViewEditor.rvActionSave1Execute (Sender: TObject);
var
Local_String: string;
begin
{------------------------------------------------------}
{ Get the RTF text into a local string variable. }
{------------------------------------------------------}
Text_Memory_Stream.Clear;
RichTextRichViewEdit.SaveRTFToStream (Text_Memory_Stream, False);
SetLength (Local_String, TRUNC(Text_Memory_Stream.Size / StringElementSize(Local_String)));
Text_Memory_Stream.Position := 0;
Defn_Text_Memory_Stream.ReadBuffer(PRVAnsiChar(Local_String)^, ByteLength(Local_String));
{------------------------------------------------------}
{ Change all instances of the "\chcbpat<N>" keyword }
{ to "\highlight<N>". }
{------------------------------------------------------}
Local_String := StrUtils.ReplaceStr (Local_String, '\chcbpat', '\highlight');
{------------------------------------------------------}
{ Transfer the modified string into the (output) }
{ TMemoryStream. }
{ This code does not, strictly speaking, put the RTF }
{ into the database, only into the output buffer!!! }
{------------------------------------------------------}
Defn_Text_Memory_Stream.Clear;
Defn_Text_Memory_Stream.WriteBuffer (Pointer(Local_String)^, ByteLength(Local_String));

RTF_Modified := False;
Text_Changed := True;
end;

+++++++++++++++++++++++++++++++++++++++++++++++
What I see in the Delphi 2007 version editor is:
Image

And what I see in the Delphi XE2 version editor is:
Image

What am I doing wrong ???

All assistance gratefully received.

Jim
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

The result looks like you load a plain text as RTF.
So, if this stream was created by RichEdit.SaveToStream, it saves a plain text, not RTF.
jfleming
Posts: 19
Joined: Tue May 25, 2010 4:58 pm

Post by jfleming »

Thanks, Sergey.
It would seem that the RichText component Save to Stream is not saving the full database string anymore, which contains RTF code that starts:

"{\rtf1\ansi\deff0{\fonttbl{\f0\fnil Arial;}{\f1\fnil\fcharset2 Symbol;}{\f2\fnil Courier New;}{\f3\fnil\fcharset0 Verdana;}}
{\colortbl ;\red255\green0\blue0;}
\viewkind4\uc1\pard\f0\fs20 One line of text, nothing special about it. Created on 2-Jun2-2010. \par

Must see what is the change that has occurred in the TwwDBRichEdit component.

Jim
Sergey Tkachenko
Site Admin
Posts: 17310
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

If RTF stored in DB field, may be you can save it to a stream using Field.SaveToStream, without RichEdit?
jfleming
Posts: 19
Joined: Tue May 25, 2010 4:58 pm

Post by jfleming »

I was able to get the full RTF text using TwwDBRichEdit.GetRTFText. Getting it from the database field would not capture any changes to the text that may have been made in the RichEdit and not yet been posted to the database.

Users can make simple text changes directly on the RichEdit. Complex changes or any that require formatting or other RTF features can only be made by calling up the editor.

The key to resolving the problems was to realize that RTF is by definition Ansi text, so essentially I went back to an AnsiString solution. However, a solution using TStringStream which is Unicode enabled also worked.
jfleming
Posts: 19
Joined: Tue May 25, 2010 4:58 pm

Final code to call Rich View Editor from RichText DblClick

Post by jfleming »

This post is to feed back the final solution adopted, just in case it might be of use to others in the future.

; RTF text passed in to the editor as an AnsiString and the modified
; RTF text received out from the editor in the same way.
; Flag Text_Changed and string Text_In_RTF are fields of the modified
; editor.
;
RichViewEditor := TRichViewEditor.Create (<Your calling form>);
try
RichViewEditor.Text_In_RTF := AnsiString(MyDBRichEdit.GetRTFText);

RichViewEditor.PopupParent := <Your calling form>;

RichViewEditor.ShowModal;

if (RichViewEditor.Text_Changed) then
begin
if ((QryTwwDBGrid.State <> dsEdit) and
(QryTwwDBGrid.State <> dsInsert)) then
QryTwwDBGrid.Edit;

MyDBRichEdit.Clear;
MyDBRichEdit.SetRTFText(string(RichViewEditor.Text_In_RTF));

MyDBRichEdit.CopyRichEdittoBlob(QryTwwDBGridCLOB_FIELD);

QryTwwDBGrid.Post;
end;
finally
RichViewEditor.Free;
end;

; Then in the editor we have:
;
private
RTF_Modified: Boolean;
Finished_Loading: Boolean;
public
Text_In_RTF: AnsiString;
Text_Changed: Boolean;

{------------------------------------------------------------------------------}
{ Load the Definition Text into the RichViewEdit object. }
{------------------------------------------------------------------------------}
procedure TRichViewEditor.FormShow (Sender: TObject);
var
Text_Memory_Stream: TMemoryStream;
begin
Text_Memory_Stream := TMemoryStream.Create;
try
Text_Memory_Stream.WriteBuffer(PRVAnsiChar(Text_In_RTF)^, Length(Text_In_RTF));

Text_Memory_Stream.Position := 0;

RichTextRichViewEdit.Clear;
RichTextRichViewEdit.LoadRTFFromStream(Text_Memory_Stream);
RichTextRichViewEdit.Format;
finally
Text_Memory_Stream.Free;
end;

RTF_Modified := False;
Text_Changed := False;
end;

procedure TRichViewEditor.FormClose (Sender: TObject; var Action: TCloseAction);
begin
if (RTF_Modified) then
rvActionSave1Execute(Sender);
end;

procedure TRichViewEditor.RichTextRichViewEditChange (Sender: TObject);
begin
if (Finished_Loading) then
RTF_Modified := True;

Finished_Loading := True;
end;

{------------------------------------------------------------------------------}
{ Implement Save differently to the standard action, as follows: }
{ - Get text into a local string variable. }
{ - Change all instances of "\chcbpat" to "\highlight". }
{------------------------------------------------------------------------------}
procedure TRichViewEditor.rvActionSave1Execute (Sender: TObject);
var
Text_Memory_Stream: TMemoryStream;
begin
{------------------------------------------------------}
{ Get the RTF text into a local string variable. }
{------------------------------------------------------}
Text_Memory_Stream := TMemoryStream.Create;
try
RichTextRichViewEdit.SaveRTFToStream (Text_Memory_Stream, False);
Text_In_RTF := '';
SetLength (Text_In_RTF, Text_Memory_Stream.Size);

Text_Memory_Stream.Position := 0;
Text_Memory_Stream.ReadBuffer(PRVAnsiChar(Text_In_RTF)^, Length(Text_In_RTF));
{------------------------------------------------------}
{ Change all instances of the "\chcbpat<N>" }
{ keyword to "\highlight<N>". }
{------------------------------------------------------}
Text_In_RTF := AnsiStrings.AnsiReplaceStr (Text_In_RTF, '\chcbpat', '\highlight');
finally
Text_Memory_Stream.Free;
end;

RTF_Modified := False;
Text_Changed := True;
end;
Post Reply