1 /* MDB Tools - A library for reading MS Access database file
2 * Copyright (C) 2000 Brian Bruns
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #include "gmdb.h"
20
21 #if SQL
22
23 GList *sql_list;
24
25 extern MdbHandle *mdb;
26 extern MdbSQL *sql;
27
28 static void gmdb_sql_tree_populate (MdbHandle*, GtkBuilder*);
29 static void gmdb_sql_load_query (GtkBuilder*, gchar*);
30 static void gmdb_sql_save_query (GtkBuilder*, gchar*);
31 static void gmdb_sql_save_as_cb (GtkWidget*, GtkBuilder*);
32
33 void
gmdb_sql_close_all()34 gmdb_sql_close_all()
35 {
36 GtkBuilder *xml;
37 GtkWidget *win;
38
39 while ((xml = g_list_nth_data(sql_list, 0))) {
40 win = GTK_WIDGET(gtk_builder_get_object (xml, "sql_window"));
41 sql_list = g_list_remove(sql_list, xml);
42 if (win) gtk_widget_destroy(win);
43 }
44 }
45
46 gchar* gmdb_export_get_filepath (GtkBuilder*); /* from table_export.c */
47
48 /* callbacks */
49 static void
gmdb_sql_write_rslt_cb(GtkWidget * w,GtkBuilder * xml)50 gmdb_sql_write_rslt_cb(GtkWidget *w, GtkBuilder *xml)
51 {
52 /* We need to re-run the whole query because some information is not stored
53 * in the TreeStore, such as column types.
54 */
55 gchar *file_path;
56 GtkBuilder *sql_xml;
57 GtkWidget *filesel, *dlg;
58 FILE *outfile;
59 int i;
60 int need_headers = 0;
61 gchar delimiter[11];
62 gchar quotechar[5];
63 gchar escape_char[5];
64 int bin_mode;
65 gchar lineterm[5];
66
67 guint len;
68 gchar *buf;
69 GtkTextIter start, end;
70 GtkTextBuffer *txtbuffer;
71 GtkWidget *textview;
72 char **bound_values;
73 int *bound_lens;
74 MdbSQLColumn *sqlcol;
75 long row;
76 char *value;
77 size_t length;
78 MdbTableDef *table;
79 MdbColumn *col = NULL;
80
81 gmdb_export_get_delimiter(xml, delimiter, sizeof(delimiter));
82 gmdb_export_get_lineterm(xml, lineterm, sizeof(lineterm));
83 gmdb_export_get_quotechar(xml, quotechar, sizeof(quotechar));
84 gmdb_export_get_escapechar(xml, escape_char, sizeof(escape_char));
85 bin_mode = gmdb_export_get_binmode(xml);
86 need_headers = gmdb_export_get_headers(xml);
87 file_path = gmdb_export_get_filepath(xml);
88
89 if ((outfile=fopen(file_path, "w"))==NULL) {
90 dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)),
91 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
92 _("Unable to open file."));
93 gtk_dialog_run (GTK_DIALOG (dlg));
94 gtk_widget_destroy (dlg);
95 return;
96 }
97
98 /* Get SQL */
99 filesel = GTK_WIDGET(gtk_builder_get_object (xml, "export_dialog"));
100 sql_xml = g_object_get_data(G_OBJECT(filesel), "sql_xml");
101 //printf("sql_xml %p\n",sql_xml);
102 textview = GTK_WIDGET(gtk_builder_get_object(sql_xml, "sql_textview"));
103 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
104 len = gtk_text_buffer_get_char_count(txtbuffer);
105 gtk_text_buffer_get_iter_at_offset (txtbuffer, &start, 0);
106 gtk_text_buffer_get_iter_at_offset (txtbuffer, &end, len);
107 buf = gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE);
108
109
110 /* ok now execute it */
111 mdb_sql_run_query(sql, buf);
112 if (mdb_sql_has_error(sql)) {
113 GtkWidget* dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)),
114 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
115 "%s", mdb_sql_last_error(sql));
116 gtk_dialog_run (GTK_DIALOG (dlg));
117 gtk_widget_destroy (dlg);
118 mdb_sql_reset(sql);
119
120 fclose(outfile);
121 gtk_widget_destroy(filesel);
122 return;
123 }
124
125 bound_values = (char **) g_malloc(sql->num_columns * sizeof(char *));
126 bound_lens = (int *) g_malloc(sql->num_columns * sizeof(int));
127
128 for (i=0; i<sql->num_columns; i++) {
129 /* bind columns */
130 bound_values[i] = (char *) g_malloc0(MDB_BIND_SIZE);
131 mdb_sql_bind_column(sql, i+1, bound_values[i], &bound_lens[i]);
132
133 /* display column titles */
134 if (need_headers) {
135 if (i>0)
136 fputs(delimiter, outfile);
137 sqlcol = g_ptr_array_index(sql->columns,i);
138 mdb_print_col(outfile, sqlcol->name, quotechar[0]!='\0', MDB_TEXT, 0, quotechar, escape_char, bin_mode);
139 }
140 }
141
142 row = 0;
143 while (mdb_fetch_row(sql->cur_table)) {
144 row++;
145 for (i=0; i<sql->num_columns; i++) {
146 if (i>0)
147 fputs(delimiter, outfile);
148
149 sqlcol = g_ptr_array_index(sql->columns, i);
150
151 /* Find col matching sqlcol */
152 table = sql->cur_table;
153 for (i=0; i<table->num_cols; i++) {
154 col = g_ptr_array_index(table->columns, i);
155 if (!g_ascii_strcasecmp(sqlcol->name, col->name))
156 break;
157 }
158 /* assert(i!=table->num_cols). Can't happen, already checked. */
159
160 /* Don't quote NULLs */
161 if (bound_lens[i] && sqlcol->bind_type != MDB_OLE) {
162 if (col->col_type == MDB_OLE) {
163 value = mdb_ole_read_full(mdb, col, &length);
164 } else {
165 value = bound_values[i];
166 length = bound_lens[i];
167 }
168 mdb_print_col(outfile, value, quotechar[0]!='\0', col->col_type, length, quotechar, escape_char, bin_mode);
169 if (col->col_type == MDB_OLE)
170 free(value);
171 }
172 }
173 fputs(lineterm, outfile);
174 }
175
176 /* free the memory used to bind */
177 for (i=0; i<sql->num_columns; i++) {
178 g_free(bound_values[i]);
179 }
180
181 mdb_sql_reset(sql);
182 g_free(buf);
183
184 fclose(outfile);
185
186 dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)),
187 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
188 _("%ld rows successfully exported."), row);
189 gtk_dialog_run (GTK_DIALOG (dlg));
190 gtk_widget_destroy (dlg);
191
192 gtk_widget_destroy(filesel);
193 }
194
195
196 static void
gmdb_sql_results_cb(GtkWidget * w,GtkBuilder * xml)197 gmdb_sql_results_cb(GtkWidget *w, GtkBuilder *xml)
198 {
199 GError *error = NULL;
200 GtkBuilder *dialog_xml;
201 GtkWidget *but;
202 GtkWidget *filesel;
203
204 /* load the interface */
205 dialog_xml = gtk_builder_new();
206 if (!gtk_builder_add_from_file(dialog_xml, GMDB_UIDIR "gmdb-export.ui", NULL)) {
207 g_warning("Error loading " GMDB_UIDIR "gmdb-export.ui: %s", error->message);
208 g_error_free(error);
209 }
210 /* connect the signals in the interface */
211 gtk_builder_connect_signals(dialog_xml, NULL);
212
213 filesel = GTK_WIDGET (gtk_builder_get_object(dialog_xml, "export_dialog"));
214 gtk_window_set_title(GTK_WINDOW(filesel), "Save Results As");
215
216 but = GTK_WIDGET(gtk_builder_get_object(dialog_xml, "export_button"));
217 gtk_widget_hide(but);
218
219 but = GTK_WIDGET(gtk_builder_get_object(dialog_xml, "save_button"));
220 g_signal_connect (G_OBJECT (but), "clicked",
221 G_CALLBACK (gmdb_sql_write_rslt_cb), dialog_xml);
222 gtk_widget_show(but);
223
224 g_object_set_data(G_OBJECT(filesel), "sql_xml", xml);
225 }
226 static void
gmdb_sql_save_cb(GtkWidget * w,GtkBuilder * xml)227 gmdb_sql_save_cb(GtkWidget *w, GtkBuilder *xml)
228 {
229 GtkWidget *textview;
230 gchar *str;
231
232 textview = GTK_WIDGET(gtk_builder_get_object (xml, "sql_textview"));
233 str = g_object_get_data(G_OBJECT(textview), "file_name");
234 if (!str) {
235 gmdb_sql_save_as_cb(w, xml);
236 return;
237 }
238 gmdb_sql_save_query(xml, str);
239 }
240 static void
gmdb_sql_save_as_cb(GtkWidget * w,GtkBuilder * xml)241 gmdb_sql_save_as_cb(GtkWidget *w, GtkBuilder *xml)
242 {
243 GtkWindow *parent_window = GTK_WINDOW(gtk_builder_get_object (xml, "gmdb"));
244 GtkWidget *dialog = gtk_file_chooser_dialog_new ("Save Query As",
245 parent_window,
246 GTK_FILE_CHOOSER_ACTION_SAVE,
247 "_Cancel", GTK_RESPONSE_CANCEL,
248 "_Save", GTK_RESPONSE_ACCEPT,
249 NULL);
250
251 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
252 {
253 char *filename;
254
255 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
256 gmdb_sql_save_query(xml, filename);
257 }
258
259 gtk_widget_destroy (dialog);
260 }
261 static void
gmdb_sql_open_cb(GtkWidget * w,GtkBuilder * xml)262 gmdb_sql_open_cb(GtkWidget *w, GtkBuilder *xml)
263 {
264 GtkWindow *parent_window = GTK_WINDOW(gtk_builder_get_object (xml, "gmdb"));
265 GtkWidget *dialog = gtk_file_chooser_dialog_new ("Open SQL Query",
266 parent_window,
267 GTK_FILE_CHOOSER_ACTION_OPEN,
268 "_Cancel", GTK_RESPONSE_CANCEL,
269 "_Open", GTK_RESPONSE_ACCEPT,
270 NULL);
271
272 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
273 {
274 char *filename;
275
276 filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
277 gmdb_sql_load_query(xml, filename);
278 }
279
280 gtk_widget_destroy (dialog);
281
282 }
283 static void
gmdb_sql_copy_cb(GtkWidget * w,GtkBuilder * xml)284 gmdb_sql_copy_cb(GtkWidget *w, GtkBuilder *xml)
285 {
286 GtkTextBuffer *txtbuffer;
287 GtkClipboard *clipboard;
288 GtkWidget *textview;
289
290 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
291 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
292 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
293 gtk_text_buffer_copy_clipboard(txtbuffer, clipboard);
294 }
295 static void
gmdb_sql_cut_cb(GtkWidget * w,GtkBuilder * xml)296 gmdb_sql_cut_cb(GtkWidget *w, GtkBuilder *xml)
297 {
298 GtkTextBuffer *txtbuffer;
299 GtkClipboard *clipboard;
300 GtkWidget *textview;
301
302 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
303 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
304 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
305 gtk_text_buffer_cut_clipboard(txtbuffer, clipboard, TRUE);
306 }
307 static void
gmdb_sql_paste_cb(GtkWidget * w,GtkBuilder * xml)308 gmdb_sql_paste_cb(GtkWidget *w, GtkBuilder *xml)
309 {
310 GtkTextBuffer *txtbuffer;
311 GtkClipboard *clipboard;
312 GtkWidget *textview;
313
314 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
315 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
316 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
317 gtk_text_buffer_paste_clipboard(txtbuffer, clipboard, NULL, TRUE);
318 }
319 static void
gmdb_sql_close_cb(GtkWidget * w,GtkBuilder * xml)320 gmdb_sql_close_cb(GtkWidget *w, GtkBuilder *xml)
321 {
322 GtkWidget *win;
323 sql_list = g_list_remove(sql_list, xml);
324 win = GTK_WIDGET(gtk_builder_get_object (xml, "sql_window"));
325 if (win) gtk_widget_destroy(win);
326 }
327
328 static void
gmdb_sql_dnd_dataget_cb(GtkWidget * w,GdkDragContext * dc,GtkSelectionData * selection_data,guint info,guint t,GtkBuilder * xml)329 gmdb_sql_dnd_dataget_cb(
330 GtkWidget *w, GdkDragContext *dc,
331 GtkSelectionData *selection_data, guint info, guint t,
332 GtkBuilder *xml)
333 {
334 gchar tablename[256];
335 //gchar *tablename = "Orders";
336 gchar *name;
337 GtkTreeSelection *select;
338 GtkTreeStore *store;
339 GtkTreeView *tree;
340 GtkTreeIter iter2;
341
342 tree = GTK_TREE_VIEW(gtk_builder_get_object(xml, "sql_treeview"));
343 select = gtk_tree_view_get_selection(GTK_TREE_VIEW (tree));
344 store = GTK_TREE_STORE(gtk_tree_view_get_model(tree));
345 gtk_tree_selection_get_selected (select, NULL, &iter2);
346 gtk_tree_model_get (GTK_TREE_MODEL(store), &iter2, 0, &name, -1);
347
348 snprintf(tablename, sizeof(tablename), "%s", name);
349 g_free(name);
350 //strcpy(tablename, "Shippers");
351 gtk_selection_data_set(
352 selection_data,
353 GDK_SELECTION_TYPE_STRING,
354 8, /* 8 bits per character. */
355 (guchar*)tablename, strlen(tablename));
356 }
gmdb_sql_dnd_datareceived_cb(GtkWidget * w,GdkDragContext * dc,gint x,gint y,GtkSelectionData * selection_data,guint info,guint t,GtkBuilder * xml)357 static void gmdb_sql_dnd_datareceived_cb(
358 GtkWidget *w,
359 GdkDragContext *dc,
360 gint x, gint y,
361 GtkSelectionData *selection_data,
362 guint info, guint t,
363 GtkBuilder *xml)
364 {
365 GtkTextIter iter;
366 GtkTextBuffer *txtbuffer;
367 GtkWidget *textview;
368
369 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
370 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
371 if (gtk_text_buffer_get_char_count(txtbuffer)==0) {
372 gtk_text_buffer_get_iter_at_offset (txtbuffer, &iter, 0);
373 gtk_text_buffer_insert(txtbuffer, &iter, "select * from ", 14);
374 }
375 gtk_widget_grab_focus(GTK_WIDGET(textview));
376 }
377
378 static void
gmdb_sql_select_hist_cb(GtkComboBoxText * combobox,GtkBuilder * xml)379 gmdb_sql_select_hist_cb(GtkComboBoxText *combobox, GtkBuilder *xml)
380 {
381 gchar *buf;
382 GtkTextBuffer *txtbuffer;
383 GtkWidget *textview;
384
385 buf = gtk_combo_box_text_get_active_text(combobox);
386 if (!buf) return;
387 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
388 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
389 gtk_text_buffer_set_text(txtbuffer, buf, strlen(buf));
390 }
391
392 static void
gmdb_sql_execute_cb(GtkWidget * w,GtkBuilder * xml)393 gmdb_sql_execute_cb(GtkWidget *w, GtkBuilder *xml)
394 {
395 guint len;
396 gchar *buf;
397 gchar *bound_data[256];
398 int i;
399 MdbSQLColumn *sqlcol;
400 GtkTextBuffer *txtbuffer;
401 GtkTextIter start, end;
402 GtkWidget *textview, *combobox, *treeview;
403 GtkTreeModel *store;
404 /*GtkWidget *window;*/
405 GType *gtypes;
406 GtkTreeIter iter;
407 GtkTreeViewColumn *column;
408 long row, maxrow;
409 /* GdkCursor *watch, *pointer; */
410
411 /* need to figure out how to clock during the treeview recalc/redraw
412 window = GTK_WIDGET(gtk_builder_get_object(xml, "sql_window");
413 watch = gdk_cursor_new(GDK_WATCH);
414 gdk_window_set_cursor(GTK_WIDGET(window)->window, watch);
415 gdk_cursor_unref(watch);
416 */
417
418 /* stuff this query on the history */
419 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
420 combobox = GTK_WIDGET(gtk_builder_get_object(xml, "sql_combo"));
421 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
422 len = gtk_text_buffer_get_char_count(txtbuffer);
423 gtk_text_buffer_get_iter_at_offset (txtbuffer, &start, 0);
424 gtk_text_buffer_get_iter_at_offset (txtbuffer, &end, len);
425 buf = gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE);
426
427 /* add to the history */
428 gtk_combo_box_text_prepend_text(GTK_COMBO_BOX_TEXT(combobox), buf);
429 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 0);
430
431 /* ok now execute it */
432 mdb_sql_run_query(sql, buf);
433 if (mdb_sql_has_error(sql)) {
434 GtkWidget* dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)),
435 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
436 "%s", mdb_sql_last_error(sql));
437 gtk_dialog_run (GTK_DIALOG (dlg));
438 gtk_widget_destroy (dlg);
439 mdb_sql_reset(sql);
440 return;
441 }
442
443 treeview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_results"));
444
445 gtypes = g_malloc(sizeof(GType) * sql->num_columns);
446 for (i=0;i<sql->num_columns;i++)
447 gtypes[i]=G_TYPE_STRING;
448
449 store = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));
450 if (store) {
451 while ((column = gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0))) {
452 gtk_tree_view_remove_column(GTK_TREE_VIEW(treeview), column);
453 }
454 g_object_unref(store);
455 }
456 store = GTK_TREE_MODEL(gtk_list_store_newv(sql->num_columns, gtypes));
457 g_free(gtypes);
458
459 gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), store);
460
461 GtkCellRenderer *renderer;
462 renderer = gtk_cell_renderer_text_new();
463
464 for (i=0;i<sql->num_columns;i++) {
465 bound_data[i] = (char *) g_malloc0(MDB_BIND_SIZE);
466 mdb_sql_bind_column(sql, i+1, bound_data[i], NULL);
467 sqlcol = g_ptr_array_index(sql->columns,i);
468 column = gtk_tree_view_column_new_with_attributes(sqlcol->name, renderer, "text", i, NULL);
469 gtk_tree_view_append_column(GTK_TREE_VIEW (treeview), column);
470 }
471
472 maxrow = gmdb_prefs_get_maxrows();
473
474 row = 0;
475 while(mdb_fetch_row(sql->cur_table) &&
476 (!maxrow || (row < maxrow))) {
477 row++;
478 gtk_list_store_append(GTK_LIST_STORE(store), &iter);
479 for (i=0;i<sql->num_columns;i++) {
480 gtk_list_store_set(GTK_LIST_STORE(store),
481 &iter, i, (gchar *) bound_data[i], -1);
482 }
483 }
484
485 /* free the memory used to bind */
486 for (i=0;i<sql->num_columns;i++) {
487 g_free(bound_data[i]);
488 }
489
490 mdb_sql_reset(sql);
491 g_free(buf);
492
493 /*
494 pointer = gdk_cursor_new(GDK_LEFT_PTR);
495 gdk_window_set_cursor(GTK_WIDGET(window)->window, pointer);
496 gdk_cursor_unref(pointer);
497 */
498
499 }
500
501 void
gmdb_sql_new_cb(GtkWidget * w,gpointer data)502 gmdb_sql_new_cb (GtkWidget *w, gpointer data) {
503 GtkTargetEntry src = { .target = "table", .info = 1 };
504 GtkWidget *mi, *but, *combobox;
505 GtkBuilder *sqlwin_xml;
506 GError *error = NULL;
507
508 /* load the interface */
509 sqlwin_xml = gtk_builder_new();
510 if (!gtk_builder_add_from_file(sqlwin_xml, GMDB_UIDIR "gmdb-sql.ui", &error)) {
511 g_warning("Error loading " GMDB_UIDIR "gmdb-sql.ui: %s", error->message);
512 g_error_free(error);
513 }
514 /* connect the signals in the interface */
515 gtk_builder_connect_signals(sqlwin_xml, NULL);
516
517 sql_list = g_list_append(sql_list, sqlwin_xml);
518
519 mi = GTK_WIDGET(gtk_builder_get_object (sqlwin_xml, "save_menu"));
520 g_signal_connect (G_OBJECT (mi), "activate",
521 G_CALLBACK (gmdb_sql_save_cb), sqlwin_xml);
522
523 but = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "save_button"));
524 g_signal_connect (G_OBJECT (but), "clicked",
525 G_CALLBACK (gmdb_sql_save_cb), sqlwin_xml);
526
527 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "save_as_menu"));
528 g_signal_connect (G_OBJECT (mi), "activate",
529 G_CALLBACK (gmdb_sql_save_as_cb), sqlwin_xml);
530
531 //but = GTK_WIDGET(gtk_builder_get_object (sqlwin_xml, "save_as_button");
532 //g_signal_connect (G_OBJECT (but), "clicked",
533 // G_CALLBACK (gmdb_sql_save_as_cb), sqlwin_xml);
534
535 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "results_menu"));
536 g_signal_connect (G_OBJECT (mi), "activate",
537 G_CALLBACK (gmdb_sql_results_cb), sqlwin_xml);
538
539 but = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "results_button"));
540 g_signal_connect (G_OBJECT (but), "clicked",
541 G_CALLBACK (gmdb_sql_results_cb), sqlwin_xml);
542
543 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "open_menu"));
544 g_signal_connect (G_OBJECT (mi), "activate",
545 G_CALLBACK (gmdb_sql_open_cb), sqlwin_xml);
546
547 but = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "open_button"));
548 g_signal_connect (G_OBJECT (but), "clicked",
549 G_CALLBACK (gmdb_sql_open_cb), sqlwin_xml);
550
551 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "paste_menu"));
552 g_signal_connect (G_OBJECT (mi), "activate",
553 G_CALLBACK (gmdb_sql_paste_cb), sqlwin_xml);
554
555 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "cut_menu"));
556 g_signal_connect (G_OBJECT (mi), "activate",
557 G_CALLBACK (gmdb_sql_cut_cb), sqlwin_xml);
558
559 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "copy_menu"));
560 g_signal_connect (G_OBJECT (mi), "activate",
561 G_CALLBACK (gmdb_sql_copy_cb), sqlwin_xml);
562
563 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "close_menu"));
564 g_signal_connect (G_OBJECT (mi), "activate",
565 G_CALLBACK (gmdb_sql_close_cb), sqlwin_xml);
566
567 but = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "close_button"));
568 g_signal_connect (G_OBJECT (but), "clicked",
569 G_CALLBACK (gmdb_sql_close_cb), sqlwin_xml);
570
571 mi = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "execute_menu"));
572 g_signal_connect (G_OBJECT (mi), "activate",
573 G_CALLBACK (gmdb_sql_execute_cb), sqlwin_xml);
574
575 combobox = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "sql_combo"));
576 g_signal_connect (G_OBJECT(GTK_COMBO_BOX_TEXT(combobox)), "changed",
577 G_CALLBACK (gmdb_sql_select_hist_cb), sqlwin_xml);
578
579 but = GTK_WIDGET(gtk_builder_get_object (sqlwin_xml, "execute_button"));
580 g_signal_connect (G_OBJECT (but), "clicked",
581 G_CALLBACK (gmdb_sql_execute_cb), sqlwin_xml);
582
583 /* set up treeview, libglade only gives us the empty widget */
584 GtkWidget *tree = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "sql_treeview"));
585 GtkTreeStore *store = gtk_tree_store_new(1, G_TYPE_STRING);
586 gtk_tree_view_set_model(GTK_TREE_VIEW(tree), GTK_TREE_MODEL(store));
587
588 GtkCellRenderer *renderer;
589 GtkTreeViewColumn *column;
590 renderer = gtk_cell_renderer_text_new();
591 column = gtk_tree_view_column_new_with_attributes("Name",
592 renderer, "text", 0, NULL);
593 gtk_tree_view_append_column(GTK_TREE_VIEW (tree), column);
594
595 GtkTreeSelection *select =
596 gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
597 gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);
598 //g_signal_connect (G_OBJECT (select), "changed",
599 //G_CALLBACK (gmdb_sql_select_cb), sqlwin_xml);
600
601 /* populate first level of tree */
602 gmdb_sql_tree_populate(mdb, sqlwin_xml);
603
604 GtkWidget *textview = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "sql_textview"));
605 gtk_drag_source_set( tree, GDK_BUTTON1_MASK, &src, 1, GDK_ACTION_COPY);
606 gtk_drag_dest_set( textview,
607 //GTK_DEST_DEFAULT_MOTION |
608 GTK_DEST_DEFAULT_HIGHLIGHT ,
609 // GTK_DEST_DEFAULT_DROP,
610 &src, 1, GDK_ACTION_COPY | GDK_ACTION_MOVE);
611 g_signal_connect(tree, "drag_data_get",
612 G_CALLBACK(gmdb_sql_dnd_dataget_cb), sqlwin_xml);
613 g_signal_connect(textview, "drag_data_received",
614 G_CALLBACK(gmdb_sql_dnd_datareceived_cb), sqlwin_xml);
615
616 //GValue value = {0, };
617 //but = GTK_WIDGET(gtk_builder_get_object(sqlwin_xml, "results_button"));
618 //g_value_init(&value, G_TYPE_STRING);
619 //g_value_set_static_string(&value, GMDB_ICONDIR "stock_export.png");
620 //g_object_set_property(G_OBJECT (but), "file" , &value);
621 //g_value_unset (&value);
622
623 gtk_widget_grab_focus(GTK_WIDGET(textview));
624 }
625
626 /* functions */
627 static gchar *
gmdb_sql_get_basename(char * file_path)628 gmdb_sql_get_basename(char *file_path)
629 {
630 int i, len;
631 gchar *basename;
632
633 for (i=strlen(file_path);i>=0 && file_path[i]!='/';i--);
634 len = strlen(file_path) - i + 2;
635 basename = g_malloc(len);
636 if (file_path[i]=='/') {
637 strncpy(basename,&file_path[i+1],len);
638 } else {
639 strncpy(basename,file_path,len);
640 }
641 basename[len]='\0';
642
643 return basename;
644 }
645
646 static void
gmdb_sql_set_file(GtkBuilder * xml,gchar * file_name)647 gmdb_sql_set_file(GtkBuilder *xml, gchar *file_name)
648 {
649 GtkWidget *window, *textview;
650 gchar *title;
651 gchar *basename;
652 gchar *suffix = " - MDB Query Tool";
653
654 basename = gmdb_sql_get_basename(file_name);
655 title = g_malloc(strlen(basename) + strlen(suffix) + 1);
656 sprintf(title,"%s%s", basename, suffix);
657 g_free(basename);
658 window = GTK_WIDGET(gtk_builder_get_object(xml, "sql_window"));
659 gtk_window_set_title(GTK_WINDOW(window), title);
660 g_free(title);
661 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
662 g_object_set_data(G_OBJECT(textview), "file_name", file_name);
663 }
664
665 static void
gmdb_sql_save_query(GtkBuilder * xml,gchar * file_path)666 gmdb_sql_save_query (GtkBuilder *xml, gchar *file_path) {
667 FILE *out;
668 GtkWidget *textview;
669 GtkTextBuffer *txtbuffer;
670 GtkTextIter start, end;
671 gchar *buf;
672
673 if (!(out=fopen(file_path, "w"))) {
674 GtkWidget* dlg = gtk_message_dialog_new (NULL,
675 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
676 _("Unable to open file."));
677 gtk_dialog_run (GTK_DIALOG (dlg));
678 gtk_widget_destroy (dlg);
679 return;
680 }
681 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
682 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
683 gtk_text_buffer_get_start_iter(txtbuffer, &start);
684 gtk_text_buffer_get_end_iter(txtbuffer, &end);
685 buf = gtk_text_buffer_get_text(txtbuffer, &start, &end, FALSE);
686 fprintf(out,"%s\n",buf);
687 fclose(out);
688 gmdb_sql_set_file(xml, file_path);
689 }
690 static void
gmdb_sql_load_query(GtkBuilder * xml,gchar * file_path)691 gmdb_sql_load_query(GtkBuilder *xml, gchar *file_path)
692 {
693 FILE *in;
694 char buf[256];
695 GtkWidget *textview;
696 GtkTextBuffer *txtbuffer;
697 GtkTextIter start, end;
698
699 if (!(in=fopen(file_path, "r"))) {
700 GtkWidget* dlg = gtk_message_dialog_new (NULL,
701 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
702 _("Unable to open file."));
703 gtk_dialog_run (GTK_DIALOG (dlg));
704 gtk_widget_destroy (dlg);
705 return;
706 }
707 textview = GTK_WIDGET(gtk_builder_get_object(xml, "sql_textview"));
708 txtbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
709 gtk_text_buffer_get_start_iter(txtbuffer, &start);
710 gtk_text_buffer_get_end_iter(txtbuffer, &end);
711 gtk_text_buffer_delete(txtbuffer, &start, &end);
712 while (fgets(buf, 255, in) && (*buf != '\0')) {
713 gtk_text_buffer_get_end_iter(txtbuffer, &end);
714 gtk_text_buffer_insert(txtbuffer, &end, buf, strlen(buf));
715 }
716 fclose(in);
717 gmdb_sql_set_file(xml, file_path);
718 }
719 static void
gmdb_sql_tree_populate(MdbHandle * mdb,GtkBuilder * xml)720 gmdb_sql_tree_populate(MdbHandle *mdb, GtkBuilder *xml)
721 {
722 int i;
723 MdbCatalogEntry *entry;
724 GtkTreeIter *iter2;
725
726 GtkTreeView *tree = GTK_TREE_VIEW(gtk_builder_get_object(xml, "sql_treeview"));
727 GtkTreeStore *store = GTK_TREE_STORE(gtk_tree_view_get_model(tree));
728
729 /* add all user tables in catalog to tab */
730 for (i=0; i < mdb->num_catalog; i++) {
731 entry = g_ptr_array_index (mdb->catalog, i);
732 if (mdb_is_user_table(entry)) {
733 iter2 = g_malloc(sizeof(GtkTreeIter));
734 gtk_tree_store_append(store, iter2, NULL);
735 gtk_tree_store_set(store, iter2, 0, entry->object_name, -1);
736 }
737 } /* for */
738 }
739 #else
740
741 void
gmdb_sql_new_cb(GtkWidget * w,gpointer data)742 gmdb_sql_new_cb (GtkWidget *w, gpointer data) {
743 GtkWidget* dlg = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (w)),
744 GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
745 _("SQL support was not built.\nMake sure flex and yacc are installed at build time."));
746 gtk_dialog_run (GTK_DIALOG (dlg));
747 gtk_widget_destroy (dlg);
748 }
749
750 #endif
751