/* * @manager: a #GdaTreeManager object * @node: (allow-none): a #GdaTreeNode object, or %NULL * @children_nodes: a list of #GdaTreeNode nodes which have previously been created by a similar call and * need to be updated ore moved * @out_error: (allow-none): a boolean to store if there was an error (can be %NULL) * @error: a place to store errors, or %NULL * * Creates (or updates) the list of #GdaTreeNode objects which are placed as children of @node. The returned * list will completely replace the existing list of nodes managed by @manager (as children of @node). * * If a node is already present in @children_nodes and needs to be kept in the new list, then it should be added * to the returned list and its reference count should be increased by one. * * Returns: a new list of #GdaTreeNode objects. * * Since: 4.2 */ void _gda_tree_manager_update_children (GdaTreeManager *manager, GdaTreeNode *node, const GSList *children_nodes, gboolean *out_error, GError **error) { GSList *nodes_list = NULL; GSList *list; g_return_if_fail (GDA_IS_TREE_MANAGER (manager)); g_return_if_fail (GDA_IS_TREE_NODE (node)); if (out_error) *out_error = FALSE; if (manager->priv->update_func) nodes_list = manager->priv->update_func (manager, node, children_nodes, out_error, error); else { GdaTreeManagerClass *klass; klass = (GdaTreeManagerClass*) G_OBJECT_GET_CLASS (manager); if (klass->update_children) nodes_list = klass->update_children (manager, node, children_nodes, out_error, error); } _gda_tree_node_add_children (node, manager, nodes_list); /* calling sub managers for each new node */ for (list = nodes_list; list; list = list->next) { GSList *sl; for (sl = manager->priv->sub_managers; sl; sl = sl->next) { if (manager->priv->recursive) { gboolean lout_error = FALSE; GdaTreeNode *parent = GDA_TREE_NODE (list->data); GdaTreeManager *mgr = (GdaTreeManager *) sl->data; _gda_tree_manager_update_children (mgr, parent, _gda_tree_node_get_children_for_manager (parent, mgr), &lout_error, error); if (lout_error) { if (out_error) *out_error = TRUE; return; } } else _gda_tree_node_add_children (GDA_TREE_NODE (list->data), (GdaTreeManager *) sl->data, NULL); } } if (nodes_list) g_slist_free (nodes_list); }
static gchar * tree_to_string_default (GdaTree *tree, FILE *stream, GdaSet *options) { GString *string; GSList *top, *list; gchar **attr_names = NULL; guint attr_names_size = 0; guint *cols_size = NULL; guint max_prefix_size = 0; g_return_val_if_fail (GDA_IS_TREE (tree), NULL); if (options) { const GValue *cvalue; cvalue = gda_set_get_holder_value (options, "GDA_TREE_COLUMN_NAMES"); if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING) && g_value_get_string (cvalue)) { attr_names = g_strsplit (g_value_get_string (cvalue), ",", 0); if (attr_names) { guint i; for (i = 0; attr_names [i]; i++) g_strstrip (attr_names [i]); attr_names_size = i; } } } string = g_string_new (""); top = gda_tree_get_nodes_in_path (tree, NULL, FALSE); if (attr_names) { /* determine prefix's max size and columns' max size */ cols_size = g_new0 (guint, attr_names_size); for (list = top; list; list = list->next) { tree_node_to_string (GDA_TREE_NODE (list->data), FALSE, list->next ? TRUE : FALSE, "", attr_names, cols_size, 0, &max_prefix_size, NULL); } guint i, j; for (i = 0; attr_names [i]; i++) { guint size = 0; if (g_utf8_validate (attr_names[i], -1, NULL)) size += g_utf8_strlen (attr_names[i], -1); else size += strlen (attr_names[i]); cols_size[i] = MAX (cols_size[i], size); } /* output column names */ const gchar *title; title = (const gchar*) g_object_get_data ((GObject*) tree, "GDA_TREE_TITLE"); if (title) { g_string_append (string, title); for (j = g_utf8_strlen (title, -1); j < max_prefix_size; j++) g_string_append_c (string, ' '); } else { for (j = 0; j < max_prefix_size; j++) g_string_append_c (string, ' '); } /* output column values */ for (i = 0; attr_names [i]; i++) { if (cols_size[i] == 0) continue; g_string_append (string, SEP); g_string_append (string, attr_names[i]); guint size = 0; if (g_utf8_validate (attr_names[i], -1, NULL)) size += g_utf8_strlen (attr_names[i], -1); else size += strlen (attr_names[i]); for (j = size; j < cols_size[i]; j++) g_string_append_c (string, ' '); } g_string_append_c (string, '\n'); } for (list = top; list; list = list->next) tree_node_to_string (GDA_TREE_NODE (list->data), FALSE, list->next ? TRUE : FALSE, "", attr_names, cols_size, max_prefix_size, NULL, string); g_slist_free (top); if (attr_names) { g_strfreev (attr_names); g_free (cols_size); } return g_string_free (string, FALSE); }
/* * REM: if @attr_names is not NULL, then @cols_size will have the same number of items * * - Optionally called once with @out_max_prefix_size not %NULL and @in_string %NULL => compute * cols_size[x] and *out_max_prefix_size * - Called once with @in_string not %NULL and @out_max_prefix_size %NULL */ static void tree_node_to_string (GdaTreeNode *node, gboolean has_parent, gboolean has_next_sibling, const gchar *prefix, gchar **attr_names, guint *cols_size, guint max_prefix_size, guint *out_max_prefix_size, GString *in_string) { gchar *pipe = "|"; gchar *prefix2 = "|- "; gchar *prefix3 = "`- "; pipe = "│"; prefix2 = "├─ "; prefix3 = "└─ "; #define SEP " " const GValue *cvalue; gchar *p; const gchar *cstr; guint i; /* prefix */ if (has_next_sibling) p = g_strdup_printf ("%s%s", prefix, prefix2); else p = g_strdup_printf ("%s%s", prefix, prefix3); if (in_string) g_string_append (in_string, p); i = g_utf8_strlen (p, -1); g_free (p); /* node name */ cvalue = gda_tree_node_get_node_attribute (node, GDA_ATTRIBUTE_NAME); cstr = cvalue && g_value_get_string (cvalue)? g_value_get_string (cvalue) : "???"; if (in_string) g_string_append (in_string, cstr); /* padding */ if (in_string) { for (i = i + g_utf8_strlen (cstr, -1); i < max_prefix_size; i++) g_string_append_c (in_string, ' '); } else { guint size = i; if (g_utf8_validate (cstr, -1, NULL)) size += g_utf8_strlen (cstr, -1); else size += strlen (cstr); *out_max_prefix_size = MAX (size, *out_max_prefix_size); } /* some node's attributes */ if (attr_names) { for (i = 0; attr_names[i] && *attr_names[i]; i++) { guint colsize = 0; if (in_string) { if (cols_size [i] == 0) continue; /* ignore this attribute as it's not set */ g_string_append (in_string, SEP); } cvalue = gda_tree_node_get_node_attribute (node, attr_names[i]); if (cvalue && (G_VALUE_TYPE (cvalue) != GDA_TYPE_NULL)) { gchar *tmp = NULL; if (G_VALUE_TYPE (cvalue) == G_TYPE_FLOAT) tmp = g_strdup_printf ("%.01f", g_value_get_float (cvalue)); else { GdaDataHandler *dh; dh = gda_data_handler_get_default (G_VALUE_TYPE (cvalue)); if (dh) tmp = gda_data_handler_get_str_from_value (dh, cvalue); else tmp = gda_value_stringify (cvalue); } if (in_string) { gboolean right = FALSE; if ((G_VALUE_TYPE (cvalue) == G_TYPE_INT) || (G_VALUE_TYPE (cvalue) == G_TYPE_UINT) || (G_VALUE_TYPE (cvalue) == G_TYPE_INT64) || (G_VALUE_TYPE (cvalue) == G_TYPE_UINT64) || (G_VALUE_TYPE (cvalue) == G_TYPE_FLOAT) || (G_VALUE_TYPE (cvalue) == G_TYPE_DOUBLE) || (G_VALUE_TYPE (cvalue) == G_TYPE_CHAR) || (G_VALUE_TYPE (cvalue) == GDA_TYPE_SHORT) || (G_VALUE_TYPE (cvalue) == GDA_TYPE_USHORT)) right = TRUE; if (right) { /* right align */ guint j; for (j = tmp ? g_utf8_strlen (tmp, -1) : 0; j < cols_size [i]; j++) g_string_append_c (in_string, ' '); if (tmp) { if (g_utf8_strlen (tmp, -1) > cols_size[i]) tmp [cols_size [i]] = 0; g_string_append (in_string, tmp); } } else { /* left align */ if (tmp) { if (g_utf8_strlen (tmp, -1) > cols_size[i]) tmp [cols_size [i]] = 0; g_string_append (in_string, tmp); } guint j; for (j = tmp ? g_utf8_strlen (tmp, -1) : 0; j < cols_size [i]; j++) g_string_append_c (in_string, ' '); } } else { if (tmp) { if (g_utf8_validate (tmp, -1, NULL)) colsize += g_utf8_strlen (tmp, -1); else colsize += strlen (tmp); } cols_size [i] = MAX (cols_size [i], colsize); } g_free (tmp); } else if (in_string) { guint j; for (j = 0; j < cols_size [i]; j++) g_string_append_c (in_string, ' '); } } } if (in_string) g_string_append_c (in_string, '\n'); /* children */ gchar *ch_prefix; if (has_next_sibling) ch_prefix = g_strdup_printf ("%s%s ", prefix, pipe); else ch_prefix = g_strdup_printf ("%s ", prefix); GSList *top, *list; top = gda_tree_node_get_children (node); for (list = top; list; list = list->next) tree_node_to_string (GDA_TREE_NODE (list->data), TRUE, list->next ? TRUE : FALSE, ch_prefix, attr_names, cols_size, max_prefix_size, out_max_prefix_size, in_string); g_slist_free (top); g_free (ch_prefix); }