2 * Copyright (c) 2008 Jiri Benc <jbenc@upir.cz>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include <hildon/hildon.h>
22 #include <hildon/hildon-file-chooser-dialog.h>
24 #include <libgnomevfs/gnome-vfs.h>
25 #include <gconf/gconf.h>
26 #include <gconf/gconf-client.h>
28 #include "ukbdcreator.h"
30 static HildonWindow *window_main;
31 static GtkClipboard *clipboard;
32 static GtkTextView *view;
33 static GtkTextBuffer *buffer;
34 static gchar *filename = NULL;
35 static gboolean is_fullscreen = FALSE;
36 static gboolean is_modified = FALSE;
38 static int last_error_line = 0;
39 static gchar *last_error_msg = NULL;
41 static GConfClient *conf;
44 static void toggle_fullscreen(void)
47 gtk_window_unfullscreen(GTK_WINDOW(window_main));
49 gtk_window_fullscreen(GTK_WINDOW(window_main));
50 is_fullscreen = !is_fullscreen;
53 static void set_modified(void)
58 static void set_filename(gchar *fname)
65 void disp_error(gchar *msg)
67 hildon_banner_show_information(GTK_WIDGET(window_main), GTK_STOCK_DIALOG_ERROR, msg);
70 void disp_info(gchar *msg)
72 hildon_banner_show_information(GTK_WIDGET(window_main), GTK_STOCK_DIALOG_INFO, msg);
75 static void __disp_compile_error(void)
81 if (last_error_line > 0) {
82 gtk_text_buffer_get_iter_at_line(buffer, &iter, last_error_line - 1);
83 gtk_text_buffer_place_cursor(buffer, &iter);
84 gtk_text_view_scroll_mark_onscreen(view, gtk_text_buffer_get_mark(buffer, "insert"));
86 hildon_banner_show_information(GTK_WIDGET(window_main), GTK_STOCK_DIALOG_ERROR, last_error_msg);
89 void disp_compile_error(int line, gchar *msg)
91 g_free(last_error_msg);
92 last_error_msg = g_strdup(msg);
93 last_error_line = line;
94 __disp_compile_error();
97 static gboolean read_file(gchar *fname)
99 GnomeVFSFileInfo finfo;
100 GnomeVFSHandle *handle = NULL;
101 GnomeVFSFileSize bytes;
104 if (gnome_vfs_get_file_info(fname, &finfo, GNOME_VFS_FILE_INFO_DEFAULT) != GNOME_VFS_OK ||
105 gnome_vfs_open(&handle, fname, GNOME_VFS_OPEN_READ) != GNOME_VFS_OK) {
106 disp_error("Error opening file");
109 buf = g_malloc0(finfo.size + 1);
111 gnome_vfs_close(handle);
112 disp_error("Not enough memory");
115 if (gnome_vfs_read(handle, buf, finfo.size, &bytes) != GNOME_VFS_OK || bytes != finfo.size) {
116 gnome_vfs_close(handle);
118 disp_error("Error reading file");
121 gnome_vfs_close(handle);
123 gtk_text_buffer_set_text(buffer, buf, -1);
128 static gchar *get_buffer(void)
130 GtkTextIter start, end;
132 gtk_text_buffer_get_bounds(buffer, &start, &end);
133 return gtk_text_buffer_get_slice(buffer, &start, &end, TRUE);
136 static gboolean write_file(gchar *fname)
138 GnomeVFSHandle *handle = NULL;
139 GnomeVFSFileSize bytes;
143 if (gnome_vfs_create(&handle, fname, GNOME_VFS_OPEN_WRITE, FALSE, 0644) != GNOME_VFS_OK) {
144 disp_error("Error creating file");
149 if (gnome_vfs_write(handle, buf, size, &bytes) != GNOME_VFS_OK || bytes != size) {
150 gnome_vfs_close(handle);
152 disp_error("Error writing file");
155 gnome_vfs_close(handle);
161 static gchar *file_chooser(gboolean open)
164 GtkFileFilter *filter;
165 gchar *result = NULL;
167 chooser = hildon_file_chooser_dialog_new(GTK_WINDOW(window_main),
168 open ? GTK_FILE_CHOOSER_ACTION_OPEN : GTK_FILE_CHOOSER_ACTION_SAVE);
169 filter = gtk_file_filter_new();
170 gtk_file_filter_add_pattern(filter, "*.def");
171 gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(chooser), filter);
172 gtk_widget_show_all(chooser);
173 if (gtk_dialog_run(GTK_DIALOG(chooser)) == GTK_RESPONSE_OK)
174 result = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(chooser));
175 gtk_widget_destroy(chooser);
176 if (!open && result && !g_str_has_suffix(result, ".def")) {
179 result = g_strconcat(result, ".def", NULL);
185 static void file_save_as(void)
189 fname = file_chooser(FALSE);
191 if (write_file(fname)) {
199 static void file_save(void)
205 if (write_file(filename))
209 static gboolean file_ask_save(void)
216 note = hildon_note_new_confirmation_add_buttons(GTK_WINDOW(window_main),
217 "Save the file before closing?", "Yes", 1, "No", 2, "Cancel", 0, NULL);
218 res = gtk_dialog_run(GTK_DIALOG(note));
219 gtk_widget_destroy(note);
229 static void file_open(void)
233 if (!file_ask_save())
235 fname = file_chooser(TRUE);
237 if (read_file(fname)) {
240 g_free(last_error_msg);
241 last_error_msg = NULL;
247 static void file_new(void)
249 if (!file_ask_save())
251 gtk_text_buffer_set_text(buffer, "", -1);
254 g_free(last_error_msg);
255 last_error_msg = NULL;
258 static gboolean file_quit(void)
260 if (!file_ask_save())
262 restore_layout(conf, FALSE);
267 static void edit_cut(void)
269 gtk_text_buffer_cut_clipboard(buffer, clipboard, TRUE);
272 static void edit_copy(void)
274 gtk_text_buffer_copy_clipboard(buffer, clipboard);
277 static void edit_paste(void)
279 gtk_text_buffer_paste_clipboard(buffer, clipboard, NULL, TRUE);
282 static void run_about(void)
284 gtk_show_about_dialog(GTK_WINDOW(window_main),
285 "version", UKBD_VERSION,
286 "comments", "Licensed under GPLv2. Please send bug reports and feature requests to jbenc@upir.cz.",
287 "copyright", "(c) 2008 Jiri Benc",
288 "website", "http://upir.cz/maemo/keyboards/");
291 static void compile_and_test(void)
293 gchar *buf, *fname, *lang;
297 res = compile_layout(buf, &fname, &lang);
300 test_layout(conf, fname, lang);
306 static void untest(void)
308 restore_layout(conf, TRUE);
311 static gboolean key_pressed(GtkWidget *widget, GdkEventKey *event)
314 switch (event->keyval) {
322 static GtkWidget *main_layout(void)
326 view = GTK_TEXT_VIEW(gtk_text_view_new());
327 gtk_text_view_set_editable(view, TRUE);
328 gtk_text_view_set_left_margin(view, 10);
329 gtk_text_view_set_right_margin(view, 10);
331 scroll = gtk_scrolled_window_new(NULL, NULL);
332 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
333 gtk_container_add(GTK_CONTAINER(scroll), GTK_WIDGET(view));
335 buffer = gtk_text_view_get_buffer(view);
336 g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(set_modified), NULL);
337 g_signal_connect(G_OBJECT(buffer), "modified-changed", G_CALLBACK(set_modified), NULL);
342 static GtkMenu *main_menu(void)
344 GtkMenuShell *menu, *submenu;
347 menu = GTK_MENU_SHELL(gtk_menu_new());
349 submenu = GTK_MENU_SHELL(gtk_menu_new());
350 item = gtk_menu_item_new_with_label("File");
351 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), GTK_WIDGET(submenu));
352 gtk_menu_shell_append(menu, item);
354 item = gtk_menu_item_new_with_label("New");
355 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(file_new), NULL);
356 gtk_menu_shell_append(submenu, item);
357 item = gtk_menu_item_new_with_label("Open...");
358 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(file_open), NULL);
359 gtk_menu_shell_append(submenu, item);
360 item = gtk_menu_item_new_with_label("Save");
361 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(file_save), NULL);
362 gtk_menu_shell_append(submenu, item);
363 item = gtk_menu_item_new_with_label("Save as...");
364 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(file_save_as), NULL);
365 gtk_menu_shell_append(submenu, item);
367 submenu = GTK_MENU_SHELL(gtk_menu_new());
368 item = gtk_menu_item_new_with_label("Edit");
369 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), GTK_WIDGET(submenu));
370 gtk_menu_shell_append(menu, item);
372 item = gtk_menu_item_new_with_label("Cut");
373 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_cut), NULL);
374 gtk_menu_shell_append(submenu, item);
375 item = gtk_menu_item_new_with_label("Copy");
376 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_copy), NULL);
377 gtk_menu_shell_append(submenu, item);
378 item = gtk_menu_item_new_with_label("Paste");
379 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(edit_paste), NULL);
380 gtk_menu_shell_append(submenu, item);
382 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
383 item = gtk_menu_item_new_with_label("Test layout");
384 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(compile_and_test), NULL);
385 gtk_menu_shell_append(menu, item);
386 item = gtk_menu_item_new_with_label("Restore original layout");
387 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(untest), NULL);
388 gtk_menu_shell_append(menu, item);
389 item = gtk_menu_item_new_with_label("Show last error");
390 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(__disp_compile_error), NULL);
391 gtk_menu_shell_append(menu, item);
393 gtk_menu_shell_append(menu, gtk_separator_menu_item_new());
394 item = gtk_menu_item_new_with_label("Fullscreen");
395 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(toggle_fullscreen), NULL);
396 gtk_menu_shell_append(menu, item);
397 item = gtk_menu_item_new_with_label("About");
398 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(run_about), NULL);
399 gtk_menu_shell_append(menu, item);
400 item = gtk_menu_item_new_with_label("Exit");
401 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(file_quit), NULL);
402 gtk_menu_shell_append(menu, item);
404 return GTK_MENU(menu);
407 static GtkToolbar *main_toolbar(void)
412 bar = GTK_TOOLBAR(gtk_toolbar_new());
413 gtk_toolbar_set_orientation(bar, GTK_ORIENTATION_HORIZONTAL);
414 gtk_toolbar_set_style(bar, GTK_TOOLBAR_BOTH_HORIZ);
416 item = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
417 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(file_open), NULL);
418 gtk_toolbar_insert(bar, item, -1);
419 item = gtk_tool_button_new_from_stock(GTK_STOCK_SAVE);
420 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(file_save), NULL);
421 gtk_toolbar_insert(bar, item, -1);
422 gtk_toolbar_insert(bar, gtk_separator_tool_item_new(), -1);
423 item = gtk_tool_button_new_from_stock(GTK_STOCK_CUT);
424 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(edit_cut), NULL);
425 gtk_toolbar_insert(bar, item, -1);
426 item = gtk_tool_button_new_from_stock(GTK_STOCK_COPY);
427 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(edit_copy), NULL);
428 gtk_toolbar_insert(bar, item, -1);
429 item = gtk_tool_button_new_from_stock(GTK_STOCK_PASTE);
430 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(edit_paste), NULL);
431 gtk_toolbar_insert(bar, item, -1);
432 gtk_toolbar_insert(bar, gtk_separator_tool_item_new(), -1);
433 item = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
434 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(compile_and_test), NULL);
435 gtk_toolbar_insert(bar, item, -1);
436 item = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP);
437 g_signal_connect(G_OBJECT(item), "clicked", G_CALLBACK(untest), NULL);
438 gtk_toolbar_insert(bar, item, -1);
443 int main(int argc, char **argv)
445 HildonProgram *program;
447 gtk_init(&argc, &argv);
448 program = hildon_program_get_instance();
449 g_set_prgname("ukbdcreator");
450 g_set_application_name("Ukeyboard Creator");
451 osso_initialize("cz.upir.ukbdcreator", UKBD_VERSION, TRUE, NULL);
453 conf = gconf_client_get_default();
454 gconf_client_add_dir(conf, "/apps/osso/inputmethod/hildon-im-languages",
455 GCONF_CLIENT_PRELOAD_NONE, NULL);
457 window_main = HILDON_WINDOW(hildon_window_new());
458 hildon_program_add_window(program, window_main);
459 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
460 gtk_clipboard_set_can_store(clipboard, NULL, 0);
462 gtk_container_add(GTK_CONTAINER(window_main), main_layout());
463 hildon_window_set_menu(window_main, main_menu());
464 hildon_window_add_toolbar(window_main, main_toolbar());
466 g_signal_connect(G_OBJECT(window_main), "key_press_event", G_CALLBACK(key_pressed), NULL);
467 g_signal_connect(G_OBJECT(window_main), "delete_event", G_CALLBACK(file_quit), NULL);
469 gtk_widget_show_all(GTK_WIDGET(window_main));