Styles and templates

General TRichView support forum. Please post your questions here
Post Reply
standay
Posts: 274
Joined: Fri Jun 18, 2021 3:07 pm

Styles and templates

Post by standay »

I guess I'm missing something with styles. Here's what I want to do.

I have set up a style template with a paragraph background color of clMaroon. And then set the text to courier and color to white. It's the only style template in the RVStyle1. I've tried applying it with:

Code: Select all

  //rve.ApplyParaStyleTemplate(rve.Style.StyleTemplates.FindItemByName('Style 1').Index, true);
  //rve.ApplyTextStyleTemplate(rve.Style.StyleTemplates.FindItemByName('Style 1').Index, true);
  //rve.ApplyStyleTemplate(rve.Style.StyleTemplates[0].Index, true);
  rve.ApplyStyleTemplate(0);
  rve.SetFocus;
Nothing works. The selected text in the rve never changes, the para background never changes. I want to set up a number of template presets, and be able to apply them easily in code. I'd prefer not setting up separate text and para styles but to do it with a template.

Any help appreciated!
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Styles and templates

Post by Sergey Tkachenko »

Did you include rvpiBackground_Color in rve.Style.StyleTemplates[0].ValidParaProperties?

Also, the result depends on selection and a kind of the paragraph style.
If Kind = rvstkText, this styletemplate is never applied to paragraph, its paragraph properties are ignored.
If Kind = rvstkParaText, results of ApplyStyleTemplate depends on selection. If a part of text inside a single paragraph is selected, it is applied to text, not paragraph.
If Kind = rvstkPara, ApplyStyleTemplate applies styletemplate to the paragraph.
standay
Posts: 274
Joined: Fri Jun 18, 2021 3:07 pm

Re: Styles and templates

Post by standay »

Sergey Tkachenko wrote: Sun Aug 15, 2021 8:13 am Did you include rvpiBackground_Color in rve.Style.StyleTemplates[0].ValidParaProperties?

Also, the result depends on selection and a kind of the paragraph style.
If Kind = rvstkText, this styletemplate is never applied to paragraph, its paragraph properties are ignored.
If Kind = rvstkParaText, results of ApplyStyleTemplate depends on selection. If a part of text inside a single paragraph is selected, it is applied to text, not paragraph.
If Kind = rvstkPara, ApplyStyleTemplate applies styletemplate to the paragraph.
I did not have the rvpiBackground_Color set. So I set that, and it sort of helps but I'm still having some issues.

First, if I do this:

Code: Select all

  for i := 0 to rve.Style.StyleTemplates.Count-1 do
  ShowMessage(rve.Style.StyleTemplates[i].Name + ' ' +
    rve.Style.StyleTemplates[i].TextStyle.FontName);
in my app, I only get 1 style returned no matter how many I have added. If I put that in your StyleTemplates demo, it returns the list of templates as expected. I can find no obvious difference in settings between the rve or rvstyle in the demo app and mine.

Second, even in the demo app that does return data, for the demo app heading 1 template, rve.Style.StyleTemplates[ i ].TextStyle.FontName is always "Arial," and it should be "Courier New". I would expect rve.Style.StyleTemplates[ i ].TextStyle.FontName to return "Courier New" if that is set in the template. I did add rviFontName and rviColor to the valid text props.

In my app, to get this to work at all, I have to use this:

Code: Select all

  rve.Style.StyleTemplates[0].ParaStyle.Background.Color := clMaroon;
  rve.Style.StyleTemplates[0].TextStyle.Color := clWhite;
  rve.Style.StyleTemplates[0].TextStyle.FontName := 'Courier New';
  rve.ApplyStyleTemplate(0);
I would expect to not have to set all that again since it was all set that way in the design time settings. And in my app, the text never changes, only the paragraph background. In the demo app I had to add this into cmbStylesClick to get it to work:

Code: Select all

  if cmbStyles.ItemIndex = 1 then
  begin
    rve.ApplyParaStyleConversion(PARA_COLOR);
    FontName := 'Courier New'; //rvs.StyleTemplates[0].TextStyle.FontName;
    FontColor := clWhite;
    rve.ApplyStyleConversion( TEXT_APPLYFONTNAME );
    rve.ApplyStyleConversion( TEXT_APPLYCOLOR );
  end;
While that works in the demo app, I had to use ApplyStyleConversion which I prefer not to have to use, which was why I was trying the style templates. It looks like those should work on their own without all the ApplyStyleConversion code. I would expect this:

Code: Select all

rve.ApplyStyleTemplate(cmbStyles.ItemIndex);
alone to work (note that I changed the demo app heading 1 to have a paragraph color and courier new font, but those never seem to work).

Maybe you can tell me where I'm going wrong?
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Styles and templates

Post by Sergey Tkachenko »

Maybe the problems is in not assigning ValidParaProperties and ValidTextProperties of a styletemplate?
if you assign

Code: Select all

  rve.Style.StyleTemplates[0].ParaStyle.Background.Color := clMaroon;
  rve.Style.StyleTemplates[0].TextStyle.Color := clWhite;
  rve.Style.StyleTemplates[0].TextStyle.FontName := 'Courier New';
you should also assign

Code: Select all

  rve.Style.StyleTemplates[0].ValidParaProperties := [rvpiBackground_Color];
  rve.Style.StyleTemplates[0].ValidTextProperties := [rvfiFontName, rvfiColor];
(I assume that only these 3 properties are defined in this styletemplate, other properties are default/inherited)

Also, make sure that rve.UseStyleTemplates = True.
standay
Posts: 274
Joined: Fri Jun 18, 2021 3:07 pm

Re: Styles and templates

Post by standay »

Sergey Tkachenko wrote: Sun Aug 15, 2021 1:48 pm (I assume that only these 3 properties are defined in this styletemplate, other properties are default/inherited)

Also, make sure that rve.UseStyleTemplates = True.
Hi Sergey, Yes, what you listed is all that I'm trying to do right now, and yes, I've had the usestyletemplates thing checked all this time as well. I put the following in:

Code: Select all

  rve.ApplyStyleTemplate(-1);
  rve.Style.StyleTemplates[0].ParaStyle.Background.Color := clMaroon;
  rve.Style.StyleTemplates[0].TextStyle.Color := clWhite;
  rve.Style.StyleTemplates[0].TextStyle.FontName := 'Courier New';
  rve.Style.StyleTemplates[0].ValidParaProperties := [rvpiBackground_Color];
  rve.Style.StyleTemplates[0].ValidTextProperties := [rvfiFontName, rvfiColor];

  rve.ApplyStyleTemplate(0);
and that finally worked. Yay!

OK, I figured out what was knocking out my styles:

Code: Select all

rve.LoadRVF(EntryPath + EntryFileName + '.rvf');
Before I load my file, I get all the templates returned by:

Code: Select all

  for i := 0 to rve.Style.StyleTemplates.Count-1 do
  ShowMessage(i.ToString + ': ' + rve.Style.StyleTemplates[i].Name + ' ' +
    rve.Style.StyleTemplates[i].TextStyle.FontName );
AFTER the load, all I get is the one style entry. Is there something special I have to do to retain my templates after calling LoadRVF?

Edit: OK, I found it. I had rvfoSaveParaStyles checked. Unchecking that leaves my style templates intact.
Edit2: Well, rvfoSaveParaStyles worked around the problem but caused other issues. I set it back and so far, it's working. I still don't know what the cause was before...

Thanks Sergey. I'm almost there with my first attempt with the formatting.
standay
Posts: 274
Joined: Fri Jun 18, 2021 3:07 pm

Re: Styles and templates

Post by standay »

Well, seems to have something to do with whether or not I save paragraphs with rvfoSaveParaStyles, and I do need to save them. I wound up with this code to make it work:

Code: Select all

  for i := 0 to rve.Style.StyleTemplates.Count-1 do
  ShowMessage(i.ToString + ': ' + rve.Style.StyleTemplates[i].Name + ' ' +
    rve.Style.StyleTemplates[i].TextStyle.FontName ); //shows all templates before storing them in tp
      tp := TRVStyleTemplateCollection.Create(nil);
      tp.AssignStyleTemplates(RVStyle1.StyleTemplates,true);
      rve.ClearAll;
      rve.SetSelectionBounds(0,0,0,0);
      rve.VScrollPos := 0;
      //rve.DeleteUnusedStyles(true,true,true);
      rve.Refresh;
      if FileExists( EntryPath + EntryFileName + '.rvf' ) then
      begin
        rve.LoadRVF(EntryPath + EntryFileName + '.rvf');
        RVETextColors;
        //rve.Format;
        rve.SetSelectionBounds(0,0,0,0);
        rve.VScrollPos := 0;
        //rve.DeleteUnusedStyles(true,true,true);
      end;
  RVStyle1.StyleTemplates.AssignStyleTemplates(tp,true);
  tp.Free;
  for i := 0 to rve.Style.StyleTemplates.Count-1 do
  ShowMessage(i.ToString + ': ' + rve.Style.StyleTemplates[i].Name + ' ' +
    rve.Style.StyleTemplates[i].TextStyle.FontName ); //shows all templates after storing them in tp; if I don't store them it doesn't show them all
Just FYI. If it suggests anything to you that I might try please let me know.

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

Re: Styles and templates

Post by Sergey Tkachenko »

If you exclude saving/loading of text/paragraph styles from RVFOptions, text and paragraph formatting will not be saved/loaded in RVF properly.
(not-saving styles may be useful for special applications that use a fixed set of text and paragraph formatting)
StyleTemplates are saved/loaded only if both text and paragraph styles are saved/loaded (because styletemplates do not make sense if set of text or paragraph attributes is fixed).

When you load RVF, RTF or DocX file, the collection of StyleTemplates is replaced by the collection from the file. All existing styletemplates are lost.
If you do not want it (want to merge styletemplates from file to the existing collection, rather than replace it), use insertion methods:

Code: Select all

Stream := TFileStream.Create(FileName, fmOpenRead);
rve.Clear;
rve.InsertRVFFromStream(Stream, 0);
rve.Format;
Stream.Free;
There are no methods similar to InsertRVFFromStream for RTF and DocX. However, all editing methods that insert data from file/stream (like InsertRVFFromFileEd, InsertRTFFromFileEd, InsertDocXFromFileEd) merge styletemplates, not replace them.



For RVF, there is another option: saving RVF files without styletemplates, but with names of styletemplates.
This is the best way to share the same collection of styletemplates across multiple documents.
Probably this is what you want.
Example: https://www.trichview.com/forums/viewto ... f=3&t=9120
standay
Posts: 274
Joined: Fri Jun 18, 2021 3:07 pm

Re: Styles and templates

Post by standay »

Sergey,

Yes, that describes what I was seeing. For now I went with saving the file with just the names of the style templates by setting rvfoSaveStyleTemplatesOnlyNames to true in the RVFOptions. Seems to be working OK. If that causes issues later I can always go back to what I was doing as that worked too. The app I'm working on will use RVF all the time other than allowing export to RTF and text later on.

After a lot of trial and error, I seem to have the formatting working now. I'm using the text and para style conversions for single words, and the templates for blocks of text. So far that seems to be the best solution for what I'm trying to do.

Thanks for the help!

Stan
Post Reply