Add more warnings source to 1.6) and fix warnings
[jvcard.git] / src / be / nikiroo / jvcard / tui / MainWindow.java
CommitLineData
a3b510ab
NR
1package be.nikiroo.jvcard.tui;
2
5ad0e17e 3import java.io.IOException;
bcb54330 4import java.util.ArrayList;
a3b510ab
NR
5import java.util.Arrays;
6import java.util.LinkedList;
7import java.util.List;
8
7da41ecd 9import be.nikiroo.jvcard.launcher.Main;
f06c8100
NR
10import be.nikiroo.jvcard.resources.ColorOption;
11import be.nikiroo.jvcard.resources.StringId;
a3b510ab 12import be.nikiroo.jvcard.tui.KeyAction.Mode;
f04d8b1c 13import be.nikiroo.jvcard.tui.panes.ContactDetails;
296a0b75 14import be.nikiroo.jvcard.tui.panes.ContactDetailsRaw;
fae07ea7
NR
15import be.nikiroo.jvcard.tui.panes.ContactList;
16import be.nikiroo.jvcard.tui.panes.MainContent;
f06c8100
NR
17import be.nikiroo.utils.StringUtils;
18import be.nikiroo.utils.Version;
a3b510ab
NR
19
20import com.googlecode.lanterna.TerminalSize;
21import com.googlecode.lanterna.gui2.BasicWindow;
22import com.googlecode.lanterna.gui2.BorderLayout;
23import com.googlecode.lanterna.gui2.Direction;
24import com.googlecode.lanterna.gui2.Interactable;
25import com.googlecode.lanterna.gui2.Label;
26import com.googlecode.lanterna.gui2.LinearLayout;
27import com.googlecode.lanterna.gui2.Panel;
28import com.googlecode.lanterna.gui2.TextBox;
a3b510ab
NR
29import com.googlecode.lanterna.gui2.Window;
30import com.googlecode.lanterna.input.KeyStroke;
31import com.googlecode.lanterna.input.KeyType;
32
33/**
0b0b2b0f
NR
34 * This is the main "window" of the program. It can show up to one
35 * {@link MainContent} at any one time, but keeps a stack of contents.
a3b510ab
NR
36 *
37 * @author niki
38 *
39 */
f720df72 40
a3b510ab
NR
41public class MainWindow extends BasicWindow {
42 private List<KeyAction> defaultActions = new LinkedList<KeyAction>();
43 private List<KeyAction> actions = new LinkedList<KeyAction>();
0b0b2b0f 44 private List<MainContent> contentStack = new LinkedList<MainContent>();
f720df72 45 private UserQuestion userQuestion;
bcb54330 46 private String titleCache;
a3b510ab
NR
47 private Panel titlePanel;
48 private Panel mainPanel;
49 private Panel contentPanel;
50 private Panel actionPanel;
51 private Panel messagePanel;
52 private TextBox text;
53
f720df72
NR
54 /**
55 * Information about a question to ask the user and its answer.
56 *
57 * @author niki
f06c8100 58 *
f720df72
NR
59 */
60 private class UserQuestion {
61 private boolean oneKeyAnswer;
62 private KeyAction action;
63 private String answer;
64
65 /**
66 * Create a new {@link UserQuestion}.
67 *
68 * @param action
69 * the action that triggered the question
70 * @param oneKeyAnswer
71 * TRUE if we expect a one-key answer
72 */
73 public UserQuestion(KeyAction action, boolean oneKeyAnswer) {
74 this.action = action;
75 this.oneKeyAnswer = oneKeyAnswer;
76 }
77
78 /**
79 * Return the {@link KeyAction} that triggered the question.
80 *
81 * @return the {@link KeyAction}
82 */
83 public KeyAction getAction() {
84 return action;
85 }
86
87 /**
88 * Check if a one-key answer is expected.
89 *
90 * @return TRUE if a one-key answer is expected
91 */
92 public boolean isOneKeyAnswer() {
93 return oneKeyAnswer;
94 }
95
96 /**
97 * Return the user answer.
98 *
99 * @return the user answer
100 */
101 public String getAnswer() {
102 return answer;
103 }
104
105 /**
106 * Set the user answer.
107 *
108 * @param answer
109 * the new answer
110 */
111 public void setAnswer(String answer) {
112 this.answer = answer;
113 }
114 }
115
0b0b2b0f
NR
116 /**
117 * Create a new, empty window.
118 */
a3b510ab
NR
119 public MainWindow() {
120 this(null);
121 }
122
0b0b2b0f
NR
123 /**
124 * Create a new window hosting the given content.
125 *
126 * @param content
127 * the content to host
128 */
a3b510ab
NR
129 public MainWindow(MainContent content) {
130 super(content == null ? "" : content.getTitle());
131
132 setHints(Arrays.asList(Window.Hint.FULL_SCREEN,
133 Window.Hint.NO_DECORATIONS, Window.Hint.FIT_TERMINAL_WINDOW));
134
135 defaultActions.add(new KeyAction(Mode.BACK, 'q',
136 StringId.KEY_ACTION_BACK));
137 defaultActions.add(new KeyAction(Mode.BACK, KeyType.Escape,
138 StringId.NULL));
139 defaultActions.add(new KeyAction(Mode.HELP, 'h',
140 StringId.KEY_ACTION_HELP));
141 defaultActions.add(new KeyAction(Mode.HELP, KeyType.F1, StringId.NULL));
142
143 actionPanel = new Panel();
144 contentPanel = new Panel();
145 mainPanel = new Panel();
146 messagePanel = new Panel();
147 titlePanel = new Panel();
148
149 Panel actionMessagePanel = new Panel();
150
151 LinearLayout llayout = new LinearLayout(Direction.HORIZONTAL);
152 llayout.setSpacing(0);
153 actionPanel.setLayoutManager(llayout);
154
0b0b2b0f
NR
155 BorderLayout blayout = new BorderLayout();
156 titlePanel.setLayoutManager(blayout);
a3b510ab
NR
157
158 llayout = new LinearLayout(Direction.VERTICAL);
159 llayout.setSpacing(0);
160 messagePanel.setLayoutManager(llayout);
161
0b0b2b0f 162 blayout = new BorderLayout();
a3b510ab
NR
163 mainPanel.setLayoutManager(blayout);
164
165 blayout = new BorderLayout();
166 contentPanel.setLayoutManager(blayout);
167
168 blayout = new BorderLayout();
169 actionMessagePanel.setLayoutManager(blayout);
170
171 actionMessagePanel
172 .addComponent(messagePanel, BorderLayout.Location.TOP);
173 actionMessagePanel.addComponent(actionPanel,
174 BorderLayout.Location.CENTER);
175
176 mainPanel.addComponent(titlePanel, BorderLayout.Location.TOP);
177 mainPanel.addComponent(contentPanel, BorderLayout.Location.CENTER);
178 mainPanel
179 .addComponent(actionMessagePanel, BorderLayout.Location.BOTTOM);
180
181 pushContent(content);
182
183 setComponent(mainPanel);
184 }
185
0b0b2b0f
NR
186 /**
187 * "push" some content to the window stack.
188 *
189 * @param content
190 * the new top-of-the-stack content
191 */
a3b510ab
NR
192 public void pushContent(MainContent content) {
193 List<KeyAction> actions = null;
a3b510ab
NR
194
195 contentPanel.removeAllComponents();
196 if (content != null) {
a3b510ab
NR
197 actions = content.getKeyBindings();
198 contentPanel.addComponent(content, BorderLayout.Location.CENTER);
0b0b2b0f 199 this.contentStack.add(content);
9c8baf0c
NR
200
201 Interactable focus = content.nextFocus(null);
202 if (focus != null)
203 focus.takeFocus();
a3b510ab
NR
204 }
205
bcb54330 206 setTitle();
0b0b2b0f 207 setActions(actions, true);
a3b510ab
NR
208 }
209
0b0b2b0f
NR
210 /**
211 * "pop" the latest, top-of-the-stack content from the window stack.
212 *
213 * @return the removed content if any
214 */
9c8baf0c
NR
215 public MainContent popContent() {
216 MainContent removed = null;
217 MainContent prev = null;
9c8baf0c 218
0b0b2b0f
NR
219 MainContent content = getContent();
220 if (content != null)
221 removed = contentStack.remove(contentStack.size() - 1);
9c8baf0c 222
0b0b2b0f
NR
223 if (contentStack.size() > 0)
224 prev = contentStack.remove(contentStack.size() - 1);
a3b510ab 225
5ad0e17e
NR
226 if (prev != null) {
227 try {
228 String mess = prev.wakeup();
229 if (mess != null)
230 setMessage(mess, false);
231 } catch (IOException e) {
232 setMessage(e.getMessage(), true);
233 }
234 }
235
0b0b2b0f 236 pushContent(prev);
a3b510ab 237
0b0b2b0f 238 return removed;
a3b510ab
NR
239 }
240
9c8baf0c
NR
241 /**
242 * Show the given message on screen. It will disappear at the next action.
243 *
244 * @param mess
245 * the message to display
246 * @param error
247 * TRUE for an error message, FALSE for an information message
bcb54330
NR
248 *
249 * @return TRUE if changes were performed
9c8baf0c 250 */
bcb54330
NR
251 public boolean setMessage(String mess, boolean error) {
252 if (mess != null || messagePanel.getChildCount() > 0) {
253 messagePanel.removeAllComponents();
254 if (mess != null) {
e119a1c1
NR
255 ColorOption element = (error ? ColorOption.LINE_MESSAGE_ERR
256 : ColorOption.LINE_MESSAGE);
257 Label lbl = UiColors.createLabel(element, " " + mess + " ");
bcb54330
NR
258 messagePanel.addComponent(lbl, LinearLayout
259 .createLayoutData(LinearLayout.Alignment.Center));
260 }
261 return true;
262 }
263
264 return false;
265 }
266
267 /**
268 * Show a question to the user and switch to "ask for answer" mode see
269 * {@link MainWindow#handleQuestion}. The user will be asked to enter some
270 * answer and confirm with ENTER.
271 *
296a0b75
NR
272 * @param action
273 * the related action
bcb54330
NR
274 * @param question
275 * the question to ask
276 * @param initial
277 * the initial answer if any (to be edited by the user)
278 */
296a0b75
NR
279 public void setQuestion(KeyAction action, String question, String initial) {
280 setQuestion(action, question, initial, false);
bcb54330
NR
281 }
282
283 /**
284 * Show a question to the user and switch to "ask for answer" mode see
285 * {@link MainWindow#handleQuestion}. The user will be asked to hit one key
286 * as an answer.
287 *
296a0b75
NR
288 * @param action
289 * the related action
bcb54330
NR
290 * @param question
291 * the question to ask
292 */
296a0b75
NR
293 public void setQuestion(KeyAction action, String question) {
294 setQuestion(action, question, null, true);
9c8baf0c
NR
295 }
296
0b0b2b0f
NR
297 /**
298 * Show a question to the user and switch to "ask for answer" mode see
299 * {@link MainWindow#handleQuestion}.
300 *
296a0b75
NR
301 * @param action
302 * the related action
bcb54330
NR
303 * @param question
304 * the question to ask
305 * @param initial
306 * the initial answer if any (to be edited by the user)
0b0b2b0f
NR
307 * @param oneKey
308 * TRUE for a one-key answer, FALSE for a text answer validated
309 * by ENTER
310 */
296a0b75 311 private void setQuestion(KeyAction action, String question, String initial,
bcb54330 312 boolean oneKey) {
f720df72 313 userQuestion = new UserQuestion(action, oneKey);
0b0b2b0f 314
9c8baf0c 315 messagePanel.removeAllComponents();
9c8baf0c 316
0b0b2b0f
NR
317 Panel hpanel = new Panel();
318 LinearLayout llayout = new LinearLayout(Direction.HORIZONTAL);
319 llayout.setSpacing(0);
320 hpanel.setLayoutManager(llayout);
9c8baf0c 321
e119a1c1 322 Label lbl = UiColors.createLabel(ColorOption.LINE_MESSAGE_QUESTION, " "
bcb54330 323 + question + " ");
296a0b75
NR
324 text = new TextBox(new TerminalSize(getSize().getColumns()
325 - lbl.getSize().getColumns(), 1));
f720df72
NR
326
327 if (initial != null) {
328 // add all chars one by one so the caret is at the end
329 for (int index = 0; index < initial.length(); index++) {
330 text.handleInput(new KeyStroke(initial.charAt(index), false,
331 false));
332 }
333 }
9c8baf0c 334
bcb54330
NR
335 hpanel.addComponent(lbl,
336 LinearLayout.createLayoutData(LinearLayout.Alignment.Beginning));
337 hpanel.addComponent(text,
338 LinearLayout.createLayoutData(LinearLayout.Alignment.Fill));
9c8baf0c 339
bcb54330
NR
340 messagePanel
341 .addComponent(hpanel, LinearLayout
342 .createLayoutData(LinearLayout.Alignment.Beginning));
9c8baf0c 343
0b0b2b0f 344 text.takeFocus();
9c8baf0c
NR
345 }
346
296a0b75
NR
347 /**
348 * Refresh the window and the empty-space handling. You should call this
349 * method when the window size changed.
350 *
351 * @param size
352 * the new size of the window
353 */
354 public void refresh(TerminalSize size) {
355 if (size == null)
356 return;
357
358 if (getSize() == null || !getSize().equals(size))
359 setSize(size);
360
361 setTitle();
362
363 if (actions != null)
364 setActions(new ArrayList<KeyAction>(actions), false);
365
366 invalidate();
367 }
368
369 @Override
370 public void invalidate() {
371 super.invalidate();
372 for (MainContent content : contentStack) {
373 content.invalidate();
374 }
375 }
376
377 @Override
378 public boolean handleInput(KeyStroke key) {
379 boolean handled = false;
380
f720df72
NR
381 if (userQuestion != null) {
382 handled = handleQuestion(userQuestion, key);
383 if (handled) {
384 if (userQuestion.getAnswer() != null) {
385 handleAction(userQuestion.getAction(),
386 userQuestion.getAnswer());
296a0b75 387
f720df72
NR
388 userQuestion = null;
389 }
296a0b75
NR
390 }
391 } else {
392 handled = handleKey(key);
393 }
394
f720df72 395 if (!handled) {
296a0b75 396 handled = super.handleInput(key);
f720df72 397 }
296a0b75
NR
398
399 return handled;
400 }
401
bcb54330
NR
402 /**
403 * Actually set the title <b>inside</b> the window. Will also call
296a0b75 404 * {@link BasicWindow#setTitle} with the computed parameters.
bcb54330
NR
405 */
406 private void setTitle() {
0b0b2b0f 407 String prefix = " " + Main.APPLICATION_TITLE + " (version "
f06c8100 408 + Version.getCurrentVersion() + ")";
0b0b2b0f 409
bcb54330 410 String title = null;
0b0b2b0f 411 int count = -1;
bcb54330 412
0b0b2b0f 413 MainContent content = getContent();
bcb54330
NR
414 if (content != null) {
415 title = content.getTitle();
0b0b2b0f 416 count = content.getCount();
bcb54330
NR
417 }
418
419 if (title == null)
420 title = "";
0b0b2b0f 421
bcb54330 422 if (title.length() > 0) {
0b0b2b0f 423 prefix = prefix + ": ";
7da41ecd 424 title = StringUtils.sanitize(title, Main.isUnicode());
0b0b2b0f
NR
425 }
426
bcb54330
NR
427 String countStr = "";
428 if (count > -1) {
429 countStr = "[" + count + "]";
430 }
431
296a0b75
NR
432 int width = -1;
433 if (getSize() != null) {
434 width = getSize().getColumns();
435 }
436
bcb54330
NR
437 if (width > 0) {
438 int padding = width - prefix.length() - title.length()
439 - countStr.length();
440 if (padding > 0) {
441 if (title.length() > 0)
442 title = StringUtils.padString(title, title.length()
443 + padding);
444 else
445 prefix = StringUtils.padString(prefix, prefix.length()
446 + padding);
447 }
0b0b2b0f 448 }
0b0b2b0f 449
bcb54330
NR
450 String titleCache = prefix + title + count;
451 if (!titleCache.equals(this.titleCache)) {
452 super.setTitle(prefix);
0b0b2b0f
NR
453
454 Label lblPrefix = new Label(prefix);
e119a1c1 455 UiColors.themeLabel(ColorOption.TITLE_MAIN, lblPrefix);
0b0b2b0f
NR
456
457 Label lblTitle = null;
bcb54330 458 if (title.length() > 0) {
0b0b2b0f 459 lblTitle = new Label(title);
e119a1c1 460 UiColors.themeLabel(ColorOption.TITLE_VARIABLE, lblTitle);
0b0b2b0f
NR
461 }
462
d5260eeb
NR
463 Label lblCount = new Label(countStr);
464 UiColors.themeLabel(ColorOption.TITLE_COUNT, lblCount);
0b0b2b0f
NR
465
466 titlePanel.removeAllComponents();
a3b510ab 467
0b0b2b0f 468 titlePanel.addComponent(lblPrefix, BorderLayout.Location.LEFT);
d5260eeb 469 if (lblTitle != null) {
0b0b2b0f 470 titlePanel.addComponent(lblTitle, BorderLayout.Location.CENTER);
d5260eeb
NR
471 }
472 titlePanel.addComponent(lblCount, BorderLayout.Location.RIGHT);
0b0b2b0f
NR
473 }
474 }
475
476 /**
477 * Return the current {@link MainContent} from the stack if any.
478 *
479 * @return the current {@link MainContent}
480 */
481 private MainContent getContent() {
482 if (contentStack.size() > 0) {
483 return contentStack.get(contentStack.size() - 1);
484 }
485
486 return null;
487 }
488
489 /**
490 * Update the list of actions and refresh the action panel.
491 *
492 * @param actions
493 * the list of actions to support
494 * @param enableDefaultactions
495 * TRUE to enable the default actions
496 */
497 private void setActions(List<KeyAction> actions,
498 boolean enableDefaultactions) {
a3b510ab 499 this.actions.clear();
9c8baf0c 500
a3b510ab
NR
501 if (enableDefaultactions)
502 this.actions.addAll(defaultActions);
503
504 if (actions != null)
505 this.actions.addAll(actions);
506
507 actionPanel.removeAllComponents();
508 for (KeyAction action : this.actions) {
668268fc 509 String trans = " " + Main.trans(action.getStringId()) + " ";
a3b510ab
NR
510
511 if (" ".equals(trans))
512 continue;
513
7da41ecd 514 String keyTrans = KeyAction.trans(action.getKey());
a3b510ab
NR
515
516 Panel kPane = new Panel();
517 LinearLayout layout = new LinearLayout(Direction.HORIZONTAL);
518 layout.setSpacing(0);
519 kPane.setLayoutManager(layout);
520
e119a1c1
NR
521 kPane.addComponent(UiColors.createLabel(ColorOption.ACTION_KEY,
522 keyTrans));
59597d59
NR
523 kPane.addComponent(UiColors.createLabel(ColorOption.ACTION_DESC,
524 trans));
a3b510ab
NR
525
526 actionPanel.addComponent(kPane);
527 }
bcb54330
NR
528
529 // fill with "desc" colour
296a0b75
NR
530 int width = -1;
531 if (getSize() != null) {
532 width = getSize().getColumns();
533 }
534
bcb54330 535 if (width > 0) {
59597d59
NR
536 actionPanel.addComponent(UiColors.createLabel(
537 ColorOption.ACTION_DESC, StringUtils.padString("", width)));
bcb54330 538 }
a3b510ab
NR
539 }
540
0b0b2b0f
NR
541 /**
542 * Handle user input when in "ask for question" mode (see
f720df72 543 * {@link MainWindow#userQuestion}).
0b0b2b0f 544 *
f720df72
NR
545 * @param userQuestion
546 * the question data
0b0b2b0f
NR
547 * @param key
548 * the key that has been pressed by the user
549 *
f720df72 550 * @return TRUE if the {@link KeyStroke} was handled
0b0b2b0f 551 */
f720df72
NR
552 private boolean handleQuestion(UserQuestion userQuestion, KeyStroke key) {
553 userQuestion.setAnswer(null);
ae22c247 554
f720df72
NR
555 if (userQuestion.isOneKeyAnswer()) {
556 userQuestion.setAnswer("" + key.getCharacter());
a3b510ab 557 } else {
f720df72
NR
558 // ^h == Backspace
559 if (key.isCtrlDown() && key.getCharacter() == 'h') {
560 key = new KeyStroke(KeyType.Backspace);
561 }
562
563 switch (key.getKeyType()) {
564 case Enter:
a3b510ab 565 if (text != null)
f720df72 566 userQuestion.setAnswer(text.getText());
a3b510ab 567 else
f720df72
NR
568 userQuestion.setAnswer("");
569 break;
570 case Backspace:
571 int pos = text.getCaretPosition().getColumn();
572 if (pos > 0) {
573 String current = text.getText();
574 // force caret one space before:
575 text.setText(current.substring(0, pos - 1));
576 // re-add full text:
577 text.setText(current.substring(0, pos - 1)
578 + current.substring(pos));
579 }
580 return true;
581 default:
582 // Do nothing (continue entering text)
583 break;
a3b510ab
NR
584 }
585 }
586
f720df72 587 if (userQuestion.getAnswer() != null) {
a3b510ab 588 Interactable focus = null;
0b0b2b0f
NR
589 MainContent content = getContent();
590 if (content != null)
591 focus = content.nextFocus(null);
a3b510ab 592
fae07ea7 593 focus.takeFocus();
f720df72
NR
594
595 return true;
a3b510ab
NR
596 }
597
f720df72 598 return false;
a3b510ab
NR
599 }
600
0b0b2b0f
NR
601 /**
602 * Handle the input in case of "normal" (not "ask for answer") mode.
603 *
604 * @param key
605 * the key that was pressed
0b0b2b0f 606 *
bcb54330 607 * @return if the window handled the input
0b0b2b0f 608 */
296a0b75 609 private boolean handleKey(KeyStroke key) {
a3b510ab
NR
610 boolean handled = false;
611
296a0b75
NR
612 if (setMessage(null, false))
613 return true;
a3b510ab 614
0b0b2b0f
NR
615 for (KeyAction action : actions) {
616 if (!action.match(key))
617 continue;
a3b510ab 618
0b0b2b0f
NR
619 handled = true;
620
5ad0e17e
NR
621 action.getObject(); // see {@link KeyAction#getMessage()}
622 String mess = action.getMessage();
623 if (mess != null) {
624 setMessage(mess, action.isError());
625 }
626
59597d59 627 if (!action.isError() && action.onAction()) {
296a0b75
NR
628 handleAction(action, null);
629 }
0b0b2b0f 630
296a0b75
NR
631 break;
632 }
0b0b2b0f 633
296a0b75
NR
634 return handled;
635 }
636
637 /**
638 * Handle the input in case of "normal" (not "ask for answer") mode.
639 *
f06c8100
NR
640 * @param action
641 * the key that was pressed and the action to take
296a0b75
NR
642 * @param answer
643 * the answer given for this key
644 *
296a0b75
NR
645 */
646 private void handleAction(KeyAction action, String answer) {
647 MainContent content = getContent();
648
296a0b75
NR
649 switch (action.getMode()) {
650 case MOVE:
651 int x = 0;
652 int y = 0;
653
654 if (action.getKey().getKeyType() == KeyType.ArrowUp)
655 x = -1;
656 if (action.getKey().getKeyType() == KeyType.ArrowDown)
657 x = 1;
658 if (action.getKey().getKeyType() == KeyType.ArrowLeft)
659 y = -1;
660 if (action.getKey().getKeyType() == KeyType.ArrowRight)
661 y = 1;
662
663 if (content != null) {
664 String err = content.move(x, y);
665 if (err != null)
666 setMessage(err, true);
667 }
668
669 break;
670 // mode with windows:
671 case CONTACT_LIST:
ae22c247
NR
672 if (action.getCard() != null) {
673 pushContent(new ContactList(action.getCard()));
5ad0e17e
NR
674 } else if (action.getObject() != null
675 && action.getObject() instanceof MainContent) {
676 MainContent mergeContent = (MainContent) action.getObject();
677 pushContent(mergeContent);
296a0b75
NR
678 }
679 break;
680 case CONTACT_DETAILS:
ae22c247
NR
681 if (action.getContact() != null) {
682 pushContent(new ContactDetails(action.getContact()));
f04d8b1c
NR
683 }
684 break;
685 case CONTACT_DETAILS_RAW:
ae22c247
NR
686 if (action.getContact() != null) {
687 pushContent(new ContactDetailsRaw(action.getContact()));
296a0b75
NR
688 }
689 break;
690 // mode interpreted by MainWindow:
691 case HELP:
692 // TODO
f720df72 693 setMessage("Help! I need somebody! Help!", false);
296a0b75
NR
694
695 break;
696 case BACK:
697 String warning = content.getExitWarning();
698 if (warning != null) {
699 if (answer == null) {
700 setQuestion(action, warning);
701 } else {
702 setMessage(null, false);
703 if (answer.equalsIgnoreCase("y")) {
bcb54330 704 popContent();
a3b510ab 705 }
296a0b75
NR
706 }
707 } else {
708 popContent();
709 }
0b0b2b0f 710
296a0b75
NR
711 if (contentStack.size() == 0) {
712 close();
713 }
bcb54330 714
296a0b75
NR
715 break;
716 // action modes:
ae22c247 717 case ASK_USER:
296a0b75 718 if (answer == null) {
ae22c247
NR
719 setQuestion(action, action.getQuestion(),
720 action.getDefaultAnswer());
296a0b75 721 } else {
ae22c247
NR
722 setMessage(action.callback(answer), true);
723 content.refreshData();
724 invalidate();
725 setTitle();
296a0b75
NR
726 }
727 break;
ae22c247 728 case ASK_USER_KEY:
296a0b75 729 if (answer == null) {
ae22c247 730 setQuestion(action, action.getQuestion());
296a0b75 731 } else {
ae22c247
NR
732 setMessage(action.callback(answer), true);
733 content.refreshData();
734 invalidate();
735 setTitle();
0b0b2b0f 736 }
296a0b75
NR
737 break;
738 default:
739 case NONE:
0b0b2b0f
NR
740 break;
741 }
a3b510ab
NR
742 }
743}