nautilus-3.6.3/libnautilus-private/nautilus-file-undo-manager.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found nautilus-file-undo-manager.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
  2 
  3 /* nautilus-file-undo-manager.c - Manages the undo/redo stack
  4  *
  5  * Copyright (C) 2007-2011 Amos Brocco
  6  * Copyright (C) 2010, 2012 Red Hat, Inc.
  7  *
  8  * This library is free software; you can redistribute it and/or
  9  * modify it under the terms of the GNU General Public
 10  * License as published by the Free Software Foundation; either
 11  * version 2 of the License, or (at your option) any later version.
 12  *
 13  * This library is distributed in the hope that it will be useful,
 14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 16  * General Public License for more details.
 17  *
 18  * You should have received a copy of the GNU General Public
 19  * License along with this library; if not, write to the
 20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 21  * Boston, MA 02111-1307, USA.
 22  *
 23  * Authors: Amos Brocco <amos.brocco@gmail.com>
 24  *          Cosimo Cecchi <cosimoc@redhat.com>
 25  *
 26  */
 27 
 28 #include <config.h>
 29 
 30 #include "nautilus-file-undo-manager.h"
 31 
 32 #include "nautilus-file-operations.h"
 33 #include "nautilus-file.h"
 34 #include "nautilus-trash-monitor.h"
 35 
 36 #include <glib/gi18n.h>
 37 
 38 #define DEBUG_FLAG NAUTILUS_DEBUG_UNDO
 39 #include "nautilus-debug.h"
 40 
 41 enum {
 42 	SIGNAL_UNDO_CHANGED,
 43 	NUM_SIGNALS,
 44 };
 45 
 46 static guint signals[NUM_SIGNALS] = { 0, };
 47 
 48 G_DEFINE_TYPE (NautilusFileUndoManager, nautilus_file_undo_manager, G_TYPE_OBJECT)
 49 
 50 struct _NautilusFileUndoManagerPrivate
 51 {
 52 	NautilusFileUndoInfo *info;
 53 	NautilusFileUndoManagerState state;
 54 	NautilusFileUndoManagerState last_state;
 55 
 56 	guint undo_redo_flag : 1;
 57 
 58 	gulong trash_signal_id;
 59 };
 60 
 61 static NautilusFileUndoManager *undo_singleton = NULL;
 62 
 63 static NautilusFileUndoManager *
 64 get_singleton (void)
 65 {
 66 	if (undo_singleton == NULL) {
 67 		undo_singleton = g_object_new (NAUTILUS_TYPE_FILE_UNDO_MANAGER, NULL);
 68 		g_object_add_weak_pointer (G_OBJECT (undo_singleton), (gpointer) &undo_singleton);
 69 	}
 70 
 71 	return undo_singleton;
 72 }
 73 
 74 static void
 75 file_undo_manager_clear (NautilusFileUndoManager *self)
 76 {
 77 	g_clear_object (&self->priv->info);
 78 	self->priv->state = NAUTILUS_FILE_UNDO_MANAGER_STATE_NONE;
 79 }
 80 
 81 static void
 82 trash_state_changed_cb (NautilusTrashMonitor *monitor,
 83 			gboolean is_empty,
 84 			gpointer user_data)
 85 {
 86 	NautilusFileUndoManager *self = user_data;
 87 
 88 	if (!is_empty) {
 89 		return;
 90 	}
 91 
 92 	if (self->priv->state == NAUTILUS_FILE_UNDO_MANAGER_STATE_NONE) {
 93 		return;
 94 	}
 95 
 96 	if (NAUTILUS_IS_FILE_UNDO_INFO_TRASH (self->priv->info)) {
 97 		file_undo_manager_clear (self);
 98 		g_signal_emit (self, signals[SIGNAL_UNDO_CHANGED], 0);
 99 	}
100 }
101 
102 static void
103 nautilus_file_undo_manager_init (NautilusFileUndoManager * self)
104 {
105 	NautilusFileUndoManagerPrivate *priv = self->priv = 
106 		G_TYPE_INSTANCE_GET_PRIVATE (self, 
107 					     NAUTILUS_TYPE_FILE_UNDO_MANAGER, 
108 					     NautilusFileUndoManagerPrivate);
109 
110 	priv->trash_signal_id = g_signal_connect (nautilus_trash_monitor_get (),
111 						  "trash-state-changed",
112 						  G_CALLBACK (trash_state_changed_cb), self);
113 }
114 
115 static void
116 nautilus_file_undo_manager_finalize (GObject * object)
117 {
118 	NautilusFileUndoManager *self = NAUTILUS_FILE_UNDO_MANAGER (object);
119 	NautilusFileUndoManagerPrivate *priv = self->priv;
120 
121 	if (priv->trash_signal_id != 0) {
122 		g_signal_handler_disconnect (nautilus_trash_monitor_get (),
123 					     priv->trash_signal_id);
124 		priv->trash_signal_id = 0;
125 	}
126 
127 	file_undo_manager_clear (self);
128 
129 	G_OBJECT_CLASS (nautilus_file_undo_manager_parent_class)->finalize (object);
130 }
131 
132 static void
133 nautilus_file_undo_manager_class_init (NautilusFileUndoManagerClass *klass)
134 {
135 	GObjectClass *oclass;
136 
137 	oclass = G_OBJECT_CLASS (klass);
138 
139 	oclass->finalize = nautilus_file_undo_manager_finalize;
140 
141 	signals[SIGNAL_UNDO_CHANGED] =
142 		g_signal_new ("undo-changed",
143 			      G_TYPE_FROM_CLASS (klass),
144 			      G_SIGNAL_RUN_LAST,
145 			      0, NULL, NULL,
146 			      g_cclosure_marshal_VOID__VOID,
147 			      G_TYPE_NONE, 0);
148 
149 	g_type_class_add_private (klass, sizeof (NautilusFileUndoManagerPrivate));
150 }
151 
152 static void
153 undo_info_apply_ready (GObject *source,
154 		       GAsyncResult *res,
155 		       gpointer user_data)
156 {
157 	NautilusFileUndoManager *self = user_data;
158 	NautilusFileUndoInfo *info = NAUTILUS_FILE_UNDO_INFO (source);
159 	gboolean success, user_cancel;
160 
161 	success = nautilus_file_undo_info_apply_finish (info, res, &user_cancel, NULL);
162 
163 	/* just return in case we got another another operation set */
164 	if ((self->priv->info != NULL) &&
165 	    (self->priv->info != info)) {
166 		return;
167 	}
168 
169 	if (success) {
170 		if (self->priv->last_state == NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO) {
171 			self->priv->state = NAUTILUS_FILE_UNDO_MANAGER_STATE_REDO;
172 		} else if (self->priv->last_state == NAUTILUS_FILE_UNDO_MANAGER_STATE_REDO) {
173 			self->priv->state = NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO;
174 		}
175 
176 		self->priv->info = g_object_ref (info);
177 	} else if (user_cancel) {
178 		self->priv->state = self->priv->last_state;
179 		self->priv->info = g_object_ref (info);
180 	} else {
181 		file_undo_manager_clear (self);
182 	}
183 
184 	g_signal_emit (self, signals[SIGNAL_UNDO_CHANGED], 0);
185 }
186 
187 static void
188 do_undo_redo (NautilusFileUndoManager *self,
189 	      GtkWindow *parent_window)
190 {
191 	gboolean undo = self->priv->state == NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO;
192 
193 	self->priv->last_state = self->priv->state;
194 	
195 	nautilus_file_undo_manager_push_flag ();
196 	nautilus_file_undo_info_apply_async (self->priv->info, undo, parent_window,
197 					     undo_info_apply_ready, self);
198 
199 	/* clear actions while undoing */
200 	file_undo_manager_clear (self);
201 	g_signal_emit (self, signals[SIGNAL_UNDO_CHANGED], 0);
202 }
203 
204 void
205 nautilus_file_undo_manager_redo (GtkWindow *parent_window)
206 {
207 	NautilusFileUndoManager *self = get_singleton ();
208 
209 	if (self->priv->state != NAUTILUS_FILE_UNDO_MANAGER_STATE_REDO) {
210 		g_warning ("Called redo, but state is %s!", self->priv->state == 0 ?
211 			   "none" : "undo");
212 		return;
213 	}
214 
215 	do_undo_redo (self, parent_window);
216 }
217 
218 void
219 nautilus_file_undo_manager_undo (GtkWindow *parent_window)
220 {
221 	NautilusFileUndoManager *self = get_singleton ();
222 
223 	if (self->priv->state != NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO) {
224 		g_warning ("Called undo, but state is %s!", self->priv->state == 0 ?
225 			   "none" : "redo");
226 		return;
227 	}
228 
229 	do_undo_redo (self, parent_window);
230 }
231 
232 void
233 nautilus_file_undo_manager_set_action (NautilusFileUndoInfo *info)
234 {
235 	NautilusFileUndoManager *self = get_singleton ();
236 
237 	DEBUG ("Setting undo information %p", info);
238 
239 	file_undo_manager_clear (self);
240 
241 	if (info != NULL) {
242 		self->priv->info = g_object_ref (info);
243 		self->priv->state = NAUTILUS_FILE_UNDO_MANAGER_STATE_UNDO;
244 		self->priv->last_state = NAUTILUS_FILE_UNDO_MANAGER_STATE_NONE;
245 	}
246 
247 	g_signal_emit (self, signals[SIGNAL_UNDO_CHANGED], 0);
248 }
249 
250 NautilusFileUndoInfo *
251 nautilus_file_undo_manager_get_action (void)
252 {
253 	NautilusFileUndoManager *self = get_singleton ();
254 
255 	return self->priv->info;
256 }
257 
258 NautilusFileUndoManagerState 
259 nautilus_file_undo_manager_get_state (void)
260 {
261 	NautilusFileUndoManager *self = get_singleton ();
262 
263 	return self->priv->state;
264 }
265 
266 void
267 nautilus_file_undo_manager_push_flag ()
268 {
269 	NautilusFileUndoManager *self = get_singleton ();
270 	NautilusFileUndoManagerPrivate *priv = self->priv;
271 
272 	priv->undo_redo_flag = TRUE;
273 }
274 
275 gboolean
276 nautilus_file_undo_manager_pop_flag ()
277 {
278 	NautilusFileUndoManager *self = get_singleton ();
279 	NautilusFileUndoManagerPrivate *priv = self->priv;
280 	gboolean retval = FALSE;
281 
282 	if (priv->undo_redo_flag) {
283 		retval = TRUE;
284 	}
285 
286 	priv->undo_redo_flag = FALSE;
287 	return retval;
288 }
289 
290 NautilusFileUndoManager *
291 nautilus_file_undo_manager_get ()
292 {
293 	return get_singleton ();
294 }