messenger-gtk

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

commit af8c864f72b0beafbd63c063bf257069af830b21
parent fbeb2aa851dee6cfb83cea0b044df609e029f46c
Author: TheJackiMonster <thejackimonster@gmail.com>
Date:   Sat, 18 Dec 2021 00:52:46 +0100

Added dialog to send files

Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>

Diffstat:
MMakefile | 1+
Aresources/ui/send_file.ui | 113+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/application.h | 4++++
Msrc/event.c | 4++--
Msrc/ui/chat.c | 82++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Msrc/ui/contacts.c | 2+-
Msrc/ui/new_contact.c | 2+-
Msrc/ui/new_group.c | 2+-
Msrc/ui/new_group.h | 2++
Msrc/ui/new_platform.c | 2+-
Msrc/ui/new_profile.c | 2+-
Asrc/ui/send_file.c | 148+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/ui/send_file.h | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
13 files changed, 403 insertions(+), 16 deletions(-)

diff --git a/Makefile b/Makefile @@ -20,6 +20,7 @@ SOURCES = messenger_gtk.c\ ui/new_profile.c\ ui/picker.c\ ui/profile_entry.c\ + ui/send_file.c\ ui/settings.c HEADERS = diff --git a/resources/ui/send_file.ui b/resources/ui/send_file.ui @@ -0,0 +1,113 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- Generated with glade 3.38.2 + +Copyright (C) 2021 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 + +--> +<interface> + <requires lib="gtk+" version="3.24"/> + <object class="GtkDialog" id="send_file_dialog"> + <property name="can-focus">False</property> + <property name="modal">True</property> + <property name="window-position">center-on-parent</property> + <property name="type-hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkBox"> + <property name="can-focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkButtonBox"> + <property name="can-focus">False</property> + <property name="layout-style">end</property> + <child> + <object class="GtkButton" id="cancel_button"> + <property name="label" translatable="yes">Cancel</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</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="send_button"> + <property name="label" translatable="yes">Send</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">True</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</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="border-width">8</property> + <property name="orientation">vertical</property> + <property name="spacing">4</property> + <child> + <object class="GtkDrawingArea" id="file_drawing_area"> + <property name="height-request">250</property> + <property name="visible">True</property> + <property name="can-focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkFileChooserButton" id="file_chooser_button"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="title" translatable="yes"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> +</interface> diff --git a/src/application.h b/src/application.h @@ -36,6 +36,7 @@ #include "ui/new_group.h" #include "ui/new_platform.h" #include "ui/new_profile.h" +#include "ui/send_file.h" #include "ui/settings.h" #include "util.h" @@ -72,10 +73,13 @@ typedef struct MESSENGER_Application UI_MESSENGER_Handle messenger; + UI_SEND_FILE_Handle send_file; + UI_NEW_CONTACT_Handle new_contact; UI_NEW_GROUP_Handle new_group; UI_NEW_PLATFORM_Handle new_platform; UI_NEW_PROFILE_Handle new_profile; + UI_CONTACTS_Handle contacts; UI_SETTINGS_Handle settings; } ui; diff --git a/src/event.c b/src/event.c @@ -200,7 +200,7 @@ event_joining_contact(MESSENGER_Application *app, contact_add_name_avatar_to_info(contact, message->sender_avatar); contact_add_name_label_to_info(contact, message->sender_label); - gtk_label_set_text(message->text_label, "joined the chat"); + gtk_label_set_text(message->text_label, _("joined the chat")); gtk_container_add( GTK_CONTAINER(handle->chat->messages_listbox), @@ -266,7 +266,7 @@ event_invitation(UNUSED MESSENGER_Application *app, contact_add_name_avatar_to_info(contact, message->sender_avatar); contact_add_name_label_to_info(contact, message->sender_label); - gtk_label_set_text(message->text_label, "invited you to a chat"); + gtk_label_set_text(message->text_label, _("invited you to a chat")); g_signal_connect( message->accept_button, diff --git a/src/ui/chat.c b/src/ui/chat.c @@ -34,10 +34,10 @@ #include "../contact.h" static void -handle_flap_via_button_click(UNUSED GtkButton* button, +handle_flap_via_button_click(UNUSED GtkButton *button, gpointer user_data) { - HdyFlap* flap = HDY_FLAP(user_data); + HdyFlap *flap = HDY_FLAP(user_data); if (TRUE == hdy_flap_get_reveal_flap(flap)) { hdy_flap_set_reveal_flap(flap, FALSE); @@ -47,8 +47,8 @@ handle_flap_via_button_click(UNUSED GtkButton* button, } static void -handle_chat_contacts_listbox_row_activated(UNUSED GtkListBox* listbox, - GtkListBoxRow* row, +handle_chat_contacts_listbox_row_activated(UNUSED GtkListBox *listbox, + GtkListBoxRow *row, gpointer user_data) { MESSENGER_Application *app = (MESSENGER_Application*) user_data; @@ -79,12 +79,12 @@ handle_chat_contacts_listbox_row_activated(UNUSED GtkListBox* listbox, } static void -handle_back_button_click(UNUSED GtkButton* button, +handle_back_button_click(UNUSED GtkButton *button, gpointer user_data) { - HdyLeaflet* leaflet = HDY_LEAFLET(user_data); + HdyLeaflet *leaflet = HDY_LEAFLET(user_data); - GList* children = gtk_container_get_children(GTK_CONTAINER(leaflet)); + GList *children = gtk_container_get_children(GTK_CONTAINER(leaflet)); if (children) { hdy_leaflet_set_visible_child(leaflet, GTK_WIDGET(children->data)); @@ -92,6 +92,57 @@ handle_back_button_click(UNUSED GtkButton* button, } static void +handle_attach_file_button_click(GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + GtkTextView *text_view = GTK_TEXT_VIEW( + g_hash_table_lookup(app->ui.bindings, button) + ); + + if (!text_view) + return; + + GtkWidget *dialog = gtk_file_chooser_dialog_new( + _("Select file"), + GTK_WINDOW(app->ui.messenger.main_window), + GTK_FILE_CHOOSER_ACTION_OPEN, + _("Cancel"), + GTK_RESPONSE_CANCEL, + _("Confirm"), + GTK_RESPONSE_ACCEPT, + NULL + ); + + if (GTK_RESPONSE_ACCEPT != gtk_dialog_run(GTK_DIALOG(dialog))) + goto close_dialog; + + gchar *filename = gtk_file_chooser_get_filename( + GTK_FILE_CHOOSER(dialog) + ); + + if (!filename) + return; + + ui_send_file_dialog_init(app, &(app->ui.send_file)); + ui_send_file_dialog_update(&(app->ui.send_file), filename); + + g_free(filename); + + g_hash_table_insert( + app->ui.bindings, + app->ui.send_file.send_button, + text_view + ); + + gtk_widget_show(GTK_WIDGET(app->ui.send_file.dialog)); + +close_dialog: + gtk_widget_destroy(dialog); +} + +static void handle_send_text_buffer_changed(GtkTextBuffer *buffer, gpointer user_data) { @@ -128,7 +179,7 @@ _send_text_from_view(MESSENGER_Application *app, return FALSE; struct GNUNET_CHAT_Context *context = g_hash_table_lookup( - app->ui.bindings, text_view + app->ui.bindings, text_view ); if (context) @@ -274,6 +325,13 @@ ui_chat_new(MESSENGER_Application *app) gtk_builder_get_object(handle->builder, "attach_file_button") ); + g_signal_connect( + handle->attach_file_button, + "clicked", + G_CALLBACK(handle_attach_file_button_click), + app + ); + handle->send_text_view = GTK_TEXT_VIEW( gtk_builder_get_object(handle->builder, "send_text_view") ); @@ -317,6 +375,12 @@ ui_chat_new(MESSENGER_Application *app) 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 ); @@ -398,7 +462,7 @@ ui_chat_update(UI_CHAT_Handle *handle, g_string_append_printf( subtitle, - "%d members", + _("%d members"), GNUNET_CHAT_group_iterate_contacts(group, NULL, NULL) ); } diff --git a/src/ui/contacts.c b/src/ui/contacts.c @@ -147,7 +147,7 @@ ui_contacts_dialog_init(MESSENGER_Application *app, gtk_window_set_title( GTK_WINDOW(handle->dialog), - "Contacts" + _("Contacts") ); gtk_window_set_transient_for( diff --git a/src/ui/new_contact.c b/src/ui/new_contact.c @@ -259,7 +259,7 @@ ui_new_contact_dialog_init(MESSENGER_Application *app, gtk_window_set_title( GTK_WINDOW(handle->dialog), - "New Contact" + _("New Contact") ); gtk_window_set_transient_for( diff --git a/src/ui/new_group.c b/src/ui/new_group.c @@ -206,7 +206,7 @@ ui_new_group_dialog_init(MESSENGER_Application *app, gtk_window_set_title( GTK_WINDOW(handle->dialog), - "New Group" + _("New Group") ); gtk_window_set_transient_for( diff --git a/src/ui/new_group.h b/src/ui/new_group.h @@ -25,6 +25,8 @@ #ifndef UI_NEW_GROUP_H_ #define UI_NEW_GROUP_H_ +#include "messenger.h" + typedef struct UI_NEW_GROUP_Handle { GList *contact_entries; diff --git a/src/ui/new_platform.c b/src/ui/new_platform.c @@ -108,7 +108,7 @@ ui_new_platform_dialog_init(MESSENGER_Application *app, gtk_window_set_title( GTK_WINDOW(handle->dialog), - "New Platform" + _("New Platform") ); gtk_window_set_transient_for( diff --git a/src/ui/new_profile.c b/src/ui/new_profile.c @@ -85,7 +85,7 @@ ui_new_profile_dialog_init(MESSENGER_Application *app, gtk_window_set_title( GTK_WINDOW(handle->dialog), - "New Profile" + _("New Profile") ); gtk_window_set_transient_for( diff --git a/src/ui/send_file.c b/src/ui/send_file.c @@ -0,0 +1,148 @@ +/* + This file is part of GNUnet. + Copyright (C) 2021 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 ui/send_file.c + */ + +#include "send_file.h" + +#include "../application.h" + +static void +handle_cancel_button_click(UNUSED GtkButton *button, + gpointer user_data) +{ + GtkDialog *dialog = GTK_DIALOG(user_data); + gtk_window_close(GTK_WINDOW(dialog)); +} + +static void +handle_send_button_click(GtkButton *button, + gpointer user_data) +{ + MESSENGER_Application *app = (MESSENGER_Application*) user_data; + + GtkTextView *text_view = GTK_TEXT_VIEW( + g_hash_table_lookup(app->ui.bindings, button) + ); + + if (!text_view) + return; + + gchar *filename = gtk_file_chooser_get_filename( + GTK_FILE_CHOOSER(app->ui.send_file.file_chooser_button) + ); + + if (!filename) + return; + + struct GNUNET_CHAT_Context *context = g_hash_table_lookup( + app->ui.bindings, text_view + ); + + if (context) + GNUNET_CHAT_context_send_file(context, filename, NULL, NULL); // TODO: callbacks! + + g_free(filename); +} + +static void +handle_dialog_destroy(UNUSED GtkWidget *window, + gpointer user_data) +{ + ui_send_file_dialog_cleanup((UI_SEND_FILE_Handle*) user_data); +} + +void +ui_send_file_dialog_init(MESSENGER_Application *app, + UI_SEND_FILE_Handle *handle) +{ + handle->builder = gtk_builder_new_from_file("resources/ui/send_file.ui"); + + handle->dialog = GTK_DIALOG( + gtk_builder_get_object(handle->builder, "send_file_dialog") + ); + + gtk_window_set_title( + GTK_WINDOW(handle->dialog), + _("Send File") + ); + + gtk_window_set_transient_for( + GTK_WINDOW(handle->dialog), + GTK_WINDOW(app->ui.messenger.main_window) + ); + + handle->file_drawing_area = GTK_DRAWING_AREA( + gtk_builder_get_object(handle->builder, "file_drawing_area") + ); + + handle->file_chooser_button = GTK_FILE_CHOOSER_BUTTON( + gtk_builder_get_object(handle->builder, "file_chooser_button") + ); + + handle->cancel_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "cancel_button") + ); + + g_signal_connect( + handle->cancel_button, + "clicked", + G_CALLBACK(handle_cancel_button_click), + handle->dialog + ); + + handle->send_button = GTK_BUTTON( + gtk_builder_get_object(handle->builder, "send_button") + ); + + g_signal_connect( + handle->send_button, + "clicked", + G_CALLBACK(handle_send_button_click), + app + ); + + g_signal_connect( + handle->dialog, + "destroy", + G_CALLBACK(handle_dialog_destroy), + handle + ); +} + +void +ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle, + const gchar *filename) +{ + if ((!filename) || (!gtk_file_chooser_set_filename( + GTK_FILE_CHOOSER(handle->file_chooser_button), + filename))) + return; + + // TODO: update preview +} + +void +ui_send_file_dialog_cleanup(UI_SEND_FILE_Handle *handle) +{ + g_object_unref(handle->builder); +} diff --git a/src/ui/send_file.h b/src/ui/send_file.h @@ -0,0 +1,55 @@ +/* + This file is part of GNUnet. + Copyright (C) 2021 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 ui/send_file.h + */ + +#ifndef UI_SEND_FILE_H_ +#define UI_SEND_FILE_H_ + +#include "messenger.h" + +typedef struct UI_SEND_FILE_Handle +{ + GList *contact_entries; + + GtkBuilder *builder; + GtkDialog *dialog; + + GtkDrawingArea *file_drawing_area; + GtkFileChooserButton *file_chooser_button; + + GtkButton *cancel_button; + GtkButton *send_button; +} UI_SEND_FILE_Handle; + +void +ui_send_file_dialog_init(MESSENGER_Application *app, + UI_SEND_FILE_Handle *handle); + +void +ui_send_file_dialog_update(UI_SEND_FILE_Handle *handle, + const gchar *filename); + +void +ui_send_file_dialog_cleanup(UI_SEND_FILE_Handle *handle); + +#endif /* UI_SEND_FILE_H_ */