ttable wip
[nikiroo-utils.git] / src / jexer / menu / TMenu.java
CommitLineData
daa4106c 1/*
928811d8
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
928811d8 5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
928811d8 7 *
e16dda65
KL
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
928811d8 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
928811d8 17 *
e16dda65
KL
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
928811d8
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer.menu;
30
339652cc
KL
31import java.util.ResourceBundle;
32
928811d8
KL
33import jexer.TApplication;
34import jexer.TKeypress;
35import jexer.TWidget;
36import jexer.TWindow;
37import jexer.bits.CellAttributes;
38import jexer.bits.GraphicsChars;
39import jexer.bits.MnemonicString;
40import jexer.event.TKeypressEvent;
41import jexer.event.TMouseEvent;
42import static jexer.TKeypress.*;
43
44/**
45 * TMenu is a top-level collection of TMenuItems.
46 */
051e2913 47public class TMenu extends TWindow {
928811d8 48
339652cc
KL
49 /**
50 * Translated strings.
51 */
52 private static final ResourceBundle i18n = ResourceBundle.getBundle(TMenu.class.getName());
53
d36057df
KL
54 // ------------------------------------------------------------------------
55 // Constants --------------------------------------------------------------
56 // ------------------------------------------------------------------------
928811d8
KL
57
58 // Reserved menu item IDs
59 public static final int MID_UNUSED = -1;
60
e23ea538
KL
61 // Tools menu
62 public static final int MID_REPAINT = 1;
63 public static final int MID_VIEW_IMAGE = 2;
64 public static final int MID_CHANGE_FONT = 3;
65
928811d8 66 // File menu
e23ea538
KL
67 public static final int MID_NEW = 10;
68 public static final int MID_EXIT = 11;
928811d8 69 public static final int MID_QUIT = MID_EXIT;
e23ea538
KL
70 public static final int MID_OPEN_FILE = 12;
71 public static final int MID_SHELL = 13;
928811d8
KL
72
73 // Edit menu
e23ea538
KL
74 public static final int MID_CUT = 20;
75 public static final int MID_COPY = 21;
76 public static final int MID_PASTE = 22;
77 public static final int MID_CLEAR = 23;
928811d8 78
d36057df 79 // Search menu
e23ea538
KL
80 public static final int MID_FIND = 30;
81 public static final int MID_REPLACE = 31;
82 public static final int MID_SEARCH_AGAIN = 32;
83 public static final int MID_GOTO_LINE = 33;
d36057df 84
928811d8 85 // Window menu
e23ea538
KL
86 public static final int MID_TILE = 40;
87 public static final int MID_CASCADE = 41;
88 public static final int MID_CLOSE_ALL = 42;
89 public static final int MID_WINDOW_MOVE = 43;
90 public static final int MID_WINDOW_ZOOM = 44;
91 public static final int MID_WINDOW_NEXT = 45;
92 public static final int MID_WINDOW_PREVIOUS = 46;
93 public static final int MID_WINDOW_CLOSE = 47;
928811d8 94
55d2b2c2 95 // Help menu
e23ea538
KL
96 public static final int MID_HELP_CONTENTS = 50;
97 public static final int MID_HELP_INDEX = 51;
98 public static final int MID_HELP_SEARCH = 52;
99 public static final int MID_HELP_PREVIOUS = 53;
100 public static final int MID_HELP_HELP = 54;
101 public static final int MID_HELP_ACTIVE_FILE = 55;
102 public static final int MID_ABOUT = 56;
1c19fdea 103
1dac6b8d
KL
104 // Table menu
105 public static final int MID_TABLE_BORDER_NONE = 60;
106 public static final int MID_TABLE_BORDER_ALL = 61;
107 public static final int MID_TABLE_BORDER_RIGHT = 62;
108 public static final int MID_TABLE_BORDER_LEFT = 63;
109 public static final int MID_TABLE_BORDER_TOP = 64;
110 public static final int MID_TABLE_BORDER_BOTTOM = 65;
111 public static final int MID_TABLE_BORDER_DOUBLE_BOTTOM = 66;
112 public static final int MID_TABLE_BORDER_THICK_BOTTOM = 67;
113 public static final int MID_TABLE_DELETE_LEFT = 68;
114 public static final int MID_TABLE_DELETE_UP = 69;
115 public static final int MID_TABLE_DELETE_ROW = 70;
116 public static final int MID_TABLE_DELETE_COLUMN = 71;
117 public static final int MID_TABLE_INSERT_LEFT = 72;
118 public static final int MID_TABLE_INSERT_RIGHT = 73;
119 public static final int MID_TABLE_INSERT_ABOVE = 74;
120 public static final int MID_TABLE_INSERT_BELOW = 75;
121 public static final int MID_TABLE_COLUMN_NARROW = 76;
122 public static final int MID_TABLE_COLUMN_WIDEN = 77;
123 public static final int MID_TABLE_FILE_SAVE_CSV = 78;
124 public static final int MID_TABLE_FILE_SAVE_TEXT = 79;
125
d36057df
KL
126 // ------------------------------------------------------------------------
127 // Variables --------------------------------------------------------------
128 // ------------------------------------------------------------------------
129
130 /**
131 * If true, this is a sub-menu. Note package private access.
132 */
133 boolean isSubMenu = false;
134
135 /**
136 * The X position of the menu's title.
137 */
138 private int titleX;
139
140 /**
141 * The shortcut and title.
142 */
143 private MnemonicString mnemonic;
144
145 // ------------------------------------------------------------------------
146 // Constructors -----------------------------------------------------------
147 // ------------------------------------------------------------------------
148
928811d8
KL
149 /**
150 * Public constructor.
151 *
152 * @param parent parent application
153 * @param x column relative to parent
154 * @param y row relative to parent
155 * @param label mnemonic menu title. Label must contain a keyboard
43ad7b6c
KL
156 * shortcut (mnemonic), denoted by prefixing a letter with "&",
157 * e.g. "&File"
928811d8
KL
158 */
159 public TMenu(final TApplication parent, final int x, final int y,
160 final String label) {
161
162 super(parent, label, x, y, parent.getScreen().getWidth(),
163 parent.getScreen().getHeight());
164
928811d8
KL
165 // Setup the menu shortcut
166 mnemonic = new MnemonicString(label);
167 setTitle(mnemonic.getRawLabel());
168 assert (mnemonic.getShortcutIdx() >= 0);
169
170 // Recompute width and height to reflect an empty menu
171 setWidth(getTitle().length() + 4);
172 setHeight(2);
173
174 setActive(false);
175 }
176
d36057df
KL
177 // ------------------------------------------------------------------------
178 // Event handlers ---------------------------------------------------------
179 // ------------------------------------------------------------------------
928811d8
KL
180
181 /**
182 * Handle mouse button presses.
183 *
184 * @param mouse mouse button event
185 */
186 @Override
187 public void onMouseDown(final TMouseEvent mouse) {
188 this.mouse = mouse;
a69ed767 189 super.onMouseDown(mouse);
928811d8
KL
190
191 // Pass to children
192 for (TWidget widget: getChildren()) {
193 if (widget.mouseWouldHit(mouse)) {
194 // Dispatch to this child, also activate it
195 activate(widget);
196
197 // Set x and y relative to the child's coordinates
198 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
199 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
200 widget.handleEvent(mouse);
201 return;
202 }
203 }
204 }
205
206 /**
207 * Handle mouse button releases.
208 *
209 * @param mouse mouse button release event
210 */
211 @Override
212 public void onMouseUp(final TMouseEvent mouse) {
213 this.mouse = mouse;
928811d8
KL
214
215 // Pass to children
216 for (TWidget widget: getChildren()) {
217 if (widget.mouseWouldHit(mouse)) {
218 // Dispatch to this child, also activate it
219 activate(widget);
220
221 // Set x and y relative to the child's coordinates
222 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
223 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
224 widget.handleEvent(mouse);
225 return;
226 }
227 }
228 }
229
230 /**
231 * Handle mouse movements.
232 *
233 * @param mouse mouse motion event
234 */
235 @Override
236 public void onMouseMotion(final TMouseEvent mouse) {
237 this.mouse = mouse;
928811d8
KL
238
239 // See if we should activate a different menu item
240 for (TWidget widget: getChildren()) {
7c870d89 241 if ((mouse.isMouse1())
928811d8
KL
242 && (widget.mouseWouldHit(mouse))
243 ) {
244 // Activate this menu item
245 activate(widget);
246 if (widget instanceof TSubMenu) {
247 ((TSubMenu) widget).dispatch();
248 }
249 return;
250 }
251 }
252 }
253
254 /**
255 * Handle keystrokes.
256 *
257 * @param keypress keystroke event
258 */
259 @Override
260 public void onKeypress(final TKeypressEvent keypress) {
91c9a837
KL
261
262 /*
263 System.err.printf("keypress: %s active child: %s\n", keypress,
264 getActiveChild());
265 */
266
267 if (getActiveChild() != this) {
268 if ((getActiveChild() instanceof TSubMenu)
269 || (getActiveChild() instanceof TMenu)
270 ) {
928811d8
KL
271 getActiveChild().onKeypress(keypress);
272 return;
273 }
274 }
275
276 if (keypress.equals(kbEsc)) {
277 getApplication().closeMenu();
278 return;
279 }
280 if (keypress.equals(kbDown)) {
281 switchWidget(true);
282 return;
283 }
284 if (keypress.equals(kbUp)) {
285 switchWidget(false);
286 return;
287 }
288 if (keypress.equals(kbRight)) {
91c9a837 289 getApplication().switchMenu(true);
928811d8
KL
290 return;
291 }
292 if (keypress.equals(kbLeft)) {
293 if (isSubMenu) {
294 getApplication().closeSubMenu();
295 } else {
296 getApplication().switchMenu(false);
297 }
298 return;
299 }
300
301 // Switch to a menuItem if it has an mnemonic
7c870d89
KL
302 if (!keypress.getKey().isFnKey()
303 && !keypress.getKey().isAlt()
304 && !keypress.getKey().isCtrl()) {
928811d8
KL
305 for (TWidget widget: getChildren()) {
306 TMenuItem item = (TMenuItem) widget;
307 if ((item.getMnemonic() != null)
308 && (Character.toLowerCase(item.getMnemonic().getShortcut())
7c870d89 309 == Character.toLowerCase(keypress.getKey().getChar()))
928811d8
KL
310 ) {
311 // Send an enter keystroke to it
312 activate(item);
313 item.handleEvent(new TKeypressEvent(kbEnter));
314 return;
315 }
316 }
317 }
318
319 // Dispatch the keypress to an active widget
320 for (TWidget widget: getChildren()) {
7c870d89 321 if (widget.isActive()) {
928811d8
KL
322 widget.handleEvent(keypress);
323 return;
324 }
325 }
326 }
327
d36057df
KL
328 // ------------------------------------------------------------------------
329 // TWindow ----------------------------------------------------------------
330 // ------------------------------------------------------------------------
331
332 /**
333 * Draw a top-level menu with title and menu items.
334 */
335 @Override
336 public void draw() {
337 CellAttributes background = getTheme().getColor("tmenu");
338
339 assert (isAbsoluteActive());
340
341 // Fill in the interior background
342 for (int i = 0; i < getHeight(); i++) {
343 hLineXY(0, i, getWidth(), ' ', background);
344 }
345
346 // Draw the box
347 char cTopLeft;
348 char cTopRight;
349 char cBottomLeft;
350 char cBottomRight;
351 char cHSide;
352
353 cTopLeft = GraphicsChars.ULCORNER;
354 cTopRight = GraphicsChars.URCORNER;
355 cBottomLeft = GraphicsChars.LLCORNER;
356 cBottomRight = GraphicsChars.LRCORNER;
357 cHSide = GraphicsChars.SINGLE_BAR;
358
359 // Place the corner characters
360 putCharXY(1, 0, cTopLeft, background);
361 putCharXY(getWidth() - 2, 0, cTopRight, background);
362 putCharXY(1, getHeight() - 1, cBottomLeft, background);
363 putCharXY(getWidth() - 2, getHeight() - 1, cBottomRight, background);
364
365 // Draw the box lines
366 hLineXY(1 + 1, 0, getWidth() - 4, cHSide, background);
367 hLineXY(1 + 1, getHeight() - 1, getWidth() - 4, cHSide, background);
368
369 // Draw a shadow
a69ed767 370 drawBoxShadow(0, 0, getWidth(), getHeight());
d36057df
KL
371 }
372
373 // ------------------------------------------------------------------------
374 // TMenu ------------------------------------------------------------------
375 // ------------------------------------------------------------------------
376
377 /**
378 * Set the menu title X position.
379 *
380 * @param titleX the position
381 */
382 public void setTitleX(final int titleX) {
383 this.titleX = titleX;
384 }
385
386 /**
387 * Get the menu title X position.
388 *
389 * @return the position
390 */
391 public int getTitleX() {
392 return titleX;
393 }
394
395 /**
396 * Get the mnemonic string.
397 *
398 * @return the full mnemonic string
399 */
400 public MnemonicString getMnemonic() {
401 return mnemonic;
402 }
403
928811d8 404 /**
efb7af1f 405 * Convenience function to add a menu item.
928811d8
KL
406 *
407 * @param id menu item ID. Must be greater than 1024.
408 * @param label menu item label
928811d8
KL
409 * @return the new menu item
410 */
329fd62e 411 public TMenuItem addItem(final int id, final String label) {
928811d8 412 assert (id >= 1024);
efb7af1f 413 return addItemInternal(id, label, null);
928811d8
KL
414 }
415
a69ed767
KL
416 /**
417 * Convenience function to add a menu item.
418 *
419 * @param id menu item ID. Must be greater than 1024.
420 * @param label menu item label
421 * @param enabled default state for enabled
422 * @return the new menu item
423 */
424 public TMenuItem addItem(final int id, final String label,
425 final boolean enabled) {
426
427 assert (id >= 1024);
428 return addItemInternal(id, label, null, enabled);
429 }
430
928811d8
KL
431 /**
432 * Convenience function to add a custom menu item.
433 *
434 * @param id menu item ID. Must be greater than 1024.
435 * @param label menu item label
436 * @param key global keyboard accelerator
437 * @return the new menu item
438 */
329fd62e 439 public TMenuItem addItem(final int id, final String label,
928811d8
KL
440 final TKeypress key) {
441
efb7af1f
KL
442 assert (id >= 1024);
443 return addItemInternal(id, label, key);
928811d8
KL
444 }
445
68c5cd6b
KL
446 /**
447 * Convenience function to add a custom menu item.
448 *
449 * @param id menu item ID. Must be greater than 1024.
450 * @param label menu item label
451 * @param key global keyboard accelerator
452 * @param enabled default state for enabled
453 * @return the new menu item
454 */
455 public TMenuItem addItem(final int id, final String label,
456 final TKeypress key, final boolean enabled) {
457
458 TMenuItem item = addItem(id, label, key);
459 item.setEnabled(enabled);
460 return item;
461 }
462
928811d8 463 /**
efb7af1f 464 * Convenience function to add a custom menu item.
928811d8
KL
465 *
466 * @param id menu item ID. Must be greater than 1024.
467 * @param label menu item label
efb7af1f 468 * @param key global keyboard accelerator
928811d8
KL
469 * @return the new menu item
470 */
efb7af1f
KL
471 private TMenuItem addItemInternal(final int id, final String label,
472 final TKeypress key) {
928811d8 473
d36057df
KL
474 return addItemInternal(id, label, key, true);
475 }
476
477 /**
478 * Convenience function to add a custom menu item.
479 *
480 * @param id menu item ID. Must be greater than 1024.
481 * @param label menu item label
482 * @param key global keyboard accelerator
483 * @param enabled default state for enabled
484 * @return the new menu item
485 */
486 private TMenuItem addItemInternal(final int id, final String label,
487 final TKeypress key, final boolean enabled) {
488
928811d8
KL
489 int newY = getChildren().size() + 1;
490 assert (newY < getHeight());
491
492 TMenuItem menuItem = new TMenuItem(this, id, 1, newY, label);
efb7af1f 493 menuItem.setKey(key);
d36057df 494 menuItem.setEnabled(enabled);
928811d8
KL
495 setHeight(getHeight() + 1);
496 if (menuItem.getWidth() + 2 > getWidth()) {
497 setWidth(menuItem.getWidth() + 2);
498 }
499 for (TWidget widget: getChildren()) {
500 widget.setWidth(getWidth() - 2);
501 }
efb7af1f 502 getApplication().addMenuItem(menuItem);
928811d8
KL
503 getApplication().recomputeMenuX();
504 activate(0);
505 return menuItem;
506 }
507
508 /**
509 * Convenience function to add one of the default menu items.
510 *
511 * @param id menu item ID. Must be between 0 (inclusive) and 1023
512 * (inclusive).
513 * @return the new menu item
514 */
329fd62e 515 public TMenuItem addDefaultItem(final int id) {
d36057df
KL
516 return addDefaultItem(id, true);
517 }
518
519 /**
520 * Convenience function to add one of the default menu items.
521 *
522 * @param id menu item ID. Must be between 0 (inclusive) and 1023
523 * (inclusive).
524 * @param enabled default state for enabled
525 * @return the new menu item
526 */
527 public TMenuItem addDefaultItem(final int id, final boolean enabled) {
928811d8
KL
528 assert (id >= 0);
529 assert (id < 1024);
530
531 String label;
532 TKeypress key = null;
928811d8
KL
533
534 switch (id) {
535
e23ea538
KL
536 case MID_REPAINT:
537 label = i18n.getString("menuRepaintDesktop");
538 break;
539
540 case MID_VIEW_IMAGE:
541 label = i18n.getString("menuViewImage");
542 break;
543
544 case MID_CHANGE_FONT:
545 label = i18n.getString("menuChangeFont");
546 break;
547
548 case MID_NEW:
549 label = i18n.getString("menuNew");
550 break;
551
928811d8 552 case MID_EXIT:
339652cc 553 label = i18n.getString("menuExit");
928811d8
KL
554 key = kbAltX;
555 break;
556
557 case MID_SHELL:
339652cc 558 label = i18n.getString("menuShell");
928811d8
KL
559 break;
560
561 case MID_OPEN_FILE:
339652cc 562 label = i18n.getString("menuOpen");
b2d49e0f 563 key = kbF3;
928811d8
KL
564 break;
565
566 case MID_CUT:
339652cc 567 label = i18n.getString("menuCut");
928811d8
KL
568 key = kbCtrlX;
569 break;
570 case MID_COPY:
339652cc 571 label = i18n.getString("menuCopy");
928811d8
KL
572 key = kbCtrlC;
573 break;
574 case MID_PASTE:
339652cc 575 label = i18n.getString("menuPaste");
928811d8
KL
576 key = kbCtrlV;
577 break;
578 case MID_CLEAR:
339652cc 579 label = i18n.getString("menuClear");
30bd4abd 580 // key = kbDel;
928811d8
KL
581 break;
582
d36057df
KL
583 case MID_FIND:
584 label = i18n.getString("menuFind");
585 break;
586 case MID_REPLACE:
587 label = i18n.getString("menuReplace");
588 break;
589 case MID_SEARCH_AGAIN:
590 label = i18n.getString("menuSearchAgain");
978a5d8f 591 key = kbCtrlL;
d36057df
KL
592 break;
593 case MID_GOTO_LINE:
594 label = i18n.getString("menuGotoLine");
d36057df
KL
595 break;
596
928811d8 597 case MID_TILE:
339652cc 598 label = i18n.getString("menuWindowTile");
928811d8
KL
599 break;
600 case MID_CASCADE:
339652cc 601 label = i18n.getString("menuWindowCascade");
928811d8
KL
602 break;
603 case MID_CLOSE_ALL:
339652cc 604 label = i18n.getString("menuWindowCloseAll");
928811d8
KL
605 break;
606 case MID_WINDOW_MOVE:
339652cc 607 label = i18n.getString("menuWindowMove");
928811d8
KL
608 key = kbCtrlF5;
609 break;
610 case MID_WINDOW_ZOOM:
339652cc 611 label = i18n.getString("menuWindowZoom");
928811d8
KL
612 key = kbF5;
613 break;
614 case MID_WINDOW_NEXT:
339652cc 615 label = i18n.getString("menuWindowNext");
928811d8
KL
616 key = kbF6;
617 break;
618 case MID_WINDOW_PREVIOUS:
339652cc 619 label = i18n.getString("menuWindowPrevious");
928811d8
KL
620 key = kbShiftF6;
621 break;
622 case MID_WINDOW_CLOSE:
339652cc 623 label = i18n.getString("menuWindowClose");
5dfd1c11 624 key = kbCtrlW;
928811d8
KL
625 break;
626
55d2b2c2 627 case MID_HELP_CONTENTS:
339652cc 628 label = i18n.getString("menuHelpContents");
55d2b2c2
KL
629 break;
630 case MID_HELP_INDEX:
339652cc 631 label = i18n.getString("menuHelpIndex");
55d2b2c2
KL
632 key = kbShiftF1;
633 break;
634 case MID_HELP_SEARCH:
339652cc 635 label = i18n.getString("menuHelpSearch");
55d2b2c2
KL
636 key = kbCtrlF1;
637 break;
638 case MID_HELP_PREVIOUS:
339652cc 639 label = i18n.getString("menuHelpPrevious");
55d2b2c2
KL
640 key = kbAltF1;
641 break;
642 case MID_HELP_HELP:
339652cc 643 label = i18n.getString("menuHelpHelp");
55d2b2c2
KL
644 break;
645 case MID_HELP_ACTIVE_FILE:
339652cc 646 label = i18n.getString("menuHelpActive");
55d2b2c2
KL
647 break;
648 case MID_ABOUT:
339652cc 649 label = i18n.getString("menuHelpAbout");
55d2b2c2
KL
650 break;
651
1dac6b8d
KL
652 case MID_TABLE_BORDER_NONE:
653 label = i18n.getString("menuTableBorderNone");
654 break;
655 case MID_TABLE_BORDER_ALL:
656 label = i18n.getString("menuTableBorderAll");
657 break;
658 case MID_TABLE_BORDER_RIGHT:
659 label = i18n.getString("menuTableBorderRight");
660 break;
661 case MID_TABLE_BORDER_LEFT:
662 label = i18n.getString("menuTableBorderLeft");
663 break;
664 case MID_TABLE_BORDER_TOP:
665 label = i18n.getString("menuTableBorderTop");
666 break;
667 case MID_TABLE_BORDER_BOTTOM:
668 label = i18n.getString("menuTableBorderBottom");
669 break;
670 case MID_TABLE_BORDER_DOUBLE_BOTTOM:
671 label = i18n.getString("menuTableBorderDoubleBottom");
672 break;
673 case MID_TABLE_BORDER_THICK_BOTTOM:
674 label = i18n.getString("menuTableBorderThickBottom");
675 break;
676 case MID_TABLE_DELETE_LEFT:
677 label = i18n.getString("menuTableDeleteLeft");
678 break;
679 case MID_TABLE_DELETE_UP:
680 label = i18n.getString("menuTableDeleteUp");
681 break;
682 case MID_TABLE_DELETE_ROW:
683 label = i18n.getString("menuTableDeleteRow");
684 break;
685 case MID_TABLE_DELETE_COLUMN:
686 label = i18n.getString("menuTableDeleteColumn");
687 break;
688 case MID_TABLE_INSERT_LEFT:
689 label = i18n.getString("menuTableInsertLeft");
690 break;
691 case MID_TABLE_INSERT_RIGHT:
692 label = i18n.getString("menuTableInsertRight");
693 break;
694 case MID_TABLE_INSERT_ABOVE:
695 label = i18n.getString("menuTableInsertAbove");
696 break;
697 case MID_TABLE_INSERT_BELOW:
698 label = i18n.getString("menuTableInsertBelow");
699 break;
700 case MID_TABLE_COLUMN_NARROW:
701 label = i18n.getString("menuTableColumnNarrow");
702 key = kbShiftLeft;
703 break;
704 case MID_TABLE_COLUMN_WIDEN:
705 label = i18n.getString("menuTableColumnWiden");
706 key = kbShiftRight;
707 break;
708 case MID_TABLE_FILE_SAVE_CSV:
709 label = i18n.getString("menuTableFileSaveCsv");
710 break;
711 case MID_TABLE_FILE_SAVE_TEXT:
712 label = i18n.getString("menuTableFileSaveText");
713 break;
714
928811d8
KL
715 default:
716 throw new IllegalArgumentException("Invalid menu ID: " + id);
717 }
718
d36057df 719 return addItemInternal(id, label, key, enabled);
928811d8
KL
720 }
721
722 /**
723 * Convenience function to add a menu separator.
724 */
329fd62e 725 public void addSeparator() {
928811d8
KL
726 int newY = getChildren().size() + 1;
727 assert (newY < getHeight());
728
cf9af8df
KL
729 // We just have to construct it, don't need to hang onto what it
730 // makes.
731 new TMenuSeparator(this, 1, newY);
928811d8
KL
732 setHeight(getHeight() + 1);
733 }
734
735 /**
736 * Convenience function to add a sub-menu.
737 *
738 * @param title menu title. Title must contain a keyboard shortcut,
43ad7b6c 739 * denoted by prefixing a letter with "&amp;", e.g. "&amp;File"
928811d8
KL
740 * @return the new sub-menu
741 */
329fd62e 742 public TSubMenu addSubMenu(final String title) {
928811d8
KL
743 int newY = getChildren().size() + 1;
744 assert (newY < getHeight());
745
746 TSubMenu subMenu = new TSubMenu(this, title, 1, newY);
747 setHeight(getHeight() + 1);
748 if (subMenu.getWidth() + 2 > getWidth()) {
749 setWidth(subMenu.getWidth() + 2);
750 }
751 for (TWidget widget: getChildren()) {
752 widget.setWidth(getWidth() - 2);
753 }
754 getApplication().recomputeMenuX();
755 activate(0);
756 subMenu.menu.setX(getX() + getWidth() - 2);
757
758 return subMenu;
759 }
760
761}