X-Git-Url: http://git.nikiroo.be/?a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Fjvcard%2Ftui%2FMainWindow.java;h=39560a4c7a57d7ea766f47df05cb9a81abaed1ce;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hp=13c6b3e238a4e021873d2a4694a667b023137eb8;hpb=296a0b75515b3a7424b98292c87cbbf2272b73f9;p=jvcard.git diff --git a/src/be/nikiroo/jvcard/tui/MainWindow.java b/src/be/nikiroo/jvcard/tui/MainWindow.java index 13c6b3e..39560a4 100644 --- a/src/be/nikiroo/jvcard/tui/MainWindow.java +++ b/src/be/nikiroo/jvcard/tui/MainWindow.java @@ -6,16 +6,16 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import be.nikiroo.jvcard.Card; -import be.nikiroo.jvcard.Contact; -import be.nikiroo.jvcard.Data; -import be.nikiroo.jvcard.i18n.Trans; -import be.nikiroo.jvcard.i18n.Trans.StringId; +import be.nikiroo.jvcard.launcher.Main; +import be.nikiroo.jvcard.resources.ColorOption; +import be.nikiroo.jvcard.resources.StringId; import be.nikiroo.jvcard.tui.KeyAction.Mode; -import be.nikiroo.jvcard.tui.UiColors.Element; +import be.nikiroo.jvcard.tui.panes.ContactDetails; import be.nikiroo.jvcard.tui.panes.ContactDetailsRaw; import be.nikiroo.jvcard.tui.panes.ContactList; import be.nikiroo.jvcard.tui.panes.MainContent; +import be.nikiroo.utils.StringUtils; +import be.nikiroo.utils.Version; import com.googlecode.lanterna.TerminalSize; import com.googlecode.lanterna.gui2.BasicWindow; @@ -37,12 +37,12 @@ import com.googlecode.lanterna.input.KeyType; * @author niki * */ + public class MainWindow extends BasicWindow { private List defaultActions = new LinkedList(); private List actions = new LinkedList(); private List contentStack = new LinkedList(); - private boolean waitForOneKeyAnswer; - private KeyAction questionAction; + private UserQuestion userQuestion; private String titleCache; private Panel titlePanel; private Panel mainPanel; @@ -51,6 +51,68 @@ public class MainWindow extends BasicWindow { private Panel messagePanel; private TextBox text; + /** + * Information about a question to ask the user and its answer. + * + * @author niki + * + */ + private class UserQuestion { + private boolean oneKeyAnswer; + private KeyAction action; + private String answer; + + /** + * Create a new {@link UserQuestion}. + * + * @param action + * the action that triggered the question + * @param oneKeyAnswer + * TRUE if we expect a one-key answer + */ + public UserQuestion(KeyAction action, boolean oneKeyAnswer) { + this.action = action; + this.oneKeyAnswer = oneKeyAnswer; + } + + /** + * Return the {@link KeyAction} that triggered the question. + * + * @return the {@link KeyAction} + */ + public KeyAction getAction() { + return action; + } + + /** + * Check if a one-key answer is expected. + * + * @return TRUE if a one-key answer is expected + */ + public boolean isOneKeyAnswer() { + return oneKeyAnswer; + } + + /** + * Return the user answer. + * + * @return the user answer + */ + public String getAnswer() { + return answer; + } + + /** + * Set the user answer. + * + * @param answer + * the new answer + */ + public void setAnswer(String answer) { + this.answer = answer; + } + } + /** * Create a new, empty window. */ @@ -161,6 +223,16 @@ public class MainWindow extends BasicWindow { if (contentStack.size() > 0) prev = contentStack.remove(contentStack.size() - 1); + if (prev != null) { + try { + String mess = prev.wakeup(); + if (mess != null) + setMessage(mess, false); + } catch (IOException e) { + setMessage(e.getMessage(), true); + } + } + pushContent(prev); return removed; @@ -180,9 +252,9 @@ public class MainWindow extends BasicWindow { if (mess != null || messagePanel.getChildCount() > 0) { messagePanel.removeAllComponents(); if (mess != null) { - Element element = (error ? UiColors.Element.LINE_MESSAGE_ERR - : UiColors.Element.LINE_MESSAGE); - Label lbl = element.createLabel(" " + mess + " "); + ColorOption element = (error ? ColorOption.LINE_MESSAGE_ERR + : ColorOption.LINE_MESSAGE); + Label lbl = UiColors.createLabel(element, " " + mess + " "); messagePanel.addComponent(lbl, LinearLayout .createLayoutData(LinearLayout.Alignment.Center)); } @@ -238,8 +310,7 @@ public class MainWindow extends BasicWindow { */ private void setQuestion(KeyAction action, String question, String initial, boolean oneKey) { - questionAction = action; - waitForOneKeyAnswer = oneKey; + userQuestion = new UserQuestion(action, oneKey); messagePanel.removeAllComponents(); @@ -248,12 +319,18 @@ public class MainWindow extends BasicWindow { llayout.setSpacing(0); hpanel.setLayoutManager(llayout); - Label lbl = UiColors.Element.LINE_MESSAGE_QUESTION.createLabel(" " + Label lbl = UiColors.createLabel(ColorOption.LINE_MESSAGE_QUESTION, " " + question + " "); text = new TextBox(new TerminalSize(getSize().getColumns() - lbl.getSize().getColumns(), 1)); - if (initial != null) - text.setText(initial); + + if (initial != null) { + // add all chars one by one so the caret is at the end + for (int index = 0; index < initial.length(); index++) { + text.handleInput(new KeyStroke(initial.charAt(index), false, + false)); + } + } hpanel.addComponent(lbl, LinearLayout.createLayoutData(LinearLayout.Alignment.Beginning)); @@ -301,20 +378,23 @@ public class MainWindow extends BasicWindow { public boolean handleInput(KeyStroke key) { boolean handled = false; - if (questionAction != null) { - String answer = handleQuestion(key); - if (answer != null) { - handled = true; + if (userQuestion != null) { + handled = handleQuestion(userQuestion, key); + if (handled) { + if (userQuestion.getAnswer() != null) { + handleAction(userQuestion.getAction(), + userQuestion.getAnswer()); - handleAction(questionAction, answer); - questionAction = null; + userQuestion = null; + } } } else { handled = handleKey(key); } - if (!handled) + if (!handled) { handled = super.handleInput(key); + } return handled; } @@ -325,7 +405,7 @@ public class MainWindow extends BasicWindow { */ private void setTitle() { String prefix = " " + Main.APPLICATION_TITLE + " (version " - + Main.APPLICATION_VERSION + ")"; + + Version.getCurrentVersion() + ")"; String title = null; int count = -1; @@ -341,8 +421,7 @@ public class MainWindow extends BasicWindow { if (title.length() > 0) { prefix = prefix + ": "; - title = StringUtils.sanitize(title, UiColors.getInstance() - .isUnicode()); + title = StringUtils.sanitize(title, Main.isUnicode()); } String countStr = ""; @@ -373,18 +452,18 @@ public class MainWindow extends BasicWindow { super.setTitle(prefix); Label lblPrefix = new Label(prefix); - UiColors.Element.TITLE_MAIN.themeLabel(lblPrefix); + UiColors.themeLabel(ColorOption.TITLE_MAIN, lblPrefix); Label lblTitle = null; if (title.length() > 0) { lblTitle = new Label(title); - UiColors.Element.TITLE_VARIABLE.themeLabel(lblTitle); + UiColors.themeLabel(ColorOption.TITLE_VARIABLE, lblTitle); } Label lblCount = null; if (countStr != null) { lblCount = new Label(countStr); - UiColors.Element.TITLE_COUNT.themeLabel(lblCount); + UiColors.themeLabel(ColorOption.TITLE_COUNT, lblCount); } titlePanel.removeAllComponents(); @@ -430,21 +509,22 @@ public class MainWindow extends BasicWindow { actionPanel.removeAllComponents(); for (KeyAction action : this.actions) { - String trans = " " + action.getStringId().trans() + " "; + String trans = " " + Main.trans(action.getStringId()) + " "; if (" ".equals(trans)) continue; - String keyTrans = Trans.getInstance().trans(action.getKey()); + String keyTrans = KeyAction.trans(action.getKey()); Panel kPane = new Panel(); LinearLayout layout = new LinearLayout(Direction.HORIZONTAL); layout.setSpacing(0); kPane.setLayoutManager(layout); - kPane.addComponent(UiColors.Element.ACTION_KEY - .createLabel(keyTrans)); - kPane.addComponent(UiColors.Element.ACTION_DESC.createLabel(trans)); + kPane.addComponent(UiColors.createLabel(ColorOption.ACTION_KEY, + keyTrans)); + kPane.addComponent(UiColors.createLabel(ColorOption.ACTION_DESC, + trans)); actionPanel.addComponent(kPane); } @@ -456,44 +536,69 @@ public class MainWindow extends BasicWindow { } if (width > 0) { - actionPanel.addComponent(UiColors.Element.ACTION_DESC - .createLabel(StringUtils.padString("", width))); + actionPanel.addComponent(UiColors.createLabel( + ColorOption.ACTION_DESC, StringUtils.padString("", width))); } } /** * Handle user input when in "ask for question" mode (see - * {@link MainWindow#questionKey}). + * {@link MainWindow#userQuestion}). * + * @param userQuestion + * the question data * @param key * the key that has been pressed by the user * - * @return the user's answer if done + * @return TRUE if the {@link KeyStroke} was handled */ - private String handleQuestion(KeyStroke key) { - String answer = null; + private boolean handleQuestion(UserQuestion userQuestion, KeyStroke key) { + userQuestion.setAnswer(null); - if (waitForOneKeyAnswer) { - answer = "" + key.getCharacter(); + if (userQuestion.isOneKeyAnswer()) { + userQuestion.setAnswer("" + key.getCharacter()); } else { - if (key.getKeyType() == KeyType.Enter) { + // ^h == Backspace + if (key.isCtrlDown() && key.getCharacter() == 'h') { + key = new KeyStroke(KeyType.Backspace); + } + + switch (key.getKeyType()) { + case Enter: if (text != null) - answer = text.getText(); + userQuestion.setAnswer(text.getText()); else - answer = ""; + userQuestion.setAnswer(""); + break; + case Backspace: + int pos = text.getCaretPosition().getColumn(); + if (pos > 0) { + String current = text.getText(); + // force caret one space before: + text.setText(current.substring(0, pos - 1)); + // re-add full text: + text.setText(current.substring(0, pos - 1) + + current.substring(pos)); + } + return true; + default: + // Do nothing (continue entering text) + break; } } - if (answer != null) { + if (userQuestion.getAnswer() != null) { Interactable focus = null; MainContent content = getContent(); if (content != null) focus = content.nextFocus(null); focus.takeFocus(); + + return true; } - return answer; + return false; } /** @@ -501,8 +606,6 @@ public class MainWindow extends BasicWindow { * * @param key * the key that was pressed - * @param answer - * the answer given for this key * * @return if the window handled the input */ @@ -518,7 +621,13 @@ public class MainWindow extends BasicWindow { handled = true; - if (action.onAction()) { + action.getObject(); // see {@link KeyAction#getMessage()} + String mess = action.getMessage(); + if (mess != null) { + setMessage(mess, action.isError()); + } + + if (!action.isError() && action.onAction()) { handleAction(action, null); } @@ -531,20 +640,15 @@ public class MainWindow extends BasicWindow { /** * Handle the input in case of "normal" (not "ask for answer") mode. * - * @param key - * the key that was pressed + * @param action + * the key that was pressed and the action to take * @param answer * the answer given for this key * - * @return if the window handled the input */ private void handleAction(KeyAction action, String answer) { MainContent content = getContent(); - Card card = action.getCard(); - Contact contact = action.getContact(); - Data data = action.getData(); - switch (action.getMode()) { case MOVE: int x = 0; @@ -568,24 +672,28 @@ public class MainWindow extends BasicWindow { break; // mode with windows: case CONTACT_LIST: - if (card != null) { - pushContent(new ContactList(card)); + if (action.getCard() != null) { + pushContent(new ContactList(action.getCard())); + } else if (action.getObject() != null + && action.getObject() instanceof MainContent) { + MainContent mergeContent = (MainContent) action.getObject(); + pushContent(mergeContent); } break; case CONTACT_DETAILS: - if (contact != null) { - pushContent(new ContactDetailsRaw(contact)); + if (action.getContact() != null) { + pushContent(new ContactDetails(action.getContact())); + } + break; + case CONTACT_DETAILS_RAW: + if (action.getContact() != null) { + pushContent(new ContactDetailsRaw(action.getContact())); } break; // mode interpreted by MainWindow: case HELP: // TODO - // setMessage("Help! I need somebody! Help!", false); - if (answer == null) { - setQuestion(action, "Test question?", "[initial]"); - } else { - setMessage("You answered: " + answer, false); - } + setMessage("Help! I need somebody! Help!", false); break; case BACK: @@ -609,58 +717,25 @@ public class MainWindow extends BasicWindow { break; // action modes: - case EDIT_DETAIL: + case ASK_USER: if (answer == null) { - if (data != null) { - String name = data.getName(); - String value = data.getValue(); - setQuestion(action, name, value); - } - } else { - setMessage(null, false); - data.setValue(answer); - } - break; - case DELETE_CONTACT: - if (answer == null) { - if (contact != null) { - setQuestion(action, "Delete contact? [Y/N]"); - } + setQuestion(action, action.getQuestion(), + action.getDefaultAnswer()); } else { - setMessage(null, false); - if (answer.equalsIgnoreCase("y")) { - if (contact.delete()) { - content.refreshData(); - invalidate(); - setTitle(); - } else { - setMessage("Cannot delete this contact", true); - } - } + setMessage(action.callback(answer), true); + content.refreshData(); + invalidate(); + setTitle(); } break; - case SAVE_CARD: + case ASK_USER_KEY: if (answer == null) { - if (card != null) { - setQuestion(action, "Save changes? [Y/N]"); - } + setQuestion(action, action.getQuestion()); } else { - setMessage(null, false); - if (answer.equalsIgnoreCase("y")) { - boolean ok = false; - try { - if (card.save()) { - ok = true; - invalidate(); - } - } catch (IOException ioe) { - ioe.printStackTrace(); - } - - if (!ok) { - setMessage("Cannot save to file", true); - } - } + setMessage(action.callback(answer), true); + content.refreshData(); + invalidate(); + setTitle(); } break; default: