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