LCOV - code coverage report
Current view: top level - src/plugins/gnome - valent-preferences-other-page.c (source / functions) Coverage Total Hit
Test: Code Coverage Lines: 42.3 % 168 71
Test Date: 2025-04-18 23:22:27 Functions: 62.5 % 16 10
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 22.6 % 62 14

             Branch data     Line data    Source code
       1                 :             : // SPDX-License-Identifier: GPL-3.0-or-later
       2                 :             : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
       3                 :             : 
       4                 :             : #define G_LOG_DOMAIN "valent-device-preferences-dialog"
       5                 :             : 
       6                 :             : #include "config.h"
       7                 :             : 
       8                 :             : #include <glib/gi18n-lib.h>
       9                 :             : #include <adwaita.h>
      10                 :             : #include <gtk/gtk.h>
      11                 :             : #include <valent.h>
      12                 :             : 
      13                 :             : #include "valent-preferences-command-editor.h"
      14                 :             : 
      15                 :             : #include "valent-preferences-other-page.h"
      16                 :             : 
      17                 :             : 
      18                 :             : struct _ValentPreferencesOtherPage
      19                 :             : {
      20                 :             :   ValentPreferencesPage  parent_instance;
      21                 :             : 
      22                 :             :   /* template */
      23                 :             :   GtkListBox            *command_list;
      24                 :             :   GtkLabel              *download_folder_label;
      25                 :             : };
      26                 :             : 
      27   [ +  +  +  - ]:          42 : G_DEFINE_FINAL_TYPE (ValentPreferencesOtherPage, valent_preferences_other_page, VALENT_TYPE_PREFERENCES_PAGE)
      28                 :             : 
      29                 :             : /*
      30                 :             :  * Commands
      31                 :             :  */
      32                 :             : static void
      33                 :           3 : valent_runcommand_preferences_populate (ValentPreferencesOtherPage *self)
      34                 :             : {
      35                 :           3 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (self);
      36                 :           3 :   GSettings *settings;
      37                 :           3 :   GtkWidget *child;
      38                 :           6 :   g_autoptr (GVariant) commands = NULL;
      39                 :           3 :   GVariantIter iter;
      40                 :           3 :   char *uuid;
      41                 :           3 :   GVariant *item;
      42                 :             : 
      43         [ +  - ]:           3 :   g_assert (VALENT_IS_PREFERENCES_OTHER_PAGE (self));
      44                 :             : 
      45                 :           3 :   child = gtk_widget_get_first_child (GTK_WIDGET (self->command_list));
      46         [ +  + ]:           6 :   while (child != NULL)
      47                 :             :     {
      48                 :           3 :       GtkWidget *current = child;
      49                 :             : 
      50                 :           3 :       child = gtk_widget_get_next_sibling (current);
      51         [ -  + ]:           3 :       if (ADW_IS_ACTION_ROW (current))
      52                 :           0 :         gtk_list_box_remove (self->command_list, current);
      53                 :             :     }
      54                 :             : 
      55                 :           3 :   settings = valent_preferences_page_get_settings (page, "runcommand");
      56                 :           3 :   commands = g_settings_get_value (settings, "commands");
      57                 :             : 
      58                 :           3 :   g_variant_iter_init (&iter, commands);
      59         [ -  + ]:           3 :   while (g_variant_iter_loop (&iter, "{sv}", &uuid, &item))
      60                 :             :     {
      61                 :           0 :       const char *name = NULL;
      62                 :           0 :       const char *command = NULL;
      63                 :             : 
      64   [ #  #  #  # ]:           0 :       if (g_variant_lookup (item, "name", "&s", &name) &&
      65                 :           0 :           g_variant_lookup (item, "command", "&s", &command))
      66                 :             :         {
      67                 :           0 :           GtkWidget *row;
      68                 :           0 :           GtkWidget *icon;
      69                 :           0 :           g_autofree char *subtitle = NULL;
      70                 :             : 
      71                 :           0 :           subtitle = g_markup_printf_escaped ("<tt>%s</tt>", command);
      72                 :           0 :           row = g_object_new (ADW_TYPE_ACTION_ROW,
      73                 :             :                               "name",          uuid,
      74                 :             :                               "title",         name,
      75                 :             :                               "subtitle",      subtitle,
      76                 :             :                               "activatable",   TRUE,
      77                 :             :                               "selectable",    FALSE,
      78                 :             :                               "action-target", g_variant_new_string (uuid),
      79                 :             :                               "action-name",   "preferences.edit-command",
      80                 :             :                               NULL);
      81                 :             : 
      82                 :           0 :           icon = g_object_new (GTK_TYPE_IMAGE,
      83                 :             :                                "icon-name",    "document-edit-symbolic",
      84                 :           0 :                                "tooltip-text", _("Edit Command"),
      85                 :             :                                NULL);
      86                 :           0 :           adw_action_row_add_suffix (ADW_ACTION_ROW (row), icon);
      87                 :             : 
      88                 :             :           /* a11y: an activatable widget would change the label and description,
      89                 :             :            * but a button is unnecessary and the label should be unchanged. */
      90                 :           0 :           gtk_accessible_update_relation (GTK_ACCESSIBLE (row),
      91                 :             :                                           GTK_ACCESSIBLE_RELATION_DESCRIBED_BY,
      92                 :             :                                           icon, NULL,
      93                 :             :                                           -1);
      94                 :             : 
      95                 :           0 :           gtk_list_box_append (self->command_list, row);
      96                 :             :         }
      97                 :             :     }
      98                 :           3 : }
      99                 :             : 
     100                 :             : static int
     101                 :           0 : sort_commands (GtkListBoxRow *row1,
     102                 :             :                GtkListBoxRow *row2,
     103                 :             :                gpointer       user_data)
     104                 :             : {
     105                 :           0 :   const char *title1;
     106                 :           0 :   const char *title2;
     107                 :             : 
     108                 :           0 :   title1 = adw_preferences_row_get_title (ADW_PREFERENCES_ROW (row1));
     109                 :           0 :   title2 = adw_preferences_row_get_title (ADW_PREFERENCES_ROW (row2));
     110                 :             : 
     111                 :           0 :   return g_utf8_collate (title1, title2);
     112                 :             : }
     113                 :             : 
     114                 :             : /*
     115                 :             :  * GAction
     116                 :             :  */
     117                 :             : static void
     118                 :           0 : on_command_changed (ValentPreferencesCommandEditor *editor,
     119                 :             :                     GParamSpec                     *pspec,
     120                 :             :                     ValentPreferencesOtherPage     *self)
     121                 :             : {
     122                 :           0 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (self);
     123                 :           0 :   GSettings *settings;
     124                 :           0 :   g_autoptr (GVariant) commands = NULL;
     125                 :           0 :   const char *uuid;
     126                 :           0 :   GVariant *command;
     127                 :           0 :   GVariantDict dict;
     128                 :             : 
     129         [ #  # ]:           0 :   g_assert (VALENT_IS_PREFERENCES_COMMAND_EDITOR (editor));
     130         [ #  # ]:           0 :   g_assert (VALENT_IS_PREFERENCES_OTHER_PAGE (self));
     131                 :             : 
     132                 :           0 :   settings = valent_preferences_page_get_settings (page, "runcommand");
     133                 :           0 :   commands = g_settings_get_value (settings, "commands");
     134                 :             : 
     135                 :           0 :   uuid = valent_preferences_command_editor_get_uuid (editor);
     136                 :           0 :   command = valent_preferences_command_editor_get_command (editor);
     137         [ #  # ]:           0 :   if (command != NULL)
     138                 :             :     {
     139                 :           0 :       g_variant_dict_init (&dict, commands);
     140                 :           0 :       g_variant_dict_insert_value (&dict, uuid, command);
     141                 :           0 :       g_settings_set_value (settings, "commands", g_variant_dict_end (&dict));
     142                 :             :     }
     143                 :             :   else
     144                 :             :     {
     145                 :           0 :       g_variant_dict_init (&dict, commands);
     146                 :           0 :       g_variant_dict_remove (&dict, uuid);
     147                 :           0 :       g_settings_set_value (settings, "commands", g_variant_dict_end (&dict));
     148                 :             :     }
     149                 :             : 
     150         [ #  # ]:           0 :   adw_dialog_close (ADW_DIALOG (editor));
     151                 :           0 : }
     152                 :             : 
     153                 :             : static void
     154                 :           0 : add_command_action (GtkWidget  *widget,
     155                 :             :                     const char *action_name,
     156                 :             :                     GVariant   *parameter)
     157                 :             : {
     158                 :           0 :   g_autofree char *uuid = NULL;
     159                 :             : 
     160         [ #  # ]:           0 :   g_assert (VALENT_IS_PREFERENCES_OTHER_PAGE (widget));
     161                 :             : 
     162                 :           0 :   uuid = g_uuid_string_random ();
     163                 :           0 :   gtk_widget_activate_action (widget, "preferences.edit-command", "s", uuid);
     164                 :           0 : }
     165                 :             : 
     166                 :             : static void
     167                 :           0 : edit_command_action (GtkWidget  *widget,
     168                 :             :                      const char *action_name,
     169                 :             :                      GVariant   *parameter)
     170                 :             : {
     171                 :           0 :   ValentPreferencesOtherPage *self = VALENT_PREFERENCES_OTHER_PAGE (widget);
     172                 :           0 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (self);
     173                 :           0 :   AdwDialog *editor = NULL;
     174                 :           0 :   const char *uuid = NULL;
     175                 :           0 :   GSettings *settings;
     176                 :           0 :   g_autoptr (GVariant) commands = NULL;
     177         [ #  # ]:           0 :   g_autoptr (GVariant) command = NULL;
     178                 :             : 
     179         [ #  # ]:           0 :   g_assert (VALENT_IS_PREFERENCES_OTHER_PAGE (self));
     180                 :             : 
     181                 :           0 :   uuid = g_variant_get_string (parameter, NULL);
     182                 :           0 :   settings = valent_preferences_page_get_settings (page, "runcommand");
     183                 :           0 :   commands = g_settings_get_value (settings, "commands");
     184                 :           0 :   g_variant_lookup (commands, uuid, "@a{sv}", &command);
     185                 :             : 
     186                 :           0 :   editor = g_object_new (VALENT_TYPE_PREFERENCES_COMMAND_EDITOR,
     187                 :             :                          "uuid",    uuid,
     188                 :             :                          "command", command,
     189                 :             :                          NULL);
     190                 :           0 :   g_signal_connect_object (editor,
     191                 :             :                            "notify::command",
     192                 :             :                            G_CALLBACK (on_command_changed),
     193                 :             :                            self,
     194                 :             :                            G_CONNECT_DEFAULT);
     195         [ #  # ]:           0 :   adw_dialog_present (editor, widget);
     196                 :           0 : }
     197                 :             : 
     198                 :             : /*
     199                 :             :  * Share
     200                 :             :  */
     201                 :             : static gboolean
     202                 :           3 : on_download_folder_changed (GValue   *value,
     203                 :             :                             GVariant *variant,
     204                 :             :                             gpointer  user_data)
     205                 :             : {
     206                 :           3 :   const char *label;
     207                 :             : 
     208                 :           3 :   label = g_variant_get_string (variant, NULL);
     209                 :           3 :   g_value_take_string (value, g_path_get_basename (label));
     210                 :             : 
     211                 :           3 :   return TRUE;
     212                 :             : }
     213                 :             : 
     214                 :             : static void
     215                 :           0 : gtk_file_dialog_select_folder_cb (GtkFileDialog         *dialog,
     216                 :             :                                   GAsyncResult          *result,
     217                 :             :                                   ValentPreferencesPage *page)
     218                 :             : {
     219                 :           0 :   g_autoptr (GFile) file = NULL;
     220                 :           0 :   g_autoptr (GError) error = NULL;
     221                 :           0 :   GSettings *settings = NULL;
     222                 :             : 
     223         [ #  # ]:           0 :   g_assert (VALENT_IS_PREFERENCES_PAGE (page));
     224                 :             : 
     225                 :           0 :   file = gtk_file_dialog_select_folder_finish (dialog, result, &error);
     226         [ #  # ]:           0 :   if (file == NULL)
     227                 :             :     {
     228   [ #  #  #  # ]:           0 :       if (!g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED) &&
     229                 :           0 :           !g_error_matches (error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_DISMISSED))
     230                 :           0 :         g_warning ("%s(): %s", G_STRFUNC, error->message);
     231                 :             : 
     232         [ #  # ]:           0 :       return;
     233                 :             :     }
     234                 :             : 
     235                 :           0 :   settings = valent_preferences_page_get_settings (page, "share");
     236         [ #  # ]:           0 :   g_settings_set_string (settings, "download-folder", g_file_peek_path (file));
     237                 :             : }
     238                 :             : 
     239                 :             : static void
     240                 :           0 : select_download_folder_action (GtkWidget  *widget,
     241                 :             :                                const char *action_name,
     242                 :             :                                GVariant   *parameter)
     243                 :             : {
     244                 :           0 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (widget);
     245                 :           0 :   g_autoptr (GtkFileDialog) dialog = NULL;
     246                 :           0 :   GSettings *settings;
     247         [ #  # ]:           0 :   g_autofree char *path = NULL;
     248                 :             : 
     249                 :           0 :   dialog = g_object_new (GTK_TYPE_FILE_DIALOG,
     250                 :           0 :                          "title",        _("Select download folder"),
     251                 :           0 :                          "accept-label", _("Open"),
     252                 :             :                          "modal",        TRUE,
     253                 :             :                          NULL);
     254                 :             : 
     255                 :           0 :   settings = valent_preferences_page_get_settings (page, "share");
     256                 :           0 :   path = g_settings_get_string (settings, "download-folder");
     257   [ #  #  #  # ]:           0 :   if (path != NULL && *path != '\0')
     258                 :             :     {
     259                 :           0 :       g_autoptr (GFile) file = NULL;
     260                 :             : 
     261                 :           0 :       file = g_file_new_for_path (path);
     262         [ #  # ]:           0 :       gtk_file_dialog_set_initial_folder (dialog, file);
     263                 :             :     }
     264                 :             : 
     265                 :           0 :   gtk_file_dialog_select_folder (dialog,
     266                 :           0 :                                  GTK_WINDOW (gtk_widget_get_root (widget)),
     267                 :             :                                  NULL,
     268                 :             :                                  (GAsyncReadyCallback)gtk_file_dialog_select_folder_cb,
     269                 :             :                                  widget);
     270                 :           0 : }
     271                 :             : 
     272                 :             : /*
     273                 :             :  * ValentPreferencesPage
     274                 :             :  */
     275                 :             : static inline void
     276                 :           3 : valent_preferences_other_page_bind_context (ValentPreferencesOtherPage *self)
     277                 :             : {
     278                 :           3 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (self);
     279                 :           6 :   g_autofree char *download_folder = NULL;
     280                 :           3 :   GSettings *settings = NULL;
     281                 :             : 
     282                 :             :   /* Commands
     283                 :             :    */
     284                 :           3 :   settings = valent_preferences_page_get_settings (page, "runcommand");
     285                 :           3 :   g_signal_connect_object (settings,
     286                 :             :                            "changed::commands",
     287                 :             :                            G_CALLBACK (valent_runcommand_preferences_populate),
     288                 :             :                            self,
     289                 :             :                            G_CONNECT_SWAPPED);
     290                 :           3 :   valent_runcommand_preferences_populate (self);
     291                 :             : 
     292                 :             :   /* Share
     293                 :             :    */
     294                 :           3 :   settings = valent_preferences_page_get_settings (page, "share");
     295                 :           3 :   download_folder = g_settings_get_string (settings, "download-folder");
     296   [ +  -  +  - ]:           3 :   if (download_folder == NULL || *download_folder == '\0')
     297                 :             :     {
     298                 :           3 :       const char *user_download = NULL;
     299                 :             : 
     300                 :           3 :       user_download = valent_get_user_directory (G_USER_DIRECTORY_DOWNLOAD);
     301                 :           3 :       g_set_str (&download_folder, user_download);
     302                 :           3 :       g_settings_set_string (settings, "download-folder", download_folder);
     303                 :             :     }
     304                 :             : 
     305                 :           3 :   g_settings_bind_with_mapping (settings,                    "download-folder",
     306                 :           3 :                                 self->download_folder_label, "label",
     307                 :             :                                 G_SETTINGS_BIND_GET,
     308                 :             :                                 on_download_folder_changed,
     309                 :             :                                 NULL,
     310                 :             :                                 NULL, NULL);
     311                 :           3 : }
     312                 :             : 
     313                 :             : /*
     314                 :             :  * GObject
     315                 :             :  */
     316                 :             : static void
     317                 :           3 : valent_preferences_other_page_dispose (GObject *object)
     318                 :             : {
     319                 :           3 :   GtkWidget *widget = GTK_WIDGET (object);
     320                 :             : 
     321                 :           3 :   gtk_widget_dispose_template (widget, VALENT_TYPE_PREFERENCES_OTHER_PAGE);
     322                 :             : 
     323                 :           3 :   G_OBJECT_CLASS (valent_preferences_other_page_parent_class)->dispose (object);
     324                 :           3 : }
     325                 :             : 
     326                 :             : static void
     327                 :          27 : valent_preferences_other_page_notify (GObject    *object,
     328                 :             :                                      GParamSpec *pspec)
     329                 :             : {
     330                 :          27 :   ValentPreferencesPage *page = VALENT_PREFERENCES_PAGE (object);
     331                 :          27 :   ValentPreferencesOtherPage *self = VALENT_PREFERENCES_OTHER_PAGE (object);
     332                 :             : 
     333         [ +  + ]:          27 :   if (g_strcmp0 (pspec->name, "context") == 0)
     334                 :             :     {
     335         [ +  - ]:           3 :       if (valent_preferences_page_get_context (page) != NULL)
     336                 :           3 :         valent_preferences_other_page_bind_context (self);
     337                 :             :     }
     338                 :             : 
     339         [ -  + ]:          27 :   if (G_OBJECT_CLASS (valent_preferences_other_page_parent_class)->notify)
     340                 :           0 :     G_OBJECT_CLASS (valent_preferences_other_page_parent_class)->notify (object,
     341                 :             :                                                                           pspec);
     342                 :          27 : }
     343                 :             : 
     344                 :             : static void
     345                 :           2 : valent_preferences_other_page_class_init (ValentPreferencesOtherPageClass *klass)
     346                 :             : {
     347                 :           2 :   GObjectClass *object_class = G_OBJECT_CLASS (klass);
     348                 :           2 :   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
     349                 :             : 
     350                 :           2 :   object_class->dispose = valent_preferences_other_page_dispose;
     351                 :           2 :   object_class->notify = valent_preferences_other_page_notify;
     352                 :             : 
     353                 :           2 :   gtk_widget_class_set_template_from_resource (widget_class, "/plugins/gnome/valent-preferences-other-page.ui");
     354                 :           2 :   gtk_widget_class_bind_template_child (widget_class, ValentPreferencesOtherPage, command_list);
     355                 :           2 :   gtk_widget_class_bind_template_child (widget_class, ValentPreferencesOtherPage, download_folder_label);
     356                 :           2 :   gtk_widget_class_install_action (widget_class, "preferences.add-command", NULL, add_command_action);
     357                 :           2 :   gtk_widget_class_install_action (widget_class, "preferences.edit-command", "s", edit_command_action);
     358                 :           2 :   gtk_widget_class_install_action (widget_class, "preferences.select-download-folder", NULL, select_download_folder_action);
     359                 :           2 : }
     360                 :             : 
     361                 :             : static void
     362                 :           3 : valent_preferences_other_page_init (ValentPreferencesOtherPage *self)
     363                 :             : {
     364                 :           3 :   gtk_widget_init_template (GTK_WIDGET (self));
     365                 :           3 :   gtk_list_box_set_sort_func (self->command_list, sort_commands, self, NULL);
     366                 :           3 : }
     367                 :             : 
        

Generated by: LCOV version 2.0-1