anjuta: Save GDL settings correctly
[anjuta.git] / libanjuta / anjuta-session.c
blobf611ee94c998c44840024900524e967cdf41270d
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * anjuta-session.c
4 * Copyright (c) 2005 Naba Kumar <naba@gnome.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 /**
22 * SECTION:anjuta-session
23 * @short_description: Store local user settings
24 * @see_also:
25 * @stability: Unstable
26 * @include: libanjuta/anjuta-session.h
28 * A anjuta session contains local user settings, by example the list of files
29 * open in one project. These settings are stored in
30 * a .ini-like config file in a directory named session. Other libraries can
31 * store their own settings in another format in the same directory.
34 #include <stdlib.h>
35 #include <string.h>
37 #include "anjuta-session.h"
38 #include "anjuta-utils.h"
40 struct _AnjutaSessionPriv {
41 gchar *dir_path;
42 GKeyFile *key_file;
45 static gpointer *parent_class = NULL;
47 static void
48 anjuta_session_finalize (GObject *object)
50 AnjutaSession *cobj;
51 cobj = ANJUTA_SESSION (object);
53 g_free (cobj->priv->dir_path);
54 g_key_file_free (cobj->priv->key_file);
55 g_free (cobj->priv);
57 G_OBJECT_CLASS(parent_class)->finalize(object);
60 static void
61 anjuta_session_class_init (AnjutaSessionClass *klass)
63 GObjectClass *object_class = G_OBJECT_CLASS (klass);
65 parent_class = g_type_class_peek_parent (klass);
66 object_class->finalize = anjuta_session_finalize;
69 static void
70 anjuta_session_instance_init (AnjutaSession *obj)
72 obj->priv = g_new0 (AnjutaSessionPriv, 1);
73 obj->priv->dir_path = NULL;
76 /**
77 * anjuta_session_new:
78 * @session_directory: Directory where session is loaded from/saved to.
80 * Created a new session object. @session_directory is the directory
81 * where session information will be stored or loaded in case of existing
82 * session.
84 * Returns: an #AnjutaSession Object
86 AnjutaSession*
87 anjuta_session_new (const gchar *session_directory)
89 AnjutaSession *obj;
90 gchar *filename;
92 g_return_val_if_fail (session_directory != NULL, NULL);
93 g_return_val_if_fail (g_path_is_absolute (session_directory), NULL);
95 obj = ANJUTA_SESSION (g_object_new (ANJUTA_TYPE_SESSION, NULL));
96 obj->priv->dir_path = g_strdup (session_directory);
98 obj->priv->key_file = g_key_file_new ();
100 filename = anjuta_session_get_session_filename (obj);
101 g_key_file_load_from_file (obj->priv->key_file, filename,
102 G_KEY_FILE_NONE, NULL);
103 g_free (filename);
105 return obj;
108 ANJUTA_TYPE_BOILERPLATE (AnjutaSession, anjuta_session, G_TYPE_OBJECT)
111 * anjuta_session_get_session_directory:
112 * @session: an #AnjutaSession object
114 * Returns the directory corresponding to this session object.
116 * Returns: session directory
118 const gchar*
119 anjuta_session_get_session_directory (AnjutaSession *session)
121 return session->priv->dir_path;
125 * anjuta_session_get_session_filename:
126 * @session: an #AnjutaSession object
128 * Gets the session filename corresponding to this session object.
130 * Returns: session (absolute) filename
132 gchar*
133 anjuta_session_get_session_filename (AnjutaSession *session)
135 g_return_val_if_fail (ANJUTA_IS_SESSION (session), NULL);
137 return g_build_filename (session->priv->dir_path,
138 "anjuta.session", NULL);
142 * anjuta_session_sync:
143 * @session: an #AnjutaSession object
145 * Synchronizes session object with session file
147 void
148 anjuta_session_sync (AnjutaSession *session)
150 gchar *filename, *data;
152 g_return_if_fail (ANJUTA_IS_SESSION (session));
154 filename = anjuta_session_get_session_filename (session);
155 data = g_key_file_to_data (session->priv->key_file, NULL, NULL);
156 g_file_set_contents (filename, data, -1, NULL);
158 g_free (filename);
159 g_free (data);
163 * anjuta_session_clear:
164 * @session: an #AnjutaSession object
166 * Clears the session.
168 void
169 anjuta_session_clear (AnjutaSession *session)
171 gchar *cmd;
172 gchar *quoted;
173 gint ret;
175 g_return_if_fail (ANJUTA_IS_SESSION (session));
177 g_key_file_free (session->priv->key_file);
178 session->priv->key_file = g_key_file_new ();
180 anjuta_session_sync (session);
182 quoted = g_shell_quote (session->priv->dir_path);
183 cmd = g_strconcat ("rm -fr ", quoted, NULL);
184 ret = system (cmd);
185 g_free (cmd);
187 cmd = g_strconcat ("mkdir -p ", quoted, NULL);
188 ret = system (cmd);
189 g_free (cmd);
190 g_free (quoted);
194 * anjuta_session_clear_section:
195 * @session: an #AnjutaSession object.
196 * @section: Section to clear.
198 * Clears the given section in session object.
200 void
201 anjuta_session_clear_section (AnjutaSession *session,
202 const gchar *section)
204 g_return_if_fail (ANJUTA_IS_SESSION (session));
205 g_return_if_fail (section != NULL);
207 g_key_file_remove_group (session->priv->key_file, section, NULL);
211 * anjuta_session_set_int:
212 * @session: an #AnjutaSession object
213 * @section: Section.
214 * @key: Key name.
215 * @value: Key value
217 * Set an integer @value to @key in given @section.
219 void
220 anjuta_session_set_int (AnjutaSession *session, const gchar *section,
221 const gchar *key, gint value)
223 g_return_if_fail (ANJUTA_IS_SESSION (session));
224 g_return_if_fail (section != NULL);
225 g_return_if_fail (key != NULL);
227 if (!value)
229 g_key_file_remove_key (session->priv->key_file, section, key, NULL);
230 return;
233 g_key_file_set_integer (session->priv->key_file, section, key, value);
237 * anjuta_session_set_float:
238 * @session: an #AnjutaSession object
239 * @section: Section.
240 * @key: Key name.
241 * @value: Key value
243 * Set a float @value to @key in given @section.
245 void
246 anjuta_session_set_float (AnjutaSession *session, const gchar *section,
247 const gchar *key, gfloat value)
249 g_return_if_fail (ANJUTA_IS_SESSION (session));
250 g_return_if_fail (section != NULL);
251 g_return_if_fail (key != NULL);
253 if (!value)
255 g_key_file_remove_key (session->priv->key_file, section, key, NULL);
256 return;
259 g_key_file_set_double (session->priv->key_file, section, key, value);
263 * anjuta_session_set_string:
264 * @session: an #AnjutaSession object
265 * @section: Section.
266 * @key: Key name.
267 * @value: Key value
269 * Set a string @value to @key in given @section.
271 void
272 anjuta_session_set_string (AnjutaSession *session, const gchar *section,
273 const gchar *key, const gchar *value)
275 g_return_if_fail (ANJUTA_IS_SESSION (session));
276 g_return_if_fail (section != NULL);
277 g_return_if_fail (key != NULL);
279 if (!value)
281 g_key_file_remove_key (session->priv->key_file, section, key, NULL);
282 return;
285 g_key_file_set_string (session->priv->key_file, section, key, value);
289 * anjuta_session_set_string_list:
290 * @session: an #AnjutaSession object
291 * @section: Section.
292 * @key: Key name.
293 * @value: Key value
295 * Set a list of strings @value to @key in given @section.
297 void
298 anjuta_session_set_string_list (AnjutaSession *session,
299 const gchar *section,
300 const gchar *key, GList *value)
302 gchar *value_str;
303 GString *str;
304 GList *node;
305 gboolean first_item = TRUE;
307 g_return_if_fail (ANJUTA_IS_SESSION (session));
308 g_return_if_fail (section != NULL);
309 g_return_if_fail (key != NULL);
311 if (!value)
313 g_key_file_remove_key (session->priv->key_file, section, key, NULL);
314 return;
317 str = g_string_new ("");
318 node = value;
319 while (node)
321 /* Keep empty string */
322 if (node->data != NULL)
324 if (first_item)
325 first_item = FALSE;
326 else
327 g_string_append (str, "%%%");
328 g_string_append (str, node->data);
330 node = g_list_next (node);
333 value_str = g_string_free (str, FALSE);
334 g_key_file_set_string (session->priv->key_file, section, key, value_str);
336 g_free (value_str);
340 * anjuta_session_get_int:
341 * @session: an #AnjutaSession object
342 * @section: Section.
343 * @key: Key name.
345 * Get an integer @value of @key in given @section.
347 * Returns: Key value
349 gint
350 anjuta_session_get_int (AnjutaSession *session, const gchar *section,
351 const gchar *key)
353 gint value;
355 g_return_val_if_fail (ANJUTA_IS_SESSION (session), 0);
356 g_return_val_if_fail (section != NULL, 0);
357 g_return_val_if_fail (key != NULL, 0);
359 value = g_key_file_get_integer (session->priv->key_file, section, key, NULL);
361 return value;
365 * anjuta_session_get_float:
366 * @session: an #AnjutaSession object
367 * @section: Section.
368 * @key: Key name.
370 * Get a float @value of @key in given @section.
372 * Returns: Key value
374 gfloat
375 anjuta_session_get_float (AnjutaSession *session, const gchar *section,
376 const gchar *key)
378 gfloat value;
380 g_return_val_if_fail (ANJUTA_IS_SESSION (session), 0);
381 g_return_val_if_fail (section != NULL, 0);
382 g_return_val_if_fail (key != NULL, 0);
384 value = (float)g_key_file_get_double (session->priv->key_file, section, key, NULL);
386 return value;
390 * anjuta_session_get_string:
391 * @session: an #AnjutaSession object
392 * @section: Section.
393 * @key: Key name.
395 * Get a string @value of @key in given @section.
397 * Returns: Key value
399 gchar*
400 anjuta_session_get_string (AnjutaSession *session, const gchar *section,
401 const gchar *key)
403 gchar *value;
405 g_return_val_if_fail (ANJUTA_IS_SESSION (session), NULL);
406 g_return_val_if_fail (section != NULL, NULL);
407 g_return_val_if_fail (key != NULL, NULL);
409 value = g_key_file_get_string (session->priv->key_file, section, key, NULL);
411 return value;
415 * anjuta_session_get_string_list:
416 * @session: an #AnjutaSession object
417 * @section: Section.
418 * @key: Key name.
420 * Get a list of strings @value of @key in given @section.
422 * Returns: Key value
424 GList*
425 anjuta_session_get_string_list (AnjutaSession *session,
426 const gchar *section,
427 const gchar *key)
429 gchar *val, **str, **ptr;
430 GList *value;
432 g_return_val_if_fail (ANJUTA_IS_SESSION (session), NULL);
433 g_return_val_if_fail (section != NULL, NULL);
434 g_return_val_if_fail (key != NULL, NULL);
436 val = g_key_file_get_string (session->priv->key_file, section, key, NULL);
439 value = NULL;
440 if (val)
442 str = g_strsplit (val, "%%%", -1);
443 if (str)
445 ptr = str;
446 while (*ptr)
448 /* Keep empty string */
449 value = g_list_prepend (value, g_strdup (*ptr));
450 ptr++;
452 g_strfreev (str);
454 g_free (val);
457 return g_list_reverse (value);
462 * anjuta_session_get_relative_uri_from_file:
463 * @session: an #AnjutaSession object
464 * @file: a GFile
465 * @fragment: an optional fragment
467 * Return an URI relative to the session directory file with an optional
468 * fragment.
469 * It is useful to keep only relative file paths in a session file to be able
470 * to copy the whole project without breaking references.
472 * Returns: A string that has to be freed with g_free().
474 gchar *
475 anjuta_session_get_relative_uri_from_file (AnjutaSession *session,
476 GFile *file,
477 const gchar *fragment)
479 GFile *parent;
480 gchar *uri;
481 gint level;
483 parent = g_file_new_for_path (session->priv->dir_path);
484 for (level = 0; (parent != NULL) && !g_file_has_prefix (file, parent); level++)
486 GFile *next = g_file_get_parent (parent);
487 g_object_unref (parent);
488 parent = next;
491 if (parent == NULL)
493 uri = g_file_get_uri (file);
495 else
497 gchar *path;
499 path = g_file_get_relative_path (parent, file);
500 uri = g_uri_escape_string (path, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
501 g_free (path);
502 if (level != 0)
504 gsize len;
505 gchar *buffer;
506 gchar *ptr;
508 len = strlen (uri);
509 buffer = g_new (gchar, len + level * 3 + 1);
510 for (ptr = buffer; level; level--)
512 memcpy (ptr, ".." G_DIR_SEPARATOR_S, 3);
513 ptr += 3;
515 memcpy (ptr, uri, len + 1);
516 g_free (uri);
518 uri = buffer;
522 if (fragment != NULL)
524 gchar *with_fragment;
526 with_fragment = g_strconcat (uri, "#", fragment, NULL);
527 g_free (uri);
528 uri = with_fragment;
531 return uri;
536 * anjuta_session_get_file_from_relative_uri:
537 * @session: an #AnjutaSession object
538 * @uri: a relative URI from a key
539 * @fragment: fragment part of the URI if existing, cal be NULL
541 * Return a GFile corresponding to the URI and and optional fragment,
542 * normally read from a session key.
543 * The path is expected to be relative to the session directory but it works
544 * with an absolute URI, in this case it returns the same file than
545 * g_file_new_for_uri.
546 * It is useful to keep only relative file paths in a session file to be able
547 * to copy the whole project without breaking references.
549 * Returns: A new GFile that has to be freed with g_object_unref().
551 GFile*
552 anjuta_session_get_file_from_relative_uri (AnjutaSession *session,
553 const gchar *uri,
554 const gchar **fragment)
556 GFile *file;
557 gchar *scheme;
559 scheme =g_uri_parse_scheme (uri);
560 if (scheme != NULL)
562 free (scheme);
563 file = g_file_new_for_uri (uri);
565 else
567 gchar *parent_uri = g_filename_to_uri (session->priv->dir_path, NULL, NULL);
568 gchar *full_uri;
570 full_uri = g_strconcat (parent_uri, G_DIR_SEPARATOR_S, uri, NULL);
571 file = g_file_new_for_uri (full_uri);
572 g_free (full_uri);
573 g_free (parent_uri);
575 if (fragment != NULL)
577 *fragment = strchr (uri, '#');
578 if (*fragment != NULL) (*fragment)++;
581 return file;