/* * GuiLoader examples * Copyright (c) 2006 Maxim Udushlivy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "application.h" void ApplicationInit(Application * app) { PangoFontDescription * pfd; GtkTextBuffer * buffer; app->loader= gui_loader_new(); GUIXML_DECL #include "typical.gui.h" GUIXML_LOAD(app->loader) app->window= gui_loader_bind_object(app->loader, "window1"); app->actions= gui_loader_bind_object(app->loader, "actionGroup1"); app->textView= gui_loader_bind_object(app->loader, "textView1"); app->statusbar= gui_loader_bind_object(app->loader, "statusbar1"); app->openDialog= gui_loader_bind_object(app->loader, "openDialog1"); app->saveDialog= gui_loader_bind_object(app->loader, "saveDialog1"); app->proceedDialog= gui_loader_bind_object(app->loader, "proceedDialog1"); pfd= pango_font_description_from_string("Monospace 10"); gtk_widget_modify_font(GTK_WIDGET(app->textView), pfd); pango_font_description_free(pfd); gui_loader_connect_signal(app->loader, "onNew", G_CALLBACK(OnNew), app); gui_loader_connect_signal(app->loader, "onOpen", G_CALLBACK(OnOpen), app); gui_loader_connect_signal(app->loader, "onSave", G_CALLBACK(OnSave), app); gui_loader_connect_signal(app->loader, "onSaveAs", G_CALLBACK(OnSaveAs), app); gui_loader_connect_signal(app->loader, "onQuit", G_CALLBACK(OnQuit), app); gui_loader_connect_signal(app->loader, "onCut", G_CALLBACK(OnCut), app); gui_loader_connect_signal(app->loader, "onCopy", G_CALLBACK(OnCopy), app); gui_loader_connect_signal(app->loader, "onPaste", G_CALLBACK(OnPaste), app); gui_loader_connect_signal(app->loader, "onDelete", G_CALLBACK(OnDelete), app); gui_loader_connect_signal(app->loader, "onAbout", G_CALLBACK(OnAbout), app); gui_loader_connect_signal(app->loader, "onDeleteEvent", G_CALLBACK(OnDeleteEvent), app); app->file= NULL; app->modified= FALSE; app->lock= FALSE; buffer= gtk_text_view_get_buffer(app->textView); g_signal_connect(buffer, "changed", G_CALLBACK(OnChanged), app); g_signal_connect(buffer, "mark-set", G_CALLBACK(OnMarkSet), app); gtk_statusbar_push(app->statusbar, 0, ""); UpdateUi(app); } void ApplicationDone(Application * app) { GtkTextBuffer * buffer= gtk_text_view_get_buffer(app->textView); g_signal_handlers_block_matched(buffer, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, app); SetFile(app, NULL); g_object_unref(app->loader); } void UpdateUi(Application * app) { gchar buf[256]; GtkTextBuffer * buffer; GtkTextIter pos; gboolean selection; if(!app->file) gtk_window_set_title(app->window, "Typical Example"); else { gchar * name= g_filename_to_utf8(app->file, -1, NULL, NULL, NULL); g_snprintf(buf, sizeof(buf), "Typical Example - %s", name); g_free(name); gtk_window_set_title(app->window, buf); } gtk_action_set_sensitive(gtk_action_group_get_action(app->actions, "Save"), app->modified || !app->file); buffer= gtk_text_view_get_buffer(app->textView); selection= gtk_text_buffer_get_selection_bounds(buffer, NULL, NULL); gtk_action_set_sensitive(gtk_action_group_get_action(app->actions, "Cut"), selection); gtk_action_set_sensitive(gtk_action_group_get_action(app->actions, "Copy"), selection); gtk_action_set_sensitive(gtk_action_group_get_action(app->actions, "Delete"), selection); gtk_text_buffer_get_iter_at_mark(buffer, &pos, gtk_text_buffer_get_insert(buffer)); g_snprintf(buf, sizeof(buf), "Cursor: %d:%d", gtk_text_iter_get_line(&pos)+1, gtk_text_iter_get_line_offset(&pos)+1); gtk_statusbar_pop(app->statusbar, 0); gtk_statusbar_push(app->statusbar, 0, buf); } void SetText(Application * app, const gchar * text) { GtkTextIter pos; GtkTextBuffer * buffer; app->lock= TRUE; buffer= gtk_text_view_get_buffer(app->textView); gtk_text_buffer_set_text(buffer, text, -1); gtk_text_buffer_get_start_iter(buffer, &pos); gtk_text_buffer_place_cursor(buffer, &pos); app->lock= FALSE; app->modified= FALSE; } gchar * GetText(Application * app) { GtkTextBuffer * buffer= gtk_text_view_get_buffer(app->textView); GtkTextIter start, end; gchar * data; gtk_text_buffer_get_bounds(buffer, &start, &end); data= gtk_text_buffer_get_text(buffer, &start, &end, FALSE); return data; } void SetFile(Application * app, gchar * str) { g_free(app->file); app->file= g_strdup(str); } void OnChanged(GtkTextBuffer * textbuffer, Application * app) { if(!app->lock) { app->modified= TRUE; UpdateUi(app); } } void OnMarkSet( GtkTextBuffer * textbuffer, GtkTextIter * arg1, GtkTextMark * arg2, Application * app ) { UpdateUi(app); } void OnNew(GtkAction * action, Application * app) { if(AskProceed(app)) { SetFile(app, NULL); SetText(app, ""); UpdateUi(app); } } void OnOpen(GtkAction * action, Application * app) { if(AskProceed(app)) { gchar * name= AskFilename(app, GTK_FILE_CHOOSER_ACTION_OPEN); if(name) { gchar * data= LoadFile(app, name); if(data) { SetText(app, data); SetFile(app, name); UpdateUi(app); g_free(data); } g_free(name); } } } void OnSave(GtkAction * action, Application * app) { gchar * name= g_strdup(app->file); if(!name) name= AskFilename(app, GTK_FILE_CHOOSER_ACTION_SAVE); if(name) { gchar * data= GetText(app); gboolean ok= SaveFile(app, name, data); g_free(data); if(ok) { SetFile(app, name); app->modified= FALSE; UpdateUi(app); } g_free(name); } } void OnSaveAs(GtkAction * action, Application * app) { gchar * name= AskFilename(app, GTK_FILE_CHOOSER_ACTION_SAVE); if(name) { gchar * data= GetText(app); gboolean ok= SaveFile(app, name, data); g_free(data); if(ok) { SetFile(app, name); app->modified= FALSE; UpdateUi(app); } g_free(name); } } void OnQuit(GtkAction * action, Application * app) { if(AskProceed(app)) gtk_main_quit(); } void OnCut(GtkAction * action, Application * app) { gtk_text_buffer_cut_clipboard( gtk_text_view_get_buffer(app->textView), gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), TRUE ); } void OnCopy(GtkAction * action, Application * app) { gtk_text_buffer_copy_clipboard( gtk_text_view_get_buffer(app->textView), gtk_clipboard_get(GDK_SELECTION_CLIPBOARD) ); } void OnPaste(GtkAction * action, Application * app) { gtk_text_buffer_paste_clipboard( gtk_text_view_get_buffer(app->textView), gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), NULL, TRUE ); } void OnDelete(GtkAction * action, Application * app) { gtk_text_buffer_delete_selection(gtk_text_view_get_buffer(app->textView), TRUE, TRUE); } void OnAbout(GtkAction * action, Application * app) { GtkAboutDialog * dialog= GTK_ABOUT_DIALOG(gtk_about_dialog_new()); gtk_about_dialog_set_name(dialog, "Typical Example"); gtk_about_dialog_set_comments(dialog, "Simple text editor"); gtk_about_dialog_set_version(dialog, "1.0"); gtk_window_set_transient_for(GTK_WINDOW(dialog), app->window); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_object_destroy(GTK_OBJECT(dialog)); } gboolean OnDeleteEvent(GtkWidget * widget, GdkEvent * event, Application * app) { OnQuit(NULL, app); return TRUE; } gchar * LoadFile(Application * app, const gchar * name) { gchar * contents; if(g_file_get_contents(name, &contents, NULL, NULL)) return contents; else { ShowMessage(app, "Loading failed"); return NULL; } } gboolean SaveFile(Application * app, const gchar * name, const gchar * data) { if(g_file_set_contents(name, data, -1, NULL)) { return TRUE; } else { ShowMessage(app, "Saving failed"); return FALSE; } } gchar * AskFilename(Application * app, GtkFileChooserAction action) { GtkFileChooserDialog * dialog= action==GTK_FILE_CHOOSER_ACTION_SAVE ? app->saveDialog : app->openDialog; gchar * F= NULL; gint result; if(app->file) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), app->file); else gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), g_get_home_dir()); result= gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_hide(GTK_WIDGET(dialog)); if(result == GTK_RESPONSE_OK) { F= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); if(action==GTK_FILE_CHOOSER_ACTION_SAVE) { gchar * base= g_path_get_basename(F); if(strchr(base, '.')==NULL) { gchar * tmp= F; F= g_strjoin(NULL, F, ".txt", NULL); g_free(tmp); } g_free(base); } } return F; } gboolean AskProceed(Application * app) { if(app->modified) { gint result= gtk_dialog_run(app->proceedDialog); gtk_widget_hide(GTK_WIDGET(app->proceedDialog)); return result == GTK_RESPONSE_OK; } else return TRUE; } void ShowMessage(Application * app, const gchar * message) { GtkWidget * dialog= gtk_message_dialog_new( app->window, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, message ); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_object_destroy(GTK_OBJECT(dialog)); }