1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
2 
3    nemo-desktop-link.c: Class that handles the links on the desktop
4 
5    Copyright (C) 2003 Red Hat, Inc.
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16 
17    You should have received a copy of the GNU General Public
18    License along with this program; if not, write to the
19    Free Software Foundation, Inc., 51 Franklin Street - Suite 500,
20    Boston, MA 02110-1335, USA.
21 
22    Author: Alexander Larsson <alexl@redhat.com>
23 */
24 
25 #include <config.h>
26 #include "nemo-desktop-link.h"
27 #include "nemo-desktop-link-monitor.h"
28 #include "nemo-desktop-icon-file.h"
29 #include "nemo-directory-private.h"
30 #include "nemo-desktop-directory.h"
31 #include "nemo-icon-names.h"
32 #include <glib/gi18n.h>
33 #include <gio/gio.h>
34 #include <libnemo-private/nemo-file-utilities.h>
35 #include <libnemo-private/nemo-trash-monitor.h>
36 #include <libnemo-private/nemo-global-preferences.h>
37 #include <string.h>
38 
39 struct NemoDesktopLinkDetails {
40 	NemoDesktopLinkType type;
41         char *filename;
42 	char *display_name;
43 	GFile *activation_location;
44 	GIcon *icon;
45 
46 	NemoDesktopIconFile *icon_file;
47 
48 	GObject *signal_handler_obj;
49 	gulong signal_handler;
50 
51 	/* Just for mount icons: */
52 	GMount *mount;
53 };
54 
G_DEFINE_TYPE(NemoDesktopLink,nemo_desktop_link,G_TYPE_OBJECT)55 G_DEFINE_TYPE(NemoDesktopLink, nemo_desktop_link, G_TYPE_OBJECT)
56 
57 static void
58 create_icon_file (NemoDesktopLink *link)
59 {
60 	link->details->icon_file = nemo_desktop_icon_file_new (link);
61 }
62 
63 static void
nemo_desktop_link_changed(NemoDesktopLink * link)64 nemo_desktop_link_changed (NemoDesktopLink *link)
65 {
66 	if (link->details->icon_file != NULL) {
67 		nemo_desktop_icon_file_update (link->details->icon_file);
68 	}
69 }
70 
71 static void
mount_changed_callback(GMount * mount,NemoDesktopLink * link)72 mount_changed_callback (GMount *mount, NemoDesktopLink *link)
73 {
74 	g_free (link->details->display_name);
75 	if (link->details->activation_location) {
76 		g_object_unref (link->details->activation_location);
77 	}
78 	if (link->details->icon) {
79 		g_object_unref (link->details->icon);
80 	}
81 
82 	link->details->display_name = g_mount_get_name (mount);
83 	link->details->activation_location = g_mount_get_default_location (mount);
84 	link->details->icon = g_mount_get_icon (mount);
85 
86 	nemo_desktop_link_changed (link);
87 }
88 
89 static void
trash_state_changed_callback(NemoTrashMonitor * trash_monitor,gboolean state,gpointer callback_data)90 trash_state_changed_callback (NemoTrashMonitor *trash_monitor,
91 			      gboolean state,
92 			      gpointer callback_data)
93 {
94 	NemoDesktopLink *link;
95 
96 	link = NEMO_DESKTOP_LINK (callback_data);
97 	g_assert (link->details->type == NEMO_DESKTOP_LINK_TRASH);
98 
99 	if (link->details->icon) {
100 		g_object_unref (link->details->icon);
101 	}
102 	link->details->icon = nemo_trash_monitor_get_icon ();
103 
104 	nemo_desktop_link_changed (link);
105 }
106 
107 NemoDesktopLink *
nemo_desktop_link_new(NemoDesktopLinkType type)108 nemo_desktop_link_new (NemoDesktopLinkType type)
109 {
110 	NemoDesktopLink *link;
111 
112 	link = NEMO_DESKTOP_LINK (g_object_new (NEMO_TYPE_DESKTOP_LINK, NULL));
113 
114 	link->details->type = type;
115 	switch (type) {
116 	case NEMO_DESKTOP_LINK_HOME:
117 		link->details->filename = g_strdup ("home");
118 		link->details->display_name = g_strdup (_("Home"));
119 		link->details->activation_location = g_file_new_for_path (g_get_home_dir ());
120 		link->details->icon = g_themed_icon_new (NEMO_ICON_HOME);
121 
122 		break;
123 
124 	case NEMO_DESKTOP_LINK_COMPUTER:
125 		link->details->filename = g_strdup ("computer");
126 		link->details->display_name = g_strdup (_("Computer"));
127 		link->details->activation_location = g_file_new_for_uri ("computer:///");
128 		/* TODO: This might need a different icon: */
129 		link->details->icon = g_themed_icon_new (NEMO_ICON_COMPUTER);
130 
131 		break;
132 
133 	case NEMO_DESKTOP_LINK_TRASH:
134 		link->details->filename = g_strdup ("trash");
135 		link->details->display_name = g_strdup (_("Trash"));
136 		link->details->activation_location = g_file_new_for_uri (EEL_TRASH_URI);
137 		link->details->icon = nemo_trash_monitor_get_icon ();
138 
139 		link->details->signal_handler_obj = G_OBJECT (nemo_trash_monitor_get ());
140 		link->details->signal_handler =
141 			g_signal_connect_object (nemo_trash_monitor_get (), "trash_state_changed",
142 						 G_CALLBACK (trash_state_changed_callback), link, 0);
143 		break;
144 
145 	case NEMO_DESKTOP_LINK_NETWORK:
146 		link->details->filename = g_strdup ("network");
147 		link->details->display_name = g_strdup (_("Network"));
148 		link->details->activation_location = g_file_new_for_uri ("network:///");
149 		link->details->icon = g_themed_icon_new (NEMO_ICON_NETWORK);
150 
151 		break;
152 
153 	default:
154 	case NEMO_DESKTOP_LINK_MOUNT:
155 		g_assert_not_reached();
156 	}
157 
158 	create_icon_file (link);
159 
160 	return link;
161 }
162 
163 NemoDesktopLink *
nemo_desktop_link_new_from_mount(GMount * mount)164 nemo_desktop_link_new_from_mount (GMount *mount)
165 {
166 	NemoDesktopLink *link;
167 	GVolume *volume;
168 	char *name, *filename;
169 
170 	link = NEMO_DESKTOP_LINK (g_object_new (NEMO_TYPE_DESKTOP_LINK, NULL));
171 
172 	link->details->type = NEMO_DESKTOP_LINK_MOUNT;
173 
174 	link->details->mount = g_object_ref (mount);
175 
176 	/* We try to use the drive name to get somewhat stable filenames
177 	   for metadata */
178 	volume = g_mount_get_volume (mount);
179 	if (volume != NULL) {
180 		name = g_volume_get_name (volume);
181 		g_object_unref (volume);
182 	} else {
183 		name = g_mount_get_name (mount);
184 	}
185 
186 	/* Replace slashes in name */
187 	filename = g_strconcat (g_strdelimit (name, "/", '-'), ".volume", NULL);
188 	link->details->filename =
189 		nemo_desktop_link_monitor_make_filename_unique (nemo_desktop_link_monitor_get (),
190 								    filename);
191 	g_free (filename);
192 	g_free (name);
193 
194 	link->details->display_name = g_mount_get_name (mount);
195 
196 	link->details->activation_location = g_mount_get_default_location (mount);
197 	link->details->icon = g_mount_get_icon (mount);
198 
199 	link->details->signal_handler_obj = G_OBJECT (mount);
200 	link->details->signal_handler =
201 		g_signal_connect (mount, "changed",
202 				  G_CALLBACK (mount_changed_callback), link);
203 
204 	create_icon_file (link);
205 
206 	return link;
207 }
208 
209 GMount *
nemo_desktop_link_get_mount(NemoDesktopLink * link)210 nemo_desktop_link_get_mount (NemoDesktopLink *link)
211 {
212 	if (link->details->mount) {
213 		return g_object_ref (link->details->mount);
214 	}
215 	return NULL;
216 }
217 
218 NemoDesktopLinkType
nemo_desktop_link_get_link_type(NemoDesktopLink * link)219 nemo_desktop_link_get_link_type (NemoDesktopLink *link)
220 {
221 	return link->details->type;
222 }
223 
224 NemoFile *
nemo_desktop_link_get_file(NemoDesktopLink * link)225 nemo_desktop_link_get_file (NemoDesktopLink *link)
226 {
227     return NEMO_FILE (link->details->icon_file);
228 }
229 
230 char *
nemo_desktop_link_get_file_name(NemoDesktopLink * link)231 nemo_desktop_link_get_file_name (NemoDesktopLink *link)
232 {
233 	return g_strdup (link->details->filename);
234 }
235 
236 char *
nemo_desktop_link_get_display_name(NemoDesktopLink * link)237 nemo_desktop_link_get_display_name (NemoDesktopLink *link)
238 {
239 	return g_strdup (link->details->display_name);
240 }
241 
242 GIcon *
nemo_desktop_link_get_icon(NemoDesktopLink * link)243 nemo_desktop_link_get_icon (NemoDesktopLink *link)
244 {
245 	if (link->details->icon != NULL) {
246 		return g_object_ref (link->details->icon);
247 	}
248 	return NULL;
249 }
250 
251 GFile *
nemo_desktop_link_get_activation_location(NemoDesktopLink * link)252 nemo_desktop_link_get_activation_location (NemoDesktopLink *link)
253 {
254 	if (link->details->activation_location) {
255 		return g_object_ref (link->details->activation_location);
256 	}
257 	return NULL;
258 }
259 
260 char *
nemo_desktop_link_get_activation_uri(NemoDesktopLink * link)261 nemo_desktop_link_get_activation_uri (NemoDesktopLink *link)
262 {
263 	if (link->details->activation_location) {
264 		return g_file_get_uri (link->details->activation_location);
265 	}
266 	return NULL;
267 }
268 
269 
270 gboolean
nemo_desktop_link_get_date(NemoDesktopLink * link,NemoDateType date_type,time_t * date)271 nemo_desktop_link_get_date (NemoDesktopLink *link,
272 				NemoDateType     date_type,
273 				time_t               *date)
274 {
275 	return FALSE;
276 }
277 
278 gboolean
nemo_desktop_link_can_rename(NemoDesktopLink * link)279 nemo_desktop_link_can_rename (NemoDesktopLink     *link)
280 {
281 	return !(link->details->type == NEMO_DESKTOP_LINK_HOME ||
282 		link->details->type == NEMO_DESKTOP_LINK_TRASH ||
283 		link->details->type == NEMO_DESKTOP_LINK_NETWORK ||
284 		link->details->type == NEMO_DESKTOP_LINK_COMPUTER ||
285         link->details->type == NEMO_DESKTOP_LINK_MOUNT);
286 }
287 
288 gboolean
nemo_desktop_link_rename(NemoDesktopLink * link,const char * name)289 nemo_desktop_link_rename (NemoDesktopLink     *link,
290 			      const char              *name)
291 {
292 	/* Do we want volume renaming? */
293 	return TRUE;
294 }
295 
296 static void
nemo_desktop_link_init(NemoDesktopLink * link)297 nemo_desktop_link_init (NemoDesktopLink *link)
298 {
299 	link->details = G_TYPE_INSTANCE_GET_PRIVATE (link,
300 						     NEMO_TYPE_DESKTOP_LINK,
301 						     NemoDesktopLinkDetails);
302 }
303 
304 static void
desktop_link_finalize(GObject * object)305 desktop_link_finalize (GObject *object)
306 {
307 	NemoDesktopLink *link;
308 
309 	link = NEMO_DESKTOP_LINK (object);
310 
311 	if (link->details->signal_handler != 0) {
312 		g_signal_handler_disconnect (link->details->signal_handler_obj,
313 					     link->details->signal_handler);
314 	}
315 
316 	if (link->details->icon_file != NULL) {
317 		nemo_desktop_icon_file_remove (link->details->icon_file);
318 		nemo_file_unref (NEMO_FILE (link->details->icon_file));
319 		link->details->icon_file = NULL;
320 	}
321 
322 	if (link->details->type == NEMO_DESKTOP_LINK_MOUNT) {
323 		g_object_unref (link->details->mount);
324 	}
325 
326 	g_free (link->details->filename);
327 	g_free (link->details->display_name);
328 	if (link->details->activation_location) {
329 		g_object_unref (link->details->activation_location);
330 	}
331 	if (link->details->icon) {
332 		g_object_unref (link->details->icon);
333 	}
334 
335 	G_OBJECT_CLASS (nemo_desktop_link_parent_class)->finalize (object);
336 }
337 
338 static void
nemo_desktop_link_class_init(NemoDesktopLinkClass * klass)339 nemo_desktop_link_class_init (NemoDesktopLinkClass *klass)
340 {
341 	GObjectClass *object_class;
342 
343 	object_class = G_OBJECT_CLASS (klass);
344 
345 	object_class->finalize = desktop_link_finalize;
346 
347 	g_type_class_add_private (object_class, sizeof(NemoDesktopLinkDetails));
348 }
349