1 /*
2  * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3  * Copyright (C) 2010 David King <davidk@openismus.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 
20 #include <libgda/libgda.h>
21 #include <glib/gi18n-lib.h>
22 #include <string.h>
23 #include "browser-canvas.h"
24 #include "browser-canvas-column.h"
25 #include "browser-canvas-table.h"
26 
27 static void browser_canvas_column_class_init (BrowserCanvasColumnClass * class);
28 static void browser_canvas_column_init       (BrowserCanvasColumn * drag);
29 static void browser_canvas_column_dispose   (GObject *object);
30 
31 static void browser_canvas_column_set_property (GObject *object,
32 					     guint param_id,
33 					     const GValue *value,
34 					     GParamSpec *pspec);
35 static void browser_canvas_column_get_property (GObject *object,
36 					     guint param_id,
37 					     GValue *value,
38 					     GParamSpec *pspec);
39 
40 static void browser_canvas_column_drag_data_get (BrowserCanvasItem *citem, GdkDragContext *drag_context,
41 						 GtkSelectionData *data, guint info, guint time);
42 
43 static void browser_canvas_column_extra_event  (BrowserCanvasItem * citem, GdkEventType event_type);
44 enum
45 {
46 	PROP_0,
47 	PROP_META_STRUCT,
48 	PROP_COLUMN,
49 };
50 
51 struct _BrowserCanvasColumnPrivate
52 {
53 	GdaMetaStruct      *mstruct;
54 	GdaMetaTableColumn *column;
55 };
56 
57 /* get a pointer to the parents to be able to call their destructor */
58 static GObjectClass *column_parent_class = NULL;
59 
60 GType
browser_canvas_column_get_type(void)61 browser_canvas_column_get_type (void)
62 {
63 	static GType type = 0;
64 
65         if (G_UNLIKELY (type == 0)) {
66 		static const GTypeInfo info = {
67 			sizeof (BrowserCanvasColumnClass),
68 			(GBaseInitFunc) NULL,
69 			(GBaseFinalizeFunc) NULL,
70 			(GClassInitFunc) browser_canvas_column_class_init,
71 			NULL,
72 			NULL,
73 			sizeof (BrowserCanvasColumn),
74 			0,
75 			(GInstanceInitFunc) browser_canvas_column_init,
76 			0
77 		};
78 
79 		type = g_type_register_static (TYPE_BROWSER_CANVAS_TEXT, "BrowserCanvasColumn", &info, 0);
80 	}
81 
82 	return type;
83 }
84 
85 
86 
87 static void
browser_canvas_column_class_init(BrowserCanvasColumnClass * klass)88 browser_canvas_column_class_init (BrowserCanvasColumnClass *klass)
89 {
90 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
91 	BrowserCanvasItemClass *iclass = BROWSER_CANVAS_ITEM_CLASS (klass);
92 
93 	column_parent_class = g_type_class_peek_parent (klass);
94 
95 	object_class->dispose = browser_canvas_column_dispose;
96 
97 	iclass->drag_data_get = browser_canvas_column_drag_data_get;
98 	iclass->extra_event = browser_canvas_column_extra_event;
99 
100 	/* Properties */
101 	object_class->set_property = browser_canvas_column_set_property;
102 	object_class->get_property = browser_canvas_column_get_property;
103 
104 	g_object_class_install_property
105                 (object_class, PROP_META_STRUCT,
106                  g_param_spec_object ("meta-struct", NULL, NULL,
107 				      GDA_TYPE_META_STRUCT,
108 				      (G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)));
109 	g_object_class_install_property
110                 (object_class, PROP_COLUMN,
111                  g_param_spec_pointer ("column", NULL, NULL,
112 				       (G_PARAM_READABLE | G_PARAM_WRITABLE)));
113 }
114 
115 static void
browser_canvas_column_init(BrowserCanvasColumn * column)116 browser_canvas_column_init (BrowserCanvasColumn * column)
117 {
118 	column->priv = g_new0 (BrowserCanvasColumnPrivate, 1);
119 	column->priv->mstruct = NULL;
120 	column->priv->column = NULL;
121 }
122 
123 static void
browser_canvas_column_dispose(GObject * object)124 browser_canvas_column_dispose (GObject   * object)
125 {
126 	BrowserCanvasColumn *cf;
127 	g_return_if_fail (object != NULL);
128 	g_return_if_fail (IS_BROWSER_CANVAS_COLUMN (object));
129 
130 	cf = BROWSER_CANVAS_COLUMN (object);
131 	if (cf->priv) {
132 		if (cf->priv->mstruct)
133 			g_object_unref (cf->priv->mstruct);
134 		g_free (cf->priv);
135 		cf->priv = NULL;
136 	}
137 
138 	/* for the parent class */
139 	column_parent_class->dispose (object);
140 }
141 
142 static void
browser_canvas_column_set_property(GObject * object,guint param_id,const GValue * value,GParamSpec * pspec)143 browser_canvas_column_set_property (GObject *object,
144 				    guint param_id,
145 				    const GValue *value,
146 				    GParamSpec *pspec)
147 {
148 	BrowserCanvasColumn *cf = NULL;
149 	GdaMetaTableColumn* column = NULL;
150 	GString *string = NULL;
151 
152 	cf = BROWSER_CANVAS_COLUMN (object);
153 
154 	switch (param_id) {
155 	case PROP_META_STRUCT:
156 		cf->priv->mstruct = g_value_dup_object (value);
157 		break;
158 	case PROP_COLUMN:
159 		g_return_if_fail (cf->priv->mstruct);
160 		column = g_value_get_pointer (value);
161 
162 		cf->priv->column = column;
163 		/* column name */
164 		g_object_set (object, "text", column->column_name, NULL);
165 
166 		/* attributes setting */
167 		string = g_string_new ("");
168 		if (column->column_type)
169 			g_string_append_printf (string, _("Type: %s"), column->column_type);
170 
171 		g_object_set (object,
172 			      "highlight_color", BROWSER_CANVAS_DB_TABLE_COLOR,
173 			      "text_underline", !column->nullok,
174 			      "text_bold", column->pkey,
175 			      NULL);
176 
177 		if (*string->str)
178 			g_object_set (object, "tip-text", string->str, NULL);
179 		else
180 			g_object_set (object, "tip-text", NULL, NULL);
181 		g_string_free (string, TRUE);
182 		break;
183 	default:
184 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
185 		break;
186 	}
187 }
188 
189 static void
browser_canvas_column_get_property(GObject * object,guint param_id,GValue * value,GParamSpec * pspec)190 browser_canvas_column_get_property (GObject *object,
191 				    guint param_id,
192 				    GValue *value,
193 				    GParamSpec *pspec)
194 {
195 	BrowserCanvasColumn *cf;
196 
197 	cf = BROWSER_CANVAS_COLUMN (object);
198 
199 	switch (param_id) {
200 	case PROP_META_STRUCT:
201 		g_value_set_object (value, cf->priv->mstruct);
202 		break;
203 	case PROP_COLUMN:
204 		g_value_set_pointer (value, cf->priv->column);
205 		break;
206 	default:
207 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
208 		break;
209 	}
210 }
211 
212 static void
browser_canvas_column_extra_event(BrowserCanvasItem * citem,GdkEventType event_type)213 browser_canvas_column_extra_event  (BrowserCanvasItem *citem, GdkEventType event_type)
214 {
215 	if (event_type == GDK_LEAVE_NOTIFY)
216 		browser_canvas_text_set_highlight (BROWSER_CANVAS_TEXT (citem), FALSE);
217 }
218 
219 /**
220  * browser_canvas_column_new: (skip)
221  * @parent: (allow-none): the parent item, or %NULL
222  * @mstruct: the #GdaMetaStruct @column is from
223  * @column: the represented entity's column
224  * @x: the x coordinate of the text
225  * @y: the y coordinate of the text
226  * @...: optional pairs of property names and values, and a terminating %NULL.
227  *
228  * Creates a new #BrowserCanvasColumn object
229  */
230 GooCanvasItem*
browser_canvas_column_new(GooCanvasItem * parent,GdaMetaStruct * mstruct,GdaMetaTableColumn * column,gdouble x,gdouble y,...)231 browser_canvas_column_new (GooCanvasItem *parent, GdaMetaStruct *mstruct, GdaMetaTableColumn *column,
232 			   gdouble x, gdouble y, ...)
233 {
234 	GooCanvasItem *item;
235 	const char *first_property;
236 	va_list var_args;
237 
238 	g_return_val_if_fail (GDA_IS_META_STRUCT (mstruct), NULL);
239 
240 	item = g_object_new (TYPE_BROWSER_CANVAS_COLUMN, "meta-struct", mstruct, NULL);
241 
242 	if (parent) {
243 		goo_canvas_item_add_child (parent, item, -1);
244 		g_object_unref (item);
245 	}
246 
247 	va_start (var_args, y);
248 	first_property = va_arg (var_args, char*);
249 	if (first_property)
250 		g_object_set_valist ((GObject*) item, first_property, var_args);
251 	va_end (var_args);
252 
253 	g_object_set (G_OBJECT (item), "column", column, NULL);
254 	goo_canvas_item_translate (item, x, y);
255 
256 	return item;
257 }
258 
259 
260 /**
261  * browser_canvas_column_get_column
262  * @column: a #BrowserCanvasColumn object
263  *
264  * Get the #GdaMetaTableColumn which @column represents
265  *
266  * Returns: the object implementing the #GdaMetaTableColumn interface
267  */
268 GdaMetaTableColumn *
browser_canvas_column_get_column(BrowserCanvasColumn * column)269 browser_canvas_column_get_column (BrowserCanvasColumn *column)
270 {
271 	g_return_val_if_fail (IS_BROWSER_CANVAS_COLUMN (column), NULL);
272 	g_return_val_if_fail (column->priv, NULL);
273 
274 	return column->priv->column;
275 }
276 
277 
278 /**
279  * browser_canvas_column_get_parent_item
280  * @column: a #BrowserCanvasColumn object
281  *
282  * Get the #BrowserCanvasTable in which @column is
283  *
284  * Returns: the #BrowserCanvasTable in which @column is, or %NULL
285  */
286 BrowserCanvasTable *
browser_canvas_column_get_parent_item(BrowserCanvasColumn * column)287 browser_canvas_column_get_parent_item (BrowserCanvasColumn *column)
288 {
289 	GooCanvasItem *ci;
290 
291 	g_return_val_if_fail (IS_BROWSER_CANVAS_COLUMN (column), NULL);
292 	for (ci = goo_canvas_item_get_parent (GOO_CANVAS_ITEM (column));
293 	     ci && !IS_BROWSER_CANVAS_TABLE (ci);
294 	     ci = goo_canvas_item_get_parent (ci));
295 
296 	return (BrowserCanvasTable *) ci;
297 }
298 
299 static void
browser_canvas_column_drag_data_get(BrowserCanvasItem * citem,G_GNUC_UNUSED GdkDragContext * drag_context,GtkSelectionData * data,G_GNUC_UNUSED guint info,G_GNUC_UNUSED guint time)300 browser_canvas_column_drag_data_get (BrowserCanvasItem *citem, G_GNUC_UNUSED GdkDragContext *drag_context,
301 				     GtkSelectionData *data, G_GNUC_UNUSED guint info,
302 				     G_GNUC_UNUSED guint time)
303 {
304 	BrowserCanvasColumn *column;
305 	BrowserCanvasTable *ctable;
306 	GdaMetaTable *mtable;
307 
308 	column = BROWSER_CANVAS_COLUMN (citem);
309 	ctable = browser_canvas_column_get_parent_item (column);
310 	g_object_get (G_OBJECT (ctable), "table", &mtable, NULL);
311 	if (!column->priv->column || !mtable)
312 		return;
313 
314 	GdaMetaDbObject *dbo;
315 	gchar *str, *tmp1, *tmp2, *tmp3, *tmp4;
316 
317 	dbo = GDA_META_DB_OBJECT (mtable);
318 	tmp1 = gda_rfc1738_encode (dbo->obj_schema);
319 	tmp2 = gda_rfc1738_encode (dbo->obj_name);
320 	tmp3 = gda_rfc1738_encode (dbo->obj_short_name);
321 	tmp4 = gda_rfc1738_encode (column->priv->column->column_name);
322 	str = g_strdup_printf ("OBJ_TYPE=tablecolumn;OBJ_SCHEMA=%s;OBJ_NAME=%s;OBJ_SHORT_NAME=%s;COL_NAME=%s",
323 			       tmp1, tmp2, tmp3, tmp4);
324 	g_free (tmp1);
325 	g_free (tmp2);
326 	g_free (tmp3);
327 	g_free (tmp4);
328 	gtk_selection_data_set (data, gtk_selection_data_get_target (data), 8, (guchar*) str, strlen (str));
329 	g_free (str);
330 }
331