More i18n, v1.0 ready
[jvcard.git] / src / be / nikiroo / jvcard / tui / panes / ContactDetailsRaw.java
CommitLineData
fae07ea7
NR
1package be.nikiroo.jvcard.tui.panes;
2
bcb54330 3import java.util.LinkedList;
fae07ea7
NR
4import java.util.List;
5
6import be.nikiroo.jvcard.Contact;
7import be.nikiroo.jvcard.Data;
bcb54330 8import be.nikiroo.jvcard.TypeInfo;
7da41ecd
NR
9import be.nikiroo.jvcard.launcher.Main;
10import be.nikiroo.jvcard.resources.StringUtils;
e119a1c1
NR
11import be.nikiroo.jvcard.resources.enums.ColorOption;
12import be.nikiroo.jvcard.resources.enums.StringId;
fae07ea7
NR
13import be.nikiroo.jvcard.tui.KeyAction;
14import be.nikiroo.jvcard.tui.KeyAction.DataType;
15import be.nikiroo.jvcard.tui.KeyAction.Mode;
16
78e4af97
NR
17import com.googlecode.lanterna.input.KeyType;
18
296a0b75 19public class ContactDetailsRaw extends MainContentList {
fae07ea7 20 private Contact contact;
176a8327 21 private boolean extMode;
fae07ea7 22
296a0b75 23 public ContactDetailsRaw(Contact contact) {
fae07ea7 24 this.contact = contact;
176a8327 25 this.extMode = false;
fae07ea7 26
78e4af97 27 for (int i = 0; i < contact.size(); i++) {
176a8327 28 addItem("x");
fae07ea7
NR
29 }
30 }
31
32 @Override
33 public DataType getDataType() {
bcb54330 34 return DataType.DATA;
fae07ea7 35 }
ae22c247 36
fae07ea7
NR
37 @Override
38 public List<KeyAction> getKeyBindings() {
bcb54330
NR
39 List<KeyAction> actions = new LinkedList<KeyAction>();
40
78e4af97 41 actions.add(new KeyAction(Mode.ASK_USER, KeyType.Enter,
88eb8122 42 StringId.KEY_ACTION_EDIT_FIELD) {
bcb54330
NR
43 @Override
44 public Object getObject() {
176a8327 45 return getSelectedData();
bcb54330 46 }
ae22c247
NR
47
48 @Override
49 public String getQuestion() {
50 Data data = getData();
51 if (data != null) {
52 return data.getName();
53 }
54
55 return null;
56 }
57
58 @Override
59 public String getDefaultAnswer() {
60 Data data = getData();
61 if (data != null) {
30a4aa17 62 return data.getRawValue().replaceAll("\n", "\\\\n");
ae22c247
NR
63 }
64
65 return null;
66 }
67
68 @Override
69 public String callback(String answer) {
70 Data data = getData();
71 if (data != null) {
30a4aa17 72 data.setRawValue(answer.replaceAll("\\\\n", "\n"));
ae22c247
NR
73 return null;
74 }
75
76 // TODO: i18n
77 return "Cannot modify value";
78 }
bcb54330 79 });
88eb8122
NR
80 actions.add(new KeyAction(Mode.ASK_USER_KEY, 'd',
81 StringId.KEY_ACTION_DELETE) {
176a8327
NR
82 @Override
83 public Object getObject() {
84 return getSelectedData();
85 }
86
87 @Override
88 public String getQuestion() {
89 // TODO i18n
90 return "Delete data? [Y/N]";
91 }
92
93 @Override
94 public String callback(String answer) {
95 if (answer.equalsIgnoreCase("y")) {
96 Data data = getData();
97 if (data != null && data.delete()) {
98 removeItem("x");
99 return null;
100 }
101
102 // TODO i18n
103 return "Cannot delete data";
104 }
105
106 return null;
107 }
108 });
109 // TODO: ui
88eb8122 110 actions.add(new KeyAction(Mode.ASK_USER, 'a', StringId.KEY_ACTION_ADD) {
176a8327
NR
111 @Override
112 public Object getObject() {
113 return contact;
114 }
115
116 @Override
117 public String getQuestion() {
118 // TODO i18n
b9f192ed 119 return "new data (xx.group = yy): ";
176a8327
NR
120 }
121
122 @Override
123 public String callback(String answer) {
b9f192ed
NR
124 int indexEq = answer.indexOf('=');
125 if (indexEq >= 0) {
126 String name = answer.substring(0, indexEq).trim();
127 String value = answer.substring(indexEq + 1).trim();
128 String group = null;
129
130 int indexDt = name.indexOf('.');
131 if (indexDt >= 0) {
132 group = name.substring(indexDt + 1).trim();
133 name = name.substring(0, indexDt).trim();
134 }
135
136 Data data = new Data(null, name, value, group);
176a8327
NR
137 getContact().add(data);
138 addItem("x");
139 }
176a8327
NR
140 return null;
141 }
142 });
143 // TODO: use a real UI for this, not a simple text box (a list or
144 // something, maybe a whole new pane?)
e119a1c1 145 actions.add(new KeyAction(Mode.ASK_USER, 't', StringId.DUMMY) {
176a8327
NR
146 private String previous;
147
148 @Override
149 public Object getObject() {
150 return getSelectedData();
151 }
152
153 @Override
154 public String getQuestion() {
155 Data data = getData();
156 if (data != null) {
157 return data.getName();
158 }
159
160 return null;
161 }
162
163 @Override
164 public String getDefaultAnswer() {
165 Data data = getData();
166 if (data != null) {
167 previous = typesToString(data, null).toString();
168 return previous;
169 }
170
171 return null;
172 }
173
174 @Override
175 public String callback(String answer) {
176 Data data = getData();
177 if (data != null) {
178 if (!answer.equals(previous)) {
26d2bd05 179 data.replaceListContent(stringToTypes(answer));
176a8327
NR
180 }
181 return null;
182 }
183
184 // TODO: i18n
185 return "Cannot modify value";
186 }
187 });
e119a1c1 188 actions.add(new KeyAction(Mode.ASK_USER, 'g', StringId.DUMMY) {
176a8327
NR
189 private String previous;
190
191 @Override
192 public Object getObject() {
193 return getSelectedData();
194 }
195
196 @Override
197 public String getQuestion() {
198 Data data = getData();
199 if (data != null) {
200 return data.getName();
201 }
202
203 return null;
204 }
205
206 @Override
207 public String getDefaultAnswer() {
208 Data data = getData();
209 if (data != null) {
210 previous = data.getGroup();
211 return previous;
212 }
213
214 return null;
215 }
216
217 @Override
218 public String callback(String answer) {
219 Data data = getData();
220 if (data != null) {
221 if (!answer.equals(previous)) {
222 data.setGroup(answer);
223 }
224 return null;
225 }
226
227 // TODO: i18n
228 return "Cannot modify group";
229 }
230 });
bcb54330 231 actions.add(new KeyAction(Mode.NONE, KeyType.Tab,
e119a1c1 232 StringId.KEY_ACTION_SWITCH_FORMAT) {
bcb54330
NR
233 @Override
234 public boolean onAction() {
176a8327 235 extMode = !extMode;
bcb54330
NR
236 return false;
237 }
238 });
239
240 return actions;
fae07ea7
NR
241 }
242
fae07ea7
NR
243 @Override
244 public String getTitle() {
0b0b2b0f
NR
245 String title = null;
246
247 if (contact != null) {
248 title = contact.getPreferredDataValue("FN");
249 if (title == null || title.length() == 0)
250 title = contact.getPreferredDataValue("N");
251 }
252
253 return title;
fae07ea7
NR
254 }
255
256 @Override
257 public String move(int x, int y) {
258 // TODO Auto-generated method stub
259 return null;
260 }
f82bad11
NR
261
262 @Override
263 protected List<TextPart> getLabel(int index, int width, boolean selected,
264 boolean focused) {
265 // TODO: from ini file?
266 int SIZE_COL_1 = 15;
176a8327
NR
267 int SIZE_COL_2_OPT = 10;
268
269 if (!extMode)
270 SIZE_COL_2_OPT = 0;
271
272 List<TextPart> parts = new LinkedList<TextPart>();
273 Data data = null;
274 if (index > -1 && index < contact.size())
275 data = contact.get(index);
276
277 if (data == null)
278 return parts;
f82bad11 279
e119a1c1
NR
280 ColorOption el = (focused && selected) ? ColorOption.CONTACT_LINE_SELECTED
281 : ColorOption.CONTACT_LINE;
282 ColorOption elSep = (focused && selected) ? ColorOption.CONTACT_LINE_SEPARATOR_SELECTED
283 : ColorOption.CONTACT_LINE_SEPARATOR;
284 ColorOption elDirty = (focused && selected) ? ColorOption.CONTACT_LINE_DIRTY_SELECTED
285 : ColorOption.CONTACT_LINE_DIRTY;
f82bad11 286
f82bad11
NR
287 if (data.isDirty()) {
288 parts.add(new TextPart(" ", el));
289 parts.add(new TextPart("*", elDirty));
290 } else {
291 parts.add(new TextPart(" ", elSep));
292 }
293 String name = " " + data.getName() + " ";
294 String value = null;
176a8327 295 String group = null;
f82bad11
NR
296
297 StringBuilder valueBuilder = new StringBuilder(" ");
176a8327 298 if (!extMode) {
aecb3399 299 valueBuilder.append(data.getValue().replaceAll("\n", "\\\\n"));
f82bad11
NR
300 if (data.getGroup() != null && data.getGroup().length() > 0) {
301 valueBuilder.append("(");
302 valueBuilder.append(data.getGroup());
303 valueBuilder.append(")");
304 }
176a8327
NR
305 } else {
306 group = data.getGroup();
307 if (group == null)
308 group = "";
309
310 typesToString(data, valueBuilder);
f82bad11
NR
311 }
312 valueBuilder.append(" ");
313
314 value = valueBuilder.toString();
315
7da41ecd
NR
316 name = StringUtils.sanitize(name, Main.isUnicode());
317 value = StringUtils.sanitize(value, Main.isUnicode());
f82bad11
NR
318
319 name = StringUtils.padString(name, SIZE_COL_1);
176a8327 320 group = StringUtils.padString(group, SIZE_COL_2_OPT);
f82bad11 321 value = StringUtils.padString(value, width - SIZE_COL_1
176a8327
NR
322 - SIZE_COL_2_OPT - (extMode ? 2 : 1) * getSeparator().length()
323 - 2);
f82bad11
NR
324
325 parts.add(new TextPart(name, el));
326 parts.add(new TextPart(getSeparator(), elSep));
327 parts.add(new TextPart(value, el));
176a8327
NR
328 if (extMode) {
329 parts.add(new TextPart(getSeparator(), elSep));
330 parts.add(new TextPart(group, el));
331 }
f82bad11
NR
332
333 return parts;
176a8327
NR
334 }
335
336 /**
337 * Return the currently selected {@link Data}.
338 *
339 * @return the currently selected {@link Data}
340 */
341 private Data getSelectedData() {
342 int index = getSelectedIndex();
343 if (index > -1 && index < this.contact.size())
344 return contact.get(index);
345 return null;
346 }
347
348 /**
349 * Serialise the {@link TypeInfo}s in the given {@link Data}.
350 *
351 * @param data
352 * the {@link Data} from which to take the {@link TypeInfo}s
353 * @param builder
354 * an optional {@link StringBuilder} to append the serialized
355 * version to
356 *
357 * @return the given {@link StringBuilder} or a new one if the given one is
358 * NULL
359 */
360 static private StringBuilder typesToString(Data data, StringBuilder builder) {
361 if (builder == null)
362 builder = new StringBuilder();
363
aecb3399 364 for (TypeInfo type : data) {
176a8327
NR
365 if (builder.length() > 1)
366 builder.append(", ");
367 builder.append(type.getName().replaceAll(",", "\\,"));
368 builder.append(": ");
369 builder.append(type.getValue().replaceAll(":", "\\:"));
370 }
371
372 return builder;
373 }
f82bad11 374
176a8327
NR
375 /**
376 * Unserialise a list of {@link TypeInfo}s.
377 *
378 * @param value
379 * the serialised value
380 *
381 * @return the {@link TypeInfo} in their object form
382 */
383 static private List<TypeInfo> stringToTypes(String value) {
384 List<TypeInfo> infos = new LinkedList<TypeInfo>();
385 if (value == null || value.length() == 0)
386 return infos;
387
388 char previous = '\0';
389 char car = '\0';
390 int done = 0;
391 for (int index = 0; index < value.length(); index++) {
392 car = value.charAt(index);
393 if (index == value.length() - 1) {
394 index++;
395 previous = '\0';
396 car = ',';
397 }
398
399 if (previous != '\\' && car == ',') {
400 String[] tab = value.substring(done, index).split("\\:");
401 infos.add(new TypeInfo( //
402 tab[0].replaceAll("\\,", ",").replaceAll("\\:", ":")
403 .trim(), //
404 tab[1].replaceAll("\\,", ",").replaceAll("\\:", ":")
405 .trim()));
406 done = index + 1;
407 }
408
409 previous = car;
410 }
411
412 return infos;
413 }
fae07ea7 414}