コード例 #1
0
ファイル: gdaui-entry-wrapper.c プロジェクト: arthurnn/libgda
static void
gdaui_entry_wrapper_set_value_default (GdauiDataEntry *iface, const GValue *value)
{
	GdauiEntryWrapper *wrapper;

	g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface));
	wrapper = (GdauiEntryWrapper*) iface;

	if (wrapper->priv->value_default)
		gda_value_free (wrapper->priv->value_default);

	if (value)
		wrapper->priv->value_default = gda_value_copy ((GValue *) value);
	else
		wrapper->priv->value_default = gda_value_new_null ();

	if (wrapper->priv->default_forced) {
		if (G_VALUE_TYPE (wrapper->priv->value_default) == wrapper->priv->type) {
			check_correct_init (wrapper);
			block_signals (wrapper);
			gdaui_entry_wrapper_set_value (iface, wrapper->priv->value_default);
			unblock_signals (wrapper);
			wrapper->priv->default_forced = TRUE;
		}
		else {
			check_correct_init (wrapper);
			(*wrapper->priv->real_class->real_set_value) (wrapper, NULL);
		}
		gdaui_entry_wrapper_emit_signal (wrapper);
	}
}
コード例 #2
0
ファイル: gdaui-entry-wrapper.c プロジェクト: arthurnn/libgda
static GValue *
gdaui_entry_wrapper_get_value (GdauiDataEntry *iface)
{
	GValue *value = NULL;
	GdauiEntryWrapper *wrapper;

	g_return_val_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface), NULL);
	wrapper = (GdauiEntryWrapper*) iface;

	if (wrapper->priv->null_forced)
		value = gda_value_new_null ();
	else {
		if (wrapper->priv->default_forced) {
			if (G_VALUE_TYPE (wrapper->priv->value_default) == wrapper->priv->type)
				value = gda_value_copy (wrapper->priv->value_default);
			else
				value = gda_value_new_null ();
		}
		else {
			check_correct_init (wrapper);
			value = (wrapper->priv->real_class->real_get_value) (wrapper);
		}
	}

	return value;
}
コード例 #3
0
/**
 * gda_tree_manager_add_new_node_attribute:
 * @manager: a #GdaTreeManager
 * @attribute: an attribute name
 * @value: (allow-none): the attribute's value, or %NULL
 *
 * Requests that for any new node managed (eg. created) by @manager, a new attribute will be set. This allows
 * one to customize the attributes of new nodes created by an existing #GdaTreeManager.
 *
 * As a side effect, if @value is %NULL, then the corresponding attribute, if it was set, is unset.
 *
 * Since: 4.2
 */
void
gda_tree_manager_add_new_node_attribute (GdaTreeManager *manager, const gchar *attribute, const GValue *value)
{
    AddedAttribute *aa = NULL;
    GSList *list;
    g_return_if_fail (GDA_IS_TREE_MANAGER (manager));
    g_return_if_fail (attribute && *attribute);

    for (list = manager->priv->added_attributes; list; list = list->next) {
        if (!strcmp (((AddedAttribute *) list->data)->att_name, attribute)) {
            aa = (AddedAttribute *) list->data;
            break;
        }
    }
    if (!aa) {
        aa = g_new0 (AddedAttribute, 1);
        aa->att_name = g_strdup (attribute);
        manager->priv->added_attributes = g_slist_append (manager->priv->added_attributes, aa);
    }
    else if (aa->value) {
        gda_value_free (aa->value);
        aa->value = NULL;
    }
    if (value)
        aa->value = gda_value_copy (value);

}
コード例 #4
0
ファイル: gda-column.c プロジェクト: arthurnn/libgda
/**
 * gda_column_set_default_value:
 * @column: a #GdaColumn.
 * @default_value: (allow-none): default #GValue for the column
 *
 * Sets @column's default #GValue.
 */
void
gda_column_set_default_value (GdaColumn *column, const GValue *default_value)
{
	g_return_if_fail (GDA_IS_COLUMN (column));

	gda_value_free (column->priv->default_value);
	if (default_value)
		column->priv->default_value = gda_value_copy ( (GValue*)default_value);
	else
		column->priv->default_value = NULL;
}
コード例 #5
0
ファイル: gdaui-entry-wrapper.c プロジェクト: arthurnn/libgda
static void
gdaui_entry_wrapper_set_ref_value (GdauiDataEntry *iface, const GValue *value)
{
	GdauiEntryWrapper *wrapper;
	gboolean changed = TRUE;
	GValue *evalue;

	g_return_if_fail (GDAUI_IS_ENTRY_WRAPPER (iface));
	wrapper = (GdauiEntryWrapper*) iface;
	check_correct_init (wrapper);

	/* compare existing value and the one provided as argument */
	if (wrapper->priv->real_class->value_is_equal_to)
		changed = ! wrapper->priv->real_class->value_is_equal_to (wrapper, value);
	else {
		evalue = gdaui_entry_wrapper_get_value (iface);
		g_assert (evalue);
		if ((!value || (G_VALUE_TYPE (value) == GDA_TYPE_NULL)) &&
		    (G_VALUE_TYPE (evalue) == GDA_TYPE_NULL))
			changed = FALSE;
		else if (!gda_value_differ ((GValue *) value, evalue))
			changed = FALSE;
		gda_value_free (evalue);
	}

	/* get rid on any existing orig value */
	if (wrapper->priv->value_ref) {
		gda_value_free (wrapper->priv->value_ref);
		wrapper->priv->value_ref = NULL;
	}

	/* apply changes, if any */
	if (changed) {
		block_signals (wrapper);
		gdaui_entry_wrapper_set_value (iface, value);
		unblock_signals (wrapper);
	}

	if (value) {
		g_return_if_fail ((G_VALUE_TYPE ((GValue *) value) == wrapper->priv->type) ||
				  (G_VALUE_TYPE ((GValue *) value) == GDA_TYPE_NULL));
		wrapper->priv->value_ref = gda_value_copy ((GValue *) value);
	}
	else
		wrapper->priv->value_ref = gda_value_new_null ();

	/* signal changes if any */
	if (changed)
		gdaui_entry_wrapper_emit_signal (wrapper);
}
コード例 #6
0
/**
 * oseaserver_command_get_dataset:
 * @datamodel: A GdaDataModel to extract data from.
 * 
 * Convenienve function to translate a given @datamodel into a
 * CoyoteDataSet structure.
 * 
 * Return value: A translated CoyoteDataSet or NULL if fails.
 **/
CoyoteDataSet * oseaserver_command_get_dataset          (GdaDataModel *  datamodel)
{
	gint rows, columns, i, j;
	CoyoteDataSet * result;
	GdaValue      * value     = NULL;
	gchar         * str_value = NULL;

	g_return_val_if_fail (datamodel, NULL);

	rows = gda_data_model_get_n_rows (datamodel);
	columns = gda_data_model_get_n_columns (datamodel);
	result = coyote_dataset_new ();

	for (i = 0; i < rows; i++) {
		for (j = 0; j < columns; j ++) {
			
			value = gda_value_copy ( gda_data_model_get_value_at (datamodel, j, i) );
			str_value = gda_value_stringify (value);

			coyote_dataset_add (result, str_value);
			
			g_free (str_value);

			if (value->type != GDA_VALUE_TYPE_NUMERIC)
				gda_value_free (value);
			else {
				#warning We must remove this if when gda fix its gda_value_copy bug
				
			}
				
		}
		
		if (i == (rows - 1))
			break;
		
		coyote_dataset_new_row (result);
	}

	return result;
}
コード例 #7
0
ファイル: gda-column.c プロジェクト: arthurnn/libgda
/**
 * gda_column_copy:
 * @column: column to get a copy from. 	 
 * 	 
 * Creates a new #GdaColumn object from an existing one.
 *
 * Returns: (transfer full): a newly allocated #GdaColumn with a copy of the data 	 
 * in @column. 	 
 */ 	 
GdaColumn * 	 
gda_column_copy (GdaColumn *column) 	 
{ 	 
	GdaColumn *column_copy; 	 
  	
	g_return_val_if_fail (GDA_IS_COLUMN (column), NULL); 	 
  	
	column_copy = gda_column_new (); 	 
	column_copy->priv->defined_size = column->priv->defined_size;
	if (column->priv->id)
		column_copy->priv->id = g_strdup (column->priv->id);
	column_copy->priv->g_type = column->priv->g_type;
	column_copy->priv->allow_null = column->priv->allow_null;
	column_copy->priv->auto_increment = column->priv->auto_increment;
	column_copy->priv->auto_increment_start = column->priv->auto_increment_start;
	column_copy->priv->auto_increment_step = column->priv->auto_increment_step;
	column_copy->priv->position = column->priv->position;
	if (column->priv->default_value)
		column_copy->priv->default_value = gda_value_copy (column->priv->default_value);
	gda_attributes_manager_copy (_gda_column_attributes_manager, (gpointer) column, _gda_column_attributes_manager, (gpointer) column_copy);

	return column_copy; 	 
}
コード例 #8
0
ファイル: gda-report-engine.c プロジェクト: UIKit0/libgda
/*
 * evaluate_expression
 *
 * Evaluates the @expr expression, which must be a valid SQLite expression
 *
 * Returns: a new GValue if no error occurred
 */
static GValue *
evaluate_expression (GdaReportEngine *engine, RunContext *context, const gchar *expr, GError **error)
{
	GdaStatement *stmt;
	GdaSet *plist;
	GdaDataModel *model;
	GValue *retval;
	gchar *sql;
	static GMutex init_mutex;
	GdaConnection *vcnc = NULL;
	GdaSqlParser *parser;

	/* create a virtual connection to execute the expression, if it's the first time */
	g_mutex_lock (&init_mutex);
	if (!vcnc) {
		static GdaVirtualProvider *provider = NULL;

		if (!provider)
			provider = gda_vprovider_data_model_new ();
		vcnc = gda_virtual_connection_open (provider, GDA_CONNECTION_OPTIONS_NONE, error);
		if (! vcnc) {
			g_mutex_unlock (&init_mutex);
			return NULL;
		}
	}
	g_mutex_unlock (&init_mutex);

	/* parser */
	parser = g_object_get_data (G_OBJECT (context->cnc), "__gda_parser");
	if (!parser) {
		parser = gda_connection_create_parser (context->cnc);
		g_object_set_data_full (G_OBJECT (context->cnc), "__gda_parser", 
					parser, g_object_unref);
	}
	
	/* create the stmt 
	 * REM: SQL injection is prevented because only the first statement is kept by GdaStatement 
	 */
	sql = g_strdup_printf ("SELECT %s", expr);
	stmt = gda_sql_parser_parse_string (parser, sql, NULL, error);
	if (!stmt)
		return NULL;

	GdaStatement *lstmt;
	lstmt = rewrite_statement (engine, context, stmt, error);
	g_object_unref (stmt);
	if (!lstmt)
		return NULL;
	
	stmt = lstmt;
	if (!gda_statement_get_parameters (stmt, &plist, error)) {
		g_object_unref (stmt);
		return NULL;
	}

	if (plist) {
		if (!assign_parameters_values (engine, context, plist, error)) {
			g_object_unref (stmt);
			g_object_unref (plist);
			return NULL;
		}
	}

	model = gda_connection_statement_execute_select (vcnc, stmt, plist, error);
	if (plist)
		g_object_unref (plist);
	g_object_unref (stmt);
	if (!model) 
		return NULL;

	if (gda_data_model_get_n_rows (model) != 1) {
		g_set_error (error, 0, 0,
			     _("Expression '%s' should return exactly one value"), expr);
		return NULL;
	}
	retval = (GValue *) gda_data_model_get_value_at (model, 0, 0, error);
	if (retval)
		retval = gda_value_copy (retval);
	g_object_unref (model);
	return retval;
}
コード例 #9
0
static void
manager_real_set (GdaAttributesManager *mgr, gpointer ptr, 
		  const gchar *att_name, GDestroyNotify destroy, 
		  const GValue *value, gboolean steal_value)
{
	ObjAttrs *objattrs;

	g_return_if_fail (att_name);
	if (mgr->for_objects) 
		g_return_if_fail (G_IS_OBJECT (ptr));
	
	gda_mutex_lock (mgr->mutex);

	/* pick up the correct ObjAttrs */
	objattrs = g_hash_table_lookup (mgr->obj_hash, ptr);
	if (!objattrs) {
		objattrs = g_new0 (ObjAttrs, 1);
		objattrs->mgr = mgr;
		objattrs->objects = g_slist_prepend (NULL, ptr);
		objattrs->values_hash = g_hash_table_new_full (attname_hash, attname_equal, 
							       (GDestroyNotify) attname_free,
							       (GDestroyNotify) gda_value_free);
		g_hash_table_insert (mgr->obj_hash, ptr, objattrs);
		if (mgr->for_objects) 
			g_object_weak_ref (G_OBJECT (ptr), (GWeakNotify) obj_destroyed_cb, objattrs);
	}

	if (objattrs->objects->next) {
		/* create another ObjAttrs specifically for @ptr */
		ObjAttrs *objattrs2;
		CopyData cdata;
		objattrs2 = g_new0 (ObjAttrs, 1);
		objattrs2->mgr = mgr;
		objattrs2->objects = g_slist_prepend (NULL, ptr);
		objattrs2->values_hash = g_hash_table_new_full (attname_hash, attname_equal, 
							       (GDestroyNotify) attname_free, 
								(GDestroyNotify) gda_value_free);

		objattrs->objects = g_slist_remove (objattrs->objects, ptr);
		g_hash_table_remove (mgr->obj_hash, ptr);
		g_hash_table_insert (mgr->obj_hash, ptr, objattrs2);

		if (mgr->for_objects) {
			g_object_weak_unref (G_OBJECT (ptr), (GWeakNotify) obj_destroyed_cb, objattrs);
			g_object_weak_ref (G_OBJECT (ptr), (GWeakNotify) obj_destroyed_cb, objattrs2);
		}

		cdata.to_mgr = mgr;
		cdata.ptr = ptr;
		g_hash_table_foreach (objattrs->values_hash, (GHFunc) foreach_copy_func, &cdata);

		objattrs = objattrs2;
	}

	/* Actually add the attribute */
	if (value) {
		AttName *attname;

		attname = g_new (AttName, 1);
		attname->mgr = mgr;
		attname->att_name = (gchar*) att_name; /* NOT duplicated */
		attname->att_name_destroy = destroy;
		if (steal_value)
			g_hash_table_insert (objattrs->values_hash, attname, (GValue*) value);
		else
			g_hash_table_insert (objattrs->values_hash, attname, gda_value_copy (value));
	}
	else {
		AttName attname;
		attname.att_name = (gchar*) att_name;
		g_hash_table_remove (objattrs->values_hash, &attname);
	}
	if (mgr->signal_func && mgr->for_objects)
		mgr->signal_func ((GObject*) ptr, att_name, value, mgr->signal_data);

	gda_mutex_unlock (mgr->mutex);
}
コード例 #10
0
static gboolean
gda_data_model_dir_set_values (GdaDataModel *model, gint row, GList *values, GError **error)
{
	GdaDataModelDir *imodel;
	GList *list;
	gint col;
	FileRow *frow;
	gboolean has_changed = FALSE;

	g_return_val_if_fail (GDA_IS_DATA_MODEL_DIR (model), FALSE);
	g_return_val_if_fail (row >= 0, FALSE);
	imodel = (GdaDataModelDir *) model;
	g_return_val_if_fail (imodel->priv, FALSE);
	if (!values)
		return TRUE;

	if ((guint)row >= imodel->priv->rows->len) {
		gchar *str;
		if (imodel->priv->rows->len > 0)
			str = g_strdup_printf (_("Row %d out of range (0-%d)"), row,
					       imodel->priv->rows->len - 1);
		else
			str = g_strdup_printf (_("Row %d not found (empty data model)"), row);
		add_error (imodel, str);
		g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ROW_OUT_OF_RANGE_ERROR,
			     "%s", str);
		g_free (str);
                return FALSE;
        }

	frow =  g_ptr_array_index (imodel->priv->rows, row);

	for (col = 0, list = values; list; list = list->next, col++) {
		GValue *value = (GValue *) list->data;
		const GValue *cvalue = gda_data_model_get_value_at (model, col, row, error);
		if (!cvalue)
			return FALSE;
		if (!value || !gda_value_compare (value, cvalue))
			continue;

		switch (col) {
		case COL_SIZE:
		case COL_MIME:
		case COL_MD5SUM:
		default:
			add_error (imodel, _("Column cannot be modified"));
			g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
				     "%s", _("Column cannot be modified"));
			return FALSE;
		case COL_DIRNAME: {
			/* check that the new dir still starts with the basedir */
			const gchar *new_path;
			gchar *old_path;
			gint len, base_len;

			new_path = value ? g_value_get_string (value) : "";
			len = strlen (new_path);
			base_len = strlen (imodel->priv->basedir);
			if ((len < base_len) ||
			    (strncmp (new_path, imodel->priv->basedir, base_len))) {
				add_error (imodel,
					   _("New path must be a subpath of the base directory"));
				g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
					     "%s",
					     _("New path must be a subpath of the base directory"));
				return FALSE;
			}

			old_path = compute_dirname (imodel, frow);
			if (dir_equal (new_path, old_path)) {
				g_free (old_path);
				g_print ("Paths are equal...\n");
				break;
			}

			if (!g_mkdir_with_parents (new_path, 0755)) {
				gchar *new_filename;
				GMappedFile *old_file;
				gboolean allok = FALSE;
				gchar *filename;

				new_filename = g_build_filename (new_path,
								 frow->raw_filename_value ? frow->raw_filename_value :
								 g_value_get_string (frow->filename_value), NULL);
				filename = compute_filename (imodel, frow);
				old_file = g_mapped_file_new (filename, FALSE, NULL);
				if (old_file) {
					if (g_file_set_contents (new_filename, g_mapped_file_get_contents (old_file),
								 g_mapped_file_get_length (old_file), NULL)) {
						g_unlink (filename);
						allok = TRUE;

						if (frow->data_value) {
							GdaBlob *blob;
							blob = (GdaBlob *) gda_value_get_blob (frow->data_value);
							if (blob && blob->op)
								_gda_dir_blob_set_filename (GDA_DIR_BLOB_OP (blob->op),
											   new_filename);
						}
					}
					g_mapped_file_unref (old_file);
				}
				if (!allok) {
					gchar *str;
					str = g_strdup_printf (_("Could not rename file '%s' to '%s'"),
							       filename, new_filename);
					add_error (imodel, str);
					g_set_error (error,
						     GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
						     "%s", str);
					g_free (str);
					g_free (new_filename);
					g_free (filename);
					g_free (old_path);
					return FALSE;
				}
				else {
					/* renaming succeeded => update FileRow */
#ifndef G_OS_WIN32
					g_rmdir (old_path);
#endif
					g_free (frow->reldir);
					frow->reldir = g_strdup (new_path + base_len);
				}
				g_free (filename);
				g_free (new_filename);
				has_changed = TRUE;
			}
			else {
				gchar *str;
				str = g_strdup_printf (_("Could not create directory '%s'"), new_path);
				add_error (imodel, str);
				g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
					     "%s", str);
				g_free (str);
				g_free (old_path);
				return FALSE;
			}
			g_free (old_path);
			break;
		}
		case COL_FILENAME: {
			gchar *new_filename;
			gchar *filename;

			new_filename = g_build_filename (imodel->priv->basedir,
							 frow->reldir,
							 g_value_get_string (value), NULL);
			filename = compute_filename (imodel, frow);
			if (g_rename (filename, new_filename)) {
				gchar *str;
				str = g_strdup_printf (_("Could not rename file '%s' to '%s'"), filename, new_filename);
				add_error (imodel, str);
				g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
					     "%s", str);
				g_free (str);
				g_free (new_filename);
				g_free (filename);
				return FALSE;
			}
			else {
				/* renaming succeeded => update FileRow */
				gda_value_free (frow->filename_value);
				frow->filename_value = gda_value_copy (value);
				if (frow->raw_filename_value) {
					g_free (frow->raw_filename_value);
					frow->raw_filename_value = g_strdup (g_value_get_string (value));
				}
				if (frow->data_value) {
					GdaBlob *blob;
					blob = (GdaBlob *) gda_value_get_blob (frow->data_value);
					if (blob && blob->op)
						_gda_dir_blob_set_filename (GDA_DIR_BLOB_OP (blob->op),
									   new_filename);
				}
			}
			g_free (new_filename);
			g_free (filename);
			has_changed = TRUE;
			break;
		}
		case COL_DATA: {
			GdaBlob *blob = NULL;
			if (gda_value_isa (value, GDA_TYPE_BLOB)) {
				blob = (GdaBlob *) gda_value_get_blob (value);
			}
			else if (gda_value_isa (value, GDA_TYPE_BINARY)) {
				blob = (GdaBlob *) gda_value_get_binary (value);
			}
			else if (gda_value_is_null (value)) {
				/* create a new empty blob */
				blob = g_new0 (GdaBlob, 1);
			}

			if (blob) {
				GdaBlobOp *op;
				gchar *filename;
				filename = compute_filename (imodel, frow);
				op = _gda_dir_blob_op_new (filename);
				if (gda_blob_op_write_all (op, blob) < 0) {
					gchar *str;
					str = g_strdup_printf (_("Could not overwrite contents of file '%s'"), filename);
					add_error (imodel, str);
					g_set_error (error, GDA_DATA_MODEL_ERROR,
						     GDA_DATA_MODEL_ACCESS_ERROR,
						     "%s", str);
					g_free (str);
					g_object_unref (op);
					g_free (filename);
					return FALSE;
				}
				g_object_unref (op);
				if (gda_value_is_null (value))
					g_free (blob);
				has_changed = FALSE;
				has_changed = update_file_size (frow, filename);
				has_changed = update_file_md5sum (frow, filename) || has_changed;
				has_changed = update_file_mime (frow, filename) || has_changed;
				g_free (filename);
			}
			else {
				add_error (imodel, _("Wrong type of data"));
				g_set_error (error, GDA_DATA_MODEL_ERROR, GDA_DATA_MODEL_ACCESS_ERROR,
					     "%s", _("Wrong type of data"));
				return FALSE;
			}
			break;
		}
		}
	}

	if (has_changed)
		/* signal changes to data model */
		gda_data_model_row_updated ((GdaDataModel *) model, row);

	return TRUE;
}
コード例 #11
0
ファイル: entry-properties.c プロジェクト: arthurnn/libgda
static void
entry_info_fetched_done (EntryProperties *eprop, GdaLdapEntry *entry)
{
	GtkTextBuffer *tbuffer;
	GtkTextIter start, end;
	TConnection *tcnc = eprop->priv->tcnc;
	
	tbuffer = eprop->priv->text;
	gtk_text_buffer_get_start_iter (tbuffer, &start);
	gtk_text_buffer_get_end_iter (tbuffer, &end);
	gtk_text_buffer_delete (tbuffer, &start, &end);

	guint i;
	GtkTextIter current;

	gtk_text_buffer_get_start_iter (tbuffer, &current);

	/* DN */
	gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, _("Distinguished Name:"), -1,
						  "section", NULL);
	gtk_text_buffer_insert (tbuffer, &current, "\n", -1);
	gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, " ", -1, "starter", NULL);
	gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, entry->dn, -1,
						  "data", NULL);
	gtk_text_buffer_insert (tbuffer, &current, "\n", -1);

	/* other attributes */
	const gchar *basedn;
	GdaDataHandler *ts_dh = NULL;
	basedn = t_connection_ldap_get_base_dn (tcnc);

	for (i = 0; i < entry->nb_attributes; i++) {
		GdaLdapAttribute *attr;
		gchar *tmp;
		attr = entry->attributes [i];
		tmp = g_strdup_printf ("%s:", attr->attr_name);
		gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, tmp, -1, "section", NULL);
		g_free (tmp);
		gtk_text_buffer_insert (tbuffer, &current, "\n", -1);

		guint j;
		for (j = 0; j < attr->nb_values; j++) {
			const GValue *cvalue;
			cvalue = attr->values [j];

			gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, " ", -1,
								  "starter", NULL);

			if (G_VALUE_TYPE (cvalue) == GDA_TYPE_BINARY) {
				GValue *copyvalue;
				GtkTextTagTable *table;
				GtkTextTag *tag;
				GtkTextMark *mark;

				copyvalue = gda_value_copy (cvalue);
				table = gtk_text_buffer_get_tag_table (tbuffer);
				tag = gtk_text_tag_new (NULL);
				gtk_text_tag_table_add (table, tag);
				g_object_set_data_full ((GObject*) tag, "binvalue",
							copyvalue, (GDestroyNotify) gda_value_free);
				g_object_unref ((GObject*) tag);

				mark = gtk_text_buffer_create_mark (tbuffer, NULL, &current, TRUE);

				GdkPixbuf *pixbuf;
				pixbuf = data_to_pixbuf (cvalue);
				if (pixbuf) {
					gtk_text_buffer_insert_pixbuf (tbuffer, &current, pixbuf); 
					g_object_unref (pixbuf);
				}
				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);
					gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current,
										  tmp, -1,
										  "data", NULL);
					g_free (tmp);
				}
				GtkTextIter before;
				gtk_text_buffer_get_iter_at_mark (tbuffer, &before, mark);
				gtk_text_buffer_apply_tag (tbuffer, tag, &before, &current);
				gtk_text_buffer_delete_mark (tbuffer, mark);
					
				gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current,
									  "\n", 1,
									  "data", NULL);
			}
			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 (tmp) {
					if (*tmp &&
					    ((basedn && g_str_has_suffix (tmp, basedn)) || !basedn) &&
					    gda_ldap_is_dn (tmp)) {
						/* we have a DN */
						GtkTextTag *tag;
						tag = gtk_text_buffer_create_tag (tbuffer, NULL,
										  "foreground", "blue",
										  "weight", PANGO_WEIGHT_NORMAL,
										  "underline", PANGO_UNDERLINE_SINGLE,
										  NULL);
						g_object_set_data_full (G_OBJECT (tag), "dn",
									g_strdup (tmp), g_free);
						gtk_text_buffer_insert_with_tags (tbuffer, &current,
										  tmp, -1,
										  tag, NULL);
					}
					else if (attr->attr_name &&
						 !g_ascii_strcasecmp (attr->attr_name, "objectClass")) {
						GtkTextTag *tag;
						tag = gtk_text_buffer_create_tag (tbuffer, NULL,
										  "foreground", "blue",
										  "weight", PANGO_WEIGHT_NORMAL,
										  "underline", PANGO_UNDERLINE_SINGLE,
										  NULL);
						g_object_set_data_full (G_OBJECT (tag), "class",
									g_strdup (tmp), g_free);
						gtk_text_buffer_insert_with_tags (tbuffer, &current,
										  tmp, -1,
										  tag, NULL);
					}
					else
						gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, tmp, -1,
											  "data", NULL);

					gchar *extrainfo = NULL;
					if (!strncmp (attr->attr_name, "shadow", 6) &&
					    (!strcmp (attr->attr_name, "shadowLastChange") ||
					     !strcmp (attr->attr_name, "shadowMax") ||
					     !strcmp (attr->attr_name, "shadowMin") ||
					     !strcmp (attr->attr_name, "shadowInactive") ||
					     !strcmp (attr->attr_name, "shadowExpire")))
						extrainfo = unix_shadow_to_string (tmp, attr->attr_name);
					else if (!strcmp (attr->attr_name, "badPasswordTime") ||
						 !strcmp (attr->attr_name, "lastLogon") ||
						 !strcmp (attr->attr_name, "pwdLastSet") ||
						 !strcmp (attr->attr_name, "accountExpires") ||
						 !strcmp (attr->attr_name, "lockoutTime") ||
						 !strcmp (attr->attr_name, "lastLogonTimestamp"))
						extrainfo = ad_1601_timestamp_to_string (tmp, attr->attr_name);
					else if (!strcmp (attr->attr_name, "userAccountControl"))
						extrainfo = ad_1601_uac_to_string (tmp);
					else if (!strcmp (attr->attr_name, "sAMAccountType"))
						extrainfo = ad_sam_account_type_to_string (tmp);

					if (extrainfo) {
						gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current,
											  " ", 1,
											  "data", NULL);
						gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current,
											  extrainfo, -1,
											  "convdata", NULL);
						g_free (extrainfo);
					}
					g_free (tmp);
				}
				else {
					gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current, _("Can't display attribute value"), -1,
										  "error", NULL);
				}
				gtk_text_buffer_insert_with_tags_by_name (tbuffer, &current,
									  "\n", 1,
									  "data", NULL);
			}
		}
	}
	if (ts_dh)
		g_object_unref (ts_dh);
	gda_ldap_entry_free (entry);


	if (eprop->priv->text_search && gtk_widget_get_visible (eprop->priv->text_search))
		text_search_rerun (TEXT_SEARCH (eprop->priv->text_search));
}