Add text-image control and separate Edit/View contact
[jvcard.git] / src / be / nikiroo / jvcard / tui / panes / ContactList.java
1 package be.nikiroo.jvcard.tui.panes;
2
3 import java.util.LinkedList;
4 import java.util.List;
5
6 import be.nikiroo.jvcard.Card;
7 import be.nikiroo.jvcard.Contact;
8 import be.nikiroo.jvcard.i18n.Trans;
9 import be.nikiroo.jvcard.tui.KeyAction;
10 import be.nikiroo.jvcard.tui.UiColors;
11 import be.nikiroo.jvcard.tui.KeyAction.DataType;
12 import be.nikiroo.jvcard.tui.KeyAction.Mode;
13 import be.nikiroo.jvcard.tui.UiColors.Element;
14
15 import com.googlecode.lanterna.input.KeyType;
16
17 public class ContactList extends MainContentList {
18 private Card card;
19
20 private List<String> formats = new LinkedList<String>();
21 private int selectedFormat = -1;
22 private String format = "";
23
24 public ContactList(Card card) {
25 super(UiColors.Element.CONTACT_LINE,
26 UiColors.Element.CONTACT_LINE_SELECTED);
27
28 // TODO: should get that in an INI file
29 formats.add("NICKNAME@3|FN@+|EMAIL@30");
30 formats.add("FN@+|EMAIL@40");
31 switchFormat();
32
33 setCard(card);
34 }
35
36 /**
37 * Change the currently displayed contacts card.
38 *
39 * @param card
40 * the new {@link Card}
41 */
42 public void setCard(Card card) {
43 clearItems();
44 this.card = card;
45
46 if (card != null) {
47 for (int i = 0; i < card.getContacts().size(); i++) {
48 addItem("[contact line]");
49 }
50 }
51
52 setSelectedIndex(0);
53 }
54
55 @Override
56 public void refreshData() {
57 int index = getSelectedIndex();
58 setCard(card);
59 setSelectedIndex(index);
60 super.refreshData();
61 }
62
63 @Override
64 public String getExitWarning() {
65 if (card != null && card.isDirty()) {
66 return "Ignore unsaved changes? [Y/N]";
67 }
68
69 return null;
70 }
71
72 @Override
73 public List<KeyAction> getKeyBindings() {
74 List<KeyAction> actions = new LinkedList<KeyAction>();
75
76 // TODO add
77 actions.add(new KeyAction(Mode.CONTACT_DETAILS_RAW, 'e',
78 Trans.StringId.KEY_ACTION_EDIT_CONTACT) {
79 @Override
80 public Object getObject() {
81 return getSelectedContact();
82 }
83 });
84 actions.add(new KeyAction(Mode.DELETE_CONTACT, 'd',
85 Trans.StringId.KEY_ACTION_DELETE_CONTACT) {
86 @Override
87 public Object getObject() {
88 return getSelectedContact();
89 }
90 });
91 actions.add(new KeyAction(Mode.SAVE_CARD, 's',
92 Trans.StringId.KEY_ACTION_SAVE_CARD) {
93 @Override
94 public Object getObject() {
95 return card;
96 }
97 });
98 actions.add(new KeyAction(Mode.CONTACT_DETAILS, KeyType.Enter,
99 Trans.StringId.KEY_ACTION_VIEW_CONTACT) {
100 @Override
101 public Object getObject() {
102 return getSelectedContact();
103 }
104 });
105 actions.add(new KeyAction(Mode.NONE, KeyType.Tab,
106 Trans.StringId.KEY_ACTION_SWITCH_FORMAT) {
107 @Override
108 public boolean onAction() {
109 switchFormat();
110 return false;
111 }
112 });
113
114 return actions;
115 }
116
117 @Override
118 public DataType getDataType() {
119 return DataType.CARD;
120 }
121
122 @Override
123 public String getTitle() {
124 if (card != null) {
125 return card.getName();
126 }
127
128 return null;
129 }
130
131 @Override
132 protected List<TextPart> getLabel(int index, int width, boolean selected,
133 boolean focused) {
134 List<TextPart> parts = new LinkedList<TextPart>();
135
136 Contact contact = null;
137 if (index > -1 && index < card.size())
138 contact = card.get(index);
139
140 if (contact == null)
141 return parts;
142
143 Element el = (focused && selected) ? Element.CONTACT_LINE_SELECTED
144 : Element.CONTACT_LINE;
145 Element elSep = (focused && selected) ? Element.CONTACT_LINE_SEPARATOR_SELECTED
146 : Element.CONTACT_LINE_SEPARATOR;
147 Element elDirty = (focused && selected) ? Element.CONTACT_LINE_DIRTY_SELECTED
148 : Element.CONTACT_LINE_DIRTY;
149
150 width -= 2; // dirty mark space
151
152 String[] array = contact.toStringArray(format, getSeparator(), " ",
153 width, UiColors.getInstance().isUnicode());
154
155 if (contact.isDirty()) {
156 parts.add(new TextPart(" ", el));
157 parts.add(new TextPart("*", elDirty));
158 } else {
159 parts.add(new TextPart(" ", elSep));
160 }
161
162 boolean separator = false;
163 for (String str : array) {
164 parts.add(new TextPart(str, (separator ? elSep : el)));
165 separator = !separator;
166 }
167
168 return parts;
169 }
170
171 /**
172 * Return the currently selected {@link Contact}.
173 *
174 * @return the currently selected {@link Contact}
175 */
176 private Contact getSelectedContact() {
177 int index = getSelectedIndex();
178 if (index > -1 && index < card.size())
179 return card.get(index);
180 return null;
181 }
182
183 private void switchFormat() {
184 if (formats.size() == 0)
185 return;
186
187 selectedFormat++;
188 if (selectedFormat >= formats.size()) {
189 selectedFormat = 0;
190 }
191
192 format = formats.get(selectedFormat);
193
194 invalidate();
195 }
196 }