evolution-3.6.4/e-util/e-ui-manager.c

No issues found

Incomplete coverage

Tool Failure ID Location Function Message Data
clang-analyzer no-output-found e-ui-manager.c Message(text='Unable to locate XML output from invoke-clang-analyzer') None
clang-analyzer no-output-found e-ui-manager.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-ui-manager.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 
 19 /**
 20  * SECTION: e-ui-manager
 21  * @short_description: construct menus and toolbars from a UI definition
 22  * @include: e-util/e-ui-manager.h
 23  *
 24  * This is a #GtkUIManager with support for Evolution's "express" mode,
 25  * which influences the parsing of UI definitions.
 26  **/
 27 
 28 #ifdef HAVE_CONFIG_H
 29 #include <config.h>
 30 #endif
 31 
 32 #include "e-ui-manager.h"
 33 #include "e-util-private.h"
 34 
 35 #include <string.h>
 36 
 37 #define E_UI_MANAGER_GET_PRIVATE(obj) \
 38 	(G_TYPE_INSTANCE_GET_PRIVATE \
 39 	((obj), E_TYPE_UI_MANAGER, EUIManagerPrivate))
 40 
 41 /*
 42  * --- NOTE TO SELF ---
 43  *
 44  * While creating this class I was tempted to add an "id" property which
 45  * EPluginUI could extract from a given EUIManager instead of having the
 46  * public EPluginUI functions take a separate "id" argument.  Seemed like
 47  * a nice cleanup until I remembered that an EUIManager instance can have
 48  * multiple IDs ("aliases"), as in the case of EShellWindow's UI manager.
 49  * So the UI Manager ID and the instance still need to be kept separate.
 50  *
 51  * Mentioning it here in case I forget why I didn't go through with it.
 52  */
 53 
 54 struct _EUIManagerPrivate {
 55 	guint express_mode : 1;
 56 };
 57 
 58 enum {
 59 	PROP_0,
 60 	PROP_EXPRESS_MODE
 61 };
 62 
 63 G_DEFINE_TYPE (
 64 	EUIManager,
 65 	e_ui_manager,
 66 	GTK_TYPE_UI_MANAGER)
 67 
 68 static void
 69 ui_manager_set_property (GObject *object,
 70                          guint property_id,
 71                          const GValue *value,
 72                          GParamSpec *pspec)
 73 {
 74 	switch (property_id) {
 75 		case PROP_EXPRESS_MODE:
 76 			e_ui_manager_set_express_mode (
 77 				E_UI_MANAGER (object),
 78 				g_value_get_boolean (value));
 79 			return;
 80 	}
 81 
 82 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 83 }
 84 
 85 static void
 86 ui_manager_get_property (GObject *object,
 87                          guint property_id,
 88                          GValue *value,
 89                          GParamSpec *pspec)
 90 {
 91 	switch (property_id) {
 92 		case PROP_EXPRESS_MODE:
 93 			g_value_set_boolean (
 94 				value, e_ui_manager_get_express_mode (
 95 				E_UI_MANAGER (object)));
 96 			return;
 97 	}
 98 
 99 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
100 }
101 
102 static gchar *
103 ui_manager_filter_ui (EUIManager *ui_manager,
104                       const gchar *ui_definition)
105 {
106 	gchar **lines;
107 	gchar *filtered;
108 	gboolean express_mode;
109 	gboolean include = TRUE;
110 	gint ii;
111 
112 	express_mode = e_ui_manager_get_express_mode (ui_manager);
113 
114 	/*
115 	 * Very simple C style pre-processing in-line in the XML:
116 	 * #if [!]EXPRESS\n ... \n#endif\n
117 	 */
118 	lines = g_strsplit (ui_definition, "\n", -1);
119 
120 	for (ii = 0; lines[ii] != NULL; ii++) {
121 		if (lines[ii][0] == '#') {
122 			if (!strncmp (lines[ii], "#if ", 4)) {
123 				gboolean not_express = lines[ii][4] == '!';
124 				include = express_mode ^ not_express;
125 				lines[ii][0] = '\0';
126 			} else if (!strncmp (lines[ii], "#endif", 6)) {
127 				lines[ii][0] = '\0';
128 				include = TRUE;
129 			}
130 		}
131 		if (!include)
132 			lines[ii][0] = '\0';
133 	}
134 
135 	filtered = g_strjoinv ("\n", lines);
136 
137 	g_strfreev (lines);
138 
139 	return filtered;
140 }
141 
142 static void
143 e_ui_manager_class_init (EUIManagerClass *class)
144 {
145 	GObjectClass *object_class;
146 
147 	g_type_class_add_private (class, sizeof (EUIManagerPrivate));
148 
149 	object_class = G_OBJECT_CLASS (class);
150 	object_class->set_property = ui_manager_set_property;
151 	object_class->get_property = ui_manager_get_property;
152 
153 	class->filter_ui = ui_manager_filter_ui;
154 
155 	g_object_class_install_property (
156 		object_class,
157 		PROP_EXPRESS_MODE,
158 		g_param_spec_boolean (
159 			"express-mode",
160 			"Express Mode",
161 			NULL,
162 			FALSE,
163 			G_PARAM_READWRITE |
164 			G_PARAM_CONSTRUCT));
165 }
166 
167 static void
168 e_ui_manager_init (EUIManager *ui_manager)
169 {
170 	ui_manager->priv = E_UI_MANAGER_GET_PRIVATE (ui_manager);
171 }
172 
173 /**
174  * e_ui_manager_new:
175  *
176  * Returns a new #EUIManager instance.
177  *
178  * Returns: a new #EUIManager instance
179  **/
180 GtkUIManager *
181 e_ui_manager_new (void)
182 {
183 	return g_object_new (E_TYPE_UI_MANAGER, NULL);
184 }
185 
186 /**
187  * e_ui_manager_get_express_mode:
188  * @ui_manager: an #EUIManager
189  *
190  * Returns the "express mode" flag in @ui_manager.
191  *
192  * Returns: %TRUE if @ui_manager is set to express mode
193  **/
194 gboolean
195 e_ui_manager_get_express_mode (EUIManager *ui_manager)
196 {
197 	g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), FALSE);
198 
199 	return ui_manager->priv->express_mode;
200 }
201 
202 /**
203  * e_ui_manager_set_express_mode:
204  * @ui_manager: an #EUIManager
205  * @express_mode: express mode flag
206  *
207  * Sets the "express mode" flag in @ui_manager, which influences how
208  * UI definitions are loaded.
209  **/
210 void
211 e_ui_manager_set_express_mode (EUIManager *ui_manager,
212                                gboolean express_mode)
213 {
214 	g_return_if_fail (E_IS_UI_MANAGER (ui_manager));
215 
216 	if (ui_manager->priv->express_mode == express_mode)
217 		return;
218 
219 	ui_manager->priv->express_mode = express_mode;
220 
221 	g_object_notify (G_OBJECT (ui_manager), "express-mode");
222 }
223 
224 /**
225  * e_ui_manager_add_ui_from_file:
226  * @ui_manager: an #EUIManager
227  * @basename: basename of the UI definition file
228  *
229  * Loads a UI definition into @ui_manager from Evolution's UI directory.
230  * If the EUIManager:express-mode property is %TRUE, a simplified version
231  * of the UI may be presented.
232  *
233  * Failure here is fatal, since the application can't function without
234  * its core UI definitions.
235  *
236  * Returns: The merge ID for the merged UI.  The merge ID can be used to
237  *          unmerge the UI with gtk_ui_manager_remove_ui().
238  **/
239 guint
240 e_ui_manager_add_ui_from_file (EUIManager *ui_manager,
241                                const gchar *basename)
242 {
243 	EUIManagerClass *class;
244 	gchar *filename;
245 	gchar *contents;
246 	guint merge_id = 0;
247 	GError *error = NULL;
248 
249 	g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), 0);
250 	g_return_val_if_fail (basename != NULL, 0);
251 
252 	class = E_UI_MANAGER_GET_CLASS (ui_manager);
253 	g_return_val_if_fail (class->filter_ui != NULL, 0);
254 
255 	filename = g_build_filename (EVOLUTION_UIDIR, basename, NULL);
256 
257 	if (g_file_get_contents (filename, &contents, NULL, &error)) {
258 		gchar *filtered;
259 
260 		/* We could call e_ui_manager_add_ui_from_string() here,
261 		 * but if an error occurs we'd like to include the file
262 		 * name in the error message. */
263 
264 		filtered = class->filter_ui (ui_manager, contents);
265 
266 		merge_id = gtk_ui_manager_add_ui_from_string (
267 			GTK_UI_MANAGER (ui_manager), filtered, -1, &error);
268 
269 		g_free (filtered);
270 		g_free (contents);
271 	}
272 
273 	g_free (filename);
274 
275 	if (error != NULL) {
276 		g_error ("%s: %s", basename, error->message);
277 		g_assert_not_reached ();
278 	}
279 
280 	return merge_id;
281 }
282 
283 /**
284  * e_ui_manager_add_ui_from_string:
285  * @ui_manager: an #EUIManager
286  * @ui_definition: the UI XML in NULL terminated string form
287  * @error: return location for a #GError, or %NULL
288  *
289  * Loads the given UI definition into @ui_manager.  If the
290  * EUIManager:express-mode property is %TRUE, a simplified version of
291  * the UI may be presented.
292  *
293  * Failure here is <i>not</i> fatal, since the function is primarily
294  * used to load UI definitions for plugins, which we can get by without.
295  *
296  * Returns: The merge ID for the merged UI.  The merge ID can be used to
297  *          unmerge the UI with gtk_ui_manager_remove_ui().
298  **/
299 guint
300 e_ui_manager_add_ui_from_string (EUIManager *ui_manager,
301                                  const gchar *ui_definition,
302                                  GError **error)
303 {
304 	EUIManagerClass *class;
305 	gchar *filtered;
306 	guint merge_id;
307 
308 	g_return_val_if_fail (E_IS_UI_MANAGER (ui_manager), 0);
309 	g_return_val_if_fail (ui_definition != NULL, 0);
310 
311 	class = E_UI_MANAGER_GET_CLASS (ui_manager);
312 	g_return_val_if_fail (class->filter_ui != NULL, 0);
313 
314 	filtered = class->filter_ui (ui_manager, ui_definition);
315 
316 	merge_id = gtk_ui_manager_add_ui_from_string (
317 		GTK_UI_MANAGER (ui_manager), filtered, -1, error);
318 
319 	g_free (filtered);
320 
321 	return merge_id;
322 }