? .cdtproject ? .project ? INSTALL_DIR ? PREFIX ? bubble.patch ? gedit.D ? sexy-search.patch ? gedit/Unsaved Document 1 ? gedit/eggnotificationbubble.c ? gedit/eggnotificationbubble.h ? gedit/gedit-document.old.c ? gedit/gedit-global-message-area.c ? gedit/gedit-global-message-area.h ? gedit/gedit-panel.c.diff ? gedit/gedit-print-job-preview.c.paolo ? gedit/gedit-vfs-utils.c ? gedit/gedit-vfs-utils.h ? gedit/gedit.diff ? gedit/output.pdf ? gedit/pippo.txt ? gedit/prova2.txt ? gedit/search-panel.gladep ? gedit/sexy-icon-entry.c ? gedit/sexy-icon-entry.h ? gedit/dialogs/gedit-dialog-goto-line.loT ? gedit/dialogs/search-panel.gladep ? plugins/sample_test ? plugins/savecopy/savecopy.c.paolo ? tools/plugin_template/Makefile.in Index: data/gedit.schemas.in =================================================================== RCS file: /cvs/gnome/gedit/data/gedit.schemas.in,v retrieving revision 1.20.2.3 diff -u -p -r1.20.2.3 gedit.schemas.in --- data/gedit.schemas.in 6 Nov 2005 18:52:43 -0000 1.20.2.3 +++ data/gedit.schemas.in 21 Nov 2005 16:58:38 -0000 @@ -597,7 +597,7 @@ gedit list string - [ssh,ftp,smb,dav] + [ssh,sftp,smb,dav,davs] Writable VFS schemes List of VFS schemes gedit supports in write mode. The 'file' scheme Index: gedit/gedit-document.c =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-document.c,v retrieving revision 1.111.2.52 diff -u -p -r1.111.2.52 gedit-document.c --- gedit/gedit-document.c 21 Nov 2005 14:21:59 -0000 1.111.2.52 +++ gedit/gedit-document.c 21 Nov 2005 16:58:39 -0000 @@ -102,7 +102,7 @@ struct _GeditDocumentPrivate GTimeVal time_of_last_save_or_load; - gint search_flags; + guint search_flags; gchar *search_text; /* Temp data while loading */ @@ -1224,7 +1224,7 @@ gedit_document_goto_line (GeditDocument void gedit_document_set_search_text (GeditDocument *doc, const gchar *text, - gint flags) + guint flags) { gchar *converted_text = NULL; @@ -1234,18 +1234,23 @@ gedit_document_set_search_text (GeditDoc gedit_debug_message (DEBUG_DOCUMENT, "text = %s", text); - if (*text != '\0') - converted_text = gedit_utils_unescape_search_text (text); + if (text != NULL) + { + if (*text != '\0') + converted_text = gedit_utils_unescape_search_text (text); - g_free (doc->priv->search_text); + g_free (doc->priv->search_text); + + doc->priv->search_text = converted_text; + } - doc->priv->search_text = converted_text; - doc->priv->search_flags = flags; + if (!GEDIT_SEARCH_IS_DONT_SET_FLAGS (flags)) + doc->priv->search_flags = flags; } gchar * gedit_document_get_search_text (GeditDocument *doc, - gint *flags) + guint *flags) { g_return_val_if_fail (GEDIT_IS_DOCUMENT (doc), NULL); Index: gedit/gedit-document.h =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-document.h,v retrieving revision 1.41.2.26 diff -u -p -r1.41.2.26 gedit-document.h --- gedit/gedit-document.h 21 Nov 2005 14:21:59 -0000 1.41.2.26 +++ gedit/gedit-document.h 21 Nov 2005 16:58:39 -0000 @@ -54,8 +54,10 @@ G_BEGIN_DECLS typedef enum { - GEDIT_SEARCH_ENTIRE_WORD = 1 << 0, - GEDIT_SEARCH_CASE_SENSITIVE = 1 << 1 + GEDIT_SEARCH_DONT_SET_FLAGS = 1 << 0, + GEDIT_SEARCH_ENTIRE_WORD = 1 << 1, + GEDIT_SEARCH_CASE_SENSITIVE = 1 << 2 + } GeditSearchFlags; @@ -183,10 +185,10 @@ gboolean gedit_document_goto_line (Ged void gedit_document_set_search_text (GeditDocument *doc, const gchar *text, - gint flags); + guint flags); gchar *gedit_document_get_search_text (GeditDocument *doc, - gint *flags); + guint *flags); gboolean gedit_document_search_forward (GeditDocument *doc, const GtkTextIter *start, @@ -239,6 +241,9 @@ gboolean _gedit_document_get_has_select /* Search macros */ +#define GEDIT_SEARCH_IS_DONT_SET_FLAGS(sflags) ((sflags & GEDIT_SEARCH_DONT_SET_FLAGS) != 0) +#define GEDIT_SEARCH_SET_DONT_SET_FLAGS(sflags,state) ((state == TRUE) ? \ +(sflags |= GEDIT_SEARCH_DONT_SET_FLAGS) : (sflags &= ~GEDIT_SEARCH_DONT_SET_FLAGS)) #define GEDIT_SEARCH_IS_ENTIRE_WORD(sflags) ((sflags & GEDIT_SEARCH_ENTIRE_WORD) != 0) #define GEDIT_SEARCH_SET_ENTIRE_WORD(sflags,state) ((state == TRUE) ? \ Index: gedit/gedit-marshal.list =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-marshal.list,v retrieving revision 1.4.8.5 diff -u -p -r1.4.8.5 gedit-marshal.list --- gedit/gedit-marshal.list 13 May 2005 20:13:29 -0000 1.4.8.5 +++ gedit/gedit-marshal.list 21 Nov 2005 16:58:39 -0000 @@ -1,4 +1,5 @@ BOOLEAN:OBJECT +BOOLEAN:NONE VOID:VOID VOID:BOOLEAN VOID:OBJECT Index: gedit/gedit-prefs-manager.h =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-prefs-manager.h,v retrieving revision 1.20.2.4 diff -u -p -r1.20.2.4 gedit-prefs-manager.h --- gedit/gedit-prefs-manager.h 6 Nov 2005 18:52:43 -0000 1.20.2.4 +++ gedit/gedit-prefs-manager.h 21 Nov 2005 16:58:39 -0000 @@ -207,7 +207,7 @@ #define GPM_DEFAULT_SYNTAX_HL_ENABLE 1 /* TRUE */ -#define GPM_DEFAULT_WRITABLE_VFS_SCHEMES {"ssh", "ftp", "smb", "dav", NULL} +#define GPM_DEFAULT_WRITABLE_VFS_SCHEMES {"ssh", "sftp", "smb", "dav", "davs", NULL} typedef enum { GEDIT_TOOLBAR_SYSTEM = 0, Index: gedit/gedit-view.c =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-view.c,v retrieving revision 1.59.2.15 diff -u -p -r1.59.2.15 gedit-view.c --- gedit/gedit-view.c 25 Sep 2005 12:08:23 -0000 1.59.2.15 +++ gedit/gedit-view.c 21 Nov 2005 16:58:39 -0000 @@ -38,17 +38,30 @@ #include +#include + #include "gedit-view.h" #include "gedit-debug.h" #include "gedit-prefs-manager-app.h" +#include "gedit-marshal.h" #define GEDIT_VIEW_SCROLL_MARGIN 0.02 +#define GEDIT_VIEW_SEARCH_DIALOG_TIMEOUT 5000 #define GEDIT_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GEDIT_TYPE_VIEW, GeditViewPrivate)) struct _GeditViewPrivate { - gint dummy; + GtkWidget *search_window; + GtkWidget *search_entry; + + gboolean search_backward; + gboolean wrap_around; + + guint typeselect_flush_timeout; + guint search_entry_changed_id; + + gboolean disable_popdown; }; static void gedit_view_destroy (GtkObject *object); @@ -58,8 +71,25 @@ static void gedit_view_move_cursor (GtkT gint count, gboolean extend_selection); +static gboolean start_interactive_search (GeditView *view); + G_DEFINE_TYPE(GeditView, gedit_view, GTK_TYPE_SOURCE_VIEW) +/* Signals */ +enum +{ + START_INTERACTIVE_SEARCH, + LAST_SIGNAL +}; + +static guint view_signals [LAST_SIGNAL] = { 0 }; + +typedef enum +{ + GEDIT_SEARCH_ENTRY_NORMAL, + GEDIT_SEARCH_ENTRY_NOT_FOUND +} GeditSearchEntryBgColor; + static void document_read_only_notify_handler (GeditDocument *document, GParamSpec *pspec, @@ -77,14 +107,31 @@ gedit_view_class_init (GeditViewClass *k GObjectClass *object_class = G_OBJECT_CLASS (klass); GtkObjectClass *gtkobject_class = GTK_OBJECT_CLASS (klass); GtkTextViewClass *textview_class = GTK_TEXT_VIEW_CLASS (klass); + GtkBindingSet *binding_set; gtkobject_class->destroy = gedit_view_destroy; object_class->finalize = gedit_view_finalize; + klass->start_interactive_search = start_interactive_search; + textview_class->move_cursor = gedit_view_move_cursor; + + view_signals[START_INTERACTIVE_SEARCH] = + g_signal_new ("start_interactive_search", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GeditViewClass, start_interactive_search), + NULL, NULL, + gedit_marshal_BOOLEAN__NONE, + G_TYPE_BOOLEAN, 0); - /* Note: it is commented out since we don't use it - Paolo */ - /* g_type_class_add_private (klass, sizeof (GeditViewPrivate)); */ + g_type_class_add_private (klass, sizeof (GeditViewPrivate)); + + binding_set = gtk_binding_set_by_class (klass); + + gtk_binding_entry_add_signal (binding_set, GDK_k, GDK_CONTROL_MASK, "start_interactive_search", 0); + + gtk_binding_entry_add_signal (binding_set, GDK_K, GDK_CONTROL_MASK, "start_interactive_search", 0); } static void @@ -197,6 +244,8 @@ gedit_view_init (GeditView *view) GeditDocument *doc; #endif gedit_debug (DEBUG_VIEW); + + view->priv = GEDIT_VIEW_GET_PRIVATE (view); /* * Set tab, fonts, wrap mode, colors, etc. according @@ -265,20 +314,31 @@ gedit_view_init (GeditView *view) * possible: see bug #172277 and bug #311728. * So we need to do this in an idle handler. */ - g_idle_add ((GSourceFunc) scroll_to_cursor_on_init, view); + g_idle_add ((GSourceFunc) scroll_to_cursor_on_init, view); + + view->priv->typeselect_flush_timeout = 0; } static void gedit_view_destroy (GtkObject *object) { GeditView *view; - GtkTextBuffer *doc; view = GEDIT_VIEW (object); - doc = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); - g_return_if_fail (doc != NULL); - + if (view->priv->search_window) + { + gtk_widget_destroy (view->priv->search_window); + view->priv->search_window = NULL; + view->priv->search_entry = NULL; + + if (view->priv->typeselect_flush_timeout != 0) + { + g_source_remove (view->priv->typeselect_flush_timeout); + view->priv->typeselect_flush_timeout = 0; + } + } + (* GTK_OBJECT_CLASS (gedit_view_parent_class)->destroy) (object); } @@ -636,4 +696,749 @@ gedit_view_set_font (GeditView *view, gtk_widget_modify_style (GTK_WIDGET (view), rc_style); } +} + +static void +set_entry_background (GtkWidget *entry, + GeditSearchEntryBgColor col) +{ + if (col == GEDIT_SEARCH_ENTRY_NOT_FOUND) + { + GdkColor red; + GdkColor white; + + /* FIXME: a11y and theme */ + + gdk_color_parse ("#FF6666", &red); + gdk_color_parse ("white", &white); + + gtk_widget_modify_base (entry, + GTK_STATE_NORMAL, + &red); + gtk_widget_modify_text (entry, + GTK_STATE_NORMAL, + &white); + } + else /* reset */ + { + gtk_widget_modify_base (entry, + GTK_STATE_NORMAL, + NULL); + gtk_widget_modify_text (entry, + GTK_STATE_NORMAL, + NULL); + } +} + +static gboolean +run_search (GeditView *view, + const gchar *entry_text, + gboolean search_backward, + gboolean wrap_around, + gboolean typing) +{ + GtkTextIter start_iter; + GtkTextIter match_start; + GtkTextIter match_end; + gboolean found = FALSE; + + GeditDocument *doc; + + doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + if (*entry_text != '\0') + { + if (!search_backward) + { + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), + &start_iter, + &match_end); + + if (!typing) + gtk_text_iter_order (&match_end, &start_iter); + + /* run search */ + found = gedit_document_search_forward (doc, + &start_iter, + NULL, + &match_start, + &match_end); + } + else if (!typing) + { + /* backward and not typing */ + + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), + &start_iter, + &match_end); + + /* run search */ + found = gedit_document_search_backward (doc, + NULL, + &start_iter, + &match_start, + &match_end); + } + else + { + /* backward (while typing) */ + + GtkTextIter sel_end; + gboolean sel; + + sel = gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), + &start_iter, + &sel_end); + + if (sel) + { + /* First search forward */ + GtkTextIter end_iter; + + end_iter = start_iter; + /* This is an upper bound */ + gtk_text_iter_forward_chars (&end_iter, + g_utf8_strlen (entry_text, -1) + 1); + + match_start = end_iter; + + /* run search */ + found = gedit_document_search_forward (doc, + &start_iter, + &end_iter, + &match_start, + &match_end); + + /* g_print ("Found: %s\n", found ? "T" : "F"); */ + } + + if (!sel || + !found || + !gtk_text_iter_equal (&start_iter, &match_start)) + { + /* Really search backward */ + start_iter = sel_end; + + found = gedit_document_search_backward (doc, + NULL, + &start_iter, + &match_start, + &match_end); + } + } + /* g_print ("Found: %s\n", found ? "TRUE" : "FALSE"); */ + + if (!found && wrap_around) + { + if (!search_backward) + found = gedit_document_search_forward (doc, + NULL, + NULL, /* FIXME: set the end_inter */ + &match_start, + &match_end); + else + found = gedit_document_search_backward (doc, + NULL, /* FIXME: set the start_inter */ + NULL, + &match_start, + &match_end); + } + } + else + { + gtk_text_buffer_get_selection_bounds (GTK_TEXT_BUFFER (doc), + &start_iter, + NULL); + } + + if (found) + { + gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), + &match_start); + + gtk_text_buffer_move_mark_by_name (GTK_TEXT_BUFFER (doc), + "selection_bound", &match_end); + } + else + gtk_text_buffer_place_cursor (GTK_TEXT_BUFFER (doc), + &start_iter); + + if (found || (*entry_text == '\0')) + { + gedit_view_scroll_to_cursor (view); + + set_entry_background (view->priv->search_entry, + GEDIT_SEARCH_ENTRY_NORMAL); } + else + { + set_entry_background (view->priv->search_entry, + GEDIT_SEARCH_ENTRY_NOT_FOUND); + } +/* + if (found && panel->priv->new_search_text && button_pressed) + { + add_entry_completion_entry (panel, doc, FALSE); + panel->priv->new_search_text = FALSE; + } +*/ + return found; +} + +/* Cut and paste from gtkwindow.c */ +static void +send_focus_change (GtkWidget *widget, + gboolean in) +{ + GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE); + + g_object_ref (widget); + + if (in) + GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS); + else + GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS); + + fevent->focus_change.type = GDK_FOCUS_CHANGE; + fevent->focus_change.window = g_object_ref (widget->window); + fevent->focus_change.in = in; + + gtk_widget_event (widget, fevent); + + g_object_notify (G_OBJECT (widget), "has-focus"); + + g_object_unref (widget); + gdk_event_free (fevent); +} + +static void +hide_search_window (GeditView *view) +{ + if (view->priv->disable_popdown) + return; + + if (view->priv->search_entry_changed_id) + { + g_signal_handler_disconnect (view->priv->search_entry, + view->priv->search_entry_changed_id); + view->priv->search_entry_changed_id = 0; + } + + if (view->priv->typeselect_flush_timeout) + { + g_source_remove (view->priv->typeselect_flush_timeout); + view->priv->typeselect_flush_timeout = 0; + } + + /* send focus-in event */ + send_focus_change (GTK_WIDGET (view->priv->search_entry), FALSE); + gtk_widget_hide (view->priv->search_window); +} + +static gboolean +search_entry_flush_timeout (GeditView *view) +{ + GDK_THREADS_ENTER (); + + hide_search_window (view); + view->priv->typeselect_flush_timeout = 0; + + GDK_THREADS_LEAVE (); + + return FALSE; +} +static void +update_search_window_position (GeditView *view) +{ + gint x, y; + gint view_x, view_y; + GdkWindow *view_window = GTK_WIDGET (view)->window; + + gtk_widget_realize (view->priv->search_window); + + gdk_window_get_origin (view_window, &view_x, &view_y); + + x = MAX (12, view_x + 12); + y = MAX (12, view_y - 12); + + gtk_window_move (GTK_WINDOW (view->priv->search_window), x, y); +} + +static gboolean +search_window_delete_event (GtkWidget *widget, + GdkEventAny *event, + GeditView *view) +{ + hide_search_window (view); + + return TRUE; +} + +static gboolean +search_window_button_press_event (GtkWidget *widget, + GdkEventButton *event, + GeditView *view) +{ + hide_search_window (view); +/* + if (event->window == tree_view->priv->bin_window) + gtk_tree_view_button_press (GTK_WIDGET (tree_view), event); +*/ + return TRUE; +} + +static void +search_again (GeditView *view, + gboolean search_backward) +{ + const gchar *entry_text; + + /* renew the flush timeout */ + if (view->priv->typeselect_flush_timeout != 0) + { + g_source_remove (view->priv->typeselect_flush_timeout); + view->priv->typeselect_flush_timeout = + g_timeout_add (GEDIT_VIEW_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc)search_entry_flush_timeout, + view); + } + + entry_text = gtk_entry_get_text (GTK_ENTRY (view->priv->search_entry)); + + run_search (view, + entry_text, + search_backward, + view->priv->wrap_around, + FALSE); +} + +static gboolean +search_window_scroll_event (GtkWidget *widget, + GdkEventScroll *event, + GeditView *view) +{ + gboolean retval = FALSE; + + if (event->direction == GDK_SCROLL_UP) + { + search_again (view, TRUE); + retval = TRUE; + } + else if (event->direction == GDK_SCROLL_DOWN) + { + search_again (view, FALSE); + retval = TRUE; + } + + return retval; +} + +static gboolean +search_window_key_press_event (GtkWidget *widget, + GdkEventKey *event, + GeditView *view) +{ + gboolean retval = FALSE; + + /* close window and cancel the search */ + if (event->keyval == GDK_Escape || + event->keyval == GDK_Tab) + { + hide_search_window (view); + return TRUE; + } + + /* select previous matching iter */ + if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up) + { + search_again (view, TRUE); + retval = TRUE; + } + + if (((event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) && + (event->keyval == GDK_g || event->keyval == GDK_G)) + { + search_again (view, TRUE); + retval = TRUE; + } + + /* select next matching iter */ + if (event->keyval == GDK_Down || event->keyval == GDK_KP_Down || event->keyval == GDK_Return) + { + search_again (view, FALSE); + retval = TRUE; + } + + if (((event->state & (GDK_CONTROL_MASK | GDK_SHIFT_MASK)) == GDK_CONTROL_MASK) && + (event->keyval == GDK_g || event->keyval == GDK_G)) + { + search_again (view, FALSE); + retval = TRUE; + } + + return retval; +} + +static void +wrap_around_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, + GeditView *view) +{ + view->priv->wrap_around = gtk_check_menu_item_get_active (checkmenuitem); +} + +static void +search_backward_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, + GeditView *view) +{ + view->priv->search_backward = gtk_check_menu_item_get_active (checkmenuitem); +} + +static void +match_entire_word_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, + GeditView *view) +{ + GeditDocument *doc; + gchar *search_text; + guint flags; + + doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + search_text = gedit_document_get_search_text (doc, + &flags); + g_free (search_text); + + GEDIT_SEARCH_SET_ENTIRE_WORD (flags, + gtk_check_menu_item_get_active (checkmenuitem)); + + gedit_document_set_search_text (doc, NULL, flags); +} + +static void +match_case_menu_item_toggled (GtkCheckMenuItem *checkmenuitem, + GeditView *view) +{ + GeditDocument *doc; + gchar *search_text; + guint flags; + + doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + search_text = gedit_document_get_search_text (doc, + &flags); + g_free (search_text); + + GEDIT_SEARCH_SET_CASE_SENSITIVE (flags, + gtk_check_menu_item_get_active (checkmenuitem)); + + gedit_document_set_search_text (doc, NULL, flags); +} + +static gboolean +real_search_enable_popdown (gpointer data) +{ + GeditView *view = (GeditView *)data; + + GDK_THREADS_ENTER (); + + view->priv->disable_popdown = FALSE; + + GDK_THREADS_LEAVE (); + + return FALSE; +} + +static void +search_enable_popdown (GtkWidget *widget, + GeditView *view) +{ + g_timeout_add (200, real_search_enable_popdown, view); + + /* renew the flush timeout */ + if (view->priv->typeselect_flush_timeout != 0) + g_source_remove (view->priv->typeselect_flush_timeout); + + view->priv->typeselect_flush_timeout = + g_timeout_add (GEDIT_VIEW_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc)search_entry_flush_timeout, + view); +} + +static void +search_entry_populate_popup (GtkEntry *entry, + GtkMenu *menu, + GeditView *view) +{ + GtkWidget *menu_item; + guint flags; + gchar *search_text; + + view->priv->disable_popdown = TRUE; + g_signal_connect (menu, "hide", + G_CALLBACK (search_enable_popdown), view); + + search_text = gedit_document_get_search_text (GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))), + &flags); + g_free (search_text); + + /* separator */ + menu_item = gtk_menu_item_new (); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_widget_show (menu_item); + + /* create "Wrap Around" menu item. */ + menu_item = gtk_check_menu_item_new_with_mnemonic (_("_Wrap Around")); + g_signal_connect (G_OBJECT (menu_item), "toggled", + G_CALLBACK (wrap_around_menu_item_toggled), + view); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), + view->priv->wrap_around); + gtk_widget_show (menu_item); + + /* create "Search Backward" menu item. */ + menu_item = gtk_check_menu_item_new_with_mnemonic (_("Search _Backward")); + g_signal_connect (G_OBJECT (menu_item), "toggled", + G_CALLBACK (search_backward_menu_item_toggled), + view); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), + view->priv->search_backward); + gtk_widget_show (menu_item); + + /* create "Match Entire Word Only" menu item. */ + menu_item = gtk_check_menu_item_new_with_mnemonic (_("Match _Entire Word Only")); + g_signal_connect (G_OBJECT (menu_item), "toggled", + G_CALLBACK (match_entire_word_menu_item_toggled), + view); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), + GEDIT_SEARCH_IS_ENTIRE_WORD (flags)); + gtk_widget_show (menu_item); + + /* create "Match Case" menu item. */ + menu_item = gtk_check_menu_item_new_with_mnemonic (_("_Match Case")); + g_signal_connect (G_OBJECT (menu_item), "toggled", + G_CALLBACK (match_case_menu_item_toggled), + view); + gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), menu_item); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item), + GEDIT_SEARCH_IS_CASE_SENSITIVE(flags)); + gtk_widget_show (menu_item); +} + +static void +ensure_search_window (GeditView *view) +{ + GtkWidget *frame; + GtkWidget *vbox; + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (view)); + + if (view->priv->search_window != NULL) + { + if (GTK_WINDOW (toplevel)->group) + gtk_window_group_add_window (GTK_WINDOW (toplevel)->group, + GTK_WINDOW (view->priv->search_window)); + else if (GTK_WINDOW (view->priv->search_window)->group) + gtk_window_group_remove_window (GTK_WINDOW (view->priv->search_window)->group, + GTK_WINDOW (view->priv->search_window)); + return; + } + + view->priv->search_window = gtk_window_new (GTK_WINDOW_POPUP); + + if (GTK_WINDOW (toplevel)->group) + gtk_window_group_add_window (GTK_WINDOW (toplevel)->group, + GTK_WINDOW (view->priv->search_window)); + + gtk_window_set_modal (GTK_WINDOW (view->priv->search_window), TRUE); + + g_signal_connect (view->priv->search_window, "delete_event", + G_CALLBACK (search_window_delete_event), + view); + g_signal_connect (view->priv->search_window, "key_press_event", + G_CALLBACK (search_window_key_press_event), + view); + g_signal_connect (view->priv->search_window, "button_press_event", + G_CALLBACK (search_window_button_press_event), + view); + g_signal_connect (view->priv->search_window, "scroll_event", + G_CALLBACK (search_window_scroll_event), + view); + + frame = gtk_frame_new (NULL); + gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_ETCHED_IN); + gtk_widget_show (frame); + gtk_container_add (GTK_CONTAINER (view->priv->search_window), frame); + + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + gtk_container_add (GTK_CONTAINER (frame), vbox); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 3); + + /* add entry */ + view->priv->search_entry = gtk_entry_new (); + gtk_widget_show (view->priv->search_entry); + + g_signal_connect (view->priv->search_entry, "populate_popup", + G_CALLBACK (search_entry_populate_popup), + view); +/* + g_signal_connect (view->priv->search_entry, "activate", + G_CALLBACK (gtk_view_search_activate), + view); + g_signal_connect (GTK_ENTRY (view->priv->search_entry)->im_context, "preedit-changed", + G_CALLBACK (gtk_view_search_preedit_changed), + view); +*/ + gtk_container_add (GTK_CONTAINER (vbox), + view->priv->search_entry); + + gtk_widget_realize (view->priv->search_entry); +} + +static gboolean +get_selected_text (GtkTextBuffer *doc, gchar **selected_text, gint *len) +{ + GtkTextIter start, end; + + g_return_val_if_fail (selected_text != NULL, FALSE); + g_return_val_if_fail (*selected_text == NULL, FALSE); + + if (!gtk_text_buffer_get_selection_bounds (doc, &start, &end)) + { + if (len != NULL) + len = 0; + + return FALSE; + } + + *selected_text = gtk_text_buffer_get_slice (doc, &start, &end, TRUE); + + if (len != NULL) + *len = g_utf8_strlen (*selected_text, -1); + + return TRUE; +} + +static void +init_search_entry (GeditView *view) +{ + GeditDocument *doc; + gboolean selection_exists; + gchar *find_text = NULL; + gint sel_len = 0; + + doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + selection_exists = get_selected_text (GTK_TEXT_BUFFER (doc), + &find_text, + &sel_len); + + if (!selection_exists || + (find_text == NULL) || + (sel_len > 160)) + { + gchar *lst; + + lst = gedit_document_get_search_text (doc, NULL); + + if (lst != NULL) + { + g_free (find_text); + find_text = lst; + } + else if (sel_len > 160) + { + g_free (find_text); + find_text = NULL; + } + } + + if (find_text != NULL) + { + gtk_entry_set_text (GTK_ENTRY (view->priv->search_entry), + find_text); + + g_free (find_text); + } +} + + + +static void +search_init (GtkWidget *entry, GeditView *view) +{ + GeditDocument *doc; + const gchar *entry_text; + gchar *search_text; + + /* renew the flush timeout */ + if (view->priv->typeselect_flush_timeout != 0) + { + g_source_remove (view->priv->typeselect_flush_timeout); + view->priv->typeselect_flush_timeout = + g_timeout_add (GEDIT_VIEW_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc)search_entry_flush_timeout, + view); + } + + doc = GEDIT_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view))); + + entry_text = gtk_entry_get_text (GTK_ENTRY (entry)); + + search_text = gedit_document_get_search_text (doc, NULL); + + if ((search_text == NULL) || (strcmp (search_text, entry_text) != 0)) + { + gedit_document_set_search_text (doc, + entry_text, + GEDIT_SEARCH_DONT_SET_FLAGS); + } + + g_free (search_text); + + run_search (view, + entry_text, + view->priv->search_backward, + view->priv->wrap_around, + TRUE); +} + +static gboolean +start_interactive_search (GeditView *view) +{ + if ((view->priv->search_window != NULL) && + GTK_WIDGET_VISIBLE (view->priv->search_window)) + return TRUE; + + if (!GTK_WIDGET_HAS_FOCUS (view)) + return FALSE; + + ensure_search_window (view); + + init_search_entry (view); + + /* done, show it */ + update_search_window_position (view); + gtk_widget_show (view->priv->search_window); + + if (view->priv->search_entry_changed_id == 0) + { + view->priv->search_entry_changed_id = + g_signal_connect (view->priv->search_entry, "changed", + G_CALLBACK (search_init), + view); + } + + view->priv->typeselect_flush_timeout = + g_timeout_add (GEDIT_VIEW_SEARCH_DIALOG_TIMEOUT, + (GSourceFunc) search_entry_flush_timeout, + view); + + gtk_widget_grab_focus (view->priv->search_entry); + + send_focus_change (view->priv->search_entry, TRUE); + + return TRUE; } Index: gedit/gedit-view.h =================================================================== RCS file: /cvs/gnome/gedit/gedit/gedit-view.h,v retrieving revision 1.13.8.3 diff -u -p -r1.13.8.3 gedit-view.h --- gedit/gedit-view.h 30 Sep 2005 18:49:15 -0000 1.13.8.3 +++ gedit/gedit-view.h 21 Nov 2005 16:58:39 -0000 @@ -74,6 +74,7 @@ struct _GeditViewClass GtkSourceViewClass parent_class; /* FIXME: Do we need placeholders ? */ + gboolean (* start_interactive_search) (GeditView *view); }; /*