1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
3 * symbol-db-model-project.c
4 * Copyright (C) Naba Kumar 2010 <naba@gnome.org>
6 * anjuta is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * anjuta is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "symbol-db-engine.h"
21 #include "symbol-db-model-project.h"
22 #include <libanjuta/anjuta-debug.h>
24 #define SDB_MODEL_PROJECT_SQL " \
28 symbol.file_position, \
29 symbol.scope_definition_id, \
35 sym_access.access_name, \
36 sym_kind.is_container \
38 LEFT JOIN file ON symbol.file_defined_id = file.file_id \
39 LEFT JOIN sym_access ON symbol.access_kind_id = sym_access.access_kind_id \
40 LEFT JOIN sym_kind ON symbol.kind_id = sym_kind.sym_kind_id \
43 symbol.scope_id = ## /* name:'parent' type:gint */ \
44 AND symbol.kind_id IN \
50 0 = ## /* name:'parent' type:gint */ \
51 AND sym_kind.kind_name IN ('class', 'struct', 'union', 'enum') \
55 0 != ## /* name:'parent' type:gint */ \
56 AND sym_kind.kind_name != 'namespace' \
67 symbol.scope_id = ## /* name:'parent' type:gint */ \
68 AND symbol.kind_id IN \
72 WHERE sym_kind.kind_name = 'namespace' \
74 GROUP BY symbol.scope_definition_id \
78 ORDER BY symbol.name \
79 LIMIT ## /* name:'limit' type:gint */ \
80 OFFSET ## /* name:'offset' type:gint */ \
83 struct _SymbolDBModelProjectPriv
88 GdaHolder
*param_parent_id
, *param_limit
, *param_offset
;
89 gboolean show_file_line
;
92 /* this values must map the fields of SDB_MODEL_PROJECT_SQL */
96 DATA_COL_SYMBOL_FILE_LINE
,
97 DATA_COL_SYMBOL_SCOPE_DEFINITION_ID
,
99 DATA_COL_SYMBOL_RETURNTYPE
,
100 DATA_COL_SYMBOL_TYPE
,
101 DATA_COL_SYMBOL_TYPE_NAME
,
102 DATA_COL_SYMBOL_FILE_PATH
,
103 DATA_COL_SYMBOL_ACCESS
,
104 DATA_COL_SYMBOL_HAS_CHILD
,
111 PROP_SYMBOL_DB_ENGINE
,
115 G_DEFINE_TYPE (SymbolDBModelProject
, sdb_model_project
,
116 SYMBOL_DB_TYPE_MODEL
);
119 sdb_model_project_update_sql_stmt (SymbolDBModel
*model
)
121 SymbolDBModelProjectPriv
*priv
;
123 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (model
));
124 priv
= SYMBOL_DB_MODEL_PROJECT (model
)->priv
;
126 priv
->stmt
= symbol_db_engine_get_statement (priv
->dbe
, SDB_MODEL_PROJECT_SQL
);
127 gda_statement_get_parameters (priv
->stmt
, &priv
->params
, NULL
);
128 priv
->param_parent_id
= gda_set_get_holder (priv
->params
, "parent");
129 priv
->param_limit
= gda_set_get_holder (priv
->params
, "limit");
130 priv
->param_offset
= gda_set_get_holder (priv
->params
, "offset");
134 sdb_model_project_get_children (SymbolDBModel
*model
, gint tree_level
,
135 GValue column_values
[], gint offset
,
138 SymbolDBModelProjectPriv
*priv
;
142 g_return_val_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (model
), 0);
143 priv
= SYMBOL_DB_MODEL_PROJECT (model
)->priv
;
145 /* If engine is not connected, there is nothing we can show */
146 if (!priv
->dbe
|| !symbol_db_engine_is_connected (priv
->dbe
))
149 /* Determin node parent */
156 parent_id
= g_value_get_int
157 (&column_values
[SYMBOL_DB_MODEL_PROJECT_COL_SCOPE_DEFINITION_ID
]);
161 sdb_model_project_update_sql_stmt (model
);
163 /* Initialize parameters */
164 g_value_init (&ival
, G_TYPE_INT
);
165 g_value_set_int (&ival
, parent_id
);
166 gda_holder_set_value (priv
->param_parent_id
, &ival
, NULL
);
167 g_value_set_int (&ival
, limit
);
168 gda_holder_set_value (priv
->param_limit
, &ival
, NULL
);
169 g_value_set_int (&ival
, offset
);
170 gda_holder_set_value (priv
->param_offset
, &ival
, NULL
);
172 return symbol_db_engine_execute_select (priv
->dbe
, priv
->stmt
, priv
->params
);
176 sdb_model_project_get_has_child (SymbolDBModel
*model
, gint tree_level
,
177 GValue column_values
[])
179 return (g_value_get_int
180 (&column_values
[SYMBOL_DB_MODEL_PROJECT_COL_HAS_CHILD
]) > 0);
184 sdb_model_project_get_n_children (SymbolDBModel
*model
, gint tree_level
,
185 GValue column_values
[])
188 GdaDataModel
*data_model
;
190 data_model
= sdb_model_project_get_children (model
, tree_level
,
193 if (GDA_IS_DATA_MODEL (data_model
))
195 n_children
= gda_data_model_get_n_rows (data_model
);
196 g_object_unref (data_model
);
202 sdb_model_project_get_query_value (SymbolDBModel
*model
,
203 GdaDataModel
*data_model
,
204 GdaDataModelIter
*iter
,
208 const GdkPixbuf
*pixbuf
;
209 const GValue
*ret_value
;
210 const gchar
*name
= NULL
;
211 const gchar
*type
= NULL
;
212 const gchar
*access
= NULL
;
213 const gchar
*args
= NULL
;
218 case SYMBOL_DB_MODEL_PROJECT_COL_PIXBUF
:
219 ret_value
= gda_data_model_iter_get_value_at (iter
,
220 DATA_COL_SYMBOL_TYPE
);
221 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
222 type
= g_value_get_string (ret_value
);
223 ret_value
= gda_data_model_iter_get_value_at (iter
,
224 DATA_COL_SYMBOL_ACCESS
);
225 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
226 access
= g_value_get_string (ret_value
);
228 pixbuf
= symbol_db_util_get_pixbuf (type
, access
);
229 g_value_set_object (value
, G_OBJECT (pixbuf
));
232 case SYMBOL_DB_MODEL_PROJECT_COL_LABEL
:
233 label
= g_string_new_len (NULL
, 256);
234 ret_value
= gda_data_model_iter_get_value_at (iter
,
235 DATA_COL_SYMBOL_NAME
);
236 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
239 name
= g_value_get_string (ret_value
);
240 escaped
= g_markup_escape_text (name
, -1);
241 g_string_assign (label
, escaped
);
244 ret_value
= gda_data_model_iter_get_value_at (iter
,
245 DATA_COL_SYMBOL_ARGS
);
246 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
247 args
= g_value_get_string (ret_value
);
251 if (strlen (args
) == 2)
252 g_string_append (label
, "()");
253 else if (strlen (args
) > 2)
254 g_string_append (label
, "(...)");
256 gda_data_model_iter_get_value_at (iter
,
257 DATA_COL_SYMBOL_RETURNTYPE
);
258 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
261 g_markup_escape_text (g_value_get_string (ret_value
), -1);
262 g_string_append (label
, "<span style=\"italic\"> : ");
263 g_string_append (label
, escaped
);
264 g_string_append (label
, "</span>");
271 gda_data_model_iter_get_value_at (iter
,
272 DATA_COL_SYMBOL_TYPE_NAME
);
273 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
) &&
274 g_strcmp0 (g_value_get_string (ret_value
), name
) != 0)
277 g_markup_escape_text (g_value_get_string (ret_value
), -1);
278 g_string_append (label
, "<span style=\"italic\"> : ");
279 g_string_append (label
, escaped
);
280 g_string_append (label
, "</span>");
284 if (SYMBOL_DB_MODEL_PROJECT (model
)->priv
->show_file_line
)
287 gda_data_model_iter_get_value_at (iter
,
288 DATA_COL_SYMBOL_FILE_PATH
);
289 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
))
292 const gchar
* file_name
= g_value_get_string (ret_value
);
295 gda_data_model_iter_get_value_at (iter
,
296 DATA_COL_SYMBOL_FILE_LINE
);
297 file_line
= g_value_get_int (ret_value
);
298 g_string_append_printf
300 "\n<span font-size=\"x-small\" font-weight=\"ultralight\"><tt>%s:%d</tt></span>",
301 file_name
, file_line
);
304 /* DEBUG_PRINT ("Output string: %s", label->str);*/
305 g_value_take_string (value
, label
->str
);
306 g_string_free (label
, FALSE
);
309 case SYMBOL_DB_MODEL_PROJECT_COL_ARGS
:
310 ret_value
= gda_data_model_iter_get_value_at (iter
,
311 DATA_COL_SYMBOL_ARGS
);
312 if (ret_value
&& G_VALUE_HOLDS_STRING (ret_value
)
313 && strlen (g_value_get_string (ret_value
)) > 2)
316 g_markup_escape_text (g_value_get_string (ret_value
), -1);
317 g_value_take_string (value
, escaped
);
322 return SYMBOL_DB_MODEL_CLASS (sdb_model_project_parent_class
)->
323 get_query_value (model
, data_model
, iter
, column
, value
);
328 on_sdb_project_dbe_unref (SymbolDBModelProject
*model
)
330 SymbolDBModelProjectPriv
*priv
;
332 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (model
));
333 priv
= SYMBOL_DB_MODEL_PROJECT (model
)->priv
;
335 symbol_db_model_update (SYMBOL_DB_MODEL (model
));
339 sdb_model_project_set_property (GObject
*object
, guint prop_id
,
340 const GValue
*value
, GParamSpec
*pspec
)
342 SymbolDBModelProjectPriv
*priv
;
344 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (object
));
345 priv
= SYMBOL_DB_MODEL_PROJECT (object
)->priv
;
349 case PROP_SYMBOL_DB_ENGINE
:
352 g_object_weak_unref (G_OBJECT (priv
->dbe
),
353 (GWeakNotify
)on_sdb_project_dbe_unref
,
355 g_signal_handlers_disconnect_by_func (priv
->dbe
,
356 G_CALLBACK (symbol_db_model_update
),
358 g_signal_handlers_disconnect_by_func (priv
->dbe
,
359 G_CALLBACK (symbol_db_model_freeze
),
361 g_signal_handlers_disconnect_by_func (priv
->dbe
,
362 G_CALLBACK (symbol_db_model_thaw
),
365 priv
->dbe
= g_value_dup_object (value
);
366 g_object_weak_ref (G_OBJECT (priv
->dbe
),
367 (GWeakNotify
)on_sdb_project_dbe_unref
,
369 g_signal_connect_swapped (priv
->dbe
, "db-connected",
370 G_CALLBACK (symbol_db_model_update
),
372 g_signal_connect_swapped (priv
->dbe
, "db-disconnected",
373 G_CALLBACK (symbol_db_model_update
),
375 g_signal_connect_swapped (priv
->dbe
, "scan-begin",
376 G_CALLBACK (symbol_db_model_freeze
), object
);
377 g_signal_connect_swapped (priv
->dbe
, "scan-end",
378 G_CALLBACK (symbol_db_model_thaw
), object
);
380 symbol_db_model_update (SYMBOL_DB_MODEL (object
));
382 case PROP_SHOW_FILE_LINE
:
383 priv
->show_file_line
= g_value_get_boolean (value
);
386 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
392 sdb_model_project_get_property (GObject
*object
, guint prop_id
,
393 GValue
*value
, GParamSpec
*pspec
)
395 SymbolDBModelProjectPriv
*priv
;
397 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (object
));
398 priv
= SYMBOL_DB_MODEL_PROJECT (object
)->priv
;
402 case PROP_SYMBOL_DB_ENGINE
:
403 g_value_set_object (value
, priv
->dbe
);
405 case PROP_SHOW_FILE_LINE
:
406 g_value_set_boolean (value
, priv
->show_file_line
);
409 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
415 sdb_model_project_finalize (GObject
*object
)
417 SymbolDBModelProjectPriv
*priv
;
419 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (object
));
420 priv
= SYMBOL_DB_MODEL_PROJECT (object
)->priv
;
424 g_object_weak_unref (G_OBJECT (priv
->dbe
),
425 (GWeakNotify
)on_sdb_project_dbe_unref
,
427 g_signal_handlers_disconnect_by_func (priv
->dbe
,
428 G_CALLBACK (symbol_db_model_update
),
430 g_signal_handlers_disconnect_by_func (priv
->dbe
,
431 G_CALLBACK (symbol_db_model_freeze
),
433 g_signal_handlers_disconnect_by_func (priv
->dbe
,
434 G_CALLBACK (symbol_db_model_thaw
),
440 g_object_unref (priv
->stmt
);
441 g_object_unref (priv
->params
);
446 G_OBJECT_CLASS (sdb_model_project_parent_class
)->finalize (object
);
450 sdb_model_project_init (SymbolDBModelProject
*object
)
452 SymbolDBModelProjectPriv
*priv
;
469 DATA_COL_SYMBOL_FILE_PATH
,
470 DATA_COL_SYMBOL_FILE_LINE
,
471 DATA_COL_SYMBOL_ARGS
,
472 DATA_COL_SYMBOL_SCOPE_DEFINITION_ID
,
473 DATA_COL_SYMBOL_HAS_CHILD
476 g_return_if_fail (SYMBOL_DB_IS_MODEL_PROJECT (object
));
478 priv
= g_new0 (SymbolDBModelProjectPriv
, 1);
483 g_assert ((sizeof (types
) / sizeof (GType
)) == (sizeof (data_cols
) / sizeof (gint
)));
484 symbol_db_model_set_columns (SYMBOL_DB_MODEL (object
),
485 (sizeof (types
) / sizeof (GType
)),
490 sdb_model_project_class_init (SymbolDBModelProjectClass
*klass
)
492 GObjectClass
* object_class
= G_OBJECT_CLASS (klass
);
493 SymbolDBModelClass
* parent_class
= SYMBOL_DB_MODEL_CLASS (klass
);
495 g_type_class_add_private (klass
, sizeof (SymbolDBModelProjectPriv
));
497 object_class
->finalize
= sdb_model_project_finalize
;
498 object_class
->set_property
= sdb_model_project_set_property
;
499 object_class
->get_property
= sdb_model_project_get_property
;
501 parent_class
->get_query_value
= sdb_model_project_get_query_value
;
502 parent_class
->get_has_child
= sdb_model_project_get_has_child
;
503 parent_class
->get_n_children
= sdb_model_project_get_n_children
;
504 parent_class
->get_children
= sdb_model_project_get_children
;
506 g_object_class_install_property
507 (object_class
, PROP_SYMBOL_DB_ENGINE
,
508 g_param_spec_object ("symbol-db-engine",
510 "Symbol DB Engine instance used to make queries",
511 SYMBOL_TYPE_DB_ENGINE
,
514 G_PARAM_CONSTRUCT_ONLY
));
515 g_object_class_install_property
516 (object_class
, PROP_SHOW_FILE_LINE
,
517 g_param_spec_boolean ("show-file-line",
518 "Show file and line",
519 "Show file and line number in labels",
526 symbol_db_model_project_new (SymbolDBEngine
* dbe
)
528 return GTK_TREE_MODEL (g_object_new (SYMBOL_DB_TYPE_MODEL_PROJECT
,
529 "symbol-db-engine", dbe
, NULL
));