Colours are now taken from a .properties file
[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}.
2a96e7b2 65 * Also re-set the image.
f82bad11
NR
66 *
67 * @param contact
68 * the new {@link Contact}
69 */
ae22c247 70 public void setContact(Contact contact) {
ae22c247 71 this.contact = contact;
2a96e7b2 72 image = null;
ae22c247 73
2a96e7b2 74 if (contact != null) {
f82bad11
NR
75 infoPanel.removeAllComponents();
76
77 String name = contact.getPreferredDataValue("FN");
78 if (name == null || name.length() == 0) {
79 // TODO format it ourself
80 name = contact.getPreferredDataValue("N");
81 }
82
83 // TODO: i18n + do it properly
84 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NAME
85 .createLabel(name));
86
87 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
88 .createLabel(""));
89 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
90 .createLabel("Phone: "
91 + contact.getPreferredDataValue("TEL")));
92 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
93 .createLabel("eMail: "
94 + contact.getPreferredDataValue("EMAIL")));
95 infoPanel.addComponent(UiColors.Element.VIEW_CONTACT_NORMAL
96 .createLabel(""));
97
98 String notes = contact.getPreferredDataValue("NOTE");
99 if (notes == null)
100 notes = "";
101 note.setText(notes.replaceAll("\\\\n", "\n"));
102
f04d8b1c
NR
103 Data photo = contact.getPreferredData("PHOTO");
104 if (photo != null) {
105 TypeInfo encoding = null;
78e4af97
NR
106 for (int index = 0; index < photo.size(); index++) {
107 TypeInfo info = photo.get(index);
f04d8b1c
NR
108 if (info.getName() != null) {
109 if (info.getName().equalsIgnoreCase("ENCODING"))
110 encoding = info;
2a96e7b2
NR
111 // We don't check for the "TYPE" anymore, we just defer
112 // it to ImageIcon
f04d8b1c
NR
113 }
114 }
115
116 if (encoding != null && encoding.getValue() != null
117 && encoding.getValue().equalsIgnoreCase("b")) {
118
f82bad11 119 image = new ImageIcon(Base64.getDecoder().decode(
f04d8b1c 120 photo.getValue())).getImage();
f04d8b1c
NR
121 }
122 }
123 }
124
f82bad11 125 setImage(image);
f04d8b1c 126 }
25232463
NR
127
128 @Override
129 public DataType getDataType() {
130 return DataType.DATA;
131 }
132
133 @Override
134 public List<KeyAction> getKeyBindings() {
135 List<KeyAction> actions = new LinkedList<KeyAction>();
136
137 // TODO
138 actions.add(new KeyAction(Mode.NONE, KeyType.Tab,
139 Trans.StringId.KEY_ACTION_SWITCH_FORMAT) {
140 @Override
141 public boolean onAction() {
f82bad11
NR
142 if (txtImage != null) {
143 txtImage.switchMode();
25232463
NR
144 }
145
146 return false;
147 }
148 });
149 actions.add(new KeyAction(Mode.NONE, 'i',
ae22c247 150 Trans.StringId.KEY_ACTION_INVERT) {
25232463
NR
151 @Override
152 public boolean onAction() {
f82bad11
NR
153 if (txtImage != null) {
154 txtImage.invertColor();
25232463
NR
155 }
156
157 return false;
158 }
159 });
ae22c247
NR
160 actions.add(new KeyAction(Mode.NONE, 'f',
161 Trans.StringId.KEY_ACTION_FULLSCREEN) {
162 @Override
163 public boolean onAction() {
164 fullscreenImage = !fullscreenImage;
165 setImage(image);
166 return false;
167 }
168 });
25232463
NR
169
170 return actions;
171 }
ae22c247
NR
172
173 @Override
174 public synchronized Panel setSize(TerminalSize size) {
175 super.setSize(size);
176 setImage(image);
177 return this;
178 }
179
180 /**
f82bad11
NR
181 * Set the {@link Image} to render and refresh it to the current size
182 * constraints.
ae22c247
NR
183 *
184 * @param image
185 * the new {@link Image}
186 */
187 private void setImage(Image image) {
188 this.image = image;
189
f82bad11
NR
190 if (txtImage != null && top.containsComponent(txtImage))
191 top.removeComponent(txtImage);
192
ae22c247
NR
193 TerminalSize size = getTxtSize();
194 if (size != null) {
f82bad11
NR
195 if (txtImage != null)
196 txtImage.setSize(size);
ae22c247 197 else
f82bad11 198 txtImage = new ImageTextControl(image, size);
ae22c247
NR
199 }
200
f82bad11
NR
201 if (size != null) {
202 top.addComponent(txtImage, BorderLayout.Location.LEFT);
203 }
ae22c247 204
f82bad11 205 invalidate();
ae22c247
NR
206 }
207
208 /**
209 * Compute the size to use for the {@link Image} text rendering. Return NULL
210 * in case of error.
211 *
212 * @return the {@link TerminalSize} to use or NULL if it is not possible
213 */
214 private TerminalSize getTxtSize() {
215 if (image != null && getSize() != null && getSize().getColumns() > 0
216 && getSize().getRows() > 0) {
217 if (fullscreenImage) {
218 return getSize();
219 } else {
f82bad11
NR
220 // TODO: configure size?
221 int w = getSize().getColumns() - 40;
222 int h = getSize().getRows() - 5;
223 if (w <= 0 || h <= 0)
224 return null;
225
226 return new TerminalSize(w, h);
ae22c247
NR
227 }
228 }
229
230 return null;
231 }
f04d8b1c 232}