1 /*
2 * xed-tab-label.c
3 * This file is part of xed
4 *
5 * Copyright (C) 2010 - Paolo Borelli
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 */
22
23 #include <config.h>
24 #include <glib/gi18n.h>
25 #include <gtk/gtk.h>
26
27 #include "xed-tab-label.h"
28 #include "xed-close-button.h"
29
30 /* Signals */
31 enum
32 {
33 CLOSE_CLICKED,
34 LAST_SIGNAL
35 };
36
37 enum
38 {
39 PROP_0,
40 PROP_TAB
41 };
42
43 struct _XedTabLabelPrivate
44 {
45 XedTab *tab;
46
47 GtkWidget *label_box;
48 GtkWidget *close_button;
49 GtkWidget *spinner;
50 GtkWidget *icon;
51 GtkWidget *label;
52
53 gboolean close_button_sensitive;
54 };
55
56 static guint signals[LAST_SIGNAL] = { 0 };
57
G_DEFINE_TYPE_WITH_PRIVATE(XedTabLabel,xed_tab_label,GTK_TYPE_BOX)58 G_DEFINE_TYPE_WITH_PRIVATE (XedTabLabel, xed_tab_label, GTK_TYPE_BOX)
59
60 static void
61 xed_tab_label_finalize (GObject *object)
62 {
63 G_OBJECT_CLASS (xed_tab_label_parent_class)->finalize (object);
64 }
65
66 static void
xed_tab_label_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)67 xed_tab_label_set_property (GObject *object,
68 guint prop_id,
69 const GValue *value,
70 GParamSpec *pspec)
71 {
72 XedTabLabel *tab_label = XED_TAB_LABEL (object);
73
74 switch (prop_id)
75 {
76 case PROP_TAB:
77 tab_label->priv->tab = XED_TAB (g_value_get_object (value));
78 break;
79
80 default:
81 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
82 break;
83 }
84 }
85
86 static void
xed_tab_label_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)87 xed_tab_label_get_property (GObject *object,
88 guint prop_id,
89 GValue *value,
90 GParamSpec *pspec)
91 {
92 XedTabLabel *tab_label = XED_TAB_LABEL (object);
93
94 switch (prop_id)
95 {
96 case PROP_TAB:
97 g_value_set_object (value, tab_label->priv->tab);
98 break;
99
100 default:
101 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
102 break;
103 }
104 }
105
106 static void
close_button_clicked_cb(GtkWidget * widget,XedTabLabel * tab_label)107 close_button_clicked_cb (GtkWidget *widget,
108 XedTabLabel *tab_label)
109 {
110 g_signal_emit (tab_label, signals[CLOSE_CLICKED], 0, NULL);
111 }
112
113 static void
sync_tip(XedTab * tab,XedTabLabel * tab_label)114 sync_tip (XedTab *tab,
115 XedTabLabel *tab_label)
116 {
117 gchar *str;
118
119 str = _xed_tab_get_tooltips (tab);
120 g_return_if_fail (str != NULL);
121
122 gtk_widget_set_tooltip_markup (tab_label->priv->label_box, str);
123 g_free (str);
124 }
125
126 static void
sync_name(XedTab * tab,GParamSpec * pspec,XedTabLabel * tab_label)127 sync_name (XedTab *tab,
128 GParamSpec *pspec,
129 XedTabLabel *tab_label)
130 {
131 gchar *str;
132
133 g_return_if_fail (tab == tab_label->priv->tab);
134
135 str = _xed_tab_get_name (tab);
136 g_return_if_fail (str != NULL);
137
138 gtk_label_set_text (GTK_LABEL (tab_label->priv->label), str);
139 g_free (str);
140
141 sync_tip (tab, tab_label);
142 }
143
144 static void
sync_state(XedTab * tab,GParamSpec * pspec,XedTabLabel * tab_label)145 sync_state (XedTab *tab,
146 GParamSpec *pspec,
147 XedTabLabel *tab_label)
148 {
149 XedTabState state;
150
151 g_return_if_fail (tab == tab_label->priv->tab);
152
153 state = xed_tab_get_state (tab);
154
155 gtk_widget_set_sensitive (tab_label->priv->close_button,
156 tab_label->priv->close_button_sensitive &&
157 (state != XED_TAB_STATE_CLOSING) &&
158 (state != XED_TAB_STATE_SAVING) &&
159 (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) &&
160 (state != XED_TAB_STATE_SAVING_ERROR));
161
162 if ((state == XED_TAB_STATE_LOADING) ||
163 (state == XED_TAB_STATE_SAVING) ||
164 (state == XED_TAB_STATE_REVERTING))
165 {
166 gtk_widget_hide (tab_label->priv->icon);
167
168 gtk_widget_show (tab_label->priv->spinner);
169 gtk_spinner_start (GTK_SPINNER (tab_label->priv->spinner));
170 }
171 else
172 {
173 GdkPixbuf *pixbuf;
174
175 pixbuf = _xed_tab_get_icon (tab);
176
177 if (pixbuf != NULL)
178 {
179 gtk_image_set_from_pixbuf (GTK_IMAGE (tab_label->priv->icon), pixbuf);
180 g_clear_object (&pixbuf);
181 gtk_widget_show (tab_label->priv->icon);
182 }
183 else
184 {
185 gtk_widget_hide (tab_label->priv->icon);
186 }
187
188 gtk_widget_hide (tab_label->priv->spinner);
189 gtk_spinner_stop (GTK_SPINNER (tab_label->priv->spinner));
190 }
191
192 /* sync tip since encoding is known only after load/save end */
193 sync_tip (tab, tab_label);
194 }
195
196 static void
xed_tab_label_constructed(GObject * object)197 xed_tab_label_constructed (GObject *object)
198 {
199 XedTabLabel *tab_label = XED_TAB_LABEL (object);
200
201 if (!tab_label->priv->tab)
202 {
203 g_critical ("The tab label was not properly constructed");
204 return;
205 }
206
207 sync_name (tab_label->priv->tab, NULL, tab_label);
208 sync_state (tab_label->priv->tab, NULL, tab_label);
209
210 g_signal_connect_object (tab_label->priv->tab, "notify::name",
211 G_CALLBACK (sync_name), tab_label, 0);
212
213 g_signal_connect_object (tab_label->priv->tab, "notify::state",
214 G_CALLBACK (sync_state), tab_label, 0);
215 }
216
217 static void
xed_tab_label_class_init(XedTabLabelClass * klass)218 xed_tab_label_class_init (XedTabLabelClass *klass)
219 {
220 GObjectClass *object_class = G_OBJECT_CLASS (klass);
221
222 object_class->finalize = xed_tab_label_finalize;
223 object_class->set_property = xed_tab_label_set_property;
224 object_class->get_property = xed_tab_label_get_property;
225 object_class->constructed = xed_tab_label_constructed;
226
227 signals[CLOSE_CLICKED] =
228 g_signal_new ("close-clicked",
229 G_OBJECT_CLASS_TYPE (object_class),
230 G_SIGNAL_RUN_LAST,
231 G_STRUCT_OFFSET (XedTabLabelClass, close_clicked),
232 NULL, NULL,
233 g_cclosure_marshal_VOID__VOID,
234 G_TYPE_NONE,
235 0);
236
237 g_object_class_install_property (object_class,
238 PROP_TAB,
239 g_param_spec_object ("tab",
240 "Tab",
241 "The XedTab",
242 XED_TYPE_TAB,
243 G_PARAM_READWRITE |
244 G_PARAM_CONSTRUCT_ONLY));
245 }
246
247 static void
xed_tab_label_init(XedTabLabel * tab_label)248 xed_tab_label_init (XedTabLabel *tab_label)
249 {
250 GtkWidget *hbox;
251 GtkWidget *close_button;
252 GtkWidget *spinner;
253 GtkWidget *icon;
254 GtkWidget *label;
255 GtkWidget *dummy_label;
256
257 tab_label->priv = xed_tab_label_get_instance_private (tab_label);
258
259 tab_label->priv->close_button_sensitive = TRUE;
260
261 gtk_orientable_set_orientation (GTK_ORIENTABLE (tab_label), GTK_ORIENTATION_HORIZONTAL);
262
263 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
264 gtk_box_pack_start (GTK_BOX (tab_label), hbox, TRUE, TRUE, 0);
265
266 close_button = xed_close_button_new ();
267 gtk_widget_set_tooltip_text (close_button, _("Close document"));
268 gtk_box_pack_start (GTK_BOX (tab_label), close_button, FALSE, FALSE, 0);
269 tab_label->priv->close_button = close_button;
270
271 g_signal_connect (close_button, "clicked",
272 G_CALLBACK (close_button_clicked_cb), tab_label);
273
274 spinner = gtk_spinner_new ();
275 gtk_box_pack_start (GTK_BOX (hbox), spinner, FALSE, FALSE, 0);
276 tab_label->priv->spinner = spinner;
277
278 /* setup icon, empty by default */
279 icon = gtk_image_new ();
280 gtk_box_pack_start (GTK_BOX (hbox), icon, FALSE, FALSE, 0);
281 tab_label->priv->icon = icon;
282
283 label = gtk_label_new ("");
284
285 tab_label->priv->label_box = hbox;
286
287 gtk_widget_set_halign (label, GTK_ALIGN_START);
288 gtk_widget_set_margin_start (label, 0);
289 gtk_widget_set_margin_end (label, 0);
290 gtk_widget_set_margin_top (label, 0);
291 gtk_widget_set_margin_bottom (label, 0);
292
293 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
294 tab_label->priv->label = label;
295
296 dummy_label = gtk_label_new ("");
297 gtk_box_pack_start (GTK_BOX (hbox), dummy_label, TRUE, TRUE, 0);
298
299 gtk_widget_show (hbox);
300 gtk_widget_show (close_button);
301 gtk_widget_show (icon);
302 gtk_widget_show (label);
303 gtk_widget_show (dummy_label);
304 }
305
306 void
xed_tab_label_set_close_button_sensitive(XedTabLabel * tab_label,gboolean sensitive)307 xed_tab_label_set_close_button_sensitive (XedTabLabel *tab_label,
308 gboolean sensitive)
309 {
310 XedTabState state;
311
312 g_return_if_fail (XED_IS_TAB_LABEL (tab_label));
313
314 sensitive = (sensitive != FALSE);
315
316 if (sensitive == tab_label->priv->close_button_sensitive)
317 {
318 return;
319 }
320
321 tab_label->priv->close_button_sensitive = sensitive;
322
323 state = xed_tab_get_state (tab_label->priv->tab);
324
325 gtk_widget_set_sensitive (tab_label->priv->close_button,
326 tab_label->priv->close_button_sensitive &&
327 (state != XED_TAB_STATE_CLOSING) &&
328 (state != XED_TAB_STATE_SAVING) &&
329 (state != XED_TAB_STATE_SHOWING_PRINT_PREVIEW) &&
330 (state != XED_TAB_STATE_PRINTING) &&
331 (state != XED_TAB_STATE_PRINT_PREVIEWING) &&
332 (state != XED_TAB_STATE_SAVING_ERROR));
333 }
334
335 XedTab *
xed_tab_label_get_tab(XedTabLabel * tab_label)336 xed_tab_label_get_tab (XedTabLabel *tab_label)
337 {
338 g_return_val_if_fail (XED_IS_TAB_LABEL (tab_label), NULL);
339
340 return tab_label->priv->tab;
341 }
342
343 GtkWidget *
xed_tab_label_new(XedTab * tab)344 xed_tab_label_new (XedTab *tab)
345 {
346 XedTabLabel *tab_label;
347
348 tab_label = g_object_new (XED_TYPE_TAB_LABEL,
349 "homogeneous", FALSE,
350 "tab", tab,
351 NULL);
352
353 return GTK_WIDGET (tab_label);
354 }
355