messenger-gtk

Gtk+3 graphical user interfaces for GNUnet Messenger
Log | Files | Refs | Submodules | README | LICENSE

commit caac18bd08717c140ca6189f5616e40867c57f98
parent b24c64652b121643b0ed12c91e0869f0b0bd9865
Author: Jacki <jacki@thejackimonster.de>
Date:   Sat, 21 Sep 2024 03:22:21 +0200

Add list of tags to contact info

Signed-off-by: Jacki <jacki@thejackimonster.de>

Diffstat:
Mresources/ui/contact_info.ui | 215++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/ui/contact_info.c | 182+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msrc/ui/contact_info.h | 9+++++++++
3 files changed, 401 insertions(+), 5 deletions(-)

diff --git a/resources/ui/contact_info.ui b/resources/ui/contact_info.ui @@ -46,6 +46,12 @@ Author: Tobias Frisch <column type="gboolean"/> </columns> </object> + <object class="GtkListStore" id="tags_list"> + <columns> + <!-- column-name name --> + <column type="gchararray"/> + </columns> + </object> <object class="GtkDialog" id="contact_info_dialog"> <property name="can-focus">False</property> <property name="title" translatable="yes">Contact Information</property> @@ -338,6 +344,50 @@ Author: Tobias Frisch </packing> </child> <child> + <object class="GtkButton" id="list_tags_button"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">user-bookmarks-symbolic</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-end">16</property> + <property name="label" translatable="yes">List Tags</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">7</property> + </packing> + </child> + <child> <object class="GtkStack" id="block_stack"> <property name="visible">True</property> <property name="can-focus">False</property> @@ -434,7 +484,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">7</property> + <property name="position">8</property> </packing> </child> <child> @@ -479,7 +529,7 @@ Author: Tobias Frisch <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="position">8</property> + <property name="position">9</property> </packing> </child> </object> @@ -807,6 +857,167 @@ Author: Tobias Frisch <property name="position">3</property> </packing> </child> + <child> + <object class="GtkBox" id="tags_box"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">Tags:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkTreeView" id="tags_tree"> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="model">tags_list</property> + <property name="headers-visible">False</property> + <property name="reorderable">True</property> + <property name="search-column">0</property> + <child internal-child="selection"> + <object class="GtkTreeSelection"/> + </child> + <child> + <object class="GtkTreeViewColumn"> + <property name="resizable">True</property> + <property name="spacing">4</property> + <property name="min-width">120</property> + <property name="title" translatable="yes">Name:</property> + <property name="clickable">True</property> + <property name="sort-indicator">True</property> + <property name="sort-column-id">0</property> + <child> + <object class="GtkCellRendererText"> + <property name="ellipsize">end</property> + </object> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkBox" id="new_tag_box"> + <property name="width-request">250</property> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="halign">center</property> + <property name="margin-top">8</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes">New Tag:</property> + <property name="xalign">0</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="spacing">4</property> + <child> + <object class="GtkEntry" id="tag_name_entry"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="placeholder-text" translatable="yes">Tag</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="remove_tag_button"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">list-remove-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="add_tag_button"> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + <child> + <object class="GtkImage"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="icon-name">list-add-symbolic</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack-type">end</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="name">page0</property> + <property name="title" translatable="yes">page0</property> + <property name="position">4</property> + </packing> + </child> </object> </child> </object> diff --git a/src/ui/contact_info.c b/src/ui/contact_info.c @@ -254,6 +254,17 @@ handle_share_attributes_button_click(UNUSED GtkButton *button, } static void +handle_list_tags_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + g_assert(user_data); + + struct UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; + + _contact_info_switch_stack_to(handle, handle->tags_box); +} + +static void handle_block_button_click(UNUSED GtkButton *button, gpointer user_data) { @@ -768,8 +779,8 @@ handle_add_attribute_button_click(UNUSED GtkButton *button, } static void -handle_attribute_value_entry_activate(UNUSED GtkEntry *entry, - gpointer user_data) +handle_attribute_entry_activate(UNUSED GtkEntry *entry, + gpointer user_data) { g_assert(user_data); @@ -827,6 +838,81 @@ handle_share_renderer_toggle(GtkCellRendererToggle *renderer, g_value_unset(&value_shared); } +static void +handle_tag_entry_changed(GtkEditable *editable, + gpointer user_data) +{ + g_assert((editable) && (user_data)); + + GtkEntry *entry = GTK_ENTRY(editable); + GtkWidget *target = GTK_WIDGET(user_data); + + const gchar *text = gtk_entry_get_text(entry); + + gtk_widget_set_sensitive(target, (text) && (strlen(text))); +} + +static void +handle_add_tag_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + g_assert(user_data); + + UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; + + struct GNUNET_CHAT_Handle *chat = handle->app->chat.messenger.handle; + + if (!chat) + return; + + const gchar *name = gtk_entry_get_text(handle->tag_name_entry); + + if (name) + { + application_chat_lock(handle->app); + GNUNET_CHAT_contact_tag(handle->contact, name); + application_chat_unlock(handle->app); + + gtk_list_store_insert_with_values( + handle->tags_list, + NULL, + -1, + 0, + name, + -1 + ); + } + + gtk_entry_set_text(handle->tag_name_entry, ""); +} + +static void +handle_remove_tag_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + g_assert(user_data); + + UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; + + struct GNUNET_CHAT_Handle *chat = handle->app->chat.messenger.handle; + + if (!chat) + return; + + // TODO: remove tag from contact +} + +static void +handle_tag_entry_activate(UNUSED GtkEntry *entry, + gpointer user_data) +{ + g_assert(user_data); + + UI_CONTACT_INFO_Handle *handle = (UI_CONTACT_INFO_Handle*) user_data; + + handle_add_tag_button_click(handle->add_tag_button, handle); +} + void ui_contact_info_dialog_init(MESSENGER_Application *app, UI_CONTACT_INFO_Handle *handle) @@ -940,6 +1026,17 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, handle ); + handle->list_tags_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "list_tags_button") + ); + + g_signal_connect( + handle->list_tags_button, + "clicked", + G_CALLBACK(handle_list_tags_button_click), + handle + ); + handle->block_stack = GTK_STACK( gtk_builder_get_object(handle->builder, "block_stack") ); @@ -1056,7 +1153,7 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, g_signal_connect( handle->attribute_value_entry, "activate", - G_CALLBACK(handle_attribute_value_entry_activate), + G_CALLBACK(handle_attribute_entry_activate), handle ); @@ -1090,6 +1187,62 @@ ui_contact_info_dialog_init(MESSENGER_Application *app, handle ); + handle->tags_box = GTK_WIDGET( + gtk_builder_get_object(handle->builder, "tags_box") + ); + + handle->tags_tree = GTK_TREE_VIEW( + gtk_builder_get_object(handle->builder, "tags_tree") + ); + + handle->tags_list = GTK_LIST_STORE( + gtk_builder_get_object(handle->builder, "tags_list") + ); + + handle->new_tag_box = GTK_WIDGET( + gtk_builder_get_object(handle->builder, "new_tag_box") + ); + + handle->tag_name_entry = GTK_ENTRY( + gtk_builder_get_object(handle->builder, "tag_name_entry") + ); + + handle->add_tag_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "add_tag_button") + ); + + handle->remove_tag_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "remove_tag_button") + ); + + g_signal_connect( + handle->tag_name_entry, + "changed", + G_CALLBACK(handle_tag_entry_changed), + handle->add_tag_button + ); + + g_signal_connect( + handle->tag_name_entry, + "activate", + G_CALLBACK(handle_tag_entry_activate), + handle + ); + + g_signal_connect( + handle->add_tag_button, + "clicked", + G_CALLBACK(handle_add_tag_button_click), + handle + ); + + g_signal_connect( + handle->remove_tag_button, + "clicked", + G_CALLBACK(handle_remove_tag_button_click), + handle + ); + handle->back_button = GTK_BUTTON( gtk_builder_get_object(handle->builder, "back_button") ); @@ -1240,6 +1393,16 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, ); gtk_widget_set_sensitive( + GTK_WIDGET(handle->list_tags_button), + !editable + ); + + gtk_widget_set_sensitive( + GTK_WIDGET(handle->tag_name_entry), + !editable + ); + + gtk_widget_set_sensitive( GTK_WIDGET(handle->block_button), !editable ); @@ -1259,6 +1422,16 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, !editable ); + gtk_widget_set_visible( + GTK_WIDGET(handle->list_tags_button), + !editable + ); + + gtk_widget_set_visible( + GTK_WIDGET(handle->new_tag_box), + !editable + ); + gtk_stack_set_visible_child( handle->block_stack, GNUNET_YES == GNUNET_CHAT_contact_is_blocked(contact)? @@ -1273,6 +1446,7 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, gtk_list_store_clear(handle->attributes_list); gtk_list_store_clear(handle->sharing_list); + gtk_list_store_clear(handle->tags_list); if (editable) GNUNET_CHAT_get_attributes( @@ -1300,6 +1474,8 @@ ui_contact_info_dialog_update(UI_CONTACT_INFO_Handle *handle, cb_contact_info_shared_attributes, handle ); + + // TODO: iterate contact tags } struct GNUNET_CHAT_Context *context = GNUNET_CHAT_contact_get_context( diff --git a/src/ui/contact_info.h b/src/ui/contact_info.h @@ -55,6 +55,7 @@ typedef struct UI_CONTACT_INFO_Handle GtkButton *reveal_identity_button; GtkButton *list_attributes_button; GtkButton *share_attributes_button; + GtkButton *list_tags_button; GtkStack *block_stack; GtkButton *block_button; GtkButton *unblock_button; @@ -81,6 +82,14 @@ typedef struct UI_CONTACT_INFO_Handle GtkListStore *sharing_list; GtkCellRendererToggle *share_renderer; + GtkWidget *tags_box; + GtkTreeView *tags_tree; + GtkListStore *tags_list; + GtkWidget *new_tag_box; + GtkEntry *tag_name_entry; + GtkButton *add_tag_button; + GtkButton *remove_tag_button; + GtkButton *back_button; GtkButton *close_button;