Replace Label with Text

General TRichView support forum. Please post your questions here
Post Reply
MarkElder
Posts: 21
Joined: Tue Aug 28, 2012 7:43 pm

Replace Label with Text

Post by MarkElder »

Hello,

I am trying to setup a mail merge using the Label examples. However, in the final document I need to be able to have merged fields wrap. I've looked at the different demos and for creating the merge templates I like how the labels work the best.

However I am having trouble deleting the label and replacing it with the text during the merge. Here is what I am trying but I keep ending up with junk in the final document.


procedure TRVViewer.UpdateRVItem(RVData: TCustomRVData; ItemNo: integer; NewData: string);
var
item: TRVTextItemInfo;
x: TRVRawByteString;
begin

case RVData.GetItemStyle(ItemNo) of
rvsLabel:
begin
// Works OK but will not support the NewData being word wrapped.
//TRVLabelItemInfo(RVData.GetItem(ItemNo)).Text := NewData;

item := TRVTextItemInfo.Create(RVData);

item.StyleNo := TRVLabelItemInfo(RVData.GetItem(ItemNo)).TextStyleNo;
item.ParaNo := TRVLabelItemInfo(RVData.GetItem(ItemNo)).ParaNo;
item.ItemOptions := RVData.GetItem(ItemNo).ItemOptions;

RVData.DeleteItems(ItemNo, 1);

// What is the string needed for here? It can't be a string it needs to be TRVRawByteString because it
// is a var paramater.
item.Inserting(RVData, x, False);
RVData.Items.InsertObject(ItemNo, NewData, item);
item.Inserted(RVData, ItemNo);

end;
MarkElder
Posts: 21
Joined: Tue Aug 28, 2012 7:43 pm

Post by MarkElder »

I've narrowed this down to a problem with setting the StyleNo. I know that labels have a different TextStyleNo property but that does not seem to work correctly.


CurLabelItem := TRVLabelItemInfo(RVData.GetItem(ItemNo));
NewTextItem := TRVTextItemInfo.Create(RVData);

// This shows me my text but does not hold the style applied to the
// label in the template.
NewTextItem.StyleNo := 0;


// Both of these options will end up with garbage in the output (looks like // Asian chars.

// NewTextItem.StyleNo := RVData.GetActualTextStyle(CurLabelItem);
// NewTextItem.StyleNo := CurLabelItem.TextStyleNo;

NewTextItem.ParaNo := CurLabelItem.ParaNo;

// It looks like AssignParaProperties ends up setting most of the
// ItemOptions?
NewTextItem.ItemOptions := CurLabelItem.ItemOptions;
NewTextItem.AssignParaProperties(CurLabelItem);

RVData.DeleteItems(ItemNo, 1);

NewTextItem.Inserting(RVData, x, False);
RVData.Items.InsertObject(ItemNo, NewData, NewTextItem);
NewTextItem.Inserted(RVData, ItemNo);
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

You can use the function from RVInsertItems.pas:

Code: Select all

procedure RVInsertString(RVData: TCustomRVData; ItemNo: Integer;
  const s: String; StyleNo, ParaNo: Integer;
  const Tag: TRVTag=RVEMPTYTAG);
It inserts string in the ItemNo-th position, automatically sets the correct raw-byte string and item options.
To add to the same paragraph, specify ParaNo=-1.
MarkElder
Posts: 21
Joined: Tue Aug 28, 2012 7:43 pm

Post by MarkElder »

That worked great.

I ended up with the following code. Much simpler than before. Posting here in case anyone else is interested.

One other change I had to make was in the main FillFields function from the mail merge examples. The examples use a for loop. Because I am inserting new items I needed to change it to a while loop. Otherwise I ended up stopping before I updated all of the items.

I ended up leaving the label in place. I think in theory I could copy the paragraph attributes to the newly inserted item but this seemed simpler.

One question I still have is am I better off setting the text to an empty string or should I leave the text alone and set CurLabelItem.Hidden := true;? I can't tell if there would really be a difference or not. The one item that worries me about the empty string is I have seen in the help where an empty item is not always valid. Not sure if that applies here or not.

Code: Select all

      // We are going to insert the new data right after this item.
      // To ensure that we stay in the same paragraph with the same formatting
      // the Label will be left in place but the text set to a blank string.
      CurLabelItem := TRVLabelItemInfo(RVData.GetItem(ItemNo));
      CurLabelItem.Text := '';

      if NewData <> '' then
        RVInsertString(RVData, ItemNo + 1, NewData, CurLabelItem.TextStyleNo, -1);
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Empty label items are valid.
(if you add/delete items, you can use "for ... downto" cycle)
MarkElder
Posts: 21
Joined: Tue Aug 28, 2012 7:43 pm

Post by MarkElder »

Thanks for the tip. Everything is now working great.
Post Reply