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.StringUtils;
+import be.nikiroo.jvcard.resources.Trans.StringId;
import be.nikiroo.jvcard.tui.KeyAction.Mode;
import be.nikiroo.jvcard.tui.UiColors.Element;
import be.nikiroo.jvcard.tui.panes.ContactDetails;
* @author niki
*
*/
+
public class MainWindow extends BasicWindow {
private List<KeyAction> defaultActions = new LinkedList<KeyAction>();
private List<KeyAction> actions = new LinkedList<KeyAction>();
private List<MainContent> contentStack = new LinkedList<MainContent>();
- private boolean waitForOneKeyAnswer;
- private KeyAction questionAction;
+ private UserQuestion userQuestion;
private String titleCache;
private Panel titlePanel;
private Panel mainPanel;
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.
*/
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;
*/
private void setQuestion(KeyAction action, String question, String initial,
boolean oneKey) {
- questionAction = action;
- waitForOneKeyAnswer = oneKey;
+ userQuestion = new UserQuestion(action, oneKey);
messagePanel.removeAllComponents();
+ 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));
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;
}
if (title.length() > 0) {
prefix = prefix + ": ";
- title = StringUtils.sanitize(title, UiColors.getInstance()
- .isUnicode());
+ title = StringUtils.sanitize(title, Main.isUnicode());
}
String countStr = "";
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);
/**
* 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);
- // TODO: support ^H (backspace)
- // TODO: start at end of initial question, not start
-
- 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;
}
/**
handled = true;
+ action.getObject(); // see {@link KeyAction#getMessage()}
+ String mess = action.getMessage();
+ if (mess != null) {
+ setMessage(mess, action.isError());
+ }
+
if (action.onAction()) {
handleAction(action, null);
}
case CONTACT_LIST:
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:
// 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: