1 /*
2 * Nautilus
3 *
4 * Copyright (C) 2011 Red Hat, Inc.
5 *
6 * Nautilus is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * Nautilus 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 GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public
17 * License along with this program; see the file COPYING. If not,
18 * see <http://www.gnu.org/licenses/>.
19 *
20 * Author: Cosimo Cecchi <cosimoc@redhat.com>
21 */
22
23 #include <config.h>
24
25 #include "nautilus-progress-info-manager.h"
26
27 struct _NautilusProgressInfoManager
28 {
29 GObject parent_instance;
30
31 GList *progress_infos;
32 GList *current_viewers;
33 };
34
35 enum
36 {
37 NEW_PROGRESS_INFO,
38 HAS_VIEWERS_CHANGED,
39 LAST_SIGNAL
40 };
41
42 static NautilusProgressInfoManager *singleton = NULL;
43
44 static guint signals[LAST_SIGNAL] = { 0, };
45
46 G_DEFINE_TYPE (NautilusProgressInfoManager, nautilus_progress_info_manager,
47 G_TYPE_OBJECT);
48
49 static void remove_viewer (NautilusProgressInfoManager *self,
50 GObject *viewer);
51
52 static void
nautilus_progress_info_manager_finalize(GObject * obj)53 nautilus_progress_info_manager_finalize (GObject *obj)
54 {
55 GList *l;
56 NautilusProgressInfoManager *self = NAUTILUS_PROGRESS_INFO_MANAGER (obj);
57
58 if (self->progress_infos != NULL)
59 {
60 g_list_free_full (self->progress_infos, g_object_unref);
61 }
62
63 for (l = self->current_viewers; l != NULL; l = l->next)
64 {
65 g_object_weak_unref (l->data, (GWeakNotify) remove_viewer, self);
66 }
67 g_list_free (self->current_viewers);
68
69 G_OBJECT_CLASS (nautilus_progress_info_manager_parent_class)->finalize (obj);
70 }
71
72 static GObject *
nautilus_progress_info_manager_constructor(GType type,guint n_props,GObjectConstructParam * props)73 nautilus_progress_info_manager_constructor (GType type,
74 guint n_props,
75 GObjectConstructParam *props)
76 {
77 GObject *retval;
78
79 if (singleton != NULL)
80 {
81 return G_OBJECT (g_object_ref (singleton));
82 }
83
84 retval = G_OBJECT_CLASS (nautilus_progress_info_manager_parent_class)->constructor
85 (type, n_props, props);
86
87 singleton = NAUTILUS_PROGRESS_INFO_MANAGER (retval);
88 g_object_add_weak_pointer (retval, (gpointer) & singleton);
89
90 return retval;
91 }
92
93 static void
nautilus_progress_info_manager_init(NautilusProgressInfoManager * self)94 nautilus_progress_info_manager_init (NautilusProgressInfoManager *self)
95 {
96 }
97
98 static void
nautilus_progress_info_manager_class_init(NautilusProgressInfoManagerClass * klass)99 nautilus_progress_info_manager_class_init (NautilusProgressInfoManagerClass *klass)
100 {
101 GObjectClass *oclass;
102
103 oclass = G_OBJECT_CLASS (klass);
104 oclass->constructor = nautilus_progress_info_manager_constructor;
105 oclass->finalize = nautilus_progress_info_manager_finalize;
106
107 signals[NEW_PROGRESS_INFO] =
108 g_signal_new ("new-progress-info",
109 G_TYPE_FROM_CLASS (klass),
110 G_SIGNAL_RUN_LAST,
111 0, NULL, NULL,
112 g_cclosure_marshal_VOID__OBJECT,
113 G_TYPE_NONE,
114 1,
115 NAUTILUS_TYPE_PROGRESS_INFO);
116
117 signals[HAS_VIEWERS_CHANGED] =
118 g_signal_new ("has-viewers-changed",
119 G_TYPE_FROM_CLASS (klass),
120 G_SIGNAL_RUN_LAST,
121 0, NULL, NULL,
122 g_cclosure_marshal_VOID__VOID,
123 G_TYPE_NONE,
124 0);
125 }
126
127 NautilusProgressInfoManager *
nautilus_progress_info_manager_dup_singleton(void)128 nautilus_progress_info_manager_dup_singleton (void)
129 {
130 return g_object_new (NAUTILUS_TYPE_PROGRESS_INFO_MANAGER, NULL);
131 }
132
133 void
nautilus_progress_info_manager_add_new_info(NautilusProgressInfoManager * self,NautilusProgressInfo * info)134 nautilus_progress_info_manager_add_new_info (NautilusProgressInfoManager *self,
135 NautilusProgressInfo *info)
136 {
137 if (g_list_find (self->progress_infos, info) != NULL)
138 {
139 g_warning ("Adding two times the same progress info object to the manager");
140 return;
141 }
142
143 self->progress_infos =
144 g_list_prepend (self->progress_infos, g_object_ref (info));
145
146 g_signal_emit (self, signals[NEW_PROGRESS_INFO], 0, info);
147 }
148
149 void
nautilus_progress_info_manager_remove_finished_or_cancelled_infos(NautilusProgressInfoManager * self)150 nautilus_progress_info_manager_remove_finished_or_cancelled_infos (NautilusProgressInfoManager *self)
151 {
152 GList *l;
153 GList *next;
154
155 l = self->progress_infos;
156 while (l != NULL)
157 {
158 next = l->next;
159 if (nautilus_progress_info_get_is_finished (l->data) ||
160 nautilus_progress_info_get_is_cancelled (l->data))
161 {
162 self->progress_infos = g_list_remove (self->progress_infos,
163 l->data);
164 }
165 l = next;
166 }
167 }
168
169 GList *
nautilus_progress_info_manager_get_all_infos(NautilusProgressInfoManager * self)170 nautilus_progress_info_manager_get_all_infos (NautilusProgressInfoManager *self)
171 {
172 return self->progress_infos;
173 }
174
175 gboolean
nautilus_progress_manager_are_all_infos_finished_or_cancelled(NautilusProgressInfoManager * self)176 nautilus_progress_manager_are_all_infos_finished_or_cancelled (NautilusProgressInfoManager *self)
177 {
178 GList *l;
179
180 for (l = self->progress_infos; l != NULL; l = l->next)
181 {
182 if (!(nautilus_progress_info_get_is_finished (l->data) ||
183 nautilus_progress_info_get_is_cancelled (l->data)))
184 {
185 return FALSE;
186 }
187 }
188
189 return TRUE;
190 }
191
192 static void
remove_viewer(NautilusProgressInfoManager * self,GObject * viewer)193 remove_viewer (NautilusProgressInfoManager *self,
194 GObject *viewer)
195 {
196 self->current_viewers = g_list_remove (self->current_viewers, viewer);
197
198 if (self->current_viewers == NULL)
199 {
200 g_signal_emit (self, signals[HAS_VIEWERS_CHANGED], 0);
201 }
202 }
203
204 void
nautilus_progress_manager_add_viewer(NautilusProgressInfoManager * self,GObject * viewer)205 nautilus_progress_manager_add_viewer (NautilusProgressInfoManager *self,
206 GObject *viewer)
207 {
208 GList *viewers;
209
210 viewers = self->current_viewers;
211 if (g_list_find (viewers, viewer) == NULL)
212 {
213 g_object_weak_ref (viewer, (GWeakNotify) remove_viewer, self);
214 viewers = g_list_append (viewers, viewer);
215 self->current_viewers = viewers;
216
217 if (g_list_length (viewers) == 1)
218 {
219 g_signal_emit (self, signals[HAS_VIEWERS_CHANGED], 0);
220 }
221 }
222 }
223
224 void
nautilus_progress_manager_remove_viewer(NautilusProgressInfoManager * self,GObject * viewer)225 nautilus_progress_manager_remove_viewer (NautilusProgressInfoManager *self,
226 GObject *viewer)
227 {
228 if (g_list_find (self->current_viewers, viewer) != NULL)
229 {
230 g_object_weak_unref (viewer, (GWeakNotify) remove_viewer, self);
231 remove_viewer (self, viewer);
232 }
233 }
234
235 gboolean
nautilus_progress_manager_has_viewers(NautilusProgressInfoManager * self)236 nautilus_progress_manager_has_viewers (NautilusProgressInfoManager *self)
237 {
238 return self->current_viewers != NULL;
239 }
240