Updated Spanish translation
[gnome-utils.git] / logview / logview-manager.c
bloba46fe6bb4799be5d70a7fa5c4d44b42798c38e95
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- */
2 /* logview-manager.c - manager for the opened log objects
4 * Copyright (C) 2008 Cosimo Cecchi <cosimoc@gnome.org>
6 * This program 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.
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.
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., 551 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 * USA.
22 /* logview-manager.c */
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include "logview-manager.h"
30 #include <glib/gi18n.h>
32 #include "logview-prefs.h"
33 #include "logview-marshal.h"
34 #include "logview-app.h"
36 enum {
37 LOG_ADDED,
38 LOG_CLOSED,
39 ACTIVE_CHANGED,
40 LAST_SIGNAL
43 typedef struct {
44 LogviewManager *manager;
45 gboolean set_active;
46 gboolean is_multiple;
47 GFile *file;
48 } CreateCBData;
50 typedef struct {
51 int total;
52 int current;
53 GPtrArray *errors;
54 } MultipleCreation;
56 struct _LogviewManagerPrivate {
57 GHashTable *logs;
58 LogviewLog *active_log;
61 static LogviewManager *singleton = NULL;
62 static MultipleCreation *op = NULL;
63 static guint signals[LAST_SIGNAL] = { 0 };
65 G_DEFINE_TYPE (LogviewManager, logview_manager, G_TYPE_OBJECT);
67 #define GET_PRIVATE(o) \
68 (G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGVIEW_TYPE_MANAGER, LogviewManagerPrivate))
70 static void
71 logview_manager_finalize (GObject *object)
73 LogviewManager *manager;
75 manager = LOGVIEW_MANAGER (object);
77 if (manager->priv->active_log) {
78 g_object_unref (manager->priv->active_log);
81 g_hash_table_destroy (manager->priv->logs);
83 G_OBJECT_CLASS (logview_manager_parent_class)->finalize (object);
86 static void
87 logview_manager_class_init (LogviewManagerClass *klass)
89 GObjectClass *object_class = G_OBJECT_CLASS (klass);
91 object_class->finalize = logview_manager_finalize;
93 signals[LOG_ADDED] = g_signal_new ("log-added",
94 G_OBJECT_CLASS_TYPE (object_class),
95 G_SIGNAL_RUN_LAST,
96 G_STRUCT_OFFSET (LogviewManagerClass, log_added),
97 NULL, NULL,
98 g_cclosure_marshal_VOID__OBJECT,
99 G_TYPE_NONE, 1,
100 LOGVIEW_TYPE_LOG);
102 signals[LOG_CLOSED] = g_signal_new ("log-closed",
103 G_OBJECT_CLASS_TYPE (object_class),
104 G_SIGNAL_RUN_LAST,
105 G_STRUCT_OFFSET (LogviewManagerClass, log_closed),
106 NULL, NULL,
107 g_cclosure_marshal_VOID__OBJECT,
108 G_TYPE_NONE, 1,
109 LOGVIEW_TYPE_LOG);
111 signals[ACTIVE_CHANGED] = g_signal_new ("active-changed",
112 G_OBJECT_CLASS_TYPE (object_class),
113 G_SIGNAL_RUN_LAST,
114 G_STRUCT_OFFSET (LogviewManagerClass, active_changed),
115 NULL, NULL,
116 logview_marshal_VOID__OBJECT_OBJECT,
117 G_TYPE_NONE, 2,
118 LOGVIEW_TYPE_LOG,
119 LOGVIEW_TYPE_LOG);
121 g_type_class_add_private (klass, sizeof (LogviewManagerPrivate));
124 static void
125 logview_manager_init (LogviewManager *self)
127 LogviewManagerPrivate *priv = self->priv = GET_PRIVATE (self);
129 priv->active_log = NULL;
130 priv->logs = g_hash_table_new_full (g_str_hash, g_str_equal,
131 (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
134 static MultipleCreation *
135 multiple_creation_op_new (int total)
137 MultipleCreation *retval;
139 retval = g_slice_new0 (MultipleCreation);
140 retval->total = total;
141 retval->current = 0;
142 retval->errors = g_ptr_array_new ();
144 return retval;
147 static void
148 multiple_creation_op_free (MultipleCreation *mc)
150 g_ptr_array_foreach (mc->errors, (GFunc) g_strfreev, NULL);
151 g_ptr_array_free (mc->errors, TRUE);
153 g_slice_free (MultipleCreation, mc);
156 static void
157 create_log_cb (LogviewLog *log,
158 GError *error,
159 gpointer user_data)
161 CreateCBData *data = user_data;
163 if (log) {
164 char *log_uri;
165 LogviewPrefs *prefs;
166 GFile *file;
168 log_uri = logview_log_get_uri (log);
170 /* creation went well, store the log and notify */
171 g_hash_table_insert (data->manager->priv->logs,
172 log_uri, log);
174 prefs = logview_prefs_get ();
175 file = logview_log_get_gfile (log);
176 logview_prefs_store_log (prefs, file);
178 g_object_unref (file);
180 g_signal_emit (data->manager, signals[LOG_ADDED], 0, log, NULL);
182 if (data->set_active) {
183 logview_manager_set_active_log (data->manager, log);
185 } else {
186 char *path;
188 /* notify the error */
189 path = g_file_get_path (data->file);
191 if (!data->is_multiple) {
192 logview_app_add_error (logview_app_get (),
193 path, error->message);
194 } else {
195 char **error_arr = g_new0 (char *, 3);
197 error_arr[0] = g_strdup (path);
198 error_arr[1] = g_strdup (error->message);
199 error_arr[2] = NULL;
201 g_ptr_array_add (op->errors, error_arr);
204 g_free (path);
207 if (data->is_multiple) {
208 op->current++;
210 if (op->total == op->current) {
211 logview_app_add_errors (logview_app_get (), op->errors);
212 multiple_creation_op_free (op);
213 op = NULL;
217 g_object_unref (data->file);
218 g_slice_free (CreateCBData, data);
221 static void
222 add_log_from_gfile_internal (LogviewManager *manager,
223 GFile *file,
224 gboolean set_active,
225 gboolean is_multiple)
227 char *file_uri;
228 LogviewLog *log;
229 CreateCBData *data;
231 file_uri = g_file_get_uri (file);
233 if (set_active == FALSE) {
234 /* if it's the first log being added, set it as active anyway */
235 set_active = (manager->priv->logs == NULL);
238 if ((log = g_hash_table_lookup (manager->priv->logs, file_uri)) != NULL) {
239 /* log already exists, don't load it */
240 if (set_active) {
241 logview_manager_set_active_log (manager, log);
243 } else {
244 data = g_slice_new0 (CreateCBData);
245 data->manager = manager;
246 data->set_active = set_active;
247 data->is_multiple = is_multiple;
248 data->file = g_object_ref (file);
250 logview_log_create_from_gfile (file, create_log_cb, data);
253 g_free (file_uri);
256 static void
257 logview_manager_add_log_from_name (LogviewManager *manager,
258 const char *filename, gboolean set_active,
259 gboolean is_multiple)
261 GFile *file;
263 file = g_file_new_for_path (filename);
265 add_log_from_gfile_internal (manager, file, set_active, is_multiple);
267 g_object_unref (file);
270 /* public methods */
272 LogviewManager*
273 logview_manager_get (void)
275 if (!singleton) {
276 singleton = g_object_new (LOGVIEW_TYPE_MANAGER, NULL);
279 return singleton;
282 void
283 logview_manager_set_active_log (LogviewManager *manager,
284 LogviewLog *log)
286 LogviewLog *old_log = NULL;
288 g_assert (LOGVIEW_IS_MANAGER (manager));
290 if (manager->priv->active_log) {
291 old_log = manager->priv->active_log;
294 manager->priv->active_log = g_object_ref (log);
296 g_signal_emit (manager, signals[ACTIVE_CHANGED], 0, log, old_log, NULL);
298 if (old_log) {
299 g_object_unref (old_log);
303 LogviewLog *
304 logview_manager_get_active_log (LogviewManager *manager)
306 g_assert (LOGVIEW_IS_MANAGER (manager));
308 return (manager->priv->active_log != NULL) ?
309 g_object_ref (manager->priv->active_log) :
310 NULL;
313 void
314 logview_manager_add_log_from_gfile (LogviewManager *manager,
315 GFile *file,
316 gboolean set_active)
318 g_assert (LOGVIEW_IS_MANAGER (manager));
320 add_log_from_gfile_internal (manager, file, set_active, FALSE);
323 void
324 logview_manager_add_logs_from_name_list (LogviewManager *manager,
325 GSList *names,
326 const char *active)
328 GSList *l;
330 g_assert (LOGVIEW_IS_MANAGER (manager));
331 g_assert (op == NULL);
333 op = multiple_creation_op_new (g_slist_length (names));
335 for (l = names; l; l = l->next) {
336 logview_manager_add_log_from_name (manager, l->data,
337 (g_ascii_strcasecmp (active, l->data) == 0),
338 TRUE);
342 void
343 logview_manager_add_logs_from_names (LogviewManager *manager,
344 char ** names,
345 const gchar *active)
347 int i;
348 gboolean set_active;
350 g_assert (LOGVIEW_IS_MANAGER (manager));
351 g_assert (op == NULL);
353 op = multiple_creation_op_new (g_strv_length (names));
355 for (i = 0; names[i]; i++) {
356 set_active = (active != NULL) && (g_ascii_strcasecmp (active, names[i]));
357 logview_manager_add_log_from_name (manager, names[i], set_active,
358 TRUE);
363 logview_manager_get_log_count (LogviewManager *manager)
365 g_assert (LOGVIEW_IS_MANAGER (manager));
367 return g_hash_table_size (manager->priv->logs);
370 LogviewLog *
371 logview_manager_get_if_loaded (LogviewManager *manager, char *uri)
373 LogviewLog *log;
375 g_assert (LOGVIEW_IS_MANAGER (manager));
377 log = g_hash_table_lookup (manager->priv->logs, uri);
379 if (log != NULL) {
380 return g_object_ref (log);
383 return NULL;
386 void
387 logview_manager_close_active_log (LogviewManager *manager)
389 LogviewLog *active_log;
390 char *log_uri;
391 GFile *file;
393 g_assert (LOGVIEW_IS_MANAGER (manager));
395 active_log = manager->priv->active_log;
396 log_uri = logview_log_get_uri (active_log);
397 file = logview_log_get_gfile (active_log);
399 g_signal_emit (manager, signals[LOG_CLOSED], 0, active_log, NULL);
401 logview_prefs_remove_stored_log (logview_prefs_get (), file);
403 g_object_unref (file);
405 /* we own two refs to the active log; one is inside the hash table */
406 g_object_unref (active_log);
407 g_hash_table_remove (manager->priv->logs, log_uri);
409 g_free (log_uri);
411 /* someone else will take care of setting the next active log to us */
414 gboolean
415 logview_manager_log_is_active (LogviewManager *manager,
416 LogviewLog *log)
418 g_assert (LOGVIEW_IS_MANAGER (manager));
420 return (manager->priv->active_log == log);