1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
4 *
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2014 Pierre Wieser and others (see AUTHORS)
8 *
9 * Nautilus-Actions is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * Nautilus-Actions is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Nautilus-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
22 *
23 * Authors:
24 * Frederic Ruaudel <grumz@grumz.net>
25 * Rodrigo Moya <rodrigo@gnome-db.org>
26 * Pierre Wieser <pwieser@trychlos.org>
27 * ... and many others (see AUTHORS)
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #include <core/na-io-provider.h>
35
36 #include "base-gtk-utils.h"
37 #include "nact-main-statusbar.h"
38
39 typedef struct {
40 guint event_source_id;
41 guint context_id;
42 GtkStatusbar *bar;
43 }
44 StatusbarTimeoutDisplayStruct;
45
46 #define LOCKED_IMAGE PKGUIDIR "/locked.png"
47
48 static GtkStatusbar *get_statusbar( const NactMainWindow *window );
49 static gboolean display_timeout( StatusbarTimeoutDisplayStruct *stds );
50 static void display_timeout_free( StatusbarTimeoutDisplayStruct *stds );
51
52 /**
53 * nact_main_statusbar_initialize_gtk_toplevel:
54 * @window: the #NactMainWindow.
55 *
56 * Initial loading of the UI.
57 */
58 void
nact_main_statusbar_initialize_gtk_toplevel(NactMainWindow * window)59 nact_main_statusbar_initialize_gtk_toplevel( NactMainWindow *window )
60 {
61 static const gchar *thisfn = "nact_main_statusbar_initialize_gtk_toplevel";
62 gint width, height;
63 GtkStatusbar *bar;
64 GtkFrame *frame;
65 /* gtk_widget_size_request() is deprecated since Gtk+ 3.0
66 * see http://library.gnome.org/devel/gtk/unstable/GtkWidget.html#gtk-widget-render-icon
67 * and http://git.gnome.org/browse/gtk+/commit/?id=07eeae15825403037b7df139acf9bfa104d5559d
68 */
69 #if GTK_CHECK_VERSION( 2, 91, 7 )
70 GtkRequisition minimal_size, natural_size;
71 #else
72 GtkRequisition requisition;
73 #endif
74
75 g_debug( "%s: window=%p", thisfn, ( void * ) window );
76
77 gtk_icon_size_lookup( GTK_ICON_SIZE_MENU, &width, &height );
78
79 bar = get_statusbar( window );
80 frame = GTK_FRAME( base_window_get_widget( BASE_WINDOW( window ), "ActionLockedFrame" ));
81
82 #if GTK_CHECK_VERSION( 2, 91, 7 )
83 gtk_widget_get_preferred_size( GTK_WIDGET( bar ), &minimal_size, &natural_size );
84 gtk_widget_set_size_request( GTK_WIDGET( bar ), natural_size.width, height+8 );
85 #else
86 gtk_widget_size_request( GTK_WIDGET( bar ), &requisition );
87 gtk_widget_set_size_request( GTK_WIDGET( bar ), requisition.width, height+8 );
88 #endif
89
90 gtk_widget_set_size_request( GTK_WIDGET( frame ), width+4, height+4 );
91 gtk_frame_set_shadow_type( frame, GTK_SHADOW_IN );
92 }
93
94 /**
95 * nact_main_statusbar_display_status:
96 * @window: the #NactMainWindow instance.
97 * @context: the context to be displayed.
98 * @status: the message.
99 *
100 * Push a message.
101 */
102 void
nact_main_statusbar_display_status(NactMainWindow * window,const gchar * context,const gchar * status)103 nact_main_statusbar_display_status( NactMainWindow *window, const gchar *context, const gchar *status )
104 {
105 static const gchar *thisfn = "nact_main_statusbar_display_status";
106 GtkStatusbar *bar;
107
108 g_debug( "%s: window=%p, context=%s, status=%s", thisfn, ( void * ) window, context, status );
109
110 if( !status || !g_utf8_strlen( status, -1 )){
111 return;
112 }
113
114 bar = get_statusbar( window );
115
116 if( bar ){
117 guint context_id = gtk_statusbar_get_context_id( bar, context );
118 gtk_statusbar_push( bar, context_id, status );
119 }
120 }
121
122 /**
123 * nact_main_statusbar_display_with_timeout:
124 * @window: the #NactMainWindow instance.
125 * @context: the context to be displayed.
126 * @status: the message.
127 *
128 * Push a message.
129 * Automatically pop it after a timeout.
130 * The timeout is not suspended when another message is pushed onto the
131 * previous one.
132 */
133 void
nact_main_statusbar_display_with_timeout(NactMainWindow * window,const gchar * context,const gchar * status)134 nact_main_statusbar_display_with_timeout( NactMainWindow *window, const gchar *context, const gchar *status )
135 {
136 static const gchar *thisfn = "nact_main_statusbar_display_with_timeout";
137 GtkStatusbar *bar;
138 StatusbarTimeoutDisplayStruct *stds;
139
140 g_debug( "%s: window=%p, context=%s, status=%s", thisfn, ( void * ) window, context, status );
141
142 if( !status || !g_utf8_strlen( status, -1 )){
143 return;
144 }
145
146 bar = get_statusbar( window );
147
148 if( bar ){
149 guint context_id = gtk_statusbar_get_context_id( bar, context );
150 gtk_statusbar_push( bar, context_id, status );
151
152 stds = g_new0( StatusbarTimeoutDisplayStruct, 1 );
153 stds->context_id = context_id;
154 stds->bar = bar;
155 stds->event_source_id = g_timeout_add_seconds_full(
156 G_PRIORITY_DEFAULT,
157 10,
158 ( GSourceFunc ) display_timeout,
159 stds,
160 ( GDestroyNotify ) display_timeout_free );
161 }
162 }
163
164 /**
165 * nact_main_statusbar_hide_status:
166 * @window: the #NactMainWindow instance.
167 * @context: the context to be hidden.
168 *
169 * Hide the specified context.
170 */
171 void
nact_main_statusbar_hide_status(NactMainWindow * window,const gchar * context)172 nact_main_statusbar_hide_status( NactMainWindow *window, const gchar *context )
173 {
174 GtkStatusbar *bar;
175
176 bar = get_statusbar( window );
177
178 if( bar ){
179 guint context_id = gtk_statusbar_get_context_id( bar, context );
180 gtk_statusbar_pop( bar, context_id );
181 }
182 }
183
184 /**
185 * nact_main_statusbar_set_locked:
186 * @window: the #NactMainWindow instance.
187 * @provider: whether the current provider is locked (read-only).
188 * @item: whether the current item is locked (read-only).
189 *
190 * Displays the writability status of the current item as an image.
191 * Installs the corresponding tooltip.
192 */
193 void
nact_main_statusbar_set_locked(NactMainWindow * window,gboolean readonly,gint reason)194 nact_main_statusbar_set_locked( NactMainWindow *window, gboolean readonly, gint reason )
195 {
196 static const gchar *thisfn = "nact_main_statusbar_set_locked";
197 GtkStatusbar *bar;
198 GtkFrame *frame;
199 GtkImage *image;
200 gchar *tooltip;
201 gboolean set_pixbuf;
202
203 g_debug( "%s: window=%p, readonly=%s, reason=%d", thisfn, ( void * ) window, readonly ? "True":"False", reason );
204
205 set_pixbuf = TRUE;
206 bar = get_statusbar( window );
207 frame = GTK_FRAME( base_window_get_widget( BASE_WINDOW( window ), "ActionLockedFrame" ));
208 image = GTK_IMAGE( base_window_get_widget( BASE_WINDOW( window ), "ActionLockedImage" ));
209
210 if( bar && frame && image ){
211
212 tooltip = g_strdup( "" );
213
214 if( readonly ){
215 gtk_image_set_from_file( image, LOCKED_IMAGE );
216 set_pixbuf = FALSE;
217 g_free( tooltip );
218 tooltip = na_io_provider_get_readonly_tooltip( reason );
219 }
220
221 gtk_widget_set_tooltip_text( GTK_WIDGET( image ), tooltip );
222 g_free( tooltip );
223 }
224
225 if( set_pixbuf ){
226 base_gtk_utils_render( NULL, image, GTK_ICON_SIZE_MENU );
227 }
228 }
229
230 /*
231 * Returns the status bar widget
232 */
233 static GtkStatusbar *
get_statusbar(const NactMainWindow * window)234 get_statusbar( const NactMainWindow *window )
235 {
236 GtkWidget *statusbar;
237
238 statusbar = base_window_get_widget( BASE_WINDOW( window ), "MainStatusbar" );
239
240 return( GTK_STATUSBAR( statusbar ));
241 }
242
243 static gboolean
display_timeout(StatusbarTimeoutDisplayStruct * stds)244 display_timeout( StatusbarTimeoutDisplayStruct *stds )
245 {
246 gboolean keep_source = FALSE;
247
248 gtk_statusbar_pop( stds->bar, stds->context_id );
249
250 return( keep_source );
251 }
252
253 static void
display_timeout_free(StatusbarTimeoutDisplayStruct * stds)254 display_timeout_free( StatusbarTimeoutDisplayStruct *stds )
255 {
256 g_debug( "nact_main_statusbar_display_timeout_free: stds=%p", ( void * ) stds );
257
258 g_free( stds );
259 }
260