Resources system rewrite + new "--save-config DIR" option
[jvcard.git] / src / be / nikiroo / jvcard / tui / panes / ContactList.java
CommitLineData
fae07ea7
NR
1package be.nikiroo.jvcard.tui.panes;
2
ae22c247 3import java.io.IOException;
fae07ea7
NR
4import java.util.LinkedList;
5import java.util.List;
6
7import be.nikiroo.jvcard.Card;
0b0b2b0f 8import be.nikiroo.jvcard.Contact;
176a8327 9import be.nikiroo.jvcard.Data;
7da41ecd 10import be.nikiroo.jvcard.launcher.Main;
e119a1c1
NR
11import be.nikiroo.jvcard.resources.bundles.DisplayBundle;
12import be.nikiroo.jvcard.resources.enums.DisplayOption;
13import be.nikiroo.jvcard.resources.enums.ColorOption;
14import be.nikiroo.jvcard.resources.enums.StringId;
fae07ea7 15import be.nikiroo.jvcard.tui.KeyAction;
fae07ea7
NR
16import be.nikiroo.jvcard.tui.KeyAction.DataType;
17import be.nikiroo.jvcard.tui.KeyAction.Mode;
18
19import com.googlecode.lanterna.input.KeyType;
20
21public class ContactList extends MainContentList {
22 private Card card;
ae22c247
NR
23 private List<Contact> contacts;
24 private String filter;
fae07ea7 25
d56a0ad4
NR
26 private List<String> formats;
27 private int selectedFormat;
28 private String format;
fae07ea7
NR
29
30 public ContactList(Card card) {
e119a1c1 31 DisplayBundle map = new DisplayBundle();
d56a0ad4 32 formats = new LinkedList<String>();
e119a1c1
NR
33 for (String format : map.getString(DisplayOption.CONTACT_LIST_FORMAT)
34 .split(",")) {
d56a0ad4
NR
35 formats.add(format);
36 }
37
38 selectedFormat = -1;
fae07ea7
NR
39 switchFormat();
40
41 setCard(card);
42 }
43
44 /**
ae22c247
NR
45 * Change the currently displayed contacts card, only allowing those that
46 * satisfy the current filter.
fae07ea7
NR
47 *
48 * @param card
49 * the new {@link Card}
ae22c247
NR
50 * @param filter
51 * the text filter or NULL for all contacts
fae07ea7
NR
52 */
53 public void setCard(Card card) {
54 clearItems();
55 this.card = card;
ae22c247 56 this.contacts = new LinkedList<Contact>();
fae07ea7
NR
57
58 if (card != null) {
26d2bd05 59 for (Contact c : card) {
ae22c247 60 if (filter == null
26d254a3 61 || c.toString(format, "|").toLowerCase()
ae22c247 62 .contains(filter.toLowerCase())) {
176a8327 63 addItem("x");
ae22c247
NR
64 contacts.add(c);
65 }
fae07ea7
NR
66 }
67 }
68
69 setSelectedIndex(0);
70 }
71
bcb54330
NR
72 @Override
73 public void refreshData() {
74 int index = getSelectedIndex();
75 setCard(card);
ae22c247
NR
76 if (index >= contacts.size())
77 index = contacts.size() - 1;
bcb54330 78 setSelectedIndex(index);
ae22c247 79
bcb54330
NR
80 super.refreshData();
81 }
82
fae07ea7
NR
83 @Override
84 public String getExitWarning() {
85 if (card != null && card.isDirty()) {
bcb54330 86 return "Ignore unsaved changes? [Y/N]";
fae07ea7 87 }
bcb54330 88
fae07ea7
NR
89 return null;
90 }
91
92 @Override
93 public List<KeyAction> getKeyBindings() {
94 List<KeyAction> actions = new LinkedList<KeyAction>();
95
176a8327 96 // TODO ui
9b8cb729 97 actions.add(new KeyAction(Mode.ASK_USER, 'a',
e119a1c1 98 StringId.KEY_ACTION_ADD) {
0b0b2b0f 99 @Override
bcb54330 100 public Object getObject() {
176a8327
NR
101 return card;
102 }
103
104 @Override
105 public String getQuestion() {
e119a1c1 106 return Main.trans(StringId.ASK_USER_CONTACT_NAME);
176a8327
NR
107 }
108
109 @Override
110 public String callback(String answer) {
111 if (answer.length() > 0) {
112 List<Data> datas = new LinkedList<Data>();
113 datas.add(new Data(null, "FN", answer, null));
114 getCard().add(new Contact(datas));
115 addItem("x");
116 }
117
118 return null;
0b0b2b0f
NR
119 }
120 });
ae22c247 121 actions.add(new KeyAction(Mode.ASK_USER_KEY, 'd',
e119a1c1 122 StringId.KEY_ACTION_DELETE_CONTACT) {
bcb54330
NR
123 @Override
124 public Object getObject() {
125 return getSelectedContact();
126 }
ae22c247
NR
127
128 @Override
129 public String getQuestion() {
9b8cb729
NR
130 Contact contact = getSelectedContact();
131 String contactName = "null";
132 if (contact != null)
133 contactName = "" + contact.getPreferredDataValue("FN");
134
e119a1c1
NR
135 return Main.trans(
136 StringId.CONFIRM_USER_DELETE_CONTACT,
26d254a3 137 contactName);
ae22c247
NR
138 }
139
140 @Override
141 public String callback(String answer) {
142 if (answer.equalsIgnoreCase("y")) {
143 Contact contact = getSelectedContact();
144 if (contact != null && contact.delete()) {
176a8327 145 removeItem("x");
ae22c247
NR
146 return null;
147 }
148
9b8cb729
NR
149 String contactName = "null";
150 if (contact != null)
151 contactName = "" + contact.getPreferredDataValue("FN");
152
e119a1c1
NR
153 return Main.trans(
154 StringId.ERR_CANNOT_DELETE_CONTACT,
9b8cb729 155 contactName);
ae22c247
NR
156 }
157
158 return null;
159 }
bcb54330 160 });
ae22c247 161 actions.add(new KeyAction(Mode.ASK_USER_KEY, 's',
e119a1c1 162 StringId.KEY_ACTION_SAVE_CARD) {
fae07ea7
NR
163 @Override
164 public Object getObject() {
bcb54330 165 return card;
fae07ea7 166 }
ae22c247
NR
167
168 @Override
169 public String getQuestion() {
170 return "Save changes? [Y/N]";
171 }
172
173 @Override
174 public String callback(String answer) {
175 if (answer.equalsIgnoreCase("y")) {
176 boolean ok = false;
177 try {
178 if (card != null && card.save())
179 ok = true;
180 } catch (IOException ioe) {
181 ioe.printStackTrace();
182 }
183
184 if (!ok) {
185 return "Cannot save to file";
186 }
187 }
188
189 return null;
190 }
191
fae07ea7
NR
192 });
193 actions.add(new KeyAction(Mode.CONTACT_DETAILS, KeyType.Enter,
e119a1c1 194 StringId.KEY_ACTION_VIEW_CONTACT) {
fae07ea7
NR
195 @Override
196 public Object getObject() {
bcb54330 197 return getSelectedContact();
fae07ea7
NR
198 }
199 });
bcb54330 200 actions.add(new KeyAction(Mode.NONE, KeyType.Tab,
e119a1c1 201 StringId.KEY_ACTION_SWITCH_FORMAT) {
fae07ea7
NR
202 @Override
203 public boolean onAction() {
204 switchFormat();
205 return false;
206 }
207 });
ae22c247 208 actions.add(new KeyAction(Mode.ASK_USER, 'w',
e119a1c1 209 StringId.KEY_ACTION_SEARCH) {
ae22c247
NR
210
211 @Override
212 public String getQuestion() {
213 return "Search:";
214 }
215
216 @Override
217 public String getDefaultAnswer() {
218 return filter;
219 }
220
221 @Override
222 public String callback(String answer) {
223 filter = answer;
224 setCard(card);
225 return null;
226 }
227 });
fae07ea7
NR
228
229 return actions;
230 }
231
232 @Override
233 public DataType getDataType() {
234 return DataType.CARD;
235 }
236
fae07ea7
NR
237 @Override
238 public String getTitle() {
0b0b2b0f 239 if (card != null) {
ae22c247
NR
240 if (filter != null)
241 return card.getName() + " [" + filter + "]";
0b0b2b0f
NR
242 return card.getName();
243 }
244
fae07ea7
NR
245 return null;
246 }
247
248 @Override
9c8baf0c
NR
249 protected List<TextPart> getLabel(int index, int width, boolean selected,
250 boolean focused) {
bcb54330
NR
251 List<TextPart> parts = new LinkedList<TextPart>();
252
253 Contact contact = null;
ae22c247
NR
254 if (index > -1 && index < contacts.size())
255 contact = contacts.get(index);
bcb54330
NR
256
257 if (contact == null)
258 return parts;
9c8baf0c 259
e119a1c1
NR
260 ColorOption el = (focused && selected) ? ColorOption.CONTACT_LINE_SELECTED
261 : ColorOption.CONTACT_LINE;
262 ColorOption elSep = (focused && selected) ? ColorOption.CONTACT_LINE_SEPARATOR_SELECTED
263 : ColorOption.CONTACT_LINE_SEPARATOR;
264 ColorOption elDirty = (focused && selected) ? ColorOption.CONTACT_LINE_DIRTY_SELECTED
265 : ColorOption.CONTACT_LINE_DIRTY;
9c8baf0c 266
0b0b2b0f 267 width -= 2; // dirty mark space
9c8baf0c 268
bcb54330 269 String[] array = contact.toStringArray(format, getSeparator(), " ",
7da41ecd 270 width, Main.isUnicode());
0b0b2b0f 271
bcb54330 272 if (contact.isDirty()) {
0b0b2b0f
NR
273 parts.add(new TextPart(" ", el));
274 parts.add(new TextPart("*", elDirty));
275 } else {
276 parts.add(new TextPart(" ", elSep));
9c8baf0c
NR
277 }
278
0b0b2b0f
NR
279 boolean separator = false;
280 for (String str : array) {
281 parts.add(new TextPart(str, (separator ? elSep : el)));
282 separator = !separator;
283 }
9c8baf0c
NR
284
285 return parts;
fae07ea7
NR
286 }
287
bcb54330
NR
288 /**
289 * Return the currently selected {@link Contact}.
290 *
291 * @return the currently selected {@link Contact}
292 */
293 private Contact getSelectedContact() {
294 int index = getSelectedIndex();
ae22c247
NR
295 if (index > -1 && index < contacts.size())
296 return contacts.get(index);
bcb54330
NR
297 return null;
298 }
299
fae07ea7
NR
300 private void switchFormat() {
301 if (formats.size() == 0)
302 return;
303
304 selectedFormat++;
305 if (selectedFormat >= formats.size()) {
306 selectedFormat = 0;
307 }
308
309 format = formats.get(selectedFormat);
310
311 invalidate();
312 }
313}