1 /*
2  * nautilus-progress-info-widget.h: file operation progress user interface.
3  *
4  * Copyright (C) 2007, 2011 Red Hat, Inc.
5  *
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.
10  *
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 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; if not, see <http://www.gnu.org/licenses/>.
18  *
19  * Authors: Alexander Larsson <alexl@redhat.com>
20  *          Cosimo Cecchi <cosimoc@redhat.com>
21  *
22  */
23 
24 #include <config.h>
25 
26 #include "nautilus-progress-info-widget.h"
27 struct _NautilusProgressInfoWidgetPrivate
28 {
29     NautilusProgressInfo *info;
30 
31     GtkWidget *status;     /* GtkLabel */
32     GtkWidget *details;     /* GtkLabel */
33     GtkWidget *progress_bar;
34     GtkWidget *button;
35     GtkWidget *done_image;
36 };
37 
38 enum
39 {
40     PROP_INFO = 1,
41     NUM_PROPERTIES
42 };
43 
44 static GParamSpec *properties[NUM_PROPERTIES] = { NULL };
45 
46 G_DEFINE_TYPE_WITH_PRIVATE (NautilusProgressInfoWidget, nautilus_progress_info_widget,
47                             GTK_TYPE_GRID);
48 
49 static void
info_finished(NautilusProgressInfoWidget * self)50 info_finished (NautilusProgressInfoWidget *self)
51 {
52     gtk_button_set_image (GTK_BUTTON (self->priv->button), self->priv->done_image);
53     gtk_widget_set_sensitive (self->priv->button, FALSE);
54 }
55 
56 static void
info_cancelled(NautilusProgressInfoWidget * self)57 info_cancelled (NautilusProgressInfoWidget *self)
58 {
59     gtk_widget_set_sensitive (self->priv->button, FALSE);
60 }
61 
62 static void
update_data(NautilusProgressInfoWidget * self)63 update_data (NautilusProgressInfoWidget *self)
64 {
65     char *status, *details;
66     char *markup;
67 
68     status = nautilus_progress_info_get_status (self->priv->info);
69     gtk_label_set_text (GTK_LABEL (self->priv->status), status);
70     g_free (status);
71 
72     details = nautilus_progress_info_get_details (self->priv->info);
73     markup = g_markup_printf_escaped ("<span size='small'>%s</span>", details);
74     gtk_label_set_markup (GTK_LABEL (self->priv->details), markup);
75     g_free (details);
76     g_free (markup);
77 }
78 
79 static void
update_progress(NautilusProgressInfoWidget * self)80 update_progress (NautilusProgressInfoWidget *self)
81 {
82     double progress;
83 
84     progress = nautilus_progress_info_get_progress (self->priv->info);
85     if (progress < 0)
86     {
87         gtk_progress_bar_pulse (GTK_PROGRESS_BAR (self->priv->progress_bar));
88     }
89     else
90     {
91         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (self->priv->progress_bar), progress);
92     }
93 }
94 
95 static void
button_clicked(GtkWidget * button,NautilusProgressInfoWidget * self)96 button_clicked (GtkWidget                  *button,
97                 NautilusProgressInfoWidget *self)
98 {
99     if (!nautilus_progress_info_get_is_finished (self->priv->info))
100     {
101         nautilus_progress_info_cancel (self->priv->info);
102     }
103 }
104 
105 static void
nautilus_progress_info_widget_dispose(GObject * obj)106 nautilus_progress_info_widget_dispose (GObject *obj)
107 {
108     NautilusProgressInfoWidget *self = NAUTILUS_PROGRESS_INFO_WIDGET (obj);
109 
110     if (self->priv->info != NULL)
111     {
112         g_signal_handlers_disconnect_by_data (self->priv->info, self);
113     }
114     g_clear_object (&self->priv->info);
115 
116     G_OBJECT_CLASS (nautilus_progress_info_widget_parent_class)->dispose (obj);
117 }
118 
119 static void
nautilus_progress_info_widget_constructed(GObject * obj)120 nautilus_progress_info_widget_constructed (GObject *obj)
121 {
122     NautilusProgressInfoWidget *self = NAUTILUS_PROGRESS_INFO_WIDGET (obj);
123 
124     G_OBJECT_CLASS (nautilus_progress_info_widget_parent_class)->constructed (obj);
125 
126     if (nautilus_progress_info_get_is_finished (self->priv->info))
127     {
128         gtk_button_set_image (GTK_BUTTON (self->priv->button), self->priv->done_image);
129     }
130 
131     gtk_widget_set_sensitive (self->priv->button,
132                               !nautilus_progress_info_get_is_finished (self->priv->info) &&
133                               !nautilus_progress_info_get_is_cancelled (self->priv->info));
134 
135     g_signal_connect_swapped (self->priv->info,
136                               "changed",
137                               G_CALLBACK (update_data), self);
138     g_signal_connect_swapped (self->priv->info,
139                               "progress-changed",
140                               G_CALLBACK (update_progress), self);
141     g_signal_connect_swapped (self->priv->info,
142                               "finished",
143                               G_CALLBACK (info_finished), self);
144     g_signal_connect_swapped (self->priv->info,
145                               "cancelled",
146                               G_CALLBACK (info_cancelled), self);
147 
148     update_data (self);
149     update_progress (self);
150 }
151 
152 static void
nautilus_progress_info_widget_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)153 nautilus_progress_info_widget_set_property (GObject      *object,
154                                             guint         property_id,
155                                             const GValue *value,
156                                             GParamSpec   *pspec)
157 {
158     NautilusProgressInfoWidget *self = NAUTILUS_PROGRESS_INFO_WIDGET (object);
159 
160     switch (property_id)
161     {
162         case PROP_INFO:
163         {
164             self->priv->info = g_value_dup_object (value);
165         }
166         break;
167 
168         default:
169         {
170             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
171         }
172         break;
173     }
174 }
175 
176 static void
nautilus_progress_info_widget_init(NautilusProgressInfoWidget * self)177 nautilus_progress_info_widget_init (NautilusProgressInfoWidget *self)
178 {
179     self->priv = nautilus_progress_info_widget_get_instance_private (self);
180 
181     gtk_widget_init_template (GTK_WIDGET (self));
182 
183     g_signal_connect (self->priv->button, "clicked",
184                       G_CALLBACK (button_clicked), self);
185 }
186 
187 static void
nautilus_progress_info_widget_class_init(NautilusProgressInfoWidgetClass * klass)188 nautilus_progress_info_widget_class_init (NautilusProgressInfoWidgetClass *klass)
189 {
190     GObjectClass *oclass;
191     GtkWidgetClass *widget_class;
192 
193     widget_class = GTK_WIDGET_CLASS (klass);
194     oclass = G_OBJECT_CLASS (klass);
195     oclass->set_property = nautilus_progress_info_widget_set_property;
196     oclass->constructed = nautilus_progress_info_widget_constructed;
197     oclass->dispose = nautilus_progress_info_widget_dispose;
198 
199     properties[PROP_INFO] =
200         g_param_spec_object ("info",
201                              "NautilusProgressInfo",
202                              "The NautilusProgressInfo associated with this widget",
203                              NAUTILUS_TYPE_PROGRESS_INFO,
204                              G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
205                              G_PARAM_STATIC_STRINGS);
206 
207     g_object_class_install_properties (oclass, NUM_PROPERTIES, properties);
208 
209     gtk_widget_class_set_template_from_resource (widget_class,
210                                                  "/org/gnome/nautilus/ui/nautilus-progress-info-widget.ui");
211 
212     gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, status);
213     gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, details);
214     gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, progress_bar);
215     gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, button);
216     gtk_widget_class_bind_template_child_private (widget_class, NautilusProgressInfoWidget, done_image);
217 }
218 
219 GtkWidget *
nautilus_progress_info_widget_new(NautilusProgressInfo * info)220 nautilus_progress_info_widget_new (NautilusProgressInfo *info)
221 {
222     return g_object_new (NAUTILUS_TYPE_PROGRESS_INFO_WIDGET,
223                          "info", info,
224                          NULL);
225 }
226