messenger-gtk

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

new_account.c (7812B)


      1 /*
      2    This file is part of GNUnet.
      3    Copyright (C) 2021--2024 GNUnet e.V.
      4 
      5    GNUnet is free software: you can redistribute it and/or modify it
      6    under the terms of the GNU Affero General Public License as published
      7    by the Free Software Foundation, either version 3 of the License,
      8    or (at your option) any later version.
      9 
     10    GNUnet is distributed in the hope that it will be useful, but
     11    WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13    Affero General Public License for more details.
     14 
     15    You should have received a copy of the GNU Affero General Public License
     16    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18    SPDX-License-Identifier: AGPL3.0-or-later
     19  */
     20 /*
     21  * @author Tobias Frisch
     22  * @file ui/new_account.c
     23  */
     24 
     25 #include "new_account.h"
     26 
     27 #include "../application.h"
     28 #include "../contact.h"
     29 #include "../file.h"
     30 #include "../ui.h"
     31 
     32 static void
     33 _open_new_account(GtkEntry *entry, 
     34                   MESSENGER_Application *app)
     35 {
     36   g_assert((entry) && (app));
     37 
     38   const gchar *name = gtk_entry_get_text(entry);
     39 
     40   application_chat_lock(app);
     41 
     42   const enum GNUNET_GenericReturnValue result = GNUNET_CHAT_account_create(
     43     app->chat.messenger.handle, name
     44   );
     45 
     46   application_chat_unlock(app);
     47 
     48   if (GNUNET_OK != result)
     49     return;
     50 
     51   app->ui.state = MESSENGER_STATE_NEW_ACCOUNT;
     52 
     53   gtk_list_box_unselect_all(app->ui.messenger.accounts_listbox);
     54   gtk_widget_set_sensitive(GTK_WIDGET(app->ui.new_account.dialog), FALSE);
     55 }
     56 
     57 static void
     58 handle_account_entry_changed(GtkEditable *editable,
     59                              gpointer user_data)
     60 {
     61   g_assert((editable) && (user_data));
     62 
     63   UI_NEW_ACCOUNT_Handle *handle = (UI_NEW_ACCOUNT_Handle*) user_data;
     64 
     65   const gchar *text = gtk_entry_get_text(GTK_ENTRY(editable));
     66 
     67   hdy_avatar_set_text(handle->account_avatar, text);
     68 
     69   gtk_widget_set_sensitive(
     70     GTK_WIDGET(handle->confirm_button),
     71     (text) && (strlen(text) > 0)
     72   );
     73 }
     74 
     75 static void
     76 handle_account_entry_activate(UNUSED GtkEntry *entry,
     77                               gpointer user_data)
     78 {
     79   g_assert(user_data);
     80 
     81   MESSENGER_Application *app = (MESSENGER_Application*) user_data;
     82 
     83   _open_new_account(app->ui.new_account.account_entry, app);
     84 }
     85 
     86 static void
     87 handle_account_avatar_file_update_preview(GtkFileChooser *file_chooser,
     88                                           gpointer user_data)
     89 {
     90   g_assert((file_chooser) && (user_data));
     91 
     92   HdyAvatar *avatar = HDY_AVATAR(user_data);
     93 
     94   gboolean have_preview = false;
     95   gchar *filename = gtk_file_chooser_get_preview_filename(file_chooser);
     96 
     97   if ((!filename) || (!g_file_test(filename, G_FILE_TEST_IS_REGULAR)))
     98     goto skip_preview;
     99 
    100   GFile *file = g_file_new_for_path(filename);
    101 
    102   if (!file)
    103     goto skip_icon;
    104 
    105   GIcon *icon = g_file_icon_new(file);
    106 
    107   if (!icon)
    108     goto skip_avatar;
    109 
    110   hdy_avatar_set_loadable_icon(avatar, G_LOADABLE_ICON(icon));
    111   g_object_unref(icon);
    112   have_preview = true;
    113 
    114 skip_avatar:
    115   g_object_unref(file);
    116 
    117 skip_icon:
    118   g_free(filename);
    119 
    120 skip_preview:
    121   gtk_file_chooser_set_preview_widget_active(file_chooser, have_preview);
    122 }
    123 
    124 static void
    125 handle_account_avatar_file_set(GtkFileChooserButton *button,
    126                                gpointer user_data)
    127 {
    128   g_assert(user_data);
    129 
    130   GtkFileChooser *file_chooser = GTK_FILE_CHOOSER(button);
    131   UI_NEW_ACCOUNT_Handle *handle = (UI_NEW_ACCOUNT_Handle*) user_data;
    132 
    133   if (handle->filename)
    134     g_free(handle->filename);
    135 
    136   handle->filename = gtk_file_chooser_get_preview_filename(file_chooser);
    137 }
    138 
    139 static void
    140 handle_cancel_button_click(UNUSED GtkButton *button,
    141                            gpointer user_data)
    142 {
    143   g_assert(user_data);
    144 
    145   GtkDialog *dialog = GTK_DIALOG(user_data);
    146   gtk_window_close(GTK_WINDOW(dialog));
    147 }
    148 
    149 static void
    150 handle_confirm_button_click(UNUSED GtkButton *button,
    151                             gpointer user_data)
    152 {
    153   g_assert(user_data);
    154 
    155   MESSENGER_Application *app = (MESSENGER_Application*) user_data;
    156 
    157   _open_new_account(app->ui.new_account.account_entry, app);
    158 }
    159 
    160 static void
    161 handle_dialog_destroy(UNUSED GtkWidget *window,
    162                       gpointer user_data)
    163 {
    164   g_assert(user_data);
    165 
    166   MESSENGER_Application *app = (MESSENGER_Application*) user_data;
    167 
    168   ui_new_account_dialog_cleanup(&(app->ui.new_account));
    169 
    170   if (MESSENGER_STATE_MAIN_WINDOW == app->ui.state)
    171     return;
    172 
    173   gtk_widget_destroy(GTK_WIDGET(app->ui.messenger.main_window));
    174 }
    175 
    176 void
    177 ui_new_account_dialog_init(MESSENGER_Application *app,
    178                            UI_NEW_ACCOUNT_Handle *handle)
    179 {
    180   g_assert((app) && (handle));
    181 
    182   handle->builder = ui_builder_from_resource(
    183     application_get_resource_path(app, "ui/new_account.ui")
    184   );
    185 
    186   handle->dialog = GTK_DIALOG(
    187     gtk_builder_get_object(handle->builder, "new_account_dialog")
    188   );
    189 
    190   gtk_window_set_transient_for(
    191     GTK_WINDOW(handle->dialog),
    192     GTK_WINDOW(app->ui.messenger.main_window)
    193   );
    194 
    195   handle->account_avatar = HDY_AVATAR(
    196     gtk_builder_get_object(handle->builder, "account_avatar")
    197   );
    198 
    199   handle->account_avatar_file = GTK_FILE_CHOOSER_BUTTON(
    200     gtk_builder_get_object(handle->builder, "account_avatar_file")
    201   );
    202 
    203   g_signal_connect(
    204     handle->account_avatar_file,
    205     "update-preview",
    206     G_CALLBACK(handle_account_avatar_file_update_preview),
    207     handle->account_avatar
    208   );
    209 
    210   g_signal_connect(
    211     handle->account_avatar_file,
    212     "file-set",
    213     G_CALLBACK(handle_account_avatar_file_set),
    214     handle
    215   );
    216 
    217   handle->account_entry = GTK_ENTRY(
    218     gtk_builder_get_object(handle->builder, "account_entry")
    219   );
    220 
    221   g_signal_connect(
    222     handle->account_entry,
    223     "changed",
    224     G_CALLBACK(handle_account_entry_changed),
    225     handle
    226   );
    227 
    228   g_signal_connect(
    229     handle->account_entry,
    230     "activate",
    231     G_CALLBACK(handle_account_entry_activate),
    232     app
    233   );
    234 
    235   handle->cancel_button = GTK_BUTTON(
    236     gtk_builder_get_object(handle->builder, "cancel_button")
    237   );
    238 
    239   g_signal_connect(
    240     handle->cancel_button,
    241     "clicked",
    242     G_CALLBACK(handle_cancel_button_click),
    243     handle->dialog
    244   );
    245 
    246   handle->confirm_button = GTK_BUTTON(
    247     gtk_builder_get_object(handle->builder, "confirm_button")
    248   );
    249 
    250   g_signal_connect(
    251     handle->confirm_button,
    252     "clicked",
    253     G_CALLBACK(handle_confirm_button_click),
    254     app
    255   );
    256 
    257   g_signal_connect(
    258     handle->dialog,
    259     "destroy",
    260     G_CALLBACK(handle_dialog_destroy),
    261     app
    262   );
    263 }
    264 
    265 static void
    266 _cb_file_upload(void *cls,
    267                 struct GNUNET_CHAT_File *file,
    268                 uint64_t completed,
    269                 uint64_t size)
    270 {
    271   g_assert((cls) && (file));
    272 
    273   MESSENGER_Application *app = (MESSENGER_Application*) cls;
    274 
    275   file_update_upload_info(file, completed, size);
    276 
    277   if (completed < size)
    278     return;
    279 
    280   struct GNUNET_CHAT_Uri *uri = GNUNET_CHAT_file_get_uri(file);
    281 
    282   if (!uri)
    283     return;
    284 
    285   char *uri_string = GNUNET_CHAT_uri_to_string(uri);
    286 
    287   if (uri_string)
    288   {
    289     GNUNET_CHAT_set_attribute(
    290       app->chat.messenger.handle,
    291       GNUNET_CHAT_ATTRIBUTE_AVATAR,
    292       uri_string
    293     );
    294 
    295     GNUNET_free(uri_string);
    296   }
    297 
    298   GNUNET_CHAT_uri_destroy(uri);
    299 }
    300 
    301 void
    302 ui_new_account_dialog_update(MESSENGER_Application *app,
    303                              UI_NEW_ACCOUNT_Handle *handle)
    304 {
    305   g_assert((app) && (handle));
    306 
    307   gtk_widget_set_sensitive(GTK_WIDGET(app->ui.new_account.dialog), TRUE);
    308   gtk_window_close(GTK_WINDOW(app->ui.new_account.dialog));
    309 
    310   if (!(handle->filename))
    311     return;
    312 
    313   GNUNET_CHAT_upload_file(
    314     app->chat.messenger.handle,
    315     handle->filename,
    316     _cb_file_upload,
    317     app
    318   );
    319   
    320   g_free(handle->filename);
    321   handle->filename = NULL;
    322 }
    323 
    324 void
    325 ui_new_account_dialog_cleanup(UI_NEW_ACCOUNT_Handle *handle)
    326 {
    327   g_assert(handle);
    328 
    329   g_object_unref(handle->builder);
    330 
    331   if (handle->filename)
    332     g_free(handle->filename);
    333 
    334   memset(handle, 0, sizeof(*handle));
    335 }