source: trunk/src/org/expeditee/gui/FrameKeyboardActions.java@ 1460

Last change on this file since 1460 was 1102, checked in by davidb, 6 years ago

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 size: 28.2 KB
RevLine 
[919]1/**
2 * FrameKeyboardActions.java
3 * Copyright (C) 2010 New Zealand Digital Library, http://expeditee.org
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
[4]19package org.expeditee.gui;
20
21import java.awt.Toolkit;
22import java.awt.datatransfer.StringSelection;
23import java.awt.event.KeyEvent;
24import java.awt.event.KeyListener;
[286]25import java.text.NumberFormat;
[4]26import java.util.ArrayList;
[72]27import java.util.Collection;
[156]28import java.util.Collections;
[108]29import java.util.HashSet;
[4]30import java.util.LinkedList;
31import java.util.List;
32
33import org.expeditee.actions.Actions;
[306]34import org.expeditee.actions.Navigation;
[4]35import org.expeditee.actions.Simple;
[1102]36import org.expeditee.core.AxisAlignedBoxBounds;
37import org.expeditee.core.Colour;
38import org.expeditee.core.Point;
[943]39import org.expeditee.gui.indirect.keyboard.IndirectKeyboardActions;
40import org.expeditee.gui.indirect.keyboard.KeyboardAction;
[949]41import org.expeditee.gui.indirect.keyboard.KeyboardInfo;
[504]42import org.expeditee.io.ItemSelection;
[108]43import org.expeditee.items.Circle;
[4]44import org.expeditee.items.Dot;
45import org.expeditee.items.Item;
46import org.expeditee.items.ItemUtils;
47import org.expeditee.items.Line;
[1064]48import org.expeditee.items.Picture;
[778]49import org.expeditee.items.Text;
[454]50import org.expeditee.items.UserAppliedPermission;
[108]51import org.expeditee.items.XRayable;
[928]52import org.expeditee.items.MagneticConstraint.MagneticConstraints;
[1102]53/*import org.expeditee.items.widgets.InteractiveWidget; TODO: Reinstate. cts16
[229]54import org.expeditee.items.widgets.WidgetCorner;
[1102]55import org.expeditee.items.widgets.WidgetEdge;*/
[1051]56import org.expeditee.settings.experimental.ExperimentalFeatures;
[778]57import org.expeditee.settings.templates.TemplateSettings;
[419]58import org.expeditee.stats.Formatter;
59import org.expeditee.stats.Logger;
[4]60import org.expeditee.stats.SessionStats;
61
[1102]62public class FrameKeyboardActions {
[362]63
[345]64 private static FrameKeyboardActions _instance = new FrameKeyboardActions();
[362]65
[764]66 protected FrameKeyboardActions() {
[1102]67 /*IndirectKeyboardActions.getInstance().setDropDownAction(
[944]68 new KeyboardAction() {
69 @Override
70 public Text exec(final KeyboardInfo info, final char c) {
71 // Get the last text item and drop from in
72 Item lastText = null;
73 for (Item i : info.enclosed) {
74 if (i instanceof Text) {
75 lastText = i;
76 }
77 }
78 // Drop from the item if there was a text item in the
79 // box
80 if (lastText != null) {
81 Drop(lastText, false);
82 } else {
83 // Move to the top of the box
[1102]84 AxisAlignedBoxBounds rect = info.firstConnected.getBounds();
85 int newX = rect.getMinX() + Text.MARGIN_LEFT;
[944]86 int newY = Text.MARGIN_LEFT
[1102]87 + rect.getMinY()
[944]88 + DisplayIO.getCurrentFrame()
89 .getItemTemplate()
90 .getBoundsHeight();
91 moveCursorAndFreeItems(newX, newY);
92 // TODO can resetOffset be put inside
93 // moveCursorAndFreeItems
94 FrameMouseActions.resetOffset();
95 }
96 return null;
[943]97 }
[944]98 });
99 IndirectKeyboardActions.getInstance().setSizeUpAction(
100 new KeyboardAction() {
101 @Override
102 public Text exec(final KeyboardInfo info, final char c) {
103 SetSize(info.firstConnected, info.repeat, false, true,
104 info.isControlDown);
105 return null;
[943]106 }
[944]107 });
108 IndirectKeyboardActions.getInstance().setSizeDownAction(
109 new KeyboardAction() {
110 @Override
111 public Text exec(final KeyboardInfo info, final char c) {
112 SetSize(info.firstConnected, -info.repeat, false, true,
113 info.isControlDown);
114 return null;
115 }
116 });
117 IndirectKeyboardActions.getInstance().setChangeColorAction(
118 new KeyboardAction() {
119 @Override
120 public Text exec(final KeyboardInfo info, final char c) {
121 if (info.connected.size() > 0) {
122 for (Item d : info.lineEnds) {
123 if (info.isControlDown)
124 SetGradientColor(d, info.isShiftDown);
125 else
126 SetFillColor(d, info.isShiftDown);
127 break;
128 }
129 }
130 return null;
131 }
132 });
133 IndirectKeyboardActions.getInstance().setToggleAnnotationAction(
134 new KeyboardAction() {
135 @Override
136 public Text exec(final KeyboardInfo info, final char c) {
137 ToggleAnnotation(info.firstConnected);
138 return null;
139 }
140 });
141 IndirectKeyboardActions.getInstance().setChangeFontStyleAction(
142 new KeyboardAction() {
143 @Override
144 public Text exec(final KeyboardInfo info, final char c) {
145 ToggleFontStyle(info.firstConnected);
146 return null;
147 }
148 });
149 IndirectKeyboardActions.getInstance().setChangeFontFamilyAction(
150 new KeyboardAction() {
151 @Override
152 public Text exec(final KeyboardInfo info, final char c) {
153 ToggleFontFamily(info.firstConnected);
154 return null;
155 }
156 });
157 IndirectKeyboardActions.getInstance().setInsertDateAction(
158 new KeyboardAction() {
159 @Override
160 public Text exec(final KeyboardInfo info, final char c) {
161 AddDate(info.firstConnected);
162 return null;
163 }
164 });
165 IndirectKeyboardActions.getInstance().setSaveAction(
166 new KeyboardAction() {
167 @Override
168 public Text exec(final KeyboardInfo info, final char c) {
169 Save();
170 return null;
171 }
[1102]172 });*/
[944]173 IndirectKeyboardActions.getInstance().setCreateNewTextAction(
174 new KeyboardAction() {
175 @Override
176 public Text exec(KeyboardInfo info, char c) {
177 Text t = DisplayIO.getCurrentFrame().createBlankText(
178 "" + c);
179
[1102]180 Point newMouse = t.insertChar(c, DisplayIO.getMouseX(), FrameMouseActions.getY());
181 DisplayIO.setCursorPosition(newMouse.x, newMouse.y, false);
[944]182
183 return t;
184 }
185 });
186 IndirectKeyboardActions.getInstance().setInsertCharacterAction(
187 new KeyboardAction() {
188 @Override
189 public Text exec(final KeyboardInfo info, final char c) {
190 float oldY = FrameMouseActions.MouseY;
[1102]191 Point newMouse = null;
[944]192 if (c == '\t') {
193 if (info.isShiftDown) {
194 newMouse = ((Text)info.firstConnected).removeTab(c, DisplayIO.getFloatMouseX(),
195 FrameMouseActions.MouseY);
196 } else {
197 newMouse = ((Text)info.firstConnected).insertTab(c, DisplayIO.getFloatMouseX(),
198 FrameMouseActions.MouseY);
199 }
200 } else {
201 newMouse = ((Text)info.firstConnected).insertChar(c, DisplayIO.getFloatMouseX(),
202 FrameMouseActions.MouseY);
203 }
204 /*
205 * check if the user hit enter and the cursor is now on another text
206 * item
207 */
208 if (oldY < newMouse.y) {
209 // float diff = newMouse.y - oldY;
210 // System.out.print("c");
[1102]211 AxisAlignedBoxBounds rect = info.firstConnected.getBounds();
[944]212
213 // Text lastEdited = FrameUtils.getLastEdited();
214 // FrameUtils.setLastEdited(null);
215
216 Item justBelow = FrameUtils.onItem(DisplayIO.getCurrentFrame(),
[1102]217 info.firstConnected.getX() + 10, rect.getMinY() + rect.getHeight() + 1, false);
[944]218
219 // FrameUtils.setLastEdited(lastEdited);
220
221 // Dont drop unless
222 if (justBelow != null && justBelow instanceof Text
223 && justBelow != info.firstConnected) {
224 // Drop all the items below it down!
225 // Get the list of items that must be dropped
226 List<Text> column = DisplayIO.getCurrentFrame().getColumn(info.firstConnected);
227 FrameUtils.Align(column, false, 0);
228 }
229 }
230
231 DisplayIO.setCursorPosition(newMouse.x, newMouse.y, false);
232 return (Text) info.firstConnected;
233 }
234 });
[345]235 }
[362]236
[345]237 public static FrameKeyboardActions getInstance() {
238 return _instance;
239 }
[4]240
241 public synchronized void keyTyped(KeyEvent e) {
[86]242 if (Simple.isProgramRunning()) {
[1102]243 if (e.isControlDown() && (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.getKeyChar() == KeyEvent.VK_C)) {
[86]244 Simple.stop();
[108]245 return;
[87]246 } else if (e.isControlDown() && e.getKeyChar() == KeyEvent.VK_SPACE) {
[86]247 Simple.nextStatement();
[108]248 return;
249 } else {
250 Simple.KeyStroke(e.getKeyChar());
[86]251 }
[1102]252
253 if (Simple.consumeKeyboardInput()) return;
[4]254 }
255
256 // ignore escape character and control characters
257 if (e.getKeyChar() == KeyEvent.VK_ESCAPE || e.isControlDown()) {
258 return;
259 }
260
[108]261 // Deal with splitting text items when typing too fast
262 // Mike: thinks this problem may have been solved and was due to
263 // rounding errors in the text class...
264 // It may have been fixed by changing to the use of floats instead of
265 // ints for text positioning etc
266 // if (FrameMouseActions.isWaitingForRobot()) {
267 // System.out.println("Waiting: " + e.getKeyChar());
268 // return;
269 // }
[4]270 e.consume();
271 char ch = e.getKeyChar();
[78]272 // System.out.println(ch);
273
[1102]274 if (!e.isAltDown()) processChar(ch, e.isShiftDown());
[4]275 // FrameGraphics.Repaint();
276 }
277
[72]278 /**
[4]279 * Receives and processes any Function, Control, and Escape key presses
280 *
281 * @param e
282 * The KeyEvent received from the keyboard
283 */
284 public void keyPressed(KeyEvent e) {
[145]285 int keyCode = e.getKeyCode();
[286]286
[1102]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) {
[282]289 resetEnclosedItems();
290 }
[286]291
[1102]292 // Notify the change in stats
293 // TODO: Will changing this to the Expeditee KBMInputEvent upset stats? cts16
[145]294 SessionStats.AddFrameEvent("k" + KeyEvent.getKeyText(keyCode));
[4]295
[1102]296 // Used for calculating frame stats (response time)
[4]297 FrameUtils.ResponseTimer.restart();
[147]298 // e.consume();
[4]299
[1102]300 // Things that should consume input before main Expeditee
[4]301 if (Actions.isAgentRunning()) {
[145]302 if (keyCode == KeyEvent.VK_ESCAPE)
[4]303 Actions.stopAgent();
304 else
305 Actions.interruptAgent();
306 return;
[87]307 } else if (Simple.consumeKeyboardInput()) {
[4]308 return;
309 }
310
[1102]311 // Function keys are handled here
[145]312 if (keyCode >= KeyEvent.VK_F1 && keyCode <= KeyEvent.VK_F12) {
[1102]313 functionKey(FunctionKey.values()[keyCode - KeyEvent.VK_F1 + 1], e.isShiftDown(), e.isControlDown());
[4]314 return;
[1102]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()) {
[176]320 int distance = e.isShiftDown() ? 1 : 20;
[145]321 switch (keyCode) {
322 case KeyEvent.VK_1:
[147]323 FrameMouseActions.leftButton();
324 // DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
[145]325 break;
326 case KeyEvent.VK_2:
[147]327 // DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
328 FrameMouseActions.middleButton();
[145]329 break;
330 case KeyEvent.VK_3:
[147]331 // DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
332 FrameMouseActions.rightButton();
[145]333 break;
[1102]334/* case KeyEvent.VK_LEFT:
[145]335 DisplayIO.translateCursor(-distance, 0);
336 break;
337 case KeyEvent.VK_RIGHT:
338 DisplayIO.translateCursor(distance, 0);
339 break;
340 case KeyEvent.VK_UP:
341 DisplayIO.translateCursor(0, -distance);
342 break;
343 case KeyEvent.VK_DOWN:
344 DisplayIO.translateCursor(0, distance);
[1102]345 break;*/
[145]346 }
[108]347 return;
[427]348 }
[1102]349
350 // Notify the mouse handler of the control/shift key state
[427]351 switch (keyCode) {
352 case KeyEvent.VK_CONTROL:
353 FrameMouseActions.control(e);
354 break;
355 case KeyEvent.VK_SHIFT:
356 FrameMouseActions.shift(e);
357 break;
358 }
359
[1102]360 // Handles all CTRL+KEY combinations
[427]361 if (e.isControlDown()) {
362 controlChar(e.getKeyCode(), e.isShiftDown());
[145]363 return;
[108]364 }
[4]365
[1102]366 // Handles all other keystrokes (with possible shift modifier)
367 // Note: At this point e.isControlDown() must be false
368/* switch (keyCode) {
[145]369 case KeyEvent.VK_ESCAPE:
[1102]370 // Do escape after control so Ctrl+Escape does not perform DropDown
371 functionKey(FunctionKey.DropDown, e.isShiftDown(), false);
[108]372 SessionStats.Escape();
[97]373 break;
[4]374 case KeyEvent.VK_LEFT:
[1102]375 move(Text.LEFT, e.isShiftDown(), false);
[4]376 break;
377 case KeyEvent.VK_RIGHT:
[1102]378 move(Text.RIGHT, e.isShiftDown(), false);
[4]379 break;
[13]380 case KeyEvent.VK_PAGE_DOWN:
381 navigateFrame(Text.PAGE_DOWN);
382 break;
383 case KeyEvent.VK_PAGE_UP:
384 navigateFrame(Text.PAGE_UP);
385 break;
[4]386 case KeyEvent.VK_UP:
[1102]387 move(Text.UP, e.isShiftDown(), false);
[4]388 break;
389 case KeyEvent.VK_DOWN:
[1102]390 move(Text.DOWN, e.isShiftDown(), false);
[4]391 break;
392 case KeyEvent.VK_END:
[1102]393 move(Text.LINE_END, e.isShiftDown(), false);
[4]394 break;
395 case KeyEvent.VK_HOME:
[1102]396 move(Text.LINE_HOME, e.isShiftDown(), false);
[4]397 break;
[147]398 // TODO remove this when upgrading Java
399 // This is a patch because Java6 wont trigger KeyTyped event for
400 // Shift+Tab
401 case KeyEvent.VK_TAB:
402 if (e.isShiftDown()) {
403 e.setKeyChar('\t');
404 keyTyped(e);
405 }
406 break;
[1102]407 }*/
[4]408 }
409
410 public void keyReleased(KeyEvent e) {
[97]411 if (e.getKeyCode() == KeyEvent.VK_CONTROL) {
[108]412 FrameMouseActions.control(e);
[427]413 } else if (e.getKeyCode() == KeyEvent.VK_SHIFT) {
414 FrameMouseActions.shift(e);
[147]415 } else if (e.isAltDown() || e.isControlDown()) {
416 // switch (e.getKeyCode()) {
417 // case KeyEvent.VK_1:
418 // DisplayIO.releaseMouse(InputEvent.BUTTON1_MASK);
419 // break;
420 // case KeyEvent.VK_2:
421 // DisplayIO.releaseMouse(InputEvent.BUTTON2_MASK);
422 // break;
423 // case KeyEvent.VK_3:
424 // DisplayIO.releaseMouse(InputEvent.BUTTON3_MASK);
425 // break;
426 // }
[97]427 }
[4]428 }
429
[7]430 /**
[4]431 * Processes all control character keystrokes. Currently Ctrl+C and Ctrl+V
432 * are copy and paste, all other keystrokes are ignored.
433 *
434 * @param ch
435 * The character being pressed along with the control key
436 */
[176]437 private void controlChar(int key, boolean isShiftDown) {
[1102]438 //Logger.Log(Logger.USER, Logger.CONTROL_CHAR, "User pressing: Ctrl+" + KeyEvent.getKeyText(key));
[87]439 //
440 // if (FrameUtils.getCurrentItem() == null
441 // && !Frame.itemAttachedToCursor()) {
442 // Item t = DisplayIO.getCurrentFrame().createNewText(ch + ": ");
443 // FrameMouseActions.pickup(t);
444 // } else {
[376]445 // remove the link for ctrl+l
[87]446 Item current = FrameUtils.getCurrentItem();
447 Frame currentFrame = DisplayIO.getCurrentFrame();
[176]448 int distance = isShiftDown ? 1 : 20;
[145]449 switch (key) {
[1102]450/* case KeyEvent.VK_HOME:
[176]451 if (current != null && current instanceof Text) {
[376]452 move(Text.HOME, isShiftDown, true);
[176]453 } else {
454 while (DisplayIO.Back())
455 ;
456 }
457 break;
458 case KeyEvent.VK_END:
459 if (current != null && current instanceof Text) {
[376]460 move(Text.END, isShiftDown, true);
[176]461 } else {
462 while (DisplayIO.Forward())
463 ;
464 }
465 break;
466 case KeyEvent.VK_PAGE_UP:
467 DisplayIO.Back();
468 break;
469 case KeyEvent.VK_PAGE_DOWN:
470 DisplayIO.Forward();
471 break;
[161]472 case KeyEvent.VK_TAB:
[294]473 calculateItem(current);
[161]474 break;
475 case KeyEvent.VK_ESCAPE:
[1102]476 // Do escape after control so Ctrl+Escape does not perform DropDown
[161]477 functionKey(FunctionKey.DropDown, isShiftDown, true);
[1102]478 SessionStats.Escape();*/
[161]479 break;
[145]480 case KeyEvent.VK_1:
[147]481 FrameMouseActions.leftButton();
482 // DisplayIO.clickMouse(InputEvent.BUTTON1_MASK);
[145]483 break;
484 case KeyEvent.VK_2:
[147]485 FrameMouseActions.middleButton();
486 // DisplayIO.clickMouse(InputEvent.BUTTON2_MASK);
[145]487 break;
488 case KeyEvent.VK_3:
[147]489 FrameMouseActions.rightButton();
490 // DisplayIO.clickMouse(InputEvent.BUTTON3_MASK);
[145]491 break;
492 case KeyEvent.VK_LEFT:
[1102]493/* if (current instanceof Text) {
494 DisplayIO.setTextCursor((Text) current, Text.LEFT, false, isShiftDown, true, true);
495 } else */{
[376]496 DisplayIO.translateCursor(-distance, 0);
[176]497 }
[145]498 break;
[376]499 case KeyEvent.VK_RIGHT:
[1102]500/* if (current instanceof Text) {
501 DisplayIO.setTextCursor((Text) current, Text.RIGHT, false, isShiftDown, true, true);
502 } else */{
[376]503 DisplayIO.translateCursor(distance, 0);
[176]504 }
[145]505 break;
[1102]506/* case KeyEvent.VK_UP:
[376]507 // if (current instanceof Text) {
508 NextTextItem(FrameUtils.getCurrentItem(), false);
509 // } else {
510 // DisplayIO.translateCursor(0, -distance);
511 // }
512 break;
513 case KeyEvent.VK_DOWN:
514 // if (current instanceof Text) {
515 NextTextItem(FrameUtils.getCurrentItem(), true);
516 // } else {
517 // DisplayIO.translateCursor(0, distance);
518 // }
519 break;
[145]520 case KeyEvent.VK_L:
[1102]521 // If its not linked then link it to itself
[87]522 if (current instanceof Text && current.getLink() == null) {
523 String text = ((Text) current).getText();
[145]524 // Ignore the annotation if there is one
525 if (text.charAt(0) == '@')
[130]526 text = text.substring(1);
[145]527
[87]528 if (FrameIO.isValidFrameName(text)) {
529 current.setLink(text);
530 } else if (FrameIO.isValidFramesetName(text)) {
531 current.setLink(text + '1');
532 }
[297]533 } else if (current != null) {
[87]534 // If its linked remove the link
535 current.setLink(null);
536 }
[145]537 break;
[1102]538 case KeyEvent.VK_G: // Same as CTRL+L but follows it afterwards
539 // If its not linked then link it to itself
[87]540 if (current instanceof Text) {
541 String text = ((Text) current).getText();
[130]542 if (text.charAt(0) == '@')
543 text = text.substring(1);
544
[87]545 if (FrameIO.isValidFrameName(text)) {
546 current.setLink(text);
547 } else if (FrameIO.isValidFramesetName(text)) {
548 current.setLink(text + '1');
549 }
550 }
[314]551 if (current != null && current.getLink() != null) {
[306]552 Navigation.Goto(current.getAbsoluteLink());
[87]553 return;
554 }
[145]555 break;
556 case KeyEvent.VK_A:
[87]557 // If its not linked then link it to its self
[115]558 if (current instanceof Text) {
[133]559 if (!current.hasAction()) {
[115]560 String text = ((Text) current).getText().trim();
561 // first trim the annotation
562 if (text.startsWith("@")) {
563 text = text.substring(1).trim();
564 }
565 // then trim the action
566 String lowerCaseText = text.toLowerCase();
567 if (lowerCaseText.startsWith("a:")) {
568 text = text.substring("a:".length()).trim();
569 } else if (lowerCaseText.startsWith("action:")) {
570 text = text.substring("action:".length()).trim();
[95]571
[115]572 }
573 current.setAction(text);
574 } else {
575 // If its linked remove the link
576 current.setActions(null);
[88]577 }
[87]578 }
[145]579 break;
[362]580 case KeyEvent.VK_B:
581 if (current instanceof Text) {
582 ((Text) current).toggleBold();
583 }
584 break;
585 case KeyEvent.VK_I:
586 if (current instanceof Text) {
587 ((Text) current).toggleItalics();
588 }
589 break;
[145]590 case KeyEvent.VK_V:
[504]591 ItemSelection.paste();
592 return;
[145]593 case KeyEvent.VK_C:
[1102]594 if (FreeItems.hasItemsAttachedToCursor()) {
[740]595 ItemSelection.copyClone();
[108]596 return;
[504]597 }
[944]598 if (current instanceof Text) {
[108]599 copyItemToClipboard(current);
600 }
601 Text item = null;
602 // Check if its a line to be turned into a circle
603 if (current instanceof Dot && current.getLines().size() == 1) {
604 item = replaceDot(current, '@');
[1102]605 } else if (current instanceof Line && current.getAllConnected().size() == 3) {
[108]606 Item end = ((Line) current).getEndItem();
607 if (end instanceof Dot) {
608 item = replaceDot(end, '@');
609 } else if (end instanceof Text) {
610 item = (Text) end;
611 }
612 }
[293]613 if (item != null) {
614 item.setText("@c");
615 DisplayIO.setCursorPosition(item.getX(), item.getY());
616 FrameUtils.setLastEdited(null);
617 Refresh();
618 }
[105]619 return;
[145]620 case KeyEvent.VK_X:
[740]621 ItemSelection.cut();
[4]622 return;
[145]623 case KeyEvent.VK_M:
[108]624 if (current == null)
625 return;
[1102]626 if (current != null && !current.hasPermission(UserAppliedPermission.full)) {
627 MessageBay.displayMessage("Insufficient permission toggle the items mark");
[108]628 return;
629 }
[1102]630 boolean newValue = !(current.getLinkMark() || current.getActionMark());
[108]631 current.setLinkMark(newValue);
632 current.setActionMark(newValue);
[145]633 break;
634 case KeyEvent.VK_Z:
[944]635 if (isShiftDown) {
[744]636 DisplayIO.getCurrentFrame().redo();
637 } else {
638 DisplayIO.getCurrentFrame().undo();
639 }
[108]640 return;
[145]641 case KeyEvent.VK_D:
[4]642 // perform a delete operation
[108]643 processChar((char) KeyEvent.VK_DELETE, isShiftDown);
[145]644 break;
645 case KeyEvent.VK_DELETE:
[105]646 // perform a delete operation
[87]647 FrameMouseActions.delete(current);
[1102]648 break;*/
[145]649 case KeyEvent.VK_SPACE:
650 if (isShiftDown) {
651 FrameMouseActions.rightButton();
652 } else {
653 FrameMouseActions.middleButton();
654 }
655 break;
[1102]656/* case KeyEvent.VK_F:
[415]657 // perform a format operation
[427]658 if (isShiftDown) {
659 Actions.PerformActionCatchErrors(currentFrame, null, "HFormat");
660 } else {
661 Actions.PerformActionCatchErrors(currentFrame, null, "Format");
662 }
[87]663 return;
[145]664 case KeyEvent.VK_J:
[4]665 Text text = getCurrentTextItem();
[247]666 if (text == null) {
[376]667 for (Text t : currentFrame.getBodyTextItems(false)) {
[400]668 t.justify(true);
[242]669 }
[247]670
[4]671 return;
[242]672 }
[4]673
[154]674 // if (text.getWidth() < 0)
675 // text.setWidth(text.getBoundsWidth() - Item.MARGIN_RIGHT
676 // - UserSettings.Gravity);
[400]677 text.justify(true);
[145]678 break;
[410]679
[1102]680 case KeyEvent.VK_R: // TODO: What is this? Similar to above? cts16
[410]681 Text textCurrent = getCurrentTextItem();
682 if (textCurrent == null) {
683 for (Text t : currentFrame.getBodyTextItems(false)) {
684 t.setWidth(null);
685 t.justify(true);
686 }
687
688 return;
689 }
690 textCurrent.setWidth(null);
691 textCurrent.justify(true);
692 break;
[145]693 case KeyEvent.VK_S:
[1102]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!
[362]698 if (!isShiftDown) {
[348]699 Save();
700 return;
701 }
[145]702 Text text2 = getCurrentTextItem();
[4]703 // split the current text item
[145]704 if (text2 == null)
[4]705 return;
[145]706 List<String> textLines = text2.getTextList();
[4]707 if (textLines.size() <= 1)
708 return;
709 // remove all except the first line of text from the item being
710 // split
[145]711 text2.setText(textLines.get(0));
712 int y = text2.getY();
[4]713 for (int i = 1; i < textLines.size(); i++) {
[145]714 Text newText = text2.copy();
[4]715 newText.setText(textLines.get(i));
716 y += newText.getBoundsHeight();
717 newText.setY(y);
718 // update the items ID to prevent conflicts with the current
719 // frame
[87]720 newText.setID(currentFrame.getNextItemID());
721 currentFrame.addItem(newText);
[4]722 }
[1102]723 break;*/
[145]724 case KeyEvent.VK_ENTER:
725 FrameMouseActions.leftButton();
726 break;
[1102]727/* case KeyEvent.VK_BACK_SPACE:
[108]728 DisplayIO.Back();
[1102]729 break;*/
[87]730 }
[95]731 FrameGraphics.Repaint();
[4]732 }
733
734 /**
735 * Gets the currently selected item if the user is allowed to modify it.
736 *
737 * @return null if the currently selected item is not a Text item that the
738 * user has permission to modify
739 */
740 private static Text getCurrentTextItem() {
[108]741 Item item = FrameUtils.getCurrentItem();
[4]742
[454]743 if (item != null && !item.hasPermission(UserAppliedPermission.full)) {
[1102]744 MessageBay.displayMessage("Insufficient permission to copy that item");
[4]745 return null;
746 }
747
748 Item on = null;
[108]749 if (item != null)
750 on = item;
[4]751
752 if (on == null || !(on instanceof Text))
753 return null;
754
755 return (Text) on;
756 }
757
[1102]758/* public static void functionKey(FunctionKey key, boolean isShiftDown, boolean isControlDown)
759 {
[115]760 functionKey(key, 1, isShiftDown, isControlDown);
[21]761 }
[1102]762*/
[4]763 /**
764 * Called when a Function key has been pressed, and performs the specific
765 * action based on the key.
766 */
[1102]767/* public static void functionKey(FunctionKey key, int repeat, boolean isShiftDown, boolean isControlDown)
768 {
[4]769 // get whatever the user is pointing at
[7]770 Item on = FrameUtils.getCurrentItem();
[289]771 String displayMessage = "F" + key.ordinal() + ": " + key.toString();
[4]772 // check for enclosed mode
[80]773 if (on == null && key.ordinal() < FunctionKey.AudienceMode.ordinal()) {
[86]774 Collection<Item> enclosed = FrameUtils.getCurrentItems(on);
[161]775
[4]776 if (enclosed != null && enclosed.size() > 0) {
777 // ensure only one dot\line is present in the list
[108]778 Collection<Item> lineEnds = FrameUtils.getEnclosingLineEnds();
779 Item firstConnected = lineEnds.iterator().next();
[72]780 Collection<Item> connected = firstConnected.getAllConnected();
[4]781
[72]782 switch (key) {
[176]783 case DropDown:
[944]784 IndirectKeyboardActions
785 .getInstance()
786 .getDropDownAction()
787 .exec(new KeyboardInfo(key, repeat, isShiftDown,
788 isControlDown, enclosed, firstConnected,
789 connected, lineEnds), (char) 0);
[176]790 break;
[80]791 case SizeUp:
[944]792 IndirectKeyboardActions
793 .getInstance()
794 .getSizeUpAction()
795 .exec(new KeyboardInfo(key, repeat, isShiftDown,
796 isControlDown, enclosed, firstConnected,
797 connected, lineEnds), (char) 0);
[72]798 break;
[80]799 case SizeDown:
[944]800 IndirectKeyboardActions
801 .getInstance()
802 .getSizeDownAction()
803 .exec(new KeyboardInfo(key, repeat, isShiftDown,
804 isControlDown, enclosed, firstConnected,
805 connected, lineEnds), (char) 0);
[72]806 break;
[80]807 case ChangeColor:
[944]808 IndirectKeyboardActions
809 .getInstance()
810 .getChangeColorAction()
811 .exec(new KeyboardInfo(key, repeat, isShiftDown,
812 isControlDown, enclosed, firstConnected,
813 connected, lineEnds), (char) 0);
[80]814 break;
815 case ToggleAnnotation:
[944]816 IndirectKeyboardActions
817 .getInstance()
818 .getToggleAnnotationAction()
819 .exec(new KeyboardInfo(key, repeat, isShiftDown,
820 isControlDown, enclosed, firstConnected,
821 connected, lineEnds), (char) 0);
[72]822 break;
[80]823 case ChangeFontStyle:
[944]824 IndirectKeyboardActions
825 .getInstance()
826 .getChangeFontStyleAction()
827 .exec(new KeyboardInfo(key, repeat, isShiftDown,
828 isControlDown, enclosed, firstConnected,
829 connected, lineEnds), (char) 0);
[72]830 break;
[80]831 case ChangeFontFamily:
[944]832 IndirectKeyboardActions
833 .getInstance()
834 .getChangeFontFamilyAction()
835 .exec(new KeyboardInfo(key, repeat, isShiftDown,
836 isControlDown, enclosed, firstConnected,
837 connected, lineEnds), (char) 0);
[72]838 break;
[80]839 case InsertDate:
[944]840 IndirectKeyboardActions
841 .getInstance()
842 .getInsertDateAction()
843 .exec(new KeyboardInfo(key, repeat, isShiftDown,
844 isControlDown, enclosed, firstConnected,
845 connected, lineEnds), (char) 0);
[72]846 break;
[289]847 case Save:
[944]848 IndirectKeyboardActions
849 .getInstance()
850 .getSaveAction()
851 .exec(new KeyboardInfo(key, repeat, isShiftDown,
852 isControlDown, enclosed, firstConnected,
853 connected, lineEnds), (char) 0);
[289]854 MessageBay.displayMessage(displayMessage);
855 break;
[4]856 }
857 return;
858 }
859 }
[1102]860
[80]861 // Show a description of the function key pressed if the user is in free
862 // space and return for the F keys that dont do anything in free space.
863 if (on == null) {
[1051]864
[1102]865 // int mouse_x = FrameMouseActions.getX(), mouse_y = FrameMouseActions.getY();
[1051]866
[80]867 switch (key) {
[86]868 // These function keys still work in free space
[1102]869// case DropDown:
870// case InsertDate:
[80]871 case XRayMode:
872 case AudienceMode:
873 case Refresh:
[1102]874// case Save:
[80]875 break;
[1051]876
[289]877 case SizeDown:
[1051]878 zoomFrameIfEnabled(DisplayIO.getCurrentFrame(), 0.909090909f, mouse_x,mouse_y);
[944]879 // if (isControlDown) {
880 // UserSettings.ScaleFactor.set(UserSettings.ScaleFactor.get() -
881 // 0.05f);
882 // Misc.repaint();
883 // return;
884 // }
[1051]885 return;
886
[289]887 case SizeUp:
[1051]888 zoomFrameIfEnabled(DisplayIO.getCurrentFrame(), 1.1f, mouse_x,mouse_y);
889 // if (isControlDown) {
890 // UserSettings.ScaleFactor.set(UserSettings.ScaleFactor.get() +
891 // 0.05f);
892 // Misc.repaint();
893 // return;
894 // }
[850]895 return;
[1051]896
[80]897 default:
[121]898 MessageBay.displayMessageOnce(displayMessage);
[80]899 return;
900 }
901 }
[4]902
903 switch (key) {
[80]904 case DropDown:
[161]905 if (isShiftDown || isControlDown) {
[235]906 if (on != null) {
[294]907 calculateItem(on);
[235]908 }
[161]909 }
[1102]910// Drop(on, false);
[80]911 return;
912 case SizeUp:
[410]913 SetSize(on, repeat, true, false, isControlDown);
[105]914 if (on instanceof Text) {
[1102]915 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true);
[105]916 }
[4]917 break;
[80]918 case SizeDown:
[410]919 SetSize(on, -repeat, true, false, isControlDown);
[105]920 if (on instanceof Text) {
[1102]921 DisplayIO.setTextCursor((Text) on, Text.NONE, true, false, false, true);
[105]922 }
[4]923 break;
[80]924 case ChangeColor:
[115]925 SetColor(on, isShiftDown, isControlDown);
[4]926 break;
[80]927 case ToggleAnnotation:
[4]928 ToggleAnnotation(on);
929 break;
[80]930 case ChangeFontStyle:
[4]931 ToggleFontStyle(on);
932 break;
[80]933 case ChangeFontFamily:
[4]934 ToggleFontFamily(on);
935 break;
[80]936 case InsertDate:
[4]937 AddDate(on);
[80]938 return;
939 case NewFrameset:
[4]940 CreateFrameset(on);
941 break;
[80]942 case XRayMode:
[108]943 FrameGraphics.ToggleXRayMode();
[4]944 break;
[80]945 case AudienceMode:
[108]946 FrameGraphics.ToggleAudienceMode();
[4]947 break;
[80]948 case Refresh:
[1077]949 if (isControlDown) {
950 MessageBay.displayMessage("Forced reload before forced refresh");
951 DisplayIO.Reload(0);
952 }
[108]953 Refresh();
[4]954 break;
[289]955 case Save:
956 Save();
957 break;
[4]958 }
[108]959 on = FrameUtils.getCurrentItem();
960 Collection<Item> enclosed = FrameUtils.getCurrentItems(on);
961 if (on == null && (enclosed == null || enclosed.size() == 0))
[121]962 MessageBay.displayMessage(displayMessage);
[4]963 }
[1102]964}*/
Note: See TracBrowser for help on using the repository browser.