1 /*
2 * Copyright (C) 2010 Stefan Walter
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include "gcr/gcr-icons.h"
21 #include "gcr/gcr-parser.h"
22
23 #include "gcr-display-view.h"
24 #include "gcr-failure-renderer.h"
25 #include "gcr-secure-entry-buffer.h"
26
27 #include <gdk/gdk.h>
28 #include <glib/gi18n-lib.h>
29
30 enum {
31 PROP_0,
32 PROP_LABEL,
33 PROP_ATTRIBUTES
34 };
35
36 struct _GcrFailureRendererPrivate {
37 gchar *label;
38 GError *error;
39 };
40
41 static void gcr_renderer_iface_init (GcrRendererIface *iface);
42
43 G_DEFINE_TYPE_WITH_CODE (GcrFailureRenderer, gcr_failure_renderer, G_TYPE_OBJECT,
44 G_ADD_PRIVATE (GcrFailureRenderer);
45 G_IMPLEMENT_INTERFACE (GCR_TYPE_RENDERER, gcr_renderer_iface_init);
46 );
47
48 static void
gcr_failure_renderer_init(GcrFailureRenderer * self)49 gcr_failure_renderer_init (GcrFailureRenderer *self)
50 {
51 self->pv = gcr_failure_renderer_get_instance_private (self);
52 }
53
54 static void
gcr_failure_renderer_finalize(GObject * obj)55 gcr_failure_renderer_finalize (GObject *obj)
56 {
57 GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
58
59 g_error_free (self->pv->error);
60 g_free (self->pv->label);
61
62 G_OBJECT_CLASS (gcr_failure_renderer_parent_class)->finalize (obj);
63 }
64
65 static void
gcr_failure_renderer_set_property(GObject * obj,guint prop_id,const GValue * value,GParamSpec * pspec)66 gcr_failure_renderer_set_property (GObject *obj,
67 guint prop_id,
68 const GValue *value,
69 GParamSpec *pspec)
70 {
71 GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
72
73 switch (prop_id) {
74 case PROP_LABEL:
75 g_free (self->pv->label);
76 self->pv->label = g_value_dup_string (value);
77 g_object_notify (obj, "label");
78 gcr_renderer_emit_data_changed (GCR_RENDERER (self));
79 break;
80 case PROP_ATTRIBUTES:
81 break;
82 default:
83 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
84 break;
85 }
86 }
87
88 static void
gcr_failure_renderer_get_property(GObject * obj,guint prop_id,GValue * value,GParamSpec * pspec)89 gcr_failure_renderer_get_property (GObject *obj,
90 guint prop_id,
91 GValue *value,
92 GParamSpec *pspec)
93 {
94 GcrFailureRenderer *self = GCR_FAILURE_RENDERER (obj);
95
96 switch (prop_id) {
97 case PROP_LABEL:
98 g_value_take_string (value, self->pv->label);
99 break;
100 case PROP_ATTRIBUTES:
101 g_value_set_boxed (value, NULL);
102 break;
103 default:
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
105 break;
106 }
107 }
108
109 static void
gcr_failure_renderer_class_init(GcrFailureRendererClass * klass)110 gcr_failure_renderer_class_init (GcrFailureRendererClass *klass)
111 {
112 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
113
114 gobject_class->finalize = gcr_failure_renderer_finalize;
115 gobject_class->set_property = gcr_failure_renderer_set_property;
116 gobject_class->get_property = gcr_failure_renderer_get_property;
117
118 g_object_class_install_property (gobject_class, PROP_LABEL,
119 g_param_spec_string ("label", "Label", "Failure Label",
120 "",
121 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
122
123 g_object_class_install_property (gobject_class, PROP_ATTRIBUTES,
124 g_param_spec_boxed ("attributes", "Attributes", "Renderer attributes",
125 GCK_TYPE_ATTRIBUTES,
126 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
127 }
128
129 static void
gcr_failure_renderer_render(GcrRenderer * renderer,GcrViewer * viewer)130 gcr_failure_renderer_render (GcrRenderer *renderer,
131 GcrViewer *viewer)
132 {
133 GcrFailureRenderer *self = GCR_FAILURE_RENDERER (renderer);
134 GcrDisplayView *view;
135 gchar *display;
136 GIcon *icon;
137
138 if (GCR_IS_DISPLAY_VIEW (viewer)) {
139 view = GCR_DISPLAY_VIEW (viewer);
140
141 } else {
142 g_warning ("GcrFailureRenderer only works with internal specific "
143 "GcrViewer returned by gcr_viewer_new().");
144 return;
145 }
146
147 _gcr_display_view_begin (view, renderer);
148
149 if (g_error_matches (self->pv->error, GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED))
150 icon = g_themed_icon_new ("dialog-warning");
151 else
152 icon = g_themed_icon_new ("dialog-error");
153 _gcr_display_view_set_icon (view, renderer, icon);
154 g_object_unref (icon);
155
156 _gcr_display_view_append_title (view, renderer, self->pv->label);
157
158 if (self->pv->label)
159 display = g_strdup_printf (_("Could not display “%s”"), self->pv->label);
160 else
161 display = g_strdup (_("Could not display file"));
162 _gcr_display_view_append_content (view, renderer, display, NULL);
163 g_free (display);
164
165 if (self->pv->error->message)
166 _gcr_display_view_append_value (view, renderer, _("Reason"),
167 self->pv->error->message, FALSE);
168
169 _gcr_display_view_end (view, renderer);
170 }
171
172 static void
gcr_renderer_iface_init(GcrRendererIface * iface)173 gcr_renderer_iface_init (GcrRendererIface *iface)
174 {
175 iface->render_view = gcr_failure_renderer_render;
176 }
177
178 /**
179 * gcr_failure_renderer_new:
180 * @label: (nullable): the label for the failure
181 * @error: the error to display
182 *
183 * Create a new renderer for an error.
184 *
185 * Returns: (transfer full) (type GcrUi.FailureRenderer): the new renderer
186 */
187 GcrRenderer *
gcr_failure_renderer_new(const gchar * label,GError * error)188 gcr_failure_renderer_new (const gchar *label,
189 GError *error)
190 {
191 GcrFailureRenderer *renderer;
192
193 renderer = g_object_new (GCR_TYPE_FAILURE_RENDERER,
194 "label", label,
195 NULL);
196
197 renderer->pv->error = g_error_copy (error);
198 return GCR_RENDERER (renderer);
199 }
200
201 /**
202 * gcr_failure_renderer_new_unsupported:
203 * @label: the label for the failure
204 *
205 * Create a new renderer for unsupported data.
206 *
207 * Returns: (transfer full): the new renderer
208 */
209 GcrRenderer *
gcr_failure_renderer_new_unsupported(const gchar * label)210 gcr_failure_renderer_new_unsupported (const gchar *label)
211 {
212 GcrRenderer *renderer;
213 GError *error;
214
215 error = g_error_new (GCR_DATA_ERROR, GCR_ERROR_UNRECOGNIZED,
216 _("Cannot display a file of this type."));
217
218 renderer = gcr_failure_renderer_new (label, error);
219
220 g_error_free (error);
221 return renderer;
222 }
223