2 * Copyright (C) 2010 Collabora Ltd.
4 * This library is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, either version 2.1 of the License, or
7 * (at your option) any later version.
9 * This library 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
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library. If not, see <http://www.gnu.org/licenses/>.
18 * Philip Withnall <philip.withnall@collabora.co.uk>
25 private class Folks.Inspect.Utils
27 /* The current indentation level, in spaces */
28 private static uint indentation = 0;
29 private static string indentation_string = "";
31 public static void init ()
33 Utils.indentation_string = "";
35 /* Register some general transformation functions */
36 Value.register_transform_func (typeof (Object), typeof (string),
37 Utils.transform_object_to_string);
38 Value.register_transform_func (typeof (Folks.PersonaStore),
39 typeof (string), Utils.transform_persona_store_to_string);
40 Value.register_transform_func (typeof (string[]), typeof (string),
41 Utils.transform_string_array_to_string);
44 private static void transform_object_to_string (Value src,
47 /* FIXME: works around bgo#638363 */
48 Value dest_tmp = Value (typeof (string));
49 dest_tmp.take_string ("%p".printf (src.get_object ()));
53 private static void transform_persona_store_to_string (Value src,
56 /* FIXME: works around bgo#638363 */
57 Value dest_tmp = Value (typeof (string));
58 Folks.PersonaStore store = (Folks.PersonaStore) src.get_object ();
59 dest_tmp.take_string ("%p: %s, %s (%s)".printf (store, store.type_id,
60 store.id, store.display_name));
64 private static void transform_string_array_to_string (Value src,
67 /* FIXME: works around bgo#638363 */
68 Value dest_tmp = Value (typeof (string));
69 unowned string[] array = (string[]) src.get_boxed ();
72 /* FIXME: Work around bgo#656467 by using for() instead of foreach() */
73 for (uint i = 0; array[i] != null; i++)
75 var element = array[i];
78 output += "'%s'".printf (element);
82 dest_tmp.take_string (output);
86 public static void indent ()
88 /* We indent in increments of two spaces */
89 Utils.indentation += 2;
90 Utils.indentation_string = string.nfill (Utils.indentation, ' ');
93 public static void unindent ()
95 Utils.indentation -= 2;
96 Utils.indentation_string = string.nfill (Utils.indentation, ' ');
100 public static void print_line (string format, ...)
102 /* FIXME: store the va_list temporarily to work around bgo#638308 */
103 var valist = va_list ();
104 string output = format.vprintf (valist);
105 stdout.printf ("%s%s\n", Utils.indentation_string, output);
108 public static void print_individual (Individual individual,
111 Utils.print_line ("Individual '%s' with %u personas:",
112 individual.id, individual.personas.size);
114 /* List the Individual's properties */
115 unowned ParamSpec[] properties =
116 individual.get_class ().list_properties ();
119 foreach (unowned ParamSpec pspec in properties)
122 string output_string;
124 /* Ignore the personas property if we're printing the personas out */
125 if (show_personas == true && pspec.get_name () == "personas")
128 prop_value = Value (pspec.value_type);
129 individual.get_property (pspec.get_name (), ref prop_value);
131 output_string = Utils.property_to_string (individual.get_type (),
132 pspec.get_name (), prop_value);
134 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
137 if (show_personas == true)
139 Utils.print_line ("");
140 Utils.print_line ("Personas:");
143 foreach (Persona persona in individual.personas)
144 Utils.print_persona (persona);
150 public static void print_persona (Persona persona)
152 Utils.print_line ("Persona '%s':", persona.uid);
154 /* List the Persona's properties */
155 unowned ParamSpec[] properties =
156 persona.get_class ().list_properties ();
159 foreach (unowned ParamSpec pspec in properties)
162 string output_string;
164 prop_value = Value (pspec.value_type);
165 persona.get_property (pspec.get_name (), ref prop_value);
167 output_string = Utils.property_to_string (persona.get_type (),
168 pspec.get_name (), prop_value);
170 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
175 public static void print_persona_store (PersonaStore store,
178 if (store.is_prepared == false)
180 Utils.print_line ("Persona store '%s':", store.id);
182 Utils.print_line ("Not prepared.");
188 Utils.print_line ("Persona store '%s' with %u personas:",
189 store.id, store.personas.size);
191 /* List the store's properties */
192 unowned ParamSpec[] properties =
193 store.get_class ().list_properties ();
196 foreach (unowned ParamSpec pspec in properties)
199 string output_string;
201 /* Ignore the personas property if we're printing the personas out */
202 if (show_personas == true && pspec.get_name () == "personas")
205 prop_value = Value (pspec.value_type);
206 store.get_property (pspec.get_name (), ref prop_value);
208 output_string = Utils.property_to_string (store.get_type (),
209 pspec.get_name (), prop_value);
211 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
214 if (show_personas == true)
216 Utils.print_line ("");
217 Utils.print_line ("Personas:");
220 foreach (var persona in store.personas.values)
222 Utils.print_persona (persona);
229 private static string property_to_string (Type object_type,
233 string output_string;
235 /* Overrides for various known properties */
236 if (object_type.is_a (typeof (Individual)) && prop_name == "personas")
238 Set<Persona> personas = (Set<Persona>) prop_value.get_object ();
239 return "List of %u personas".printf (personas.size);
241 else if (object_type.is_a (typeof (PersonaStore)) &&
242 prop_name == "personas")
244 Map<string, Persona> personas =
245 (Map<string, Persona>) prop_value.get_object ();
246 return "Set of %u personas".printf (personas.size);
248 else if (prop_name == "groups" ||
249 prop_name == "local-ids")
251 Set<string> groups = (Set<string>) prop_value.get_object ();
252 output_string = "{ ";
255 foreach (var group in groups)
258 output_string += ", ";
259 output_string += "'%s'".printf (group);
263 output_string += " }";
264 return output_string;
266 else if (prop_name == "avatar")
269 LoadableIcon? avatar = (LoadableIcon) prop_value.get_object ();
271 if (avatar != null &&
272 avatar is FileIcon && ((FileIcon) avatar).get_file () != null)
274 ret = "%p (file: %s)".printf (avatar,
275 ((FileIcon) avatar).get_file ().get_uri ());
277 else if (avatar != null)
279 ret = "%p".printf (avatar);
284 else if (prop_name == "im-addresses" ||
285 prop_name == "web-service-addresses")
288 (MultiMap<string, AbstractFieldDetails<string>>)
289 prop_value.get_object ();
290 output_string = "{ ";
293 foreach (var k in prop_list.get_keys ())
296 output_string += ", ";
297 output_string += "'%s' : { ".printf (k);
300 var v = prop_list.get (k);
305 output_string += ", ";
306 output_string += "'%s'".printf (a.value);
310 output_string += " }";
313 output_string += " }";
314 return output_string;
316 else if (prop_name == "email-addresses" ||
317 prop_name == "phone-numbers" ||
320 output_string = "{ ";
323 (Set<AbstractFieldDetails<string>>) prop_value.get_object ();
325 foreach (var p in prop_list)
329 output_string += ", ";
331 output_string += p.value;
334 output_string += " }";
336 return output_string;
338 else if (prop_name == "birthday")
340 unowned DateTime dobj = (DateTime) prop_value.get_boxed ();
342 return dobj.to_string ();
346 else if (prop_name == "postal-addresses")
348 output_string = "{ ";
351 (Set<PostalAddressFieldDetails>) prop_value.get_object ();
353 foreach (var p in prop_list)
357 output_string += ". ";
359 output_string += p.value.to_string ();
362 output_string += " }";
364 return output_string;
366 else if (prop_name == "notes")
368 Set<NoteFieldDetails> notes =
369 prop_value.get_object () as Set<NoteFieldDetails>;
371 output_string = "{ ";
374 foreach (var note in notes)
378 output_string += ", ";
380 output_string += note.uid;
383 output_string += " }";
385 return output_string;
387 else if (prop_name == "roles")
389 var roles = (Set<RoleFieldDetails>) prop_value.get_object ();
391 output_string = "{ ";
394 foreach (var role in roles)
398 output_string += ", ";
400 output_string += role.value.to_string ();
403 output_string += " }";
405 return output_string;
407 else if (prop_name == "structured-name")
409 unowned StructuredName sn = (StructuredName) prop_value.get_object ();
412 ret = sn.to_string ();
416 return Utils.transform_value_to_string (prop_value);
419 public static string transform_value_to_string (Value prop_value)
421 if (Value.type_transformable (prop_value.type (), typeof (string)))
423 /* Convert to a string value */
424 Value string_value = Value (typeof (string));
425 prop_value.transform (ref string_value);
426 return string_value.get_string ();
430 /* Can't convert the property value to a string */
431 return "Can't convert from type '%s' to '%s'".printf (
432 prop_value.type ().name (), typeof (string).name ());
436 /* FIXME: This can't be in the command_completion_cb() function because Vala
437 * doesn't allow static local variables. Erk. */
438 private static MapIterator<string, Command>? command_name_iter = null;
440 /* Complete a command name, starting with @word. */
441 public static string? command_name_completion_cb (string word,
444 /* Initialise state. Whoever wrote the readline API should be shot. */
446 Utils.command_name_iter = main_client.commands.map_iterator ();
448 while (Utils.command_name_iter.next () == true)
450 string command_name = Utils.command_name_iter.get_key ();
451 if (command_name.has_prefix (word))
456 Utils.command_name_iter = null;
460 /* FIXME: This can't be in the individual_id_completion_cb() function because
461 * Vala doesn't allow static local variables. Erk. */
462 private static MapIterator<string, Individual>? individual_id_iter = null;
464 /* Complete an individual's ID, starting with @word. */
465 public static string? individual_id_completion_cb (string word,
468 /* Initialise state. Whoever wrote the readline API should be shot. */
471 Utils.individual_id_iter =
472 main_client.aggregator.individuals.map_iterator ();
475 while (Utils.individual_id_iter.next () == true)
477 var id = Utils.individual_id_iter.get_key ();
478 if (id.has_prefix (word))
483 Utils.individual_id_iter = null;
487 /* FIXME: This can't be in the individual_id_completion_cb() function because
488 * Vala doesn't allow static local variables. Erk. */
489 private static Iterator<Persona>? persona_uid_iter = null;
491 /* Complete an individual's ID, starting with @word. */
492 public static string? persona_uid_completion_cb (string word,
495 /* Initialise state. Whoever wrote the readline API should be shot. */
498 Utils.individual_id_iter =
499 main_client.aggregator.individuals.map_iterator ();
500 Utils.persona_uid_iter = null;
503 while (Utils.persona_uid_iter != null ||
504 Utils.individual_id_iter.next () == true)
506 var individual = Utils.individual_id_iter.get_value ();
508 if (Utils.persona_uid_iter == null)
510 assert (individual != null);
511 Utils.persona_uid_iter = individual.personas.iterator ();
514 while (Utils.persona_uid_iter.next ())
516 var persona = Utils.persona_uid_iter.get ();
517 if (persona.uid.has_prefix (word))
522 Utils.persona_uid_iter = null;
526 Utils.individual_id_iter = null;
530 /* FIXME: This can't be in the backend_name_completion_cb() function because
531 * Vala doesn't allow static local variables. Erk. */
532 private static Iterator<Backend>? backend_name_iter = null;
534 /* Complete an individual's ID, starting with @word. */
535 public static string? backend_name_completion_cb (string word,
538 /* Initialise state. Whoever wrote the readline API should be shot. */
541 Utils.backend_name_iter =
542 main_client.backend_store.list_backends ().iterator ();
545 while (Utils.backend_name_iter.next () == true)
547 Backend backend = Utils.backend_name_iter.get ();
548 if (backend.name.has_prefix (word))
553 Utils.backend_name_iter = null;
557 /* FIXME: This can't be in the persona_store_id_completion_cb() function
558 * because Vala doesn't allow static local variables. Erk. */
559 private static MapIterator<string, PersonaStore>? persona_store_id_iter =
562 /* Complete a persona store's ID, starting with @word. */
563 public static string? persona_store_id_completion_cb (string word,
566 /* Initialise state. Whoever wrote the readline API should be shot. */
569 Utils.backend_name_iter =
570 main_client.backend_store.list_backends ().iterator ();
571 Utils.persona_store_id_iter = null;
574 while (Utils.persona_store_id_iter != null ||
575 Utils.backend_name_iter.next () == true)
577 if (Utils.persona_store_id_iter == null)
579 Backend backend = Utils.backend_name_iter.get ();
580 Utils.persona_store_id_iter =
581 backend.persona_stores.map_iterator ();
584 while (Utils.persona_store_id_iter.next () == true)
586 var id = Utils.persona_store_id_iter.get_key ();
587 if (id.has_prefix (word))
592 Utils.persona_store_id_iter = null;
596 Utils.backend_name_iter = null;