Show some information in ContacTView (FN/N, email, phone, notes)
[jvcard.git] / src / be / nikiroo / jvcard / tui / panes / ContactDetails.java
CommitLineData
f04d8b1c
NR
1package be.nikiroo.jvcard.tui.panes;
2
3import java.awt.Image;
4import java.util.Base64;
25232463 5import java.util.LinkedList;
f04d8b1c
NR
6import java.util.List;
7
8import javax.swing.ImageIcon;
9
10import be.nikiroo.jvcard.Contact;
11import be.nikiroo.jvcard.Data;
12import be.nikiroo.jvcard.TypeInfo;
25232463
NR
13import be.nikiroo.jvcard.i18n.Trans;
14import be.nikiroo.jvcard.tui.ImageTextControl;
f04d8b1c
NR
15import be.nikiroo.jvcard.tui.KeyAction;
16import be.nikiroo.jvcard.tui.KeyAction.DataType;
25232463 17import be.nikiroo.jvcard.tui.KeyAction.Mode;
f82bad11 18import be.nikiroo.jvcard.tui.UiColors;
f04d8b1c
NR
19
20import com.googlecode.lanterna.TerminalSize;
21import com.googlecode.lanterna.gui2.BorderLayout;
f82bad11
NR
22import com.googlecode.lanterna.gui2.Direction;
23import com.googlecode.lanterna.gui2.Label;
24import com.googlecode.lanterna.gui2.LinearLayout;
f04d8b1c 25import com.googlecode.lanterna.gui2.Panel;
25232463 26import com.googlecode.lanterna.input.KeyType;
f04d8b1c
NR
27
28public class ContactDetails extends MainContent {
29 private Contact contact;
ae22c247 30 private Panel top;
f82bad11 31 private ImageTextControl txtImage;
ae22c247
NR
32 private Image image;
33 private boolean fullscreenImage;
f82bad11
NR
34 private Panel infoPanel;
35 private Label note;
f04d8b1c
NR
36
37 public ContactDetails(Contact contact) {
f04d8b1c
NR
38 BorderLayout blayout = new BorderLayout();
39 setLayoutManager(blayout);
40
ae22c247 41 top = new Panel();
f82bad11
NR
42 blayout = new BorderLayout();
43 top.setLayoutManager(blayout);
44
45 infoPanel = new Panel();
46 infoPanel.setLayoutManager(new LinearLayout(Direction.VERTICAL));
47 top.addComponent(infoPanel, BorderLayout.Location.CENTER);
48
49 Panel notePanel = new Panel();
50 notePanel.setLayoutManager(new LinearLayout(Direction.HORIZONTAL));
51
52 notePanel.addComponent(UiColors.Element.VIEW_CONTACT_NOTES_TITLE
53 .createLabel("Notes:"));
54 note = UiColors.Element.VIEW_CONTACT_NORMAL.createLabel("");
55 notePanel.addComponent(note);
56
ae22c247 57 setContact(contact);
f82bad11 58
ae22c247 59 addComponent(top, BorderLayout.Location.TOP);
f82bad11 60 addComponent(notePanel, BorderLayout.Location.CENTER);
ae22c247
NR
61 }
62
f82bad11
NR
63 /**
64 * Change the enclosed {@link Contact} from this {@link ContactDetails}.
65 *
66 * @param contact
67 * the new {@link Contact}
68 */
ae22c247 69 public void setContact(Contact contact) {
f82bad11
NR
70 if (this.contact == contact)
71 return;
72
ae22c247
NR
73 this.contact = contact;
74
f82bad11
NR
75 if (contact == null) {
76 image = null;
77 } else {
78 infoPanel.removeAllComponents();
79
80 String name = contact.getPreferredDataValue("FN");
81 if (name == null || name.length() == 0) {
82 // TODO format it ourself
83 name = contact.getPreferredDataValue("N");
84 }
85
86 // TODO: i18n + do it properly
87 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NAME
88 .createLabel(name));
89
90 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
91 .createLabel(""));
92 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
93 .createLabel("Phone: "
94 + contact.getPreferredDataValue("TEL")));
95 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
96 .createLabel("eMail: "
97 + contact.getPreferredDataValue("EMAIL")));
98 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
99 .createLabel(""));
100
101 String notes = contact.getPreferredDataValue("NOTE");
102 if (notes == null)
103 notes = "";
104 note.setText(notes.replaceAll("\\\\n", "\n"));
105
f04d8b1c
NR
106 Data photo = contact.getPreferredData("PHOTO");
107 if (photo != null) {
108 TypeInfo encoding = null;
109 TypeInfo type = null;
78e4af97
NR
110 for (int index = 0; index < photo.size(); index++) {
111 TypeInfo info = photo.get(index);
f04d8b1c
NR
112 if (info.getName() != null) {
113 if (info.getName().equalsIgnoreCase("ENCODING"))
114 encoding = info;
115 if (info.getName().equalsIgnoreCase("TYPE"))
116 type = info;
117 }
118 }
119
120 if (encoding != null && encoding.getValue() != null
121 && encoding.getValue().equalsIgnoreCase("b")) {
122
f82bad11 123 image = new ImageIcon(Base64.getDecoder().decode(
f04d8b1c 124 photo.getValue())).getImage();
f04d8b1c
NR
125 }
126 }
127 }
128
f82bad11 129 setImage(image);
f04d8b1c 130 }
25232463
NR
131
132 @Override
133 public DataType getDataType() {
134 return DataType.DATA;
135 }
136
137 @Override
138 public List<KeyAction> getKeyBindings() {
139 List<KeyAction> actions = new LinkedList<KeyAction>();
140
141 // TODO
142 actions.add(new KeyAction(Mode.NONE, KeyType.Tab,
143 Trans.StringId.KEY_ACTION_SWITCH_FORMAT) {
144 @Override
145 public boolean onAction() {
f82bad11
NR
146 if (txtImage != null) {
147 txtImage.switchMode();
25232463
NR
148 }
149
150 return false;
151 }
152 });
153 actions.add(new KeyAction(Mode.NONE, 'i',
ae22c247 154 Trans.StringId.KEY_ACTION_INVERT) {
25232463
NR
155 @Override
156 public boolean onAction() {
f82bad11
NR
157 if (txtImage != null) {
158 txtImage.invertColor();
25232463
NR
159 }
160
161 return false;
162 }
163 });
ae22c247
NR
164 actions.add(new KeyAction(Mode.NONE, 'f',
165 Trans.StringId.KEY_ACTION_FULLSCREEN) {
166 @Override
167 public boolean onAction() {
168 fullscreenImage = !fullscreenImage;
169 setImage(image);
170 return false;
171 }
172 });
25232463
NR
173
174 return actions;
175 }
ae22c247
NR
176
177 @Override
178 public synchronized Panel setSize(TerminalSize size) {
179 super.setSize(size);
180 setImage(image);
181 return this;
182 }
183
184 /**
f82bad11
NR
185 * Set the {@link Image} to render and refresh it to the current size
186 * constraints.
ae22c247
NR
187 *
188 * @param image
189 * the new {@link Image}
190 */
191 private void setImage(Image image) {
192 this.image = image;
193
f82bad11
NR
194 if (txtImage != null && top.containsComponent(txtImage))
195 top.removeComponent(txtImage);
196
ae22c247
NR
197 TerminalSize size = getTxtSize();
198 if (size != null) {
f82bad11
NR
199 if (txtImage != null)
200 txtImage.setSize(size);
ae22c247 201 else
f82bad11 202 txtImage = new ImageTextControl(image, size);
ae22c247
NR
203 }
204
f82bad11
NR
205 if (size != null) {
206 top.addComponent(txtImage, BorderLayout.Location.LEFT);
207 }
ae22c247 208
f82bad11 209 invalidate();
ae22c247
NR
210 }
211
212 /**
213 * Compute the size to use for the {@link Image} text rendering. Return NULL
214 * in case of error.
215 *
216 * @return the {@link TerminalSize} to use or NULL if it is not possible
217 */
218 private TerminalSize getTxtSize() {
219 if (image != null && getSize() != null && getSize().getColumns() > 0
220 && getSize().getRows() > 0) {
221 if (fullscreenImage) {
222 return getSize();
223 } else {
f82bad11
NR
224 // TODO: configure size?
225 int w = getSize().getColumns() - 40;
226 int h = getSize().getRows() - 5;
227 if (w <= 0 || h <= 0)
228 return null;
229
230 return new TerminalSize(w, h);
ae22c247
NR
231 }
232 }
233
234 return null;
235 }
f04d8b1c 236}