aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-03-17 13:05:06 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-03-17 13:05:06 +0100
commitf52675513361ac166800d2216969ab370c845318 (patch)
treedd032d46a7189cffb7ba1dfe50fd07042c630b83
parent5481b37fcf1a820e55719da9593216e58774da18 (diff)
downloadmessenger-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.ui46
-rw-r--r--src/application.h4
-rw-r--r--src/ui/chat.c46
-rw-r--r--src/ui/contact_info.c339
-rw-r--r--src/ui/contact_info.h17
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
4Copyright (C) 2021‑‑2022 GNUnet e.V. 4Copyright (C) 2022 GNUnet e.V.
5 5
6GNUnet is free software: you can redistribute it and/or modify it 6GNUnet is free software: you can redistribute it and/or modify it
7under the terms of the GNU Affero General Public License as published 7under 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
122static void 119static void
@@ -156,12 +153,25 @@ handle_back_button_click(UNUSED GtkButton *button,
156} 153}
157 154
158static void 155static void
159handle_reveal_identity_button_click(UNUSED GtkButton *button, 156handle_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
167static void 177static 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
29static void 30static void
31handle_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
69static void
70handle_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
78static 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
89static void
90handle_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
96static void
97handle_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
139close_dialog:
140 gtk_window_close(GTK_WINDOW(handle->dialog));
141}
142
143static void
144handle_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
157static void
30handle_close_button_click(UNUSED GtkButton *button, 158handle_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
172static gboolean
173handle_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
44void 266void
45ui_contact_info_dialog_init(MESSENGER_Application *app, 267ui_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
112void 386void
113ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, 387ui_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
119void 444void
120ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle) 445ui_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
30typedef struct UI_CONTACT_INFO_Handle 34typedef 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
50void 62void
@@ -53,7 +65,8 @@ ui_contact_info_dialog_init(MESSENGER_Application *app,
53 65
54void 66void
55ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, 67ui_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
58void 71void
59ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle); 72ui_contact_info_dialog_cleanup(UI_CONTACT_INFO_Handle *handle);