Changeset 1102 for trunk/src/org/expeditee/gui/FrameKeyboardActions.java
- Timestamp:
- 05/10/18 16:04:51 (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/expeditee/gui/FrameKeyboardActions.java
r1077 r1102 19 19 package org.expeditee.gui; 20 20 21 import java.awt.Color;22 import java.awt.Rectangle;23 21 import java.awt.Toolkit; 24 22 import java.awt.datatransfer.StringSelection; 25 23 import java.awt.event.KeyEvent; 26 24 import java.awt.event.KeyListener; 27 import java.awt.geom.Point2D;28 25 import java.text.NumberFormat; 29 26 import java.util.ArrayList; … … 37 34 import org.expeditee.actions.Navigation; 38 35 import org.expeditee.actions.Simple; 36 import org.expeditee.core.AxisAlignedBoxBounds; 37 import org.expeditee.core.Colour; 38 import org.expeditee.core.Point; 39 39 import org.expeditee.gui.indirect.keyboard.IndirectKeyboardActions; 40 40 import org.expeditee.gui.indirect.keyboard.KeyboardAction; … … 51 51 import org.expeditee.items.XRayable; 52 52 import org.expeditee.items.MagneticConstraint.MagneticConstraints; 53 import org.expeditee.items.widgets.InteractiveWidget; 53 /*import org.expeditee.items.widgets.InteractiveWidget; TODO: Reinstate. cts16 54 54 import org.expeditee.items.widgets.WidgetCorner; 55 import org.expeditee.items.widgets.WidgetEdge; 55 import org.expeditee.items.widgets.WidgetEdge;*/ 56 56 import org.expeditee.settings.experimental.ExperimentalFeatures; 57 57 import org.expeditee.settings.templates.TemplateSettings; … … 60 60 import org.expeditee.stats.SessionStats; 61 61 62 public class FrameKeyboardActions implements KeyListener{62 public class FrameKeyboardActions { 63 63 64 64 private static FrameKeyboardActions _instance = new FrameKeyboardActions(); 65 65 66 66 protected FrameKeyboardActions() { 67 IndirectKeyboardActions.getInstance().setDropDownAction(67 /*IndirectKeyboardActions.getInstance().setDropDownAction( 68 68 new KeyboardAction() { 69 69 @Override … … 82 82 } else { 83 83 // Move to the top of the box 84 Rectangle rect = info.firstConnected 85 .getEnclosedShape().getBounds(); 86 int newX = rect.x + Text.MARGIN_LEFT; 84 AxisAlignedBoxBounds rect = info.firstConnected.getBounds(); 85 int newX = rect.getMinX() + Text.MARGIN_LEFT; 87 86 int newY = Text.MARGIN_LEFT 88 + rect. y87 + rect.getMinY() 89 88 + DisplayIO.getCurrentFrame() 90 89 .getItemTemplate() … … 171 170 return null; 172 171 } 173 }); 172 });*/ 174 173 IndirectKeyboardActions.getInstance().setCreateNewTextAction( 175 174 new KeyboardAction() { … … 179 178 "" + c); 180 179 181 Point2D.Float newMouse = t.insertChar(c, 182 DisplayIO.getMouseX(), FrameMouseActions.getY()); 183 DisplayIO.setCursorPosition(newMouse.x, newMouse.y, 184 false); 180 Point newMouse = t.insertChar(c, DisplayIO.getMouseX(), FrameMouseActions.getY()); 181 DisplayIO.setCursorPosition(newMouse.x, newMouse.y, false); 185 182 186 183 return t; … … 192 189 public Text exec(final KeyboardInfo info, final char c) { 193 190 float oldY = FrameMouseActions.MouseY; 194 Point 2D.FloatnewMouse = null;191 Point newMouse = null; 195 192 if (c == '\t') { 196 193 if (info.isShiftDown) { … … 212 209 // float diff = newMouse.y - oldY; 213 210 // System.out.print("c"); 214 Rectangle rect = info.firstConnected.getPolygon().getBounds();211 AxisAlignedBoxBounds rect = info.firstConnected.getBounds(); 215 212 216 213 // Text lastEdited = FrameUtils.getLastEdited(); … … 218 215 219 216 Item justBelow = FrameUtils.onItem(DisplayIO.getCurrentFrame(), 220 info.firstConnected.getX() + 10, rect. y + rect.height+ 1, false);217 info.firstConnected.getX() + 10, rect.getMinY() + rect.getHeight() + 1, false); 221 218 222 219 // FrameUtils.setLastEdited(lastEdited); … … 242 239 } 243 240 244 private static Text _toRemove = null;245 246 private static Collection<Item> _enclosedItems = null;247 248 public static void resetEnclosedItems() {249 _enclosedItems = null;250 }251 252 241 public synchronized void keyTyped(KeyEvent e) { 253 242 if (Simple.isProgramRunning()) { 254 if (e.isControlDown() 255 && (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.getKeyChar() == KeyEvent.VK_C)) { 243 if (e.isControlDown() && (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.getKeyChar() == KeyEvent.VK_C)) { 256 244 Simple.stop(); 257 245 return; … … 262 250 Simple.KeyStroke(e.getKeyChar()); 263 251 } 264 if (Simple.consumeKeyboardInput())265 252 253 if (Simple.consumeKeyboardInput()) return; 266 254 } 267 255 … … 284 272 // System.out.println(ch); 285 273 286 if (e.isAltDown()) { 287 288 } else { 289 processChar(ch, e.isShiftDown()); 290 } 274 if (!e.isAltDown()) processChar(ch, e.isShiftDown()); 291 275 // FrameGraphics.Repaint(); 292 }293 294 public static void processChar(char ch, boolean isShiftDown) {295 Navigation.ResetLastAddToBack();296 Item on = FrameUtils.getCurrentItem();297 298 // permission check299 if (on != null && !on.hasPermission(UserAppliedPermission.full)) {300 MessageBay301 .displayMessage("Insufficient permission to edit this item");302 return;303 }304 305 if (isShiftDown && MagneticConstraints.getInstance().keyHit(-ch, on))306 return;307 else if (MagneticConstraints.getInstance().keyHit(ch, on))308 return;309 310 if (_toRemove != null && on != _toRemove) {311 assert (_toRemove.getLength() == 0);312 // This line is to protect mistaken removal of items if there is a313 // bug...314 if (_toRemove.getLength() == 0)315 DisplayIO.getCurrentFrame().removeItem(_toRemove);316 }317 _toRemove = null;318 319 // ignore delete and backspace if in free space320 if ((on == null || !(on instanceof Text))321 && (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_TAB || ch == KeyEvent.VK_DELETE))322 return;323 324 SessionStats.TypedChar(ch);325 326 // check for dot's being replaced with text327 if (on != null && on instanceof Dot && !(on instanceof WidgetCorner)) {328 if (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE) {329 return;330 }331 replaceDot((Item) on, ch);332 return;333 }334 335 // only text can interact with keyboard events336 if (on != null && !(on instanceof Text))337 on = null;338 339 // DisplayIO.UpdateTitle();340 341 Text text = (Text) on;342 // if this text is empty but has not been removed (such as from343 // ESC-pushdown)344 if (text != null && text.isEmpty()345 && (ch == KeyEvent.VK_BACK_SPACE || ch == KeyEvent.VK_DELETE)) {346 if (text.getLines().size() > 0)347 replaceText(text);348 else {349 DisplayIO.setCursor(Item.DEFAULT_CURSOR);350 }351 return;352 }353 354 // if the user is in free space, create a new text item355 /*356 * MikeSays: Why do we have to check is highlighted... doing so causes357 * problems if you type characters to fast, they turn into multiple text358 * items. ie. JK together on the Linux laptop.359 */360 if (on == null /* || !on.isHighlighted() */) {361 // DisplayIO.UpdateTitle();362 text = createText(ch);363 text.justify(false);364 365 FrameUtils.setLastEdited(text);366 DisplayIO.setTextCursor(text, Text.NONE);367 return;368 } else {369 FrameUtils.setLastEdited(text);370 }371 372 DisplayIO.setTextCursor(text, Text.NONE);373 IndirectKeyboardActions.getInstance().getInsertCharacterAction()374 .exec(new KeyboardInfo(null, ch, isShiftDown, isShiftDown,375 _enclosedItems, text, _enclosedItems, _enclosedItems), ch);376 377 // This repaint is needed for WINDOWS only?!?!? Mike is not sure why!378 if (ch == KeyEvent.VK_DELETE)379 FrameGraphics.requestRefresh(true);380 381 // a change has occured to the Frame382 text.getParent().setChanged(true);383 384 // check that the Text item still exists (hasn't been deleted\backspaced385 // away)386 if (text.isEmpty()) {387 _toRemove = text;388 389 if (text.hasAction())390 text.setActionMark(true);391 else if (text.getLink() != null)392 text.setLinkMark(true);393 else if (text.getLines().size() > 0)394 replaceText(text);395 else {396 // DisplayIO.getCurrentFrame().removeItem(text);397 DisplayIO.setCursor(Item.DEFAULT_CURSOR);398 }399 }400 }401 402 public static Text replaceDot(Item dot, char ch) {403 Text text = createText(ch);404 Item.DuplicateItem(dot, text);405 FrameUtils.setLastEdited(text);406 407 // Copy the lines list so it can be modified408 List<Line> lines = new LinkedList<Line>(dot.getLines());409 for (Line line : lines)410 line.replaceLineEnd(dot, text);411 Frame current = dot.getParentOrCurrentFrame();412 current.removeItem(dot);413 ItemUtils.EnclosedCheck(current.getItems());414 return text;415 }416 417 /**418 * Replaces the given text item with a dot419 */420 public static Item replaceText(Item text) {421 Item dot = new Dot(text.getX(), text.getY(), text.getID());422 Item.DuplicateItem(text, dot);423 424 List<Line> lines = new LinkedList<Line>();425 lines.addAll(text.getLines());426 if (lines.size() > 0)427 dot.setColor(lines.get(0).getColor());428 for (Line line : lines) {429 line.replaceLineEnd(text, dot);430 }431 text.delete();432 Frame current = text.getParentOrCurrentFrame();433 current.addItem(dot);434 DisplayIO.setCursor(Item.DEFAULT_CURSOR);435 ItemUtils.EnclosedCheck(current.getItems());436 return dot;437 }438 439 /**440 * Creates a new Text Item whose text contains the given character. This441 * method also moves the mouse cursor to be pointing at the newly created442 * Text Item ready to insert the next character.443 *444 * @param start445 * The character to use as the initial text of this Item.446 * @return The newly created Text Item447 */448 private static Text createText(char start) {449 return IndirectKeyboardActions.getInstance().getCreateNewTextAction()450 .exec(new KeyboardInfo(null, start, false, false, _enclosedItems, _toRemove, _enclosedItems, _enclosedItems), start);451 }452 453 /**454 * Creates a new Text Item with no text. The newly created Item is a copy of455 * any ItemTemplate if one is present, and inherits all the attributes of456 * the Template457 *458 * @return The newly created Text Item459 */460 private static Text createText() {461 return DisplayIO.getCurrentFrame().createNewText();462 }463 464 private void move(int direction, boolean isShiftDown, boolean isCtrlDown) {465 Item on = FrameUtils.getCurrentItem();466 467 if ((on == null) || (on instanceof Picture)){468 navigateFrame(direction);469 return;470 }471 472 if (on instanceof Text) {473 Text text = (Text) on;474 // When the user hits the left and right button with mouse475 // positions over the the frame name navigation occurs476 if (text.isFrameName()) {477 navigateFrame(direction);478 return;479 } else {480 FrameUtils.setLastEdited(text);481 DisplayIO.setTextCursor(text, direction, false, isShiftDown,482 isCtrlDown, true);483 }484 }485 }486 487 private void navigateFrame(int direction) {488 switch (direction) {489 case Text.RIGHT:490 case Text.PAGE_UP:491 Navigation.NextFrame(false);492 break;493 case Text.LEFT:494 case Text.PAGE_DOWN:495 Navigation.PreviousFrame(false);496 break;497 case Text.HOME:498 case Text.LINE_HOME:499 Navigation.ZeroFrame();500 break;501 case Text.END:502 case Text.LINE_END:503 Navigation.LastFrame();504 break;505 }506 276 } 507 277 … … 515 285 int keyCode = e.getKeyCode(); 516 286 517 if (keyCode != KeyEvent.VK_F1 && keyCode != KeyEvent.VK_F2) { 287 // Empty the list of enclosed items if not a size-up or size-down press 288 /* if (keyCode != KeyEvent.VK_F1 && keyCode != KeyEvent.VK_F2) { 518 289 resetEnclosedItems(); 519 290 } 520 291 292 // Notify the change in stats 293 // TODO: Will changing this to the Expeditee KBMInputEvent upset stats? cts16 521 294 SessionStats.AddFrameEvent("k" + KeyEvent.getKeyText(keyCode)); 522 295 296 // Used for calculating frame stats (response time) 523 297 FrameUtils.ResponseTimer.restart(); 524 298 // e.consume(); 525 299 300 // Things that should consume input before main Expeditee 526 301 if (Actions.isAgentRunning()) { 527 302 if (keyCode == KeyEvent.VK_ESCAPE) … … 534 309 } 535 310 311 // Function keys are handled here 536 312 if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) { 537 functionKey(FunctionKey.values()[keyCode - KeyEvent.VK_F1 + 1], 538 e.isShiftDown(), e.isControlDown()); 539 return; 540 } else if (e.isAltDown()) { 313 functionKey(FunctionKey.values()[keyCode - KeyEvent.VK_F1 + 1], e.isShiftDown(), e.isControlDown()); 314 return; 315 }*/ 316 317 // Keyboard for mouse emulation 318 // TODO: Do we need individual mouse button clicks? Are the corresponding gestures enough? cts16 319 if (e.isAltDown()) { 541 320 int distance = e.isShiftDown() ? 1 : 20; 542 321 switch (keyCode) { … … 553 332 FrameMouseActions.rightButton(); 554 333 break; 555 case KeyEvent.VK_LEFT:334 /* case KeyEvent.VK_LEFT: 556 335 DisplayIO.translateCursor(-distance, 0); 557 336 break; … … 564 343 case KeyEvent.VK_DOWN: 565 344 DisplayIO.translateCursor(0, distance); 566 break; 567 } 568 return; 569 } 345 break;*/ 346 } 347 return; 348 } 349 350 // Notify the mouse handler of the control/shift key state 570 351 switch (keyCode) { 571 352 case KeyEvent.VK_CONTROL: … … 577 358 } 578 359 360 // Handles all CTRL+KEY combinations 579 361 if (e.isControlDown()) { 580 362 controlChar(e.getKeyCode(), e.isShiftDown()); … … 582 364 } 583 365 584 switch (keyCode) { 366 // Handles all other keystrokes (with possible shift modifier) 367 // Note: At this point e.isControlDown() must be false 368 /* switch (keyCode) { 585 369 case KeyEvent.VK_ESCAPE: 586 // Do escape after control so Ctl+Escape does not perform DropDown 587 functionKey(FunctionKey.DropDown, e.isShiftDown(), 588 e.isControlDown()); 370 // Do escape after control so Ctrl+Escape does not perform DropDown 371 functionKey(FunctionKey.DropDown, e.isShiftDown(), false); 589 372 SessionStats.Escape(); 590 373 break; 591 374 case KeyEvent.VK_LEFT: 592 move(Text.LEFT, e.isShiftDown(), e.isControlDown());375 move(Text.LEFT, e.isShiftDown(), false); 593 376 break; 594 377 case KeyEvent.VK_RIGHT: 595 move(Text.RIGHT, e.isShiftDown(), e.isControlDown());378 move(Text.RIGHT, e.isShiftDown(), false); 596 379 break; 597 380 case KeyEvent.VK_PAGE_DOWN: … … 602 385 break; 603 386 case KeyEvent.VK_UP: 604 if (e.isControlDown()) { 605 NextTextItem(FrameUtils.getCurrentItem(), false); 606 } else { 607 move(Text.UP, e.isShiftDown(), e.isControlDown()); 608 } 387 move(Text.UP, e.isShiftDown(), false); 609 388 break; 610 389 case KeyEvent.VK_DOWN: 611 if (e.isControlDown()) { 612 NextTextItem(FrameUtils.getCurrentItem(), true); 613 } else { 614 move(Text.DOWN, e.isShiftDown(), e.isControlDown()); 615 } 390 move(Text.DOWN, e.isShiftDown(), false); 616 391 break; 617 392 case KeyEvent.VK_END: 618 if (e.isControlDown()) 619 move(Text.END, e.isShiftDown(), e.isControlDown()); 620 else 621 move(Text.LINE_END, e.isShiftDown(), e.isControlDown()); 393 move(Text.LINE_END, e.isShiftDown(), false); 622 394 break; 623 395 case KeyEvent.VK_HOME: 624 if (e.isControlDown()) 625 move(Text.HOME, e.isShiftDown(), e.isControlDown()); 626 else 627 move(Text.LINE_HOME, e.isShiftDown(), e.isControlDown()); 396 move(Text.LINE_HOME, e.isShiftDown(), false); 628 397 break; 629 398 // TODO remove this when upgrading Java … … 636 405 } 637 406 break; 638 } 639 } 640 641 /** 642 * Moves the cursor to the next text item on the frame 643 * 644 * @param currentItem 645 * @param direction 646 * move up if direction is negative, down if direction is 647 * positive 648 */ 649 public static void NextTextItem(Item currentItem, boolean down) { 650 // Move the cursor to the next text item 651 Frame current = DisplayIO.getCurrentFrame(); 652 Text title = current.getTitleItem(); 653 654 Collection<Text> currentItems = FrameUtils.getCurrentTextItems(); 655 List<Text> textItems = new ArrayList<Text>(); 656 // Move to the next text item in the box if 657 if (currentItems.contains(currentItem)) { 658 textItems.addAll(currentItems); 659 } else { 660 if (title != null) 661 textItems.add(title); 662 textItems.addAll(current.getBodyTextItems(true)); 663 } 664 665 Collections.sort(textItems); 666 667 if (textItems.size() == 0) { 668 // If there are no text items on the frame its a NoOp 669 if (title == null) 670 return; 671 if (title != null) 672 DisplayIO.MoveCursorToEndOfItem(title); 673 FrameGraphics.Repaint(); 674 return; 675 } 676 677 // If the user is mouse wheeling in free space... 678 if (currentItem == null) { 679 // find the nearest item in the correct direction 680 int currY = FrameMouseActions.getY(); 681 for (int i = 0; i < textItems.size(); i++) { 682 Item t = textItems.get(i); 683 if (currY < t.getY()) { 684 if (down) { 685 DisplayIO.MoveCursorToEndOfItem(t); 686 } else { 687 if (i == 0) { 688 DisplayIO.MoveCursorToEndOfItem(current 689 .getTitleItem()); 690 } else { 691 DisplayIO.MoveCursorToEndOfItem(textItems 692 .get(i - 1)); 693 } 694 } 695 FrameGraphics.Repaint(); 696 return; 697 } 698 } 699 // If we are at the botton of the screen and the user scrolls down 700 // then scroll backup to the title 701 if (textItems.size() > 0) { 702 DisplayIO 703 .MoveCursorToEndOfItem(textItems.get(textItems.size() - 1)); 704 } 705 return; 706 } 707 708 // Find the current item... then move to the next item 709 int i = textItems.indexOf(currentItem); 710 711 int nextIndex = i + (down ? 1 : -1); 712 if (nextIndex >= 0 && nextIndex < textItems.size()) { 713 DisplayIO.MoveCursorToEndOfItem(textItems.get(nextIndex)); 714 } else { 715 DisplayIO.MoveCursorToEndOfItem(currentItem); 716 } 717 return; 718 407 }*/ 719 408 } 720 409 … … 739 428 } 740 429 741 private static void copyItemToClipboard(Item on) {742 if (on == null || !(on instanceof Text))743 return;744 745 Text text = (Text) on;746 String string = text.copySelectedText();747 748 if (string == null || string.length() == 0)749 string = text.getText();750 751 // add the text of the item to the clipboard752 StringSelection selection = new StringSelection(string);753 Toolkit.getDefaultToolkit().getSystemClipboard()754 .setContents(selection, null);755 }756 757 430 /** 758 431 * Processes all control character keystrokes. Currently Ctrl+C and Ctrl+V … … 763 436 */ 764 437 private void controlChar(int key, boolean isShiftDown) { 765 Logger.Log(Logger.USER, Logger.CONTROL_CHAR, "User pressing: Ctrl+" 766 + KeyEvent.getKeyText(key)); 438 //Logger.Log(Logger.USER, Logger.CONTROL_CHAR, "User pressing: Ctrl+" + KeyEvent.getKeyText(key)); 767 439 // 768 440 // if (FrameUtils.getCurrentItem() == null … … 776 448 int distance = isShiftDown ? 1 : 20; 777 449 switch (key) { 778 case KeyEvent.VK_HOME:450 /* case KeyEvent.VK_HOME: 779 451 if (current != null && current instanceof Text) { 780 452 move(Text.HOME, isShiftDown, true); … … 802 474 break; 803 475 case KeyEvent.VK_ESCAPE: 804 // Do escape after control so Ct l+Escape does not perform DropDown476 // Do escape after control so Ctrl+Escape does not perform DropDown 805 477 functionKey(FunctionKey.DropDown, isShiftDown, true); 806 SessionStats.Escape(); 478 SessionStats.Escape();*/ 807 479 break; 808 480 case KeyEvent.VK_1: … … 819 491 break; 820 492 case KeyEvent.VK_LEFT: 821 if (current instanceof Text) { 822 DisplayIO.setTextCursor((Text) current, Text.LEFT, false, 823 isShiftDown, true, true); 824 } else { 493 /* if (current instanceof Text) { 494 DisplayIO.setTextCursor((Text) current, Text.LEFT, false, isShiftDown, true, true); 495 } else */{ 825 496 DisplayIO.translateCursor(-distance, 0); 826 497 } 827 498 break; 828 499 case KeyEvent.VK_RIGHT: 829 if (current instanceof Text) { 830 DisplayIO.setTextCursor((Text) current, Text.RIGHT, false, 831 isShiftDown, true, true); 832 } else { 500 /* if (current instanceof Text) { 501 DisplayIO.setTextCursor((Text) current, Text.RIGHT, false, isShiftDown, true, true); 502 } else */{ 833 503 DisplayIO.translateCursor(distance, 0); 834 504 } 835 505 break; 836 case KeyEvent.VK_UP:506 /* case KeyEvent.VK_UP: 837 507 // if (current instanceof Text) { 838 508 NextTextItem(FrameUtils.getCurrentItem(), false); … … 849 519 break; 850 520 case KeyEvent.VK_L: 851 // If its not linked then link it to its self521 // If its not linked then link it to itself 852 522 if (current instanceof Text && current.getLink() == null) { 853 523 String text = ((Text) current).getText(); … … 866 536 } 867 537 break; 868 case KeyEvent.VK_G: 869 // If its not linked then link it to its self538 case KeyEvent.VK_G: // Same as CTRL+L but follows it afterwards 539 // If its not linked then link it to itself 870 540 if (current instanceof Text) { 871 541 String text = ((Text) current).getText(); … … 922 592 return; 923 593 case KeyEvent.VK_C: 924 if (FreeItems. itemsAttachedToCursor()) {594 if (FreeItems.hasItemsAttachedToCursor()) { 925 595 ItemSelection.copyClone(); 926 596 return; … … 933 603 if (current instanceof Dot && current.getLines().size() == 1) { 934 604 item = replaceDot(current, '@'); 935 } else if (current instanceof Line 936 && current.getAllConnected().size() == 3) { 605 } else if (current instanceof Line && current.getAllConnected().size() == 3) { 937 606 Item end = ((Line) current).getEndItem(); 938 607 if (end instanceof Dot) { … … 955 624 if (current == null) 956 625 return; 957 if (current != null 958 && !current.hasPermission(UserAppliedPermission.full)) { 959 MessageBay 960 .displayMessage("Insufficient permission toggle the items mark"); 961 return; 962 } 963 boolean newValue = !(current.getLinkMark() || current 964 .getActionMark()); 626 if (current != null && !current.hasPermission(UserAppliedPermission.full)) { 627 MessageBay.displayMessage("Insufficient permission toggle the items mark"); 628 return; 629 } 630 boolean newValue = !(current.getLinkMark() || current.getActionMark()); 965 631 current.setLinkMark(newValue); 966 632 current.setActionMark(newValue); … … 980 646 // perform a delete operation 981 647 FrameMouseActions.delete(current); 982 break; 648 break;*/ 983 649 case KeyEvent.VK_SPACE: 984 650 if (isShiftDown) { … … 988 654 } 989 655 break; 990 case KeyEvent.VK_F:656 /* case KeyEvent.VK_F: 991 657 // perform a format operation 992 658 if (isShiftDown) { … … 1012 678 break; 1013 679 1014 case KeyEvent.VK_R: 680 case KeyEvent.VK_R: // TODO: What is this? Similar to above? cts16 1015 681 Text textCurrent = getCurrentTextItem(); 1016 682 if (textCurrent == null) { … … 1026 692 break; 1027 693 case KeyEvent.VK_S: 1028 /* 1029 * Only split when shift is down... it is too easy to accidentally 1030 * hit Ctrl+S after completing a paragraph because this is the 1031 * shortcut for saving a document in most word processors and text 1032 * editors! 1033 */ 694 // Only split when shift is down... it is too easy to accidentally 695 // hit Ctrl+S after completing a paragraph because this is the 696 // shortcut for saving a document in most word processors and text 697 // editors! 1034 698 if (!isShiftDown) { 1035 699 Save(); … … 1057 721 currentFrame.addItem(newText); 1058 722 } 1059 break; 723 break;*/ 1060 724 case KeyEvent.VK_ENTER: 1061 725 FrameMouseActions.leftButton(); 1062 726 break; 1063 case KeyEvent.VK_BACK_SPACE:727 /* case KeyEvent.VK_BACK_SPACE: 1064 728 DisplayIO.Back(); 1065 break; 729 break;*/ 1066 730 } 1067 731 FrameGraphics.Repaint(); … … 1078 742 1079 743 if (item != null && !item.hasPermission(UserAppliedPermission.full)) { 1080 MessageBay 1081 .displayMessage("Insufficient permission to copy that item"); 744 MessageBay.displayMessage("Insufficient permission to copy that item"); 1082 745 return null; 1083 746 } … … 1093 756 } 1094 757 1095 public static void functionKey(FunctionKey key, boolean isShiftDown, 1096 boolean isControlDown){758 /* public static void functionKey(FunctionKey key, boolean isShiftDown, boolean isControlDown) 759 { 1097 760 functionKey(key, 1, isShiftDown, isControlDown); 1098 761 } 1099 762 */ 1100 763 /** 1101 764 * Called when a Function key has been pressed, and performs the specific 1102 765 * action based on the key. 1103 766 */ 1104 public static void functionKey(FunctionKey key, int repeat, 1105 boolean isShiftDown, boolean isControlDown){767 /* public static void functionKey(FunctionKey key, int repeat, boolean isShiftDown, boolean isControlDown) 768 { 1106 769 // get whatever the user is pointing at 1107 770 Item on = FrameUtils.getCurrentItem(); … … 1195 858 } 1196 859 } 860 1197 861 // Show a description of the function key pressed if the user is in free 1198 862 // space and return for the F keys that dont do anything in free space. 1199 863 if (on == null) { 1200 864 1201 int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();865 // int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY(); 1202 866 1203 867 switch (key) { 1204 868 // These function keys still work in free space 1205 case DropDown:1206 case InsertDate:869 // case DropDown: 870 // case InsertDate: 1207 871 case XRayMode: 1208 872 case AudienceMode: 1209 873 case Refresh: 1210 case Save:874 // case Save: 1211 875 break; 1212 876 … … 1244 908 } 1245 909 } 1246 Drop(on, false);910 // Drop(on, false); 1247 911 return; 1248 912 case SizeUp: 1249 913 SetSize(on, repeat, true, false, isControlDown); 1250 914 if (on instanceof Text) { 1251 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, 1252 false, true); 915 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true); 1253 916 } 1254 917 break; … … 1256 919 SetSize(on, -repeat, true, false, isControlDown); 1257 920 if (on instanceof Text) { 1258 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, 1259 false, true); 921 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true); 1260 922 } 1261 923 break; … … 1300 962 MessageBay.displayMessage(displayMessage); 1301 963 } 1302 1303 private static void calculateItem(Item toCalculate) { 1304 if (toCalculate == null) 1305 return; 1306 1307 if (!toCalculate.update()) { 1308 toCalculate.setFormula(null); 1309 MessageBay.errorMessage("Can not calculate formula [" 1310 + toCalculate.getText() + ']'); 1311 } 1312 } 1313 1314 public static void Save() { 1315 Frame current = DisplayIO.getCurrentFrame(); 1316 current.change(); 1317 FrameIO.SaveFrame(current, true, true); 1318 } 1319 1320 public static final String DEFAULT_NEW_ITEM_TEXT = ""; 1321 1322 /** 1323 * Performs the dropping action: If the cursor is in free space then: the 1324 * cursor is repositioned below the last non-annotation text item. If the 1325 * cursor is on an item, and has items attached then: the cusor is 1326 * positioned below the pointed to item, and the items below are 'pushed 1327 * down' to make room. 1328 * 1329 * @param toDropFrom 1330 * The Item being pointed at by the mouse, may be null to 1331 * indicate the cursor is in free space. 1332 */ 1333 public static boolean Drop(Item toDropFrom, boolean bPasting) { 1334 try { 1335 FrameUtils.setLastEdited(null); 1336 1337 String newItemText = DEFAULT_NEW_ITEM_TEXT; 1338 1339 // if a line is being rubber-banded, this is a no-op 1340 if (Frame.rubberbandingLine()) 1341 return false; // No-op 1342 1343 // if the cursor is in free space then the drop will happen from the 1344 // last non annotation text item on the frame 1345 if (toDropFrom == null) { 1346 toDropFrom = DisplayIO.getCurrentFrame() 1347 .getLastNonAnnotationTextItem(); 1348 } 1349 1350 // if no item was found, return 1351 if (toDropFrom == null) { 1352 MessageBay.errorMessage("No item could be found to drop from"); 1353 return false; 1354 } 1355 1356 if (!(toDropFrom instanceof Text)) { 1357 MessageBay 1358 .displayMessage("Only text items can be dropped from"); 1359 return false; 1360 } 1361 1362 // Get the list of items that must be dropped 1363 List<Text> column = DisplayIO.getCurrentFrame().getColumn( 1364 toDropFrom); 1365 1366 if (column == null) { 1367 MessageBay.errorMessage("No column found to align items to"); 1368 return false; 1369 } 1370 1371 Item title = DisplayIO.getCurrentFrame().getTitleItem(); 1372 1373 // We wont do auto bulleting when dropping from titles 1374 if (!bPasting && toDropFrom != title) { 1375 newItemText = getAutoBullet(((Text) toDropFrom).getFirstLine()); 1376 } 1377 1378 Text dummyItem = null; 1379 if (!bPasting && FreeItems.textOnlyAttachedToCursor()) { 1380 dummyItem = (Text) FreeItems.getItemAttachedToCursor(); 1381 String autoBullet = getAutoBullet(dummyItem.getText()); 1382 1383 if (autoBullet.length() > 0) 1384 newItemText = ""; 1385 dummyItem.setText(newItemText + dummyItem.getText()); 1386 } 1387 1388 dummyItem = createText(); 1389 if (FreeItems.textOnlyAttachedToCursor()) { 1390 Text t = (Text) FreeItems.getItemAttachedToCursor(); 1391 dummyItem.setSize(t.getSize()); 1392 int lines = t.getTextList().size(); 1393 for (int i = 0; i < lines; i++) { 1394 newItemText += '\n'; 1395 } 1396 } 1397 1398 dummyItem.setText(newItemText); 1399 1400 // If the only item on the frame is the title and the frame name 1401 // goto the zero frame and drop to the @start if there is one 1402 // or a fixed amount if there is not 1403 if (column.size() == 0) { 1404 Frame current = DisplayIO.getCurrentFrame(); 1405 // Item itemTemplate = current.getItemTemplate(); 1406 int xPos = title.getX() + FrameCreator.INDENT_FROM_TITLE; 1407 int yPos = FrameCreator.getYStart(title); 1408 // Check for @start on the zero frame 1409 Frame zero = FrameIO.LoadFrame(current.getFramesetName() + '0'); 1410 Text start = zero.getAnnotation("start"); 1411 if (start != null) { 1412 xPos = start.getX(); 1413 yPos = start.getY(); 1414 } 1415 1416 dummyItem.setPosition(xPos, yPos); 1417 // DisplayIO.setCursorPosition(xPos, yPos); 1418 1419 checkMovingCursor(dummyItem); 1420 } else { 1421 int yPos = column.get(0).getY() + 1; 1422 int xPos = column.get(0).getX(); 1423 // Either position the new item below the title or just above 1424 // the first item below the title 1425 if (toDropFrom == title && column.get(0) != title) { 1426 // If dropping from the title position just above top item 1427 yPos = column.get(0).getY() - 1; 1428 1429 Frame current = DisplayIO.getCurrentFrame(); 1430 // Check for @start on the zero frame 1431 Frame zero = FrameIO 1432 .LoadFrame(current.getFramesetName() + '0'); 1433 Text start = zero.getAnnotation("start"); 1434 if (start != null) { 1435 yPos = Math.min(yPos, start.getY()); 1436 } 1437 } 1438 dummyItem.setPosition(xPos, yPos); 1439 column.add(dummyItem); 1440 FrameUtils.Align(column, false, 0); 1441 // Check if it will be outside the frame area 1442 if (dummyItem.getY() < 0 1443 || dummyItem.getY() > FrameGraphics.getMaxFrameSize() 1444 .getHeight()) { 1445 // Check for the 'next' tag! 1446 Frame current = DisplayIO.getCurrentFrame(); 1447 Item next = current.getAnnotation("next"); 1448 Item prev = current.getAnnotation("previous"); 1449 // Check for an unlinked next tag 1450 if ((next != null && !next.hasLink()) 1451 || (prev != null && prev.hasLink())) { 1452 Frame firstFrame = current; 1453 if (next != null) 1454 next.delete(); 1455 FrameCreator frameCreator = new FrameCreator(null); 1456 // Add the next button 1457 next = frameCreator.addNextButton(current, null); 1458 1459 // Create the new frame linked to the next tag 1460 boolean mouseMoved = FrameMouseActions.tdfc(next); 1461 Frame moreFrame = DisplayIO.getCurrentFrame(); 1462 1463 // Add previous button to the new frame 1464 frameCreator.addPreviousButton(moreFrame, 1465 firstFrame.getName()); 1466 Item first = current.getAnnotation("first"); 1467 if (first != null) { 1468 frameCreator.addFirstButton(moreFrame, 1469 first.getLink()); 1470 } else { 1471 frameCreator.addFirstButton(moreFrame, 1472 firstFrame.getName()); 1473 } 1474 // Add the @next if we are pasting 1475 // if (bPasting) { 1476 // Item copy = next.copy(); 1477 // copy.setLink(null); 1478 // moreFrame.addItem(copy); 1479 // } 1480 1481 moreFrame.setTitle(firstFrame.getTitleItem().getText()); 1482 // need to move the mouse to the top of the frame if 1483 // there wasnt an @start on it 1484 if (!mouseMoved) { 1485 Item moreTitle = moreFrame.getTitleItem(); 1486 moreTitle 1487 .setOverlayPermission(UserAppliedPermission.full); 1488 Drop(moreTitle, bPasting); 1489 } 1490 // Add the bullet text to the item 1491 dummyItem.setPosition(DisplayIO.getMouseX(), 1492 FrameMouseActions.getY()); 1493 } else { 1494 MessageBay 1495 .warningMessage("Can not create items outside the frame area"); 1496 // ensures correct repainting when items don't move 1497 DisplayIO.setCursorPosition(DisplayIO.getMouseX(), 1498 FrameMouseActions.getY()); 1499 return false; 1500 } 1501 } 1502 if (!FreeItems.textOnlyAttachedToCursor() 1503 && !dummyItem.isEmpty()) { 1504 DisplayIO.getCurrentFrame().addItem(dummyItem); 1505 } 1506 1507 checkMovingCursor(dummyItem); 1508 } 1509 if (dummyItem.getText().length() == 0 1510 || FreeItems.itemsAttachedToCursor()) { 1511 dummyItem.getParentOrCurrentFrame().removeItem(dummyItem); 1512 dummyItem.setRightMargin(FrameGraphics.getMaxFrameSize().width, 1513 false); 1514 } else { 1515 dummyItem.setWidth(toDropFrom.getWidth()); 1516 } 1517 1518 DisplayIO.resetCursorOffset(); 1519 FrameGraphics.Repaint(); 1520 } catch (RuntimeException e) { 1521 // MessageBay.errorMessage(e.getMessage()); 1522 e.printStackTrace(); 1523 return false; 1524 } 1525 return true; 1526 } 1527 1528 /** 1529 * @param dummyItem 1530 */ 1531 private static void checkMovingCursor(Text dummyItem) { 1532 // Move the item to the cursor position 1533 if (FreeItems.itemsAttachedToCursor()) { 1534 moveCursorAndFreeItems(dummyItem.getX(), dummyItem.getY()); 1535 } else { 1536 DisplayIO.MoveCursorToEndOfItem(dummyItem); 1537 } 1538 } 1539 1540 /** 1541 * @param dummyItem 1542 */ 1543 public static void moveCursorAndFreeItems(int x, int y) { 1544 int oldX = FrameMouseActions.getX(); 1545 int oldY = FrameMouseActions.getY(); 1546 1547 if (oldX == x && oldY == y) 1548 return; 1549 1550 DisplayIO.setCursorPosition(x, y); 1551 Item firstItem = FreeItems.getItemAttachedToCursor(); 1552 1553 if (firstItem == null) { 1554 firstItem = null; 1555 return; 1556 } 1557 1558 int deltaX = firstItem.getX() - x; 1559 int deltaY = firstItem.getY() - y; 1560 1561 for (Item i : FreeItems.getInstance()) { 1562 i.setPosition(i.getX() - deltaX, i.getY() - deltaY); 1563 } 1564 } 1565 1566 /** 1567 * Gets the next letter sequence for a given string to be used in auto 1568 * lettering. 1569 * 1570 * @param s 1571 * a sequence of letters 1572 * @return the next sequence of letters 1573 */ 1574 static private String nextLetterSequence(String s) { 1575 if (s.length() > 1) 1576 return s; 1577 1578 if (s.equals("z")) 1579 return "a"; 1580 1581 return (char) ((int) s.charAt(0) + 1) + ""; 1582 } 1583 1584 public static String getBullet(String s) { 1585 return getBullet(s, false); 1586 } 1587 1588 public static String getAutoBullet(String s) { 1589 return getBullet(s, true); 1590 } 1591 1592 private static String getBullet(String s, boolean nextBullet) { 1593 String newItemText = DEFAULT_NEW_ITEM_TEXT; 1594 1595 if (s == null) 1596 return newItemText; 1597 /* 1598 * Item i = ItemUtils.FindTag(DisplayIO.getCurrentFrame().getItems(), 1599 * "@NoAutoBullets"); if (i != null) return newItemText; 1600 */ 1601 // Separate the space at the start of the text item 1602 String preceedingSpace = ""; 1603 for (int i = 0; i < s.length(); i++) { 1604 if (!Character.isSpaceChar(s.charAt(i))) { 1605 preceedingSpace = s.substring(0, i); 1606 s = s.substring(i); 1607 break; 1608 } 1609 } 1610 1611 // figure out the type of the text item 1612 // This allows us to do auto bulleting 1613 if (s != null && s.length() > 1) { 1614 // First check for text beginning with * @ # etc 1615 // These are simple auto bullets 1616 if (!Character.isLetterOrDigit(s.charAt(0)) 1617 && !Character.isSpaceChar(s.charAt(0))) { 1618 if (Text.isBulletChar(s.charAt(0))) { 1619 int nonSpaceIndex = 1; 1620 // Find the end of the bullet and space after the bullet 1621 while (nonSpaceIndex < s.length() 1622 && s.charAt(nonSpaceIndex) == ' ') { 1623 nonSpaceIndex++; 1624 } 1625 // we must have a special char followed by >= 1 space 1626 if (nonSpaceIndex > 1) 1627 newItemText = s.substring(0, nonSpaceIndex); 1628 } 1629 // Auto numbering and lettering 1630 } else { 1631 if (Character.isDigit(s.charAt(0))) { 1632 newItemText = getAutoNumber(s, nextBullet); 1633 // Auto lettering 1634 } else if (Character.isLetter(s.charAt(0))) { 1635 newItemText = getAutoLetter(s, nextBullet); 1636 } 1637 } 1638 } 1639 return preceedingSpace + newItemText; 1640 } 1641 1642 private static boolean isAutoNumberOrLetterChar(char c) { 1643 return c == ':' || c == '-' || c == '.' || c == ')' || c == '>'; 1644 } 1645 1646 /** 1647 * Gets the string to be used to start the next auto numbered text item. 1648 * 1649 * @param s 1650 * the previous text item 1651 * @return the beginning of the next auto numbered text item 1652 */ 1653 private static String getAutoNumber(String s, boolean nextBullet) { 1654 String newItemText = DEFAULT_NEW_ITEM_TEXT; 1655 1656 int nonDigitIndex = 1; 1657 while (Character.isDigit(s.charAt(nonDigitIndex))) { 1658 nonDigitIndex++; 1659 1660 if (nonDigitIndex + 1 >= s.length()) 1661 return DEFAULT_NEW_ITEM_TEXT; 1662 } 1663 1664 if (isAutoNumberOrLetterChar(s.charAt(nonDigitIndex))) { 1665 1666 // we must have a number followed one non letter 1667 // then one or more spaces 1668 int nonSpaceIndex = nonDigitIndex + 1; 1669 while (nonSpaceIndex < s.length() && s.charAt(nonSpaceIndex) == ' ') { 1670 nonSpaceIndex++; 1671 } 1672 1673 if (nonSpaceIndex > nonDigitIndex + 1) { 1674 if (nextBullet) 1675 newItemText = (Integer.parseInt(s.substring(0, 1676 nonDigitIndex)) + 1) 1677 + s.substring(nonDigitIndex, nonSpaceIndex); 1678 else 1679 newItemText = s.substring(0, nonSpaceIndex); 1680 } 1681 } 1682 return newItemText; 1683 } 1684 1685 /** 1686 * Gets the string to be used to start the next auto lettered text item. 1687 * 1688 * @param s 1689 * the previous text items 1690 * @return the initial text for the new text item 1691 */ 1692 private static String getAutoLetter(String s, boolean nextBullet) { 1693 String newItemText = DEFAULT_NEW_ITEM_TEXT; 1694 1695 int nonLetterIndex = 1; 1696 1697 if (isAutoNumberOrLetterChar(s.charAt(nonLetterIndex))) { 1698 1699 // Now search for the next non space character 1700 int nonSpaceIndex = nonLetterIndex + 1; 1701 while (nonSpaceIndex < s.length() && s.charAt(nonSpaceIndex) == ' ') { 1702 nonSpaceIndex++; 1703 } 1704 1705 // If there was a space then we have reached the end of our auto 1706 // text 1707 if (nonSpaceIndex > nonLetterIndex + 1) { 1708 if (nextBullet) 1709 newItemText = nextLetterSequence(s.substring(0, 1710 nonLetterIndex)) 1711 + s.substring(nonLetterIndex, nonSpaceIndex); 1712 else 1713 newItemText = s.substring(0, nonSpaceIndex); 1714 } 1715 } 1716 return newItemText; 1717 } 1718 1719 private static boolean refreshAnchors(Collection<Item> items) { 1720 boolean bReparse = false; 1721 1722 for (Item i : items) { 1723 Float anchorLeft = i.getAnchorLeft(); 1724 Float anchorRight = i.getAnchorRight(); 1725 Float anchorTop = i.getAnchorTop(); 1726 Float anchorBottom = i.getAnchorBottom(); 1727 1728 if (anchorLeft != null) { 1729 i.setAnchorLeft(anchorLeft); 1730 if (i.hasVector()) { 1731 bReparse = true; 1732 } 1733 } 1734 1735 if (anchorRight != null) { 1736 i.setAnchorRight(anchorRight); 1737 if (i.hasVector()) { 1738 bReparse = true; 1739 } 1740 } 1741 1742 if (anchorTop != null) { 1743 i.setAnchorTop(anchorTop); 1744 if (i.hasVector()) { 1745 bReparse = true; 1746 } 1747 } 1748 1749 if (anchorBottom != null) { 1750 i.setAnchorBottom(anchorBottom); 1751 if (i.hasVector()) { 1752 bReparse = true; 1753 } 1754 } 1755 } 1756 return bReparse; 1757 } 1758 1759 protected static void zoomFrame(Frame frame, double scaleFactor, int x, int y) { 1760 1761 if (frame == null) { 1762 return; 1763 } 1764 1765 Collection<Item> items = frame.getVisibleItems(); 1766 1767 for (Item item : items) { 1768 if (item instanceof Text 1769 && item.getSize() <= Text.MINIMUM_FONT_SIZE 1770 && scaleFactor < 1) { 1771 return; 1772 } 1773 } 1774 1775 for (Vector v : frame.getVectors()) { 1776 v.Source.scale((float) scaleFactor, x, y); 1777 } 1778 1779 for (Item item : items) { 1780 // This line is only needed for circles!! 1781 // Need to really fix up the way this works!! 1782 if (item.hasEnclosures()) 1783 continue; 1784 if (!item.hasPermission(UserAppliedPermission.full)) 1785 continue; 1786 item.invalidateAll(); 1787 if (!(item instanceof Line)) { 1788 item.scale((float) scaleFactor, x, y); 1789 } 1790 } 1791 1792 for (Item item : items) { 1793 if (!item.hasPermission(UserAppliedPermission.full)) 1794 continue; 1795 // if (!(item instanceof Line)) 1796 item.updatePolygon(); 1797 1798 if (item instanceof Line) { 1799 ((Line) item).refreshStroke(item.getThickness()); 1800 } 1801 1802 item.invalidateAll(); 1803 } 1804 } 1805 1806 public static boolean zoomFrameIfEnabled(Frame frame, double scaleFactor, int mouse_x, int mouse_y) 1807 { 1808 boolean zoom_active = ExperimentalFeatures.FrameZoom.get(); 1809 1810 if (zoom_active) { 1811 1812 int x, y; 1813 if (ExperimentalFeatures.FrameZoomAroundCursor.get()) { 1814 x = mouse_x; 1815 y = mouse_y; 1816 } 1817 else { 1818 x = 0; 1819 y = 0; 1820 } 1821 1822 zoomFrame(DisplayIO.getCurrentFrame(), scaleFactor, x, y); 1823 DisplayIO.getCurrentFrame().refreshSize(); 1824 FrameKeyboardActions.Refresh(); 1825 } 1826 else { 1827 String frameZoomingDisabledMessage = "Frame Zooming currently disabled. " 1828 + "Access Settings->Experimental->FrameZoom and set to 'true' to enable this"; 1829 MessageBay.displayMessageOnce(frameZoomingDisabledMessage); 1830 } 1831 1832 return zoom_active; 1833 } 1834 1835 public static boolean zoomFrameTopLeftIfEnabled(Frame frame, double scaleFactor) 1836 { 1837 return zoomFrameIfEnabled(frame, scaleFactor, 0, 0); 1838 } 1839 1840 /** 1841 * Adjusts the size of the given Item, by the given amount. Note: The amount 1842 * is relative and can be positive or negative. 1843 * 1844 * @param toSet 1845 * The Item whose size is to be adjusted 1846 * @param diff 1847 * The amount to adjust the Item's size by 1848 * @param moveCursor 1849 * true if the cursor position should be automatically adjusted 1850 * with resizing 1851 */ 1852 public static void SetSize(Item item, int diff, boolean moveCursor, 1853 boolean insideEnclosure, boolean isControlDown) { 1854 Collection<Item> toSize = new HashSet<Item>(); 1855 Collection<InteractiveWidget> widgets = new HashSet<InteractiveWidget>(); 1856 // the mouse is only moved when the Item is on the frame, not free 1857 // boolean moveMouse = false; 1858 Item toSet = null; 1859 1860 // if the user is not pointing to any item 1861 if (item == null) { 1862 if (FreeItems.itemsAttachedToCursor()) 1863 toSize.addAll(FreeItems.getInstance()); 1864 else { 1865 MessageBay 1866 .displayMessage("There are no Items selected on the Frame or on the Cursor"); 1867 return; 1868 } 1869 } else { 1870 if (item.isFrameName()) { 1871 // scale the entire frame 1872 if (diff != 0) { 1873 double scaleFactor = diff > 0 ? 1.1 : 0.909090909; 1874 zoomFrameTopLeftIfEnabled(DisplayIO.getCurrentFrame(), scaleFactor); 1875 } 1876 // MessageBay.displayMessage("Can not resize the frame name"); 1877 return; 1878 } 1879 // check permissions 1880 if (!item.hasPermission(UserAppliedPermission.full)) { 1881 Item editTarget = item.getEditTarget(); 1882 if (editTarget != item 1883 && editTarget.hasPermission(UserAppliedPermission.full)) { 1884 item = editTarget; 1885 } else { 1886 MessageBay 1887 .displayMessage("Insufficient permission to change the size of that item"); 1888 return; 1889 } 1890 } 1891 toSet = item; 1892 // For resizing enclosures pick up everything that is attached to 1893 // items partly in the enclosure 1894 // TODO make this only pick up stuff COMPLETELY enclosed... if we 1895 // change copying to copy only the stuff completely enclosed 1896 if (insideEnclosure) { 1897 if (_enclosedItems == null) { 1898 for (Item i : FrameUtils.getCurrentItems(toSet)) { 1899 if (i.hasPermission(UserAppliedPermission.full) 1900 && !toSize.contains(i)) 1901 toSize.addAll(i.getAllConnected()); 1902 } 1903 _enclosedItems = toSize; 1904 } else { 1905 toSize = _enclosedItems; 1906 } 1907 1908 }// Enclosed circle centers are resized with the center as origin 1909 // Just add the circle center to the list of items to size 1910 else if (!toSet.hasEnclosures() && !(toSet instanceof Text) 1911 && toSet.isLineEnd()) { 1912 toSize.addAll(toSet.getLines()); 1913 } else if (toSet instanceof Line) { 1914 1915 Line line = (Line) toSet; 1916 1917 if (!(toSet instanceof WidgetEdge) 1918 || ((WidgetEdge) toSet).getWidgetSource() 1919 .isWidgetEdgeThicknessAdjustable()) { 1920 1921 float current = Math.abs(line.getThickness()); 1922 current = Math.max(current + diff, Item.MINIMUM_THICKNESS); 1923 line.setThickness(current); 1924 FrameGraphics.Repaint(); 1925 return; 1926 1927 } 1928 1929 } else { 1930 toSize.add(toSet); 1931 } 1932 } 1933 1934 // add widgets to notify 1935 for (Item i : toSize) { 1936 if (i instanceof WidgetEdge) { 1937 widgets.add(((WidgetEdge) i).getWidgetSource()); 1938 } else if (i instanceof WidgetCorner) { 1939 widgets.add(((WidgetCorner) i).getWidgetSource()); 1940 } 1941 } 1942 1943 Point2D origin = new Point2D.Float(FrameMouseActions.MouseX, 1944 FrameMouseActions.MouseY); 1945 // Inside enclosures increase the size of the enclosure 1946 double ratio = (100.0 + diff * 2) / 100.0; 1947 if (insideEnclosure) { 1948 Collection<Item> done = new HashSet<Item>(); 1949 // adjust the size of all the items 1950 for (Item i : toSize) { 1951 if (done.contains(i)) 1952 continue; 1953 1954 if (i.isLineEnd()) { 1955 1956 if (!(i instanceof WidgetCorner) 1957 || !((WidgetCorner) i).getWidgetSource() 1958 .isFixedSize()) { // don't size fixed 1959 // widgets 1960 1961 Collection<Item> allConnected = i.getAllConnected(); 1962 done.addAll(allConnected); 1963 for (Item it : allConnected) { 1964 it.translate(origin, ratio); 1965 it.setArrowheadLength((float) (it 1966 .getArrowheadLength() * ratio)); 1967 } 1968 i.setThickness((float) (i.getThickness() * ratio)); 1969 } 1970 } else if (i instanceof XRayable) { 1971 XRayable xRay = (XRayable) i; 1972 Text source = xRay.getSource(); 1973 // Ensure that the source is done before the XRayable 1974 if (!done.contains(source)) { 1975 scaleText(insideEnclosure, origin, ratio, done, source); 1976 } 1977 1978 i.translate(origin, ratio); 1979 i.setThickness((float) (i.getThickness() * ratio)); 1980 done.add(i); 1981 } else if (i.hasVector()) { 1982 // TODO Improve the effiency of resizing vectors... ie... 1983 // dont want to have to reparse all the time 1984 assert (i instanceof Text); 1985 Text text = (Text) i; 1986 AttributeValuePair avp = new AttributeValuePair( 1987 text.getText()); 1988 double scale = 1F; 1989 try { 1990 scale = avp.getDoubleValue(); 1991 } catch (Exception e) { 1992 } 1993 scale *= ratio; 1994 NumberFormat nf = Vector.getNumberFormatter(); 1995 text.setAttributeValue(nf.format(scale)); 1996 text.translate(origin, ratio); 1997 item.getParent().parse(); 1998 } else if (i instanceof Text) { 1999 scaleText(insideEnclosure, origin, ratio, done, (Text) i); 2000 } 2001 } 2002 // refresh anchored items 2003 if (refreshAnchors(toSize)) { 2004 FrameUtils.Parse(DisplayIO.getCurrentFrame(), false); 2005 } 2006 // notify widgets they were resized 2007 for (InteractiveWidget iw : widgets) { 2008 iw.onResized(); 2009 } 2010 FrameGraphics.refresh(true); 2011 return; 2012 } 2013 2014 // adjust the size of all the items 2015 for (Item i : toSize) { 2016 // Lines and dots use thickness, not size 2017 if (i.hasEnclosures()) { 2018 Circle c = (Circle) i.getEnclosures().iterator().next(); 2019 c.setSize(c.getSize() * (float) ratio); 2020 } else if (i instanceof Line || i instanceof Circle 2021 && !insideEnclosure) { 2022 float current = Math.abs(i.getThickness()); 2023 current = Math.max(current + diff, Item.MINIMUM_THICKNESS); 2024 i.setThickness(current); 2025 } else if (i instanceof Dot) { 2026 Item dot = (Item) i; 2027 float current = Math.abs(dot.getThickness()); 2028 current = Math.max(current + diff, Item.MINIMUM_THICKNESS); 2029 dot.setThickness(current); 2030 } else if (i.hasVector()) { 2031 assert (item instanceof Text); 2032 Text text = (Text) item; 2033 AttributeValuePair avp = new AttributeValuePair(text.getText()); 2034 double scale = 1F; 2035 try { 2036 scale = avp.getDoubleValue(); 2037 } catch (Exception e) { 2038 } 2039 scale *= ratio; 2040 NumberFormat nf = Vector.getNumberFormatter(); 2041 text.setAttributeValue(nf.format(scale)); 2042 text.translate(origin, ratio); 2043 item.getParent().parse(); 2044 } else { 2045 float oldSize = Math.abs(i.getSize()); 2046 float newSize = Math 2047 .max(oldSize + diff, Item.MINIMUM_THICKNESS); 2048 float resizeRatio = newSize / oldSize; 2049 // Set size for Picture also translates 2050 i.setSize(newSize); 2051 if (i instanceof Text && i.getSize() != oldSize) { 2052 if (toSize.size() == 1 && !isControlDown) { 2053 moveCursorAndFreeItems(i.getX(), i.getY()); 2054 } else { 2055 i.translate(origin, resizeRatio); 2056 if (i.isLineEnd()) { 2057 i.setPosition(i.getPosition()); 2058 } 2059 } 2060 } 2061 } 2062 } 2063 2064 if (toSet != null) 2065 toSet.getParent().setChanged(true); 2066 2067 // refresh anchored items 2068 if (refreshAnchors(toSize)) { 2069 FrameUtils.Parse(DisplayIO.getCurrentFrame(), false); 2070 } 2071 2072 // notify widgets they were resized 2073 for (InteractiveWidget iw : widgets) { 2074 iw.onResized(); 2075 } 2076 FrameGraphics.refresh(true); 2077 } 2078 2079 /** 2080 * @param origin 2081 * @param ratio 2082 * @param done 2083 * @param source 2084 */ 2085 private static void scaleText(boolean insideEnclosure, Point2D origin, 2086 double ratio, Collection<Item> done, Text source) { 2087 if (insideEnclosure) 2088 source.setWidth(Math.round((float) (source.getWidth() * ratio))); 2089 source.translate(origin, ratio); 2090 source.setSize((float) (source.getSize() * ratio)); 2091 done.add(source); 2092 } 2093 2094 private static void SetFillColor(Item item, boolean setTransparent) { 2095 if (item == null) 2096 return; 2097 2098 if (!item.hasPermission(UserAppliedPermission.full)) { 2099 MessageBay 2100 .displayMessage("Insufficient permission to change fill color"); 2101 return; 2102 } 2103 2104 Item toSet = item; 2105 Color color = toSet.getFillColor(); 2106 if (setTransparent) 2107 color = null; 2108 else 2109 color = ColorUtils.getNextColor(color, 2110 TemplateSettings.FillColorWheel.get(), 2111 toSet.getGradientColor()); 2112 2113 // if (color == null) { 2114 // MessageBay.displayMessage("FillColor is now transparent"); 2115 // } 2116 2117 toSet.setFillColor(color); 2118 toSet.getParent().setChanged(true); 2119 2120 FrameGraphics.Repaint(); 2121 } 2122 2123 private static void SetGradientColor(Item item, boolean setTransparent) { 2124 if (item == null) 2125 return; 2126 2127 if (!item.hasPermission(UserAppliedPermission.full)) { 2128 MessageBay 2129 .displayMessage("Insufficient permission to change gradient color"); 2130 return; 2131 } 2132 2133 Item toSet = item; 2134 Color color = toSet.getGradientColor(); 2135 if (setTransparent) 2136 color = null; 2137 else 2138 color = ColorUtils.getNextColor(color, 2139 TemplateSettings.ColorWheel.get(), toSet.getFillColor()); 2140 2141 // if (color == null) { 2142 // MessageBay.displayMessage("FillColor is now transparent"); 2143 // } 2144 2145 toSet.setGradientColor(color); 2146 toSet.getParent().setChanged(true); 2147 2148 FrameGraphics.Repaint(); 2149 } 2150 2151 /** 2152 * Sets the colour of the current Item based on its current colour. The 2153 * colours proceed in the order stored in COLOR_WHEEL. 2154 * 2155 * @param toSet 2156 * The Item whose colour is to be changed 2157 */ 2158 private static void SetColor(Item item, boolean setTransparent, 2159 boolean setBackgroundColor) { 2160 // first determine the next color 2161 Color color = null; 2162 Frame currentFrame = DisplayIO.getCurrentFrame(); 2163 if (item == null) { 2164 if (FreeItems.itemsAttachedToCursor()) { 2165 color = FreeItems.getInstance().get(0).getColor(); 2166 } else { 2167 return; 2168 } 2169 // change the background color if the user is pointing on the 2170 // frame name 2171 } else if (item == currentFrame.getNameItem()) { 2172 // check permissions 2173 if (!item.hasPermission(UserAppliedPermission.full)) { 2174 MessageBay 2175 .displayMessage("Insufficient permission to the frame's background color"); 2176 return; 2177 } 2178 if (setTransparent) 2179 currentFrame.setBackgroundColor(null); 2180 else 2181 currentFrame.toggleBackgroundColor(); 2182 // Display a message if the color has changed to transparent 2183 // if (currentFrame.getBackgroundColor() == null) 2184 // FrameGraphics 2185 // .displayMessage("Background color is now transparent"); 2186 FrameGraphics.Repaint(); 2187 return; 2188 } else { 2189 // check permissions 2190 if (!item.hasPermission(UserAppliedPermission.full)) { 2191 Item editTarget = item.getEditTarget(); 2192 if (editTarget != item 2193 && editTarget.hasPermission(UserAppliedPermission.full)) { 2194 item = editTarget; 2195 } else { 2196 MessageBay 2197 .displayMessage("Insufficient permission to change color"); 2198 return; 2199 } 2200 } 2201 // Toggling color of circle center changes the circle fill color 2202 if (item.hasEnclosures()) { 2203 if (setBackgroundColor) { 2204 SetGradientColor(item.getEnclosures().iterator().next(), 2205 setTransparent); 2206 } else { 2207 SetFillColor(item.getEnclosures().iterator().next(), 2208 setTransparent); 2209 } 2210 } else if (setBackgroundColor) { 2211 color = item.getPaintBackgroundColor(); 2212 } else { 2213 color = item.getPaintColor(); 2214 } 2215 } 2216 if (setTransparent) 2217 color = null; 2218 else if (setBackgroundColor) { 2219 color = ColorUtils 2220 .getNextColor(color, TemplateSettings.FillColorWheel.get(), 2221 item.getPaintColor()); 2222 } else { 2223 color = ColorUtils.getNextColor(color, 2224 TemplateSettings.ColorWheel.get(), 2225 currentFrame.getPaintBackgroundColor()); 2226 } 2227 // if (currentFrame.getPaintForegroundColor().equals(color)) 2228 // color = null; 2229 2230 // if color is being set to default display a message to indicate that 2231 // if (color == null) { 2232 // MessageBay.displayMessage("Color is set to default"); 2233 // } 2234 2235 if (setBackgroundColor) { 2236 if (item == null && FreeItems.itemsAttachedToCursor()) { 2237 for (Item i : FreeItems.getInstance()) 2238 i.setBackgroundColor(color); 2239 } else { 2240 item.setBackgroundColor(color); 2241 item.getParent().setChanged(true); 2242 } 2243 } else { 2244 if (item == null && FreeItems.itemsAttachedToCursor()) { 2245 for (Item i : FreeItems.getInstance()) 2246 i.setColor(color); 2247 } else { 2248 item.setColor(color); 2249 item.getParent().setChanged(true); 2250 } 2251 } 2252 FrameGraphics.Repaint(); 2253 } 2254 2255 /** 2256 * Toggles the given Item's annotation status on\off. 2257 * 2258 * @param toToggle 2259 * The Item to toggle 2260 */ 2261 private static void ToggleAnnotation(Item toToggle) { 2262 if (toToggle == null) { 2263 MessageBay.displayMessage("There is no Item selected to toggle"); 2264 return; 2265 } 2266 2267 // check permissions 2268 if (!toToggle.hasPermission(UserAppliedPermission.full)) { 2269 MessageBay 2270 .displayMessage("Insufficient permission to toggle that item's annotation"); 2271 return; 2272 } 2273 toToggle.setAnnotation(!toToggle.isAnnotation()); 2274 2275 toToggle.getParent().setChanged(true); 2276 FrameGraphics.Repaint(); 2277 } 2278 2279 /** 2280 * Toggles the face style of a text item 2281 * 2282 * @param toToggle 2283 * The Item to toggle 2284 */ 2285 private static void ToggleFontStyle(Item toToggle) { 2286 if (toToggle == null) { 2287 MessageBay.displayMessage("There is no Item selected to toggle"); 2288 return; 2289 } 2290 2291 // check permissions 2292 if (!toToggle.hasPermission(UserAppliedPermission.full)) { 2293 MessageBay 2294 .displayMessage("Insufficient permission to toggle that item's annotation"); 2295 return; 2296 } 2297 2298 if (toToggle instanceof Text) { 2299 Text text = (Text) toToggle; 2300 text.toggleFontStyle(); 2301 2302 text.getParent().setChanged(true); 2303 FrameGraphics.Repaint(); 2304 } 2305 } 2306 2307 /** 2308 * Toggles the face style of a text item 2309 * 2310 * @param toToggle 2311 * The Item to toggle 2312 */ 2313 private static void ToggleFontFamily(Item toToggle) { 2314 if (toToggle == null) { 2315 MessageBay.displayMessage("There is no Item selected to toggle"); 2316 return; 2317 } 2318 2319 // check permissions 2320 if (!toToggle.hasPermission(UserAppliedPermission.full)) { 2321 MessageBay 2322 .displayMessage("Insufficient permission to toggle that item's annotation"); 2323 return; 2324 } 2325 2326 if (toToggle instanceof Text) { 2327 Text text = (Text) toToggle; 2328 text.toggleFontFamily(); 2329 2330 text.getParent().setChanged(true); 2331 FrameGraphics.Repaint(); 2332 } 2333 } 2334 2335 /** 2336 * If the given Item is null, then a new Text item is created with the 2337 * current date If the given Item is not null, then the current date is 2338 * prepended to the Item's text 2339 * 2340 * @param toAdd 2341 * The Item to prepend the date to, or null 2342 */ 2343 public static void AddDate(Item toAdd) { 2344 String date1 = Formatter.getDateTime(); 2345 String date2 = Formatter.getDate(); 2346 final String leftSeparator = " :"; 2347 final String rightSeparator = ": "; 2348 String dateToAdd = date1 + rightSeparator; 2349 boolean prepend = false; 2350 boolean append = false; 2351 2352 // if the user is pointing at an item, add the date where ever the 2353 // cursor is pointing 2354 if (toAdd != null && toAdd instanceof Text) { 2355 // permission check 2356 if (!toAdd.hasPermission(UserAppliedPermission.full)) { 2357 MessageBay 2358 .displayMessage("Insufficicent permission to add the date to that item"); 2359 return; 2360 } 2361 2362 Text textItem = (Text) toAdd; 2363 2364 String text = textItem.getText(); 2365 2366 // check if the default date has already been put on this item 2367 if (text.startsWith(date1 + rightSeparator)) { 2368 textItem.removeText(date1 + rightSeparator); 2369 dateToAdd = date2 + rightSeparator; 2370 prepend = true; 2371 } else if (text.startsWith(date2 + rightSeparator)) { 2372 textItem.removeText(date2 + rightSeparator); 2373 dateToAdd = leftSeparator + date2; 2374 append = true; 2375 } else if (text.endsWith(leftSeparator + date2)) { 2376 textItem.removeEndText(leftSeparator + date2); 2377 append = true; 2378 dateToAdd = leftSeparator + date1; 2379 } else if (text.endsWith(leftSeparator + date1)) { 2380 textItem.removeEndText(leftSeparator + date1); 2381 if (textItem.getLength() > 0) { 2382 dateToAdd = ""; 2383 prepend = true; 2384 } else { 2385 // use the default date format 2386 prepend = true; 2387 } 2388 } 2389 2390 if (prepend) { 2391 // add the date to the text item 2392 textItem.prependText(dateToAdd); 2393 if (dateToAdd.length() == textItem.getLength()) 2394 DisplayIO.setCursorPosition(textItem 2395 .getParagraphEndPosition()); 2396 } else if (append) { 2397 textItem.appendText(dateToAdd); 2398 if (dateToAdd.length() == textItem.getLength()) 2399 DisplayIO.setCursorPosition(textItem.getPosition()); 2400 } else { 2401 for (int i = 0; i < date1.length(); i++) { 2402 processChar(date1.charAt(i), false); 2403 } 2404 } 2405 2406 textItem.getParent().setChanged(true); 2407 FrameGraphics.Repaint(); 2408 // } else { 2409 // MessageBay 2410 // .displayMessage("Only text items can have the date prepended to 2411 // them"); 2412 // } 2413 // otherwise, create a new text item 2414 } else { 2415 Text newText = createText(); 2416 newText.setText(dateToAdd); 2417 DisplayIO.getCurrentFrame().addItem(newText); 2418 DisplayIO.getCurrentFrame().setChanged(true); 2419 FrameGraphics.Repaint(); 2420 2421 DisplayIO.setCursorPosition(newText.getParagraphEndPosition()); 2422 } 2423 2424 } 2425 2426 /** 2427 * Creates a new Frameset with the name given by the Item 2428 * 2429 * @param name 2430 */ 2431 private static void CreateFrameset(Item item) { 2432 if (item == null) { 2433 MessageBay 2434 .displayMessage("There is no selected item to use for the frameset name"); 2435 return; 2436 } 2437 2438 if (!(item instanceof Text)) { 2439 MessageBay 2440 .displayMessage("Framesets can only be created from text items"); 2441 return; 2442 } 2443 2444 // dont create frameset if the item is linked 2445 if (item.getLink() != null) { 2446 MessageBay 2447 .displayMessage("A frameset can not be created from a linked item"); 2448 return; 2449 } 2450 2451 // check permissions 2452 if (!item.hasPermission(UserAppliedPermission.full)) { 2453 MessageBay 2454 .displayMessage("Insufficient permission to create a frameset from this item"); 2455 return; 2456 } 2457 2458 Text text = (Text) item; 2459 try { 2460 // create the new frameset 2461 Frame linkTo = FrameIO.CreateNewFrameset(text.getFirstLine()); 2462 DisplayIO.setCursor(Item.DEFAULT_CURSOR); 2463 text.setLink(linkTo.getName()); 2464 text.getParent().setChanged(true); 2465 FrameUtils.DisplayFrame(linkTo, true, true); 2466 linkTo.moveMouseToDefaultLocation(); 2467 // this needs to be done if the user doesnt move the mouse before 2468 // doing Tdfc while the cursor is set to the text cursor 2469 DisplayIO.setCursor(Item.DEFAULT_CURSOR); 2470 } catch (Exception e) { 2471 MessageBay.errorMessage(e.getMessage()); 2472 } 2473 } 2474 2475 /** 2476 * Forces a re-parse and repaint of the current Frame. 2477 */ 2478 public static void Refresh() { 2479 Frame currentFrame = DisplayIO.getCurrentFrame(); 2480 2481 if (FrameMouseActions.isShiftDown()) { 2482 currentFrame.refreshSize(); 2483 } 2484 2485 // Refresh widgets that use its self as a data source 2486 currentFrame.notifyObservers(true); 2487 2488 if (FrameIO.isProfileFrame(currentFrame)) { 2489 // TODO ensure that users can not delete the first frame in a 2490 // frameset... 2491 // TODO handle the case when users manually delete the first frame 2492 // in a frameset from the filesystem 2493 Frame profile = FrameIO.LoadFrame(currentFrame.getFramesetName() 2494 + "1"); 2495 assert (profile != null); 2496 FrameUtils.Parse(currentFrame); 2497 FrameUtils.ParseProfile(profile); 2498 } else { 2499 FrameUtils.Parse(currentFrame); 2500 } 2501 // Need to update the cursor for when text items change to @b pictures 2502 // etc and the text cursor is showing 2503 FrameMouseActions.updateCursor(); 2504 FrameMouseActions.getInstance().refreshHighlights(); 2505 FrameGraphics.ForceRepaint(); 2506 } 2507 } 964 }*/
Note:
See TracChangeset
for help on using the changeset viewer.