evolution-3.6.4/modules/mail/e-mail-shell-sidebar.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-mail-shell-sidebar.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-mail-shell-sidebar.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
Failure running clang-analyzer ('no-output-found')
Message
Unable to locate XML output from invoke-clang-analyzer
  1 /*
  2  * e-mail-shell-sidebar.c
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  *
 18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 19  *
 20  */
 21 
 22 #ifdef HAVE_CONFIG_H
 23 #include <config.h>
 24 #endif
 25 
 26 #include "e-mail-shell-sidebar.h"
 27 
 28 #include "mail/e-mail-backend.h"
 29 #include "mail/e-mail-sidebar.h"
 30 #include "mail/em-folder-utils.h"
 31 
 32 #define E_MAIL_SHELL_SIDEBAR_GET_PRIVATE(obj) \
 33 	(G_TYPE_INSTANCE_GET_PRIVATE \
 34 	((obj), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebarPrivate))
 35 
 36 struct _EMailShellSidebarPrivate {
 37 	GtkWidget *folder_tree;
 38 };
 39 
 40 enum {
 41 	PROP_0,
 42 	PROP_FOLDER_TREE
 43 };
 44 
 45 G_DEFINE_DYNAMIC_TYPE (
 46 	EMailShellSidebar,
 47 	e_mail_shell_sidebar,
 48 	E_TYPE_SHELL_SIDEBAR)
 49 
 50 static void
 51 mail_shell_sidebar_selection_changed_cb (EShellSidebar *shell_sidebar,
 52                                          GtkTreeSelection *selection)
 53 {
 54 	EShellView *shell_view;
 55 	EShellViewClass *shell_view_class;
 56 	GtkTreeModel *model;
 57 	GtkTreeIter iter;
 58 	const gchar *icon_name;
 59 	gchar *display_name = NULL;
 60 	gboolean is_folder = FALSE;
 61 	guint flags = 0;
 62 
 63 	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
 64 	shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view);
 65 
 66 	if (gtk_tree_selection_get_selected (selection, &model, &iter))
 67 		gtk_tree_model_get (
 68 			model, &iter,
 69 			COL_STRING_DISPLAY_NAME, &display_name,
 70 			COL_BOOL_IS_FOLDER, &is_folder,
 71 			COL_UINT_FLAGS, &flags, -1);
 72 
 73 	if (is_folder)
 74 		icon_name = em_folder_utils_get_icon_name (flags);
 75 	else {
 76 		g_free (display_name);
 77 
 78 		icon_name = shell_view_class->icon_name;
 79 		display_name = g_strdup (shell_view_class->label);
 80 	}
 81 
 82 	e_shell_sidebar_set_icon_name (shell_sidebar, icon_name);
 83 	e_shell_sidebar_set_primary_text (shell_sidebar, display_name);
 84 
 85 	g_free (display_name);
 86 }
 87 
 88 static void
 89 mail_shell_sidebar_get_property (GObject *object,
 90                                  guint property_id,
 91                                  GValue *value,
 92                                  GParamSpec *pspec)
 93 {
 94 	switch (property_id) {
 95 		case PROP_FOLDER_TREE:
 96 			g_value_set_object (
 97 				value, e_mail_shell_sidebar_get_folder_tree (
 98 				E_MAIL_SHELL_SIDEBAR (object)));
 99 			return;
100 	}
101 
102 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
103 }
104 
105 static void
106 mail_shell_sidebar_dispose (GObject *object)
107 {
108 	EMailShellSidebarPrivate *priv;
109 
110 	priv = E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (object);
111 
112 	if (priv->folder_tree != NULL) {
113 		g_object_unref (priv->folder_tree);
114 		priv->folder_tree = NULL;
115 	}
116 
117 	/* Chain up to parent's dispose() method. */
118 	G_OBJECT_CLASS (e_mail_shell_sidebar_parent_class)->dispose (object);
119 }
120 
121 static void
122 mail_shell_sidebar_constructed (GObject *object)
123 {
124 	EMailShellSidebar *mail_shell_sidebar;
125 	EShellSettings *shell_settings;
126 	EShellBackend *shell_backend;
127 	EShellSidebar *shell_sidebar;
128 	EShellWindow *shell_window;
129 	EShellView *shell_view;
130 	EShell *shell;
131 	EMailBackend *backend;
132 	EMailSession *session;
133 	EAlertSink *alert_sink;
134 	GtkTreeSelection *selection;
135 	GtkTreeView *tree_view;
136 	GtkWidget *container;
137 	GtkWidget *widget;
138 
139 	/* Chain up to parent's constructed method. */
140 	G_OBJECT_CLASS (e_mail_shell_sidebar_parent_class)->constructed (object);
141 
142 	shell_sidebar = E_SHELL_SIDEBAR (object);
143 	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
144 	shell_backend = e_shell_view_get_shell_backend (shell_view);
145 	shell_window = e_shell_view_get_shell_window (shell_view);
146 
147 	shell = e_shell_window_get_shell (shell_window);
148 	shell_settings = e_shell_get_shell_settings (shell);
149 
150 	backend = E_MAIL_BACKEND (shell_backend);
151 	session = e_mail_backend_get_session (backend);
152 
153 	alert_sink = E_ALERT_SINK (shell_sidebar);
154 
155 	mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (object);
156 
157 	/* Build sidebar widgets. */
158 
159 	container = GTK_WIDGET (object);
160 
161 	widget = gtk_scrolled_window_new (NULL, NULL);
162 	gtk_scrolled_window_set_policy (
163 		GTK_SCROLLED_WINDOW (widget),
164 		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
165 	gtk_scrolled_window_set_shadow_type (
166 		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
167 	gtk_container_add (GTK_CONTAINER (container), widget);
168 	gtk_widget_show (widget);
169 
170 	container = widget;
171 
172 	widget = e_mail_sidebar_new (session, alert_sink);
173 	gtk_container_add (GTK_CONTAINER (container), widget);
174 	mail_shell_sidebar->priv->folder_tree = g_object_ref (widget);
175 	gtk_widget_show (widget);
176 
177 	g_object_bind_property (
178 		shell_view, "state-key-file",
179 		widget, "key-file",
180 		G_BINDING_SYNC_CREATE);
181 
182 	g_object_bind_property (
183 		shell_settings, "mail-sidebar-ellipsize",
184 		widget, "ellipsize",
185 		G_BINDING_SYNC_CREATE);
186 
187 	g_object_bind_property (
188 		shell_settings, "mail-sidebar-search",
189 		widget, "enable-search",
190 		G_BINDING_SYNC_CREATE);
191 
192 	g_signal_connect_swapped (
193 		widget, "key-file-changed",
194 		G_CALLBACK (e_shell_view_set_state_dirty), shell_view);
195 
196 	tree_view = GTK_TREE_VIEW (mail_shell_sidebar->priv->folder_tree);
197 	selection = gtk_tree_view_get_selection (tree_view);
198 
199 	g_signal_connect_swapped (
200 		selection, "changed",
201 		G_CALLBACK (mail_shell_sidebar_selection_changed_cb),
202 		shell_sidebar);
203 }
204 
205 static gint
206 guess_screen_width (EMailShellSidebar *sidebar)
207 {
208 	GtkWidget *widget;
209 	GdkScreen *screen;
210 	gint screen_width;
211 
212 	widget = GTK_WIDGET (sidebar);
213 
214 	screen_width = 0;
215 
216 	screen = gtk_widget_get_screen (widget);
217 	if (screen) {
218 		GtkWidget *toplevel;
219 		gint monitor;
220 		GdkRectangle rect;
221 
222 		toplevel = gtk_widget_get_toplevel (widget);
223 		if (toplevel && gtk_widget_get_realized (toplevel))
224 			monitor = gdk_screen_get_monitor_at_window (
225 				screen, gtk_widget_get_window (toplevel));
226 		else {
227 			/* We don't know in which monitor the window manager
228 			 * will put us.  So we will just use the geometry of
229 			 * the first monitor.
230 			 */
231 			monitor = 0;
232 		}
233 
234 		gdk_screen_get_monitor_geometry (screen, monitor, &rect);
235 		screen_width = rect.width;
236 	}
237 
238 	if (screen_width == 0)
239 		screen_width = 1024;
240 
241 	return screen_width;
242 }
243 
244 static void
245 mail_shell_sidebar_get_preferred_height (GtkWidget *widget,
246                                          gint *minimum_height,
247                                          gint *natural_height)
248 {
249 	GTK_WIDGET_CLASS (e_mail_shell_sidebar_parent_class)->
250 		get_preferred_height (widget, minimum_height, natural_height);
251 }
252 
253 static void
254 mail_shell_sidebar_get_preferred_width (GtkWidget *widget,
255                                         gint *minimum_width,
256                                         gint *natural_width)
257 {
258 	/* We override the normal size-request handler so that we can
259 	 * spit out a treeview with a suitable width.  We measure the
260 	 * length of a typical string and use that as the requisition's
261 	 * width.
262 	 *
263 	 * EMFolderTreeClass, our parent class, is based on GtkTreeView,
264 	 * which doesn't really have a good way of figuring out a minimum
265 	 * width for the tree.  This is really GTK+'s fault at large, as
266 	 * it only has "minimum size / allocated size", instead of
267 	 * "minimum size / preferred size / allocated size".  Hopefully
268 	 * the extended-layout branch of GTK+ will get merged soon and
269 	 * then we can remove this crap.
270 	 */
271 
272 	EMailShellSidebar *sidebar;
273 	PangoLayout *layout;
274 	PangoRectangle ink_rect;
275 	GtkStyle *style;
276 	gint border;
277 	gint sidebar_width;
278 	gint screen_width;
279 
280 	sidebar = E_MAIL_SHELL_SIDEBAR (widget);
281 
282 	GTK_WIDGET_CLASS (e_mail_shell_sidebar_parent_class)->
283 		get_preferred_width (widget, minimum_width, natural_width);
284 
285 	/* This string is a mockup only; it doesn't need to be translated */
286 	layout = gtk_widget_create_pango_layout (
287 		widget, "typical.account@mailservice.com");
288 	pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
289 	g_object_unref (layout);
290 
291 	style = gtk_widget_get_style (widget);
292 
293 	screen_width = guess_screen_width (sidebar);
294 
295 	/* Thickness of frame shadow plus some slack for padding. */
296 	border = 2 * style->xthickness + 4;
297 	sidebar_width = ink_rect.width + border;
298 	sidebar_width = MIN (sidebar_width, screen_width / 4);
299 	*minimum_width = *natural_width = MAX (*natural_width, sidebar_width);
300 }
301 
302 static guint32
303 mail_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
304 {
305 	EMailShellSidebarPrivate *priv;
306 	EMailSidebar *sidebar;
307 
308 	priv = E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
309 	sidebar = E_MAIL_SIDEBAR (priv->folder_tree);
310 
311 	return e_mail_sidebar_check_state (sidebar);
312 }
313 
314 static void
315 e_mail_shell_sidebar_class_init (EMailShellSidebarClass *class)
316 {
317 	GObjectClass *object_class;
318 	GtkWidgetClass *widget_class;
319 	EShellSidebarClass *shell_sidebar_class;
320 
321 	g_type_class_add_private (class, sizeof (EMailShellSidebarPrivate));
322 
323 	object_class = G_OBJECT_CLASS (class);
324 	object_class->get_property = mail_shell_sidebar_get_property;
325 	object_class->dispose = mail_shell_sidebar_dispose;
326 	object_class->constructed = mail_shell_sidebar_constructed;
327 
328 	widget_class = GTK_WIDGET_CLASS (class);
329 	widget_class->get_preferred_width = mail_shell_sidebar_get_preferred_width;
330 	widget_class->get_preferred_height = mail_shell_sidebar_get_preferred_height;
331 
332 	shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
333 	shell_sidebar_class->check_state = mail_shell_sidebar_check_state;
334 
335 	g_object_class_install_property (
336 		object_class,
337 		PROP_FOLDER_TREE,
338 		g_param_spec_object (
339 			"folder-tree",
340 			NULL,
341 			NULL,
342 			EM_TYPE_FOLDER_TREE,
343 			G_PARAM_READABLE));
344 }
345 
346 static void
347 e_mail_shell_sidebar_class_finalize (EMailShellSidebarClass *class)
348 {
349 }
350 
351 static void
352 e_mail_shell_sidebar_init (EMailShellSidebar *mail_shell_sidebar)
353 {
354 	mail_shell_sidebar->priv =
355 		E_MAIL_SHELL_SIDEBAR_GET_PRIVATE (mail_shell_sidebar);
356 
357 	/* Postpone widget construction until we have a shell view. */
358 }
359 
360 void
361 e_mail_shell_sidebar_type_register (GTypeModule *type_module)
362 {
363 	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
364 	 *     function, so we have to wrap it with a public function in
365 	 *     order to register types from a separate compilation unit. */
366 	e_mail_shell_sidebar_register_type (type_module);
367 }
368 
369 GtkWidget *
370 e_mail_shell_sidebar_new (EShellView *shell_view)
371 {
372 	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
373 
374 	return g_object_new (
375 		E_TYPE_MAIL_SHELL_SIDEBAR,
376 		"shell-view", shell_view, NULL);
377 }
378 
379 EMFolderTree *
380 e_mail_shell_sidebar_get_folder_tree (EMailShellSidebar *mail_shell_sidebar)
381 {
382 	g_return_val_if_fail (
383 		E_IS_MAIL_SHELL_SIDEBAR (mail_shell_sidebar), NULL);
384 
385 	return EM_FOLDER_TREE (mail_shell_sidebar->priv->folder_tree);
386 }