Last modified 15 years ago
Last modified on 04/26/10 14:33:59
Analysis
Overview
- After the TEXT_MODEL_REDESIGN task the positions of the caret and mark in the text views are not updating.
- The text links and the search highlights are not visualizing.
After the task these two bugs shold be fixed.
Task requirements
- Fix the updating of the caret, mark and search highlights position.
- Implement search highlight visualization in the text views.
- Implement link attachment visualization (as foreground color) in the text views.
Task result
The result should be code.
Implementation idea
- Create a new class related to the text views that updates the indexes.
- Create processors to help text layout draw the search highlights.
- The processors add some attributes to the raw text (the text in the model) and produce a final text with all attributes added (as highlights and selection etc.) that can be laid out.
Related
How to demo
- Run sophie, insert text frame, type some text, select some of the text.
- Run sophie, insert text frame, type some text, add text link.
- Run sophie, insert text frame, search an existing word from the search palette.
Design
- Make interface TextProcessor.
- Usage: Gets a text on its input and gives another text as a result. Processors get the model text of an element and make it ready for drawing, that is, they may put decorations, colors, may even change the text itself.
- Contents:
- Empty interface Options. This is the criteria for processing the text, e.g. highlight color, caret position, highlight interval, etc.
- Interface Effect. This consists of the resulting text after a processing and the change that is generated from it (the change that if applied to the raw text, the processed one will be the result). An Effect is actually an instruction for the next processor in a processing chain.
- public ImmText getText();
- public TextChange getChange(); The TextChange this text processing has caused.
- ImmText process(ImmText sourceText, T procOptions); You give the processor a text and the rules for processing, then it returns the processed text. For example: TextSelectionProcessor, which has text 'abc' and options 'caret: 2, mark:1, color: red' will return 'abc' with colored in green 'b' and 'c', as well as a caret before the 'c'.
- Effect applyChange(Effect prevEffect, ImmText oldSource, T procOptions); Processes the text again after a TextChange has been applied to it. You could actually use process in this case, but it will do a whole processing of the text, which will be slow. So, this method's purpose is to be effective.
- Effect setOptions(ImmText source, ImmText oldProcessed, T oldOptions, T newOptions); If the text is not modified itself, but only the options are changed, then it could perform even faster. This method should implement this idea.
- Implement text search processor
- Usage: It is intended to draw the background highlight for the current quick search result. Since selection will also use a TestProcessor, the highlights() property somewhere in the text frame view, becomes unneeded. The quick search logic should stay unchanged, but the results will not be put in the highlights() property - they will be set as current options for the search processor.
- Contents:
- TextSearchOptions - they only contain the ImmTextInterval for the highlight and the highlight color.
- Implement text link processor
- Usage: The current text model has attributes with link Ids attached to the text units. The processor needs the colors associated with these IDs so it can set the text foreground - this way, the text will be drawn with different color in its link intervals. Any maps that map intervals to attachments will be removed - the only thing we need to map is link IDs. Methods like HeadTextFrameView.getExtraHighlights() should also be removed.
- Contents:
- TextLinkOptions - contains a map of strings to ImmColors. Nothing special here.
- In org.sophie2.base.model.text.mvc package add new class public static class SelectionOptions<T> implements TextProcessor.Options - a class representing the options of the selection processor. This class has private final HotAttr<T> attribute, private final T value, private final ImmTextInterval selectionInterval. The first one holds the attribute of the selection (CommonAttr.BACKGROUND_COLOR), the second one holds it's value (Ex: ImmColor.Blue) and the third one holds the selection interval.
- In org.sophie2.base.model.text.mvc package add new class SelectionProcessor implements TextProcessor<SelectionOptions, DefaultTextEffect> - Processes text selection and caret.Its work consists of modifying some of the the color attributes for the selected chars.
TEXT_VIEW part
- In org.sophie2.base.model.text package add new abstract class TextChange that represents
the base model of a text change (applying styles ot text, replacing existing text in some interval).
This class has the following abstract functions:
- public abstract ImmText applyTo(ImmText sourceText) - This method applies the current text change to a given text and returns new text with applied change.
- public abstract ImmTextInterval getSourceDamage(ImmText sourceText) - Returns the region (interval) from the source text that has been affected by the change
- public abstract ImmTextInterval getTargetDamage(ImmText sourceText) - Returns the region (interval) from the target text (text after the change is made to the source text) hat has been affected by the change.
- public abstract int updateIndex(int index, ImmText sourceText) - Updates the given index. Ex: text: ASD, the change is deleting the A; update(2) will return 1.
- In org.sophie2.base.model.text add new class TextReplaceChange that extends TextChange. This class gives basic implementation of the TextChange's functions for a change representing replacing in the ImmText. This class has two private fields: final ImmTextInterval interval and final ImmText substitution - the first one holds the interval that will be replaced and the second one holds the text for the substitution. The applyTo method simply calls ImmText#replace function.
- In org.sophie2.base.model.text package add class TextStyleChange that extends TextChange class. This class is basic implementation of the functions in TextChange class for changes in text that represent applying styles on ImmText. It has two private fields - final ImmTextInterval interval and final HotStyleDef style. The first one holds the interval that the styles will be applied to and the second one holds the styles. The applyTo method calls ImmText#applyStyle function.
- In CommonAttr class add public static ImmList<HotAttr<?>> getAllAttr() function and remove the same from HotStyleDef class. This function gets all the attributes that are defined in the class.
- In CommonAttr class add new public static final HotAttr<Boolean> END_TEXT_ATTRIBUTE - Attribute that is true only if the char is DOC_BREAK.This is needed because the last text run in the text layout has to consist only of the DOC_BREAK in order not to be drawn and not to be handled in complicated ways.
- In ImmTextUtils class add new method: public static ImmText createDefaultText() - Creates a text with one char equal to DOC_BREAK.
- In org.sophie2.base.model.text.elements package add new final class : LayoutAttr that holds all the attributes that only the processors can apply to the text.
- In LayoutAttr class add HotAttr<Boolean> CARET_ATTR - this attribute represents the caret in the view. True if the caret is before that char.
- In ImmTextInterval class add new function: public ImmTextInterval unite(ImmTextInterval interval) - Unites two intervals - gets the largest possible interval from the given one and the current. This is needed when the text processors setOptions and changeOptions is called - to reuse some of the processed text before the change.
- In ImmTextUtils add new function: public static ImmText concat(ImmText text1, ImmText text2) - Concatenates the two given texts. Keeps the styles as the origin texts. This is needed in the processors to add the DOC_BREAK in the end of the text and to keep its style.
- Rename TextViewFlow to TextModel , make it extend BaseProObject class and add new functions as follows:
- public abstract ImmText getRawText() - The text in the model. This is text without any attributes added for highlights, selection, etc.
- public abstract ImmText getProcessedText() - The text that the layout use. This text differs from the raw text only by some text attributes (added for highlights, selection etc.)
- remove the caret() and mark() properties and replace them with getCaret, setCaret, getMark and setMark.
- In org.sophie2.base.model.text.mvc package add new class abstract class BaseTextModel extends TextModel - Basic implementation of the methods from the TextModel abstract class. This class has function public void update(TextChange change) that applies the given change to the raw text and to the processed text and updates the indexes of the caret an the mark of the model.
- In org.sophie2.base.model.text.mvc.swing package add new class: SwingTextModel extends BaseTextModel - The swing realization of the {@link TextModel} class. It is used only for testing.
- In org.sophie2.main.func.text.view package add new class : abstract class ResourceTextModel extends BaseTextModel - Base implementation of the TextModel that connects the view with the text resource. It has one function: public void changeModel(final TextChange change, ResourceAccess access, final ImmText text, boolean significant, String description) - Method for updating the text model with a given TextChange. Changes the text resource, related to the view that holds the current ResourceTextModel and updates the caret and mark posses to stay consistent.
- Make the class HeadTextModel extend ResourceTextModel.
- In HotTextLogic class rename ON_SET_TEXT to ON_CHANGE_TEXT and call the changeModel when the text needs to be changed in the model(replace the AutoAction part).
- In TextView class : EventIds rename the SET_TEXT to CHANGE_TEXT and set its event params to: TextChange.class, String.class, Boolean.class - the change to be made, the description of the action and the significance (if it can be undo/redo).
- In org.sophie2.base.model.text.mvc pachage add new class CaretProcessor implements TextProcessor<CaretOptions, DefaultTextEffect> - Processes text with caret. It puts the LayoutAttr#CARET_ATTR somewhere.
- In CaretProcessor class add new class - CaretOptions implements TextProcessor.Options - Class representing the options of the caret processor.
- this class has two fvields : private final int caretPos and private final boolean withCaret - the first one represents the caret position in the
current text and the second one is true only if the caret should be drawn.
- the class has a default constructor - public CaretOptions(int caretPos, boolean withCaret).
- public int getCaretPos() - Getter for the caret position. Returns the position of the caret(will be drawn before the char in the returned position).
- public boolean getWithCaret() - Getter for the caret visibility. Returns true if the caret will be drawn, false otherwise.
Tests : SelectionProcessorTest, LinkProcessorTest.
Implementation
Done according to the design in branches/private/diana/2384. Please, integrate it in the text trunk.
Testing
(Place the testing results here.)
Comments
(Write comments for this or later revisions here.)