Seems that answers to complicated questions are a bit sparse in these parts, but I'll try again anyway
I'm wondering if there is any technique to reliably undo a character format application change; that is, an application of properties to a range of text with SetTextProps(). It is fairly simple to remember a list of original properties (PropVals) and the original text range (TextRange), then reapply those original properties to the whole range. However, within a text range, each character can have its own unique set of properties. So, remembering one set of original properties is not enough... seems I have to remember the properties of every single character in the range, the reapply character-by-character, in order to ensure that the new property application is completely undone.
When you apply a character format in the GUI, FM reliably allows an undo, restoring each affected character to its original state. Surely it isn't remembering a PropVals array for every single character (?) I'm just wondering if there is another trick here. It's entirely possible if FM is internally using another trick, it isn't one that I can feasibly replicate.
If you use a GetText method and use the Constants.FTI_CharPropsChange you should get an array of text items where each item has one particular set of properties. You should be able to save those for later restore. There should be no need to save the properties of each single character.
Thanks for the tip. This would streamline things a bit, I think, but I would still need to store multiple property sets at each point where the properties change, right? I'd have to also retain the text items, so I could step through all the offsets, retrieve the historic properties, then apply them to the correct range.
Just thinking out loud here, trying to ***** whether this is worth it.
You don't need to actually do the GetProps until the moment when something needs to be undone. Keep the array of TextItems until it is no longer needed. Thinking out loud as well, this leads me to the original question: what is it exactly that you want to restore?
You could keep a safety copy of a Pgf every time something within that Pgf is changed. Then restoring becomes retrieving the entire Pgf and overwriting the changed Pgf with it. Similar for other objects, but as you mention character formats I assume saving a verison of a Pgf on every change inside it should do the trick.
Hi Jang (you might need to look at this on the forum websie),
Effectively, I want to be able to restore a range of text to its original format, after the original format is completely overwritten. For example:
Here is someTEXT
Imagine that someone applies a character format that wipes all that out:
Here is some text
I want to restore the text to its original format. In the GUI, the FrameMaker Undo command successfully does that. I have a script that applies formatting and I'd like to replicate the undo, if its feasible. Naturally, the FM undo will not undo a script action.
I am talking about text ranges only. By the way, how do you store a "safety paragraph?" Using the clipboard is not an option in this case.
Thanks to Jang's tip and further experimentation, I got this to work. In order to restore original formatting to a range of text, I had to store three things:
- The original text range
- A list of text items retrieved with FTI_CharPropsChange that show all the offsets where a format change takes place. This was where Jang was pointing.
- A master array of text PropVals objects, one for each location where a change took place.
The third is necessary because the text items do not contain the actual properties at the locations of change, only the offset where a change took place and a clue as to what changed. When it comes to restoring exactly what was there before, that clue is not of much use. So, I store a full PropVals list for each location of change.
Afterwards, it's just a matter of stepping through the text items, forming text ranges out of the offsets, and applying the corresponding PropVals list to the range. It is a little tricky to keep it all straight, but it works. Of course, if there is a single text change within the restoration range prior to the restoration, it all breaks down. But this is better than what I was working with.