Ticket #2269: 2269.patch
File 2269.patch, 25.8 KB (added by diana, 15 years ago) |
---|
-
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/smart/ImmHotText.java
### Eclipse Workspace Patch 1.0 #P sophie
32 32 */ 33 33 @Immutable(kind="hot-text") 34 34 public final class ImmHotText { 35 35 36 36 private static long ID_BASE = 1000000; 37 37 private ImmList<Character> chars; 38 38 private final long uid; 39 39 private final ImmHotText prevText; 40 40 private final ElemOp lastOperation; 41 42 43 41 private final HotIndexInterval subSingleInterval; 42 private final HotInterval lastChangedInterval; 43 44 44 private ImmMap<HotAttr<?>, StyleValueSet<?>> styleValues = new ImmTreeMap<HotAttr<?>, StyleValueSet<?>>( 45 45 new ImmHashingTree<ImmEntry<HotAttr<?>, StyleValueSet<?>>>(), getAttrComparator()); 46 46 47 47 private ImmMap<HotInterval, Attachment> attachments = new ImmTreeMap<HotInterval, Attachment>( 48 48 new ImmHashingTree<ImmEntry<HotInterval, Attachment>>(), getIntervalComparator()); 49 49 50 50 // Caching 51 51 private Hash styledHash = null; 52 52 private AttributedString attrString = null; 53 53 54 54 // Constructors. For internal use only. 55 55 // Factory methods should be used for creation of text 56 56 // from the client code 57 57 private ImmHotText(ImmList<Character> text, ImmMap<HotAttr<?>, StyleValueSet<?>> styleValues, ImmHotText prev, ElemOp lastOp, 58 58 HotIndexInterval subSingleInterval, ImmMap<HotInterval, Attachment> attachments, AttributedString attrString) { 59 59 this(text, styleValues, prev, lastOp, subSingleInterval, attachments, null, attrString); 60 60 61 61 } 62 62 63 63 private ImmHotText(ImmList<Character> text, ImmMap<HotAttr<?>, StyleValueSet<?>> styleValues, ImmHotText prev, ElemOp lastOp, 64 64 HotIndexInterval subSingleInterval, ImmMap<HotInterval, Attachment> attachments, HotInterval lastChangedInterval, AttributedString attrString) { 65 65 this(text, styleValues, prev, lastOp, subSingleInterval, generateId(), lastChangedInterval, attachments, attrString); 66 66 } 67 68 67 68 69 69 private ImmHotText(ImmList<Character> text, ImmMap<HotAttr<?>, StyleValueSet<?>> styleValues, ImmHotText prev, ElemOp lastOp, 70 70 HotIndexInterval subSingleInterval, long uid, HotInterval lastChangedInterval, ImmMap<HotInterval, Attachment> attachments, AttributedString attrString) { 71 71 this.chars = text; … … 73 73 if (uid > ID_BASE) { 74 74 ID_BASE = uid; 75 75 } 76 76 77 77 this.prevText = prev; 78 78 this.lastOperation = lastOp; 79 80 81 82 lastChangedInterval.getEnd().normalize(this));79 this.subSingleInterval = subSingleInterval; 80 this.lastChangedInterval = (lastChangedInterval == null) ? null : 81 new HotInterval(lastChangedInterval.getBegin().normalize(this), 82 lastChangedInterval.getEnd().normalize(this)); 83 83 if (styleValues != null) { 84 84 this.styleValues = styleValues; 85 85 } 86 86 if (attachments != null) { 87 87 this.attachments = attachments; 88 88 } 89 89 90 90 // This should be performance effective. 91 91 if (attrString != null) { 92 92 this.attrString = attrString; … … 99 99 @SuppressWarnings("unchecked") 100 100 private ImmHotText(String text, HotStyleDef style) { 101 101 assert text != null : "Text must be not null."; 102 102 103 103 this.chars = new ImmTreeList<Character>(new ImmHashingTree<Character>()); 104 104 105 105 for (char ch : text.toCharArray()) { 106 106 this.chars = this.chars.add(this.chars.size(), ch); 107 107 } 108 108 this.subSingleInterval = new HotIndexInterval(0 , this.chars.size()); 109 109 this.lastChangedInterval = null; 110 110 this.uid = generateId(); 111 111 112 112 if (style != null) { 113 113 for (HotAttr<?> key : style.getAttributeKeys()) { 114 114 StyleValueSet<Object> valueSet = (StyleValueSet<Object>) 115 115 StyleValueSet.create(key, getPosComparator()); 116 116 valueSet = valueSet.setValue( 117 117 changePosKind(getBegin(), HotPosKind.AFTER), 118 118 changePosKind(getEnd(), HotPosKind.BEFORE), … … 124 124 125 125 this.prevText = null; 126 126 this.lastOperation = null; 127 127 128 128 // If you remove this line, every sub-text of this one will generate its own AttributedString.. 129 129 // this is a slow operation on large texts. 130 130 this.attrString = StyleUtils.getAttributedString( … … 137 137 } 138 138 139 139 // Factory methods for creation of ImmHotText. 140 140 141 141 /** 142 142 * Factory method for creation of a styled text. 143 143 * … … 167 167 public static ImmHotText empty() { 168 168 return new ImmHotText("", null); 169 169 } 170 170 171 171 /** 172 172 * Factory method for creation of text by its internals. 173 173 * Needed by persistence. … … 190 190 } 191 191 192 192 // Edition operations 193 193 194 194 /** 195 195 * Applies the specified style to the range of text, defined by 196 196 * the specified interval of {@link HotPos}es. The new style values … … 207 207 HotPos begin = orderInterval.getBegin(); 208 208 HotPos end = orderInterval.getEnd(); 209 209 begin = begin.equals(end) 210 210 ? changePosKind(begin, HotPosKind.AFTER) 211 211 : changePosKind(begin, HotPosKind.BEFORE); 212 212 end = changePosKind(end, HotPosKind.BEFORE); 213 213 214 214 ImmMap<HotAttr<?>, StyleValueSet<?>> newStyleValues = this.styleValues; 215 215 for (HotAttr<?> key : style.getAttributeKeys()) { 216 216 StyleValueSet<Object> valueSet = (StyleValueSet<Object>) 217 218 217 (newStyleValues.contains(key) ? newStyleValues.get(key) 218 : StyleValueSet.create(key, getPosComparator())); 219 219 valueSet = valueSet.setValue(begin, end, style.getValue(key)); 220 220 221 221 newStyleValues = newStyleValues.put(key, valueSet); … … 224 224 // TODO consider re-using the attributed string. 225 225 return new ImmHotText(this.chars, newStyleValues, this, lastOp, this.subSingleInterval, this.attachments, null); 226 226 } 227 227 228 228 @SuppressWarnings("unchecked") 229 229 private ImmHotText applyStyles(ImmHotText insertText, HotPos beginPos) { 230 230 int beginIndex = getIndex(beginPos) + HotPosKind.getRelativeIndex(this.subSingleInterval.getBegin()); … … 233 233 for (ImmEntry<HotAttr<?>, StyleValueSet<?>> entry : insertText.getStyleValues()) { 234 234 HotAttr<?> key = entry.getKey(); 235 235 StyleValueSet<Object> valueSet = (StyleValueSet<Object>) 236 236 insertText.getStyleValues().get(key); 237 237 StyleValueSet<Object> newValueSet = this.styleValues.contains(key) 238 239 238 ? StyleValueSet.create((HotAttr)key, getPosComparator(), 239 this.styleValues.get(key).getValueSet()) 240 240 : (StyleValueSet<Object>)StyleValueSet.create(key, getPosComparator()); 241 241 242 242 HotPos prevPos = null; … … 247 247 continue; 248 248 } 249 249 int intervalStart = HotPosKind.getIndexForKind(beginIndex, prevPos.getKind()) + 250 251 250 insertText.getIndex(prevPos) - insertText.getIndex( 251 changePosKind(insertText.getBegin(), prevPos.getKind())); 252 252 int intervalEnd = HotPosKind.getIndexForKind(beginIndex, pos.getKind()) + 253 254 253 insertText.getIndex(pos) - insertText.getIndex( 254 changePosKind(insertText.getBegin(), pos.getKind())); 255 255 256 256 Object value = valueSet.getValue(prevPos); 257 257 newValueSet = newValueSet.setValue(getPos(intervalStart), getPos(intervalEnd), value); 258 258 prevPos = pos; 259 259 } 260 260 261 261 newStyleValues = newStyleValues.put(key, newValueSet); 262 262 } 263 263 264 264 return new ImmHotText(this.chars, newStyleValues, this.prevText, this.lastOperation, 265 265 this.subSingleInterval, this.uid, null, this.attachments, null); 266 266 } … … 274 274 * @param insertText The new styled text that should be inserted. 275 275 * @return A new text with replaced text range. 276 276 */ 277 @SuppressWarnings("unchecked") 277 278 public ImmHotText replace(HotInterval interval, ImmHotText insertText) { 278 279 int beginIndex = getIndex(interval.getBegin()); 279 280 int endIndex = getIndex(interval.getEnd()); 280 281 282 ImmMap<HotAttr<?>, StyleValueSet<?>> newInsStyleValues = insertText.getStyleValues(); 283 //-------------------- 284 if(getPosComparator().compare(interval.getBegin(), interval.getEnd()) != 0) { 285 for (ImmEntry<HotAttr<?>, StyleValueSet<?>> entry : this.styleValues) { 286 HotAttr<?> key = entry.getKey(); 287 StyleValueSet<Object> valueSet = (StyleValueSet<Object>) 288 this.styleValues.get(key); 289 StyleValueSet<Object> newValueSet = insertText.getStyleValues().contains(key) 290 ? StyleValueSet.create((HotAttr)key, getPosComparator(), 291 insertText.getStyleValues().get(key).getValueSet()) 292 : (StyleValueSet<Object>)StyleValueSet.create(key, getPosComparator()); 293 294 HotPos prevPos = null; 295 for (HotStyleValue<Object> styleValue : valueSet.getValueSet()) { 296 HotPos pos = styleValue.getPos(); 297 if (prevPos == null) { 298 prevPos = pos; 299 continue; 300 } 301 302 HotInterval newInterval = new HotInterval(interval.getBegin(), 303 advance(interval.getBegin(), 1)); 304 if(getPosComparator().compare(interval.getBegin(), interval.getEnd()) > 0) { 305 newInterval = new HotInterval(interval.getEnd(), 306 advance(interval.getEnd(), 1)); 307 } 308 Object value = this.getStyleValue(key, newInterval); 309 int intervalStart = HotPosKind.getIndexForKind(insertText.subSingleInterval.getBegin(), prevPos.getKind()); 310 int intervalEnd = HotPosKind.getIndexForKind(insertText.subSingleInterval.getEnd(), pos.getKind()); 311 if(intervalStart > intervalEnd) { 312 int temp = intervalEnd; 313 intervalEnd = intervalStart; 314 intervalStart = temp; 315 } 316 newValueSet = newValueSet.setValue(insertText.getPos(intervalStart), insertText.getPos(intervalEnd), value); 317 prevPos = pos; 318 } 319 320 newInsStyleValues = newInsStyleValues.put(key, newValueSet); 321 } 322 } 323 //-------------------- 324 281 325 // new text 282 326 ImmList<Character> newText = this.chars; 283 327 int index = HotPosKind.getRealIndex(getIndex(interval.getBegin())); 284 328 285 329 int i = index; 286 330 for (; i < Math.min( 287 331 HotPosKind.getRealIndex(endIndex), getLength()); ++i) { … … 298 342 elemOp = new ElemOp.DeleteOp(beginIndex, endIndex); 299 343 } 300 344 int insertLength = HotPosKind.getRelativeIndex(insertText.getLength()); 301 345 302 346 if (insertLength > 0) { 303 347 ElemOp.InsertOp insOp = new ElemOp.InsertOp(beginIndex, insertLength); 304 348 if (elemOp == null) { … … 307 351 elemOp = new ElemOp.ReplaceOp((ElemOp.DeleteOp)elemOp, insOp); 308 352 } 309 353 } 310 354 311 355 if (elemOp == null) { 312 356 elemOp = new ElemOp.NoOp(endIndex, endIndex); 313 357 } … … 315 359 HotIndexInterval newSingleInterval = new HotIndexInterval( 316 360 this.subSingleInterval.getBegin(), this.subSingleInterval.getEnd() 317 361 + insertText.getLength() - length); 318 319 362 ImmHotText newHotText = new ImmHotText(newText, this.styleValues, this, elemOp,newSingleInterval, this.attachments, null); 320 321 return newHotText.applyStyles(insertText, interval.getBegin()); 363 364 ElemOp lastInsOp = new ElemOp.NoOp(getIndex(interval.getBegin()), getIndex(interval.getEnd())); 365 ImmHotText newInsHotText = new ImmHotText(insertText.chars, newInsStyleValues, insertText, lastInsOp, 366 insertText.subSingleInterval, insertText.attachments, null); 367 return newHotText.applyStyles(newInsHotText, interval.getBegin()); 322 368 } 323 369 324 370 /** … … 328 374 * @return A new styled text, that is a sub text of the current one. 329 375 */ 330 376 public ImmHotText subText(HotInterval interval) { 331 332 333 377 HotIndexInterval newSingleInterval = new HotIndexInterval( 378 HotPosKind.getRealIndex(getIndex(interval.getBegin())), 379 HotPosKind.getRealIndex(getIndex(interval.getEnd()))); 334 380 return new ImmHotText(this.chars, this.styleValues, this.prevText, 335 381 this.lastOperation, newSingleInterval, this.uid, 336 382 this.lastChangedInterval, this.attachments, this.attrString); … … 352 398 353 399 // last operation 354 400 ElemOp elemOp = new ElemOp.InsertOp(beginIndex, HotPosKind.getRelativeIndex(1)); 355 401 HotIndexInterval newInterval = new HotIndexInterval(this.subSingleInterval.getBegin(),this.subSingleInterval.getEnd() + 1); 356 402 ImmHotText newHotText = new ImmHotText(newText, this.styleValues, this, elemOp, newInterval, this.attachments, null); 357 403 return newHotText.applyStyles(ImmHotText.createPlain(String.valueOf(ch)), pos); 358 404 } … … 361 407 return this.chars.subList(this.subSingleInterval.getBegin(), 362 408 this.subSingleInterval.getEnd()); 363 409 } 364 410 365 411 // Getters and conversion operations. 366 412 367 413 /** 368 414 * Retrieves the number of characters of the current text. 369 415 * … … 371 417 */ 372 418 public int getLength() { 373 419 return this.subSingleInterval.getEnd() 374 420 - this.subSingleInterval.getBegin(); 375 421 } 376 422 377 423 /** 378 424 * Retrieves the style value of the specified attribute at the 379 425 * given {@link HotInterval} of the current text. If the whole interval … … 390 436 public <T> T getStyleValue(HotAttr<T> attribute, HotInterval interval) { 391 437 if (this.styleValues.contains(attribute)) { 392 438 StyleValueSet<T> valueMap = (StyleValueSet<T>) 393 394 439 this.styleValues.get(attribute); 440 395 441 HotInterval orderedInterval = IntervalUtility.orderAscending( 396 442 interval, getPosComparator()); 397 443 HotPos begin = orderedInterval.getBegin(); 398 444 HotPos end = orderedInterval.getEnd(); 399 445 begin = begin.equals(end) 400 446 ? changePosKind(begin, HotPosKind.AFTER) 401 447 : changePosKind(begin, HotPosKind.BEFORE); 402 448 end = changePosKind(end, HotPosKind.BEFORE); 403 449 404 450 HotPos currentPos = changePosKind(begin, HotPosKind.MIDDLE); 405 451 T beginValue = valueMap.getValue(begin); 406 452 while(getPosComparator().compare(currentPos, orderedInterval.getEnd()) < 0 && … … 411 457 } 412 458 currentPos = advance(currentPos, 1); 413 459 } 414 460 415 461 if (beginValue != null) { 416 462 return beginValue; 417 463 } 418 464 } 419 465 return attribute.getDefaultValue(); 420 466 } 421 467 422 468 /** 423 469 * Retrieves the style value of the specified attribute at the given 424 470 * {@link HotPos} of the current text. If the attribute has no value defined … … 448 494 } 449 495 return attribute.getDefaultValue(); 450 496 } 451 497 452 498 /** 453 499 * Adds a new attachment to this text. 454 500 * … … 466 512 key = interval.reverse(); 467 513 } 468 514 ImmMap<HotInterval, Attachment> newAtt = this.attachments.put(key, attachment); 469 515 470 516 ElemOp lastOp = new ElemOp.NoOp(this.getIndex(interval.getBegin()), 471 517 this.getIndex(interval.getEnd())); 472 518 473 519 return new ImmHotText(this.chars, this.styleValues, this, lastOp, 474 520 this.subSingleInterval, generateId(), null, newAtt, this.attrString); 475 521 } 476 522 477 523 /** 478 524 * Removes from this text the attachments associated with the given interval. 479 525 * If there are no such attachments, returns the same text. … … 488 534 if(getPosComparator().compare(interval.getBegin(), interval.getEnd()) > 0) { 489 535 key = interval.reverse(); 490 536 } 491 537 492 538 if (!this.attachments.contains(key)) { 493 539 return this; 494 540 } 495 541 496 542 ImmMap<HotInterval, Attachment> newAtt = this.attachments.remove(key); 497 543 498 544 ElemOp lastOp = new ElemOp.NoOp(getIndex(interval.getBegin()), 499 545 getIndex(interval.getEnd())); 500 546 501 547 return new ImmHotText(this.chars, this.styleValues, this, lastOp, 502 548 this.subSingleInterval, generateId(), null, newAtt, this.attrString); 503 549 } 504 550 505 551 /** 506 552 * Gets a map associating the attachments of this text to {@link HotInterval}s. 507 553 * … … 511 557 public ImmMap<HotInterval, Attachment> getAttachments() { 512 558 return this.attachments; 513 559 } 514 560 515 561 /** 516 562 * Retrieves the style values of the current text. For internal 517 563 * use only - needed for testing purposes. 518 564 * 519 565 * @return The current text's style values. 520 566 */ 521 567 ImmMap<HotAttr<?>, StyleValueSet<?>> getStyleValues() { 522 568 return this.styleValues; 523 569 } 524 570 525 571 /** 526 572 * Transforms the styleValues of the current text to a map 527 573 * with new poses that belong to the current text. Used for persistence. … … 532 578 ImmMap<HotAttr<?>,StyleValueSet<?>> getNormalizedStyleValues() { 533 579 ImmMap<HotAttr<?>,StyleValueSet<?>> newValueImmMap = new ImmTreeMap<HotAttr<?>, StyleValueSet<?>>( 534 580 new ImmHashingTree<ImmEntry<HotAttr<?>, StyleValueSet<?>>>(), getAttrComparator()); 535 581 536 582 for (ImmEntry<HotAttr<?>, StyleValueSet<?>> entry : this.getStyleValues()) { 537 583 HotAttr<?> key = entry.getKey(); 538 584 StyleValueSet<Object> valueMap = (StyleValueSet<Object>) 539 585 this.styleValues.get(key); 540 586 StyleValueSet<Object> newValueMap = (StyleValueSet<Object>)StyleValueSet.create(key, getPosComparator()); 541 587 542 588 HotPos prevPos = null; … … 555 601 prevPos = pos; 556 602 continue; 557 603 } 558 559 560 561 562 563 604 HotPos firstPos = getPos(HotPosKind.getIndexForKind 605 (HotPosKind.getRelativeIndex 606 (getRealIndex(prevPos)),prevPos.getKind())); 607 HotPos secondPos = getPos(HotPosKind.getIndexForKind 608 (HotPosKind.getRelativeIndex 609 (getRealIndex(pos)),pos.getKind())); 564 610 Object value = valueMap.getValue(prevPos); 565 611 newValueMap = newValueMap.setValue(firstPos, secondPos, value); 566 612 prevPos = pos; 567 613 } 568 614 569 615 newValueImmMap = newValueImmMap.put(key, newValueMap); 570 616 } 571 617 572 618 return newValueImmMap; 573 619 } 574 620 … … 707 753 } 708 754 res = index; 709 755 } 710 // int begin = HotPosKind.getIndexForKind(HotPosKind.getRelativeIndex(0), pos.getKind());711 // int end = HotPosKind.getIndexForKind(HotPosKind.getRelativeIndex(this.chars.size()), pos.getKind());712 // if (res < begin) {713 // System.out.println("Begin: " + this);714 // }715 // assert res >= begin : "Invalid index: " + res + ", expected > " + begin;716 //717 // if (HotPosKind.getRealIndex(res) < this.subSingleInterval.getBegin()) {718 // res -= 4;719 // }720 // if (res > end) {721 // System.out.println("End: " + this);722 // }723 // assert res <= end : "Invalid index: " + res + ", expected < " + end;756 // int begin = HotPosKind.getIndexForKind(HotPosKind.getRelativeIndex(0), pos.getKind()); 757 // int end = HotPosKind.getIndexForKind(HotPosKind.getRelativeIndex(this.chars.size()), pos.getKind()); 758 // if (res < begin) { 759 // System.out.println("Begin: " + this); 760 // } 761 // assert res >= begin : "Invalid index: " + res + ", expected > " + begin; 762 // 763 // if (HotPosKind.getRealIndex(res) < this.subSingleInterval.getBegin()) { 764 // res -= 4; 765 // } 766 // if (res > end) { 767 // System.out.println("End: " + this); 768 // } 769 // assert res <= end : "Invalid index: " + res + ", expected < " + end; 724 770 725 771 return res; 726 772 } … … 735 781 */ 736 782 int getRealIndex(HotPos pos) { 737 783 return HotPosKind.getRealIndex(getIndex(pos)) 738 784 - this.subSingleInterval.getBegin(); 739 785 } 740 786 741 787 /** 742 788 * Retrieves the {@link HotPos} relative to the specified index with the appropriate kind. 743 789 * Note that the input index is a custom index for internal use only and is not the real … … 763 809 */ 764 810 HotPos getRealPos(int index) { 765 811 int relativeIndex = HotPosKind.getIndexForKind( 766 HotPosKind.getRelativeIndex(index), HotPosKind.MIDDLE);812 HotPosKind.getRelativeIndex(index), HotPosKind.MIDDLE); 767 813 return new HotPos(relativeIndex + HotPosKind.getRelativeIndex( 768 814 this.subSingleInterval.getBegin()), this); 769 815 } 770 816 771 817 private HotPos changePosKind(HotPos pos, HotPosKind kind) { 772 818 return getPos(HotPosKind.getIndexForKind(getIndex(pos), kind)); 773 819 } 774 820 775 821 // Navigation operations. 776 822 777 823 /** … … 787 833 public HotPos advance(HotPos from, int offset) { 788 834 if (!hasPosition(from)) { 789 835 throw new IllegalArgumentException("The input position does not " + 790 836 "belong to the current text"); 791 837 } 792 838 int index = getIndex(from) + HotPosKind.getRelativeIndex(offset); 793 839 if (getIndex(changePosKind(getBegin(), from.getKind())) <= index && … … 796 842 } 797 843 798 844 throw new IllegalArgumentException("The wanted position does not " + 799 845 "belong to the current text"); 800 846 } 801 847 802 848 /** … … 832 878 assert pos.getKind() == HotPosKind.MIDDLE; 833 879 return this.chars.get(TextUtils.getIndex(this, pos) + this.subSingleInterval.getBegin() - 1); 834 880 } 835 881 836 882 /** 837 883 * Retrieves the character after the specified position in 838 884 * the current text. … … 883 929 public boolean hasPosition(HotPos pos) { 884 930 Comparator<HotPos> posComparator = getPosComparator(); 885 931 return posComparator.compare(getBegin(), pos) <= 0 886 932 && posComparator.compare(pos, getEnd()) <= 0; 887 933 } 888 934 889 935 /** 890 936 * Retrieves the interval of positions of the last operation 891 937 * that lead to the creation of the current {@link ImmHotText}. … … 898 944 if (this.lastOperation == null) { 899 945 return this.lastChangedInterval; 900 946 } 901 947 902 948 HotIndexInterval indexInterval = this.lastOperation.getChangedInterval(); 903 949 return new HotInterval(getPos(indexInterval.getBegin()), 904 950 getPos(indexInterval.getEnd())); … … 919 965 } 920 966 }; 921 967 } 922 968 923 969 /** 924 970 * Retrieves a comparator for two styling attributes. 925 971 * The {@link HotAttr} objects are compared by string ID. … … 1119 1165 private static class NoOp extends ElemOp { 1120 1166 private int begin; 1121 1167 private int end; 1122 1168 1123 1169 public NoOp(int begin, int end) { 1124 1170 this.begin = begin; 1125 1171 this.end = end; 1126 1172 } 1127 1173 1128 1174 @Override 1129 1175 public int updatePastIndex(int oldIndex) { 1130 1176 return oldIndex; … … 1141 1187 } 1142 1188 } 1143 1189 } 1144 1145 /** 1146 * Checks whether this text has the same ID as the passed one, 1147 * or this text's parent has. 1148 * 1149 * @param parentText 1150 * The text this one should come from. 1151 * @return 1152 * True if this text is the same, sub-text or result of an 1153 * {@link ElemOp} over the parent, false otherwise. 1154 */ 1155 public boolean derivesFrom(ImmHotText parentText) { 1156 if (parentText == null) { 1157 return false; 1158 } 1159 1160 boolean res = false; 1161 res = res || ((this.prevText != null) && (parentText.getId() == this.prevText.getId())); 1162 res = res || (parentText.getId() == getId()); 1163 1164 return res; 1190 1191 /** 1192 * Checks whether this text has the same ID as the passed one, 1193 * or this text's parent has. 1194 * 1195 * @param parentText 1196 * The text this one should come from. 1197 * @return 1198 * True if this text is the same, sub-text or result of an 1199 * {@link ElemOp} over the parent, false otherwise. 1200 */ 1201 public boolean derivesFrom(ImmHotText parentText) { 1202 if (parentText == null) { 1203 return false; 1165 1204 } 1166 1205 1206 boolean res = false; 1207 res = res || ((this.prevText != null) && (parentText.getId() == this.prevText.getId())); 1208 res = res || (parentText.getId() == getId()); 1209 1210 return res; 1211 } 1212 1167 1213 } -
modules/org.sophie2.main.func.text/src/main/java/org/sophie2/main/func/text/view/HotTextLogic.java
363 363 HotInterval interval = getSelectionEnds(flow); 364 364 assert interval != null; 365 365 366 ImmHotText newText = text.replace(interval, textToInsert); 366 367 ImmHotText newText = text.replace(interval, ImmHotText.empty()); 368 newText = newText.replace(new HotInterval(interval.getBegin(), 369 interval.getBegin()), textToInsert); 367 370 boolean handled = LogicR3.fire(TextFlowLogic.createSetTextEvent(newText, 368 371 "Insert text", event)); 369 372 -
modules/org.sophie2.base.model.text/src/main/java/org/sophie2/base/model/text/mvc/TextFlowLogic.java
456 456 457 457 HotInterval interval = getSelectionEnds(flow); 458 458 assert interval != null; 459 460 459 ImmHotText newText = immHotText.replace(interval, ImmHotText 461 460 .createPlain(text)); 462 461