1 19 20 package org.netbeans.editor; 21 22 import javax.swing.text.BadLocationException ; 23 import javax.swing.text.Document ; 24 25 33 34 public class MarkBlock { 35 36 40 public static final int INVALID = 0; 41 42 50 public static final int OVERLAP = 1; 51 52 59 public static final int CONTINUE = 2; 60 61 63 public static final int EMPTY = 4; 64 65 67 public static final int THIS_EMPTY = 8; 68 69 76 public static final int EXTEND = 16 | OVERLAP; 77 78 83 public static final int INSIDE = 32 | OVERLAP; 84 85 86 88 public static final int BEFORE = 64; 89 90 92 public static final int AFTER = 128; 93 94 99 public static final int CONTINUE_BEGIN = BEFORE | CONTINUE; 100 101 106 public static final int CONTINUE_END = AFTER | CONTINUE; 107 108 111 public static final int OVERLAP_BEGIN = 256 | OVERLAP; 112 113 116 public static final int OVERLAP_END = 512 | OVERLAP; 117 118 123 public static final int EXTEND_BEGIN = OVERLAP_BEGIN | EXTEND; 124 125 130 public static final int EXTEND_END = OVERLAP_END | EXTEND; 131 132 136 public static final int INCLUDE = EXTEND_BEGIN | EXTEND_END; 137 138 143 public static final int INSIDE_BEGIN = 1024 | INSIDE; 144 145 150 public static final int INSIDE_END = 2048 | INSIDE; 151 152 157 public static final int INNER = 4096 | INSIDE; 158 159 163 public static final int SAME = INSIDE_BEGIN | INSIDE_END; 164 165 166 170 public static final int IGNORE_EMPTY = ~(EMPTY | THIS_EMPTY); 171 172 173 174 protected MarkBlock next; 175 176 177 protected MarkBlock prev; 178 179 public Mark startMark; 180 181 public Mark endMark; 182 183 protected BaseDocument doc; 184 185 public MarkBlock(BaseDocument doc, Mark startMark, 186 Mark endMark) { 187 this.doc = doc; 188 this.startMark = startMark; 189 this.endMark = endMark; 190 } 191 192 193 public MarkBlock(BaseDocument doc, int startPos, int endPos) 194 throws BadLocationException { 195 this(doc, new Mark(), new Mark(), startPos, endPos); 196 } 197 198 199 public MarkBlock(BaseDocument doc, Mark startMark, 200 Mark endMark, int startPos, int endPos) 201 throws BadLocationException { 202 this(doc, startMark, endMark); 203 try { 204 startMark.insert(doc, startPos); 205 try { 206 endMark.insert(doc, endPos); 207 } catch (BadLocationException e) { 208 try { 209 startMark.remove(); 210 } catch (InvalidMarkException e2) { 211 Utilities.annotateLoggable(e2); 212 } 213 throw e; 214 } catch (InvalidMarkException e) { 215 Utilities.annotateLoggable(e); 216 } 217 } catch (InvalidMarkException e) { 218 Utilities.annotateLoggable(e); 219 } 220 } 221 222 225 public MarkBlock insertChain(MarkBlock blk) { 226 MarkBlock thisPrev = this.prev; 227 blk.prev = thisPrev; 228 blk.next = this; 229 if (thisPrev != null) { 230 thisPrev.next = blk; 231 } 232 this.prev = blk; 233 return blk; 234 } 235 236 239 public MarkBlock addChain(MarkBlock blk) { 240 if (next != null) { 241 next.insertChain(blk); 242 } else { 243 setNextChain(blk); 244 } 245 return blk; 246 } 247 248 251 public MarkBlock removeChain() { 252 MarkBlock thisNext = this.next; 253 MarkBlock thisPrev = this.prev; 254 if (thisPrev != null) { thisPrev.next = thisNext; 256 this.prev = null; 257 } 258 if (thisNext != null) { 259 thisNext.prev = thisPrev; 260 this.next = null; 261 } 262 destroyMarks(); 263 return thisNext; 264 } 265 266 272 public int compare(int startPos, int endPos) { 273 try { 274 int startThis = startMark.getOffset(); 275 int endThis = endMark.getOffset(); 276 if (startThis > endThis) { int tmp = startThis; 278 startThis = endThis; 279 endThis = tmp; 280 } 281 int ret = 0; 282 if (startPos == endPos) { if (startThis == endThis) { if (startPos < startThis) { 285 return EMPTY | THIS_EMPTY | BEFORE; 286 } else if (startPos > startThis) { 287 return EMPTY | THIS_EMPTY | AFTER; 288 } else { 289 return EMPTY | THIS_EMPTY | SAME; 290 } 291 } else { if (startPos <= startThis) { 293 return (startPos < startThis) ? (EMPTY | BEFORE) 294 : (EMPTY | INSIDE_BEGIN); 295 } else if (startPos >= endThis) { 296 return (startPos > endThis) ? (EMPTY | AFTER) 297 : (EMPTY | INSIDE_END); 298 } else { 299 return EMPTY | INNER; 300 } 301 } 302 303 } 304 if (startThis == endThis) { if (startPos >= startThis) { 306 return (startPos > startThis) ? (THIS_EMPTY | AFTER) 307 : (THIS_EMPTY | EXTEND_END); 308 } else if (endPos >= startThis) { 309 return (endPos > startThis) ? (THIS_EMPTY | BEFORE) 310 : (THIS_EMPTY | EXTEND_BEGIN); 311 } else { 312 return THIS_EMPTY | INCLUDE; 313 } 314 } 315 if (endPos <= startThis) { 317 return (endPos < startThis) ? BEFORE : CONTINUE_BEGIN; 318 } else if (startPos >= endThis) { 319 return (startPos > endThis) ? AFTER : CONTINUE_END; 320 } else { 321 if (endPos < endThis) { 322 if (startPos > startThis) { 323 return INNER; 324 } else if (startPos == startThis) { 325 return INSIDE_BEGIN; 326 } else { return OVERLAP_BEGIN; 328 } 329 } else if (endPos == endThis) { 330 if (startPos > startThis) { 331 return INSIDE_END; 332 } else if (startPos == startThis) { 333 return SAME; 334 } else { return EXTEND_BEGIN; 336 } 337 } else { if (startPos > startThis) { 339 return OVERLAP_END; 340 } else if (startPos == startThis) { 341 return EXTEND_END; 342 } else { return INCLUDE; 344 } 345 } 346 } 347 } catch (InvalidMarkException e) { 348 return INVALID; 349 } 350 } 351 352 public final MarkBlock getNext() { 353 return next; 354 } 355 356 public final void setNext(MarkBlock b) { 357 next = b; 358 } 359 360 361 public void setNextChain(MarkBlock b) { 362 this.next = b; 363 if (b != null) { 364 b.prev = this; 365 } 366 } 367 368 public final MarkBlock getPrev() { 369 return prev; 370 } 371 372 public final void setPrev(MarkBlock b) { 373 prev = b; 374 } 375 376 377 public void setPrevChain(MarkBlock b) { 378 this.prev = b; 379 if (b != null) { 380 b.next = this; 381 } 382 } 383 384 public boolean isReverse() { 385 try { 386 return (startMark.getOffset() > endMark.getOffset()); 387 } catch (InvalidMarkException e) { 388 return false; 389 } 390 } 391 392 public void reverse() { 393 Mark tmp = startMark; 394 startMark = endMark; 395 endMark = tmp; 396 } 397 398 public boolean checkReverse() { 399 if (isReverse()) { 400 reverse(); 401 return true; 402 } 403 return false; 404 } 405 406 409 public int extendStart(int startPos) throws BadLocationException { 410 try { 411 int markPos = startMark.getOffset(); 412 startPos = Math.min(startPos, markPos); 413 if (startPos != markPos) { 414 startMark.move(doc, startPos); 415 } 416 return startPos; 417 } catch (InvalidMarkException e) { 418 Utilities.annotateLoggable(e); 419 return 0; 420 } 421 } 422 423 426 public int extendEnd(int endPos) throws BadLocationException { 427 try { 428 int markPos = endMark.getOffset(); 429 endPos = Math.max(endPos, markPos); 430 if (endPos != markPos) { 431 endMark.move(doc, endPos); 432 } 433 return endPos; 434 } catch (InvalidMarkException e) { 435 Utilities.annotateLoggable(e); 436 return 0; 437 } 438 } 439 440 444 public boolean extend(int startPos, int endPos, boolean concat) throws BadLocationException { 445 try { 446 boolean extended = false; 447 int rel = compare(startPos, endPos); 448 if ((rel & OVERLAP_BEGIN) == OVERLAP_BEGIN 449 || ((rel & CONTINUE_BEGIN) == CONTINUE_BEGIN && concat) 450 ) { 451 extended = true; 452 startMark.move(doc, startPos); 453 } 454 if ((rel & OVERLAP_END) == OVERLAP_END 455 || ((rel & CONTINUE_END) == CONTINUE_END && concat) 456 ) { 457 extended = true; 458 endMark.move(doc, endPos); 459 } 460 return extended; 461 } catch (InvalidMarkException e) { 462 Utilities.annotateLoggable(e); 463 return false; 464 } 465 } 466 467 471 public boolean extend(MarkBlock blk, boolean concat) { 472 try { 473 return extend(blk.startMark.getOffset(), blk.endMark.getOffset(), concat); 474 } catch (BadLocationException e) { 475 Utilities.annotateLoggable(e); 476 } catch (InvalidMarkException e) { 477 Utilities.annotateLoggable(e); 478 } 479 return false; 480 } 481 482 492 public int shrink(int startPos, int endPos) throws BadLocationException { 493 try { 494 int rel = compare(startPos, endPos); 495 switch (rel) { 496 case OVERLAP_BEGIN: 497 case INSIDE_BEGIN: 498 startMark.move(doc, endPos); 499 break; 500 case OVERLAP_END: 501 case INSIDE_END: 502 endMark.move(doc, startPos); 503 break; 504 } 505 return rel; 506 } catch (InvalidMarkException e) { 507 Utilities.annotateLoggable(e); 508 return INVALID; 509 } 510 } 511 512 public Document getDocument() { 513 return doc; 514 } 515 516 public int getStartOffset() { 517 try { 518 return startMark.getOffset(); 519 } catch (InvalidMarkException e) { 520 return 0; 521 } 522 } 523 524 public int getEndOffset() { 525 try { 526 return endMark.getOffset(); 527 } catch (InvalidMarkException e) { 528 return 0; 529 } 530 } 531 532 533 void destroyMarks() { 534 try { 536 if (startMark != null) { 537 startMark.remove(); 538 startMark = null; 539 } 540 } catch (InvalidMarkException e) { 541 } 543 try { 544 if (endMark != null) { 545 endMark.remove(); 546 endMark = null; 547 } 548 } catch (InvalidMarkException e) { 549 } 551 } 552 553 554 protected void finalize() throws Throwable { 555 destroyMarks(); 556 super.finalize(); 557 } 558 559 560 public String toString() { 561 try { 562 return "startPos=" 563 + ((startMark != null) ? (String.valueOf(startMark.getOffset()) + '[' 565 + Utilities.debugPosition(doc, startMark.getOffset()) + ']') 566 : "null") 567 + ", endPos=" + ((endMark != null) 569 ? (String.valueOf(endMark.getOffset()) + '[' 570 + Utilities.debugPosition(doc, endMark.getOffset()) + ']') 571 : "null") + ", " + ((prev != null) ? ((next != null) ? "chain member" : "last member") : ((next != null) ? "first member" : "standalone member")); } catch (InvalidMarkException e) { 576 return ""; } 578 } 579 580 581 public String toStringChain() { 582 return toString() + ((next != null) ? ("\n" + next.toStringChain()) : ""); } 584 585 public static String debugRelation(int rel) { 586 String s = ((rel & EMPTY) != 0) ? "EMPTY | " : ""; s += ((rel & THIS_EMPTY) != 0) ? "THIS_EMPTY | " : ""; rel &= IGNORE_EMPTY; 589 switch (rel) { 590 case BEFORE: 591 return s + "BEFORE"; case AFTER: 593 return s + "AFTER"; case CONTINUE_BEGIN: 595 return s + "CONTINUE_BEGIN"; case CONTINUE_END: 597 return s + "CONTINUE_END"; case OVERLAP_BEGIN: 599 return s + "OVERLAP_BEGIN"; case OVERLAP_END: 601 return s + "OVERLAP_END"; case EXTEND_BEGIN: 603 return s + "EXTEND_BEGIN"; case EXTEND_END: 605 return s + "EXTEND_END"; case INCLUDE: 607 return s + "INCLUDE"; case INSIDE_BEGIN: 609 return s + "INSIDE_BEGIN"; case INSIDE_END: 611 return s + "INSIDE_END"; case INNER: 613 return s + "INNER"; case SAME: 615 return s + "SAME"; case INVALID: 617 return s + "INVALID"; default: 619 return s + "UNKNOWN_STATE " + rel; } 621 } 622 623 } 624 | Popular Tags |