Update formatting in multiple editors with a single style

General TRichView support forum. Please post your questions here
Post Reply
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Update formatting in multiple editors with a single style

Post by Vitalii »

Hi Sergey and others!

I have a question / issue about Styles and Style templates. Situation:

1. All editors (TRichViewEdit) is created dynamically in tabs (TTabSheet).
2. A new style (TRVStyle) also created dynamically and associated with correspondent editor. The style is assigned to a common style via MainRVStyle property.
3. When user closes tab, we save data in RVF stream. When necessary, we create an editor in a new tab and load a stream into it.
4. We use Style templates mechanism, so UseStyleTemplates=True.

But, when we changing the style (for example, click TrvActionStyleTemplate), formatting changes only in editor on opened (active) tab. In the other (inactive) tabs, the formatting does not change. So, how can I update all editors in all tabs (and in those editors that will be opened later)?
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Update formatting in multiple editors with a single style

Post by Sergey Tkachenko »

I can suggest two solutions.

Let we have rve1 and rve2: TRichViewEdit.

1) All editors are linked to independent RVStyles, with their own collections of style templates. MainRVStyle is not assigned.
You can synchronize style templates in all editors. For example, assign rve1's OnStyleTemplateChange event:

Code: Select all

procedure TForm1.rve1StyleTemplatesChange(Sender: TObject);
begin
  rve2.ChangeStyleTemplates(rve1.Style.StyleTemplates);
end;
Now, if style templates of rve1 are changed, the same change is made in style templates of rve2.
Of course, you can do the same in a reverse direction (but set some flag to avoid infinite recursion).

Again, this approach works only if RVStyles are independent from each other.
Why? Because ChangeStyleTemplates compares the current StyleTemplates with the StyleTemplates in the parameter, and applies changes to TextStyles and ParaStyles. If you would use MainRVStyle, rve1.Style.StyleTemplates will be the same as rve2.Style.StyleTemplates, so no changes will be detected.
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Update formatting in multiple editors with a single style

Post by Sergey Tkachenko »

2) Another approach can be used if all RVStyles are linked to a main RVStyle, and only names of style templates are stored in RVF (include rvfoSaveStyleTemplatesOnlyNames in RVFOptions.
When switching tabs from an editor, save its content to TMemoryStream (using SaveRVFToStream).
When switching to a tab with this editor, re-load it from the stream (LoadRVFFromStream).

RVF reloading allows to re-apply changed style templates. This feature is used in this demo: https://www.trichview.com/forums/viewto ... f=3&t=9120 (user can change styles while editing some record in DB; changes are applied to other records when they are loaded).
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Re: Update formatting in multiple editors with a single style

Post by Vitalii »

Thank you, Sergey, both solutions are interesting in their own way)

In this case, another question: does TRVStyle class have methods for working with the stream? Our program file is an ZIP-archive, so we pack all internal data into it using TStream / TMemoryStream. There are no problems with RVF (SaveRVFToStream), but RVST?
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Update formatting in multiple editors with a single style

Post by Sergey Tkachenko »

RVST files (that contain StyleTemplates) are ini-files basically, so SaveToRVST and LoadFromRVST use TIniFile internally.

There are several possibilities to store StyleTemplates to a stream.
One of them is using TMemIniFile instead of TIniFile. You need to implement procedures - copies of SaveToRVST and LoadFromRVST, that use TMemIniFile instead of TIniFile.
Use the constructor TMemIniFile that takes TStream as a parameter. I'll consider adding the methods working with RVST in streams as standard methods in the next update.
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Re: Update formatting in multiple editors with a single style

Post by Vitalii »

Thanks for the answers, Sergey.

Another question. If there are several RVFs saved in the "old" version of the program (each with its own styles), how to assemble a common collection of styles, and then switch all the RVFs (TRichViewEdit) to this common collection in the "new" version of the program? It is acceptable that the styles of the same name be overwritten by the last loaded RVF. The main thing is that each RVF "forget" about their styles and use a common collection.

At the moment, when loading RVF, the collection of styles is completely overwritten, and I would like styles to be added to it without data loss.
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Update formatting in multiple editors with a single style

Post by Sergey Tkachenko »

I think you can do the following.

Load an old files in a separate TRichView. Save style templates from this TRichView's RVStyle in a temporal file (SaveToRVST) or a stream (as it was discussed).
Then call InsertFromRVST(<name of this temporal file>) for RVStyle containing the common collection of styles. This method does what you said: adds new styles, overrides styles having the same name.
Re-save the old document, this time only with names of style templates.
Repeat for all old documents.
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Re: Update formatting in multiple editors with a single style

Post by Vitalii »

It seems that I can’t write a working converter.

I successfully collected all the styles from separate RVF files (as you said), but when saving to a common RVST file there are different IDs. In "old" version of our program RVF styles can be at different levels of nesting, maybe this is the problem? I attached 4 RVF files (for example), each with its own style tree. I would be grateful if you show me how to create a common style list with a minimal formatting loss.
Attachments
RFVs.zip
(93.64 KiB) Downloaded 1632 times
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Re: Update formatting in multiple editors with a single style

Post by Vitalii »

Interesting observation. If I use clipboard, then everything good: copy data from the "old" RVF (with individual styles) and paste it into empty sheet in the "new" document (with common styles). When paste, text correctly refers to existing styles or just a new style is added to the common list. That's OK. But what is different in copying / pasting RVF in comparison with loading / saving to stream?

Upd.
When copying, all RVF contains correct info in the following format:
Style1
ID1
Style2
ID2
...
But when I use SaveToStream / LoadToStream, all style IDs is different. I think if I can get the same IDs through the stream, then everything will be fine. But how?)
Sergey Tkachenko
Site Admin
Posts: 17566
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Update formatting in multiple editors with a single style

Post by Sergey Tkachenko »

Loading and insertion methods process style templates differently.
On loading, ST from RVF replace ST in TRichView.
On insertion, ST are merged (according to StyleTemplateInsertMode property).

If you need merging, use Clear;InsertRVFFromStream instead of LoadRVFromStream.

--

IDs are used to refer to ST within the same document. They are used for efficiency.
Names are used to refer to ST between different document (for example, when merging ST when inserting/pasting). In different documents, styles of the same name may have different IDs (but it does not matter, because merging procedures use only names).
Vitalii
Posts: 61
Joined: Sat Oct 20, 2018 2:55 pm

Re: Update formatting in multiple editors with a single style

Post by Vitalii »

Oh, thank you so much, Sergey!
Clear + InsertRVFFromStream that's what I need)
Post Reply