Ignore:
Timestamp:
05/10/18 16:04:51 (6 years ago)
Author:
davidb
Message:

Reworking of the code-base to separate logic from graphics. This version of Expeditee now supports a JFX graphics as an alternative to SWING

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/gui/FrameKeyboardActions.java

    r1077 r1102  
    1919package org.expeditee.gui;
    2020
    21 import java.awt.Color;
    22 import java.awt.Rectangle;
    2321import java.awt.Toolkit;
    2422import java.awt.datatransfer.StringSelection;
    2523import java.awt.event.KeyEvent;
    2624import java.awt.event.KeyListener;
    27 import java.awt.geom.Point2D;
    2825import java.text.NumberFormat;
    2926import java.util.ArrayList;
     
    3734import org.expeditee.actions.Navigation;
    3835import org.expeditee.actions.Simple;
     36import org.expeditee.core.AxisAlignedBoxBounds;
     37import org.expeditee.core.Colour;
     38import org.expeditee.core.Point;
    3939import org.expeditee.gui.indirect.keyboard.IndirectKeyboardActions;
    4040import org.expeditee.gui.indirect.keyboard.KeyboardAction;
     
    5151import org.expeditee.items.XRayable;
    5252import org.expeditee.items.MagneticConstraint.MagneticConstraints;
    53 import org.expeditee.items.widgets.InteractiveWidget;
     53/*import org.expeditee.items.widgets.InteractiveWidget; TODO: Reinstate. cts16
    5454import org.expeditee.items.widgets.WidgetCorner;
    55 import org.expeditee.items.widgets.WidgetEdge;
     55import org.expeditee.items.widgets.WidgetEdge;*/
    5656import org.expeditee.settings.experimental.ExperimentalFeatures;
    5757import org.expeditee.settings.templates.TemplateSettings;
     
    6060import org.expeditee.stats.SessionStats;
    6161
    62 public class FrameKeyboardActions implements KeyListener {
     62public class FrameKeyboardActions {
    6363
    6464        private static FrameKeyboardActions _instance = new FrameKeyboardActions();
    6565
    6666        protected FrameKeyboardActions() {
    67                 IndirectKeyboardActions.getInstance().setDropDownAction(
     67                /*IndirectKeyboardActions.getInstance().setDropDownAction(
    6868                                new KeyboardAction() {
    6969                                        @Override
     
    8282                                                } else {
    8383                                                        // 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;
    8786                                                        int newY = Text.MARGIN_LEFT
    88                                                                         + rect.y
     87                                                                        + rect.getMinY()
    8988                                                                        + DisplayIO.getCurrentFrame()
    9089                                                                                        .getItemTemplate()
     
    171170                                                return null;
    172171                                        }
    173                                 });
     172                                });*/
    174173                IndirectKeyboardActions.getInstance().setCreateNewTextAction(
    175174                                new KeyboardAction() {
     
    179178                                                                "" + c);
    180179
    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);
    185182
    186183                                                return t;
     
    192189                                        public Text exec(final KeyboardInfo info, final char c) {
    193190                                                float oldY = FrameMouseActions.MouseY;
    194                                                 Point2D.Float newMouse = null;
     191                                                Point newMouse = null;
    195192                                                if (c == '\t') {
    196193                                                        if (info.isShiftDown) {
     
    212209                                                        // float diff = newMouse.y - oldY;
    213210                                                        // System.out.print("c");
    214                                                         Rectangle rect = info.firstConnected.getPolygon().getBounds();
     211                                                        AxisAlignedBoxBounds rect = info.firstConnected.getBounds();
    215212
    216213                                                        // Text lastEdited = FrameUtils.getLastEdited();
     
    218215
    219216                                                        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);
    221218
    222219                                                        // FrameUtils.setLastEdited(lastEdited);
     
    242239        }
    243240
    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 
    252241        public synchronized void keyTyped(KeyEvent e) {
    253242                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)) {
    256244                                Simple.stop();
    257245                                return;
     
    262250                                Simple.KeyStroke(e.getKeyChar());
    263251                        }
    264                         if (Simple.consumeKeyboardInput())
    265                                 return;
     252                       
     253                        if (Simple.consumeKeyboardInput()) return;
    266254                }
    267255
     
    284272                // System.out.println(ch);
    285273
    286                 if (e.isAltDown()) {
    287 
    288                 } else {
    289                         processChar(ch, e.isShiftDown());
    290                 }
     274                if (!e.isAltDown()) processChar(ch, e.isShiftDown());
    291275                // FrameGraphics.Repaint();
    292         }
    293 
    294         public static void processChar(char ch, boolean isShiftDown) {
    295                 Navigation.ResetLastAddToBack();
    296                 Item on = FrameUtils.getCurrentItem();
    297 
    298                 // permission check
    299                 if (on != null && !on.hasPermission(UserAppliedPermission.full)) {
    300                         MessageBay
    301                                         .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 a
    313                         // bug...
    314                         if (_toRemove.getLength() == 0)
    315                                 DisplayIO.getCurrentFrame().removeItem(_toRemove);
    316                 }
    317                 _toRemove = null;
    318 
    319                 // ignore delete and backspace if in free space
    320                 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 text
    327                 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 events
    336                 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 from
    343                 // 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 item
    355                 /*
    356                  * MikeSays: Why do we have to check is highlighted... doing so causes
    357                  * problems if you type characters to fast, they turn into multiple text
    358                  * 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 Frame
    382                 text.getParent().setChanged(true);
    383 
    384                 // check that the Text item still exists (hasn't been deleted\backspaced
    385                 // 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 modified
    408                 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 dot
    419          */
    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. This
    441          * method also moves the mouse cursor to be pointing at the newly created
    442          * Text Item ready to insert the next character.
    443          *
    444          * @param start
    445          *            The character to use as the initial text of this Item.
    446          * @return The newly created Text Item
    447          */
    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 of
    455          * any ItemTemplate if one is present, and inherits all the attributes of
    456          * the Template
    457          *
    458          * @return The newly created Text Item
    459          */
    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 mouse
    475                         // positions over the the frame name navigation occurs
    476                         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                 }
    506276        }
    507277
     
    515285                int keyCode = e.getKeyCode();
    516286
    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) {
    518289                        resetEnclosedItems();
    519290                }
    520291
     292                // Notify the change in stats
     293                // TODO: Will changing this to the Expeditee KBMInputEvent upset stats? cts16
    521294                SessionStats.AddFrameEvent("k" + KeyEvent.getKeyText(keyCode));
    522295
     296                // Used for calculating frame stats (response time)
    523297                FrameUtils.ResponseTimer.restart();
    524298                // e.consume();
    525299
     300                // Things that should consume input before main Expeditee
    526301                if (Actions.isAgentRunning()) {
    527302                        if (keyCode == KeyEvent.VK_ESCAPE)
     
    534309                }
    535310
     311                // Function keys are handled here
    536312                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()) {
    541320                        int distance = e.isShiftDown() ? 1 : 20;
    542321                        switch (keyCode) {
     
    553332                                FrameMouseActions.rightButton();
    554333                                break;
    555                         case KeyEvent.VK_LEFT:
     334/*                      case KeyEvent.VK_LEFT:
    556335                                DisplayIO.translateCursor(-distance, 0);
    557336                                break;
     
    564343                        case KeyEvent.VK_DOWN:
    565344                                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
    570351                switch (keyCode) {
    571352                case KeyEvent.VK_CONTROL:
     
    577358                }
    578359
     360                // Handles all CTRL+KEY combinations
    579361                if (e.isControlDown()) {
    580362                        controlChar(e.getKeyCode(), e.isShiftDown());
     
    582364                }
    583365
    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) {
    585369                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);
    589372                        SessionStats.Escape();
    590373                        break;
    591374                case KeyEvent.VK_LEFT:
    592                         move(Text.LEFT, e.isShiftDown(), e.isControlDown());
     375                        move(Text.LEFT, e.isShiftDown(), false);
    593376                        break;
    594377                case KeyEvent.VK_RIGHT:
    595                         move(Text.RIGHT, e.isShiftDown(), e.isControlDown());
     378                        move(Text.RIGHT, e.isShiftDown(), false);
    596379                        break;
    597380                case KeyEvent.VK_PAGE_DOWN:
     
    602385                        break;
    603386                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);
    609388                        break;
    610389                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);
    616391                        break;
    617392                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);
    622394                        break;
    623395                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);
    628397                        break;
    629398                // TODO remove this when upgrading Java
     
    636405                        }
    637406                        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                }*/
    719408        }
    720409
     
    739428        }
    740429
    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 clipboard
    752                 StringSelection selection = new StringSelection(string);
    753                 Toolkit.getDefaultToolkit().getSystemClipboard()
    754                                 .setContents(selection, null);
    755         }
    756 
    757430        /**
    758431         * Processes all control character keystrokes. Currently Ctrl+C and Ctrl+V
     
    763436         */
    764437        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));
    767439                //
    768440                // if (FrameUtils.getCurrentItem() == null
     
    776448                int distance = isShiftDown ? 1 : 20;
    777449                switch (key) {
    778                 case KeyEvent.VK_HOME:
     450/*              case KeyEvent.VK_HOME:
    779451                        if (current != null && current instanceof Text) {
    780452                                move(Text.HOME, isShiftDown, true);
     
    802474                        break;
    803475                case KeyEvent.VK_ESCAPE:
    804                         // Do escape after control so Ctl+Escape does not perform DropDown
     476                        // Do escape after control so Ctrl+Escape does not perform DropDown
    805477                        functionKey(FunctionKey.DropDown, isShiftDown, true);
    806                         SessionStats.Escape();
     478                        SessionStats.Escape();*/
    807479                        break;
    808480                case KeyEvent.VK_1:
     
    819491                        break;
    820492                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 */{
    825496                                DisplayIO.translateCursor(-distance, 0);
    826497                        }
    827498                        break;
    828499                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 */{
    833503                                DisplayIO.translateCursor(distance, 0);
    834504                        }
    835505                        break;
    836                 case KeyEvent.VK_UP:
     506/*              case KeyEvent.VK_UP:
    837507                        // if (current instanceof Text) {
    838508                        NextTextItem(FrameUtils.getCurrentItem(), false);
     
    849519                        break;
    850520                case KeyEvent.VK_L:
    851                         // If its not linked then link it to its self
     521                        // If its not linked then link it to itself
    852522                        if (current instanceof Text && current.getLink() == null) {
    853523                                String text = ((Text) current).getText();
     
    866536                        }
    867537                        break;
    868                 case KeyEvent.VK_G:
    869                         // If its not linked then link it to its self
     538                case KeyEvent.VK_G: // Same as CTRL+L but follows it afterwards
     539                        // If its not linked then link it to itself
    870540                        if (current instanceof Text) {
    871541                                String text = ((Text) current).getText();
     
    922592                        return;
    923593                case KeyEvent.VK_C:
    924                         if (FreeItems.itemsAttachedToCursor()) {
     594                        if (FreeItems.hasItemsAttachedToCursor()) {
    925595                                ItemSelection.copyClone();
    926596                                return;
     
    933603                        if (current instanceof Dot && current.getLines().size() == 1) {
    934604                                item = replaceDot(current, '@');
    935                         } else if (current instanceof Line
    936                                         && current.getAllConnected().size() == 3) {
     605                        } else if (current instanceof Line && current.getAllConnected().size() == 3) {
    937606                                Item end = ((Line) current).getEndItem();
    938607                                if (end instanceof Dot) {
     
    955624                        if (current == null)
    956625                                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());
    965631                        current.setLinkMark(newValue);
    966632                        current.setActionMark(newValue);
     
    980646                        // perform a delete operation
    981647                        FrameMouseActions.delete(current);
    982                         break;
     648                        break;*/
    983649                case KeyEvent.VK_SPACE:
    984650                        if (isShiftDown) {
     
    988654                        }
    989655                        break;
    990                 case KeyEvent.VK_F:
     656/*              case KeyEvent.VK_F:
    991657                        // perform a format operation
    992658                        if (isShiftDown) {
     
    1012678                        break;
    1013679
    1014                 case KeyEvent.VK_R:
     680                case KeyEvent.VK_R: // TODO: What is this? Similar to above? cts16
    1015681                        Text textCurrent = getCurrentTextItem();
    1016682                        if (textCurrent == null) {
     
    1026692                        break;
    1027693                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!
    1034698                        if (!isShiftDown) {
    1035699                                Save();
     
    1057721                                currentFrame.addItem(newText);
    1058722                        }
    1059                         break;
     723                        break;*/
    1060724                case KeyEvent.VK_ENTER:
    1061725                        FrameMouseActions.leftButton();
    1062726                        break;
    1063                 case KeyEvent.VK_BACK_SPACE:
     727/*              case KeyEvent.VK_BACK_SPACE:
    1064728                        DisplayIO.Back();
    1065                         break;
     729                        break;*/
    1066730                }
    1067731                FrameGraphics.Repaint();
     
    1078742
    1079743                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");
    1082745                        return null;
    1083746                }
     
    1093756        }
    1094757
    1095         public static void functionKey(FunctionKey key, boolean isShiftDown,
    1096                         boolean isControlDown) {
     758/*      public static void functionKey(FunctionKey key, boolean isShiftDown, boolean isControlDown)
     759        {
    1097760                functionKey(key, 1, isShiftDown, isControlDown);
    1098761        }
    1099 
     762*/
    1100763        /**
    1101764         * Called when a Function key has been pressed, and performs the specific
    1102765         * action based on the key.
    1103766         */
    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        {
    1106769                // get whatever the user is pointing at
    1107770                Item on = FrameUtils.getCurrentItem();
     
    1195858                        }
    1196859                }
     860                               
    1197861                // Show a description of the function key pressed if the user is in free
    1198862                // space and return for the F keys that dont do anything in free space.
    1199863                if (on == null) {
    1200864                       
    1201                         int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();
     865                        // int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();
    1202866                       
    1203867                        switch (key) {
    1204868                        // These function keys still work in free space
    1205                         case DropDown:
    1206                         case InsertDate:
     869//                      case DropDown:
     870//                      case InsertDate:
    1207871                        case XRayMode:
    1208872                        case AudienceMode:
    1209873                        case Refresh:
    1210                         case Save:
     874//                      case Save:
    1211875                                break;
    1212876                               
     
    1244908                                }
    1245909                        }
    1246                         Drop(on, false);
     910//                      Drop(on, false);
    1247911                        return;
    1248912                case SizeUp:
    1249913                        SetSize(on, repeat, true, false, isControlDown);
    1250914                        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);
    1253916                        }
    1254917                        break;
     
    1256919                        SetSize(on, -repeat, true, false, isControlDown);
    1257920                        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);
    1260922                        }
    1261923                        break;
     
    1300962                        MessageBay.displayMessage(displayMessage);
    1301963        }
    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.