1 22 23 package org.gjt.sp.jedit.textarea; 24 25 import java.util.ArrayList ; 27 import java.util.List ; 28 29 import org.gjt.sp.jedit.buffer.JEditBuffer; 30 import org.gjt.sp.util.StandardUtilities; 31 33 48 public abstract class Selection implements Cloneable 49 { 50 54 public int getStart() 55 { 56 return start; 57 } 59 63 public int getEnd() 64 { 65 return end; 66 } 68 77 public abstract int getStart(JEditBuffer buffer, int line); 78 80 89 public abstract int getEnd(JEditBuffer buffer, int line); 90 92 96 public int getStartLine() 97 { 98 return startLine; 99 } 101 105 public int getEndLine() 106 { 107 return endLine; 108 } 110 116 public boolean overlaps(Selection s) 117 { 118 if((start >= s.start && start <= s.end) 119 || (end >= s.start && end <= s.end)) 120 return true; 121 else 122 return false; 123 } 125 public String toString() 127 { 128 return getClass().getName() + "[start=" + start 129 + ",end=" + end + ",startLine=" + startLine 130 + ",endLine=" + endLine + ']'; 131 } 133 public Object clone() 135 { 136 try 137 { 138 return super.clone(); 139 } 140 catch(CloneNotSupportedException e) 141 { 142 throw new InternalError ("I just drank a whole " 143 + "bottle of cough syrup and I feel " 144 + "funny!"); 145 } 146 } 148 int start, end; 150 int startLine, endLine; 151 152 Selection() 154 { 155 } 157 Selection(Selection sel) 159 { 160 this.start = sel.start; 161 this.end = sel.end; 162 } 164 Selection(int start, int end) 166 { 167 this.start = start; 168 this.end = end; 169 } 171 abstract void getText(JEditBuffer buffer, StringBuffer buf); 173 abstract int setText(JEditBuffer buffer, String text); 174 175 abstract boolean contentInserted(JEditBuffer buffer, int startLine, int start, 176 int numLines, int length); 177 abstract boolean contentRemoved(JEditBuffer buffer, int startLine, int start, 178 int numLines, int length); 179 181 186 public static class Range extends Selection 187 { 188 public Range() 190 { 191 } 193 public Range(Selection sel) 195 { 196 super(sel); 197 } 199 public Range(int start, int end) 201 { 202 super(start,end); 203 } 205 public int getStart(JEditBuffer buffer, int line) 207 { 208 if(line == startLine) 209 return start; 210 else 211 return buffer.getLineStartOffset(line); 212 } 214 public int getEnd(JEditBuffer buffer, int line) 216 { 217 if(line == endLine) 218 return end; 219 else 220 return buffer.getLineEndOffset(line) - 1; 221 } 223 225 void getText(JEditBuffer buffer, StringBuffer buf) 227 { 228 buf.append(buffer.getText(start,end - start)); 229 } 231 int setText(JEditBuffer buffer, String text) 233 { 234 buffer.remove(start,end - start); 235 if(text != null && text.length() != 0) 236 { 237 buffer.insert(start,text); 238 return start + text.length(); 239 } 240 else 241 return start; 242 } 244 boolean contentInserted(JEditBuffer buffer, int startLine, int start, 246 int numLines, int length) 247 { 248 boolean changed = false; 249 250 if(this.start >= start) 251 { 252 this.start += length; 253 if(numLines != 0) 254 this.startLine = buffer.getLineOfOffset(this.start); 255 changed = true; 256 } 257 258 if(this.end >= start) 259 { 260 this.end += length; 261 if(numLines != 0) 262 this.endLine = buffer.getLineOfOffset(this.end); 263 changed = true; 264 } 265 266 return changed; 267 } 269 boolean contentRemoved(JEditBuffer buffer, int startLine, int start, 271 int numLines, int length) 272 { 273 int end = start + length; 274 boolean changed = false; 275 276 if(this.start > start && this.start <= end) 277 { 278 this.start = start; 279 changed = true; 280 } 281 else if(this.start > end) 282 { 283 this.start -= length; 284 changed = true; 285 } 286 287 if(this.end > start && this.end <= end) 288 { 289 this.end = start; 290 changed = true; 291 } 292 else if(this.end > end) 293 { 294 this.end -= length; 295 changed = true; 296 } 297 298 if(changed && numLines != 0) 299 { 300 this.startLine = buffer.getLineOfOffset(this.start); 301 this.endLine = buffer.getLineOfOffset(this.end); 302 } 303 304 return changed; 305 } 307 } 310 315 public static class Rect extends Selection 317 { 318 public Rect() 320 { 321 super(); 322 } 324 public Rect(Selection sel) 326 { 327 super(sel); 328 } 330 public Rect(int start, int end) 332 { 333 super(start,end); 334 } 336 public Rect(int startLine, int start, int endLine, int end) 338 { 339 this.startLine = startLine; 340 this.start = start; 341 this.endLine = endLine; 342 this.end = end; 343 } 345 public Rect(JEditBuffer buffer, int startLine, int startColumn, 347 int endLine, int endColumn) 348 { 349 this.startLine = startLine; 350 this.endLine = endLine; 351 352 int[] width = new int[1]; 353 int startOffset = buffer.getOffsetOfVirtualColumn(startLine, 354 startColumn,width); 355 if(startOffset == -1) 356 { 357 extraStartVirt = startColumn - width[0]; 358 startOffset = buffer.getLineEndOffset(startLine) - 1; 359 } 360 else 361 startOffset += buffer.getLineStartOffset(startLine); 362 363 int endOffset = buffer.getOffsetOfVirtualColumn(endLine, 364 endColumn,width); 365 if(endOffset == -1) 366 { 367 extraEndVirt = endColumn - width[0]; 368 endOffset = buffer.getLineEndOffset(endLine) - 1; 369 } 370 else 371 endOffset += buffer.getLineStartOffset(endLine); 372 } 374 public int getStartColumn(JEditBuffer buffer) 376 { 377 int virtColStart = buffer.getVirtualWidth(startLine, 378 start - buffer.getLineStartOffset(startLine)) + extraStartVirt; 379 int virtColEnd = buffer.getVirtualWidth(endLine, 380 end - buffer.getLineStartOffset(endLine)) + extraEndVirt; 381 return Math.min(virtColStart,virtColEnd); 382 } 384 public int getEndColumn(JEditBuffer buffer) 386 { 387 int virtColStart = buffer.getVirtualWidth(startLine, 388 start - buffer.getLineStartOffset(startLine)) + extraStartVirt; 389 int virtColEnd = buffer.getVirtualWidth(endLine, 390 end - buffer.getLineStartOffset(endLine)) + extraEndVirt; 391 return Math.max(virtColStart,virtColEnd); 392 } 394 public int getStart(JEditBuffer buffer, int line) 396 { 397 return getColumnOnOtherLine(buffer,line, 398 getStartColumn(buffer)); 399 } 401 public int getEnd(JEditBuffer buffer, int line) 403 { 404 return getColumnOnOtherLine(buffer,line, 405 getEndColumn(buffer)); 406 } 408 int extraStartVirt; 410 int extraEndVirt; 411 412 void getText(JEditBuffer buffer, StringBuffer buf) 414 { 415 int start = getStartColumn(buffer); 416 int end = getEndColumn(buffer); 417 418 for(int i = startLine; i <= endLine; i++) 419 { 420 int lineStart = buffer.getLineStartOffset(i); 421 int lineLen = buffer.getLineLength(i); 422 423 int rectStart = buffer.getOffsetOfVirtualColumn( 424 i,start,null); 425 if(rectStart == -1) 426 rectStart = lineLen; 427 428 int rectEnd = buffer.getOffsetOfVirtualColumn( 429 i,end,null); 430 if(rectEnd == -1) 431 rectEnd = lineLen; 432 433 if(rectEnd < rectStart) 434 System.err.println(i + ":::" + start + ':' + end 435 + " ==> " + rectStart + ':' + rectEnd); 436 buf.append(buffer.getText(lineStart + rectStart, 437 rectEnd - rectStart)); 438 439 if(i != endLine) 440 buf.append('\n'); 441 } 442 } 444 int setText(JEditBuffer buffer, String text) 446 { 447 int startColumn = getStartColumn(buffer); 448 int endColumn = getEndColumn(buffer); 449 450 int tabSize = buffer.getTabSize(); 451 452 int maxWidth = 0; 453 int totalLines = 0; 454 List lines = new ArrayList (); 455 456 if(text != null) 458 { 459 int lastNewline = 0; 460 int currentWidth = startColumn; 461 for(int i = 0; i < text.length(); i++) 462 { 463 char ch = text.charAt(i); 464 if(ch == '\n') 465 { 466 totalLines++; 467 lines.add(text.substring( 468 lastNewline,i)); 469 lastNewline = i + 1; 470 maxWidth = Math.max(maxWidth,currentWidth); 471 lines.add(currentWidth); 472 currentWidth = startColumn; 473 } 474 else if(ch == '\t') 475 currentWidth += tabSize - (currentWidth % tabSize); 476 else 477 currentWidth++; 478 } 479 480 if(lastNewline != text.length()) 481 { 482 totalLines++; 483 lines.add(text.substring(lastNewline)); 484 lines.add(currentWidth); 485 maxWidth = Math.max(maxWidth,currentWidth); 486 } 487 } 489 int endOffset = 0; 491 int[] total = new int[1]; 492 int lastLine = Math.max(startLine + totalLines - 1,endLine); 493 for(int i = startLine; i <= lastLine; i++) 494 { 495 if(i == buffer.getLineCount()) 496 buffer.insert(buffer.getLength(),"\n"); 497 498 int lineStart = buffer.getLineStartOffset(i); 499 int lineLen = buffer.getLineLength(i); 500 501 int rectStart = buffer.getOffsetOfVirtualColumn( 502 i,startColumn,total); 503 int startWhitespace; 504 if(rectStart == -1) 505 { 506 startWhitespace = startColumn - total[0]; 507 rectStart = lineLen; 508 } 509 else 510 startWhitespace = 0; 511 512 int rectEnd = buffer.getOffsetOfVirtualColumn( 513 i,endColumn,null); 514 if(rectEnd == -1) 515 rectEnd = lineLen; 516 517 buffer.remove(rectStart + lineStart,rectEnd - rectStart); 518 519 if(startWhitespace != 0) 520 { 521 buffer.insert(rectStart + lineStart, 522 StandardUtilities.createWhiteSpace(startWhitespace,0)); 523 } 524 525 int endWhitespace; 526 if(totalLines == 0) 527 { 528 if(rectEnd == lineLen) 529 endWhitespace = 0; 530 else 531 endWhitespace = maxWidth - startColumn; 532 } 533 else 534 { 535 int index = 2 * ((i - startLine) % totalLines); 536 String str = (String )lines.get(index); 537 buffer.insert(rectStart + lineStart + startWhitespace,str); 538 if(rectEnd == lineLen) 539 endWhitespace = 0; 540 else 541 { 542 endWhitespace = maxWidth 543 - (Integer ) lines.get(index + 1); 544 } 545 startWhitespace += str.length(); 546 } 547 548 if(endWhitespace != 0) 549 { 550 buffer.insert(rectStart + lineStart 551 + startWhitespace, 552 StandardUtilities.createWhiteSpace(endWhitespace,0)); 553 } 554 555 endOffset = rectStart + lineStart 556 + startWhitespace 557 + endWhitespace; 558 } 560 if(text == null || text.length() == 0) 562 return end; 563 else 564 return endOffset; 565 } 568 boolean contentInserted(JEditBuffer buffer, int startLine, int start, 570 int numLines, int length) 571 { 572 if(this.end < start) 573 return false; 574 575 this.end += length; 576 577 if(this.startLine > startLine) 578 { 579 this.start += length; 580 if(numLines != 0) 581 { 582 this.startLine = buffer.getLineOfOffset( 583 this.start); 584 this.endLine = buffer.getLineOfOffset( 585 this.end); 586 } 587 return true; 588 } 589 590 int endVirtualColumn = buffer.getVirtualWidth( 591 this.endLine,end 592 - buffer.getLineStartOffset(this.endLine)); 593 594 if(this.start == start) 595 { 596 int startVirtualColumn = buffer.getVirtualWidth( 597 this.startLine,start 598 - buffer.getLineStartOffset( 599 this.startLine)); 600 601 this.start += length; 602 603 int newStartVirtualColumn 604 = buffer.getVirtualWidth( 605 startLine,start - 606 buffer.getLineStartOffset( 607 this.startLine)); 608 609 int[] totalVirtualWidth = new int[1]; 610 int newEnd = buffer.getOffsetOfVirtualColumn( 611 this.endLine,endVirtualColumn + 612 newStartVirtualColumn - 613 startVirtualColumn, 614 totalVirtualWidth); 615 616 if(newEnd != -1) 617 { 618 end = buffer.getLineStartOffset( 619 this.endLine) + newEnd; 620 } 621 else 622 { 623 end = buffer.getLineEndOffset( 624 this.endLine) - 1; 625 extraEndVirt = totalVirtualWidth[0] 626 - endVirtualColumn; 627 } 628 } 629 else if(this.start > start) 630 { 631 this.start += length; 632 if(numLines != 0) 633 { 634 this.startLine = buffer.getLineOfOffset( 635 this.start); 636 } 637 } 638 639 if(numLines != 0) 640 this.endLine = buffer.getLineOfOffset(this.end); 641 int newEndVirtualColumn = buffer.getVirtualWidth( 642 endLine, 643 end - buffer.getLineStartOffset(this.endLine)); 644 if(startLine == this.endLine && extraEndVirt != 0) 645 { 646 extraEndVirt += endVirtualColumn - newEndVirtualColumn; 647 } 648 else if(startLine == this.startLine 649 && extraStartVirt != 0) 650 { 651 extraStartVirt += endVirtualColumn - newEndVirtualColumn; 652 } 653 654 return true; 655 } 657 boolean contentRemoved(JEditBuffer buffer, int startLine, int start, 659 int numLines, int length) 660 { 661 int end = start + length; 662 boolean changed = false; 663 664 if(this.start > start && this.start <= end) 665 { 666 this.start = start; 667 changed = true; 668 } 669 else if(this.start > end) 670 { 671 this.start -= length; 672 changed = true; 673 } 674 675 if(this.end > start && this.end <= end) 676 { 677 this.end = start; 678 changed = true; 679 } 680 else if(this.end > end) 681 { 682 this.end -= length; 683 changed = true; 684 } 685 686 if(changed && numLines != 0) 687 { 688 this.startLine = buffer.getLineOfOffset(this.start); 689 this.endLine = buffer.getLineOfOffset(this.end); 690 } 691 692 return changed; 693 } 695 697 699 private static int getColumnOnOtherLine(JEditBuffer buffer, int line, 701 int col) 702 { 703 int returnValue = buffer.getOffsetOfVirtualColumn( 704 line,col,null); 705 if(returnValue == -1) 706 return buffer.getLineEndOffset(line) - 1; 707 else 708 return buffer.getLineStartOffset(line) + returnValue; 709 } 711 } } 714 | Popular Tags |