GCC Code Coverage Report


Directory: ./
File: panels/printers/pp-ppd-selection-dialog.c
Date: 2024-05-04 07:58:27
Exec Total Coverage
Lines: 0 150 0.0%
Functions: 0 17 0.0%
Branches: 0 47 0.0%

Line Branch Exec Source
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
2 *
3 * Copyright 2012 Red Hat, Inc,
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 2 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 * Author: Marek Kasik <mkasik@redhat.com>
19 */
20
21 #include "config.h"
22
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <sys/wait.h>
27
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <glib/gstdio.h>
31 #include <gtk/gtk.h>
32
33 #include "pp-ppd-selection-dialog.h"
34
35 enum
36 {
37 PPD_NAMES_COLUMN = 0,
38 PPD_DISPLAY_NAMES_COLUMN
39 };
40
41 enum
42 {
43 PPD_MANUFACTURERS_NAMES_COLUMN = 0,
44 PPD_MANUFACTURERS_DISPLAY_NAMES_COLUMN
45 };
46
47
48 struct _PpPPDSelectionDialog {
49 AdwWindow parent_instance;
50
51 GtkButton *ppd_selection_select_button;
52 GtkSpinner *ppd_spinner;
53 GtkLabel *progress_label;
54 GtkTreeView *ppd_selection_manufacturers_treeview;
55 GtkTreeView *ppd_selection_models_treeview;
56
57 UserResponseCallback user_callback;
58 gpointer user_data;
59
60 gchar *ppd_name;
61 gchar *ppd_display_name;
62 gchar *manufacturer;
63
64 PPDList *list;
65 };
66
67 G_DEFINE_TYPE (PpPPDSelectionDialog, pp_ppd_selection_dialog, ADW_TYPE_WINDOW)
68
69 static void
70 manufacturer_selection_changed_cb (PpPPDSelectionDialog *self)
71 {
72 GtkTreeView *treeview;
73 g_autoptr(GtkListStore) store = NULL;
74 GtkTreeModel *model;
75 GtkTreeIter iter;
76 GtkTreeView *models_treeview;
77 gchar *manufacturer_name = NULL;
78 gint i, index;
79
80 treeview = self->ppd_selection_manufacturers_treeview;
81 if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), &model, &iter))
82 {
83 gtk_tree_model_get (model, &iter,
84 PPD_MANUFACTURERS_NAMES_COLUMN, &manufacturer_name,
85 -1);
86 }
87
88 if (manufacturer_name)
89 {
90 index = -1;
91 for (i = 0; i < self->list->num_of_manufacturers; i++)
92 {
93 if (g_strcmp0 (manufacturer_name,
94 self->list->manufacturers[i]->manufacturer_name) == 0)
95 {
96 index = i;
97 break;
98 }
99 }
100
101 if (index >= 0)
102 {
103 models_treeview = self->ppd_selection_models_treeview;
104
105 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
106
107 for (i = 0; i < self->list->manufacturers[index]->num_of_ppds; i++)
108 {
109 gtk_list_store_append (store, &iter);
110 gtk_list_store_set (store, &iter,
111 PPD_NAMES_COLUMN, self->list->manufacturers[index]->ppds[i]->ppd_name,
112 PPD_DISPLAY_NAMES_COLUMN, self->list->manufacturers[index]->ppds[i]->ppd_display_name,
113 -1);
114 }
115
116 gtk_tree_view_set_model (models_treeview, GTK_TREE_MODEL (store));
117 gtk_tree_view_columns_autosize (models_treeview);
118 }
119
120 g_free (manufacturer_name);
121 }
122 }
123
124 static void
125 model_selection_changed_cb (PpPPDSelectionDialog *self)
126 {
127 GtkTreeView *treeview;
128 GtkTreeModel *model;
129 GtkTreeIter iter;
130 GtkButton *ppd_select_button;
131 gchar *model_name = NULL;
132
133 treeview = self->ppd_selection_models_treeview;
134 if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (treeview), &model, &iter))
135 {
136 gtk_tree_model_get (model, &iter,
137 PPD_NAMES_COLUMN, &model_name,
138 -1);
139 }
140
141 ppd_select_button = self->ppd_selection_select_button;
142
143 if (model_name)
144 {
145 gtk_widget_set_sensitive (GTK_WIDGET (ppd_select_button), TRUE);
146 g_free (model_name);
147 }
148 else
149 {
150 gtk_widget_set_sensitive (GTK_WIDGET (ppd_select_button), FALSE);
151 }
152 }
153
154 static void
155 fill_ppds_list (PpPPDSelectionDialog *self)
156 {
157 GtkTreeSelection *selection;
158 g_autoptr(GtkListStore) store = NULL;
159 GtkTreePath *path;
160 GtkTreeView *treeview;
161 GtkTreeIter iter;
162 GtkTreeIter *preselect_iter = NULL;
163 gint i;
164
165 gtk_widget_set_visible (GTK_WIDGET (self->ppd_spinner), FALSE);
166 gtk_spinner_stop (self->ppd_spinner);
167
168 gtk_widget_set_visible (GTK_WIDGET (self->progress_label), FALSE);
169
170 treeview = self->ppd_selection_manufacturers_treeview;
171
172 if (self->list)
173 {
174 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
175
176 for (i = 0; i < self->list->num_of_manufacturers; i++)
177 {
178 gtk_list_store_append (store, &iter);
179 gtk_list_store_set (store, &iter,
180 PPD_MANUFACTURERS_NAMES_COLUMN, self->list->manufacturers[i]->manufacturer_name,
181 PPD_MANUFACTURERS_DISPLAY_NAMES_COLUMN, self->list->manufacturers[i]->manufacturer_display_name,
182 -1);
183
184 if (g_strcmp0 (self->manufacturer,
185 self->list->manufacturers[i]->manufacturer_display_name) == 0)
186 {
187 preselect_iter = gtk_tree_iter_copy (&iter);
188 }
189 }
190
191 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (store));
192
193 if (preselect_iter &&
194 (selection = gtk_tree_view_get_selection (treeview)) != NULL)
195 {
196 gtk_tree_selection_select_iter (selection, preselect_iter);
197 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), preselect_iter);
198 gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.0);
199 gtk_tree_path_free (path);
200 gtk_tree_iter_free (preselect_iter);
201 }
202 }
203 }
204
205 static void
206 populate_dialog (PpPPDSelectionDialog *self)
207 {
208 GtkTreeViewColumn *column;
209 GtkCellRenderer *renderer;
210 GtkTreeView *manufacturers_treeview;
211 GtkTreeView *models_treeview;
212 GtkWidget *header;
213
214 manufacturers_treeview = self->ppd_selection_manufacturers_treeview;
215
216 renderer = gtk_cell_renderer_text_new ();
217 gtk_cell_renderer_set_padding (renderer, 10, 0);
218
219 /* Translators: Name of column showing printer manufacturers */
220 column = gtk_tree_view_column_new_with_attributes (_("Manufacturer"), renderer,
221 "text", PPD_MANUFACTURERS_DISPLAY_NAMES_COLUMN, NULL);
222 gtk_tree_view_column_set_expand (column, TRUE);
223 header = gtk_label_new (gtk_tree_view_column_get_title (column));
224 gtk_widget_set_margin_start (header, 10);
225 gtk_tree_view_column_set_widget (column, header);
226 gtk_widget_set_visible (header, TRUE);
227 gtk_tree_view_append_column (manufacturers_treeview, column);
228
229
230 models_treeview = self->ppd_selection_models_treeview;
231
232 renderer = gtk_cell_renderer_text_new ();
233 gtk_cell_renderer_set_padding (renderer, 10, 0);
234
235 /* Translators: Name of column showing printer drivers */
236 column = gtk_tree_view_column_new_with_attributes (_("Driver"), renderer,
237 "text", PPD_DISPLAY_NAMES_COLUMN,
238 NULL);
239 gtk_tree_view_column_set_expand (column, TRUE);
240 header = gtk_label_new (gtk_tree_view_column_get_title (column));
241 gtk_widget_set_margin_start (header, 10);
242 gtk_tree_view_column_set_widget (column, header);
243 gtk_tree_view_append_column (models_treeview, column);
244
245
246 g_signal_connect_object (gtk_tree_view_get_selection (models_treeview),
247 "changed", G_CALLBACK (model_selection_changed_cb), self, G_CONNECT_SWAPPED);
248
249 g_signal_connect_object (gtk_tree_view_get_selection (manufacturers_treeview),
250 "changed", G_CALLBACK (manufacturer_selection_changed_cb), self, G_CONNECT_SWAPPED);
251
252 if (!self->list)
253 {
254 gtk_widget_set_visible (GTK_WIDGET (self->ppd_spinner), TRUE);
255 gtk_spinner_start (self->ppd_spinner);
256
257 gtk_widget_set_visible (GTK_WIDGET (self->progress_label), TRUE);
258 }
259 else
260 {
261 fill_ppds_list (self);
262 }
263 }
264
265 static void
266 select_cb (PpPPDSelectionDialog *self)
267 {
268 GtkTreeSelection *selection;
269 GtkTreeModel *model;
270 GtkTreeView *models_treeview;
271 GtkTreeIter iter;
272
273 models_treeview = self->ppd_selection_models_treeview;
274
275 if (models_treeview)
276 {
277 selection = gtk_tree_view_get_selection (models_treeview);
278
279 if (selection)
280 {
281 if (gtk_tree_selection_get_selected (selection, &model, &iter))
282 {
283 gtk_tree_model_get (model, &iter,
284 PPD_NAMES_COLUMN, &self->ppd_name,
285 PPD_DISPLAY_NAMES_COLUMN, &self->ppd_display_name,
286 -1);
287 }
288 }
289 }
290
291 self->user_callback (GTK_WINDOW (self), GTK_RESPONSE_OK, self->user_data);
292 }
293
294 static void
295 cancel_cb (PpPPDSelectionDialog *self)
296 {
297 self->user_callback (GTK_WINDOW (self), GTK_RESPONSE_CANCEL, self->user_data);
298 }
299
300 PpPPDSelectionDialog *
301 pp_ppd_selection_dialog_new (PPDList *ppd_list,
302 const gchar *manufacturer,
303 UserResponseCallback user_callback,
304 gpointer user_data)
305 {
306 PpPPDSelectionDialog *self;
307
308 self = g_object_new (pp_ppd_selection_dialog_get_type (), NULL);
309
310 self->user_callback = user_callback;
311 self->user_data = user_data;
312
313 self->list = ppd_list_copy (ppd_list);
314
315 self->manufacturer = get_standard_manufacturers_name (manufacturer);
316
317 gtk_spinner_start (self->ppd_spinner);
318
319 populate_dialog (self);
320
321 return self;
322 }
323
324 static gboolean
325 pp_ppd_selection_dialog_close_request (GtkWindow *window)
326 {
327 PpPPDSelectionDialog *self = PP_PPD_SELECTION_DIALOG (window);
328
329 cancel_cb (self);
330
331 return GDK_EVENT_STOP;
332 }
333
334 static void
335 pp_ppd_selection_dialog_dispose (GObject *object)
336 {
337 PpPPDSelectionDialog *self = PP_PPD_SELECTION_DIALOG (object);
338
339 g_clear_pointer (&self->ppd_name, g_free);
340 g_clear_pointer (&self->ppd_display_name, g_free);
341 g_clear_pointer (&self->manufacturer, g_free);
342
343 G_OBJECT_CLASS (pp_ppd_selection_dialog_parent_class)->dispose (object);
344 }
345
346 void
347 pp_ppd_selection_dialog_class_init (PpPPDSelectionDialogClass *klass)
348 {
349 GtkWindowClass *window_class = GTK_WINDOW_CLASS (klass);
350 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
351 GObjectClass *object_class = G_OBJECT_CLASS (klass);
352
353 gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/printers/ppd-selection-dialog.ui");
354 gtk_widget_class_bind_template_child (widget_class, PpPPDSelectionDialog, ppd_selection_select_button);
355 gtk_widget_class_bind_template_child (widget_class, PpPPDSelectionDialog, ppd_spinner);
356 gtk_widget_class_bind_template_child (widget_class, PpPPDSelectionDialog, progress_label);
357 gtk_widget_class_bind_template_child (widget_class, PpPPDSelectionDialog, ppd_selection_manufacturers_treeview);
358 gtk_widget_class_bind_template_child (widget_class, PpPPDSelectionDialog, ppd_selection_models_treeview);
359
360 gtk_widget_class_bind_template_callback (widget_class, select_cb);
361 gtk_widget_class_bind_template_callback (widget_class, cancel_cb);
362
363 object_class->dispose = pp_ppd_selection_dialog_dispose;
364 window_class->close_request = pp_ppd_selection_dialog_close_request;
365
366 gtk_widget_class_add_binding_action (widget_class, GDK_KEY_Escape, 0, "window.close", NULL);
367 }
368
369 void
370 pp_ppd_selection_dialog_init (PpPPDSelectionDialog *self)
371 {
372 gtk_widget_init_template (GTK_WIDGET (self));
373 }
374
375 gchar *
376 pp_ppd_selection_dialog_get_ppd_name (PpPPDSelectionDialog *self)
377 {
378 return g_strdup (self->ppd_name);
379 }
380
381 gchar *
382 pp_ppd_selection_dialog_get_ppd_display_name (PpPPDSelectionDialog *self)
383 {
384 return g_strdup (self->ppd_display_name);
385 }
386
387 void
388 pp_ppd_selection_dialog_set_ppd_list (PpPPDSelectionDialog *self,
389 PPDList *list)
390 {
391 self->list = list;
392 fill_ppds_list (self);
393 }
394