/*
 * @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);
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
/*
 * 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);
}