Improved searching

This commit is contained in:
Jesse van den Kieboom 2005-11-19 13:05:06 +00:00
parent 8ab4125290
commit 53276e8a54
1 changed files with 212 additions and 103 deletions

View File

@ -1,4 +1,5 @@
#include <gdk/gdkkeysyms.h>
#include <string.h>
#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;
}
}
}
}