wiki:TEXT_CHAIN_AUTO_R0
Last modified 15 years ago Last modified on 12/07/09 11:58:14

Error: Macro BackLinksMenu(None) failed
compressed data is corrupt

Error: Macro TicketQuery(summary=TEXT_CHAIN_AUTO_R0, format=table, col=summary|owner|status|type|component|priority|effort|importance, rows=description|analysis_owners|analysis_reviewers|analysis_score|design_owners|design_reviewers|design_score|implementation_owners|implementation_reviewers|implementation_score|test_owners|test_reviewers|test_score|) failed
current transaction is aborted, commands ignored until end of transaction block

Analysis

Overview

Autochaining should be more stable

Task requirements

  • Add an item "Autochain" in the chain dropdown and remove the autochain button.
    • The item may be italic in order to be clear that it is not a regular item
    • When autochaining is enabled, a template for this page is automatically added.
      • When the last page is modified, a new template is created automatically on creating a new page for the flow.
      • New pages appear with the layout of the last page in the chain.
  • When the text overflows, a new page with the same layout is created at the end of the page sequence
    • The page may contain more than one auto chained frame
  • When text is deleted and the flow no longer fills all of the frames on a page
    • If the page has local modifications, it is not deleted
    • If there are previous pages without local modifications, they are deleted (there should not be text from other flows)
  • When autochain is created the last frame of the autochain should be with enabled autochain by default:
    • Create text frame paste. -> Text frame is inserted.
    • Paste text in it. -> The frame is filled with text (visual marker appears (optional)).
    • Click on autochain. -> New pages with same template are created.
    • Paste some text in the already created autochain. -> New pages with frames should be added after the last, because the text is overflowing.
  • Optional - When a text frame is full and unchained, make a red glow to indicate that there is text that is not displayed
    • This glow should be visible in author mode only

Task result

Code

Implementation idea

Make a single method that uses the dry run of HotLayout and recalculates the areas needed for the text flow. It should add or remove pages if necessary. When auto-chaining is enabled call this method whenever chainging the layout of the HeadTextFrameView.

TEXT_AUTO_CHAIN_BEHAVIOUR_R1
TEXT_AUTO_CHAIN_BEHAVIOUR_R0

How to demo

  • First case:
    • Create a page
    • Set custom layout.
    • Insert an image frame
    • Insert a text frame, put enough text and autochain
    • Delete the text and show that pages are deleted
  • Second case:
    • Create text frame paste. -> Text frame is inserted.
    • Paste text in it. -> The frame is filled with text (visual marker appears (optional)).
    • Click on autochain. -> New pages with same template are created.
    • Paste some text in the already created autochain. -> New pages with frames should be added after the last, because the text is overflowing.

Design

In org.sophie2.main.func.text.chaining package add a new enum ChainingMode containing different modes of the chaining:

  • NO_CHAINING - The representation of no chain mode.
  • AUTO_CHAINING - The representation of auto-chaining mode.
  • MANUAL_CHAINING - The representation of manual chaining mode.

The KEY_CHAIN_MODE should be holding value from this enum.

The chaing hud elements would no longer be of the ResourceH class, since there are two special elements to add - for turning on and off auto-chainig. Create a class ChainHudElement in org.sophie2.main.func.text.chaining package that holds a ResourceRefR4 and a String representation of the object. It would be immutable. There will be two special elements holding NONE-REF and the strings "AUTO-CHAIN" and "NO CHAIN". Other elements should not be created withh NONE resource ref. So the constructor should be private and there will be a create method to validate the given refs.

In TextChainingLogic::ON_CHAIN_TEXT_FRAME check what elements was choosen and if it is with none ref change HeadTextFrameR4.KEY_CHAIN_MODE corespondingly, otherwise chain the frame pointed by the resource ref held in the element to the head of the current frame. This hsould always change the chain mode to manual.

In org.sophie2.main.app.commons.util package create a util class named TemplateUtil. It will contain helper methods for the page and frame templating and for the creating of new templates. There is a difference in code of templating those elements since the templating of sub elements is not yet final.

  • createTemplate - creates a template from a given element view. It should check whether it is page or frame.
  • applyPageTemplate - apply given template to the given page. That is - set all keys to null, except the sub-entries one.
  • applyFrameTemplate - Set all given templated keys to null. If it is setting the main-resource, change the kind corespondingly.

Write better dryRun method in the HotLayout class that takes in mind the number of chianed areas in the last page. It should also check if there are extra pages and return -1.

In TextChainHud change the existing TextChainComboBox class to extend BoundComboBox<ChainHudElement> and change the addFrames method to get a list of ChainHudElements constructed by the resource ref of the frame and its name (for string representation). Remove the AutoChain button and all its logic.

The TextChainUtils should be quite extended to hold the helper methods used by the chaing logic. Some of them are moved from the TextChainingLogic. The method used for auto-chaining will be called reflowText. It would get a head frame view as argument and basically handle all auto-fitting of its text flow (creatin, deletion of pages). It should get all frame views in this head frame`s chain. Then it gets the number of frames on the last page and runs the HotLayout.dryrun method with them. If the result is 0 - there is nothing more to do. If the result is -1 this means that the last page is empty. There should be a separate method that hamdles the deletion of extra pages. Its name should be reduceChain. If the result is an positive int this is the number of pages exactly as the first one to be added. This should be done by the method expandChain.

  • expandChain - The chain should be expanded with pages that use templates made from the last page in the current chain and children that use templates made from the children of the last page`s children. The last page should also be made to use this template so that wnem it is changd it chanes just like the others in the chain. Those templates are added to the library just like regular ones. There are some x-cases:
  • when there is another auto-chain in the page - the new frames are made the next in their chain.
  • if there is an head frame (that is not autochained) its copy uses the same text resource.
  • when there is a tail frame (or head frame that is auto-chained), its copy is the next in the chain of the source. Its chain order is also placing it before any other frame of this chain.
  • reduceChain - Checks all pages starting from the last one for pages that are all templated. This means that their templated keys should be templated and all their children should also be templated. Also all of its tail text frames should be empty. If such page is found it is deleted. If there is no more an empty page in the end of the chain the job is done, otherwise we continue looking ofr pages to remove from the previous page.

There will be needed some helper methods:

  • TEXT_VIEW_COMP - Comparator for thext views. It compares views from the same chain by their chain-order strings.
  • isAllPageTemplated - checks if all the templatable keys from the given page along with the keys of it's subelements(frames) are in TEMPLATE mode. This is not the best way to see whther the whole page is templated but it would do before implementatin of the sub-elements templating.
  • isPageTemplated - checks if all the templatable keys(for now except sub-entries) are in TEMPLATE mode, i.e. are their raw values null.

In HeadTextFrameView in the class textFlow used for a the resource property with the same name crate a class named ReflowThread. Its run method will be quite simple. It should sleep for a second and then invoke later in the event dispatching thread the method TextChainUtils.reflowText giving it this HeadTextFrameView object. he Headin getTextLayout method that extends Thread and delays the invoking of the TextChainUtils.reflowText method. Now the only thing that is left is to start the thread and this will happen every time the method getTextLayout() is called on an autochained head view. It would check if there is a thread runing and if not - strat one. Otherwise its job is done. For optimization there may be a check whether the text flow is going to be the same as the last time the thread was called.

There will be some additional fixes of bugs in the current chainig logic:
Now the logic assumes that in a chain there are never same chain orders. But this is not always this way. when there are same chain orders the order of the pages and the z order are taken in consideration. Also this is the reason why the getChainedFrames() helper method can not return a map - since there is not always a single TailFrameH corresponding to a chain order.
The logic of the two buttons for unchain (previous and next) should be unified. There will be a common method splitChain that they will use. It would make the given frame - head of a new chain and all after it would be chained to it. It could use the same text resource as the previous one or get a new empty one. This should be specified by an flag argument.
This method will also be used when deleting pages. Its logic was broken if deleting from the button but it was ok if deleting by 'del' or backspace. The delete page button should have the same event as the others (its source should be the PagePreviewPalette). Now before the page is deleted the chains that start in it are split to the first frame that is not in this page.

Also there are a couple of bugs in the base functionality of the resources.
First one is in the ModelResourceChanger. When an key is set to null and get in the same auto-action the get returns wrong value - the old one from the model. This could only be found while developing and I don`t think there is an ticket for it.
The other one is in the modify method of the ResourceModel. The problem occures when creating template from templated frame. There is an exception thrown but there is no ticket also. It this case the values of some of the keys are already null and there is no need for them to be set to null but their 'locked-key's are still set to false. The moidfy method relies on the fact that when modifing a node corresponding to a key there are chanes meant for it if the sub map of changes for entries whose keys start with this key is not empty. This is not true for the case of templated keys though since their locked keys idd start exactly the same as their ids. This method hsould not rely on such assumptions.

Implementation

The implementation was done according to the desing. The impl code is located on straxil:5 in workspace.

There is no problem with saving/loading books (old or new). There were some simple optimizations. I added a method that ckeck if we are in the last frame of the chain - there is no need to traverse the frame views of the book.

Testing

(Place the testing results here.)

Comments

(Write comments for this or later revisions here.)