commit 3090047dcd647bd1daddf904472a7f909b00f875
parent 43e1bdf4a87b0e6979aa75f36a920e21028c4f74
Author: TheJackiMonster <thejackimonster@gmail.com>
Date: Sat, 19 Feb 2022 21:31:03 +0100
Refactored setting ui content and binding widgets
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
Diffstat:
28 files changed, 561 insertions(+), 347 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,6 +8,7 @@ INSTALL_DIR ?= /usr/local/
BINARY = messenger-gtk
SOURCES = messenger_gtk.c\
application.c\
+ bindings.c\
contact.c\
event.c\
file.c\
diff --git a/resources/ui/accounts.ui b/resources/ui/accounts.ui
@@ -72,6 +72,7 @@ Author: Tobias Frisch
<object class="GtkListBox" id="accounts_listbox">
<property name="visible">True</property>
<property name="can-focus">False</property>
+ <property name="selection-mode">none</property>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
diff --git a/src/application.c b/src/application.c
@@ -100,7 +100,7 @@ application_init(MESSENGER_Application *app,
pthread_mutex_init(&(app->chat.mutex), NULL);
- app->ui.bindings = g_hash_table_new(g_direct_hash, g_direct_equal);
+ app->bindings = bindings_create();
g_application_add_main_option(
G_APPLICATION(app->application),
@@ -195,7 +195,7 @@ application_run(MESSENGER_Application *app)
pthread_join(app->chat.tid, NULL);
- g_hash_table_destroy(app->ui.bindings);
+ bindings_destroy(app->bindings);
close(app->chat.pipe[0]);
close(app->chat.pipe[1]);
diff --git a/src/application.h b/src/application.h
@@ -42,6 +42,7 @@
#include "ui/send_file.h"
#include "ui/settings.h"
+#include "bindings.h"
#include "util.h"
typedef enum MESSENGER_ApplicationSignal
@@ -59,6 +60,8 @@ typedef struct MESSENGER_Application
GtkApplication *application;
GList *notifications;
+ MESSENGER_Bindings *bindings;
+
struct {
int status;
pthread_t tid;
@@ -73,8 +76,6 @@ typedef struct MESSENGER_Application
struct {
int status;
- GHashTable *bindings;
-
UI_MESSENGER_Handle messenger;
UI_INVITE_CONTACT_Handle invite_contact;
diff --git a/src/bindings.c b/src/bindings.c
@@ -0,0 +1,129 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2022 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file bindings.h
+ */
+
+#include "bindings.h"
+#include "util.h"
+
+MESSENGER_Bindings*
+bindings_create()
+{
+ MESSENGER_Bindings *bindings = GNUNET_new(MESSENGER_Bindings);
+
+ bindings->map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
+
+ return bindings;
+}
+
+void
+bindings_put(MESSENGER_Bindings *bindings,
+ gconstpointer key,
+ gpointer value)
+{
+ struct GNUNET_ShortHashCode hash;
+ memset(&hash, 0, sizeof(hash));
+ memcpy(&hash, &key, sizeof(key));
+
+ GNUNET_CONTAINER_multishortmap_put(
+ bindings->map,
+ &hash,
+ (void*) value,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
+ );
+}
+
+int
+_bindings_append_list(void *cls,
+ UNUSED const struct GNUNET_ShortHashCode *key,
+ void *value)
+{
+ GList **list = (GList**) cls;
+ *list = g_list_append(*list, (gpointer) value);
+ return GNUNET_YES;
+}
+
+void
+bindings_remove(MESSENGER_Bindings *bindings,
+ const void *key,
+ void *value,
+ void (destroy)(void*))
+{
+ struct GNUNET_ShortHashCode hash;
+ memset(&hash, 0, sizeof(hash));
+ memcpy(&hash, &key, sizeof(key));
+
+ if (value)
+ {
+ GNUNET_CONTAINER_multishortmap_remove(
+ bindings->map,
+ &hash,
+ (void*) value
+ );
+
+ if (destroy)
+ destroy(value);
+ }
+ else
+ {
+ GList *values = NULL;
+
+ GNUNET_CONTAINER_multishortmap_get_multiple(
+ bindings->map,
+ &hash,
+ _bindings_append_list,
+ &values
+ );
+
+ GNUNET_CONTAINER_multishortmap_remove_all(
+ bindings->map,
+ &hash
+ );
+
+ if (destroy)
+ g_list_free_full(values, destroy);
+ else
+ g_list_free(values);
+ }
+}
+
+void*
+bindings_get(const MESSENGER_Bindings *bindings,
+ const void *key)
+{
+ struct GNUNET_ShortHashCode hash;
+ memset(&hash, 0, sizeof(hash));
+ memcpy(&hash, &key, sizeof(key));
+
+ return GNUNET_CONTAINER_multishortmap_get(
+ bindings->map,
+ &hash
+ );
+}
+
+void
+bindings_destroy(MESSENGER_Bindings *bindings)
+{
+ GNUNET_CONTAINER_multishortmap_destroy(bindings->map);
+
+ GNUNET_free(bindings);
+}
diff --git a/src/bindings.h b/src/bindings.h
@@ -0,0 +1,60 @@
+/*
+ This file is part of GNUnet.
+ Copyright (C) 2022 GNUnet e.V.
+
+ GNUnet is free software: you can redistribute it and/or modify it
+ under the terms of the GNU Affero General Public License as published
+ by the Free Software Foundation, either version 3 of the License,
+ or (at your option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+ SPDX-License-Identifier: AGPL3.0-or-later
+ */
+/*
+ * @author Tobias Frisch
+ * @file bindings.h
+ */
+
+#ifndef BINDINGS_H_
+#define BINDINGS_H_
+
+#include <gnunet/platform.h>
+#include <gnunet/gnunet_common.h>
+#include <gnunet/gnunet_container_lib.h>
+
+#include <glib.h>
+
+typedef struct MESSENGER_Bindings
+{
+ struct GNUNET_CONTAINER_MultiShortmap *map;
+} MESSENGER_Bindings;
+
+MESSENGER_Bindings*
+bindings_create();
+
+void
+bindings_put(MESSENGER_Bindings *bindings,
+ gconstpointer key,
+ gpointer value);
+
+void
+bindings_remove(MESSENGER_Bindings *bindings,
+ gconstpointer key,
+ gpointer value,
+ GDestroyNotify destroy);
+
+void*
+bindings_get(const MESSENGER_Bindings *bindings,
+ gconstpointer key);
+
+void
+bindings_destroy(MESSENGER_Bindings *bindings);
+
+#endif /* BINDINGS_H_ */
diff --git a/src/event.c b/src/event.c
@@ -93,57 +93,11 @@ _clear_each_selectable_widget(GtkWidget *widget,
gtk_container_remove(container, widget);
}
-static int
-_iterate_accounts(void *cls,
- const struct GNUNET_CHAT_Handle *handle,
- struct GNUNET_CHAT_Account *account)
-{
- MESSENGER_Application *app = (MESSENGER_Application*) cls;
- UI_MESSENGER_Handle *ui = &(app->ui.messenger);
-
- const gchar *name = GNUNET_CHAT_account_get_name(account);
-
- UI_ACCOUNT_ENTRY_Handle *entry = ui_account_entry_new(app);
-
- hdy_avatar_set_text(entry->entry_avatar, name);
- gtk_label_set_text(entry->entry_label, name);
-
- gtk_list_box_prepend(ui->accounts_listbox, entry->entry_box);
-
- GtkListBoxRow *row = GTK_LIST_BOX_ROW(
- gtk_widget_get_parent(entry->entry_box)
- );
-
- g_hash_table_insert(ui->bindings, row, account);
-
- if ((account == GNUNET_CHAT_get_connected(handle)) ||
- ((app->chat.identity) && (0 == g_strcmp0(app->chat.identity, name))))
- gtk_widget_activate(GTK_WIDGET(row));
-
- ui_account_entry_delete(entry);
- return GNUNET_YES;
-}
-
void
event_refresh_accounts(MESSENGER_Application *app)
{
- UI_MESSENGER_Handle *ui = &(app->ui.messenger);
- CHAT_MESSENGER_Handle *chat = &(app->chat.messenger);
-
ui_accounts_dialog_refresh(app, &(app->ui.accounts));
-
- if (!(ui->accounts_listbox))
- return;
-
- gtk_list_box_unselect_all(ui->accounts_listbox);
-
- gtk_container_foreach(
- GTK_CONTAINER(ui->accounts_listbox),
- _clear_each_selectable_widget,
- ui->accounts_listbox
- );
-
- GNUNET_CHAT_iterate_accounts(chat->handle, _iterate_accounts, app);
+ ui_messenger_refresh(app, &(app->ui.messenger));
}
static void
@@ -163,11 +117,7 @@ _add_new_chat_entry(MESSENGER_Application *app,
entry->chat->chat_box
);
- g_hash_table_insert(
- app->ui.bindings,
- entry->chat->send_text_view,
- context
- );
+ bindings_put(app->bindings, entry->chat->send_text_view, context);
ui->chat_entries = g_list_append(ui->chat_entries, entry);
@@ -175,11 +125,7 @@ _add_new_chat_entry(MESSENGER_Application *app,
gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(
- app->ui.bindings,
- row,
- entry
- );
+ bindings_put(app->bindings, row, entry);
gtk_list_box_select_row(ui->chats_listbox, row);
gtk_list_box_invalidate_filter(ui->chats_listbox);
@@ -298,13 +244,23 @@ event_joining_contact(MESSENGER_Application *app,
if (!handle)
return;
- UI_MESSAGE_Handle *message = ui_message_new(app, UI_MESSAGE_STATUS);
- ui_message_update(message, app, msg);
-
struct GNUNET_CHAT_Contact *contact = GNUNET_CHAT_message_get_sender(
msg
);
+ if (!contact)
+ return;
+
+ UI_MESSAGE_Handle *message = (UI_MESSAGE_Handle*) (
+ bindings_get(handle->joining, contact)
+ );
+
+ if (message)
+ ui_chat_remove_message(handle->chat, app, message);
+
+ message = ui_message_new(app, UI_MESSAGE_STATUS);
+ ui_message_update(message, app, msg);
+
contact_create_info(contact);
_update_contact_context(app, contact);
@@ -332,6 +288,8 @@ event_joining_contact(MESSENGER_Application *app,
gtk_label_set_text(message->timestamp_label, time? time : "");
ui_chat_add_message(handle->chat, app, message);
+ bindings_put(handle->joining, contact, message);
+
ui_chat_entry_update(handle, app, context);
}
@@ -344,6 +302,9 @@ event_update_contacts(MESSENGER_Application *app,
msg
);
+ if (!contact)
+ return;
+
contact_update_info(contact);
_update_contact_context(app, contact);
diff --git a/src/ui/account_entry.c b/src/ui/account_entry.c
@@ -51,6 +51,32 @@ ui_account_entry_new(MESSENGER_Application *app)
}
void
+ui_account_entry_set_account(UI_ACCOUNT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Account *account)
+{
+ const gchar *name = GNUNET_CHAT_account_get_name(account);
+
+ if (!name)
+ return;
+
+ hdy_avatar_set_text(handle->entry_avatar, name);
+ gtk_label_set_text(handle->entry_label, name);
+}
+
+void
+ui_account_entry_set_contact(UI_ACCOUNT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact)
+{
+ const gchar *name = GNUNET_CHAT_contact_get_name(contact);
+
+ if (!name)
+ return;
+
+ hdy_avatar_set_text(handle->entry_avatar, name);
+ gtk_label_set_text(handle->entry_label, name);
+}
+
+void
ui_account_entry_delete(UI_ACCOUNT_ENTRY_Handle *handle)
{
g_object_unref(handle->builder);
diff --git a/src/ui/account_entry.h b/src/ui/account_entry.h
@@ -41,6 +41,14 @@ UI_ACCOUNT_ENTRY_Handle*
ui_account_entry_new(MESSENGER_Application *app);
void
+ui_account_entry_set_account(UI_ACCOUNT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Account *account);
+
+void
+ui_account_entry_set_contact(UI_ACCOUNT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact);
+
+void
ui_account_entry_delete(UI_ACCOUNT_ENTRY_Handle *handle);
#endif /* UI_ACCOUNT_ENTRY_H_ */
diff --git a/src/ui/accounts.c b/src/ui/accounts.c
@@ -72,7 +72,7 @@ handle_accounts_listbox_row_activated(UNUSED GtkListBox* listbox,
}
struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) (
- g_hash_table_lookup(app->ui.bindings, row)
+ bindings_get(app->bindings, row)
);
if (!account)
@@ -109,25 +109,18 @@ _iterate_accounts(void *cls,
{
MESSENGER_Application *app = (MESSENGER_Application*) cls;
- const gchar *name = GNUNET_CHAT_account_get_name(account);
-
UI_ACCOUNT_ENTRY_Handle *entry = ui_account_entry_new(app);
- hdy_avatar_set_text(entry->entry_avatar, name);
- gtk_label_set_text(entry->entry_label, name);
+ ui_account_entry_set_account(entry, account);
gtk_list_box_prepend(app->ui.accounts.accounts_listbox, entry->entry_box);
GtkListBoxRow *row = GTK_LIST_BOX_ROW(
- gtk_widget_get_parent(entry->entry_box)
+ gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(app->ui.bindings, row, account);
-
- app->ui.accounts.account_entries = g_list_append(
- app->ui.accounts.account_entries,
- entry
- );
+ bindings_put(app->bindings, row, account);
+ bindings_put(app->ui.accounts.bindings, row, entry);
return GNUNET_YES;
}
@@ -136,8 +129,7 @@ void
ui_accounts_dialog_init(MESSENGER_Application *app,
UI_ACCOUNTS_Handle *handle)
{
- handle->account_entries = NULL;
- handle->bindings = app->ui.bindings;
+ handle->bindings = bindings_create();
handle->show_queued = 0;
handle->builder = gtk_builder_new_from_resource(
@@ -198,35 +190,22 @@ _clear_accounts_listbox_rows(UI_ACCOUNTS_Handle *handle,
if ((!row) || (!gtk_list_box_row_get_selectable(row)))
goto skip_row;
- g_hash_table_remove(handle->bindings, row);
-
if (!bindings_only)
gtk_container_remove(
GTK_CONTAINER(handle->accounts_listbox),
GTK_WIDGET(row)
);
- skip_row:
- list = list->next;
- }
-}
-
-static void
-_clear_accounts_entries(UI_ACCOUNTS_Handle *handle)
-{
- GList *list = handle->account_entries;
-
- while (list) {
- if (list->data)
- ui_account_entry_delete((UI_ACCOUNT_ENTRY_Handle*) list->data);
+ bindings_remove(
+ handle->bindings,
+ row,
+ NULL,
+ (GDestroyNotify) ui_account_entry_delete
+ );
+ skip_row:
list = list->next;
}
-
- if (handle->account_entries)
- g_list_free(handle->account_entries);
-
- handle->account_entries = NULL;
}
void
@@ -236,20 +215,13 @@ ui_accounts_dialog_refresh(MESSENGER_Application *app,
if (!(handle->accounts_listbox))
return;
- if (!(handle->account_entries))
- goto add_account_entries;
-
_clear_accounts_listbox_rows(handle, FALSE);
- _clear_accounts_entries(handle);
-add_account_entries:
GNUNET_CHAT_iterate_accounts(
app->chat.messenger.handle,
_iterate_accounts,
app
);
-
- gtk_list_box_unselect_all(handle->accounts_listbox);
}
void
@@ -259,7 +231,8 @@ ui_accounts_dialog_cleanup(UI_ACCOUNTS_Handle *handle)
g_object_unref(handle->builder);
- _clear_accounts_entries(handle);
+ bindings_destroy(handle->bindings);
+ handle->bindings = NULL;
handle->accounts_listbox = NULL;
}
diff --git a/src/ui/accounts.h b/src/ui/accounts.h
@@ -26,11 +26,11 @@
#define UI_ACCOUNTS_H_
#include "messenger.h"
+#include "../bindings.h"
typedef struct UI_ACCOUNTS_Handle
{
- GList *account_entries;
- GHashTable *bindings;
+ MESSENGER_Bindings *bindings;
guint show_queued;
GtkBuilder *builder;
diff --git a/src/ui/chat.c b/src/ui/chat.c
@@ -76,7 +76,7 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
GtkTextView *text_view = GTK_TEXT_VIEW(
- g_hash_table_lookup(app->ui.bindings, listbox)
+ bindings_get(app->bindings, listbox)
);
if (!text_view)
@@ -86,18 +86,14 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox,
{
ui_invite_contact_dialog_init(app, &(app->ui.invite_contact));
- g_hash_table_insert(
- app->ui.bindings,
- app->ui.invite_contact.contacts_listbox,
- text_view
- );
+ bindings_put(app->bindings, app->ui.invite_contact.contacts_listbox, text_view);
gtk_widget_show(GTK_WIDGET(app->ui.invite_contact.dialog));
return;
}
struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
- g_hash_table_lookup(app->ui.bindings, row)
+ bindings_get(app->bindings, row)
);
if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -159,11 +155,11 @@ handle_chat_messages_sort(GtkListBoxRow* row0,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
UI_MESSAGE_Handle *message0 = (UI_MESSAGE_Handle*) (
- g_hash_table_lookup(app->ui.bindings, row0)
+ bindings_get(app->bindings, row0)
);
UI_MESSAGE_Handle *message1 = (UI_MESSAGE_Handle*) (
- g_hash_table_lookup(app->ui.bindings, row1)
+ bindings_get(app->bindings, row1)
);
if ((!message0) || (!message1))
@@ -216,7 +212,7 @@ handle_chat_selection_close_button_click(UNUSED GtkButton *button,
}
void
-_delete_messages_callback(GHashTable *bindings,
+_delete_messages_callback(MESSENGER_Application *app,
GList *selected,
gulong delay)
{
@@ -229,7 +225,7 @@ _delete_messages_callback(GHashTable *bindings,
if (!row)
goto skip_row;
- message = g_hash_table_lookup(bindings, row);
+ message = bindings_get(app->bindings, row);
if ((!message) || (!(message->msg)))
goto skip_row;
@@ -258,7 +254,7 @@ handle_chat_selection_delete_button_click(UNUSED GtkButton *button,
GList *selected = gtk_list_box_get_selected_rows(handle->messages_listbox);
if (app->settings.hide_delete_dialog)
- _delete_messages_callback(app->ui.bindings, selected, 0);
+ _delete_messages_callback(app, selected, 0);
else
{
ui_delete_messages_dialog_init(app, &(app->ui.delete_messages));
@@ -280,7 +276,7 @@ handle_attach_file_button_click(GtkButton *button,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
GtkTextView *text_view = GTK_TEXT_VIEW(
- g_hash_table_lookup(app->ui.bindings, button)
+ bindings_get(app->bindings, button)
);
if (!text_view)
@@ -312,11 +308,7 @@ handle_attach_file_button_click(GtkButton *button,
g_free(filename);
- g_hash_table_insert(
- app->ui.bindings,
- app->ui.send_file.send_button,
- text_view
- );
+ bindings_put(app->bindings, app->ui.send_file.send_button, text_view);
gtk_widget_show(GTK_WIDGET(app->ui.send_file.dialog));
@@ -360,8 +352,8 @@ _send_text_from_view(MESSENGER_Application *app,
if (0 == strlen(text))
return FALSE;
- struct GNUNET_CHAT_Context *context = g_hash_table_lookup(
- app->ui.bindings, text_view
+ struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
+ bindings_get(app->bindings, text_view)
);
if (context)
@@ -378,7 +370,7 @@ handle_send_record_button_click(GtkButton *button,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
GtkTextView *text_view = GTK_TEXT_VIEW(
- g_hash_table_lookup(app->ui.bindings, button)
+ bindings_get(app->bindings, button)
);
if (!_send_text_from_view(app, text_view))
@@ -654,23 +646,9 @@ ui_chat_new(MESSENGER_Application *app)
app
);
- g_hash_table_insert(
- app->ui.bindings,
- handle->chat_contacts_listbox,
- handle->send_text_view
- );
-
- g_hash_table_insert(
- app->ui.bindings,
- handle->attach_file_button,
- handle->send_text_view
- );
-
- g_hash_table_insert(
- app->ui.bindings,
- handle->send_record_button,
- handle->send_text_view
- );
+ bindings_put(app->bindings, handle->chat_contacts_listbox, handle->send_text_view);
+ bindings_put(app->bindings, handle->attach_file_button, handle->send_text_view);
+ bindings_put(app->bindings, handle->send_record_button, handle->send_text_view);
handle->picker_revealer = GTK_REVEALER(
gtk_builder_get_object(handle->builder, "picker_revealer")
@@ -695,7 +673,6 @@ ui_chat_new(MESSENGER_Application *app)
struct IterateChatGroupClosure {
MESSENGER_Application *app;
- GHashTable *bindings;
GtkListBox *listbox;
};
@@ -711,10 +688,7 @@ iterate_ui_chat_update_group_contacts(void *cls,
GtkListBox *listbox = closure->listbox;
UI_ACCOUNT_ENTRY_Handle* entry = ui_account_entry_new(closure->app);
- const char *name = GNUNET_CHAT_contact_get_name(contact);
-
- gtk_label_set_text(entry->entry_label, name? name : "");
- hdy_avatar_set_text(entry->entry_avatar, name? name : "");
+ ui_account_entry_set_contact(entry, contact);
gtk_list_box_prepend(listbox, entry->entry_box);
@@ -722,7 +696,7 @@ iterate_ui_chat_update_group_contacts(void *cls,
gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(closure->bindings, row, contact);
+ bindings_put(closure->app->bindings, row, contact);
ui_account_entry_delete(entry);
return GNUNET_YES;
@@ -776,8 +750,7 @@ ui_chat_update(UI_CHAT_Handle *handle,
GtkWidget *widget = GTK_WIDGET(children->data);
children = children->next;
- if (g_hash_table_contains(app->ui.bindings, widget))
- g_hash_table_remove(app->ui.bindings, widget);
+ bindings_remove(app->bindings, widget, NULL, NULL);
gtk_container_remove(
GTK_CONTAINER(handle->chat_contacts_listbox),
@@ -789,7 +762,6 @@ ui_chat_update(UI_CHAT_Handle *handle,
{
struct IterateChatGroupClosure closure;
closure.app = app;
- closure.bindings = app->ui.bindings;
closure.listbox = handle->chat_contacts_listbox;
GNUNET_CHAT_group_iterate_contacts(
@@ -845,29 +817,11 @@ ui_chat_delete(UI_CHAT_Handle *handle)
g_object_unref(handle->builder);
- GList *list = handle->messages;
-
- while (list) {
- if (list->data)
- ui_message_delete((UI_MESSAGE_Handle*) list->data);
-
- list = list->next;
- }
-
- list = handle->loads;
-
- while (list) {
- if (list->data)
- ui_file_load_entry_delete((UI_FILE_LOAD_ENTRY_Handle*) list->data);
-
- list = list->next;
- }
-
if (handle->messages)
- g_list_free(handle->messages);
+ g_list_free_full(handle->messages, (GDestroyNotify) ui_message_delete);
if (handle->loads)
- g_list_free(handle->loads);
+ g_list_free_full(handle->loads, (GDestroyNotify) ui_file_load_entry_delete);
g_free(handle);
}
@@ -886,7 +840,7 @@ ui_chat_add_message(UI_CHAT_Handle *handle,
GtkWidget *row = gtk_widget_get_parent(message->message_box);
- g_hash_table_insert(app->ui.bindings, row, message);
+ bindings_put(app->bindings, row, message);
handle->messages = g_list_prepend(handle->messages, message);
@@ -904,12 +858,14 @@ ui_chat_remove_message(UI_CHAT_Handle *handle,
GtkWidget *row = gtk_widget_get_parent(message->message_box);
- g_hash_table_remove(app->ui.bindings, row);
+ bindings_remove(app->bindings, row, NULL, NULL);
gtk_container_remove(
GTK_CONTAINER(handle->messages_listbox),
gtk_widget_get_parent(GTK_WIDGET(message->message_box))
);
+
+ handle->messages = g_list_append(handle->messages, message);
}
void
diff --git a/src/ui/chat_entry.c b/src/ui/chat_entry.c
@@ -34,6 +34,8 @@ ui_chat_entry_new(MESSENGER_Application *app)
{
UI_CHAT_ENTRY_Handle* handle = g_malloc(sizeof(UI_CHAT_ENTRY_Handle));
+ handle->joining = bindings_create();
+
handle->chat = ui_chat_new(app);
handle->builder = gtk_builder_new_from_resource(
application_get_resource_path(app, "ui/chat_entry.ui")
@@ -153,5 +155,7 @@ ui_chat_entry_delete(UI_CHAT_ENTRY_Handle *handle)
g_object_unref(handle->builder);
+ bindings_destroy(handle->joining);
+
g_free(handle);
}
diff --git a/src/ui/chat_entry.h b/src/ui/chat_entry.h
@@ -26,9 +26,12 @@
#define UI_CHAT_ENTRY_H_
#include "chat.h"
+#include "../bindings.h"
typedef struct UI_CHAT_ENTRY_Handle
{
+ MESSENGER_Bindings *joining;
+
UI_CHAT_Handle *chat;
GtkBuilder *builder;
diff --git a/src/ui/contact_entry.c b/src/ui/contact_entry.c
@@ -55,6 +55,31 @@ ui_contact_entry_new(MESSENGER_Application *app)
}
void
+ui_contact_entry_set_contact(UI_CONTACT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact)
+{
+
+ const gchar *name;
+ const gchar *key;
+
+ name = GNUNET_CHAT_contact_get_name(contact);
+
+ if (!name)
+ goto skip_name;
+
+ hdy_avatar_set_text(handle->entry_avatar, name);
+ gtk_label_set_text(handle->title_label, name);
+
+skip_name:
+ key = GNUNET_CHAT_contact_get_key(contact);
+
+ if (!key)
+ return;
+
+ gtk_label_set_text(handle->subtitle_label, name);
+}
+
+void
ui_contact_entry_delete(UI_CONTACT_ENTRY_Handle *handle)
{
g_object_unref(handle->builder);
diff --git a/src/ui/contact_entry.h b/src/ui/contact_entry.h
@@ -43,6 +43,10 @@ UI_CONTACT_ENTRY_Handle*
ui_contact_entry_new(MESSENGER_Application *app);
void
+ui_contact_entry_set_contact(UI_CONTACT_ENTRY_Handle* handle,
+ const struct GNUNET_CHAT_Contact *contact);
+
+void
ui_contact_entry_delete(UI_CONTACT_ENTRY_Handle *handle);
#endif /* UI_CONTACT_ENTRY_H_ */
diff --git a/src/ui/contacts.c b/src/ui/contacts.c
@@ -61,7 +61,7 @@ handle_contacts_listbox_row_activated(UNUSED GtkListBox* listbox,
}
struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
- g_hash_table_lookup(app->ui.bindings, row)
+ bindings_get(app->bindings, row)
);
if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -88,7 +88,7 @@ handle_contacts_listbox_filter_func(GtkListBoxRow *row,
{
UI_CONTACTS_Handle *handle = (UI_CONTACTS_Handle*) user_data;
- if (!gtk_list_box_row_get_selectable(row))
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)))
return TRUE;
const gchar *filter = gtk_entry_get_text(
@@ -98,14 +98,14 @@ handle_contacts_listbox_filter_func(GtkListBoxRow *row,
if (!filter)
return TRUE;
- struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
- g_hash_table_lookup(handle->bindings, row)
+ UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) (
+ bindings_get(handle->bindings, row)
);
- if (!contact)
+ if (!entry)
return FALSE;
- const gchar *name = GNUNET_CHAT_contact_get_name(contact);
+ const gchar *name = gtk_label_get_text(entry->title_label);
if (!name)
return FALSE;
@@ -139,36 +139,20 @@ _iterate_contacts(void *cls,
MESSENGER_Application *app = (MESSENGER_Application*) cls;
- const char *title;
- title = GNUNET_CHAT_contact_get_name(contact);
-
- const char *key = GNUNET_CHAT_contact_get_key(contact);
-
UI_CONTACT_ENTRY_Handle *entry = ui_contact_entry_new(app);
+ ui_contact_entry_set_contact(entry, contact);
+
gtk_list_box_prepend(
app->ui.contacts.contacts_listbox,
entry->entry_box
);
- if (title)
- {
- gtk_label_set_text(entry->title_label, title);
- hdy_avatar_set_text(entry->entry_avatar, title);
- }
-
- if (key)
- gtk_label_set_text(entry->subtitle_label, key);
-
GtkListBoxRow *row = GTK_LIST_BOX_ROW(
gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(app->ui.bindings, row, contact);
-
- app->ui.contacts.contact_entries = g_list_append(
- app->ui.contacts.contact_entries,
- entry
- );
+ bindings_put(app->bindings, row, contact);
+ bindings_put(app->ui.contacts.bindings, row, entry);
return GNUNET_YES;
}
@@ -177,8 +161,7 @@ void
ui_contacts_dialog_init(MESSENGER_Application *app,
UI_CONTACTS_Handle *handle)
{
- handle->contact_entries = NULL;
- handle->bindings = app->ui.bindings;
+ handle->bindings = bindings_create();
handle->builder = gtk_builder_new_from_resource(
application_get_resource_path(app, "ui/contacts.ui")
@@ -249,8 +232,9 @@ ui_contacts_dialog_init(MESSENGER_Application *app,
gtk_list_box_invalidate_filter(handle->contacts_listbox);
}
-void
-ui_contacts_dialog_cleanup(UI_CONTACTS_Handle *handle)
+static void
+_clear_contacts_listbox_rows(UI_CONTACTS_Handle *handle,
+ gboolean bindings_only)
{
GList *list = gtk_container_get_children(
GTK_CONTAINER(handle->contacts_listbox)
@@ -258,23 +242,38 @@ ui_contacts_dialog_cleanup(UI_CONTACTS_Handle *handle)
while (list)
{
- if (list->data)
- g_hash_table_remove(handle->bindings, list->data);
+ GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
- list = list->next;
- }
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)))
+ goto skip_row;
- g_object_unref(handle->builder);
+ if (!bindings_only)
+ gtk_container_remove(
+ GTK_CONTAINER(handle->contacts_listbox),
+ GTK_WIDGET(row)
+ );
- list = handle->contact_entries;
-
- while (list) {
- if (list->data)
- ui_contact_entry_delete((UI_CONTACT_ENTRY_Handle*) list->data);
+ bindings_remove(
+ handle->bindings,
+ row,
+ NULL,
+ (GDestroyNotify) ui_contact_entry_delete
+ );
+ skip_row:
list = list->next;
}
+}
+
+void
+ui_contacts_dialog_cleanup(UI_CONTACTS_Handle *handle)
+{
+ _clear_contacts_listbox_rows(handle, TRUE);
+
+ g_object_unref(handle->builder);
+
+ bindings_destroy(handle->bindings);
+ handle->bindings = NULL;
- if (handle->contact_entries)
- g_list_free(handle->contact_entries);
+ handle->contacts_listbox = NULL;
}
diff --git a/src/ui/contacts.h b/src/ui/contacts.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021 GNUnet e.V.
+ Copyright (C) 2021--2022 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -26,11 +26,11 @@
#define UI_CONTACTS_H_
#include "messenger.h"
+#include "../bindings.h"
typedef struct UI_CONTACTS_Handle
{
- GList *contact_entries;
- GHashTable *bindings;
+ MESSENGER_Bindings *bindings;
GtkBuilder *builder;
GtkDialog *dialog;
diff --git a/src/ui/delete_messages.c b/src/ui/delete_messages.c
@@ -57,7 +57,7 @@ handle_confirm_button_click(UNUSED GtkButton *button,
if (app->ui.delete_messages.callback)
app->ui.delete_messages.callback(
- app->ui.bindings,
+ app,
app->ui.delete_messages.selected,
delay
);
diff --git a/src/ui/delete_messages.h b/src/ui/delete_messages.h
@@ -28,7 +28,7 @@
#include "messenger.h"
typedef void
-(*UI_DELETE_MESSAGES_Callback) (GHashTable *bindings,
+(*UI_DELETE_MESSAGES_Callback) (MESSENGER_Application *app,
GList *selected,
gulong delay);
diff --git a/src/ui/invite_contact.c b/src/ui/invite_contact.c
@@ -44,11 +44,11 @@ handle_contacts_listbox_row_activated(GtkListBox* listbox,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
GtkTextView *text_view = GTK_TEXT_VIEW(
- g_hash_table_lookup(app->ui.bindings, listbox)
+ bindings_get(app->bindings, listbox)
);
struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
- g_hash_table_lookup(app->ui.bindings, row)
+ bindings_get(app->bindings, row)
);
if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -56,8 +56,8 @@ handle_contacts_listbox_row_activated(GtkListBox* listbox,
(!text_view))
goto close_dialog;
- struct GNUNET_CHAT_Context *context = g_hash_table_lookup(
- app->ui.bindings, text_view
+ struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
+ bindings_get(app->bindings, text_view)
);
if (!context)
@@ -78,9 +78,9 @@ static gboolean
handle_contacts_listbox_filter_func(GtkListBoxRow *row,
gpointer user_data)
{
- UI_CONTACTS_Handle *handle = (UI_CONTACTS_Handle*) user_data;
+ UI_INVITE_CONTACT_Handle *handle = (UI_INVITE_CONTACT_Handle*) user_data;
- if (!gtk_list_box_row_get_selectable(row))
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)))
return TRUE;
const gchar *filter = gtk_entry_get_text(
@@ -90,14 +90,14 @@ handle_contacts_listbox_filter_func(GtkListBoxRow *row,
if (!filter)
return TRUE;
- struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
- g_hash_table_lookup(handle->bindings, row)
+ UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) (
+ bindings_get(handle->bindings, row)
);
- if (!contact)
+ if (!entry)
return FALSE;
- const gchar *name = GNUNET_CHAT_contact_get_name(contact);
+ const gchar *name = gtk_label_get_text(entry->title_label);
if (!name)
return FALSE;
@@ -131,36 +131,20 @@ _iterate_contacts(void *cls,
MESSENGER_Application *app = (MESSENGER_Application*) cls;
- const char *title;
- title = GNUNET_CHAT_contact_get_name(contact);
-
- const char *key = GNUNET_CHAT_contact_get_key(contact);
-
UI_CONTACT_ENTRY_Handle *entry = ui_contact_entry_new(app);
+ ui_contact_entry_set_contact(entry, contact);
+
gtk_list_box_prepend(
app->ui.invite_contact.contacts_listbox,
entry->entry_box
);
- if (title)
- {
- gtk_label_set_text(entry->title_label, title);
- hdy_avatar_set_text(entry->entry_avatar, title);
- }
-
- if (key)
- gtk_label_set_text(entry->subtitle_label, key);
-
GtkListBoxRow *row = GTK_LIST_BOX_ROW(
gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(app->ui.bindings, row, contact);
-
- app->ui.invite_contact.contact_entries = g_list_append(
- app->ui.invite_contact.contact_entries,
- entry
- );
+ bindings_put(app->bindings, row, contact);
+ bindings_put(app->ui.invite_contact.bindings, row, entry);
return GNUNET_YES;
}
@@ -169,8 +153,7 @@ void
ui_invite_contact_dialog_init(MESSENGER_Application *app,
UI_INVITE_CONTACT_Handle *handle)
{
- handle->contact_entries = NULL;
- handle->bindings = app->ui.bindings;
+ handle->bindings = bindings_create();
handle->builder = gtk_builder_new_from_resource(
application_get_resource_path(app, "ui/invite_contact.ui")
@@ -241,20 +224,48 @@ ui_invite_contact_dialog_init(MESSENGER_Application *app,
gtk_list_box_invalidate_filter(handle->contacts_listbox);
}
-void
-ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle)
+static void
+_clear_contacts_listbox_rows(UI_INVITE_CONTACT_Handle *handle,
+ gboolean bindings_only)
{
- g_object_unref(handle->builder);
+ GList *list = gtk_container_get_children(
+ GTK_CONTAINER(handle->contacts_listbox)
+ );
+
+ while (list)
+ {
+ GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
- GList *list = handle->contact_entries;
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)))
+ goto skip_row;
- while (list) {
- if (list->data)
- ui_contact_entry_delete((UI_CONTACT_ENTRY_Handle*) list->data);
+ if (!bindings_only)
+ gtk_container_remove(
+ GTK_CONTAINER(handle->contacts_listbox),
+ GTK_WIDGET(row)
+ );
+ bindings_remove(
+ handle->bindings,
+ row,
+ NULL,
+ (GDestroyNotify) ui_contact_entry_delete
+ );
+
+ skip_row:
list = list->next;
}
+}
+
+void
+ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle)
+{
+ _clear_contacts_listbox_rows(handle, TRUE);
+
+ g_object_unref(handle->builder);
+
+ bindings_destroy(handle->bindings);
+ handle->bindings = NULL;
- if (handle->contact_entries)
- g_list_free(handle->contact_entries);
+ handle->contacts_listbox = NULL;
}
diff --git a/src/ui/invite_contact.h b/src/ui/invite_contact.h
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- Copyright (C) 2021 GNUnet e.V.
+ Copyright (C) 2021--2022 GNUnet e.V.
GNUnet is free software: you can redistribute it and/or modify it
under the terms of the GNU Affero General Public License as published
@@ -26,11 +26,11 @@
#define UI_INVITE_CONTACT_H_
#include "messenger.h"
+#include "../bindings.h"
typedef struct UI_INVITE_CONTACT_Handle
{
- GList *contact_entries;
- GHashTable *bindings;
+ MESSENGER_Bindings *bindings;
GtkBuilder *builder;
GtkDialog *dialog;
diff --git a/src/ui/message.c b/src/ui/message.c
@@ -49,15 +49,15 @@ handle_file_button_click(GtkButton *button,
{
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
- UI_MESSAGE_Handle* handle = g_hash_table_lookup(
- app->ui.bindings, button
+ UI_MESSAGE_Handle* handle = (UI_MESSAGE_Handle*) (
+ bindings_get(app->bindings, button)
);
if (!handle)
return;
- struct GNUNET_CHAT_File *file = g_hash_table_lookup(
- app->ui.bindings, handle->file_progress_bar
+ struct GNUNET_CHAT_File *file = (struct GNUNET_CHAT_File*) (
+ bindings_get(app->bindings, handle->file_progress_bar)
);
if (!file)
@@ -266,38 +266,38 @@ ui_message_new(MESSENGER_Application *app,
break;
}
- handle->builder = gtk_builder_new_from_resource(
+ handle->builder[0] = gtk_builder_new_from_resource(
application_get_resource_path(app, ui_builder_file)
);
handle->message_box = GTK_WIDGET(
- gtk_builder_get_object(handle->builder, "message_box")
+ gtk_builder_get_object(handle->builder[0], "message_box")
);
handle->sender_avatar = HDY_AVATAR(
- gtk_builder_get_object(handle->builder, "sender_avatar")
+ gtk_builder_get_object(handle->builder[0], "sender_avatar")
);
handle->sender_label = GTK_LABEL(
- gtk_builder_get_object(handle->builder, "sender_label")
+ gtk_builder_get_object(handle->builder[0], "sender_label")
);
if (UI_MESSAGE_STATUS == handle->type)
{
handle->deny_revealer = GTK_REVEALER(
- gtk_builder_get_object(handle->builder, "deny_revealer")
+ gtk_builder_get_object(handle->builder[0], "deny_revealer")
);
handle->accept_revealer = GTK_REVEALER(
- gtk_builder_get_object(handle->builder, "accept_revealer")
+ gtk_builder_get_object(handle->builder[0], "accept_revealer")
);
handle->deny_button = GTK_BUTTON(
- gtk_builder_get_object(handle->builder, "deny_button")
+ gtk_builder_get_object(handle->builder[0], "deny_button")
);
handle->accept_button = GTK_BUTTON(
- gtk_builder_get_object(handle->builder, "accept_button")
+ gtk_builder_get_object(handle->builder[0], "accept_button")
);
}
else
@@ -310,43 +310,43 @@ ui_message_new(MESSENGER_Application *app,
}
GtkContainer *content_box = GTK_CONTAINER(
- gtk_builder_get_object(handle->builder, "content_box")
+ gtk_builder_get_object(handle->builder[0], "content_box")
);
- GtkBuilder *builder = gtk_builder_new_from_resource(
+ handle->builder[1] = gtk_builder_new_from_resource(
application_get_resource_path(app, "ui/message_content.ui")
);
handle->timestamp_label = GTK_LABEL(
- gtk_builder_get_object(builder, "timestamp_label")
+ gtk_builder_get_object(handle->builder[1], "timestamp_label")
);
handle->read_receipt_image = GTK_IMAGE(
- gtk_builder_get_object(builder, "read_receipt_image")
+ gtk_builder_get_object(handle->builder[1], "read_receipt_image")
);
handle->content_stack = GTK_STACK(
- gtk_builder_get_object(builder, "content_stack")
+ gtk_builder_get_object(handle->builder[1], "content_stack")
);
handle->text_label = GTK_LABEL(
- gtk_builder_get_object(builder, "text_label")
+ gtk_builder_get_object(handle->builder[1], "text_label")
);
handle->file_revealer = GTK_REVEALER(
- gtk_builder_get_object(builder, "file_revealer")
+ gtk_builder_get_object(handle->builder[1], "file_revealer")
);
handle->filename_label = GTK_LABEL(
- gtk_builder_get_object(builder, "filename_label")
+ gtk_builder_get_object(handle->builder[1], "filename_label")
);
handle->file_progress_bar = GTK_PROGRESS_BAR(
- gtk_builder_get_object(builder, "file_progress_bar")
+ gtk_builder_get_object(handle->builder[1], "file_progress_bar")
);
handle->file_button = GTK_BUTTON(
- gtk_builder_get_object(builder, "file_button")
+ gtk_builder_get_object(handle->builder[1], "file_button")
);
g_signal_connect(
@@ -357,16 +357,16 @@ ui_message_new(MESSENGER_Application *app,
);
handle->file_status_image = GTK_IMAGE(
- gtk_builder_get_object(builder, "file_status_image")
+ gtk_builder_get_object(handle->builder[1], "file_status_image")
);
- g_hash_table_insert(app->ui.bindings, handle->file_button, handle);
+ bindings_put(app->bindings, handle->file_button, handle);
handle->preview_drawing_area = GTK_DRAWING_AREA(
- gtk_builder_get_object(builder, "preview_drawing_area")
+ gtk_builder_get_object(handle->builder[1], "preview_drawing_area")
);
- handle->preview_draw_signal = g_signal_connect(
+ g_signal_connect(
handle->preview_drawing_area,
"draw",
G_CALLBACK(handle_preview_drawing_area_draw),
@@ -383,11 +383,9 @@ ui_message_new(MESSENGER_Application *app,
}
gtk_container_add(content_box, GTK_WIDGET(
- gtk_builder_get_object(builder, "message_content_box")
+ gtk_builder_get_object(handle->builder[1], "message_content_box")
));
- g_object_unref(builder);
-
handle->preview_image = NULL;
handle->preview_animation = NULL;
handle->preview_animation_iter = NULL;
@@ -445,15 +443,14 @@ ui_message_update(UI_MESSAGE_Handle *handle,
handle->timestamp = GNUNET_CHAT_message_get_timestamp(msg);
}
else
- file = g_hash_table_lookup(app->ui.bindings, handle->message_box);
+ file = (struct GNUNET_CHAT_File*) (
+ bindings_get(app->bindings, handle->message_box)
+ );
if (!file)
return;
- if (g_hash_table_contains(app->ui.bindings, handle->message_box))
- g_hash_table_replace(app->ui.bindings, handle->message_box, file);
- else
- g_hash_table_insert(app->ui.bindings, handle->message_box, file);
+ bindings_put(app->bindings, handle->message_box, file);
uint64_t size = GNUNET_CHAT_file_get_size(file);
uint64_t local_size = GNUNET_CHAT_file_get_local_size(file);
@@ -522,10 +519,7 @@ file_content:
gtk_revealer_set_reveal_child(handle->file_revealer, TRUE);
- if (g_hash_table_contains(app->ui.bindings, handle->file_progress_bar))
- g_hash_table_replace(app->ui.bindings, handle->file_progress_bar, file);
- else
- g_hash_table_insert(app->ui.bindings, handle->file_progress_bar, file);
+ bindings_put(app->bindings, handle->file_progress_bar, file);
}
void
@@ -533,12 +527,8 @@ ui_message_delete(UI_MESSAGE_Handle *handle)
{
_clear_message_preview_data(handle);
- g_signal_handler_disconnect(
- handle->preview_drawing_area,
- handle->preview_draw_signal
- );
-
- g_object_unref(handle->builder);
+ g_object_unref(handle->builder[1]);
+ g_object_unref(handle->builder[0]);
g_free(handle);
}
diff --git a/src/ui/message.h b/src/ui/message.h
@@ -48,7 +48,7 @@ typedef struct UI_MESSAGE_Handle
struct GNUNET_TIME_Absolute timestamp;
const struct GNUNET_CHAT_Message *msg;
- GtkBuilder *builder;
+ GtkBuilder *builder [2];
GtkWidget *message_box;
HdyAvatar *sender_avatar;
@@ -75,8 +75,6 @@ typedef struct UI_MESSAGE_Handle
GtkDrawingArea *preview_drawing_area;
- gulong preview_draw_signal;
-
GdkPixbuf *preview_image;
GdkPixbufAnimation *preview_animation;
GdkPixbufAnimationIter *preview_animation_iter;
diff --git a/src/ui/messenger.c b/src/ui/messenger.c
@@ -26,6 +26,7 @@
#include <gtk-3.0/gdk/gdkkeys.h>
+#include "account_entry.h"
#include "chat_entry.h"
#include "contacts.h"
#include "message.h"
@@ -105,7 +106,7 @@ handle_accounts_listbox_row_activated(UNUSED GtkListBox* listbox,
}
struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) (
- g_hash_table_lookup(app->ui.bindings, row)
+ bindings_get(app->bindings, row)
);
if (!account)
@@ -192,8 +193,8 @@ handle_chats_listbox_row_activated(UNUSED GtkListBox* listbox,
if (!gtk_list_box_row_get_selectable(row))
return;
- UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) g_hash_table_lookup(
- handle->bindings, row
+ UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) (
+ bindings_get(handle->app->bindings, row)
);
if ((!entry) || (!(entry->chat)) || (!(entry->chat->chat_box)))
@@ -217,7 +218,7 @@ handle_chats_listbox_filter_func(GtkListBoxRow *row,
{
UI_MESSENGER_Handle *handle = (UI_MESSENGER_Handle*) user_data;
- if ((!gtk_list_box_row_get_selectable(row)) ||
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)) ||
(gtk_list_box_row_is_selected(row)))
return TRUE;
@@ -228,8 +229,8 @@ handle_chats_listbox_filter_func(GtkListBoxRow *row,
if (!filter)
return TRUE;
- UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) g_hash_table_lookup(
- handle->bindings, row
+ UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) (
+ bindings_get(handle->app->bindings, row)
);
if ((!entry) || (!(entry->title_label)))
@@ -267,8 +268,8 @@ void
ui_messenger_init(MESSENGER_Application *app,
UI_MESSENGER_Handle *handle)
{
+ handle->app = app;
handle->chat_entries = NULL;
- handle->bindings = app->ui.bindings;
handle->builder = gtk_builder_new_from_resource(
application_get_resource_path(app, "ui/messenger.ui")
@@ -490,6 +491,79 @@ ui_messenger_init(MESSENGER_Application *app,
);
}
+static void
+_messenger_clear_accounts_listbox_rows(UI_MESSENGER_Handle *handle)
+{
+ GList *list = gtk_container_get_children(
+ GTK_CONTAINER(handle->accounts_listbox)
+ );
+
+ while (list)
+ {
+ GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
+
+ if ((!row) || (!gtk_list_box_row_get_selectable(row)))
+ goto skip_row;
+
+ bindings_remove(handle->app->bindings, row, NULL, NULL);
+
+ gtk_container_remove(
+ GTK_CONTAINER(handle->accounts_listbox),
+ GTK_WIDGET(row)
+ );
+
+ skip_row:
+ list = list->next;
+ }
+}
+
+static int
+_messenger_iterate_accounts(void *cls,
+ const struct GNUNET_CHAT_Handle *handle,
+ struct GNUNET_CHAT_Account *account)
+{
+ MESSENGER_Application *app = (MESSENGER_Application*) cls;
+ UI_MESSENGER_Handle *ui = &(app->ui.messenger);
+
+ const gchar *name = GNUNET_CHAT_account_get_name(account);
+
+ UI_ACCOUNT_ENTRY_Handle *entry = ui_account_entry_new(app);
+
+ hdy_avatar_set_text(entry->entry_avatar, name);
+ gtk_label_set_text(entry->entry_label, name);
+
+ gtk_list_box_prepend(ui->accounts_listbox, entry->entry_box);
+
+ GtkListBoxRow *row = GTK_LIST_BOX_ROW(
+ gtk_widget_get_parent(entry->entry_box)
+ );
+
+ bindings_put(app->bindings, row, account);
+
+ if ((account == GNUNET_CHAT_get_connected(handle)) ||
+ ((app->chat.identity) && (0 == g_strcmp0(app->chat.identity, name))))
+ gtk_widget_activate(GTK_WIDGET(row));
+
+ ui_account_entry_delete(entry);
+ return GNUNET_YES;
+}
+
+void
+ui_messenger_refresh(MESSENGER_Application *app,
+ UI_MESSENGER_Handle *handle)
+{
+ if (!(handle->accounts_listbox))
+ return;
+
+ _messenger_clear_accounts_listbox_rows(handle);
+
+ GNUNET_CHAT_iterate_accounts(
+ app->chat.messenger.handle,
+ _messenger_iterate_accounts,
+ app
+ );
+}
+
gboolean
ui_messenger_is_context_active(UI_MESSENGER_Handle *handle,
struct GNUNET_CHAT_Context *context)
@@ -514,11 +588,8 @@ ui_messenger_cleanup(UI_MESSENGER_Handle *handle)
{
g_object_unref(handle->builder);
- for (GList *list = handle->chat_entries; list; list = list->next)
- ui_chat_entry_delete((UI_CHAT_ENTRY_Handle*) list->data);
-
if (handle->chat_entries)
- g_list_free(handle->chat_entries);
+ g_list_free_full(handle->chat_entries, (GDestroyNotify) ui_chat_entry_delete);
memset(handle, 0, sizeof(*handle));
}
diff --git a/src/ui/messenger.h b/src/ui/messenger.h
@@ -35,8 +35,9 @@ typedef struct MESSENGER_Application MESSENGER_Application;
typedef struct UI_MESSENGER_Handle
{
+ MESSENGER_Application *app;
+
GList *chat_entries;
- GHashTable *bindings;
GtkBuilder *builder;
GtkApplicationWindow *main_window;
@@ -77,6 +78,10 @@ void
ui_messenger_init(MESSENGER_Application *app,
UI_MESSENGER_Handle *handle);
+void
+ui_messenger_refresh(MESSENGER_Application *app,
+ UI_MESSENGER_Handle *handle);
+
gboolean
ui_messenger_is_context_active(UI_MESSENGER_Handle *handle,
struct GNUNET_CHAT_Context *context);
diff --git a/src/ui/new_group.c b/src/ui/new_group.c
@@ -50,8 +50,8 @@ _open_new_group(GtkEntry *entry,
{
GtkListBoxRow *row = GTK_LIST_BOX_ROW(selected->data);
- struct GNUNET_CHAT_Contact* contact = g_hash_table_lookup(
- app->ui.bindings, row
+ struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
+ bindings_get(app->bindings, row)
);
GNUNET_CHAT_group_invite_contact(group, contact);
@@ -158,31 +158,19 @@ _iterate_contacts(void *cls,
MESSENGER_Application *app = (MESSENGER_Application*) cls;
- const char *title;
- title = GNUNET_CHAT_contact_get_name(contact);
-
- const char *key = GNUNET_CHAT_contact_get_key(contact);
-
UI_CONTACT_ENTRY_Handle *entry = ui_contact_entry_new(app);
+ ui_contact_entry_set_contact(entry, contact);
+
gtk_list_box_prepend(
app->ui.new_group.contacts_listbox,
entry->entry_box
);
- if (title)
- {
- gtk_label_set_text(entry->title_label, title);
- hdy_avatar_set_text(entry->entry_avatar, title);
- }
-
- if (key)
- gtk_label_set_text(entry->subtitle_label, key);
-
GtkListBoxRow *row = GTK_LIST_BOX_ROW(
gtk_widget_get_parent(entry->entry_box)
);
- g_hash_table_insert(app->ui.bindings, row, contact);
+ bindings_put(app->bindings, row, contact);
app->ui.new_group.contact_entries = g_list_append(
app->ui.new_group.contact_entries,
diff --git a/src/ui/send_file.c b/src/ui/send_file.c
@@ -65,7 +65,7 @@ handle_send_button_click(GtkButton *button,
MESSENGER_Application *app = (MESSENGER_Application*) user_data;
GtkTextView *text_view = GTK_TEXT_VIEW(
- g_hash_table_lookup(app->ui.bindings, button)
+ bindings_get(app->bindings, button)
);
if (!text_view)
@@ -78,8 +78,8 @@ handle_send_button_click(GtkButton *button,
if (!filename)
return;
- struct GNUNET_CHAT_Context *context = g_hash_table_lookup(
- app->ui.bindings, text_view
+ struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
+ bindings_get(app->bindings, text_view)
);
UI_CHAT_ENTRY_Handle *entry = GNUNET_CHAT_context_get_user_pointer(context);