diff options
author | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-17 13:05:06 +0100 |
---|---|---|
committer | TheJackiMonster <thejackimonster@gmail.com> | 2022-03-17 13:05:06 +0100 |
commit | f52675513361ac166800d2216969ab370c845318 (patch) | |
tree | dd032d46a7189cffb7ba1dfe50fd07042c630b83 | |
parent | 5481b37fcf1a820e55719da9593216e58774da18 (diff) | |
download | messenger-gtk-f52675513361ac166800d2216969ab370c845318.tar.gz messenger-gtk-f52675513361ac166800d2216969ab370c845318.zip |
Implemented contact details dialog
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r-- | resources/ui/contact_info.ui | 46 | ||||
-rw-r--r-- | src/application.h | 4 | ||||
-rw-r--r-- | src/ui/chat.c | 46 | ||||
-rw-r--r-- | src/ui/contact_info.c | 339 | ||||
-rw-r--r-- | src/ui/contact_info.h | 17 |
5 files changed, 426 insertions, 26 deletions
diff --git a/resources/ui/contact_info.ui b/resources/ui/contact_info.ui index 8ac2e04..4f69d59 100644 --- a/resources/ui/contact_info.ui +++ b/resources/ui/contact_info.ui | |||
@@ -1,7 +1,7 @@ | |||
1 | <?xml version="1.0" encoding="UTF-8"?> | 1 | <?xml version="1.0" encoding="UTF-8"?> |
2 | <!-- Generated with glade 3.38.2 | 2 | <!-- Generated with glade 3.38.2 |
3 | 3 | ||
4 | Copyright (C) 2021‑‑2022 GNUnet e.V. | 4 | Copyright (C) 2022 GNUnet e.V. |
5 | 5 | ||
6 | GNUnet is free software: you can redistribute it and/or modify it | 6 | GNUnet is free software: you can redistribute it and/or modify it |
7 | under the terms of the GNU Affero General Public License as published | 7 | under the terms of the GNU Affero General Public License as published |
@@ -25,6 +25,7 @@ Author: Tobias Frisch | |||
25 | <requires lib="libhandy" version="1.2"/> | 25 | <requires lib="libhandy" version="1.2"/> |
26 | <object class="GtkDialog" id="contact_info_dialog"> | 26 | <object class="GtkDialog" id="contact_info_dialog"> |
27 | <property name="can-focus">False</property> | 27 | <property name="can-focus">False</property> |
28 | <property name="title" translatable="yes">Contact Information</property> | ||
28 | <property name="modal">True</property> | 29 | <property name="modal">True</property> |
29 | <property name="window-position">center-on-parent</property> | 30 | <property name="window-position">center-on-parent</property> |
30 | <property name="type-hint">dialog</property> | 31 | <property name="type-hint">dialog</property> |
@@ -40,7 +41,6 @@ Author: Tobias Frisch | |||
40 | <child> | 41 | <child> |
41 | <object class="GtkButton" id="back_button"> | 42 | <object class="GtkButton" id="back_button"> |
42 | <property name="label" translatable="yes">Back</property> | 43 | <property name="label" translatable="yes">Back</property> |
43 | <property name="visible">True</property> | ||
44 | <property name="can-focus">True</property> | 44 | <property name="can-focus">True</property> |
45 | <property name="receives-default">True</property> | 45 | <property name="receives-default">True</property> |
46 | </object> | 46 | </object> |
@@ -114,10 +114,42 @@ Author: Tobias Frisch | |||
114 | </packing> | 114 | </packing> |
115 | </child> | 115 | </child> |
116 | <child> | 116 | <child> |
117 | <object class="GtkEntry" id="contact_name"> | 117 | <object class="GtkBox"> |
118 | <property name="width-request">250</property> | ||
119 | <property name="visible">True</property> | 118 | <property name="visible">True</property> |
120 | <property name="can-focus">True</property> | 119 | <property name="can-focus">False</property> |
120 | <property name="spacing">4</property> | ||
121 | <child> | ||
122 | <object class="GtkEntry" id="contact_name"> | ||
123 | <property name="width-request">210</property> | ||
124 | <property name="visible">True</property> | ||
125 | <property name="sensitive">False</property> | ||
126 | <property name="can-focus">True</property> | ||
127 | </object> | ||
128 | <packing> | ||
129 | <property name="expand">False</property> | ||
130 | <property name="fill">True</property> | ||
131 | <property name="position">0</property> | ||
132 | </packing> | ||
133 | </child> | ||
134 | <child> | ||
135 | <object class="GtkButton" id="contact_edit_button"> | ||
136 | <property name="visible">True</property> | ||
137 | <property name="can-focus">True</property> | ||
138 | <property name="receives-default">True</property> | ||
139 | <child> | ||
140 | <object class="GtkImage" id="contact_edit_symbol"> | ||
141 | <property name="visible">True</property> | ||
142 | <property name="can-focus">False</property> | ||
143 | <property name="icon-name">document-edit-symbolic</property> | ||
144 | </object> | ||
145 | </child> | ||
146 | </object> | ||
147 | <packing> | ||
148 | <property name="expand">False</property> | ||
149 | <property name="fill">True</property> | ||
150 | <property name="position">1</property> | ||
151 | </packing> | ||
152 | </child> | ||
121 | </object> | 153 | </object> |
122 | <packing> | 154 | <packing> |
123 | <property name="expand">False</property> | 155 | <property name="expand">False</property> |
@@ -161,6 +193,10 @@ Author: Tobias Frisch | |||
161 | <property name="height-request">250</property> | 193 | <property name="height-request">250</property> |
162 | <property name="visible">True</property> | 194 | <property name="visible">True</property> |
163 | <property name="can-focus">False</property> | 195 | <property name="can-focus">False</property> |
196 | <property name="margin-start">16</property> | ||
197 | <property name="margin-end">16</property> | ||
198 | <property name="margin-top">16</property> | ||
199 | <property name="margin-bottom">16</property> | ||
164 | </object> | 200 | </object> |
165 | <packing> | 201 | <packing> |
166 | <property name="name">drawing_page</property> | 202 | <property name="name">drawing_page</property> |
diff --git a/src/application.h b/src/application.h index 8e0149b..8dc92a2 100644 --- a/src/application.h +++ b/src/application.h | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "ui/about.h" | 33 | #include "ui/about.h" |
34 | #include "ui/accounts.h" | 34 | #include "ui/accounts.h" |
35 | #include "ui/contact_info.h" | ||
35 | #include "ui/contacts.h" | 36 | #include "ui/contacts.h" |
36 | #include "ui/delete_messages.h" | 37 | #include "ui/delete_messages.h" |
37 | #include "ui/invite_contact.h" | 38 | #include "ui/invite_contact.h" |
@@ -94,9 +95,10 @@ typedef struct MESSENGER_Application | |||
94 | UI_MESSENGER_Handle messenger; | 95 | UI_MESSENGER_Handle messenger; |
95 | UI_ABOUT_Handle about; | 96 | UI_ABOUT_Handle about; |
96 | 97 | ||
98 | UI_CONTACT_INFO_Handle contact_info; | ||
99 | UI_DELETE_MESSAGES_Handle delete_messages; | ||
97 | UI_INVITE_CONTACT_Handle invite_contact; | 100 | UI_INVITE_CONTACT_Handle invite_contact; |
98 | UI_SEND_FILE_Handle send_file; | 101 | UI_SEND_FILE_Handle send_file; |
99 | UI_DELETE_MESSAGES_Handle delete_messages; | ||
100 | 102 | ||
101 | UI_NEW_CONTACT_Handle new_contact; | 103 | UI_NEW_CONTACT_Handle new_contact; |
102 | UI_NEW_GROUP_Handle new_group; | 104 | UI_NEW_GROUP_Handle new_group; |
diff --git a/src/ui/chat.c b/src/ui/chat.c index c0ea685..79603db 100644 --- a/src/ui/chat.c +++ b/src/ui/chat.c | |||
@@ -77,7 +77,8 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox, | |||
77 | GtkListBoxRow *row, | 77 | GtkListBoxRow *row, |
78 | gpointer user_data) | 78 | gpointer user_data) |
79 | { | 79 | { |
80 | MESSENGER_Application *app = (MESSENGER_Application*) user_data; | 80 | UI_CHAT_Handle *handle = (UI_CHAT_Handle*) user_data; |
81 | MESSENGER_Application *app = handle->app; | ||
81 | 82 | ||
82 | GtkTextView *text_view = GTK_TEXT_VIEW( | 83 | GtkTextView *text_view = GTK_TEXT_VIEW( |
83 | g_object_get_qdata(G_OBJECT(listbox), app->quarks.widget) | 84 | g_object_get_qdata(G_OBJECT(listbox), app->quarks.widget) |
@@ -104,19 +105,15 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox, | |||
104 | g_object_get_qdata(G_OBJECT(row), app->quarks.data) | 105 | g_object_get_qdata(G_OBJECT(row), app->quarks.data) |
105 | ); | 106 | ); |
106 | 107 | ||
107 | if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) || | 108 | if (!contact) |
108 | (GNUNET_YES == GNUNET_CHAT_contact_is_owned(contact))) | ||
109 | return; | 109 | return; |
110 | 110 | ||
111 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context( | 111 | hdy_flap_set_reveal_flap(handle->flap_chat_details, FALSE); |
112 | contact | ||
113 | ); | ||
114 | 112 | ||
115 | if (!context) | 113 | ui_contact_info_dialog_init(app, &(app->ui.contact_info)); |
116 | return; | 114 | ui_contact_info_dialog_update(&(app->ui.contact_info), contact, FALSE); |
117 | 115 | ||
118 | if (GNUNET_SYSERR == GNUNET_CHAT_context_get_status(context)) | 116 | gtk_widget_show(GTK_WIDGET(app->ui.contact_info.dialog)); |
119 | GNUNET_CHAT_context_request(context); | ||
120 | } | 117 | } |
121 | 118 | ||
122 | static void | 119 | static void |
@@ -156,12 +153,25 @@ handle_back_button_click(UNUSED GtkButton *button, | |||
156 | } | 153 | } |
157 | 154 | ||
158 | static void | 155 | static void |
159 | handle_reveal_identity_button_click(UNUSED GtkButton *button, | 156 | handle_reveal_identity_button_click(GtkButton *button, |
160 | gpointer user_data) | 157 | gpointer user_data) |
161 | { | 158 | { |
162 | UI_CHAT_Handle *handle = (UI_CHAT_Handle*) user_data; | 159 | UI_CHAT_Handle *handle = (UI_CHAT_Handle*) user_data; |
160 | MESSENGER_Application *app = handle->app; | ||
161 | |||
162 | struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( | ||
163 | g_object_get_qdata(G_OBJECT(button), app->quarks.data) | ||
164 | ); | ||
163 | 165 | ||
164 | // TODO | 166 | if (!contact) |
167 | return; | ||
168 | |||
169 | hdy_flap_set_reveal_flap(handle->flap_chat_details, FALSE); | ||
170 | |||
171 | ui_contact_info_dialog_init(app, &(app->ui.contact_info)); | ||
172 | ui_contact_info_dialog_update(&(app->ui.contact_info), contact, TRUE); | ||
173 | |||
174 | gtk_widget_show(GTK_WIDGET(app->ui.contact_info.dialog)); | ||
165 | } | 175 | } |
166 | 176 | ||
167 | static void | 177 | static void |
@@ -1197,7 +1207,7 @@ ui_chat_new(MESSENGER_Application *app) | |||
1197 | handle->chat_contacts_listbox, | 1207 | handle->chat_contacts_listbox, |
1198 | "row-activated", | 1208 | "row-activated", |
1199 | G_CALLBACK(handle_chat_contacts_listbox_row_activated), | 1209 | G_CALLBACK(handle_chat_contacts_listbox_row_activated), |
1200 | app | 1210 | handle |
1201 | ); | 1211 | ); |
1202 | 1212 | ||
1203 | handle->chat_files_listbox = GTK_LIST_BOX( | 1213 | handle->chat_files_listbox = GTK_LIST_BOX( |
@@ -1443,8 +1453,8 @@ ui_chat_update(UI_CHAT_Handle *handle, | |||
1443 | { | 1453 | { |
1444 | GNUNET_assert((handle) && (app) && (context)); | 1454 | GNUNET_assert((handle) && (app) && (context)); |
1445 | 1455 | ||
1446 | const struct GNUNET_CHAT_Contact* contact; | 1456 | struct GNUNET_CHAT_Contact* contact; |
1447 | const struct GNUNET_CHAT_Group* group; | 1457 | struct GNUNET_CHAT_Group* group; |
1448 | 1458 | ||
1449 | contact = GNUNET_CHAT_context_get_contact(context); | 1459 | contact = GNUNET_CHAT_context_get_contact(context); |
1450 | group = GNUNET_CHAT_context_get_group(context); | 1460 | group = GNUNET_CHAT_context_get_group(context); |
@@ -1524,6 +1534,12 @@ ui_chat_update(UI_CHAT_Handle *handle, | |||
1524 | group? TRUE : FALSE | 1534 | group? TRUE : FALSE |
1525 | ); | 1535 | ); |
1526 | 1536 | ||
1537 | g_object_set_qdata( | ||
1538 | G_OBJECT(handle->reveal_identity_button), | ||
1539 | app->quarks.data, | ||
1540 | contact | ||
1541 | ); | ||
1542 | |||
1527 | gtk_widget_set_visible( | 1543 | gtk_widget_set_visible( |
1528 | GTK_WIDGET(handle->reveal_identity_button), | 1544 | GTK_WIDGET(handle->reveal_identity_button), |
1529 | contact? TRUE : FALSE | 1545 | contact? TRUE : FALSE |
diff --git a/src/ui/contact_info.c b/src/ui/contact_info.c index b8e504b..9952ab6 100644 --- a/src/ui/contact_info.c +++ b/src/ui/contact_info.c | |||
@@ -24,9 +24,137 @@ | |||
24 | 24 | ||
25 | #include "contact_info.h" | 25 | #include "contact_info.h" |
26 | 26 | ||
27 | #include "chat_entry.h" | ||
27 | #include "../application.h" | 28 | #include "../application.h" |
28 | 29 | ||
29 | static void | 30 | static void |
31 | handle_contact_edit_button_click(UNUSED GtkButton *button, | ||
32 | gpointer user_data) | ||
33 | { | ||
34 | UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; | ||
35 | |||
36 | gboolean editable = gtk_widget_is_sensitive( | ||
37 | GTK_WIDGET(handle->contact_name_entry) | ||
38 | ); | ||
39 | |||
40 | struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( | ||
41 | g_object_get_qdata( | ||
42 | G_OBJECT(handle->contact_name_entry), | ||
43 | handle->app->quarks.data | ||
44 | ) | ||
45 | ); | ||
46 | |||
47 | const gchar *name = gtk_entry_get_text(handle->contact_name_entry); | ||
48 | |||
49 | if ((editable) && (contact)) | ||
50 | GNUNET_CHAT_contact_set_name( | ||
51 | contact, | ||
52 | (name) && (g_utf8_strlen(name, 1))? name : NULL | ||
53 | ); | ||
54 | |||
55 | gtk_image_set_from_icon_name( | ||
56 | handle->contact_edit_symbol, | ||
57 | editable? | ||
58 | "document-edit-symbolic" : | ||
59 | "emblem-ok-symbolic", | ||
60 | GTK_ICON_SIZE_BUTTON | ||
61 | ); | ||
62 | |||
63 | gtk_widget_set_sensitive( | ||
64 | GTK_WIDGET(handle->contact_name_entry), | ||
65 | !editable | ||
66 | ); | ||
67 | } | ||
68 | |||
69 | static void | ||
70 | handle_contact_name_entry_activate(UNUSED GtkEntry *entry, | ||
71 | gpointer user_data) | ||
72 | { | ||
73 | UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; | ||
74 | |||
75 | handle_contact_edit_button_click(handle->contact_edit_button, handle); | ||
76 | } | ||
77 | |||
78 | static void | ||
79 | _contact_info_reveal_identity(UI_CONTACT_INFO_Handle *handle) | ||
80 | { | ||
81 | gtk_widget_set_visible(GTK_WIDGET(handle->back_button), TRUE); | ||
82 | |||
83 | gtk_stack_set_visible_child( | ||
84 | handle->contact_info_stack, | ||
85 | GTK_WIDGET(handle->id_drawing_area) | ||
86 | ); | ||
87 | } | ||
88 | |||
89 | static void | ||
90 | handle_reveal_identity_button_click(UNUSED GtkButton *button, | ||
91 | gpointer user_data) | ||
92 | { | ||
93 | _contact_info_reveal_identity((UI_CONTACT_INFO_Handle*) user_data); | ||
94 | } | ||
95 | |||
96 | static void | ||
97 | handle_open_chat_button_click(UNUSED GtkButton *button, | ||
98 | gpointer user_data) | ||
99 | { | ||
100 | UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; | ||
101 | |||
102 | struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( | ||
103 | g_object_get_qdata( | ||
104 | G_OBJECT(handle->contact_name_entry), | ||
105 | handle->app->quarks.data | ||
106 | ) | ||
107 | ); | ||
108 | |||
109 | if (!contact) | ||
110 | return; | ||
111 | |||
112 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context( | ||
113 | contact | ||
114 | ); | ||
115 | |||
116 | if (!context) | ||
117 | return; | ||
118 | |||
119 | if (GNUNET_SYSERR == GNUNET_CHAT_context_get_status(context)) | ||
120 | { | ||
121 | GNUNET_CHAT_context_request(context); | ||
122 | goto close_dialog; | ||
123 | } | ||
124 | |||
125 | UI_CHAT_ENTRY_Handle *entry = GNUNET_CHAT_context_get_user_pointer(context); | ||
126 | |||
127 | if (!entry) | ||
128 | return; | ||
129 | |||
130 | GtkListBoxRow *row = GTK_LIST_BOX_ROW( | ||
131 | gtk_widget_get_parent(entry->entry_box) | ||
132 | ); | ||
133 | |||
134 | gtk_list_box_select_row(handle->app->ui.messenger.chats_listbox, row); | ||
135 | gtk_list_box_invalidate_filter(handle->app->ui.messenger.chats_listbox); | ||
136 | |||
137 | gtk_widget_activate(GTK_WIDGET(row)); | ||
138 | |||
139 | close_dialog: | ||
140 | gtk_window_close(GTK_WINDOW(handle->dialog)); | ||
141 | } | ||
142 | |||
143 | static void | ||
144 | handle_back_button_click(UNUSED GtkButton *button, | ||
145 | gpointer user_data) | ||
146 | { | ||
147 | UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; | ||
148 | |||
149 | gtk_widget_set_visible(GTK_WIDGET(handle->back_button), FALSE); | ||
150 | |||
151 | gtk_stack_set_visible_child( | ||
152 | handle->contact_info_stack, | ||
153 | handle->details_box | ||
154 | ); | ||
155 | } | ||
156 | |||
157 | static void | ||
30 | handle_close_button_click(UNUSED GtkButton *button, | 158 | handle_close_button_click(UNUSED GtkButton *button, |
31 | gpointer user_data) | 159 | gpointer user_data) |
32 | { | 160 | { |
@@ -41,10 +169,106 @@ handle_dialog_destroy(UNUSED GtkWidget *window, | |||
41 | ui_contact_info_dialog_cleanup((UI_CONTACT_INFO_Handle*) user_data); | 169 | ui_contact_info_dialog_cleanup((UI_CONTACT_INFO_Handle*) user_data); |
42 | } | 170 | } |
43 | 171 | ||
172 | static gboolean | ||
173 | handle_id_drawing_area_draw(GtkWidget* drawing_area, | ||
174 | cairo_t* cairo, | ||
175 | gpointer user_data) | ||
176 | { | ||
177 | UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; | ||
178 | |||
179 | GtkStyleContext* context = gtk_widget_get_style_context(drawing_area); | ||
180 | |||
181 | if (!context) | ||
182 | return FALSE; | ||
183 | |||
184 | const guint width = gtk_widget_get_allocated_width(drawing_area); | ||
185 | const guint height = gtk_widget_get_allocated_height(drawing_area); | ||
186 | |||
187 | gtk_render_background(context, cairo, 0, 0, width, height); | ||
188 | |||
189 | if ((!(handle->qr)) || (handle->qr->width <= 0)) | ||
190 | return FALSE; | ||
191 | |||
192 | const guint m = 3; | ||
193 | const guint w = handle->qr->width; | ||
194 | const guint w2 = w + m * 2; | ||
195 | |||
196 | guchar *pixels = (guchar*) g_malloc(sizeof(guchar) * w2 * w2 * 3); | ||
197 | |||
198 | guint x, y, z; | ||
199 | for (y = 0; y < w2; y++) | ||
200 | for (x = 0; x < w2; x++) | ||
201 | { | ||
202 | guchar value; | ||
203 | |||
204 | if ((x >= m) && (y >= m) && (x - m < w) && (y - m < w)) | ||
205 | value = ((handle->qr->data[(y - m) * w + x - m]) & 1); | ||
206 | else | ||
207 | value = 0; | ||
208 | |||
209 | for (z = 0; z < 3; z++) | ||
210 | pixels[(y * w2 + x) * 3 + z] = value? 0x00 : 0xff; | ||
211 | } | ||
212 | |||
213 | GdkPixbuf *image = gdk_pixbuf_new_from_data( | ||
214 | pixels, | ||
215 | GDK_COLORSPACE_RGB, | ||
216 | FALSE, | ||
217 | 8, | ||
218 | w2, | ||
219 | w2, | ||
220 | w2 * 3, | ||
221 | NULL, | ||
222 | NULL | ||
223 | ); | ||
224 | |||
225 | if (!image) | ||
226 | return FALSE; | ||
227 | |||
228 | int dwidth = gdk_pixbuf_get_width(image); | ||
229 | int dheight = gdk_pixbuf_get_height(image); | ||
230 | |||
231 | double ratio_width = 1.0 * width / dwidth; | ||
232 | double ratio_height = 1.0 * height / dheight; | ||
233 | |||
234 | const double ratio = ratio_width < ratio_height? ratio_width : ratio_height; | ||
235 | |||
236 | dwidth = (int) (dwidth * ratio); | ||
237 | dheight = (int) (dheight * ratio); | ||
238 | |||
239 | double dx = (width - dwidth) * 0.5; | ||
240 | double dy = (height - dheight) * 0.5; | ||
241 | |||
242 | const int interp_type = (ratio >= 1.0? | ||
243 | GDK_INTERP_NEAREST : | ||
244 | GDK_INTERP_BILINEAR | ||
245 | ); | ||
246 | |||
247 | GdkPixbuf* scaled = gdk_pixbuf_scale_simple( | ||
248 | image, | ||
249 | dwidth, | ||
250 | dheight, | ||
251 | interp_type | ||
252 | ); | ||
253 | |||
254 | gtk_render_icon(context, cairo, scaled, dx, dy); | ||
255 | |||
256 | cairo_fill(cairo); | ||
257 | |||
258 | g_object_unref(scaled); | ||
259 | g_object_unref(image); | ||
260 | |||
261 | g_free(pixels); | ||
262 | |||
263 | return FALSE; | ||
264 | } | ||
265 | |||
44 | void | 266 | void |
45 | ui_contact_info_dialog_init(MESSENGER_Application *app, | 267 | ui_contact_info_dialog_init(MESSENGER_Application *app, |
46 | UI_CONTACT_INFO_Handle *handle) | 268 | UI_CONTACT_INFO_Handle *handle) |
47 | { | 269 | { |
270 | handle->app = app; | ||
271 | |||
48 | handle->builder = gtk_builder_new_from_resource( | 272 | handle->builder = gtk_builder_new_from_resource( |
49 | application_get_resource_path(app, "ui/contact_info.ui") | 273 | application_get_resource_path(app, "ui/contact_info.ui") |
50 | ); | 274 | ); |
@@ -70,26 +294,76 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, | |||
70 | gtk_builder_get_object(handle->builder, "contact_avatar") | 294 | gtk_builder_get_object(handle->builder, "contact_avatar") |
71 | ); | 295 | ); |
72 | 296 | ||
73 | handle->contact_name = GTK_ENTRY( | 297 | handle->contact_name_entry = GTK_ENTRY( |
74 | gtk_builder_get_object(handle->builder, "contact_name") | 298 | gtk_builder_get_object(handle->builder, "contact_name") |
75 | ); | 299 | ); |
76 | 300 | ||
301 | handle->contact_edit_button = GTK_BUTTON( | ||
302 | gtk_builder_get_object(handle->builder, "contact_edit_button") | ||
303 | ); | ||
304 | |||
305 | handle->contact_edit_symbol = GTK_IMAGE( | ||
306 | gtk_builder_get_object(handle->builder, "contact_edit_symbol") | ||
307 | ); | ||
308 | |||
309 | g_signal_connect( | ||
310 | handle->contact_name_entry, | ||
311 | "activate", | ||
312 | G_CALLBACK(handle_contact_name_entry_activate), | ||
313 | handle | ||
314 | ); | ||
315 | |||
316 | g_signal_connect( | ||
317 | handle->contact_edit_button, | ||
318 | "clicked", | ||
319 | G_CALLBACK(handle_contact_edit_button_click), | ||
320 | handle | ||
321 | ); | ||
322 | |||
77 | handle->reveal_identity_button = GTK_BUTTON( | 323 | handle->reveal_identity_button = GTK_BUTTON( |
78 | gtk_builder_get_object(handle->builder, "reveal_identity_button") | 324 | gtk_builder_get_object(handle->builder, "reveal_identity_button") |
79 | ); | 325 | ); |
80 | 326 | ||
327 | g_signal_connect( | ||
328 | handle->reveal_identity_button, | ||
329 | "clicked", | ||
330 | G_CALLBACK(handle_reveal_identity_button_click), | ||
331 | handle | ||
332 | ); | ||
333 | |||
81 | handle->open_chat_button = GTK_BUTTON( | 334 | handle->open_chat_button = GTK_BUTTON( |
82 | gtk_builder_get_object(handle->builder, "open_chat_button") | 335 | gtk_builder_get_object(handle->builder, "open_chat_button") |
83 | ); | 336 | ); |
84 | 337 | ||
338 | g_signal_connect( | ||
339 | handle->open_chat_button, | ||
340 | "clicked", | ||
341 | G_CALLBACK(handle_open_chat_button_click), | ||
342 | handle | ||
343 | ); | ||
344 | |||
85 | handle->id_drawing_area = GTK_DRAWING_AREA( | 345 | handle->id_drawing_area = GTK_DRAWING_AREA( |
86 | gtk_builder_get_object(handle->builder, "id_drawing_area") | 346 | gtk_builder_get_object(handle->builder, "id_drawing_area") |
87 | ); | 347 | ); |
88 | 348 | ||
349 | handle->id_draw_signal = g_signal_connect( | ||
350 | handle->id_drawing_area, | ||
351 | "draw", | ||
352 | G_CALLBACK(handle_id_drawing_area_draw), | ||
353 | handle | ||
354 | ); | ||
355 | |||
89 | handle->back_button = GTK_BUTTON( | 356 | handle->back_button = GTK_BUTTON( |
90 | gtk_builder_get_object(handle->builder, "back_button") | 357 | gtk_builder_get_object(handle->builder, "back_button") |
91 | ); | 358 | ); |
92 | 359 | ||
360 | g_signal_connect( | ||
361 | handle->back_button, | ||
362 | "clicked", | ||
363 | G_CALLBACK(handle_back_button_click), | ||
364 | handle | ||
365 | ); | ||
366 | |||
93 | handle->close_button = GTK_BUTTON( | 367 | handle->close_button = GTK_BUTTON( |
94 | gtk_builder_get_object(handle->builder, "close_button") | 368 | gtk_builder_get_object(handle->builder, "close_button") |
95 | ); | 369 | ); |
@@ -111,15 +385,74 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, | |||
111 | 385 | ||
112 | void | 386 | void |
113 | ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, | 387 | ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, |
114 | struct GNUNET_CHAT_Contact *contact) | 388 | struct GNUNET_CHAT_Contact *contact, |
389 | gboolean reveal) | ||
115 | { | 390 | { |
116 | // TODO | 391 | const char *name = GNUNET_CHAT_contact_get_name(contact); |
392 | |||
393 | hdy_avatar_set_text(handle->contact_avatar, name? name : ""); | ||
394 | gtk_entry_set_text(handle->contact_name_entry, name? name : ""); | ||
395 | |||
396 | g_object_set_qdata( | ||
397 | G_OBJECT(handle->contact_name_entry), | ||
398 | handle->app->quarks.data, | ||
399 | contact | ||
400 | ); | ||
401 | |||
402 | const char *key = GNUNET_CHAT_contact_get_key(contact); | ||
403 | |||
404 | if (handle->qr) | ||
405 | QRcode_free(handle->qr); | ||
406 | |||
407 | if (key) | ||
408 | handle->qr = QRcode_encodeString( | ||
409 | key, | ||
410 | 0, | ||
411 | QR_ECLEVEL_L, | ||
412 | QR_MODE_8, | ||
413 | 0 | ||
414 | ); | ||
415 | else | ||
416 | handle->qr = NULL; | ||
417 | |||
418 | if (handle->id_drawing_area) | ||
419 | gtk_widget_queue_draw(GTK_WIDGET(handle->id_drawing_area)); | ||
420 | |||
421 | gtk_widget_set_sensitive( | ||
422 | GTK_WIDGET(handle->reveal_identity_button), | ||
423 | key? TRUE : FALSE | ||
424 | ); | ||
425 | |||
426 | struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context( | ||
427 | contact | ||
428 | ); | ||
429 | |||
430 | gtk_widget_set_sensitive( | ||
431 | GTK_WIDGET(handle->open_chat_button), | ||
432 | context? TRUE : FALSE | ||
433 | ); | ||
434 | |||
435 | gtk_widget_set_visible( | ||
436 | GTK_WIDGET(handle->open_chat_button), | ||
437 | GNUNET_YES != GNUNET_CHAT_contact_is_owned(contact) | ||
438 | ); | ||
439 | |||
440 | if (reveal) | ||
441 | _contact_info_reveal_identity(handle); | ||
117 | } | 442 | } |
118 | 443 | ||
119 | void | 444 | void |
120 | ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle) | 445 | ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle) |
121 | { | 446 | { |
447 | g_signal_handler_disconnect( | ||
448 | handle->id_drawing_area, | ||
449 | handle->id_draw_signal | ||
450 | ); | ||
451 | |||
122 | g_object_unref(handle->builder); | 452 | g_object_unref(handle->builder); |
123 | 453 | ||
454 | if (handle->qr) | ||
455 | QRcode_free(handle->qr); | ||
456 | |||
124 | memset(handle, 0, sizeof(*handle)); | 457 | memset(handle, 0, sizeof(*handle)); |
125 | } | 458 | } |
diff --git a/src/ui/contact_info.h b/src/ui/contact_info.h index ef44c0c..9b89f3c 100644 --- a/src/ui/contact_info.h +++ b/src/ui/contact_info.h | |||
@@ -27,8 +27,14 @@ | |||
27 | 27 | ||
28 | #include "messenger.h" | 28 | #include "messenger.h" |
29 | 29 | ||
30 | #include <cairo/cairo.h> | ||
31 | #include <gdk/gdkpixbuf.h> | ||
32 | #include <qrencode.h> | ||
33 | |||
30 | typedef struct UI_CONTACT_INFO_Handle | 34 | typedef struct UI_CONTACT_INFO_Handle |
31 | { | 35 | { |
36 | MESSENGER_Application *app; | ||
37 | |||
32 | GtkBuilder *builder; | 38 | GtkBuilder *builder; |
33 | GtkDialog *dialog; | 39 | GtkDialog *dialog; |
34 | 40 | ||
@@ -36,15 +42,21 @@ typedef struct UI_CONTACT_INFO_Handle | |||
36 | 42 | ||
37 | GtkWidget *details_box; | 43 | GtkWidget *details_box; |
38 | HdyAvatar *contact_avatar; | 44 | HdyAvatar *contact_avatar; |
39 | GtkEntry *contact_name; | 45 | GtkEntry *contact_name_entry; |
46 | |||
47 | GtkButton *contact_edit_button; | ||
48 | GtkImage *contact_edit_symbol; | ||
40 | 49 | ||
41 | GtkButton *reveal_identity_button; | 50 | GtkButton *reveal_identity_button; |
42 | GtkButton *open_chat_button; | 51 | GtkButton *open_chat_button; |
43 | 52 | ||
44 | GtkDrawingArea *id_drawing_area; | 53 | GtkDrawingArea *id_drawing_area; |
54 | gulong id_draw_signal; | ||
45 | 55 | ||
46 | GtkButton *back_button; | 56 | GtkButton *back_button; |
47 | GtkButton *close_button; | 57 | GtkButton *close_button; |
58 | |||
59 | QRcode *qr; | ||
48 | } UI_CONTACT_INFO_Handle; | 60 | } UI_CONTACT_INFO_Handle; |
49 | 61 | ||
50 | void | 62 | void |
@@ -53,7 +65,8 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, | |||
53 | 65 | ||
54 | void | 66 | void |
55 | ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, | 67 | ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, |
56 | struct GNUNET_CHAT_Contact *contact); | 68 | struct GNUNET_CHAT_Contact *contact, |
69 | gboolean reveal); | ||
57 | 70 | ||
58 | void | 71 | void |
59 | ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle); | 72 | ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle); |