From 53276e8a54c04b16c60e5ae00a2bf9bb12c30093 Mon Sep 17 00:00:00 2001 From: Jesse van den Kieboom Date: Sat, 19 Nov 2005 13:05:06 +0000 Subject: [PATCH] Improved searching --- gnoemoe/widgets/gm-world-view.c | 315 +++++++++++++++++++++----------- 1 file changed, 212 insertions(+), 103 deletions(-) diff --git a/gnoemoe/widgets/gm-world-view.c b/gnoemoe/widgets/gm-world-view.c index dabfae4..fd11107 100644 --- a/gnoemoe/widgets/gm-world-view.c +++ b/gnoemoe/widgets/gm-world-view.c @@ -1,4 +1,5 @@ #include +#include #include "../gm-app.h" #include "gm-world-view.h" @@ -6,12 +7,16 @@ #include "gm-world-input-view.h" #include "gm-text-scroller.h" #include "gm-editor-view.h" +#include "gm-embedded-view.h" +#include "gm-external-view.h" + #include "../gm-debug.h" #include "../gm-support.h" #include "../gm-color-table.h" #include "../mcp/gm-mcp-package.h" #include "../mcp/gm-mcp-session.h" #include "../gm-editor.h" +#include "gm-searchable.h" #define GM_WORLD_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), \ GM_TYPE_WORLD_VIEW, GmWorldViewPrivate)) @@ -24,6 +29,8 @@ struct _GmWorldViewPrivate { GmWorldTextView *text_view_world; GmWorldInputView *text_view_input; GmTextScroller *text_scroller_world; + + GList *external_editors; }; void on_gm_world_view_world_text_received(GmWorld *world, gchar *text, @@ -51,24 +58,54 @@ gboolean on_gm_world_view_world_text_view_scroll_event(GmWorldView *view, GdkEventScroll *event, GmWorldTextView *text); void on_gm_world_view_world_text_view_url_activate(GmWorldView *view, gchar const *url); - +void on_gm_world_view_editor_view_close_clicked(GtkButton *button, + GtkWidget *view); + gboolean on_gm_world_view_world_input_view_key_pressed(GtkWidget *widget, GdkEventKey *event, GmWorldView *view); - -/* Signals */ + +/* Signals -/*enum { - NUM_SIGNALS +enum { + NUM_SIGNALS }; -static guint world_view_signals[NUM_SIGNALS] = {0};*/ +static guint gm_world_view_signals[NUM_SIGNALS] = {0};*/ -G_DEFINE_TYPE(GmWorldView, gm_world_view, GTK_TYPE_NOTEBOOK) +static void gm_world_view_searchable_iface_init( + GmSearchableInterface *iface); + +static GtkTextView *gm_world_view_searchable_get_text_view(GmSearchable *sea); + +G_DEFINE_TYPE_EXTENDED(GmWorldView, gm_world_view, GTK_TYPE_NOTEBOOK, 0, \ + G_IMPLEMENT_INTERFACE(GM_TYPE_SEARCHABLE, \ + gm_world_view_searchable_iface_init)) + +static void +gm_world_view_searchable_iface_init(GmSearchableInterface *iface) { + iface->get_text_view = gm_world_view_searchable_get_text_view; +} + +static GtkTextView * +gm_world_view_searchable_get_text_view(GmSearchable *sea) { + GmWorldView *view = (GmWorldView *)(sea); + + g_return_val_if_fail(GM_IS_WORLD_VIEW(sea), NULL); + + return GTK_TEXT_VIEW(view->priv->text_view_world); +} static void gm_world_view_finalize(GObject *object) { GmWorldView *view = GM_WORLD_VIEW(object); - + GList *ext; + + for (ext = view->priv->external_editors; ext; ext = ext->next) { + gm_external_view_destroy(GM_EXTERNAL_VIEW(ext->data)); + } + + g_list_free(view->priv->external_editors); + g_signal_handlers_disconnect_by_func(view->priv->world, G_CALLBACK(on_gm_world_view_world_text_received), view); g_signal_handlers_disconnect_by_func(view->priv->world, @@ -95,7 +132,7 @@ gm_world_view_class_init(GmWorldViewClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS(klass); object_class->finalize = gm_world_view_finalize; - + g_type_class_add_private(object_class, sizeof(GmWorldViewPrivate)); } @@ -158,34 +195,74 @@ gm_world_view_update_status(GmWorldView *view, gchar const *status) { } } -GmEditorView * +GtkWidget * +gm_world_view_log_page_new(GmWorldView *view, gchar const *filename) { + /*GtkWidget *label; + GmLabelInfo info; + GtkWidget *scrolled_window = gtk_scrolled_window_new(); + GtkWidget *text_view; + + label = gm_create_tab_label("editor_text.xpm", */ + return NULL; +} + +GtkWidget * +gm_world_view_editor_create_view(GmWorldView *view, GmEditor *editor) { + GtkWidget *editor_view; + GmOptions *options = gm_app_options(gm_app_instance()); + if (strcmp(gm_options_get(options, "editor_alternative"), + "0") != 0) { + if (gm_options_get_int(options, "editor_embed")) { + editor_view = GTK_WIDGET(gm_embedded_view_new(view->priv->world, + editor)); + } else { + view->priv->external_editors = g_list_append( + view->priv->external_editors, + gm_external_view_new(view->priv->world, editor)); + return NULL; + } + } else { + editor_view = GTK_WIDGET(gm_editor_view_new(view->priv->world, editor)); + g_signal_connect(editor_view, "modified-changed", + G_CALLBACK(on_gm_world_view_editor_view_modified_changed), + view); + } + + gtk_widget_show(editor_view); + return editor_view; +} + +GtkWidget * gm_world_view_editor_page_new(GmWorldView *view, GmEditor *editor) { - GmEditorView *editor_view = gm_editor_view_new(view->priv->world, editor); GtkWidget *label; + GtkWidget *editor_view; + GmLabelInfo info; gchar const *icon; - + if (gm_editor_is_code(editor)) { icon = "editor_verb.xpm"; } else { icon = "editor_text.xpm"; } - gtk_widget_show(GTK_WIDGET(editor_view)); label = gm_create_tab_label("editor_verb.xpm", gm_editor_name(editor), TRUE, &info); - gtk_notebook_append_page(GTK_NOTEBOOK(view), GTK_WIDGET(editor_view), - label); + + editor_view = gm_world_view_editor_create_view(view, editor); + + if (editor_view == NULL) { + return NULL; + } + + gtk_notebook_append_page(GTK_NOTEBOOK(view), editor_view, label); gtk_notebook_set_show_tabs(GTK_NOTEBOOK(view), TRUE); gtk_notebook_set_current_page(GTK_NOTEBOOK(view), - gtk_notebook_page_num(GTK_NOTEBOOK(view), - GTK_WIDGET(editor_view))); + gtk_notebook_page_num(GTK_NOTEBOOK(view), editor_view)); - GM_DEBUG("Connecting modified changed!!!"); - - g_signal_connect(editor_view, "modified-changed", - G_CALLBACK(on_gm_world_view_editor_view_modified_changed), - view); + g_signal_connect(info.button_exit, "clicked", + G_CALLBACK(on_gm_world_view_editor_view_close_clicked), + editor_view); return editor_view; } @@ -289,83 +366,6 @@ gm_world_view_new(GmWorld *world) { return GTK_WIDGET(view); } -gboolean -gm_world_view_find_first(GmWorldView *view, const gchar *str, - GmWorldViewSearchFlags flags) { - GtkTextView *tview = GTK_TEXT_VIEW(view->priv->text_view_world); - GtkTextIter iter; - GtkTextBuffer *buffer; - - if (tview) { - buffer = gtk_text_view_get_buffer(tview); - - if (buffer) { - if (flags & GM_WORLD_VIEW_SEARCH_BACKWARDS) { - gtk_text_buffer_get_end_iter(buffer, &iter); - } else { - gtk_text_buffer_get_start_iter(buffer, &iter); - } - - gtk_text_buffer_place_cursor(buffer, &iter); - - return gm_world_view_find_next(view, str, flags); - } - } - - return FALSE; -} - -gboolean -gm_world_view_find_next(GmWorldView *view, const gchar *str, - GmWorldViewSearchFlags flags) { - GtkTextBuffer *buffer = NULL; - GtkTextView *tview = NULL; - GtkTextIter end, start, matchStart, matchEnd; - gboolean found = FALSE; - - if (*str == '\0') { - return FALSE; - } - - tview = GTK_TEXT_VIEW(view->priv->text_view_world); - - if (tview) { - buffer = gtk_text_view_get_buffer(tview); - } - - if (buffer) { - if (!gtk_text_buffer_get_selection_bounds(buffer, &start, &end)) { - if (flags & GM_WORLD_VIEW_SEARCH_BACKWARDS) { - gtk_text_buffer_get_end_iter(buffer, &end); - } else { - gtk_text_buffer_get_start_iter(buffer, &end); - } - - start = end; - } - - if (flags & GM_WORLD_VIEW_SEARCH_FORWARDS) { - found = gtk_text_iter_forward_search(&end, str, - GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, - &matchStart, &matchEnd, NULL); - } else { - found = gtk_text_iter_backward_search(&start, str, - GTK_TEXT_SEARCH_VISIBLE_ONLY | GTK_TEXT_SEARCH_TEXT_ONLY, - &matchStart, &matchEnd, NULL); - } - - if (found) { - gtk_text_buffer_place_cursor(buffer, &matchStart); - gtk_text_buffer_move_mark_by_name(buffer, "selection_bound", - &matchEnd); - gtk_text_view_scroll_to_iter(tview, &matchStart, - 0.0, FALSE, 0.0, 0.0); - } - } - - return found; -} - gboolean gm_world_view_text_active(GmWorldView *view) { return gtk_notebook_get_current_page(GTK_NOTEBOOK(view)) == 0; @@ -381,6 +381,82 @@ gm_world_view_scroll_end(GmWorldView *view) { // TODO } +gboolean +gm_world_view_page_can_find(GmWorldView *view, gint page_num) { + GtkWidget *page; + GmSearchable *sea; + + if (page_num == -1) { + return FALSE; + } else if (page_num == 0) { + return gm_searchable_can_find(GM_SEARCHABLE(view)); + } else { + page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(view), page_num); + + if (GM_IS_SEARCHABLE(page)) { + sea = GM_SEARCHABLE(page); + + return gm_searchable_can_find(sea); + } + } + + return FALSE; +} + +gboolean +gm_world_view_can_find(GmWorldView *view) { + gint np = gtk_notebook_get_current_page(GTK_NOTEBOOK(view)); + return gm_world_view_page_can_find(view, np); +} + +gboolean +gm_world_view_find_first(GmWorldView *view, const gchar *str, + GmSearchableSearchFlags flags) { + gint np = gtk_notebook_get_current_page(GTK_NOTEBOOK(view)); + GtkWidget *page; + GmSearchable *sea; + + if (np == 0) { + return gm_searchable_find_first(GM_SEARCHABLE(view), str, flags); + } else { + page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(view), np); + + if (GM_IS_SEARCHABLE(page)) { + sea = GM_SEARCHABLE(page); + + if (gm_searchable_can_find(sea)) { + return gm_searchable_find_first(sea, str, flags); + } + } + } + + return FALSE; +} + +gboolean +gm_world_view_find_next(GmWorldView *view, const gchar *str, + GmSearchableSearchFlags flags) { + gint np = gtk_notebook_get_current_page(GTK_NOTEBOOK(view)); + GtkWidget *page; + GmSearchable *sea; + + if (np == 0) { + return gm_searchable_find_next(GM_SEARCHABLE(view), str, flags); + } else { + page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(view), np); + + if (GM_IS_SEARCHABLE(page)) { + sea = GM_SEARCHABLE(page); + + if (gm_searchable_can_find(sea)) { + return gm_searchable_find_next(sea, str, flags); + } + } + } + + return FALSE; +} + GmWorld * gm_world_view_world(GmWorldView *view) { return view->priv->world; @@ -408,7 +484,7 @@ gm_world_view_hpaned(GmWorldView *view) { void gm_world_view_open_log(GmWorldView *view, const gchar *filename) { - // TODO: open log + gm_world_view_log_page_new(view, filename); } void @@ -463,6 +539,18 @@ on_gm_world_view_editor_save(GmEditor *editor, GmWorldView *view) { gtk_widget_grab_focus(GTK_WIDGET(view->priv->text_view_input)); } +void +on_gm_world_view_editor_view_close_clicked(GtkButton *button, + GtkWidget *view) { + // TODO: make this into an interface + if (GM_IS_EDITOR_VIEW(view)) { + gm_editor_close(gm_editor_view_editor(GM_EDITOR_VIEW(view))); + } else if (GM_IS_EMBEDDED_VIEW(view)) { + gm_editor_close(gm_embedded_view_editor(GM_EMBEDDED_VIEW(view))); + } +} + + void on_gm_world_view_editor_view_modified_changed(GmEditorView *editor_view, gboolean modified, GmWorldView *view) { @@ -508,19 +596,40 @@ on_gm_world_view_world_editor_removed(GmWorld *world, GmEditor *editor, GmWorldView *view) { gint i, n = gtk_notebook_get_n_pages(GTK_NOTEBOOK(view)); GtkWidget *page; + gboolean found = FALSE; + GList *ext; for (i = 1; i < n; ++i) { page = gtk_notebook_get_nth_page(GTK_NOTEBOOK(view), i); + found = GM_IS_EDITOR_VIEW(page) && gm_editor_view_editor( + GM_EDITOR_VIEW(page)) == editor; + found = found || (GM_IS_EMBEDDED_VIEW(page) && gm_embedded_view_editor( + GM_EMBEDDED_VIEW(page)) == editor); - if (GM_IS_EDITOR_VIEW(page) && gm_editor_view_editor( - GM_EDITOR_VIEW(page)) == editor) { - + if (found) { g_signal_handlers_disconnect_by_func(editor, on_gm_world_view_editor_save, view); gtk_widget_destroy(page); gtk_notebook_set_current_page(GTK_NOTEBOOK(view), 0); gtk_widget_grab_focus(GTK_WIDGET(view->priv->text_view_input)); + break; + } + } + + if (!found) { + // Might be an external editor? + for (ext = view->priv->external_editors; ext; ext = ext->next) { + if ((GM_EXTERNAL_VIEW(ext->data))->editor == editor) { + g_signal_handlers_disconnect_by_func(editor, + on_gm_world_view_editor_save, view); + gm_external_view_destroy(GM_EXTERNAL_VIEW(ext->data)); + + view->priv->external_editors = + g_list_remove_link(view->priv->external_editors, ext); + g_list_free_1(ext); + break; + } } } }