Page 1 of 1

RTF blob field to RVF blob field

Posted: Sun Nov 18, 2012 11:00 am
by Alexander_Dober
Hello,

I need to convert the content of some BLOB SUB_TYPE 1 fields with RTF content to RVF and save it in BLOB SUB_TYPE 0 fields. If possible without using a form with RichViewEdit(s).

I believe there was a thread about a similar question, but it's not accessable anymore, so I would like to ask here.

So far I've tried this:

Code: Select all

function RTFToRVF_BlobFeld(RTF_Field, RVF_Field: TField; RichViewStyle: TRVStyle): boolean;
var
   myRichViewStyle: TRVStyle;
   myReportHelper: TRVReportHelper;
   myStream: TMemoryStream;
begin
   Result := false;

   if assigned(RTF_Field) and assigned(RVF_Field) then begin
      if (RTF_Field is TBlobField) and (RVF_Field is TBlobField) then begin
         if RichViewStyle = nil then begin
            myRichViewStyle := TRVStyle.Create(nil);
         end
         else begin
            myRichViewStyle := RichViewStyle;
         end;
         myReportHelper := TRVReportHelper.Create(nil);
         myStream := TMemoryStream.Create;
         try
            myReportHelper.RichView.Style := myRichViewStyle;

            myReportHelper.RichView.Options := myReportHelper.RichView.Options + [rvoTagsArePChars];

            TBlobField(RTF_Field).SaveToStream(myStream);
            myStream.Position := 0;

            if myReportHelper.RichView.LoadRTFFromStream(myStream) then begin
               myStream.Clear;
               myReportHelper.RichView.SaveRVFToStream(myStream, false);
               myStream.Position := 0;
               TBlobField(RVF_Field).LoadFromStream(myStream);

               Result := true;
            end;
         finally
            FreeAndNil(myStream);
            FreeAndNil(myReportHelper);
            if RichViewStyle = nil then begin
               FreeAndNil(myRichViewStyle);
            end;
         end;
      end;
   end;
end;
The format (colors, font settings etc.) get lost though. Probably something RVStyle related...
Can it work that way at all? What am I missing here to get it to work?

Posted: Mon Nov 19, 2012 6:10 pm
by Sergey Tkachenko
Additional settings for initialization of myReportHelper:

Code: Select all

myReportHelper.RichView.RTFReadProperties.TextStyleMode := rvrsAddIfNeeded;
myReportHelper.RichView.RTFReadProperties.ParaStyleMode := rvrsAddIfNeeded;
myReportHelper.RichView.RVFOptions := myReportHelper.RichView.RVFOptions+[rvfoSaveTextStyles, rvfoSaveParaStyles];

Posted: Thu Nov 29, 2012 11:31 am
by Alexander_Dober
Thanks Sergey, that worked fine, but there is another problem now: the size of the content.

A given text saved as RTF in a BLOB SUB_TYPE 1 field (ISO8859_1 character set) has the size of 173 bytes.

After the conversion described in the first post the same text saved in RVF format in a BLOB SUB_TYPE 0 field (UTF8 character set) has the size of 55155 bytes!

In a table with ~16800 records this means a difference of ~800+ MB...

I was somehwat shocked, but luckily I tried to save the same record from my application via the appropriate edit form with a DBRichViewEdit on it. After this the size went down to 860 bytes. That's calmative, but I need to find out why the size is *that* much higher after the conversion and to fix it. I don't see any differences in settings of the DBRichViewEdit and myReportHelper so far...

Any ideas on what the problem is and how to fix that?

Thanks,
Alex

Posted: Thu Nov 29, 2012 1:45 pm
by Sergey Tkachenko
I think it happens because of presence of unused styles

Change the procedure:

Code: Select all

function RTFToRVF_BlobFeld(RTF_Field, RVF_Field: TField): boolean; 
var 
   myRichViewStyle: TRVStyle; 
   myReportHelper: TRVReportHelper; 
   myStream: TMemoryStream; 
begin 
   Result := false; 

   if assigned(RTF_Field) and assigned(RVF_Field) then begin 
      if (RTF_Field is TBlobField) and (RVF_Field is TBlobField) then begin 
         myRichViewStyle := TRVStyle.Create(nil); 
         myRichViewStyle.TextStyles.Clear;
         myRichViewStyle.TextStyles.Add;
         myRichViewStyle.ParaStyles.Clear;
         myRichViewStyle.TextStyles.Add;
         myReportHelper := TRVReportHelper.Create(nil); 
         myStream := TMemoryStream.Create; 
         try 
            myReportHelper.RichView.Style := myRichViewStyle; 

            myReportHelper.RichView.Options := myReportHelper.RichView.Options + [rvoTagsArePChars]; 

            TBlobField(RTF_Field).SaveToStream(myStream); 
            myStream.Position := 0; 

            if myReportHelper.RichView.LoadRTFFromStream(myStream) then begin 
               myStream.Clear; 
               myReportHelper.RichView.SaveRVFToStream(myStream, false); 
               myStream.Position := 0; 
               TBlobField(RVF_Field).LoadFromStream(myStream); 

               Result := true; 
            end; 
         finally 
            FreeAndNil(myStream); 
            FreeAndNil(myReportHelper); 
            FreeAndNil(myRichViewStyle); 
            end; 
         end; 
      end; 
   end; 
end; 

Posted: Thu Nov 29, 2012 3:48 pm
by Alexander_Dober
Wow, what a difference.
Thank you Sergey, that was the reason. I wasn't aware that a RVStyle has 6 TextStyles and 2 ParaStyles after creation.

Is it necessary to add a style straight after clearing? Won't one get added because of "xxxStyleMode = rvrsAddIfNeeded"?

Posted: Thu Nov 29, 2012 4:45 pm
by Sergey Tkachenko
The main problem was not in the initial set of styles, but in accumulating styles from different RTFs.
In the new version this problem is solved by recreating TRVStyle.
Another approach would be calling DeleteUnusedStyles.

One text and paragraph style is required. It's better to assign the same font size and name that used for normal text in your RTF.