/* * Nautilus * * Copyright (C) 2011 Red Hat, Inc. * * Nautilus is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * Nautilus is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; see the file COPYING. If not, * see . * * Author: Cosimo Cecchi */ #include #include "nautilus-progress-info-manager.h" struct _NautilusProgressInfoManagerPriv { GList *progress_infos; GList *current_viewers; }; enum { NEW_PROGRESS_INFO, HAS_VIEWERS_CHANGED, LAST_SIGNAL }; static NautilusProgressInfoManager *singleton = NULL; static guint signals[LAST_SIGNAL] = { 0, }; G_DEFINE_TYPE (NautilusProgressInfoManager, nautilus_progress_info_manager, G_TYPE_OBJECT); static void remove_viewer (NautilusProgressInfoManager *self, GObject *viewer); static void nautilus_progress_info_manager_finalize (GObject *obj) { GList *l; NautilusProgressInfoManager *self = NAUTILUS_PROGRESS_INFO_MANAGER (obj); if (self->priv->progress_infos != NULL) { g_list_free_full (self->priv->progress_infos, g_object_unref); } for (l = self->priv->current_viewers; l != NULL; l = l->next) { g_object_weak_unref (l->data, (GWeakNotify) remove_viewer, self); } g_list_free (self->priv->current_viewers); G_OBJECT_CLASS (nautilus_progress_info_manager_parent_class)->finalize (obj); } static GObject * nautilus_progress_info_manager_constructor (GType type, guint n_props, GObjectConstructParam *props) { GObject *retval; if (singleton != NULL) { return g_object_ref (singleton); } retval = G_OBJECT_CLASS (nautilus_progress_info_manager_parent_class)->constructor (type, n_props, props); singleton = NAUTILUS_PROGRESS_INFO_MANAGER (retval); g_object_add_weak_pointer (retval, (gpointer) & singleton); return retval; } static void nautilus_progress_info_manager_init (NautilusProgressInfoManager *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NAUTILUS_TYPE_PROGRESS_INFO_MANAGER, NautilusProgressInfoManagerPriv); } static void nautilus_progress_info_manager_class_init (NautilusProgressInfoManagerClass *klass) { GObjectClass *oclass; oclass = G_OBJECT_CLASS (klass); oclass->constructor = nautilus_progress_info_manager_constructor; oclass->finalize = nautilus_progress_info_manager_finalize; signals[NEW_PROGRESS_INFO] = g_signal_new ("new-progress-info", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, NAUTILUS_TYPE_PROGRESS_INFO); signals[HAS_VIEWERS_CHANGED] = g_signal_new ("has-viewers-changed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); g_type_class_add_private (klass, sizeof (NautilusProgressInfoManagerPriv)); } NautilusProgressInfoManager * nautilus_progress_info_manager_dup_singleton (void) { return g_object_new (NAUTILUS_TYPE_PROGRESS_INFO_MANAGER, NULL); } void nautilus_progress_info_manager_add_new_info (NautilusProgressInfoManager *self, NautilusProgressInfo *info) { if (g_list_find (self->priv->progress_infos, info) != NULL) { g_warning ("Adding two times the same progress info object to the manager"); return; } self->priv->progress_infos = g_list_prepend (self->priv->progress_infos, g_object_ref (info)); g_signal_emit (self, signals[NEW_PROGRESS_INFO], 0, info); } void nautilus_progress_info_manager_remove_finished_or_cancelled_infos (NautilusProgressInfoManager *self) { GList *l; GList *next; l = self->priv->progress_infos; while (l != NULL) { next = l->next; if (nautilus_progress_info_get_is_finished (l->data) || nautilus_progress_info_get_is_cancelled (l->data)) { self->priv->progress_infos = g_list_remove (self->priv->progress_infos, l->data); } l = next; } } GList * nautilus_progress_info_manager_get_all_infos (NautilusProgressInfoManager *self) { return self->priv->progress_infos; } gboolean nautilus_progress_manager_are_all_infos_finished_or_cancelled (NautilusProgressInfoManager *self) { GList *l; for (l = self->priv->progress_infos; l != NULL; l = l->next) { if (!(nautilus_progress_info_get_is_finished (l->data) || nautilus_progress_info_get_is_cancelled (l->data))) { return FALSE; } } return TRUE; } static void remove_viewer (NautilusProgressInfoManager *self, GObject *viewer) { self->priv->current_viewers = g_list_remove (self->priv->current_viewers, viewer); if (self->priv->current_viewers == NULL) { g_signal_emit (self, signals[HAS_VIEWERS_CHANGED], 0); } } void nautilus_progress_manager_add_viewer (NautilusProgressInfoManager *self, GObject *viewer) { GList *viewers; viewers = self->priv->current_viewers; if (g_list_find (viewers, viewer) == NULL) { g_object_weak_ref (viewer, (GWeakNotify) remove_viewer, self); viewers = g_list_append (viewers, viewer); self->priv->current_viewers = viewers; if (g_list_length (viewers) == 1) { g_signal_emit (self, signals[HAS_VIEWERS_CHANGED], 0); } } } void nautilus_progress_manager_remove_viewer (NautilusProgressInfoManager *self, GObject *viewer) { if (g_list_find (self->priv->current_viewers, viewer) != NULL) { g_object_weak_unref (viewer, (GWeakNotify) remove_viewer, self); remove_viewer (self, viewer); } } gboolean nautilus_progress_manager_has_viewers (NautilusProgressInfoManager *self) { return self->priv->current_viewers != NULL; }