/* Copyright (C) 2008-2010 Christian Dywan This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. See the file COPYING for the full license text. */ #include "midori-findbar.h" #include "midori-browser.h" #include "gtkiconentry.h" #include "sokoke.h" #include #include #include #if HAVE_CONFIG_H #include "config.h" #endif struct _MidoriFindbar { GtkToolbar parent_instance; GtkWidget* find_text; GtkToolItem* previous; GtkToolItem* next; GtkToolItem* find_case; GtkToolItem* find_highlight; GtkToolItem* find_close; gboolean find_typing; }; struct _MidoriFindbarClass { GtkToolbarClass parent_class; }; G_DEFINE_TYPE (MidoriFindbar, midori_findbar, GTK_TYPE_TOOLBAR); static void midori_findbar_class_init (MidoriFindbarClass* class) { /* Nothing to do */ } static void midori_findbar_done (MidoriFindbar* findbar) { MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (findbar)); GtkWidget* view = midori_browser_get_current_tab (browser); midori_view_unmark_text_matches (MIDORI_VIEW (view)); gtk_widget_hide (GTK_WIDGET (findbar)); findbar->find_typing = FALSE; gtk_window_set_focus (GTK_WINDOW (browser), view); } static gboolean midori_findbar_find_key_press_event_cb (MidoriFindbar* findbar, GdkEventKey* event) { if (event->keyval == GDK_Escape) { midori_findbar_done (findbar); return TRUE; } else if (event->keyval == GDK_Return && (event->state & GDK_SHIFT_MASK)) { midori_findbar_find (findbar, FALSE); return TRUE; } return FALSE; } static void midori_findbar_entry_clear_icon_released_cb (GtkIconEntry* entry, gint icon_pos, gint button, gpointer user_data) { if (icon_pos == GTK_ICON_ENTRY_SECONDARY) gtk_entry_set_text (GTK_ENTRY (entry), ""); } static gboolean midori_findbar_case_sensitive (MidoriFindbar* findbar) { /* Smart case while typing: foo or fOO lowercase, Foo or FOO uppercase */ if (findbar->find_typing) { const gchar* text = gtk_entry_get_text (GTK_ENTRY (findbar->find_text)); return g_unichar_isupper (g_utf8_get_char (text)); } return gtk_toggle_tool_button_get_active ( GTK_TOGGLE_TOOL_BUTTON (findbar->find_case)); } void midori_findbar_find_text (MidoriFindbar* findbar, const gchar* text, gboolean forward) { MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (findbar)); gboolean case_sensitive; GtkWidget* view; if (!(view = midori_browser_get_current_tab (browser))) return; case_sensitive = midori_findbar_case_sensitive (findbar); midori_view_search_text (MIDORI_VIEW (view), text, case_sensitive, forward); } void midori_findbar_find (MidoriFindbar* findbar, gboolean forward) { const gchar* text = gtk_entry_get_text (GTK_ENTRY (findbar->find_text)); midori_findbar_find_text (findbar, text, forward); } void midori_findbar_invoke (MidoriFindbar* findbar) { if (gtk_widget_get_visible (GTK_WIDGET (findbar))) midori_findbar_done (findbar); else { MidoriBrowser* browser = midori_browser_get_for_widget (findbar->find_text); GtkWidget* view = midori_browser_get_current_tab (browser); const gchar* text; #if !HAVE_HILDON gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (findbar->find_text), GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FIND); gtk_widget_show (GTK_WIDGET (findbar->find_case)); #endif gtk_widget_show (GTK_WIDGET (findbar->find_highlight)); gtk_widget_show (GTK_WIDGET (findbar->find_close)); if ((text = midori_view_get_selected_text (MIDORI_VIEW (view)))) gtk_entry_set_text (GTK_ENTRY (findbar->find_text), text); gtk_widget_show (GTK_WIDGET (findbar)); } gtk_widget_grab_focus (GTK_WIDGET (findbar->find_text)); } static void midori_findbar_next_activate_cb (GtkWidget* entry, MidoriFindbar* findbar) { midori_findbar_find (findbar, TRUE); } static void midori_findbar_previous_clicked_cb (GtkWidget* entry, MidoriFindbar* findbar) { midori_findbar_find (findbar, FALSE); } static void midori_findbar_button_close_clicked_cb (GtkWidget* widget, MidoriFindbar* findbar) { midori_findbar_done (findbar); } static void midori_findbar_preedit_changed_cb (GtkWidget* entry, const gchar* preedit, MidoriFindbar* findbar) { if (findbar->find_typing) { MidoriBrowser* browser = midori_browser_get_for_widget (entry); GtkWidget* view = midori_browser_get_current_tab (browser); midori_view_unmark_text_matches (MIDORI_VIEW (view)); if (g_utf8_strlen (preedit, -1) > 1) midori_findbar_find_text (findbar, preedit, TRUE); } } static void midori_findbar_text_changed_cb (GtkWidget* entry, MidoriFindbar* findbar) { const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry)); midori_findbar_preedit_changed_cb (entry, text, findbar); } static gboolean midori_findbar_text_focus_out_event_cb (GtkWidget* entry, GdkEventFocus* event, MidoriFindbar* findbar) { if (findbar->find_typing) midori_findbar_done (findbar); return FALSE; } static void midori_findbar_highlight_toggled_cb (GtkToggleToolButton* toolitem, MidoriFindbar* findbar) { MidoriBrowser* browser = midori_browser_get_for_widget (GTK_WIDGET (findbar)); GtkWidget* view = midori_browser_get_current_tab (browser); gboolean highlight = gtk_toggle_tool_button_get_active (toolitem); midori_view_set_highlight_text_matches (MIDORI_VIEW (view), highlight); } static void midori_findbar_init (MidoriFindbar* findbar) { GtkToolItem* toolitem; gtk_widget_set_name (GTK_WIDGET (findbar), "MidoriFindbar"); gtk_toolbar_set_icon_size (GTK_TOOLBAR (findbar), GTK_ICON_SIZE_MENU); gtk_toolbar_set_style (GTK_TOOLBAR (findbar), GTK_TOOLBAR_BOTH_HORIZ); g_signal_connect (findbar, "key-press-event", G_CALLBACK (midori_findbar_find_key_press_event_cb), NULL); toolitem = gtk_tool_item_new (); gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6); gtk_container_add (GTK_CONTAINER (toolitem), /* i18n: A panel at the bottom, to search text in pages */ gtk_label_new_with_mnemonic (_("_Inline Find:"))); gtk_toolbar_insert (GTK_TOOLBAR (findbar), toolitem, -1); findbar->find_text = gtk_icon_entry_new (); #if !HAVE_HILDON gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (findbar->find_text), GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FIND); gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (findbar->find_text), GTK_ICON_ENTRY_SECONDARY, GTK_STOCK_CLEAR); gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (findbar->find_text), GTK_ICON_ENTRY_SECONDARY, TRUE); #endif g_signal_connect (findbar->find_text, "icon-release", G_CALLBACK (midori_findbar_entry_clear_icon_released_cb), NULL); g_signal_connect (findbar->find_text, "activate", G_CALLBACK (midori_findbar_next_activate_cb), findbar); g_signal_connect (findbar->find_text, "preedit-changed", G_CALLBACK (midori_findbar_preedit_changed_cb), findbar); g_signal_connect (findbar->find_text, "changed", G_CALLBACK (midori_findbar_text_changed_cb), findbar); g_signal_connect (findbar->find_text, "focus-out-event", G_CALLBACK (midori_findbar_text_focus_out_event_cb), findbar); toolitem = gtk_tool_item_new (); gtk_container_add (GTK_CONTAINER (toolitem), findbar->find_text); gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE); gtk_toolbar_insert (GTK_TOOLBAR (findbar), toolitem, -1); #if HAVE_HILDON findbar->find_case = gtk_toggle_tool_button_new (); findbar->find_highlight = gtk_toggle_tool_button_new (); #else findbar->previous = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK); g_signal_connect (findbar->previous, "clicked", G_CALLBACK (midori_findbar_previous_clicked_cb), findbar); gtk_tool_button_set_label (GTK_TOOL_BUTTON (findbar->previous), _("Previous")); gtk_tool_item_set_is_important (findbar->previous, TRUE); gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->previous, -1); findbar->next = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD); g_signal_connect (findbar->next, "clicked", G_CALLBACK (midori_findbar_next_activate_cb), findbar); gtk_tool_button_set_label (GTK_TOOL_BUTTON (findbar->next), _("Next")); gtk_tool_item_set_is_important (findbar->next, TRUE); gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->next, -1); findbar->find_case = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_SPELL_CHECK); gtk_tool_button_set_label (GTK_TOOL_BUTTON (findbar->find_case), _("Match Case")); gtk_tool_item_set_is_important (GTK_TOOL_ITEM (findbar->find_case), TRUE); gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->find_case, -1); findbar->find_highlight = gtk_toggle_tool_button_new_from_stock ( GTK_STOCK_SELECT_ALL); #endif g_signal_connect (findbar->find_highlight, "toggled", G_CALLBACK (midori_findbar_highlight_toggled_cb), findbar); gtk_tool_button_set_label (GTK_TOOL_BUTTON (findbar->find_highlight), _("Highlight Matches")); gtk_tool_item_set_is_important (GTK_TOOL_ITEM (findbar->find_highlight), TRUE); gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->find_highlight, -1); toolitem = gtk_separator_tool_item_new (); gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE); #if !HAVE_HILDON gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE); #endif gtk_toolbar_insert (GTK_TOOLBAR (findbar), toolitem, -1); findbar->find_close = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE); gtk_tool_button_set_label (GTK_TOOL_BUTTON (findbar->find_close), _("Close Findbar")); g_signal_connect (findbar->find_close, "clicked", G_CALLBACK (midori_findbar_button_close_clicked_cb), findbar); #if HAVE_OSX gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->find_close, 0); #else gtk_toolbar_insert (GTK_TOOLBAR (findbar), findbar->find_close, -1); #endif sokoke_container_show_children (GTK_CONTAINER (findbar)); } void midori_findbar_set_can_find (MidoriFindbar* findbar, gboolean can_find) { gtk_widget_set_sensitive (GTK_WIDGET (findbar->next), can_find); gtk_widget_set_sensitive (GTK_WIDGET (findbar->previous), can_find); } void midori_findbar_search_text (MidoriFindbar* findbar, GtkWidget* view, gboolean found, gchar* typing) { const gchar* text; gboolean case_sensitive; gboolean highlight; if (typing) { MidoriBrowser* browser = midori_browser_get_for_widget (view); gint position = -1; findbar->find_typing = TRUE; gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON ( findbar->find_highlight), TRUE); gtk_widget_hide (GTK_WIDGET (findbar->find_case)); gtk_widget_hide (GTK_WIDGET (findbar->find_highlight)); gtk_widget_hide (GTK_WIDGET (findbar->find_close)); if (!gtk_widget_get_visible (GTK_WIDGET (findbar))) gtk_entry_set_text (GTK_ENTRY (findbar->find_text), ""); gtk_widget_show (GTK_WIDGET (findbar)); gtk_window_set_focus (GTK_WINDOW (browser), findbar->find_text); gtk_editable_insert_text (GTK_EDITABLE (findbar->find_text), typing, -1, &position); gtk_editable_set_position (GTK_EDITABLE (findbar->find_text), -1); } if (gtk_widget_get_visible (GTK_WIDGET (findbar)) && !typing) { #if !HAVE_HILDON gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (findbar->find_text), GTK_ICON_ENTRY_PRIMARY, (found) ? GTK_STOCK_FIND : GTK_STOCK_STOP); #endif text = gtk_entry_get_text (GTK_ENTRY (findbar->find_text)); case_sensitive = midori_findbar_case_sensitive (findbar); midori_view_mark_text_matches (MIDORI_VIEW (view), text, case_sensitive); highlight = gtk_toggle_tool_button_get_active ( GTK_TOGGLE_TOOL_BUTTON (findbar->find_highlight)); midori_view_set_highlight_text_matches (MIDORI_VIEW (view), highlight); } }