Ticket #2419: 2419.patch
File 2419.patch, 17.9 KB (added by diana, 15 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
26 26 import org.sophie2.base.model.text.model.ImmTextUtils; 27 27 import org.sophie2.base.model.text.model.TextUnit; 28 28 import org.sophie2.base.model.text.model.TextUtils; 29 import org.sophie2.base.model.text.mvc.CaretProcessor.CaretOptions; 29 30 import org.sophie2.base.model.text.mvc.TextView.Place; 30 31 import org.sophie2.base.model.text.style.HotStyleDef; 31 32 import org.sophie2.base.skins.Message; … … 65 66 SophieLog.trace("FLOW_MOUSE_OPERATION.handle"); 66 67 InputEventR3 eventId = event.getEventId(InputEventR3.class); 67 68 TextView source = event.getSource(TextView.class); 68 69 69 70 boolean handle = false; 70 71 if (eventId == InputEventR3.MOUSE_PRESSED 71 72 || eventId == InputEventR3.MOUSE_DRAGGED … … 197 198 // This TextView is no longer in the flow. 198 199 return true; 199 200 } 200 201 201 202 Place place = event.getEventParam(0, Place.class); 202 203 if (place == Place.ALL) { 203 204 setSelection(source,textModel.getRawText().getBegin(), … … 235 236 //This TextView is no longer in the flow. 236 237 return true; 237 238 } 238 239 239 240 ModifierSet modifiers = 240 241 event.getEventParam(InputEventR3.MODIFIERS_PARAM_INDEX, ModifierSet.class); 241 242 char keyChar = event.getEventParam(InputEventR3.CHAR_PARAM_INDEX, … … 263 264 ImmTextInterval(caretInfo.getCaret(), caretInfo.getMarkIndex()), txtToReplaceWith); 264 265 265 266 boolean result = fireChangeText(event, change, false, Place.RIGHT); 266 267 267 268 if (result) { 268 269 textModel.inputStyle().set(HotStyleDef.getEmpty()); 269 270 } … … 305 306 } 306 307 LogicR3.fire(new EventR3(source, null, null, null, EventIds.SELECT_VIEW, areaIndex)); 307 308 } 308 309 309 310 boolean isSignificant = false; 310 311 int intervalLength = interval.getEnd() - interval.getBegin(); 311 312 if (intervalLength == 1 … … 392 393 filter.setEventId(TextView.EventIds.APPLY_STYLE); 393 394 } 394 395 396 @SuppressWarnings("unchecked") 395 397 public boolean handle(EventR3 event) { 396 398 TextView view = event.getSource(TextView.class); 397 399 TextModel textModel = view.getTextModel(); … … 403 405 if (!textModel.isEditable()) { 404 406 return true; 405 407 } 406 408 407 409 SelectionInfo caretInfo = textModel.getSelectionInfo(); 408 410 int caretPos = caretInfo.getCaret(); 409 411 int markPos = caretInfo.getMarkIndex(); … … 413 415 HotStyleDef newStyles = textModel.inputStyle().get().derive(styleValues); 414 416 if (caretPos - markPos == 0) { 415 417 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 416 426 return true; 417 427 } 418 428 … … 441 451 filter.setEventId(TextView.EventIds.APPLY_PARA_STYLE); 442 452 } 443 453 454 @SuppressWarnings("unchecked") 444 455 public boolean handle(EventR3 event) { 445 456 TextView view = event.getSource(TextView.class); 446 457 TextModel textModel = view.getTextModel(); … … 457 468 458 469 if (textModel.getRawText() != ImmTextUtils.createEmptyText()) { 459 470 List<Character> breaks = CommonChar.getEffectiveBreaks(CommonChar.PARA_BREAK); 460 471 461 472 SelectionInfo selectionInfo = textModel.getSelectionInfo(); 462 473 int caret = selectionInfo.getCaret(); 463 474 int mark = selectionInfo.getMarkIndex(); 464 475 465 476 int first = (caret <= mark ? caret : mark); 466 477 int second = (caret > mark ? caret : mark); 467 478 … … 472 483 473 484 if (selection.isEmpty()) { 474 485 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); 475 491 } 476 492 TextChange change = new TextStyleChange(selection, style); 477 493 … … 480 496 } 481 497 482 498 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); 483 504 return false; 484 505 } 485 506 }, … … 500 521 TextModel textModel = view.getTextModel(); 501 522 ImmText text = textModel.getRawText(); 502 523 SelectionInfo caretInfo = textModel.getSelectionInfo(); 503 524 504 525 ImmTextInterval selection = 505 526 new ImmTextInterval(caretInfo.getMarkIndex(), caretInfo.getCaret()); 506 527 … … 547 568 * Used for skinning. 548 569 */ 549 570 public static final String DELETE_CHARACTERS = "Delete characters"; 550 571 551 572 /** 552 573 * Constant created for applying style. 553 574 * Constant created to be a parameter of a message of an AutoAction. 554 575 * Used for skinning. 555 576 */ 556 577 public static final String APPLY_STYLE = "Apply style"; 557 578 558 579 /** 559 580 * Constant created for applying paragraph style. 560 581 * Constant created to be a parameter of a message of an AutoAction. 561 582 * Used for skinning. 562 583 */ 563 584 public static final String APPLY_PARAGRAPH_STYLE = "Apply paragraph style"; 564 585 565 586 /** 566 587 * Constant created for inserting characters. 567 588 * Constant created to be a parameter of a message of an AutoAction. … … 583 604 * @return whether the Set Event is handled 584 605 */ 585 606 final boolean fireChangeText(EventR3 event, TextChange change, boolean isSignificant, Place place) { 586 607 587 608 TextView source = event.getSource(TextView.class); 588 609 TextModel textModel = source.getTextModel(); 589 610 … … 627 648 if (place != null) { 628 649 addEventParam(TextView.EventIds.PLACE_PARAM_INDEX, place, fields); 629 650 } 630 651 return new EventR3(fields); 631 652 } 632 653 /** 633 654 * Creates an {@link EventR3} which sets a given text. … … 644 665 */ 645 666 public static EventR3 createChangeText(TextChange change, Message description, EventR3 cause, 646 667 boolean forceSignificance) { 647 668 648 669 return createTextEvent(change, description, cause, 649 670 forceSignificance, null, TextView.EventIds.CHANGE_TEXT_FORCED); 650 671 } … … 679 700 ImmTextInterval interval = new ImmTextInterval(mark, caret); 680 701 return interval; 681 702 } 682 683 703 704 684 705 /** 685 706 * Returns a <code>HotPos</code> relative to the caret of the given 686 707 * <code>SwingTextView</code>. The relation between the caret and the new … … 704 725 705 726 int resultIndex = - 1; 706 727 int resultArea = 0; 707 728 708 729 int textBegin = text.getBegin(); 709 730 710 731 if (text.getEnd() == 0) { 711 732 return new CaretInfo(0, -1); 712 733 } 713 734 714 735 Break wordBreak = Breaks.WORD_BREAK; 715 736 716 737 switch (place) { 717 738 case LEFT : 718 739 resultIndex = ((caret == textBegin) ? … … 813 834 while (end > text.getBegin() && end < text.getEnd() && text.unitAt(end).getChar() == CommonChar.PARA_BREAK) { 814 835 end = ImmTextUtils.advance(text, end, -1); 815 836 } 816 837 817 838 resultIndex = ImmTextUtils.advance(text, textBegin, end); 818 839 } 819 840 break; … … 866 887 } 867 888 LogicR3.fire(new EventR3(view, null, null, null, EventIds.SELECT_VIEW, areaIndex)); 868 889 } 869 890 870 891 /** 871 892 * The events fired by {@link TextModelLogic}. 872 893 * -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/layout/HotLayout.java
10 10 import org.sophie2.base.model.text.model.ImmTextInterval; 11 11 import org.sophie2.base.model.text.model.ImmText; 12 12 import org.sophie2.base.model.text.model.ImmTextUtils; 13 import org.sophie2.base.model.text.style.HotStyleDef; 13 14 14 15 /** 15 16 * Wrapper for a {@link HotTextLayout}, which encapsulates … … 30 31 * Layout with no text and no areas. Used for default return values. 31 32 */ 32 33 public static final HotLayout EMPTY = 33 HotLayout.create(ImmTextUtils.createDefaultText(), ImmTreeList.<ImmArea>empty()); 34 HotLayout.create(ImmTextUtils.createDefaultText(HotStyleDef.getEmpty()), 35 ImmTreeList.<ImmArea>empty()); 34 36 35 37 private HotTextLayout layout; 36 38 … … 80 82 * A new layout with these characteristics. 81 83 */ 82 84 public HotLayout update(ImmText text, ImmList<VisibleArea> areas) { 83 // ImmText concatText = ImmTextUtils.concat(text, ImmTextUtils.createEmptyText());84 85 HotLayout result = new HotLayout(this.layout.update(text, areas, LAZY_FACTOR)); 85 86 return result; 86 87 } -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/BaseTextModel.java
224 224 ImmTextInterval interval = 225 225 new ImmTextInterval(caretInfo.getCaret(), caretInfo.getMarkIndex()); 226 226 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()); 227 235 selectionOpts = new SelectionOptions( 228 236 CommonAttr.BACKGROUND_COLOR, selectionColor, interval); 229 caretOpts = new CaretOptions(caretInfo.getCaret(), isEditable() );237 caretOpts = new CaretOptions(caretInfo.getCaret(), isEditable(), caretStyle); 230 238 231 239 } else { 232 240 selectionOpts = new SelectionOptions( 233 241 CommonAttr.BACKGROUND_COLOR, selectionColor, new ImmTextInterval(0, 0)); 234 caretOpts = new CaretOptions(0, isEditable() );242 caretOpts = new CaretOptions(0, isEditable(), inputStyle().get()); 235 243 } 236 244 237 245 setOptionsInternal((TextProcessor<TextProcessorOptions, TextProcessorEffect>) -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/model/ImmTextUtils.java
27 27 /** 28 28 * Creates a text with one char equal to {@link CommonChar#DOC_BREAK} 29 29 * 30 * @param def 31 * The style of the text. 32 * 30 33 * @return 31 34 * Text with this char, not styled. 32 35 */ 33 public static ImmText createDefaultText( ) {36 public static ImmText createDefaultText(HotStyleDef def) { 34 37 Map<HotAttr<?>, Object> styleValues = new HashMap<HotAttr<?>, Object>(); 35 38 styleValues.put(CommonAttr.END_TEXT_ATTRIBUTE, true); 36 39 HotStyleDef style = HotStyleDef.getEmpty().derive(styleValues); 37 return DEFAULT_CHAR_TEXT.applyStyle(style ,40 return DEFAULT_CHAR_TEXT.applyStyle(style.derive(def), 38 41 new ImmTextInterval(DEFAULT_CHAR_TEXT.getBegin(), 39 42 DEFAULT_CHAR_TEXT.getEnd())); 40 43 } -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/CaretProcessor.java
65 65 } 66 66 67 67 public CaretOptions getDefaultOptions() { 68 return new CaretOptions(0, false 68 return new CaretOptions(0, false, HotStyleDef.getEmpty()); 69 69 } 70 70 71 71 private ImmText getStyledText(ImmText sourceText, CaretOptions caretOptions) { 72 72 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)); 74 80 int begin = caretOptions.getCaretPos(); 75 81 begin = begin > styledText.getEnd() ? styledText.getEnd() : begin; 76 82 int end = begin + 1 > styledText.getEnd() ? begin : begin + 1; 77 83 Map<HotAttr<?>, Object> caretStyleValues = new HashMap<HotAttr<?>, Object>(); 84 caretStyleValues.put(LayoutAttr.CARET_ATTR, 85 caretOptions.isCaretVisible()); 78 86 //TODO: fix for right-to-left 79 caretStyleValues.put(LayoutAttr.CARET_ATTR, caretOptions.isCaretVisible());80 87 HotStyleDef caretStyle = HotStyleDef.getEmpty().derive(caretStyleValues); 81 88 82 89 ImmTextInterval caretInterval = new ImmTextInterval(begin, end); … … 85 92 assert result.getEnd() == sourceText.getEnd() + 1; 86 93 return result; 87 94 } 88 95 89 96 /** 90 97 * Class representing the options of the caret processor. 91 98 * … … 94 101 95 102 private final int caretPos; 96 103 private final boolean caretVisible; 104 private final HotStyleDef caretStyle; 97 105 98 106 /** 99 107 * Default constructor. … … 103 111 * @param isCaretVisible 104 112 * True if the processor should draw the caret, 105 113 * false otherwise. 114 * @param caretStyle 115 * The style of the caret(bold, italic, font-size, etc.). 106 116 */ 107 public CaretOptions(int caretPos, boolean isCaretVisible) { 117 public CaretOptions(int caretPos, boolean isCaretVisible, 118 HotStyleDef caretStyle) { 108 119 this.caretPos = caretPos; 109 120 this.caretVisible = isCaretVisible; 121 this.caretStyle = caretStyle; 110 122 } 111 123 112 124 /** … … 130 142 return this.caretVisible; 131 143 } 132 144 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 } 133 154 @Override 134 155 public int hashCode() { 135 156 final int prime = 31; 136 157 int result = 1; 137 158 result = prime * result + this.caretPos; 138 159 result = prime * result + (this.caretVisible ? 1231 : 1237); 160 result = prime * result + this.caretStyle.hashCode(); 139 161 return result; 140 162 } 141 163 … … 157 179 if (this.caretVisible != other.caretVisible) { 158 180 return false; 159 181 } 182 if (! this.caretStyle.equals(other.caretStyle)) { 183 return false; 184 } 160 185 return true; 161 186 } 162 187 } -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/layout/HotSegmentLayout.java
29 29 * @author kyli 30 30 */ 31 31 class HotSegmentLayout { 32 32 33 private final static int ITALICS_DISPLACEMENT = 2; 33 34 /** 34 35 * Layout with no text. Used to fill spaces that should stay empty. 35 36 */ … … 278 279 } 279 280 280 281 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 } 284 297 285 298 graphics.setColor(Color.BLACK); 286 299 graphics.draw(line); 300 graphics.fill(line); 287 301 ++ caretCount1; 288 302 } 289 303 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 // }301 304 } 302 305 303 306 assert caretCount + caretCount1 <= 1 : "Too many carets in the text: " … … 305 308 graphics.dispose(); 306 309 } 307 310 308 309 311 /** 310 312 * Retrieves the location point of the char with the specified index 311 313 * in the current layout.