1 /*
2  * gedit-statusbar.c
3  * This file is part of gedit
4  *
5  * Copyright (C) 2005 - 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, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "config.h"
22 
23 #include "gedit-statusbar.h"
24 
25 #include <string.h>
26 #include <glib/gi18n.h>
27 #include <gtk/gtk.h>
28 
29 #include "gedit-app.h"
30 #include "gedit-status-menu-button.h"
31 
32 struct _GeditStatusbar
33 {
34 	GtkStatusbar  parent_instance;
35 
36 	GtkWidget     *error_frame;
37 	GtkWidget     *error_image;
38 	GtkWidget     *state_frame;
39 	GtkWidget     *load_image;
40 	GtkWidget     *save_image;
41 	GtkWidget     *print_image;
42 	GtkWidget     *overwrite_mode_label;
43 
44 	/* tmp flash timeout data */
45 	guint          flash_timeout;
46 	guint          flash_context_id;
47 	guint          flash_message_id;
48 };
49 
G_DEFINE_TYPE(GeditStatusbar,gedit_statusbar,GTK_TYPE_STATUSBAR)50 G_DEFINE_TYPE (GeditStatusbar, gedit_statusbar, GTK_TYPE_STATUSBAR)
51 
52 static gchar *
53 get_overwrite_mode_string (gboolean overwrite)
54 {
55 	/* Use spaces to leave padding proportional to the font size */
56 	return g_strdup_printf ("  %s  ", overwrite ? _("OVR") : _("INS"));
57 }
58 
59 static gint
get_overwrite_mode_length(void)60 get_overwrite_mode_length (void)
61 {
62 	return 4 + MAX (g_utf8_strlen (_("OVR"), -1), g_utf8_strlen (_("INS"), -1));
63 }
64 
65 static void
gedit_statusbar_dispose(GObject * object)66 gedit_statusbar_dispose (GObject *object)
67 {
68 	GeditStatusbar *statusbar = GEDIT_STATUSBAR (object);
69 
70 	if (statusbar->flash_timeout > 0)
71 	{
72 		g_source_remove (statusbar->flash_timeout);
73 		statusbar->flash_timeout = 0;
74 	}
75 
76 	G_OBJECT_CLASS (gedit_statusbar_parent_class)->dispose (object);
77 }
78 
79 static void
gedit_statusbar_class_init(GeditStatusbarClass * klass)80 gedit_statusbar_class_init (GeditStatusbarClass *klass)
81 {
82 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
83 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
84 
85 	object_class->dispose = gedit_statusbar_dispose;
86 
87 	gtk_widget_class_set_template_from_resource (widget_class,
88 		                                    "/org/gnome/gedit/ui/gedit-statusbar.ui");
89 
90 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, error_frame);
91 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, error_image);
92 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, state_frame);
93 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, load_image);
94 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, save_image);
95 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, print_image);
96 	gtk_widget_class_bind_template_child (widget_class, GeditStatusbar, overwrite_mode_label);
97 }
98 
99 static void
gedit_statusbar_init(GeditStatusbar * statusbar)100 gedit_statusbar_init (GeditStatusbar *statusbar)
101 {
102 	gtk_widget_init_template (GTK_WIDGET (statusbar));
103 
104 	gtk_label_set_width_chars (GTK_LABEL (statusbar->overwrite_mode_label),
105 	                           get_overwrite_mode_length ());
106 }
107 
108 /**
109  * gedit_statusbar_new:
110  *
111  * Creates a new #GeditStatusbar.
112  *
113  * Return value: the new #GeditStatusbar object
114  **/
115 GtkWidget *
gedit_statusbar_new(void)116 gedit_statusbar_new (void)
117 {
118 	return GTK_WIDGET (g_object_new (GEDIT_TYPE_STATUSBAR, NULL));
119 }
120 
121 /**
122  * gedit_statusbar_set_overwrite:
123  * @statusbar: a #GeditStatusbar
124  * @overwrite: if the overwrite mode is set
125  *
126  * Sets the overwrite mode on the statusbar.
127  **/
128 void
gedit_statusbar_set_overwrite(GeditStatusbar * statusbar,gboolean overwrite)129 gedit_statusbar_set_overwrite (GeditStatusbar *statusbar,
130                                gboolean        overwrite)
131 {
132 	gchar *msg;
133 
134 	g_return_if_fail (GEDIT_IS_STATUSBAR (statusbar));
135 
136 	msg = get_overwrite_mode_string (overwrite);
137 	gtk_label_set_text (GTK_LABEL (statusbar->overwrite_mode_label), msg);
138 	g_free (msg);
139 }
140 
141 void
gedit_statusbar_clear_overwrite(GeditStatusbar * statusbar)142 gedit_statusbar_clear_overwrite (GeditStatusbar *statusbar)
143 {
144 	g_return_if_fail (GEDIT_IS_STATUSBAR (statusbar));
145 
146 	gtk_label_set_text (GTK_LABEL (statusbar->overwrite_mode_label), NULL);
147 }
148 
149 static gboolean
remove_message_timeout(GeditStatusbar * statusbar)150 remove_message_timeout (GeditStatusbar *statusbar)
151 {
152 	gtk_statusbar_remove (GTK_STATUSBAR (statusbar),
153 	                      statusbar->flash_context_id,
154 	                      statusbar->flash_message_id);
155 
156 	/* remove the timeout */
157 	statusbar->flash_timeout = 0;
158   	return FALSE;
159 }
160 
161 /* FIXME this is an issue for introspection */
162 /**
163  * gedit_statusbar_flash_message:
164  * @statusbar: a #GeditStatusbar
165  * @context_id: message context_id
166  * @format: message to flash on the statusbar
167  * @...: the arguments to insert in @format
168  *
169  * Flash a temporary message on the statusbar.
170  */
171 void
gedit_statusbar_flash_message(GeditStatusbar * statusbar,guint context_id,const gchar * format,...)172 gedit_statusbar_flash_message (GeditStatusbar *statusbar,
173 			       guint           context_id,
174 			       const gchar    *format,
175 			       ...)
176 {
177 	const guint32 flash_length = 3000; /* three seconds */
178 	va_list args;
179 	gchar *msg;
180 
181 	g_return_if_fail (GEDIT_IS_STATUSBAR (statusbar));
182 	g_return_if_fail (format != NULL);
183 
184 	va_start (args, format);
185 	msg = g_strdup_vprintf (format, args);
186 	va_end (args);
187 
188 	/* remove a currently ongoing flash message */
189 	if (statusbar->flash_timeout > 0)
190 	{
191 		g_source_remove (statusbar->flash_timeout);
192 		statusbar->flash_timeout = 0;
193 
194 		gtk_statusbar_remove (GTK_STATUSBAR (statusbar),
195 		                      statusbar->flash_context_id,
196 		                      statusbar->flash_message_id);
197 	}
198 
199 	statusbar->flash_context_id = context_id;
200 	statusbar->flash_message_id = gtk_statusbar_push (GTK_STATUSBAR (statusbar),
201 							  context_id,
202 							  msg);
203 
204 	statusbar->flash_timeout = g_timeout_add (flash_length,
205 						  (GSourceFunc) remove_message_timeout,
206 						  statusbar);
207 
208 	g_free (msg);
209 }
210 
211 void
gedit_statusbar_set_window_state(GeditStatusbar * statusbar,GeditWindowState state,gint num_of_errors)212 gedit_statusbar_set_window_state (GeditStatusbar   *statusbar,
213 				  GeditWindowState  state,
214 				  gint              num_of_errors)
215 {
216 	g_return_if_fail (GEDIT_IS_STATUSBAR (statusbar));
217 
218 	gtk_widget_hide (statusbar->state_frame);
219 	gtk_widget_hide (statusbar->save_image);
220 	gtk_widget_hide (statusbar->load_image);
221 	gtk_widget_hide (statusbar->print_image);
222 
223 	if (state & GEDIT_WINDOW_STATE_SAVING)
224 	{
225 		gtk_widget_show (statusbar->state_frame);
226 		gtk_widget_show (statusbar->save_image);
227 	}
228 	if (state & GEDIT_WINDOW_STATE_LOADING)
229 	{
230 		gtk_widget_show (statusbar->state_frame);
231 		gtk_widget_show (statusbar->load_image);
232 	}
233 	if (state & GEDIT_WINDOW_STATE_PRINTING)
234 	{
235 		gtk_widget_show (statusbar->state_frame);
236 		gtk_widget_show (statusbar->print_image);
237 	}
238 	if (state & GEDIT_WINDOW_STATE_ERROR)
239 	{
240 	 	gchar *tip;
241 
242  		tip = g_strdup_printf (ngettext("There is a tab with errors",
243 		                                "There are %d tabs with errors",
244 		                                num_of_errors),
245 		                       num_of_errors);
246 
247 		gtk_widget_set_tooltip_text (statusbar->error_image, tip);
248 		g_free (tip);
249 
250 		gtk_widget_show (statusbar->error_frame);
251 	}
252 	else
253 	{
254 		gtk_widget_hide (statusbar->error_frame);
255 	}
256 }
257 
258 /* ex:set ts=8 noet: */
259