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 /* The FILE we're printing output to. */
32 public static unowned FileStream output_filestream = GLib.stdout;
34 public static void init ()
36 Utils.indentation_string = "";
37 Utils.indentation = 0;
38 Utils.output_filestream = GLib.stdout;
40 /* Register some general transformation functions */
41 Value.register_transform_func (typeof (Object), typeof (string),
42 Utils.transform_object_to_string);
43 Value.register_transform_func (typeof (Folks.PersonaStore),
44 typeof (string), Utils.transform_persona_store_to_string);
45 Value.register_transform_func (typeof (string[]), typeof (string),
46 Utils.transform_string_array_to_string);
47 Value.register_transform_func (typeof (DateTime), typeof (string),
48 Utils.transform_date_time_to_string);
51 private static void transform_object_to_string (Value src,
54 var output = "%p".printf (src.get_object ());
55 dest = (owned) output;
58 private static void transform_persona_store_to_string (Value src,
61 var store = (Folks.PersonaStore) src;
62 var output = "%p: %s, %s (%s)".printf (store, store.type_id,
63 store.id, store.display_name);
64 dest = (owned) output;
67 private static void transform_string_array_to_string (Value src,
70 unowned string[] array = (string[]) src;
73 foreach (var element in array)
77 output += "'%s'".printf (element);
81 dest = (owned) output;
84 private static void transform_date_time_to_string (Value src, out Value dest)
86 unowned DateTime? date_time = (DateTime?) src;
87 string output = "(null)";
88 if (date_time != null)
90 output = ((!) date_time).format ("%FT%T%z");
93 dest = (owned) output;
96 public static void indent ()
98 /* We indent in increments of two spaces */
99 Utils.indentation += 2;
100 Utils.indentation_string = string.nfill (Utils.indentation, ' ');
103 public static void unindent ()
105 Utils.indentation -= 2;
106 Utils.indentation_string = string.nfill (Utils.indentation, ' ');
110 public static void print_line (string format, ...)
112 /* FIXME: store the va_list temporarily to work around bgo#638308 */
113 var valist = va_list ();
114 string output = format.vprintf (valist);
115 var str = "%s%s\n".printf (Utils.indentation_string, output);
116 Utils.output_filestream.printf (str);
119 public static void print_individual (Individual individual,
122 Utils.print_line ("Individual '%s' with %u personas:",
123 individual.id, individual.personas.size);
125 /* List the Individual's properties */
126 unowned ParamSpec[] properties =
127 individual.get_class ().list_properties ();
130 foreach (unowned ParamSpec pspec in properties)
133 string output_string;
135 /* Ignore the personas property if we're printing the personas out */
136 if (show_personas == true && pspec.get_name () == "personas")
139 prop_value = Value (pspec.value_type);
140 individual.get_property (pspec.get_name (), ref prop_value);
142 output_string = Utils.property_to_string (individual.get_type (),
143 pspec.get_name (), prop_value);
145 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
148 if (show_personas == true)
150 Utils.print_line ("");
151 Utils.print_line ("Personas:");
154 foreach (Persona persona in individual.personas)
155 Utils.print_persona (persona);
161 public static void print_persona (Persona persona)
163 Utils.print_line ("Persona '%s':", persona.uid);
165 /* List the Persona's properties */
166 unowned ParamSpec[] properties =
167 persona.get_class ().list_properties ();
170 foreach (unowned ParamSpec pspec in properties)
173 string output_string;
175 prop_value = Value (pspec.value_type);
176 persona.get_property (pspec.get_name (), ref prop_value);
178 output_string = Utils.property_to_string (persona.get_type (),
179 pspec.get_name (), prop_value);
181 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
186 public static void print_persona_store (PersonaStore store,
189 if (store.is_prepared == false)
191 Utils.print_line ("Persona store '%s':", store.id);
193 Utils.print_line ("Not prepared.");
199 Utils.print_line ("Persona store '%s' with %u personas:",
200 store.id, store.personas.size);
202 /* List the store's properties */
203 unowned ParamSpec[] properties =
204 store.get_class ().list_properties ();
207 foreach (unowned ParamSpec pspec in properties)
210 string output_string;
212 /* Ignore the personas property if we're printing the personas out */
213 if (show_personas == true && pspec.get_name () == "personas")
216 prop_value = Value (pspec.value_type);
217 store.get_property (pspec.get_name (), ref prop_value);
219 output_string = Utils.property_to_string (store.get_type (),
220 pspec.get_name (), prop_value);
222 Utils.print_line ("%-20s %s", pspec.get_nick (), output_string);
225 if (show_personas == true)
227 Utils.print_line ("");
228 Utils.print_line ("Personas:");
231 foreach (var persona in store.personas.values)
233 Utils.print_persona (persona);
240 private static string property_to_string (Type object_type,
244 string output_string;
246 /* Overrides for various known properties */
247 if (object_type.is_a (typeof (Individual)) && prop_name == "personas")
249 Set<Persona> personas = (Set<Persona>) prop_value.get_object ();
250 return "List of %u personas".printf (personas.size);
252 else if (object_type.is_a (typeof (PersonaStore)) &&
253 prop_name == "personas")
255 Map<string, Persona> personas =
256 (Map<string, Persona>) prop_value.get_object ();
257 return "Set of %u personas".printf (personas.size);
259 else if (prop_name == "groups" ||
260 prop_name == "local-ids" ||
261 prop_name == "supported-fields" ||
262 prop_name == "anti-links")
264 Set<string> groups = (Set<string>) prop_value.get_object ();
265 output_string = "{ ";
268 foreach (var group in groups)
271 output_string += ", ";
272 output_string += "'%s'".printf (group);
276 output_string += " }";
277 return output_string;
279 else if (prop_name == "avatar")
282 LoadableIcon? avatar = (LoadableIcon) prop_value.get_object ();
284 if (avatar != null &&
285 avatar is FileIcon && ((FileIcon) avatar).get_file () != null)
287 ret = "%p (file: %s)".printf (avatar,
288 ((FileIcon) avatar).get_file ().get_uri ());
290 else if (avatar != null)
292 ret = "%p".printf (avatar);
297 else if (prop_name == "file")
300 File? file = (File) prop_value.get_object ();
304 ret = "%p (file: %s)".printf (file, file.get_uri ());
309 else if (prop_name == "im-addresses" ||
310 prop_name == "web-service-addresses")
313 (MultiMap<string, AbstractFieldDetails<string>>)
314 prop_value.get_object ();
315 output_string = "{ ";
318 foreach (var k in prop_list.get_keys ())
321 output_string += ", ";
322 output_string += "'%s' : { ".printf (k);
325 var v = prop_list.get (k);
330 output_string += ", ";
331 output_string += "'%s'".printf (a.value);
335 output_string += " }";
338 output_string += " }";
339 return output_string;
341 else if (prop_name == "email-addresses" ||
342 prop_name == "phone-numbers" ||
345 output_string = "{ ";
348 (Set<AbstractFieldDetails<string>>) prop_value.get_object ();
350 foreach (var p in prop_list)
354 output_string += ", ";
356 output_string += p.value;
359 output_string += " }";
361 return output_string;
363 else if (prop_name == "birthday")
365 unowned DateTime dobj = (DateTime) prop_value.get_boxed ();
367 return dobj.to_string ();
371 else if (prop_name == "postal-addresses")
373 output_string = "{ ";
376 (Set<PostalAddressFieldDetails>) prop_value.get_object ();
378 foreach (var p in prop_list)
382 output_string += ". ";
384 output_string += p.value.to_string ();
387 output_string += " }";
389 return output_string;
391 else if (prop_name == "notes")
393 Set<NoteFieldDetails> notes =
394 prop_value.get_object () as Set<NoteFieldDetails>;
396 output_string = "{ ";
399 foreach (var note in notes)
403 output_string += ", ";
405 output_string += note.id;
408 output_string += " }";
410 return output_string;
412 else if (prop_name == "roles")
414 var roles = (Set<RoleFieldDetails>) prop_value.get_object ();
416 output_string = "{ ";
419 foreach (var role in roles)
423 output_string += ", ";
425 output_string += role.value.to_string ();
428 output_string += " }";
430 return output_string;
432 else if (prop_name == "structured-name")
434 unowned StructuredName sn = (StructuredName) prop_value.get_object ();
437 ret = sn.to_string ();
441 return Utils.transform_value_to_string (prop_value);
444 public static string transform_value_to_string (Value prop_value)
446 if (Value.type_transformable (prop_value.type (), typeof (string)))
448 /* Convert to a string value */
449 Value string_value = Value (typeof (string));
450 prop_value.transform (ref string_value);
451 return string_value.get_string ();
455 /* Can't convert the property value to a string */
456 return "Can't convert from type '%s' to '%s'".printf (
457 prop_value.type ().name (), typeof (string).name ());
461 /* FIXME: This can't be in the command_completion_cb() function because Vala
462 * doesn't allow static local variables. Erk. */
463 private static MapIterator<string, Command>? command_name_iter = null;
465 /* Complete a command name, starting with @word. */
466 public static string? command_name_completion_cb (string word,
469 /* Initialise state. Whoever wrote the readline API should be shot. */
471 Utils.command_name_iter = main_client.commands.map_iterator ();
473 while (Utils.command_name_iter.next () == true)
475 string command_name = Utils.command_name_iter.get_key ();
476 if (command_name.has_prefix (word))
481 Utils.command_name_iter = null;
485 /* FIXME: This can't be in the individual_id_completion_cb() function because
486 * Vala doesn't allow static local variables. Erk. */
487 private static MapIterator<string, Individual>? individual_id_iter = null;
489 /* Complete an individual's ID, starting with @word. */
490 public static string? individual_id_completion_cb (string word,
493 /* Initialise state. Whoever wrote the readline API should be shot. */
496 Utils.individual_id_iter =
497 main_client.aggregator.individuals.map_iterator ();
500 while (Utils.individual_id_iter.next () == true)
502 var id = Utils.individual_id_iter.get_key ();
503 if (id.has_prefix (word))
508 Utils.individual_id_iter = null;
512 /* FIXME: This can't be in the individual_id_completion_cb() function because
513 * Vala doesn't allow static local variables. Erk. */
514 private static Iterator<Persona>? persona_uid_iter = null;
516 /* Complete an individual's ID, starting with @word. */
517 public static string? persona_uid_completion_cb (string word,
520 /* Initialise state. Whoever wrote the readline API should be shot. */
523 Utils.individual_id_iter =
524 main_client.aggregator.individuals.map_iterator ();
525 Utils.persona_uid_iter = null;
528 while (Utils.persona_uid_iter != null ||
529 Utils.individual_id_iter.next () == true)
531 var individual = Utils.individual_id_iter.get_value ();
533 if (Utils.persona_uid_iter == null)
535 assert (individual != null);
536 Utils.persona_uid_iter = individual.personas.iterator ();
539 while (Utils.persona_uid_iter.next ())
541 var persona = Utils.persona_uid_iter.get ();
542 if (persona.uid.has_prefix (word))
547 Utils.persona_uid_iter = null;
551 Utils.individual_id_iter = null;
555 /* FIXME: This can't be in the backend_name_completion_cb() function because
556 * Vala doesn't allow static local variables. Erk. */
557 private static Iterator<Backend>? backend_name_iter = null;
559 /* Complete an individual's ID, starting with @word. */
560 public static string? backend_name_completion_cb (string word,
563 /* Initialise state. Whoever wrote the readline API should be shot. */
566 Utils.backend_name_iter =
567 main_client.backend_store.list_backends ().iterator ();
570 while (Utils.backend_name_iter.next () == true)
572 Backend backend = Utils.backend_name_iter.get ();
573 if (backend.name.has_prefix (word))
578 Utils.backend_name_iter = null;
582 /* FIXME: This can't be in the persona_store_id_completion_cb() function
583 * because Vala doesn't allow static local variables. Erk. */
584 private static MapIterator<string, PersonaStore>? persona_store_id_iter =
587 /* Complete a persona store's ID, starting with @word. */
588 public static string? persona_store_id_completion_cb (string word,
591 /* Initialise state. Whoever wrote the readline API should be shot. */
594 Utils.backend_name_iter =
595 main_client.backend_store.list_backends ().iterator ();
596 Utils.persona_store_id_iter = null;
599 while (Utils.persona_store_id_iter != null ||
600 Utils.backend_name_iter.next () == true)
602 if (Utils.persona_store_id_iter == null)
604 Backend backend = Utils.backend_name_iter.get ();
605 Utils.persona_store_id_iter =
606 backend.persona_stores.map_iterator ();
609 while (Utils.persona_store_id_iter.next () == true)
611 var id = Utils.persona_store_id_iter.get_key ();
612 if (id.has_prefix (word))
617 Utils.persona_store_id_iter = null;
621 Utils.backend_name_iter = null;