1 /* dzl-preferences-file-chooser-button.c
2  *
3  * Copyright (C) 2016 Akshaya Kakkilaya <akshaya.kakkilaya@gmail.com>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #define G_LOG_DOMAIN "dzl-preferences-file-chooser-button"
20 
21 #include "config.h"
22 
23 #include "util/dzl-util-private.h"
24 #include "prefs/dzl-preferences-file-chooser-button.h"
25 
26 struct _DzlPreferencesFileChooserButton
27 {
28   DzlPreferencesBin    parent_instance;
29 
30   gchar                *key;
31   GSettings            *settings;
32 
33   GtkFileChooserButton *widget;
34   GtkLabel             *title;
35   GtkLabel             *subtitle;
36 };
37 
38 G_DEFINE_TYPE (DzlPreferencesFileChooserButton, dzl_preferences_file_chooser_button, DZL_TYPE_PREFERENCES_BIN)
39 
40 enum {
41   PROP_0,
42   PROP_ACTION,
43   PROP_KEY,
44   PROP_SUBTITLE,
45   PROP_TITLE,
46   LAST_PROP
47 };
48 
49 static GParamSpec *properties [LAST_PROP];
50 
51 static void
dzl_preferences_file_chooser_button_save_file(DzlPreferencesFileChooserButton * self,GtkFileChooserButton * widget)52 dzl_preferences_file_chooser_button_save_file (DzlPreferencesFileChooserButton *self,
53                                                GtkFileChooserButton            *widget)
54 {
55   g_autofree gchar *path = NULL;
56 
57   g_assert (DZL_IS_PREFERENCES_FILE_CHOOSER_BUTTON (self));
58 
59   path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (self->widget));
60 
61   g_settings_set_string (self->settings, self->key, path);
62 
63 }
64 
65 static void
dzl_preferences_file_chooser_button_connect(DzlPreferencesBin * bin,GSettings * settings)66 dzl_preferences_file_chooser_button_connect (DzlPreferencesBin *bin,
67                                              GSettings         *settings)
68 {
69   DzlPreferencesFileChooserButton *self = (DzlPreferencesFileChooserButton *)bin;
70   g_autofree gchar *file = NULL;
71   g_autofree gchar *path = NULL;
72 
73   g_assert (DZL_IS_PREFERENCES_FILE_CHOOSER_BUTTON (self));
74   g_assert (G_IS_SETTINGS (settings));
75 
76   self->settings = g_object_ref (settings);
77 
78   file = g_settings_get_string (settings, self->key);
79 
80   if (!dzl_str_empty0 (file))
81     {
82       if (!g_path_is_absolute (file))
83         path = g_build_filename (g_get_home_dir (), file, NULL);
84       else
85         path = g_steal_pointer (&file);
86 
87       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (self->widget), path);
88     }
89 
90   g_signal_connect_object (self->widget,
91                            "file-set",
92                            G_CALLBACK (dzl_preferences_file_chooser_button_save_file),
93                            self,
94                            G_CONNECT_SWAPPED);
95 }
96 
97 static gboolean
dzl_preferences_file_chooser_button_matches(DzlPreferencesBin * bin,DzlPatternSpec * spec)98 dzl_preferences_file_chooser_button_matches (DzlPreferencesBin *bin,
99                                              DzlPatternSpec    *spec)
100 {
101   DzlPreferencesFileChooserButton *self = (DzlPreferencesFileChooserButton *)bin;
102   const gchar *tmp;
103 
104   g_assert (DZL_IS_PREFERENCES_FILE_CHOOSER_BUTTON (self));
105   g_assert (spec != NULL);
106 
107   tmp = gtk_label_get_label (self->title);
108   if (tmp && dzl_pattern_spec_match (spec, tmp))
109     return TRUE;
110 
111   tmp = gtk_label_get_label (self->subtitle);
112   if (tmp && dzl_pattern_spec_match (spec, tmp))
113     return TRUE;
114 
115   if (self->key && dzl_pattern_spec_match (spec, self->key))
116     return TRUE;
117 
118   return FALSE;
119 }
120 
121 static void
dzl_preferences_file_chooser_button_finalize(GObject * object)122 dzl_preferences_file_chooser_button_finalize (GObject *object)
123 {
124   DzlPreferencesFileChooserButton *self = (DzlPreferencesFileChooserButton *)object;
125 
126   g_clear_pointer (&self->key, g_free);
127   g_clear_object (&self->settings);
128 
129   G_OBJECT_CLASS (dzl_preferences_file_chooser_button_parent_class)->finalize (object);
130 }
131 
132 static void
dzl_preferences_file_chooser_button_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)133 dzl_preferences_file_chooser_button_get_property (GObject    *object,
134                                                   guint       prop_id,
135                                                   GValue     *value,
136                                                   GParamSpec *pspec)
137 {
138   DzlPreferencesFileChooserButton *self = DZL_PREFERENCES_FILE_CHOOSER_BUTTON (object);
139 
140   switch (prop_id)
141     {
142     case PROP_ACTION:
143       g_value_set_enum (value, gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self->widget)));
144       break;
145 
146     case PROP_KEY:
147       g_value_set_string (value, self->key);
148       break;
149 
150     case PROP_TITLE:
151       g_value_set_string (value, gtk_label_get_label (self->title));
152       break;
153 
154     case PROP_SUBTITLE:
155       g_value_set_string (value, gtk_label_get_label (self->title));
156       break;
157 
158     default:
159       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
160     }
161 }
162 
163 static void
dzl_preferences_file_chooser_button_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)164 dzl_preferences_file_chooser_button_set_property (GObject      *object,
165                                                   guint         prop_id,
166                                                   const GValue *value,
167                                                   GParamSpec   *pspec)
168 {
169   DzlPreferencesFileChooserButton *self = DZL_PREFERENCES_FILE_CHOOSER_BUTTON (object);
170 
171   switch (prop_id)
172     {
173     case PROP_ACTION:
174       gtk_file_chooser_set_action (GTK_FILE_CHOOSER (self->widget), g_value_get_enum (value));
175       break;
176 
177     case PROP_KEY:
178       self->key = g_value_dup_string (value);
179       break;
180 
181     case PROP_TITLE:
182       gtk_label_set_label (self->title, g_value_get_string (value));
183       break;
184 
185     case PROP_SUBTITLE:
186       gtk_label_set_label (self->subtitle, g_value_get_string (value));
187       break;
188 
189     default:
190       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
191     }
192 }
193 
194 static void
dzl_preferences_file_chooser_button_class_init(DzlPreferencesFileChooserButtonClass * klass)195 dzl_preferences_file_chooser_button_class_init (DzlPreferencesFileChooserButtonClass *klass)
196 {
197   GObjectClass *object_class = G_OBJECT_CLASS (klass);
198   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
199   DzlPreferencesBinClass *bin_class = DZL_PREFERENCES_BIN_CLASS (klass);
200 
201   object_class->finalize = dzl_preferences_file_chooser_button_finalize;
202   object_class->get_property = dzl_preferences_file_chooser_button_get_property;
203   object_class->set_property = dzl_preferences_file_chooser_button_set_property;
204 
205   bin_class->connect = dzl_preferences_file_chooser_button_connect;
206   bin_class->matches = dzl_preferences_file_chooser_button_matches;
207 
208   properties [PROP_ACTION] =
209     g_param_spec_enum ("action",
210                        "Action",
211                        "Action",
212                        GTK_TYPE_FILE_CHOOSER_ACTION,
213                        GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
214                        (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
215 
216   properties [PROP_KEY] =
217     g_param_spec_string ("key",
218                          "Key",
219                          "Key",
220                          NULL,
221                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
222 
223   properties [PROP_TITLE] =
224     g_param_spec_string ("title",
225                          "Title",
226                          "Title",
227                          NULL,
228                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
229 
230   properties [PROP_SUBTITLE] =
231     g_param_spec_string ("subtitle",
232                          "Subtitle",
233                          "Subtitle",
234                          NULL,
235                          (G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
236 
237   g_object_class_install_properties (object_class, LAST_PROP, properties);
238 
239   gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/dazzle/ui/dzl-preferences-file-chooser-button.ui");
240   gtk_widget_class_bind_template_child (widget_class, DzlPreferencesFileChooserButton, widget);
241   gtk_widget_class_bind_template_child (widget_class, DzlPreferencesFileChooserButton, title);
242   gtk_widget_class_bind_template_child (widget_class, DzlPreferencesFileChooserButton, subtitle);
243 }
244 
245 static void
dzl_preferences_file_chooser_button_init(DzlPreferencesFileChooserButton * self)246 dzl_preferences_file_chooser_button_init (DzlPreferencesFileChooserButton *self)
247 {
248   gtk_widget_init_template (GTK_WIDGET (self));
249 }
250