Ticket #2419: 2419.patch

File 2419.patch, 17.9 KB (added by diana, 9 years ago)
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/TextModelLogic.java

    ### Eclipse Workspace Patch 1.0
    #P sophie
     
    2626import org.sophie2.base.model.text.model.ImmTextUtils; 
    2727import org.sophie2.base.model.text.model.TextUnit; 
    2828import org.sophie2.base.model.text.model.TextUtils; 
     29import org.sophie2.base.model.text.mvc.CaretProcessor.CaretOptions; 
    2930import org.sophie2.base.model.text.mvc.TextView.Place; 
    3031import org.sophie2.base.model.text.style.HotStyleDef; 
    3132import org.sophie2.base.skins.Message; 
     
    6566                        SophieLog.trace("FLOW_MOUSE_OPERATION.handle"); 
    6667                        InputEventR3 eventId = event.getEventId(InputEventR3.class); 
    6768                        TextView source = event.getSource(TextView.class); 
    68                          
     69 
    6970                        boolean handle = false; 
    7071                        if (eventId == InputEventR3.MOUSE_PRESSED 
    7172                                        || eventId == InputEventR3.MOUSE_DRAGGED 
     
    197198                                // This TextView is no longer in the flow.  
    198199                                return true; 
    199200                        } 
    200                          
     201 
    201202                        Place place = event.getEventParam(0, Place.class); 
    202203                        if (place == Place.ALL) { 
    203204                                setSelection(source,textModel.getRawText().getBegin(),  
     
    235236                                //This TextView is no longer in the flow.  
    236237                                return true; 
    237238                        } 
    238                          
     239 
    239240                        ModifierSet modifiers =  
    240241                                event.getEventParam(InputEventR3.MODIFIERS_PARAM_INDEX, ModifierSet.class); 
    241242                        char keyChar = event.getEventParam(InputEventR3.CHAR_PARAM_INDEX, 
     
    263264                                        ImmTextInterval(caretInfo.getCaret(), caretInfo.getMarkIndex()), txtToReplaceWith); 
    264265 
    265266                        boolean result = fireChangeText(event, change, false, Place.RIGHT); 
    266                          
     267 
    267268                        if (result) { 
    268269                                textModel.inputStyle().set(HotStyleDef.getEmpty()); 
    269270                        } 
     
    305306                                } 
    306307                                LogicR3.fire(new EventR3(source, null, null, null, EventIds.SELECT_VIEW, areaIndex)); 
    307308                        } 
    308                          
     309 
    309310                        boolean isSignificant = false; 
    310311                        int intervalLength = interval.getEnd() - interval.getBegin(); 
    311312                        if (intervalLength == 1  
     
    392393                        filter.setEventId(TextView.EventIds.APPLY_STYLE); 
    393394                } 
    394395 
     396                @SuppressWarnings("unchecked") 
    395397                public boolean handle(EventR3 event) { 
    396398                        TextView view = event.getSource(TextView.class); 
    397399                        TextModel textModel = view.getTextModel(); 
     
    403405                        if (!textModel.isEditable()) { 
    404406                                return true; 
    405407                        } 
    406                          
     408 
    407409                        SelectionInfo caretInfo = textModel.getSelectionInfo(); 
    408410                        int caretPos = caretInfo.getCaret(); 
    409411                        int markPos = caretInfo.getMarkIndex(); 
     
    413415                        HotStyleDef newStyles = textModel.inputStyle().get().derive(styleValues); 
    414416                        if (caretPos - markPos == 0) { 
    415417                                textModel.inputStyle().set(newStyles); 
     418                                 
     419                                 
     420                                CaretOptions oldCaretOpt = textModel.getProcessOptions(CaretProcessor.get()); 
     421                                CaretOptions newCaretOptions = new CaretOptions(oldCaretOpt.getCaretPos(), 
     422                                                oldCaretOpt.isCaretVisible(), textModel.inputStyle().get()); 
     423                                textModel.setProcessOptions((TextProcessor<TextProcessorOptions, TextProcessorEffect>)  
     424                                                (TextProcessor<?, ?>) CaretProcessor.get(), newCaretOptions); 
     425                                 
    416426                                return true; 
    417427                        } 
    418428 
     
    441451                        filter.setEventId(TextView.EventIds.APPLY_PARA_STYLE); 
    442452                } 
    443453 
     454                @SuppressWarnings("unchecked") 
    444455                public boolean handle(EventR3 event) { 
    445456                        TextView view = event.getSource(TextView.class); 
    446457                        TextModel textModel = view.getTextModel(); 
     
    457468 
    458469                        if (textModel.getRawText() != ImmTextUtils.createEmptyText()) { 
    459470                                List<Character> breaks = CommonChar.getEffectiveBreaks(CommonChar.PARA_BREAK); 
    460                                  
     471 
    461472                                SelectionInfo selectionInfo = textModel.getSelectionInfo(); 
    462473                                int caret = selectionInfo.getCaret(); 
    463474                                int mark = selectionInfo.getMarkIndex(); 
    464                                  
     475 
    465476                                int first = (caret <= mark  ? caret : mark); 
    466477                                int second = (caret > mark ? caret : mark); 
    467478 
     
    472483 
    473484                                if (selection.isEmpty()) { 
    474485                                        textModel.inputStyle().set(inputStyle.derive(style)); 
     486                                        CaretOptions oldCaretOpt = textModel.getProcessOptions(CaretProcessor.get()); 
     487                                        CaretOptions newCaretOptions = new CaretOptions(oldCaretOpt.getCaretPos(), 
     488                                                        oldCaretOpt.isCaretVisible(), textModel.inputStyle().get()); 
     489                                        textModel.setProcessOptions((TextProcessor<TextProcessorOptions, TextProcessorEffect>)  
     490                                                        (TextProcessor<?, ?>) CaretProcessor.get(), newCaretOptions); 
    475491                                } 
    476492                                TextChange change = new TextStyleChange(selection, style); 
    477493 
     
    480496                        }   
    481497 
    482498                        textModel.inputStyle().set(inputStyle.derive(style)); 
     499                        CaretOptions oldCaretOpt = textModel.getProcessOptions(CaretProcessor.get()); 
     500                        CaretOptions newCaretOptions = new CaretOptions(oldCaretOpt.getCaretPos(), 
     501                                        oldCaretOpt.isCaretVisible(), textModel.inputStyle().get()); 
     502                        textModel.setProcessOptions((TextProcessor<TextProcessorOptions, TextProcessorEffect>)  
     503                                        (TextProcessor<?, ?>) CaretProcessor.get(), newCaretOptions); 
    483504                        return false; 
    484505                } 
    485506        }, 
     
    500521                        TextModel textModel = view.getTextModel(); 
    501522                        ImmText text = textModel.getRawText(); 
    502523                        SelectionInfo caretInfo = textModel.getSelectionInfo(); 
    503                          
     524 
    504525                        ImmTextInterval selection =  
    505526                                new ImmTextInterval(caretInfo.getMarkIndex(), caretInfo.getCaret());    
    506527 
     
    547568         * Used for skinning. 
    548569         */ 
    549570        public static final String DELETE_CHARACTERS = "Delete characters"; 
    550          
     571 
    551572        /** 
    552573         * Constant created for applying style. 
    553574         * Constant created to be a parameter of a message of an AutoAction.  
    554575         * Used for skinning. 
    555576         */ 
    556577        public static final String APPLY_STYLE = "Apply style"; 
    557          
     578 
    558579        /** 
    559580         * Constant created for applying paragraph style. 
    560581         * Constant created to be a parameter of a message of an AutoAction.  
    561582         * Used for skinning. 
    562583         */ 
    563584        public static final String APPLY_PARAGRAPH_STYLE = "Apply paragraph style"; 
    564          
     585 
    565586        /** 
    566587         * Constant created for inserting characters. 
    567588         * Constant created to be a parameter of a message of an AutoAction.  
     
    583604         * @return whether the Set Event is handled 
    584605         */ 
    585606        final boolean fireChangeText(EventR3 event, TextChange change, boolean isSignificant, Place place) { 
    586          
     607 
    587608                TextView source = event.getSource(TextView.class); 
    588609                TextModel textModel = source.getTextModel(); 
    589610 
     
    627648                if (place != null) { 
    628649                        addEventParam(TextView.EventIds.PLACE_PARAM_INDEX, place, fields); 
    629650                } 
    630                 return new EventR3(fields); 
     651                return new EventR3(fields); 
    631652        } 
    632653        /** 
    633654         * Creates an {@link EventR3} which sets a given text. 
     
    644665         */ 
    645666        public static EventR3 createChangeText(TextChange change, Message description, EventR3 cause, 
    646667                        boolean forceSignificance) { 
    647                  
     668 
    648669                return createTextEvent(change, description, cause,  
    649670                                forceSignificance, null, TextView.EventIds.CHANGE_TEXT_FORCED); 
    650671        } 
     
    679700                ImmTextInterval interval = new ImmTextInterval(mark, caret); 
    680701                return interval; 
    681702        } 
    682          
    683          
     703 
     704 
    684705        /** 
    685706         * Returns a <code>HotPos</code> relative to the caret of the given  
    686707         * <code>SwingTextView</code>. The relation between the caret and the new 
     
    704725 
    705726                int resultIndex = - 1; 
    706727                int resultArea = 0; 
    707                  
     728 
    708729                int textBegin = text.getBegin(); 
    709730 
    710731                if (text.getEnd() == 0) { 
    711732                        return new CaretInfo(0, -1); 
    712733                } 
    713                  
     734 
    714735                Break wordBreak = Breaks.WORD_BREAK; 
    715                  
     736 
    716737                switch (place) { 
    717738                case LEFT : 
    718739                        resultIndex = ((caret == textBegin) ?  
     
    813834                                while (end > text.getBegin() && end < text.getEnd() && text.unitAt(end).getChar() == CommonChar.PARA_BREAK) { 
    814835                                        end = ImmTextUtils.advance(text, end, -1); 
    815836                                } 
    816                                          
     837 
    817838                                resultIndex = ImmTextUtils.advance(text, textBegin, end); 
    818839                        } 
    819840                        break; 
     
    866887                } 
    867888                LogicR3.fire(new EventR3(view, null, null, null, EventIds.SELECT_VIEW, areaIndex)); 
    868889        } 
    869          
     890 
    870891        /** 
    871892         * The events fired by {@link TextModelLogic}. 
    872893         *  
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/layout/HotLayout.java

     
    1010import org.sophie2.base.model.text.model.ImmTextInterval; 
    1111import org.sophie2.base.model.text.model.ImmText; 
    1212import org.sophie2.base.model.text.model.ImmTextUtils; 
     13import org.sophie2.base.model.text.style.HotStyleDef; 
    1314 
    1415/** 
    1516 * Wrapper for a {@link HotTextLayout}, which encapsulates  
     
    3031         * Layout with no text and no areas. Used for default return values. 
    3132         */ 
    3233        public static final HotLayout EMPTY =  
    33                 HotLayout.create(ImmTextUtils.createDefaultText(), ImmTreeList.<ImmArea>empty()); 
     34                HotLayout.create(ImmTextUtils.createDefaultText(HotStyleDef.getEmpty()), 
     35                                ImmTreeList.<ImmArea>empty()); 
    3436         
    3537        private HotTextLayout layout; 
    3638 
     
    8082         *                      A new layout with these characteristics. 
    8183         */ 
    8284        public HotLayout update(ImmText text, ImmList<VisibleArea> areas) { 
    83 //              ImmText concatText = ImmTextUtils.concat(text, ImmTextUtils.createEmptyText()); 
    8485                HotLayout result = new HotLayout(this.layout.update(text, areas, LAZY_FACTOR)); 
    8586                return result; 
    8687        } 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/BaseTextModel.java

     
    224224                        ImmTextInterval interval =  
    225225                                new ImmTextInterval(caretInfo.getCaret(), caretInfo.getMarkIndex()); 
    226226 
     227                        HotStyleDef caretStyle = HotStyleDef.getEmpty(); 
     228                        ImmText rawText = getRawText(); 
     229                        if (interval.isEmpty() && interval.getEnd() > rawText.getBegin()) { 
     230                                        caretStyle = rawText.unitAt(interval.getEnd() - 1).getStyle(); 
     231                        } else if (interval.getEnd() != rawText.getEnd()){ 
     232                                caretStyle = rawText.unitAt(interval.getEnd()).getStyle(); 
     233                        } 
     234                        caretStyle = caretStyle.derive(inputStyle().get()); 
    227235                        selectionOpts = new SelectionOptions( 
    228236                                        CommonAttr.BACKGROUND_COLOR, selectionColor, interval); 
    229                         caretOpts = new CaretOptions(caretInfo.getCaret(), isEditable()); 
     237                        caretOpts = new CaretOptions(caretInfo.getCaret(), isEditable(), caretStyle); 
    230238 
    231239                } else { 
    232240                        selectionOpts = new SelectionOptions( 
    233241                                        CommonAttr.BACKGROUND_COLOR, selectionColor, new ImmTextInterval(0, 0)); 
    234                         caretOpts = new CaretOptions(0, isEditable()); 
     242                        caretOpts = new CaretOptions(0, isEditable(), inputStyle().get()); 
    235243                } 
    236244 
    237245                setOptionsInternal((TextProcessor<TextProcessorOptions, TextProcessorEffect>) 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/model/ImmTextUtils.java

     
    2727        /** 
    2828         * Creates a text with one char equal to {@link CommonChar#DOC_BREAK} 
    2929         *  
     30         * @param def  
     31         *              The style of the text. 
     32         *  
    3033         * @return 
    3134         *        Text with this char, not styled. 
    3235         */ 
    33         public static ImmText createDefaultText() { 
     36        public static ImmText createDefaultText(HotStyleDef def) { 
    3437                Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 
    3538                styleValues.put(CommonAttr.END_TEXT_ATTRIBUTE, true); 
    3639                HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 
    37                 return DEFAULT_CHAR_TEXT.applyStyle(style, 
     40                return DEFAULT_CHAR_TEXT.applyStyle(style.derive(def), 
    3841                                new ImmTextInterval(DEFAULT_CHAR_TEXT.getBegin(),  
    3942                                                DEFAULT_CHAR_TEXT.getEnd())); 
    4043        } 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/CaretProcessor.java

     
    6565        } 
    6666 
    6767        public CaretOptions getDefaultOptions() { 
    68                 return new CaretOptions(0, false ); 
     68                return new CaretOptions(0, false, HotStyleDef.getEmpty()); 
    6969        } 
    7070 
    7171        private ImmText getStyledText(ImmText sourceText, CaretOptions caretOptions) { 
    7272 
    73                 ImmText styledText = ImmTextUtils.concat(sourceText, ImmTextUtils.createDefaultText()); 
     73                HotStyleDef defaultCharDef = HotStyleDef.getEmpty(); 
     74                if (sourceText.getEnd() >= 1) { 
     75                        defaultCharDef = sourceText.unitAt(sourceText.getEnd() - 1).getStyle(); 
     76                } 
     77                defaultCharDef = defaultCharDef.derive(caretOptions.getCaretStyle()); 
     78                ImmText styledText = ImmTextUtils.concat(sourceText,  
     79                                ImmTextUtils.createDefaultText(defaultCharDef)); 
    7480                int begin = caretOptions.getCaretPos(); 
    7581                begin = begin > styledText.getEnd() ? styledText.getEnd() : begin; 
    7682                int end = begin + 1 > styledText.getEnd() ? begin : begin + 1; 
    7783                Map<HotAttr<?>, Object> caretStyleValues = new HashMap<HotAttr<?>, Object>(); 
     84                caretStyleValues.put(LayoutAttr.CARET_ATTR, 
     85                                caretOptions.isCaretVisible()); 
    7886                //TODO: fix for right-to-left 
    79                 caretStyleValues.put(LayoutAttr.CARET_ATTR, caretOptions.isCaretVisible()); 
    8087                HotStyleDef caretStyle = HotStyleDef.getEmpty().derive(caretStyleValues); 
    8188 
    8289                ImmTextInterval caretInterval = new ImmTextInterval(begin, end); 
     
    8592                assert result.getEnd() == sourceText.getEnd() + 1; 
    8693                return result; 
    8794        } 
    88  
     95         
    8996        /** 
    9097         * Class representing the options of the caret processor. 
    9198         * 
     
    94101 
    95102                private final int caretPos; 
    96103                private final boolean caretVisible; 
     104                private final HotStyleDef caretStyle; 
    97105 
    98106                /** 
    99107                 * Default constructor. 
     
    103111                 * @param isCaretVisible 
    104112                 *                True if the processor should draw the caret, 
    105113                 *                false otherwise. 
     114                 * @param caretStyle  
     115                 *                                The style of the caret(bold, italic, font-size, etc.). 
    106116                 */ 
    107                 public CaretOptions(int caretPos, boolean isCaretVisible) {  
     117                public CaretOptions(int caretPos, boolean isCaretVisible,  
     118                                HotStyleDef caretStyle) { 
    108119                        this.caretPos = caretPos; 
    109120                        this.caretVisible = isCaretVisible; 
     121                        this.caretStyle = caretStyle; 
    110122                } 
    111123 
    112124                /** 
     
    130142                        return this.caretVisible; 
    131143                } 
    132144 
     145                /** 
     146                 * Getter for the caret style values. 
     147                 *  
     148                 * @return 
     149                 *                      The caret style values. 
     150                 */ 
     151                public HotStyleDef getCaretStyle() { 
     152                        return this.caretStyle; 
     153                } 
    133154                @Override 
    134155                public int hashCode() { 
    135156                        final int prime = 31; 
    136157                        int result = 1; 
    137158                        result = prime * result + this.caretPos; 
    138159                        result = prime * result + (this.caretVisible ? 1231 : 1237); 
     160                        result = prime * result + this.caretStyle.hashCode(); 
    139161                        return result; 
    140162                } 
    141163 
     
    157179                        if (this.caretVisible != other.caretVisible) { 
    158180                                return false; 
    159181                        } 
     182                        if (! this.caretStyle.equals(other.caretStyle)) { 
     183                                return false; 
     184                        } 
    160185                        return true; 
    161186                } 
    162187        } 
  • modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/layout/HotSegmentLayout.java

     
    2929 * @author kyli 
    3030 */ 
    3131class HotSegmentLayout { 
    32  
     32         
     33        private final static int ITALICS_DISPLACEMENT = 2; 
    3334        /** 
    3435         * Layout with no text. Used to fill spaces that should stay empty. 
    3536         */ 
     
    278279                        } 
    279280                         
    280281                        if (isEditable &&  
    281                                         run.getAttrValue(LayoutAttr.CARET_ATTR) != LayoutAttr.CARET_ATTR.getDefaultValue()) { 
    282                                 Shape line = new Line2D.Double(logicalBounds.getBounds().getMinX(), logicalBounds.getBounds().y,  
    283                                                 logicalBounds.getBounds().getMinX(), logicalBounds.getBounds().y + logicalBounds.getBounds().height); 
     282                                        run.getAttrValue(LayoutAttr.CARET_ATTR) 
     283                                        != LayoutAttr.CARET_ATTR.getDefaultValue()) { 
     284                                 
     285                                Shape line; 
     286                                boolean italicsAttr = run.getAttrValue(CommonAttr.ITALIC); 
     287                                double minX = logicalBounds.getBounds().getMinX(); 
     288                                double minY = logicalBounds.getBounds().y; 
     289                                double maxY = run.getOutline().getBounds().getMaxY(); 
     290                                if (italicsAttr) { 
     291                                        line = new Line2D.Double(minX + ITALICS_DISPLACEMENT, 
     292                                                        minY, minX, maxY); 
     293                                } else {  
     294                                 line = new Line2D.Double(minX, 
     295                                                minY, minX, maxY); 
     296                                } 
    284297 
    285298                                graphics.setColor(Color.BLACK); 
    286299                                graphics.draw(line); 
     300                                graphics.fill(line); 
    287301                                ++ caretCount1; 
    288302                        } 
    289303 
    290 //                      if (isEditable && (runText.equals("" + CommonChar.DOC_BREAK) &&  
    291 //                                      (this.textRuns.size() == 1 || run.hasTabBreak())) || 
    292 //                                      (i == runsCount - 1 &&  
    293 //                                                      runText.equals("" + CommonChar.PARA_BREAK))) { 
    294 //                              Shape line = new Line2D.Double(outlineShape.getBounds().x, outlineShape.getBounds().y,  
    295 //                                              outlineShape.getBounds().x, outlineShape.getBounds().y + outlineShape.getBounds().height); 
    296 // 
    297 //                              graphics.setColor(Color.BLACK); 
    298 //                              graphics.draw(line); 
    299 //                              ++ caretCount; 
    300 //                      } 
    301304                } 
    302305 
    303306                assert caretCount + caretCount1 <= 1 : "Too many carets in the text: " 
     
    305308                graphics.dispose(); 
    306309        } 
    307310 
    308  
    309311        /** 
    310312         * Retrieves the location point of the char with the specified index  
    311313         * in the current layout.