1 /*
2 * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2010 David King <davidk@openismus.com>
4 * Copyright (C) 2011 Murray Cumming <murrayc@murrayc.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <glib/gi18n-lib.h>
22 #include <string.h>
23 #include <gtk/gtk.h>
24 #include <libgda-ui/libgda-ui.h>
25 #include <libgda/binreloc/gda-binreloc.h>
26 #include "dsn-config.h"
27 #include "provider-config.h"
28 #include "gdaui-dsn-assistant.h"
29
30 GtkApplication *app;
31 GtkWindow *main_window;
32 GtkActionGroup *actions;
33
34 #define DSN_PAGE "DSN_Page"
35 #define PROVIDER_PAGE "Provider_Page"
36 static GtkWidget *create_main_notebook (void);
37
38 static void
show_error(GtkWindow * parent,const gchar * format,...)39 show_error (GtkWindow *parent, const gchar *format, ...)
40 {
41 va_list args;
42 gchar sz[2048];
43 GtkWidget *dialog;
44
45 /* build the message string */
46 va_start (args, format);
47 vsnprintf (sz, sizeof sz, format, args);
48 va_end (args);
49
50 /* create the error message dialog */
51 gchar *str;
52 str = g_strconcat ("<span weight=\"bold\">",
53 _("Error:"),
54 "</span>\n",
55 sz,
56 NULL);
57
58 dialog = gtk_message_dialog_new_with_markup (parent,
59 GTK_DIALOG_DESTROY_WITH_PARENT |
60 GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR,
61 GTK_BUTTONS_CLOSE, "%s", str);
62 gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
63 gtk_button_new_from_stock (GTK_STOCK_OK),
64 GTK_RESPONSE_OK);
65 gtk_widget_show_all (dialog);
66 gtk_dialog_run (GTK_DIALOG (dialog));
67 gtk_widget_destroy (dialog);
68 }
69
70 static void
assistant_finished_cb(GdauiDsnAssistant * assistant,gboolean error,G_GNUC_UNUSED gpointer user_data)71 assistant_finished_cb (GdauiDsnAssistant *assistant, gboolean error, G_GNUC_UNUSED gpointer user_data)
72 {
73 const GdaDsnInfo *dsn_info;
74
75 if (!error) {
76 dsn_info = gdaui_dsn_assistant_get_dsn (assistant);
77 if (dsn_info) {
78 if (! gda_config_define_dsn (dsn_info, NULL))
79 show_error (NULL, _("Could not declare new data source"));
80 }
81 else
82 show_error (NULL, _("No valid data source info was created"));
83 }
84 }
85
86 static void
assistant_closed_cb(GdauiDsnAssistant * assistant,G_GNUC_UNUSED gpointer user_data)87 assistant_closed_cb (GdauiDsnAssistant *assistant, G_GNUC_UNUSED gpointer user_data)
88 {
89 gtk_widget_destroy (GTK_WIDGET (assistant));
90 }
91
92 static void
file_new_cb(G_GNUC_UNUSED GtkAction * action,G_GNUC_UNUSED gpointer user_data)93 file_new_cb (G_GNUC_UNUSED GtkAction *action, G_GNUC_UNUSED gpointer user_data)
94 {
95 GtkWidget *assistant;
96
97 assistant = gdaui_dsn_assistant_new ();
98 g_signal_connect (G_OBJECT (assistant), "finished",
99 G_CALLBACK (assistant_finished_cb), NULL);
100 g_signal_connect (G_OBJECT (assistant), "close",
101 G_CALLBACK (assistant_closed_cb), NULL);
102 gtk_widget_show (assistant);
103 }
104
105 static void
file_properties_cb(G_GNUC_UNUSED GtkAction * action,gpointer user_data)106 file_properties_cb (G_GNUC_UNUSED GtkAction *action, gpointer user_data)
107 {
108 GtkWidget *nb = GTK_WIDGET (user_data);
109 GtkWidget *dsn, *provider, *current_widget;
110 gint current;
111
112 dsn = g_object_get_data (G_OBJECT (nb), DSN_PAGE);
113 provider = g_object_get_data (G_OBJECT (nb), PROVIDER_PAGE);
114
115 current = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb));
116 if (current == -1)
117 return;
118
119 current_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), current);
120 if (current_widget == dsn)
121 dsn_config_edit_properties (dsn);
122 }
123
124 static void
file_delete_cb(G_GNUC_UNUSED GtkAction * action,gpointer user_data)125 file_delete_cb (G_GNUC_UNUSED GtkAction *action, gpointer user_data)
126 {
127 GtkWidget *nb = GTK_WIDGET (user_data);
128 GtkWidget *dsn, *provider, *current_widget;
129 gint current;
130
131 dsn = g_object_get_data (G_OBJECT (nb), DSN_PAGE);
132 provider = g_object_get_data (G_OBJECT (nb), PROVIDER_PAGE);
133
134 current = gtk_notebook_get_current_page (GTK_NOTEBOOK (nb));
135 if (current == -1)
136 return;
137
138 current_widget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (nb), current);
139 if (current_widget == dsn)
140 dsn_config_delete (dsn);
141 }
142
143 static void
window_closed_cb(G_GNUC_UNUSED GtkAction * action,G_GNUC_UNUSED gpointer user_data)144 window_closed_cb (G_GNUC_UNUSED GtkAction *action, G_GNUC_UNUSED gpointer user_data)
145 {
146 g_application_quit (G_APPLICATION (app));
147 }
148
149 static void
about_cb(G_GNUC_UNUSED GtkAction * action,G_GNUC_UNUSED gpointer user_data)150 about_cb (G_GNUC_UNUSED GtkAction *action, G_GNUC_UNUSED gpointer user_data)
151 {
152 GdkPixbuf *icon;
153 GtkWidget *dialog;
154 const gchar *authors[] = {
155 "Vivien Malerba <malerba@gnome-db.org> (current maintainer)",
156 "Rodrigo Moya <rodrigo@gnome-db.org>",
157 "Carlos Perello Marin <carlos@gnome-db.org>",
158 "Gonzalo Paniagua Javier <gonzalo@gnome-db.org>",
159 "Laurent Sansonetti <lrz@gnome.org>",
160 "Daniel Espinosa <esodan@gmail.com>",
161 NULL
162 };
163 const gchar *documenters[] = {
164 "Rodrigo Moya <rodrigo@gnome-db.org>",
165 NULL
166 };
167 const gchar *translator_credits =
168 "Christian Rose <menthos@menthos.com> Swedish translations\n" \
169 "Kjartan Maraas <kmaraas@online.no> Norwegian translation\n";
170
171 gchar *path;
172 path = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "pixmaps", "gda-control-center.png", NULL);
173 icon = gdk_pixbuf_new_from_file (path, NULL);
174 g_free (path);
175
176 dialog = gtk_about_dialog_new ();
177 gtk_about_dialog_set_program_name (GTK_ABOUT_DIALOG (dialog), _("Database access control center"));
178 gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (dialog), PACKAGE_VERSION);
179 gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (dialog), "(C) 1998 - 2011 GNOME Foundation");
180 gtk_about_dialog_set_comments (GTK_ABOUT_DIALOG (dialog), _("Database access services for the GNOME Desktop"));
181 gtk_about_dialog_set_license (GTK_ABOUT_DIALOG (dialog), "GNU Lesser General Public License");
182 gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (dialog), "http://www.gnome-db.org");
183 gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (dialog), authors);
184 gtk_about_dialog_set_documenters (GTK_ABOUT_DIALOG (dialog), documenters);
185 gtk_about_dialog_set_translator_credits (GTK_ABOUT_DIALOG (dialog), translator_credits);
186 gtk_about_dialog_set_logo (GTK_ABOUT_DIALOG (dialog), icon);
187 g_signal_connect (G_OBJECT (dialog), "response",
188 G_CALLBACK (gtk_widget_destroy),
189 dialog);
190 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (main_window));
191 gtk_widget_show (dialog);
192
193 }
194
195 static GtkActionEntry ui_actions[] = {
196 { "Database", NULL, N_("_Data source"), NULL, N_("Database"), NULL },
197 { "DatabaseClose", GTK_STOCK_CLOSE, N_("_Close"), NULL, N_("Close this window"), G_CALLBACK (window_closed_cb) },
198 { "DatabaseNew", GTK_STOCK_NEW, N_("_New datasource"), NULL, N_("Create new data source"), G_CALLBACK (file_new_cb) },
199 { "DatabaseDelete", GTK_STOCK_DELETE, N_("_Delete datasource"), NULL, N_("Delete selected data source"), G_CALLBACK (file_delete_cb) },
200 { "DatabaseProperties", GTK_STOCK_PROPERTIES, N_("_Properties"), NULL, N_("Edit properties for selected data source"), G_CALLBACK (file_properties_cb) },
201 { "About", NULL, N_("_About"), NULL, N_("About"), NULL },
202 { "HelpAbout", GTK_STOCK_ABOUT, N_("_About"), NULL, N_("About GNOME-DB"), G_CALLBACK (about_cb) }
203 };
204
205 static const gchar *ui_actions_info =
206 "<ui>"
207 " <menubar name='MenuBar'>"
208 " <menu name='Database' action='Database'>"
209 " <menuitem name='DatabaseNew' action= 'DatabaseNew'/>"
210 " <menuitem name='DatabaseProperties' action= 'DatabaseProperties'/>"
211 " <menuitem name='DatabaseDelete' action= 'DatabaseDelete'/>"
212 " <separator/>"
213 " <menuitem name='DatabaseClose' action= 'DatabaseClose'/>"
214 " </menu>"
215 " <menu name='About' action='About'>"
216 " <menuitem name='HelpAbout' action= 'HelpAbout'/>"
217 " </menu>"
218 " </menubar>"
219 " <toolbar name='ToolBar'>"
220 " <toolitem action='DatabaseNew'/>"
221 " <toolitem action='DatabaseProperties'/>"
222 " <toolitem action='DatabaseDelete'/>"
223 " </toolbar>"
224 "</ui>";
225
226 static void
prepare_menu(GtkBox * vbox,GtkWidget * nb)227 prepare_menu (GtkBox *vbox, GtkWidget *nb)
228 {
229 GtkWidget *menubar;
230 GtkWidget *toolbar;
231 GtkUIManager *ui;
232
233 actions = gtk_action_group_new ("Actions");
234 gtk_action_group_set_translation_domain (actions, GETTEXT_PACKAGE);
235 gtk_action_group_add_actions (actions, ui_actions, G_N_ELEMENTS (ui_actions), nb);
236
237 ui = gtk_ui_manager_new ();
238 gtk_ui_manager_insert_action_group (ui, actions, 0);
239 gtk_ui_manager_add_ui_from_string (ui, ui_actions_info, -1, NULL);
240
241 menubar = gtk_ui_manager_get_widget (ui, "/MenuBar");
242 gtk_box_pack_start (vbox, menubar, FALSE, FALSE, 0);
243 gtk_widget_show (menubar);
244
245 toolbar = gtk_ui_manager_get_widget (ui, "/ToolBar");
246 gtk_box_pack_start (vbox, toolbar, FALSE, FALSE, 0);
247 gtk_widget_show (toolbar);
248
249 GtkAction *action;
250 action = gtk_action_group_get_action (actions, "DatabaseProperties");
251 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
252 action = gtk_action_group_get_action (actions, "DatabaseDelete");
253 g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
254 }
255
256
257 static GtkWidget *
create_main_window(void)258 create_main_window (void)
259 {
260 GtkWidget *window, *vbox;
261 GtkWidget *nb;
262 GdkPixbuf *icon;
263
264 /* create the main window */
265 window = gtk_application_window_new (app);
266 main_window = GTK_WINDOW (window);
267 gtk_window_set_title (GTK_WINDOW (window), _("Database access control center"));
268 gtk_window_set_position (GTK_WINDOW (window), GTK_WIN_POS_CENTER);
269 gtk_window_set_default_size (GTK_WINDOW (window), 650, 600);
270 g_signal_connect (G_OBJECT (window), "destroy",
271 G_CALLBACK (window_closed_cb), NULL);
272
273 /* icon */
274 gchar *path;
275 path = gda_gbr_get_file_path (GDA_DATA_DIR, LIBGDA_ABI_NAME, "pixmaps", "gda-control-center.png", NULL);
276 icon = gdk_pixbuf_new_from_file (path, NULL);
277 g_free (path);
278 if (icon) {
279 gtk_window_set_icon (GTK_WINDOW (window), icon);
280 g_object_unref (icon);
281 }
282
283 /* menu and contents */
284 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
285 gtk_container_add (GTK_CONTAINER (window), vbox);
286 gtk_widget_show (vbox);
287
288 nb = create_main_notebook ();
289 prepare_menu (GTK_BOX (vbox), nb);
290
291 gtk_container_set_border_width (GTK_CONTAINER (nb), 6);
292 gtk_box_pack_start (GTK_BOX (vbox), nb, TRUE, TRUE, 0);
293 gtk_widget_show (nb);
294
295 gtk_widget_show (window);
296 return window;
297 }
298
299 static void
activate(GtkApplication * app)300 activate (GtkApplication *app)
301 {
302 static GtkWidget *window = NULL;
303
304 if (! window) {
305 gdaui_init ();
306 window = create_main_window ();
307 gtk_window_set_application (GTK_WINDOW (window), app);
308 gtk_widget_show (window);
309 }
310 }
311
312 int
main(int argc,char * argv[])313 main (int argc, char *argv[])
314 {
315 gint status;
316
317 app = gtk_application_new ("org.GnomeDb.GdaBrowser", G_APPLICATION_FLAGS_NONE);
318 g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
319
320 status = g_application_run (G_APPLICATION (app), argc, argv);
321
322 g_object_unref (app);
323
324 return status;
325 }
326
327 static void
dsn_selection_changed_cb(GdauiRawGrid * dbrawgrid,G_GNUC_UNUSED gboolean row_selected,G_GNUC_UNUSED gpointer data)328 dsn_selection_changed_cb (GdauiRawGrid *dbrawgrid, G_GNUC_UNUSED gboolean row_selected, G_GNUC_UNUSED gpointer data)
329 {
330 GtkAction *action;
331 GArray *selection;
332
333 selection = gdaui_data_selector_get_selected_rows (GDAUI_DATA_SELECTOR (dbrawgrid));
334
335 action = gtk_action_group_get_action (actions, "DatabaseProperties");
336 g_object_set (G_OBJECT (action), "sensitive", selection ? TRUE : FALSE, NULL);
337
338 action = gtk_action_group_get_action (actions, "DatabaseDelete");
339 g_object_set (G_OBJECT (action), "sensitive", selection ? TRUE : FALSE, NULL);
340 if (selection)
341 g_array_free (selection, TRUE);
342 }
343
344 static void
main_nb_page_switched_cb(G_GNUC_UNUSED GtkNotebook * notebook,G_GNUC_UNUSED GtkWidget * page,guint page_num,G_GNUC_UNUSED gpointer data)345 main_nb_page_switched_cb (G_GNUC_UNUSED GtkNotebook *notebook, G_GNUC_UNUSED GtkWidget *page, guint page_num, G_GNUC_UNUSED gpointer data)
346 {
347 gboolean show;
348 GtkAction *action;
349
350 if (!actions)
351 return;
352
353 show = page_num == 0 ? TRUE : FALSE;
354 action = gtk_action_group_get_action (actions, "DatabaseProperties");
355 g_object_set (G_OBJECT (action), "visible", show, NULL);
356 action = gtk_action_group_get_action (actions, "DatabaseDelete");
357 g_object_set (G_OBJECT (action), "visible", show, NULL);
358 }
359
360 static GtkWidget *
create_main_notebook(void)361 create_main_notebook (void)
362 {
363 GtkWidget *nb;
364 GtkWidget *dsn;
365 GtkWidget *provider;
366 GdauiRawGrid *grid;
367
368 nb = gtk_notebook_new ();
369 gtk_notebook_set_show_tabs (GTK_NOTEBOOK (nb), TRUE);
370 gtk_notebook_set_scrollable (GTK_NOTEBOOK (nb), TRUE);
371 gtk_notebook_popup_enable (GTK_NOTEBOOK (nb));
372 gtk_widget_show (nb);
373 g_signal_connect (G_OBJECT (nb), "switch-page",
374 G_CALLBACK (main_nb_page_switched_cb), NULL);
375
376 /* data source configuration page */
377 dsn = dsn_config_new ();
378 g_object_set_data (G_OBJECT (nb), DSN_PAGE, dsn);
379 gtk_notebook_append_page (GTK_NOTEBOOK (nb), dsn,
380 gtk_label_new (_("Data Sources")));
381
382 grid = g_object_get_data (G_OBJECT (dsn), "grid");
383 g_signal_connect (G_OBJECT (grid), "selection-changed",
384 G_CALLBACK (dsn_selection_changed_cb), NULL);
385
386 /* providers configuration page */
387 provider = provider_config_new ();
388 g_object_set_data (G_OBJECT (nb), PROVIDER_PAGE, provider);
389 gtk_notebook_append_page (GTK_NOTEBOOK (nb), provider,
390 gtk_label_new (_("Providers")));
391
392 return nb;
393 }
394