1 package be
.nikiroo
.jvcard
.tui
.panes
;
4 import java
.io
.ByteArrayInputStream
;
5 import java
.util
.LinkedList
;
8 import javax
.imageio
.ImageIO
;
9 import javax
.xml
.bind
.DatatypeConverter
;
11 import be
.nikiroo
.jvcard
.Contact
;
12 import be
.nikiroo
.jvcard
.Data
;
13 import be
.nikiroo
.jvcard
.TypeInfo
;
14 import be
.nikiroo
.jvcard
.i18n
.Trans
;
15 import be
.nikiroo
.jvcard
.tui
.ImageTextControl
;
16 import be
.nikiroo
.jvcard
.tui
.KeyAction
;
17 import be
.nikiroo
.jvcard
.tui
.KeyAction
.DataType
;
18 import be
.nikiroo
.jvcard
.tui
.KeyAction
.Mode
;
19 import be
.nikiroo
.jvcard
.tui
.UiColors
;
21 import com
.googlecode
.lanterna
.TerminalSize
;
22 import com
.googlecode
.lanterna
.gui2
.BorderLayout
;
23 import com
.googlecode
.lanterna
.gui2
.Direction
;
24 import com
.googlecode
.lanterna
.gui2
.Label
;
25 import com
.googlecode
.lanterna
.gui2
.LinearLayout
;
26 import com
.googlecode
.lanterna
.gui2
.Panel
;
27 import com
.googlecode
.lanterna
.input
.KeyType
;
29 public class ContactDetails
extends MainContent
{
30 private Contact contact
;
32 private ImageTextControl txtImage
;
34 private boolean fullscreenImage
;
35 private Panel infoPanel
;
38 public ContactDetails(Contact contact
) {
39 BorderLayout blayout
= new BorderLayout();
40 setLayoutManager(blayout
);
43 blayout
= new BorderLayout();
44 top
.setLayoutManager(blayout
);
46 infoPanel
= new Panel();
47 infoPanel
.setLayoutManager(new LinearLayout(Direction
.VERTICAL
));
48 top
.addComponent(infoPanel
, BorderLayout
.Location
.CENTER
);
50 Panel notePanel
= new Panel();
51 notePanel
.setLayoutManager(new LinearLayout(Direction
.HORIZONTAL
));
53 notePanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NOTES_TITLE
54 .createLabel("Notes:"));
55 note
= UiColors
.Element
.VIEW_CONTACT_NORMAL
.createLabel("");
56 notePanel
.addComponent(note
);
60 addComponent(top
, BorderLayout
.Location
.TOP
);
61 addComponent(notePanel
, BorderLayout
.Location
.CENTER
);
65 * Change the enclosed {@link Contact} from this {@link ContactDetails}.
66 * Also re-set the image.
69 * the new {@link Contact}
71 public void setContact(Contact contact
) {
72 this.contact
= contact
;
75 if (contact
!= null) {
76 infoPanel
.removeAllComponents();
78 String name
= contact
.getPreferredDataValue("FN");
79 if (name
== null || name
.length() == 0) {
80 // TODO format it ourself
81 name
= contact
.getPreferredDataValue("N");
84 // TODO: i18n + do it properly
85 infoPanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NAME
88 infoPanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NORMAL
90 infoPanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NORMAL
91 .createLabel("Phone: "
92 + contact
.getPreferredDataValue("TEL")));
93 infoPanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NORMAL
94 .createLabel("eMail: "
95 + contact
.getPreferredDataValue("EMAIL")));
96 infoPanel
.addComponent(UiColors
.Element
.VIEW_CONTACT_NORMAL
99 String notes
= contact
.getPreferredDataValue("NOTE");
102 note
.setText(notes
.replaceAll("\\\\n", "\n"));
104 Data photo
= contact
.getPreferredData("PHOTO");
106 TypeInfo encoding
= null;
107 for (int index
= 0; index
< photo
.size(); index
++) {
108 TypeInfo info
= photo
.get(index
);
109 if (info
.getName() != null) {
110 if (info
.getName().equalsIgnoreCase("ENCODING"))
112 // We don't check for the "TYPE" anymore, we just defer
117 if (encoding
!= null && encoding
.getValue() != null
118 && encoding
.getValue().equalsIgnoreCase("b")) {
121 image
= ImageIO
.read(new ByteArrayInputStream(
122 DatatypeConverter
.parseBase64Binary(photo
125 } catch (Exception e
) {
126 System
.err
.println("Cannot parse image for contact: "
127 + contact
.getPreferredDataValue("UID"));
137 public DataType
getDataType() {
138 return DataType
.DATA
;
142 public List
<KeyAction
> getKeyBindings() {
143 List
<KeyAction
> actions
= new LinkedList
<KeyAction
>();
146 actions
.add(new KeyAction(Mode
.NONE
, KeyType
.Tab
,
147 Trans
.StringId
.KEY_ACTION_SWITCH_FORMAT
) {
149 public boolean onAction() {
150 if (txtImage
!= null) {
151 txtImage
.switchMode();
157 actions
.add(new KeyAction(Mode
.NONE
, 'i',
158 Trans
.StringId
.KEY_ACTION_INVERT
) {
160 public boolean onAction() {
161 if (txtImage
!= null) {
162 txtImage
.invertColor();
168 actions
.add(new KeyAction(Mode
.NONE
, 'f',
169 Trans
.StringId
.KEY_ACTION_FULLSCREEN
) {
171 public boolean onAction() {
172 fullscreenImage
= !fullscreenImage
;
177 // TODO: add "normal" edit and remove this one into RAW edit
178 actions
.add(new KeyAction(Mode
.CONTACT_DETAILS_RAW
, 'e',
179 Trans
.StringId
.KEY_ACTION_EDIT_CONTACT
) {
181 public Object
getObject() {
190 public synchronized Panel
setSize(TerminalSize size
) {
197 * Set the {@link Image} to render and refresh it to the current size
201 * the new {@link Image}
203 private void setImage(Image image
) {
206 if (txtImage
!= null && top
.containsComponent(txtImage
))
207 top
.removeComponent(txtImage
);
209 TerminalSize size
= getTxtSize();
211 if (txtImage
!= null)
212 txtImage
.setSize(size
);
214 txtImage
= new ImageTextControl(image
, size
);
218 top
.addComponent(txtImage
, BorderLayout
.Location
.LEFT
);
225 * Compute the size to use for the {@link Image} text rendering. Return NULL
228 * @return the {@link TerminalSize} to use or NULL if it is not possible
230 private TerminalSize
getTxtSize() {
231 if (image
!= null && getSize() != null && getSize().getColumns() > 0
232 && getSize().getRows() > 0) {
233 if (fullscreenImage
) {
236 // TODO: configure size?
237 int w
= getSize().getColumns() - 40;
238 int h
= getSize().getRows() - 5;
239 if (w
<= 0 || h
<= 0)
242 return new TerminalSize(w
, h
);