1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Copyright (C) 2008 Red Hat, Inc.
4 * Copyright (C) 2006 Paolo Borelli <pborelli@katamail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street - Suite 500, Boston, MA 02110-1335, USA.
19 *
20 * Authors: David Zeuthen <davidz@redhat.com>
21 * Paolo Borelli <pborelli@katamail.com>
22 *
23 */
24
25 #include "config.h"
26
27 #include <glib/gi18n.h>
28 #include <gtk/gtk.h>
29 #include <string.h>
30
31 #include "nemo-x-content-bar.h"
32 #include <libnemo-private/nemo-program-choosing.h>
33
34 #define NEMO_X_CONTENT_BAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NEMO_TYPE_X_CONTENT_BAR, NemoXContentBarPrivate))
35
36 struct NemoXContentBarPrivate
37 {
38 GtkWidget *label;
39 GtkWidget *button;
40
41 char *x_content_type;
42 GMount *mount;
43 };
44
45 enum {
46 PROP_0,
47 PROP_MOUNT,
48 PROP_X_CONTENT_TYPE,
49 };
50
51 enum {
52 CONTENT_BAR_RESPONSE_APP = 1
53 };
54
G_DEFINE_TYPE(NemoXContentBar,nemo_x_content_bar,GTK_TYPE_INFO_BAR)55 G_DEFINE_TYPE (NemoXContentBar, nemo_x_content_bar, GTK_TYPE_INFO_BAR)
56
57 static void
58 content_bar_response_cb (GtkInfoBar *infobar,
59 gint response_id,
60 gpointer user_data)
61 {
62 GAppInfo *default_app;
63 NemoXContentBar *bar;
64
65 if (response_id != CONTENT_BAR_RESPONSE_APP) {
66 return;
67 }
68
69 bar = user_data;
70
71 if (bar->priv->x_content_type == NULL ||
72 bar->priv->mount == NULL)
73 return;
74
75 default_app = g_app_info_get_default_for_type (bar->priv->x_content_type, FALSE);
76 if (default_app != NULL) {
77 nemo_launch_application_for_mount (default_app, bar->priv->mount,
78 GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (bar))));
79 g_object_unref (default_app);
80 }
81 }
82
83 static void
nemo_x_content_bar_set_x_content_type(NemoXContentBar * bar,const char * x_content_type)84 nemo_x_content_bar_set_x_content_type (NemoXContentBar *bar, const char *x_content_type)
85 {
86 char *message;
87 char *description;
88 GAppInfo *default_app;
89
90 g_free (bar->priv->x_content_type);
91 bar->priv->x_content_type = g_strdup (x_content_type);
92
93 description = g_content_type_get_description (x_content_type);
94
95 /* Customize greeting for well-known x-content types */
96 if (strcmp (x_content_type, "x-content/audio-cdda") == 0) {
97 message = g_strdup (_("These files are on an Audio CD."));
98 } else if (strcmp (x_content_type, "x-content/audio-dvd") == 0) {
99 message = g_strdup (_("These files are on an Audio DVD."));
100 } else if (strcmp (x_content_type, "x-content/video-dvd") == 0) {
101 message = g_strdup (_("These files are on a Video DVD."));
102 } else if (strcmp (x_content_type, "x-content/video-vcd") == 0) {
103 message = g_strdup (_("These files are on a Video CD."));
104 } else if (strcmp (x_content_type, "x-content/video-svcd") == 0) {
105 message = g_strdup (_("These files are on a Super Video CD."));
106 } else if (strcmp (x_content_type, "x-content/image-photocd") == 0) {
107 message = g_strdup (_("These files are on a Photo CD."));
108 } else if (strcmp (x_content_type, "x-content/image-picturecd") == 0) {
109 message = g_strdup (_("These files are on a Picture CD."));
110 } else if (strcmp (x_content_type, "x-content/image-dcf") == 0) {
111 message = g_strdup (_("The media contains digital photos."));
112 } else if (strcmp (x_content_type, "x-content/audio-player") == 0) {
113 message = g_strdup (_("These files are on a digital audio player."));
114 } else if (strcmp (x_content_type, "x-content/software") == 0) {
115 message = g_strdup (_("The media contains software."));
116 } else {
117 /* fallback to generic greeting */
118 message = g_strdup_printf (_("The media has been detected as \"%s\"."), description);
119 }
120
121
122 gtk_label_set_text (GTK_LABEL (bar->priv->label), message);
123 gtk_widget_show (bar->priv->label);
124
125 /* TODO: We really need a GtkBrowserBackButton-ish widget here.. until then, we only
126 * show the default application. */
127
128 default_app = g_app_info_get_default_for_type (x_content_type, FALSE);
129 if (default_app != NULL) {
130 char *button_text;
131 const char *name;
132 GIcon *icon;
133 GtkWidget *image;
134
135 icon = g_app_info_get_icon (default_app);
136 if (icon != NULL) {
137 image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON);
138 } else {
139 image = NULL;
140 }
141
142 name = g_app_info_get_display_name (default_app);
143 button_text = g_strdup_printf (_("Open %s"), name);
144
145 gtk_button_set_image (GTK_BUTTON (bar->priv->button), image);
146 gtk_button_set_label (GTK_BUTTON (bar->priv->button), button_text);
147 gtk_widget_show (bar->priv->button);
148 g_free (button_text);
149 g_object_unref (default_app);
150 } else {
151 gtk_widget_hide (bar->priv->button);
152 }
153
154 g_free (message);
155 g_free (description);
156 }
157
158 static void
nemo_x_content_bar_set_mount(NemoXContentBar * bar,GMount * mount)159 nemo_x_content_bar_set_mount (NemoXContentBar *bar, GMount *mount)
160 {
161 if (bar->priv->mount != NULL) {
162 g_object_unref (bar->priv->mount);
163 }
164 bar->priv->mount = mount != NULL ? g_object_ref (mount) : NULL;
165 }
166
167
168 static void
nemo_x_content_bar_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)169 nemo_x_content_bar_set_property (GObject *object,
170 guint prop_id,
171 const GValue *value,
172 GParamSpec *pspec)
173 {
174 NemoXContentBar *bar;
175
176 bar = NEMO_X_CONTENT_BAR (object);
177
178 switch (prop_id) {
179 case PROP_MOUNT:
180 nemo_x_content_bar_set_mount (bar, G_MOUNT (g_value_get_object (value)));
181 break;
182 case PROP_X_CONTENT_TYPE:
183 nemo_x_content_bar_set_x_content_type (bar, g_value_get_string (value));
184 break;
185 default:
186 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
187 break;
188 }
189 }
190
191 static void
nemo_x_content_bar_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)192 nemo_x_content_bar_get_property (GObject *object,
193 guint prop_id,
194 GValue *value,
195 GParamSpec *pspec)
196 {
197 NemoXContentBar *bar = NEMO_X_CONTENT_BAR (object);
198
199 switch (prop_id) {
200 case PROP_MOUNT:
201 g_value_set_object (value, bar->priv->mount);
202 break;
203 case PROP_X_CONTENT_TYPE:
204 g_value_set_string (value, bar->priv->x_content_type);
205 break;
206 default:
207 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
208 break;
209 }
210 }
211
212 static void
nemo_x_content_bar_finalize(GObject * object)213 nemo_x_content_bar_finalize (GObject *object)
214 {
215 NemoXContentBar *bar = NEMO_X_CONTENT_BAR (object);
216
217 g_free (bar->priv->x_content_type);
218 if (bar->priv->mount != NULL)
219 g_object_unref (bar->priv->mount);
220
221 G_OBJECT_CLASS (nemo_x_content_bar_parent_class)->finalize (object);
222 }
223
224 static void
nemo_x_content_bar_class_init(NemoXContentBarClass * klass)225 nemo_x_content_bar_class_init (NemoXContentBarClass *klass)
226 {
227 GObjectClass *object_class;
228
229 object_class = G_OBJECT_CLASS (klass);
230 object_class->get_property = nemo_x_content_bar_get_property;
231 object_class->set_property = nemo_x_content_bar_set_property;
232 object_class->finalize = nemo_x_content_bar_finalize;
233
234 g_type_class_add_private (klass, sizeof (NemoXContentBarPrivate));
235
236 g_object_class_install_property (object_class,
237 PROP_MOUNT,
238 g_param_spec_object (
239 "mount",
240 "The GMount to run programs for",
241 "The GMount to run programs for",
242 G_TYPE_MOUNT,
243 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
244
245 g_object_class_install_property (object_class,
246 PROP_X_CONTENT_TYPE,
247 g_param_spec_string (
248 "x-content-type",
249 "The x-content type for the cluebar",
250 "The x-content type for the cluebar",
251 NULL,
252 G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
253 }
254
255 static void
nemo_x_content_bar_init(NemoXContentBar * bar)256 nemo_x_content_bar_init (NemoXContentBar *bar)
257 {
258 GtkWidget *content_area;
259
260 bar->priv = NEMO_X_CONTENT_BAR_GET_PRIVATE (bar);
261 content_area = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar));
262
263 bar->priv->label = gtk_label_new (NULL);
264 gtk_style_context_add_class (gtk_widget_get_style_context (bar->priv->label),
265 "nemo-cluebar-label");
266 gtk_label_set_ellipsize (GTK_LABEL (bar->priv->label), PANGO_ELLIPSIZE_END);
267 gtk_container_add (GTK_CONTAINER (content_area), bar->priv->label);
268
269 bar->priv->button = gtk_info_bar_add_button (GTK_INFO_BAR (bar),
270 "",
271 CONTENT_BAR_RESPONSE_APP);
272
273 g_signal_connect (bar, "response",
274 G_CALLBACK (content_bar_response_cb),
275 bar);
276 }
277
278 GtkWidget *
nemo_x_content_bar_new(GMount * mount,const char * x_content_type)279 nemo_x_content_bar_new (GMount *mount,
280 const char *x_content_type)
281 {
282 return g_object_new (NEMO_TYPE_X_CONTENT_BAR,
283 "mount", mount,
284 "x-content-type", x_content_type,
285 NULL);
286 }
287