diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-02 11:14:42 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2009-03-02 11:14:42 +0800 |
commit | 85d0142d21286ce87cd5f6c3d1e2f71aa994151f (patch) | |
tree | adf19534f082b2074b3c7e7faf0ef10aa5c51806 | |
parent | 08b1d0ae8e36ef20da800bf6358ca0cd9fb4e026 (diff) | |
download | gsoc2013-evolution-85d0142d21286ce87cd5f6c3d1e2f71aa994151f.tar.gz gsoc2013-evolution-85d0142d21286ce87cd5f6c3d1e2f71aa994151f.tar.zst gsoc2013-evolution-85d0142d21286ce87cd5f6c3d1e2f71aa994151f.zip |
Move text searching UI into a new EMailSearchBar widget.
svn path=/branches/kill-bonobo/; revision=37351
-rw-r--r-- | mail/Makefile.am | 138 | ||||
-rw-r--r-- | mail/e-mail-browser.c | 27 | ||||
-rw-r--r-- | mail/e-mail-display.c | 2 | ||||
-rw-r--r-- | mail/e-mail-reader.c | 20 | ||||
-rw-r--r-- | mail/e-mail-reader.h | 4 | ||||
-rw-r--r-- | mail/e-mail-search-bar.c | 664 | ||||
-rw-r--r-- | mail/e-mail-search-bar.h | 85 | ||||
-rw-r--r-- | mail/e-mail-shell-content.c | 68 | ||||
-rw-r--r-- | mail/e-mail-shell-content.h | 3 | ||||
-rw-r--r-- | mail/e-mail-shell-view-private.c | 20 | ||||
-rw-r--r-- | mail/e-searching-tokenizer.c | 633 | ||||
-rw-r--r-- | mail/e-searching-tokenizer.h | 82 | ||||
-rw-r--r-- | mail/em-folder-browser.c | 266 | ||||
-rw-r--r-- | mail/em-format-html-display.c | 341 | ||||
-rw-r--r-- | mail/em-format-html-display.h | 28 | ||||
-rw-r--r-- | mail/mail-types.h | 40 |
16 files changed, 1221 insertions, 1200 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am index cf7f71acea..ef5b769ce4 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -51,6 +51,8 @@ libevolution_module_mail_la_SOURCES = \ e-mail-reader.h \ e-mail-reader-utils.c \ e-mail-reader-utils.h \ + e-mail-search-bar.c \ + e-mail-search-bar.h \ e-mail-shell-module.c \ e-mail-shell-module.h \ e-mail-shell-module-migrate.c \ @@ -186,128 +188,6 @@ libevolution_module_mail_la_LIBADD = \ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ $(SMIME_LIBS) -# plugin mail api -#mailinclude_HEADERS = \ -# em-composer-utils.h \ -# em-config.h \ -# em-event.h \ -# em-folder-browser.h \ -# em-folder-tree-model.h \ -# em-folder-tree.h \ -# em-folder-utils.h \ -# em-folder-view.h \ -# em-format-hook.h \ -# em-format-html-display.h \ -# em-format-html-print.h \ -# em-format-html.h \ -# em-format-quote.h \ -# em-format.h \ -# em-html-stream.h \ -# em-icon-stream.h \ -# em-inline-filter.h \ -# em-junk-hook.h \ -# em-menu.h \ -# em-popup.h \ -# em-stripsig-filter.h \ -# em-sync-stream.h \ -# em-utils.h \ -# mail-autofilter.h \ -# mail-component.h \ -# mail-config.h \ -# mail-mt.h \ -# mail-ops.h \ -# mail-session.h \ -# mail-tools.h \ -# message-list.h \ -# mail-vfolder.h - -# libevolution-mail - -#libevolution_mail_la_SOURCES = \ -# $(mailinclude_HEADERS) \ -# e-searching-tokenizer.c \ -# e-searching-tokenizer.h \ -# em-account-editor.c \ -# em-account-editor.h \ -# em-account-prefs.c \ -# em-account-prefs.h \ -# em-composer-prefs.c \ -# em-composer-prefs.h \ -# em-composer-utils.c \ -# em-config.c \ -# em-event.c \ -# em-filter-context.c \ -# em-filter-context.h \ -# em-filter-editor.c \ -# em-filter-editor.h \ -# em-filter-folder-element.c \ -# em-filter-folder-element.h \ -# em-filter-rule.c \ -# em-filter-rule.h \ -# em-filter-source-element.c \ -# em-filter-source-element.h \ -# em-folder-browser.c \ -# em-folder-properties.c \ -# em-folder-properties.h \ -# em-folder-selection-button.c \ -# em-folder-selection-button.h \ -# em-folder-selection.c \ -# em-folder-selection.h \ -# em-folder-selector.c \ -# em-folder-selector.h \ -# em-folder-tree-model.c \ -# em-folder-tree.c \ -# em-folder-utils.c \ -# em-folder-view.c \ -# em-format-hook.c \ -# em-format-html-display.c \ -# em-format-html-print.c \ -# em-format-html.c \ -# em-format-quote.c \ -# em-format.c \ -# em-html-stream.c \ -# em-icon-stream.c \ -# em-inline-filter.c \ -# em-junk-hook.c \ -# em-menu.c \ -# em-migrate.c \ -# em-migrate.h \ -# em-popup.c \ -# em-search-context.c \ -# em-search-context.h \ -# em-stripsig-filter.c \ -# em-subscribe-editor.c \ -# em-subscribe-editor.h \ -# em-sync-stream.c \ -# em-utils.c \ -# em-vfolder-context.c \ -# em-vfolder-context.h \ -# em-vfolder-editor.c \ -# em-vfolder-editor.h \ -# em-vfolder-rule.c \ -# em-vfolder-rule.h \ -# mail-autofilter.c \ -# mail-component-factory.c \ -# mail-component.c \ -# mail-config.c \ -# mail-folder-cache.c \ -# mail-folder-cache.h \ -# mail-mt.c \ -# mail-ops.c \ -# mail-send-recv.c \ -# mail-send-recv.h \ -# mail-session.c \ -# mail-signature-editor.c \ -# mail-signature-editor.h \ -# mail-tools.c \ -# mail-types.h \ -# mail-vfolder.c \ -# message-list.c \ -# message-tag-editor.c \ -# message-tag-editor.h \ -# message-tag-followup.c \ -# message-tag-followup.h - if ENABLE_SMIME SMIME_LIBS = \ $(top_builddir)/smime/lib/libessmime.la \ @@ -319,10 +199,6 @@ endif # $(top_builddir)/filter/libfilter.la \ # $(top_builddir)/widgets/menus/libmenus.la \ # $(top_builddir)/addressbook/util/libeabutil.la \ -# $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ -# $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ -# $(top_builddir)/mail/importers/libevolution-mail-importers.la \ -# $(SMIME_LIBS) \ # $(EVOLUTION_MAIL_LIBS) \ # $(GTKHTML_LIBS) \ # $(REGEX_LIBS) \ @@ -333,14 +209,6 @@ endif #libevolution_mail_la_DEPENDENCIES = em-filter-i18n.h -# .server files - -server_in_files = GNOME_Evolution_Mail.server.in.in -server_DATA = $(server_in_files:.server.in.in=.server) - -@EVO_SERVER_RULE@ -@INTLTOOL_SERVER_RULE@ - # Misc data to install filterdir = $(privdatadir) filter_DATA = filtertypes.xml vfoldertypes.xml searchtypes.xml @@ -418,7 +286,7 @@ endif dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) -BUILT_SOURCES = $(server_DATA) $(error_DATA) +BUILT_SOURCES = $(error_DATA) CLEANFILES = $(BUILT_SOURCES) diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c index 8d685537bf..ac53faeffa 100644 --- a/mail/e-mail-browser.c +++ b/mail/e-mail-browser.c @@ -31,6 +31,7 @@ #include "mail/e-mail-reader.h" #include "mail/e-mail-reader-utils.h" +#include "mail/e-mail-search-bar.h" #include "mail/e-mail-shell-module.h" #include "mail/em-folder-tree-model.h" #include "mail/em-format-html-display.h" @@ -51,6 +52,7 @@ struct _EMailBrowserPrivate { GtkWidget *main_menu; GtkWidget *main_toolbar; GtkWidget *message_list; + GtkWidget *search_bar; GtkWidget *statusbar; }; @@ -325,6 +327,11 @@ mail_browser_dispose (GObject *object) priv->message_list = NULL; } + if (priv->search_bar != NULL) { + g_object_unref (priv->search_bar); + priv->search_bar = NULL; + } + if (priv->statusbar != NULL) { g_object_unref (priv->statusbar); priv->statusbar = NULL; @@ -415,6 +422,15 @@ mail_browser_constructed (GObject *object) priv->statusbar = g_object_ref (widget); gtk_widget_show (widget); + widget = e_mail_search_bar_new (EM_FORMAT_HTML (html_display)->html); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + priv->search_bar = g_object_ref (widget); + gtk_widget_hide (widget); + + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (em_format_redraw), html_display); + widget = gtk_ui_manager_get_widget (ui_manager, "/main-menu"); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); priv->main_menu = g_object_ref (widget); @@ -544,6 +560,16 @@ mail_browser_set_message (EMailReader *reader, } static void +mail_browser_show_search_bar (EMailReader *reader) +{ + EMailBrowserPrivate *priv; + + priv = E_MAIL_BROWSER_GET_PRIVATE (reader); + + gtk_widget_show (priv->search_bar); +} + +static void mail_browser_class_init (EMailBrowserClass *class) { GObjectClass *object_class; @@ -583,6 +609,7 @@ mail_browser_iface_init (EMailReaderIface *iface) iface->get_shell_module = mail_browser_get_shell_module; iface->get_window = mail_browser_get_window; iface->set_message = mail_browser_set_message; + iface->show_search_bar = mail_browser_show_search_bar; } static void diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c index 8ad72ebf86..f649393f40 100644 --- a/mail/e-mail-display.c +++ b/mail/e-mail-display.c @@ -581,7 +581,7 @@ gboolean e_mail_display_get_caret_mode (EMailDisplay *display) { /* XXX This is just here to maintain symmetry - * with e_mail_display_get_caret_mode(). */ + * with e_mail_display_set_caret_mode(). */ g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), FALSE); diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index b058fda07e..b28221d5e9 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -52,6 +52,7 @@ enum { CHANGED, FOLDER_LOADED, + SHOW_SEARCH_BAR, LAST_SIGNAL }; @@ -265,7 +266,7 @@ static void action_mail_find_cb (GtkAction *action, EMailReader *reader) { - /* FIXME */ + e_mail_reader_show_search_bar (reader); } static void @@ -1982,6 +1983,15 @@ mail_reader_class_init (EMailReaderIface *iface) 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + + signals[SHOW_SEARCH_BAR] = g_signal_new ( + "show-search-bar", + G_OBJECT_CLASS_TYPE (iface), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMailReaderIface, show_search_bar), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } GType @@ -2733,3 +2743,11 @@ e_mail_reader_create_charset_menu (EMailReader *reader, gtk_ui_manager_ensure_update (ui_manager); } + +void +e_mail_reader_show_search_bar (EMailReader *reader) +{ + g_return_if_fail (E_IS_MAIL_READER (reader)); + + g_signal_emit (reader, signals[SHOW_SEARCH_BAR], 0); +} diff --git a/mail/e-mail-reader.h b/mail/e-mail-reader.h index 5bacc1fb1b..6499eaf07b 100644 --- a/mail/e-mail-reader.h +++ b/mail/e-mail-reader.h @@ -95,6 +95,9 @@ struct _EMailReaderIface { void (*set_message) (EMailReader *reader, const gchar *uid, gboolean mark_read); + + /* Signals */ + void (*show_search_bar) (EMailReader *reader); }; GType e_mail_reader_get_type (void); @@ -124,6 +127,7 @@ void e_mail_reader_create_charset_menu (EMailReader *reader, GtkUIManager *ui_manager, guint merge_id); +void e_mail_reader_show_search_bar (EMailReader *reader); G_END_DECLS diff --git a/mail/e-mail-search-bar.c b/mail/e-mail-search-bar.c new file mode 100644 index 0000000000..2d02d618c9 --- /dev/null +++ b/mail/e-mail-search-bar.c @@ -0,0 +1,664 @@ +/* + * e-mail-search-bar.c + * + * This program 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 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "e-mail-search-bar.h" + +#include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> +#include <gtkhtml/gtkhtml-search.h> + +#include "e-util/e-binding.h" +#include "widgets/misc/e-icon-entry.h" + +#define E_MAIL_SEARCH_BAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MAIL_SEARCH_BAR, EMailSearchBarPrivate)) + +struct _EMailSearchBarPrivate { + GtkHTML *html; + GtkWidget *icon_entry; + GtkWidget *case_sensitive_button; + GtkWidget *matches_label; + + ESearchingTokenizer *tokenizer; + gchar *active_search; + + guint search_wrapped : 1; +}; + +enum { + PROP_0, + PROP_CASE_SENSITIVE, + PROP_HTML, + PROP_TEXT +}; + +enum { + CHANGED, + CLEAR, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +static void +mail_search_bar_update_matches (EMailSearchBar *search_bar) +{ + ESearchingTokenizer *tokenizer; + GtkWidget *matches_label; + gint matches; + gchar *text; + + tokenizer = e_mail_search_bar_get_tokenizer (search_bar); + matches_label = search_bar->priv->matches_label; + + matches = e_searching_tokenizer_match_count (tokenizer); + text = g_strdup_printf (_("Matches: %d"), matches); + + gtk_label_set_text (GTK_LABEL (matches_label), text); + gtk_widget_show (matches_label); + + g_free (text); +} + +static void +mail_search_bar_update_tokenizer (EMailSearchBar *search_bar) +{ + ESearchingTokenizer *tokenizer; + gboolean case_sensitive; + gchar *active_search; + + tokenizer = e_mail_search_bar_get_tokenizer (search_bar); + case_sensitive = e_mail_search_bar_get_case_sensitive (search_bar); + + if (GTK_WIDGET_VISIBLE (search_bar)) + active_search = search_bar->priv->active_search; + else + active_search = NULL; + + e_searching_tokenizer_set_primary_case_sensitivity ( + tokenizer, case_sensitive); + e_searching_tokenizer_set_primary_search_string ( + tokenizer, active_search); + + e_mail_search_bar_changed (search_bar); +} + +static void +mail_search_bar_find (EMailSearchBar *search_bar, + gboolean search_forward) +{ + GtkHTML *html; + gboolean case_sensitive; + gboolean new_search; + gchar *text; + + html = e_mail_search_bar_get_html (search_bar); + case_sensitive = e_mail_search_bar_get_case_sensitive (search_bar); + text = e_mail_search_bar_get_text (search_bar); + + if (text == NULL || *text == '\0') + gtk_widget_hide (search_bar->priv->matches_label); + + new_search = + (search_bar->priv->active_search == NULL) || + (g_strcmp0 (text, search_bar->priv->active_search) != 0); + + if (new_search) { + g_free (search_bar->priv->active_search); + search_bar->priv->active_search = text; + mail_search_bar_update_tokenizer (search_bar); + } else { + gtk_html_engine_search_set_forward (html, search_forward); + if (!gtk_html_engine_search_next (html)) + new_search = TRUE; + g_free (text); + } + + if (new_search) + gtk_html_engine_search ( + html, search_bar->priv->active_search, + case_sensitive, search_forward, FALSE); +} + +static void +mail_search_bar_changed_cb (EMailSearchBar *search_bar) +{ + g_object_notify (G_OBJECT (search_bar), "text"); +} + +static void +mail_search_bar_find_next_cb (EMailSearchBar *search_bar) +{ + mail_search_bar_find (search_bar, TRUE); +} + +static void +mail_search_bar_find_previous_cb (EMailSearchBar *search_bar) +{ + mail_search_bar_find (search_bar, FALSE); +} + +static void +mail_search_bar_toggled_cb (EMailSearchBar *search_bar) +{ + g_free (search_bar->priv->active_search); + search_bar->priv->active_search = NULL; + + g_object_notify (G_OBJECT (search_bar), "case-sensitive"); +} + +static void +mail_search_bar_set_html (EMailSearchBar *search_bar, + GtkHTML *html) +{ + ESearchingTokenizer *tokenizer; + + g_return_if_fail (search_bar->priv->html == NULL); + + search_bar->priv->html = g_object_ref (html); + + tokenizer = e_mail_search_bar_get_tokenizer (search_bar); + gtk_html_set_tokenizer (html, HTML_TOKENIZER (tokenizer)); +} + +static void +mail_search_bar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CASE_SENSITIVE: + e_mail_search_bar_set_case_sensitive ( + E_MAIL_SEARCH_BAR (object), + g_value_get_boolean (value)); + return; + + case PROP_HTML: + mail_search_bar_set_html ( + E_MAIL_SEARCH_BAR (object), + g_value_get_object (value)); + return; + + case PROP_TEXT: + e_mail_search_bar_set_text ( + E_MAIL_SEARCH_BAR (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_search_bar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_CASE_SENSITIVE: + g_value_set_boolean ( + value, e_mail_search_bar_get_case_sensitive ( + E_MAIL_SEARCH_BAR (object))); + return; + + case PROP_HTML: + g_value_set_object ( + value, e_mail_search_bar_get_html ( + E_MAIL_SEARCH_BAR (object))); + return; + + case PROP_TEXT: + g_value_take_string ( + value, e_mail_search_bar_get_text ( + E_MAIL_SEARCH_BAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +mail_search_bar_dispose (GObject *object) +{ + EMailSearchBarPrivate *priv; + + priv = E_MAIL_SEARCH_BAR_GET_PRIVATE (object); + + if (priv->html != NULL) { + g_object_unref (priv->html); + priv->html = NULL; + } + + if (priv->icon_entry != NULL) { + g_object_unref (priv->icon_entry); + priv->icon_entry = NULL; + } + + if (priv->case_sensitive_button != NULL) { + g_object_unref (priv->case_sensitive_button); + priv->case_sensitive_button = NULL; + } + + if (priv->matches_label != NULL) { + g_object_unref (priv->matches_label); + priv->matches_label = NULL; + } + + if (priv->tokenizer != NULL) { + g_object_unref (priv->tokenizer); + priv->tokenizer = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +mail_search_bar_finalize (GObject *object) +{ + EMailSearchBarPrivate *priv; + + priv = E_MAIL_SEARCH_BAR_GET_PRIVATE (object); + + g_free (priv->active_search); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +mail_search_bar_constructed (GObject *object) +{ + EMailSearchBarPrivate *priv; + + priv = E_MAIL_SEARCH_BAR_GET_PRIVATE (object); + + e_mutual_binding_new ( + G_OBJECT (object), "case-sensitive", + G_OBJECT (priv->case_sensitive_button), "active"); +} + +static void +mail_search_bar_show (GtkWidget *widget) +{ + EMailSearchBar *search_bar; + EIconEntry *icon_entry; + GtkWidget *entry; + + search_bar = E_MAIL_SEARCH_BAR (widget); + + /* Chain up to parent's show() method. */ + GTK_WIDGET_CLASS (parent_class)->show (widget); + + icon_entry = E_ICON_ENTRY (search_bar->priv->icon_entry); + entry = e_icon_entry_get_entry (icon_entry); + gtk_widget_grab_focus (entry); + + mail_search_bar_update_tokenizer (search_bar); +} + +static void +mail_search_bar_hide (GtkWidget *widget) +{ + EMailSearchBar *search_bar; + + search_bar = E_MAIL_SEARCH_BAR (widget); + + /* Chain up to parent's hide() method. */ + GTK_WIDGET_CLASS (parent_class)->hide (widget); + + mail_search_bar_update_tokenizer (search_bar); +} + +static gboolean +mail_search_bar_key_press_event (GtkWidget *widget, + GdkEventKey *event) +{ + if (event->keyval == GDK_Escape) { + gtk_widget_hide (widget); + return TRUE; + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (parent_class)-> + key_press_event (widget, event); +} + +static void +mail_search_bar_clear (EMailSearchBar *search_bar) +{ + g_free (search_bar->priv->active_search); + search_bar->priv->active_search = NULL; + + gtk_widget_hide (search_bar->priv->matches_label); + + mail_search_bar_update_tokenizer (search_bar); +} + +static void +mail_search_bar_class_init (EMailSearchBarClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EMailSearchBarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = mail_search_bar_set_property; + object_class->get_property = mail_search_bar_get_property; + object_class->dispose = mail_search_bar_dispose; + object_class->finalize = mail_search_bar_finalize; + object_class->constructed = mail_search_bar_constructed; + + widget_class = GTK_WIDGET_CLASS (class); + widget_class->show = mail_search_bar_show; + widget_class->hide = mail_search_bar_hide; + widget_class->key_press_event = mail_search_bar_key_press_event; + + class->clear = mail_search_bar_clear; + + g_object_class_install_property ( + object_class, + PROP_CASE_SENSITIVE, + g_param_spec_boolean ( + "case-sensitive", + "Case Sensitive", + NULL, + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_HTML, + g_param_spec_object ( + "html", + "HTML Display", + NULL, + GTK_TYPE_HTML, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_TEXT, + g_param_spec_string ( + "text", + "Search Text", + NULL, + NULL, + G_PARAM_READWRITE)); + + signals[CHANGED] = g_signal_new ( + "changed", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMailSearchBarClass, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CLEAR] = g_signal_new ( + "clear", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMailSearchBarClass, clear), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +mail_search_bar_init (EMailSearchBar *search_bar) +{ + GtkWidget *label; + GtkWidget *widget; + GtkWidget *container; + + search_bar->priv = E_MAIL_SEARCH_BAR_GET_PRIVATE (search_bar); + search_bar->priv->tokenizer = e_searching_tokenizer_new (); + + g_signal_connect_swapped ( + search_bar->priv->tokenizer, "match", + G_CALLBACK (mail_search_bar_update_matches), search_bar); + + gtk_box_set_spacing (GTK_BOX (search_bar), 6); + + container = GTK_WIDGET (search_bar); + + widget = gtk_alignment_new (1.0, 0.5, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (widget), 0, 0, 6, 0); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + container = widget; + + widget = gtk_label_new_with_mnemonic (_("Fin_d:")); + gtk_container_add (GTK_CONTAINER (container), widget); + gtk_widget_show (widget); + + container = GTK_WIDGET (search_bar); + label = widget; + + widget = e_icon_entry_new (); + gtk_label_set_mnemonic_widget ( + GTK_LABEL (label), + e_icon_entry_get_entry (E_ICON_ENTRY (widget))); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + search_bar->priv->icon_entry = g_object_ref (widget); + gtk_widget_show (widget); + + widget = e_icon_entry_get_entry (E_ICON_ENTRY (widget)); + + g_signal_connect_swapped ( + widget, "activate", + G_CALLBACK (mail_search_bar_find_next_cb), search_bar); + + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (mail_search_bar_changed_cb), search_bar); + + widget = gtk_button_new_with_mnemonic (_("Find _Previous")); + gtk_button_set_image ( + GTK_BUTTON (widget), gtk_image_new_from_stock ( + GTK_STOCK_GO_BACK, GTK_ICON_SIZE_MENU)); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (mail_search_bar_find_previous_cb), search_bar); + + widget = gtk_button_new_with_mnemonic (_("Find _Next")); + gtk_button_set_image ( + GTK_BUTTON (widget), gtk_image_new_from_stock ( + GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU)); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (mail_search_bar_find_next_cb), search_bar); + + widget = gtk_check_button_new_with_mnemonic (_("C_ase sensitive")); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + search_bar->priv->case_sensitive_button = g_object_ref (widget); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "toggled", + G_CALLBACK (mail_search_bar_toggled_cb), search_bar); + + g_signal_connect_swapped ( + widget, "toggled", + G_CALLBACK (mail_search_bar_find_next_cb), search_bar); + + widget = gtk_button_new (); + gtk_button_set_image ( + GTK_BUTTON (widget), gtk_image_new_from_stock ( + GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU)); + gtk_button_set_relief (GTK_BUTTON (widget), GTK_RELIEF_NONE); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + gtk_widget_show (widget); + + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (gtk_widget_hide), search_bar); + + widget = gtk_label_new (NULL); + gtk_box_pack_end (GTK_BOX (container), widget, FALSE, FALSE, 0); + search_bar->priv->matches_label = g_object_ref (widget); + gtk_widget_show (widget); +} + +GType +e_mail_search_bar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EMailSearchBarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) mail_search_bar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EMailSearchBar), + 0, /* n_preallocs */ + (GInstanceInitFunc) mail_search_bar_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GTK_TYPE_HBOX, "EMailSearchBar", &type_info, 0); + } + + return type; +} + +GtkWidget * +e_mail_search_bar_new (GtkHTML *html) +{ + g_return_val_if_fail (GTK_IS_HTML (html), NULL); + + return g_object_new (E_TYPE_MAIL_SEARCH_BAR, "html", html, NULL); +} + +void +e_mail_search_bar_clear (EMailSearchBar *search_bar) +{ + g_return_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar)); + + g_signal_emit (search_bar, signals[CLEAR], 0); +} + +void +e_mail_search_bar_changed (EMailSearchBar *search_bar) +{ + g_return_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar)); + + g_signal_emit (search_bar, signals[CHANGED], 0); +} + +GtkHTML * +e_mail_search_bar_get_html (EMailSearchBar *search_bar) +{ + g_return_val_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar), NULL); + + return search_bar->priv->html; +} + +ESearchingTokenizer * +e_mail_search_bar_get_tokenizer (EMailSearchBar *search_bar) +{ + g_return_val_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar), NULL); + + return search_bar->priv->tokenizer; +} + +gboolean +e_mail_search_bar_get_case_sensitive (EMailSearchBar *search_bar) +{ + GtkToggleButton *button; + + g_return_val_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar), FALSE); + + button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button); + + return gtk_toggle_button_get_active (button); +} + +void +e_mail_search_bar_set_case_sensitive (EMailSearchBar *search_bar, + gboolean case_sensitive) +{ + GtkToggleButton *button; + + g_return_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar)); + + button = GTK_TOGGLE_BUTTON (search_bar->priv->case_sensitive_button); + + gtk_toggle_button_set_active (button, case_sensitive); + + g_object_notify (G_OBJECT (search_bar), "case-sensitive"); +} + +gchar * +e_mail_search_bar_get_text (EMailSearchBar *search_bar) +{ + EIconEntry *icon_entry; + GtkWidget *entry; + const gchar *text; + + g_return_val_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar), NULL); + + icon_entry = E_ICON_ENTRY (search_bar->priv->icon_entry); + entry = e_icon_entry_get_entry (icon_entry); + text = gtk_entry_get_text (GTK_ENTRY (entry)); + + return g_strstrip (g_strdup (text)); +} + +void +e_mail_search_bar_set_text (EMailSearchBar *search_bar, + const gchar *text) +{ + EIconEntry *icon_entry; + GtkWidget *entry; + + g_return_if_fail (E_IS_MAIL_SEARCH_BAR (search_bar)); + + icon_entry = E_ICON_ENTRY (search_bar->priv->icon_entry); + entry = e_icon_entry_get_entry (icon_entry); + + if (text == NULL) + text = ""; + + /* This will trigger a "notify::text" signal. */ + gtk_entry_set_text (GTK_ENTRY (entry), text); +} diff --git a/mail/e-mail-search-bar.h b/mail/e-mail-search-bar.h new file mode 100644 index 0000000000..7f19e176b7 --- /dev/null +++ b/mail/e-mail-search-bar.h @@ -0,0 +1,85 @@ +/* + * e-mail-search-bar.h + * + * This program 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 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef E_MAIL_SEARCH_BAR_H +#define E_MAIL_SEARCH_BAR_H + +#include <gtk/gtk.h> +#include <gtkhtml/gtkhtml.h> +#include <mail/e-searching-tokenizer.h> + +/* Standard GObject macros */ +#define E_TYPE_MAIL_SEARCH_BAR \ + (e_mail_search_bar_get_type ()) +#define E_MAIL_SEARCH_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_SEARCH_BAR, EMailSearchBar)) +#define E_MAIL_SEARCH_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_SEARCH_BAR, EMailSearchBarClass)) +#define E_IS_MAIL_SEARCH_BAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_SEARCH_BAR)) +#define E_IS_MAIL_SEARCH_BAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_SEARCH_BAR)) +#define E_MAIL_SEARCH_BAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MAIL_SEARCH_BAR, EMailSearchBarClass)) + +G_BEGIN_DECLS + +typedef struct _EMailSearchBar EMailSearchBar; +typedef struct _EMailSearchBarClass EMailSearchBarClass; +typedef struct _EMailSearchBarPrivate EMailSearchBarPrivate; + +struct _EMailSearchBar { + GtkHBox parent; + EMailSearchBarPrivate *priv; +}; + +struct _EMailSearchBarClass { + GtkHBoxClass parent_class; + + /* Signals */ + void (*changed) (EMailSearchBar *search_bar); + void (*clear) (EMailSearchBar *search_bar); +}; + +GType e_mail_search_bar_get_type (void); +GtkWidget * e_mail_search_bar_new (GtkHTML *html); +void e_mail_search_bar_clear (EMailSearchBar *search_bar); +void e_mail_search_bar_changed (EMailSearchBar *search_bar); +GtkHTML * e_mail_search_bar_get_html (EMailSearchBar *search_bar); +ESearchingTokenizer * + e_mail_search_bar_get_tokenizer (EMailSearchBar *search_bar); +gboolean e_mail_search_bar_get_case_sensitive + (EMailSearchBar *search_bar); +void e_mail_search_bar_set_case_sensitive + (EMailSearchBar *search_bar, + gboolean case_sensitive); +gchar * e_mail_search_bar_get_text (EMailSearchBar *search_bar); +void e_mail_search_bar_set_text (EMailSearchBar *search_bar, + const gchar *text); + +G_END_DECLS + +#endif /* E_MAIL_SEARCH_BAR_H */ diff --git a/mail/e-mail-shell-content.c b/mail/e-mail-shell-content.c index 17d873e8c0..0f7e91f4ad 100644 --- a/mail/e-mail-shell-content.c +++ b/mail/e-mail-shell-content.c @@ -36,6 +36,7 @@ #include "mail-ops.h" #include "e-mail-reader.h" +#include "e-mail-search-bar.h" #include "e-mail-shell-module.h" #include "e-mail-shell-view-actions.h" @@ -46,6 +47,7 @@ struct _EMailShellContentPrivate { GtkWidget *paned; GtkWidget *message_list; + GtkWidget *search_bar; EMFormatHTMLDisplay *html_display; GalViewInstance *view_instance; @@ -307,6 +309,11 @@ mail_shell_content_dispose (GObject *object) priv->message_list = NULL; } + if (priv->search_bar != NULL) { + g_object_unref (priv->search_bar); + priv->search_bar = NULL; + } + if (priv->html_display != NULL) { g_object_unref (priv->html_display); priv->html_display = NULL; @@ -347,10 +354,12 @@ mail_shell_content_constructed (GObject *object) GConfBridge *bridge; GtkWidget *container; GtkWidget *widget; + GtkHTML *html; GalViewCollection *view_collection; const gchar *key; priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (object); + priv->html_display = em_format_html_display_new (); /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (parent_class)->constructed (object); @@ -361,6 +370,8 @@ mail_shell_content_constructed (GObject *object) shell_module = e_shell_view_get_shell_module (shell_view); view_collection = shell_view_class->view_collection; + html = EM_FORMAT_HTML (priv->html_display)->html; + /* Build content widgets. */ container = GTK_WIDGET (object); @@ -377,21 +388,31 @@ mail_shell_content_constructed (GObject *object) priv->message_list = g_object_ref (widget); gtk_widget_show (widget); + widget = gtk_vbox_new (FALSE, 0); + gtk_paned_add2 (GTK_PANED (container), widget); + gtk_widget_show (widget); + + container = widget; + widget = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_paned_add2 (GTK_PANED (container), widget); + gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (html)); + gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0); + gtk_widget_show (GTK_WIDGET (html)); gtk_widget_show (widget); - container = widget; + widget = e_mail_search_bar_new (html); + gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); + priv->search_bar = g_object_ref (widget); + gtk_widget_hide (widget); - priv->html_display = em_format_html_display_new (); - widget = GTK_WIDGET (((EMFormatHTML *) priv->html_display)->html); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (em_format_redraw), priv->html_display); /* Load the view instance. */ @@ -547,6 +568,16 @@ exit: } static void +mail_shell_content_show_search_bar (EMailReader *reader) +{ + EMailShellContentPrivate *priv; + + priv = E_MAIL_SHELL_CONTENT_GET_PRIVATE (reader); + + gtk_widget_show (priv->search_bar); +} + +static void mail_shell_content_class_init (EMailShellContentClass *class) { GObjectClass *object_class; @@ -597,6 +628,7 @@ mail_shell_content_iface_init (EMailReaderIface *iface) iface->get_shell_module = mail_shell_content_get_shell_module; iface->get_window = mail_shell_content_get_window; iface->set_folder = mail_shell_content_set_folder; + iface->show_search_bar = mail_shell_content_show_search_bar; } static void @@ -763,6 +795,30 @@ e_mail_shell_content_get_view_instance (EMailShellContent *mail_shell_content) } void +e_mail_shell_content_set_search_strings (EMailShellContent *mail_shell_content, + GSList *search_strings) +{ + EMailSearchBar *search_bar; + ESearchingTokenizer *tokenizer; + + g_return_if_fail (E_IS_MAIL_SHELL_CONTENT (mail_shell_content)); + + search_bar = E_MAIL_SEARCH_BAR (mail_shell_content->priv->search_bar); + tokenizer = e_mail_search_bar_get_tokenizer (search_bar); + + e_searching_tokenizer_set_secondary_case_sensitivity (tokenizer, FALSE); + e_searching_tokenizer_set_secondary_search_string (tokenizer, NULL); + + while (search_strings != NULL) { + e_searching_tokenizer_add_secondary_search_string ( + tokenizer, search_strings->data); + search_strings = g_slist_next (search_strings); + } + + e_mail_search_bar_changed (search_bar); +} + +void e_mail_shell_content_update_view_instance (EMailShellContent *mail_shell_content) { EMailReader *reader; diff --git a/mail/e-mail-shell-content.h b/mail/e-mail-shell-content.h index 2c328ce268..a27e1a6f7e 100644 --- a/mail/e-mail-shell-content.h +++ b/mail/e-mail-shell-content.h @@ -76,6 +76,9 @@ void e_mail_shell_content_set_vertical_view GalViewInstance * e_mail_shell_content_get_view_instance (EMailShellContent *mail_shell_content); +void e_mail_shell_content_set_search_strings + (EMailShellContent *mail_shell_content, + GSList *search_strings); void e_mail_shell_content_update_view_instance (EMailShellContent *mail_shell_content); diff --git a/mail/e-mail-shell-view-private.c b/mail/e-mail-shell-view-private.c index 460856ba5e..8aecb20656 100644 --- a/mail/e-mail-shell-view-private.c +++ b/mail/e-mail-shell-view-private.c @@ -328,6 +328,7 @@ e_mail_shell_view_execute_search (EMailShellView *mail_shell_view) EShellContent *shell_content; EShellSettings *shell_settings; EMFormatHTMLDisplay *html_display; + EMailShellContent *mail_shell_content; MessageList *message_list; FilterRule *rule; EMailReader *reader; @@ -338,7 +339,7 @@ e_mail_shell_view_execute_search (EMailShellView *mail_shell_view) GtkTreeIter tree_iter; GString *string; GList *iter; - GSList *word_list = NULL; + GSList *search_strings = NULL; const gchar *folder_uri; const gchar *text; gboolean valid; @@ -356,6 +357,8 @@ e_mail_shell_view_execute_search (EMailShellView *mail_shell_view) shell = e_shell_window_get_shell (shell_window); shell_settings = e_shell_get_shell_settings (shell); + mail_shell_content = mail_shell_view->priv->mail_shell_content; + reader = E_MAIL_READER (shell_content); html_display = e_mail_reader_get_html_display (reader); message_list = e_mail_reader_get_message_list (reader); @@ -400,8 +403,8 @@ e_mail_shell_view_execute_search (EMailShellView *mail_shell_view) words = camel_search_words_split ((guchar *) text); for (ii = 0; ii < words->len; ii++) - word_list = g_slist_prepend ( - word_list, g_strdup ( + search_strings = g_slist_prepend ( + search_strings, g_strdup ( words->words[ii]->word)); camel_search_words_free (words); } @@ -550,14 +553,11 @@ filter: message_list_set_search (message_list, query); - em_format_html_display_set_search ( - html_display, - EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY | - EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE, - word_list); + e_mail_shell_content_set_search_strings ( + mail_shell_content, search_strings); - g_slist_foreach (word_list, (GFunc) g_free, NULL); - g_slist_free (word_list); + g_slist_foreach (search_strings, (GFunc) g_free, NULL); + g_slist_free (search_strings); g_object_unref (model); g_free (query); diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c index 172a126c92..129aa0539b 100644 --- a/mail/e-searching-tokenizer.c +++ b/mail/e-searching-tokenizer.c @@ -38,77 +38,17 @@ #define d(x) +#define E_SEARCHING_TOKENIZER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerPrivate)) + enum { MATCH_SIGNAL, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0, }; - -static void e_searching_tokenizer_begin (HTMLTokenizer *, const char *); -static void e_searching_tokenizer_end (HTMLTokenizer *); -static char *e_searching_tokenizer_peek_token (HTMLTokenizer *); -static char *e_searching_tokenizer_next_token (HTMLTokenizer *); -static gboolean e_searching_tokenizer_has_more (HTMLTokenizer *); - -static HTMLTokenizer *e_searching_tokenizer_clone (HTMLTokenizer *); - -/* - static const gchar *space_tags[] = { "br", NULL };*/ - -static HTMLTokenizerClass *parent_class = NULL; - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* ??? -typedef struct _SharedState SharedState; -struct _SharedState { - gint refs; - gchar *str_primary; - gchar *str_secondary; - gboolean case_sensitive_primary; - gboolean case_sensitive_secondary; -}; -*/ - -/* ********************************************************************** */ - - -#if 0 -static SharedState * -shared_state_new (void) -{ - SharedState *shared = g_new0 (SharedState, 1); - shared->refs = 1; - return shared; -} - -static void -shared_state_ref (SharedState *shared) -{ - g_return_if_fail (shared != NULL); - g_return_if_fail (shared->refs > 0); - ++shared->refs; -} - -static void -shared_state_unref (SharedState *shared) -{ - if (shared) { - g_return_if_fail (shared->refs > 0); - --shared->refs; - if (shared->refs == 0) { - g_free (shared->str_primary); - g_free (shared->str_secondary); - g_free (shared); - } - } -} -#endif - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* ********************************************************************** */ +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; /* Utility functions */ @@ -184,7 +124,7 @@ ignore_tag (const char *tag) *out = 0; for (i=0;i<sizeof(ignored_tags)/sizeof(ignored_tags[0]);i++) { - if (strcmp(t, ignored_tags[i]) == 0) + if (strcmp (t, ignored_tags[i]) == 0) return 1; } @@ -222,7 +162,7 @@ struct _trie { /* will be enabled only if debug is enabled */ #if d(1) -1 != -1 static void -dump_trie(struct _state *s, int d) +dump_trie (struct _state *s, int d) { char *p = alloca(d*2+1); struct _match *m; @@ -235,7 +175,7 @@ dump_trie(struct _state *s, int d) while (m) { printf(" %s'%c' -> %p\n", p, m->ch, m->match); if (m->match) - dump_trie(m->match, d+1); + dump_trie (m->match, d+1); m = m->next; } } @@ -247,7 +187,7 @@ dump_trie(struct _state *s, int d) for a neat demo */ static inline struct _match * -g(struct _state *q, guint32 c) +g (struct _state *q, guint32 c) { struct _match *m = q->matches; @@ -258,7 +198,7 @@ g(struct _state *q, guint32 c) } static struct _trie * -build_trie(int nocase, int len, unsigned char **words) +build_trie (int nocase, int len, unsigned char **words) { struct _state *q, *qt, *r; const unsigned char *word; @@ -275,8 +215,8 @@ build_trie(int nocase, int len, unsigned char **words) trie->root.fail = NULL; trie->root.next = NULL; - trie->state_chunks = e_memchunk_new(8, sizeof(struct _state)); - trie->match_chunks = e_memchunk_new(8, sizeof(struct _match)); + trie->state_chunks = e_memchunk_new (8, sizeof(struct _state)); + trie->match_chunks = e_memchunk_new (8, sizeof(struct _match)); /* This will correspond to the length of the longest pattern */ state_depth_size = 0; @@ -294,8 +234,8 @@ build_trie(int nocase, int len, unsigned char **words) depth = 0; while ((c = camel_utf8_getc (&word))) { if (nocase) - c = g_unichar_tolower(c); - m = g(q, c); + c = g_unichar_tolower (c); + m = g (q, c); if (m == NULL) { m = e_memchunk_alloc(trie->match_chunks); m->ch = c; @@ -324,7 +264,7 @@ build_trie(int nocase, int len, unsigned char **words) } d(printf("Dumping trie:\n")); - d(dump_trie(&trie->root, 0)); + d(dump_trie (&trie->root, 0)); /* Step 2: Build failure graph */ @@ -340,14 +280,14 @@ build_trie(int nocase, int len, unsigned char **words) c = m->ch; qt = m->match; r = q->fail; - while (r && (n = g(r, c)) == NULL) + while (r && (n = g (r, c)) == NULL) r = r->fail; if (r != NULL) { qt->fail = n->match; if (qt->fail->final > qt->final) qt->final = qt->fail->final; } else { - if ((n = g(&trie->root, c))) + if ((n = g (&trie->root, c))) qt->fail = n->match; else qt->fail = &trie->root; @@ -358,10 +298,10 @@ build_trie(int nocase, int len, unsigned char **words) } } - d(printf("After failure analysis\n")); - d(dump_trie(&trie->root, 0)); + d (printf("After failure analysis\n")); + d (dump_trie (&trie->root, 0)); - g_free(state_depth); + g_free (state_depth); trie->max_depth = state_depth_size; @@ -369,12 +309,12 @@ build_trie(int nocase, int len, unsigned char **words) } static void -free_trie(struct _trie *t) +free_trie (struct _trie *t) { e_memchunk_destroy(t->match_chunks); e_memchunk_destroy(t->state_chunks); - g_free(t); + g_free (t); } /* ********************************************************************** */ @@ -444,10 +384,10 @@ searcher_new (int flags, int argc, unsigned char **argv, const char *tags, const s = g_malloc(sizeof(*s)); - s->t = build_trie((flags&SEARCH_CASE) == 0, argc, argv); + s->t = build_trie ((flags&SEARCH_CASE) == 0, argc, argv); s->words = argc; - s->tags = g_strdup(tags); - s->tage = g_strdup(tage); + s->tags = g_strdup (tags); + s->tage = g_strdup (tage); s->flags = flags; s->state = &s->t->root; s->matchcount = 0; @@ -476,20 +416,20 @@ searcher_new (int flags, int argc, unsigned char **argv, const char *tags, const } static void -searcher_free(struct _searcher *s) +searcher_free (struct _searcher *s) { struct _token *t; - while ((t = (struct _token *)e_dlist_remhead(&s->input))) - g_free(t); - while ((t = (struct _token *)e_dlist_remhead(&s->output))) - g_free(t); - g_free(s->tags); - g_free(s->tage); - g_free(s->last); - g_free(s->submatches); - free_trie(s->t); - g_free(s); + while ((t = (struct _token *)e_dlist_remhead (&s->input))) + g_free (t); + while ((t = (struct _token *)e_dlist_remhead (&s->output))) + g_free (t); + g_free (s->tags); + g_free (s->tage); + g_free (s->last); + g_free (s->submatches); + free_trie (s->t); + g_free (s); } static struct _token * append_token(EDList *list, const char *tok, int len) @@ -507,7 +447,7 @@ append_token(EDList *list, const char *tok, int len) return token; } -#define free_token(x) (g_free(x)) +#define free_token(x) (g_free (x)) static void output_token(struct _searcher *s, struct _token *token) @@ -517,10 +457,10 @@ output_token(struct _searcher *s, struct _token *token) if (token->tok[0] == TAG_ESCAPE) { if (token->offset >= s->offout) { - d(printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); e_dlist_addtail(&s->output, (EDListNode *)token); } else { - d(printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); free_token(token); } } else { @@ -529,12 +469,12 @@ output_token(struct _searcher *s, struct _token *token) if (left > 0) { pre = s->offout - token->offset; if (pre>0) - memmove(token->tok, token->tok+pre, left+1); - d(printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + memmove (token->tok, token->tok+pre, left+1); + d (printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = offend; e_dlist_addtail(&s->output, (EDListNode *)token); } else { - d(printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); free_token(token); } } @@ -563,30 +503,30 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) struct _token *starttoken, *endtoken; char b[8]; - d(printf("output match: %d-%d at %d\n", start, end, s->offout)); + d (printf("output match: %d-%d at %d\n", start, end, s->offout)); starttoken = find_token(s, start); endtoken = find_token(s, end); if (starttoken == NULL || endtoken == NULL) { - d(printf("Cannot find match history for match %d-%d\n", start, end)); + d (printf("Cannot find match history for match %d-%d\n", start, end)); return; } - d(printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok)); - d(printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok)); + d (printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok)); + d (printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok)); /* output pending stuff that didn't match afterall */ while ((struct _token *)s->input.head != starttoken) { - token = (struct _token *)e_dlist_remhead(&s->input); - d(printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + token = (struct _token *)e_dlist_remhead (&s->input); + d (printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); output_token(s, token); } /* output any pre-match text */ if (s->offout < start) { token = append_token(&s->output, starttoken->tok + (s->offout-starttoken->offset), start-s->offout); - d(printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = start; } @@ -598,11 +538,11 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) if (s->tags) append_token(&s->output, s->tags, -1); - /* output match node(s) */ + /* output match node (s) */ if (starttoken != endtoken) { while ((struct _token *)s->input.head != endtoken) { - token = (struct _token *)e_dlist_remhead(&s->input); - d(printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + token = (struct _token *)e_dlist_remhead (&s->input); + d (printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); output_token(s, token); } } @@ -610,7 +550,7 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) /* any remaining partial content */ if (s->offout < end) { token = append_token(&s->output, endtoken->tok+(s->offout-endtoken->offset), end-s->offout); - d(printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = end; } @@ -627,7 +567,7 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) /* output any sub-pending blocks */ static void -output_subpending(struct _searcher *s) +output_subpending (struct _searcher *s) { int i; @@ -638,7 +578,7 @@ output_subpending(struct _searcher *s) /* returns true if a merge took place */ static int -merge_subpending(struct _searcher *s, int offstart, int offend) +merge_subpending (struct _searcher *s, int offstart, int offend) { int i; @@ -663,11 +603,11 @@ merge_subpending(struct _searcher *s, int offstart, int offend) } static void -push_subpending(struct _searcher *s, int offstart, int offend) +push_subpending (struct _searcher *s, int offstart, int offend) { /* This is really an assertion, we just ignore the last pending match instead of crashing though */ if (s->submatchp >= s->words) { - d(printf("ERROR: submatch pending stack overflow\n")); + d (printf("ERROR: submatch pending stack overflow\n")); s->submatchp = s->words-1; } @@ -678,11 +618,11 @@ push_subpending(struct _searcher *s, int offstart, int offend) /* move any (partial) tokens from input to output if they are beyond the current output position */ static void -output_pending(struct _searcher *s) +output_pending (struct _searcher *s) { struct _token *token; - while ( (token = (struct _token *)e_dlist_remhead(&s->input)) ) + while ( (token = (struct _token *)e_dlist_remhead (&s->input)) ) output_token(s, token); } @@ -706,7 +646,7 @@ flush_extra(struct _searcher *s) return; while ((struct _token *)s->input.head != starttoken) { - token = (struct _token *)e_dlist_remhead(&s->input); + token = (struct _token *)e_dlist_remhead (&s->input); output_token(s, token); } } @@ -726,8 +666,8 @@ searcher_next_token(struct _searcher *s) /* get next token */ tok = (unsigned char *)s->next_token(s->next_data); if (tok == NULL) { - output_subpending(s); - output_pending(s); + output_subpending (s); + output_pending (s); break; } @@ -736,14 +676,14 @@ searcher_next_token(struct _searcher *s) token->offset = s->offset; tok = (unsigned char *)token->tok; - d(printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); /* tag test, reset state on unknown tags */ if (tok[0] == TAG_ESCAPE) { if (!ignore_tag ((char *)tok)) { /* force reset */ - output_subpending(s); - output_pending(s); + output_subpending (s); + output_pending (s); q = &t->root; } @@ -754,12 +694,12 @@ searcher_next_token(struct _searcher *s) pre_tok = stok = tok; while ((c = camel_utf8_getc (&tok))) { if ((s->flags & SEARCH_CASE) == 0) - c = g_unichar_tolower(c); - while (q && (m = g(q, c)) == NULL) + c = g_unichar_tolower (c); + while (q && (m = g (q, c)) == NULL) q = q->fail; if (q == NULL) { /* mismatch ... reset state */ - output_subpending(s); + output_subpending (s); q = &t->root; } else if (m != NULL) { /* keep track of previous offsets of utf8 chars, rotating buffer */ @@ -778,21 +718,21 @@ searcher_next_token(struct _searcher *s) if (q->matches == NULL) { if (s->submatchp == 0) { /* nothing pending, always put something in so we can try merge */ - push_subpending(s, offstart, offend); - } else if (!merge_subpending(s, offstart, offend)) { + push_subpending (s, offstart, offend); + } else if (!merge_subpending (s, offstart, offend)) { /* can't merge, output what we have, and start againt */ - output_subpending(s); - push_subpending(s, offstart, offend); + output_subpending (s); + push_subpending (s, offstart, offend); /*output_match(s, offstart, offend);*/ } else if (e_dlist_length(&s->input) > 8) { /* we're continuing to match and merge, but we have a lot of stuff waiting, so flush it out now since this is a safe point to do it */ - output_subpending(s); + output_subpending (s); } } else { /* merge/add subpending */ - if (!merge_subpending(s, offstart, offend)) - push_subpending(s, offstart, offend); + if (!merge_subpending (s, offstart, offend)) + push_subpending (s, offstart, offend); } } } @@ -809,7 +749,7 @@ searcher_next_token(struct _searcher *s) if (s->current) free_token(s->current); - s->current = token = (struct _token *)e_dlist_remhead(&s->output); + s->current = token = (struct _token *)e_dlist_remhead (&s->output); return token ? g_strdup (token->tok) : NULL; } @@ -823,7 +763,7 @@ searcher_peek_token(struct _searcher *s) tok = searcher_next_token(s); if (tok) { /* need to clear this so we dont free it while its still active */ - e_dlist_addhead(&s->output, (EDListNode *)s->current); + e_dlist_addhead (&s->output, (EDListNode *)s->current); s->current = NULL; } @@ -831,7 +771,7 @@ searcher_peek_token(struct _searcher *s) } static int -searcher_pending(struct _searcher *s) +searcher_pending (struct _searcher *s) { return !(e_dlist_empty(&s->input) && e_dlist_empty(&s->output)); } @@ -840,7 +780,7 @@ searcher_pending(struct _searcher *s) struct _search_info { GPtrArray *strv; - char *colour; + char *color; unsigned int size:8; unsigned int flags:8; }; @@ -848,12 +788,12 @@ struct _search_info { /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ static struct _search_info * -search_info_new(void) +search_info_new (void) { struct _search_info *s; s = g_malloc0(sizeof(struct _search_info)); - s->strv = g_ptr_array_new(); + s->strv = g_ptr_array_new (); return s; } @@ -865,14 +805,14 @@ search_info_set_flags(struct _search_info *si, unsigned int flags, unsigned int } static void -search_info_set_colour(struct _search_info *si, const char *colour) +search_info_set_color (struct _search_info *si, const char *color) { - g_free(si->colour); - si->colour = g_strdup(colour); + g_free (si->color); + si->color = g_strdup (color); } static void -search_info_add_string(struct _search_info *si, const char *s) +search_info_add_string (struct _search_info *si, const char *s) { const unsigned char *start; guint32 c; @@ -889,44 +829,44 @@ search_info_add_string(struct _search_info *si, const char *s) } /* should probably also strip trailing, but i'm lazy today */ if (start[0]) - g_ptr_array_add(si->strv, g_strdup ((char *)start)); + g_ptr_array_add (si->strv, g_strdup ((char *)start)); } } static void -search_info_clear(struct _search_info *si) +search_info_clear (struct _search_info *si) { int i; for (i=0;i<si->strv->len;i++) - g_free(si->strv->pdata[i]); + g_free (si->strv->pdata[i]); - g_ptr_array_set_size(si->strv, 0); + g_ptr_array_set_size (si->strv, 0); } static void -search_info_free(struct _search_info *si) +search_info_free (struct _search_info *si) { int i; for (i=0;i<si->strv->len;i++) - g_free(si->strv->pdata[i]); + g_free (si->strv->pdata[i]); - g_ptr_array_free(si->strv, TRUE); - g_free(si->colour); - g_free(si); + g_ptr_array_free (si->strv, TRUE); + g_free (si->color); + g_free (si); } static struct _search_info * -search_info_clone(struct _search_info *si) +search_info_clone (struct _search_info *si) { struct _search_info *out; int i; - out = search_info_new(); + out = search_info_new (); for (i=0;i<si->strv->len;i++) - g_ptr_array_add(out->strv, g_strdup(si->strv->pdata[i])); - out->colour = g_strdup(si->colour); + g_ptr_array_add (out->strv, g_strdup (si->strv->pdata[i])); + out->color = g_strdup (si->color); out->flags = si->flags; out->size = si->size; @@ -934,7 +874,7 @@ search_info_clone(struct _search_info *si) } static struct _searcher * -search_info_to_searcher(struct _search_info *si) +search_info_to_searcher (struct _search_info *si) { char *tags, *tage; char *col; @@ -942,10 +882,10 @@ search_info_to_searcher(struct _search_info *si) if (si->strv->len == 0) return NULL; - if (si->colour == NULL) + if (si->color == NULL) col = "red"; else - col = si->colour; + col = si->color; tags = alloca(20+strlen(col)); sprintf(tags, "%c<font color=\"%s\">", TAG_ESCAPE, col); @@ -964,288 +904,289 @@ struct _ESearchingTokenizerPrivate { /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ -static void -e_searching_tokenizer_finalise (GObject *obj) -{ - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (obj); - struct _ESearchingTokenizerPrivate *p = st->priv; - - search_info_free (p->primary); - search_info_free (p->secondary); - if (p->engine) - searcher_free(p->engine); +/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - /* again wtf? - shared_state_unref (st->priv->shared); - */ +/* blah blah the htmltokeniser doesn't like being asked + for a token if it doens't hvae any! */ +static char * +get_token (HTMLTokenizer *tokenizer) +{ + HTMLTokenizerClass *class = HTML_TOKENIZER_CLASS (parent_class); - g_free (p); + if (class->has_more (tokenizer)) + return class->next_token (tokenizer); - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize(obj); + return NULL; } +/* proxy matched event, not sure what its for otherwise */ static void -e_searching_tokenizer_class_init (ESearchingTokenizerClass *klass) +matched (ESearchingTokenizer *tokenizer) { - GObjectClass *obj_class = (GObjectClass *) klass; - HTMLTokenizerClass *tok_class = HTML_TOKENIZER_CLASS (klass); - - parent_class = g_type_class_ref (HTML_TYPE_TOKENIZER); - - signals[MATCH_SIGNAL] = - g_signal_new ("match", - E_TYPE_SEARCHING_TOKENIZER, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchingTokenizerClass, match), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - obj_class->finalize = e_searching_tokenizer_finalise; - - tok_class->begin = e_searching_tokenizer_begin; - tok_class->end = e_searching_tokenizer_end; - - tok_class->peek_token = e_searching_tokenizer_peek_token; - tok_class->next_token = e_searching_tokenizer_next_token; - tok_class->has_more = e_searching_tokenizer_has_more; - tok_class->clone = e_searching_tokenizer_clone; + /*++tokenizer->priv->match_count;*/ + g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0); } +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + static void -e_searching_tokenizer_init (ESearchingTokenizer *st) +searching_tokenizer_finalize (GObject *object) { - struct _ESearchingTokenizerPrivate *p; - - p = st->priv = g_new0 (struct _ESearchingTokenizerPrivate, 1); + ESearchingTokenizerPrivate *priv; - p->primary = search_info_new(); - search_info_set_flags(p->primary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD); - search_info_set_colour(p->primary, "red"); + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (object); - p->secondary = search_info_new(); - search_info_set_flags(p->secondary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD); - search_info_set_colour(p->secondary, "purple"); -} + search_info_free (priv->primary); + search_info_free (priv->secondary); -GType -e_searching_tokenizer_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (ESearchingTokenizerClass), - NULL, NULL, - (GClassInitFunc) e_searching_tokenizer_class_init, - NULL, NULL, - sizeof (ESearchingTokenizer), - 0, - (GInstanceInitFunc) e_searching_tokenizer_init, - }; - - type = g_type_register_static (HTML_TYPE_TOKENIZER, "ESearchingTokenizer", &info, 0); - } + if (priv->engine != NULL) + searcher_free (priv->engine); - return type; -} - -HTMLTokenizer * -e_searching_tokenizer_new (void) -{ - return (HTMLTokenizer *) g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL); -} - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* blah blah the htmltokeniser doesn't like being asked - for a token if it doens't hvae any! */ -static char *get_token(HTMLTokenizer *t) -{ - HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class); - - return klass->has_more(t) ? klass->next_token(t) : NULL; + /* Chain up to parent's finalize () method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -e_searching_tokenizer_begin (HTMLTokenizer *t, const char *content_type) +searching_tokenizer_begin (HTMLTokenizer *tokenizer, + const gchar *content_type) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t); - struct _ESearchingTokenizerPrivate *p = st->priv; + ESearchingTokenizerPrivate *priv; + + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); /* reset search */ - if (p->engine) { - searcher_free(p->engine); - p->engine = NULL; + if (priv->engine != NULL) { + searcher_free (priv->engine); + priv->engine = NULL; } - if ((p->engine = search_info_to_searcher(p->primary)) - || (p->engine = search_info_to_searcher(p->secondary))) { - /*HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);*/ - - /*searcher_set_tokenfunc(p->engine, klass->next_token, st);*/ - searcher_set_tokenfunc(p->engine, get_token, st); + if ((priv->engine = search_info_to_searcher (priv->primary)) + || (priv->engine = search_info_to_searcher (priv->secondary))) { + searcher_set_tokenfunc(priv->engine, get_token, tokenizer); } /* else - no engine, no search active */ - HTML_TOKENIZER_CLASS (parent_class)->begin (t, content_type); + /* Chain up to parent's begin() method. */ + HTML_TOKENIZER_CLASS (parent_class)->begin (tokenizer, content_type); } -static void -e_searching_tokenizer_end (HTMLTokenizer *t) +static gchar * +searching_tokenizer_peek_token (HTMLTokenizer *tokenizer) { - /* so end gets called before any get/next tokens. - I dont get it. */ -#if 0 - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t); - struct _ESearchingTokenizerPrivate *p = st->priv; - - /* not sure if we should reset search every time ... *shrug* */ - if (p->engine) { - searcher_free(p->engine); - p->engine = NULL; - } -#endif + ESearchingTokenizerPrivate *priv; - HTML_TOKENIZER_CLASS (parent_class)->end (t); -} + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); -static char * -e_searching_tokenizer_peek_token (HTMLTokenizer *tok) -{ - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + if (priv->engine != NULL) + return searcher_peek_token (priv->engine); - /* If no search is active, just use the default method. */ - if (st->priv->engine == NULL) - return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tok); - - return searcher_peek_token(st->priv->engine); + /* Chain up to parent's peek_token() method. */ + return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tokenizer); } -static char * -e_searching_tokenizer_next_token (HTMLTokenizer *tok) +static gchar * +searching_tokenizer_next_token (HTMLTokenizer *tokenizer) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + ESearchingTokenizerPrivate *priv; int oldmatched; char *token; + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); + /* If no search is active, just use the default method. */ - if (st->priv->engine == NULL) - return HTML_TOKENIZER_CLASS (parent_class)->next_token (tok); + if (priv->engine == NULL) + return HTML_TOKENIZER_CLASS (parent_class)->next_token (tokenizer); - oldmatched = st->priv->engine->matchcount; + oldmatched = priv->engine->matchcount; - token = searcher_next_token(st->priv->engine); + token = searcher_next_token (priv->engine); /* not sure if this has to be accurate or just say we had some matches */ - if (oldmatched != st->priv->engine->matchcount) - g_signal_emit (st, signals[MATCH_SIGNAL], 0); + if (oldmatched != priv->engine->matchcount) + g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0); return token; } static gboolean -e_searching_tokenizer_has_more (HTMLTokenizer *tok) +searching_tokenizer_has_more (HTMLTokenizer *tokenizer) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + ESearchingTokenizerPrivate *priv; + + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); - return (st->priv->engine != NULL && searcher_pending(st->priv->engine)) - || HTML_TOKENIZER_CLASS (parent_class)->has_more (tok); + return (priv->engine != NULL && searcher_pending (priv->engine)) || + HTML_TOKENIZER_CLASS (parent_class)->has_more (tokenizer); } -/* proxy matched event, not sure what its for otherwise */ +static HTMLTokenizer * +searching_tokenizer_clone (HTMLTokenizer *tokenizer) +{ + ESearchingTokenizer *orig_st; + ESearchingTokenizer *new_st; + + orig_st = E_SEARCHING_TOKENIZER (tokenizer); + new_st = e_searching_tokenizer_new (); + + search_info_free (new_st->priv->primary); + search_info_free (new_st->priv->secondary); + + new_st->priv->primary = search_info_clone (orig_st->priv->primary); + new_st->priv->secondary = search_info_clone (orig_st->priv->secondary); + + g_signal_connect_swapped ( + new_st, "match", G_CALLBACK (matched), orig_st); + + return HTML_TOKENIZER (new_st); +} static void -matched (ESearchingTokenizer *st) +searching_tokenizer_class_init (ESearchingTokenizerClass *class) { - /*++st->priv->match_count;*/ - g_signal_emit (st, signals[MATCH_SIGNAL], 0); + GObjectClass *object_class; + HTMLTokenizerClass *tokenizer_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESearchingTokenizerPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = searching_tokenizer_finalize; + + tokenizer_class = HTML_TOKENIZER_CLASS (class); + tokenizer_class->begin = searching_tokenizer_begin; + tokenizer_class->peek_token = searching_tokenizer_peek_token; + tokenizer_class->next_token = searching_tokenizer_next_token; + tokenizer_class->has_more = searching_tokenizer_has_more; + tokenizer_class->clone = searching_tokenizer_clone; + + signals[MATCH_SIGNAL] = g_signal_new ( + "match", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ESearchingTokenizerClass, match), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } -static HTMLTokenizer * -e_searching_tokenizer_clone (HTMLTokenizer *tok) +static void +searching_tokenizer_init (ESearchingTokenizer *tokenizer) { - ESearchingTokenizer *orig_st = E_SEARCHING_TOKENIZER (tok); - ESearchingTokenizer *new_st = E_SEARCHING_TOKENIZER (e_searching_tokenizer_new ()); + tokenizer->priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); + + tokenizer->priv->primary = search_info_new (); + search_info_set_flags ( + tokenizer->priv->primary, + SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD); + search_info_set_color (tokenizer->priv->primary, "red"); + + tokenizer->priv->secondary = search_info_new (); + search_info_set_flags( + tokenizer->priv->secondary, + SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD); + search_info_set_color (tokenizer->priv->secondary, "purple"); +} - search_info_free(new_st->priv->primary); - search_info_free(new_st->priv->secondary); +GType +e_searching_tokenizer_get_type (void) +{ + static GType type = 0; - new_st->priv->primary = search_info_clone(orig_st->priv->primary); - new_st->priv->secondary = search_info_clone(orig_st->priv->secondary); + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESearchingTokenizerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) searching_tokenizer_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESearchingTokenizer), + 0, /* n_preallocs */ + (GInstanceInitFunc) searching_tokenizer_init, + NULL /* value_table */ + }; - /* what the fucking what???? */ -#if 0 - shared_state_ref (orig_st->priv->shared); - shared_state_unref (new_st->priv->shared); - new_st->priv->shared = orig_st->priv->shared; -#endif + type = g_type_register_static ( + HTML_TYPE_TOKENIZER, "ESearchingTokenizer", + &type_info, 0); + } - g_signal_connect_swapped (new_st, "match", G_CALLBACK(matched), orig_st); + return type; +} - return HTML_TOKENIZER (new_st); +ESearchingTokenizer * +e_searching_tokenizer_new (void) +{ + return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL); } -/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ void -e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *tokenizer, + const gchar *primary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_clear(st->priv->primary); - search_info_add_string(st->priv->primary, search_str); + search_info_clear (tokenizer->priv->primary); + search_info_add_string (tokenizer->priv->primary, primary_string); } void -e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *tokenizer, + const gchar *primary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_add_string(st->priv->primary, search_str); + search_info_add_string (tokenizer->priv->primary, primary_string); } void -e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase) +e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *tokenizer, + gboolean case_sensitive) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_set_flags(st->priv->primary, iscase?SEARCH_CASE:0, SEARCH_CASE); + search_info_set_flags ( + tokenizer->priv->primary, + case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE); } void -e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *tokenizer, + const gchar *secondary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_clear(st->priv->secondary); - search_info_add_string(st->priv->secondary, search_str); + search_info_clear (tokenizer->priv->secondary); + search_info_add_string (tokenizer->priv->secondary, secondary_string); } void -e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *tokenizer, + const gchar *secondary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_add_string(st->priv->secondary, search_str); + search_info_add_string (tokenizer->priv->secondary, secondary_string); } void -e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase) +e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *tokenizer, + gboolean case_sensitive) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_set_flags(st->priv->secondary, iscase?SEARCH_CASE:0, SEARCH_CASE); + search_info_set_flags ( + tokenizer->priv->secondary, + case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE); } /* Note: only returns the primary search string count */ gint -e_searching_tokenizer_match_count (ESearchingTokenizer *st) +e_searching_tokenizer_match_count (ESearchingTokenizer *tokenizer) { - g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (st), -1); + g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer), -1); - if (st->priv->engine && st->priv->primary->strv->len) - return st->priv->engine->matchcount; + if (tokenizer->priv->engine && tokenizer->priv->primary->strv->len) + return tokenizer->priv->engine->matchcount; return 0; } diff --git a/mail/e-searching-tokenizer.h b/mail/e-searching-tokenizer.h index ecc914dab7..7bab007a9f 100644 --- a/mail/e-searching-tokenizer.h +++ b/mail/e-searching-tokenizer.h @@ -21,50 +21,72 @@ * */ -#ifndef __E_SEARCHING_TOKENIZER_H__ -#define __E_SEARCHING_TOKENIZER_H__ +#ifndef E_SEARCHING_TOKENIZER_H +#define E_SEARCHING_TOKENIZER_H #include <glib.h> #include <gtkhtml/htmltokenizer.h> -#define E_TYPE_SEARCHING_TOKENIZER (e_searching_tokenizer_get_type ()) -#define E_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer)) -#define E_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass)) -#define E_IS_SEARCHING_TOKENIZER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_SEARCHING_TOKENIZER)) -#define E_IS_SEARCHING_TOKENIZER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_SEARCHING_TOKENIZER)) +/* Standard GObject macros */ +#define E_TYPE_SEARCHING_TOKENIZER \ + (e_searching_tokenizer_get_type ()) +#define E_SEARCHING_TOKENIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizer)) +#define E_SEARCHING_TOKENIZER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass)) +#define E_IS_SEARCHING_TOKENIZER(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SEARCHING_TOKENIZER)) +#define E_IS_SEARCHING_TOKENIZER_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SEARCHING_TOKENIZER)) +#define E_SEARCH_TOKENIZER_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerClass)) + +G_BEGIN_DECLS typedef struct _ESearchingTokenizer ESearchingTokenizer; typedef struct _ESearchingTokenizerClass ESearchingTokenizerClass; - -struct _ESearchingTokenizerPrivate; +typedef struct _ESearchingTokenizerPrivate ESearchingTokenizerPrivate; struct _ESearchingTokenizer { HTMLTokenizer parent; - - struct _ESearchingTokenizerPrivate *priv; + ESearchingTokenizerPrivate *priv; }; struct _ESearchingTokenizerClass { HTMLTokenizerClass parent_class; - void (*match) (ESearchingTokenizer *); + void (*match) (ESearchingTokenizer *tokenizer); }; -GType e_searching_tokenizer_get_type (void); - -HTMLTokenizer *e_searching_tokenizer_new (void); - -/* For now, just a simple API */ - -void e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *, const char *); -void e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *, const char *); -void e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive); - -void e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *, const char *); -void e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const char *search_str); -void e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *, gboolean is_case_sensitive); - - -int e_searching_tokenizer_match_count (ESearchingTokenizer *); - -#endif /* __E_SEARCHING_TOKENIZER_H__ */ +GType e_searching_tokenizer_get_type (void); +ESearchingTokenizer * + e_searching_tokenizer_new (void); +void e_searching_tokenizer_set_primary_search_string + (ESearchingTokenizer *tokenizer, + const gchar *primary_string); +void e_searching_tokenizer_add_primary_search_string + (ESearchingTokenizer *tokenizer, + const gchar *primary_string); +void e_searching_tokenizer_set_primary_case_sensitivity + (ESearchingTokenizer *tokenizer, + gboolean case_sensitive); +void e_searching_tokenizer_set_secondary_search_string + (ESearchingTokenizer *tokenizer, + const gchar *secondary_string); +void e_searching_tokenizer_add_secondary_search_string + (ESearchingTokenizer *tokenizer, + const gchar *secondary_string); +void e_searching_tokenizer_set_secondary_case_sensitivity + (ESearchingTokenizer *tokenizer, + gboolean case_sensitive); +gint e_searching_tokenizer_match_count + (ESearchingTokenizer *tokenizer); + +G_END_DECLS + +#endif /* E_SEARCHING_TOKENIZER_H */ diff --git a/mail/em-folder-browser.c b/mail/em-folder-browser.c index 572b51239b..97945cad56 100644 --- a/mail/em-folder-browser.c +++ b/mail/em-folder-browser.c @@ -58,13 +58,6 @@ #include <camel/camel-vee-store.h> #include <camel/camel-operation.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-generic-factory.h> -#include <bonobo/bonobo-control.h> -#include <bonobo/bonobo-ui-component.h> -#include <bonobo/bonobo-ui-util.h> - /* for efilterbar stuff */ #include <libedataserver/e-sexp.h> #include "mail-vfolder.h" @@ -485,146 +478,6 @@ emfb_search_menu_activated(ESearchBar *esb, int id, EMFolderBrowser *emfb) } } -//static void -//emfb_search_config_search(EFilterBar *efb, FilterRule *rule, int id, const char *query, void *data) -//{ -// EMFolderBrowser *emfb = data; -// GList *partl; -// struct _camel_search_words *words; -// int i; -// GSList *strings = NULL; -// -// /* we scan the parts of a rule, and set all the types we know about to the query string */ -// partl = rule->parts; -// while (partl) { -// FilterPart *part = partl->data; -// -// if (!strcmp(part->name, "subject")) { -// FilterInput *input = (FilterInput *)filter_part_find_element(part, "subject"); -// if (input) -// filter_input_set_value(input, query); -// } else if (!strcmp(part->name, "body")) { -// FilterInput *input = (FilterInput *)filter_part_find_element(part, "word"); -// if (input) -// filter_input_set_value(input, query); -// -// words = camel_search_words_split((unsigned char *)query); -// for (i=0;i<words->len;i++) -// strings = g_slist_prepend(strings, g_strdup(words->words[i]->word)); -// camel_search_words_free (words); -// } else if(!strcmp(part->name, "sender")) { -// FilterInput *input = (FilterInput *)filter_part_find_element(part, "sender"); -// if (input) -// filter_input_set_value(input, query); -// } else if(!strcmp(part->name, "to")) { -// FilterInput *input = (FilterInput *)filter_part_find_element(part, "recipient"); -// if (input) -// filter_input_set_value(input, query); -// } -// -// partl = partl->next; -// } -// -// em_format_html_display_set_search(emfb->view.preview, -// EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY|EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE, -// strings); -// while (strings) { -// GSList *n = strings->next; -// g_free(strings->data); -// g_slist_free_1(strings); -// strings = n; -// } -//} - -//static char * -//get_view_query (ESearchBar *esb, CamelFolder *folder, const char *folder_uri) -//{ -// char *view_sexp = NULL; -// gint id; -// GtkWidget *menu_item; -// char *tag; -// gboolean duplicate = TRUE; -// -// /* Get the current selected view */ -// id = e_search_bar_get_viewitem_id (esb); -// menu_item = e_search_bar_get_selected_viewitem (esb); -// -// switch (id & VIEW_ITEMS_MASK) { -// case VIEW_ALL_MESSAGES: -// /* one space indicates no filtering */ -// view_sexp = " "; -// break; -// -// case VIEW_UNREAD_MESSAGES: -// view_sexp = "(match-all (not (system-flag \"Seen\")))"; -// break; -// case VIEW_READ_MESSAGES: -// view_sexp = "(match-all (system-flag \"Seen\" ))"; -// break; -// case VIEW_RECENT_MESSAGES: -// if (!em_utils_folder_is_sent (folder, folder_uri)) -// view_sexp = "(match-all (> (get-received-date) (- (get-current-date) 86400)))"; -// else -// view_sexp = "(match-all (> (get-sent-date) (- (get-current-date) 86400)))"; -// break; -// case VIEW_LAST_FIVE_DAYS: -// if (!em_utils_folder_is_sent (folder, folder_uri)) -// view_sexp = " (match-all (> (get-received-date) (- (get-current-date) 432000)))"; -// else -// view_sexp = " (match-all (> (get-sent-date) (- (get-current-date) 432000)))"; -// break; -// case VIEW_WITH_ATTACHMENTS: -// view_sexp = "(match-all (system-flag \"Attachments\" ))"; -// break; -// case VIEW_NOT_JUNK: -// view_sexp = "(match-all (not (system-flag \"junk\")))"; -// break; -// case VIEW_NO_LABEL: { -// GSList *l; -// GString *s = g_string_new ("(and"); -// -// for (l = mail_config_get_labels (); l; l = l->next) { -// EUtilLabel *label = (EUtilLabel *)l->data; -// -// if (label && label->tag) { -// const gchar *tag = label->tag; -// -// if (strncmp (tag, "$Label", 6) == 0) -// tag += 6; -// -// g_string_append_printf (s, " (match-all (not (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\"))))", tag, tag, tag); -// } -// } -// -// g_string_append (s, ")"); -// -// duplicate = FALSE; -// view_sexp = g_string_free (s, FALSE); -// } break; -// case VIEW_LABEL: -// tag = (char *)g_object_get_data (G_OBJECT (menu_item), "LabelTag"); -// view_sexp = g_strdup_printf ("(match-all (or (= (user-tag \"label\") \"%s\") (user-flag \"$Label%s\") (user-flag \"%s\")))", tag, tag, tag); -// duplicate = FALSE; -// break; -// case VIEW_MESSAGES_MARKED_AS_IMPORTANT: -// view_sexp = "(match-all (system-flag \"Flagged\" ))"; -// break; -// case VIEW_ANY_FIELD_CONTAINS: -// break; -// -// case VIEW_CUSTOMIZE: -// /* one space indicates no filtering, so here use two */ -// view_sexp = " "; -// break; -// } -// -// if (duplicate) -// view_sexp = g_strdup (view_sexp); -// -// return view_sexp; -//} - - struct _setup_msg { MailMsg base; @@ -1081,125 +934,6 @@ emfb_hide_deleted(BonoboUIComponent *uic, const char *path, Bonobo_UIComponent_E em_folder_view_set_hide_deleted(emfv, state[0] != '0'); } -//static void -//emfb_list_scrolled (MessageList *ml, EMFolderBrowser *emfb) -//{ -// EMFolderView *emfv = (EMFolderView *) emfb; -// double position; -// char *state; -// -// position = message_list_get_scrollbar_position (ml); -// state = g_strdup_printf ("%f", position); -// -// if (camel_object_meta_set (emfv->folder, "evolution:list_scroll_position", state)) -// camel_object_state_write (emfv->folder); -// -// g_free (state); -//} - -//static gboolean -//scroll_idle_cb (EMFolderBrowser *emfb) -//{ -// EMFolderView *emfv = (EMFolderView *) emfb; -// double position; -// char *state; -// -// if ((state = camel_object_meta_get (emfv->folder, "evolution:list_scroll_position"))) { -// position = strtod (state, NULL); -// g_free (state); -// } else { -// position = emfb->priv->default_scroll_position; -// } -// -// message_list_set_scrollbar_position (emfv->list, position); -// -// emfb->priv->list_scrolled_id = g_signal_connect (emfv->list, "message_list_scrolled", G_CALLBACK (emfb_list_scrolled), emfb); -// -// emfb->priv->idle_scroll_id = 0; -// -// return FALSE; -//} - -//static void -//emfb_gui_folder_changed(CamelFolder *folder, void *dummy, EMFolderBrowser *emfb) -//{ -// if (emfb->priv->select_uid) { -// CamelMessageInfo *mi; -// -// mi = camel_folder_get_message_info(emfb->view.folder, emfb->priv->select_uid); -// if (mi) { -// camel_folder_free_message_info(emfb->view.folder, mi); -// em_folder_view_set_message(&emfb->view, emfb->priv->select_uid, FALSE); -// g_free (emfb->priv->select_uid); -// emfb->priv->select_uid = NULL; -// } -// } -// -// g_object_unref(emfb); -//} - -//static void -//emfb_folder_changed(CamelFolder *folder, CamelFolderChangeInfo *changes, EMFolderBrowser *emfb) -//{ -// g_object_ref(emfb); -// mail_async_event_emit(emfb->view.async, MAIL_ASYNC_GUI, (MailAsyncFunc)emfb_gui_folder_changed, folder, NULL, emfb); -//} - -//static void -//emfb_etree_unfreeze (GtkWidget *widget, GdkEvent *event, EMFolderView *emfv) -//{ -// -// ETableItem *item = e_tree_get_item (emfv->list->tree); -// -// g_object_set_data (G_OBJECT (((GnomeCanvasItem *) item)->canvas), "freeze-cursor", 0); -//} - - -/* TODO: This should probably be handled by message-list, by storing/queueing - up the select operation if its busy rebuilding the message-list */ -//static void -//emfb_list_built (MessageList *ml, EMFolderBrowser *emfb) -//{ -// EMFolderView *emfv = (EMFolderView *) emfb; -// double position = 0.0f; -// -// g_signal_handler_disconnect (ml, emfb->priv->list_built_id); -// emfb->priv->list_built_id = 0; -// -// if (emfv->list->cursor_uid == NULL) { -// if (emfb->priv->select_uid) { -// CamelMessageInfo *mi; -// -// /* If the message isn't in the folder yet, keep select_uid around, it could be caught by -// folder_changed, at some later date */ -// mi = camel_folder_get_message_info(emfv->folder, emfb->priv->select_uid); -// if (mi) { -// camel_folder_free_message_info(emfv->folder, mi); -// em_folder_view_set_message(emfv, emfb->priv->select_uid, TRUE); -// g_free (emfb->priv->select_uid); -// emfb->priv->select_uid = NULL; -// } -// -// /* change the default to the current position */ -// position = message_list_get_scrollbar_position (ml); -// } else { -// /* NOTE: not all users want this, so we need a preference for it perhaps? see bug #52887 */ -// /* FIXME: if the 1st message in the list is unread, this will actually select the second unread msg */ -// /*message_list_select (ml, MESSAGE_LIST_SELECT_NEXT, 0, CAMEL_MESSAGE_SEEN, TRUE);*/ -// } -// } -// -// emfb->priv->default_scroll_position = position; -// -// /* FIXME: this is a gross workaround for an etable bug that I can't fix - bug #55303 */ -// /* this needs to be a lower priority than anything in e-table-item/e-canvas, since -// * e_canvas_item_region_show_relay() uses a timeout, we have to use a timeout of the -// * same interval but a lower priority. */ -// emfb->priv->idle_scroll_id = g_timeout_add_full (G_PRIORITY_LOW, 250, (GSourceFunc) scroll_idle_cb, emfb, NULL); -// /* FIXME: This is another ugly hack done to hide a bug that above hack leaves. */ -// g_signal_connect (((GtkScrolledWindow *) ml)->vscrollbar, "button-press-event", G_CALLBACK (emfb_etree_unfreeze), emfb); -//} - static void emfb_set_search_folder(EMFolderView *emfv, CamelFolder *folder, const char *uri) { diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c index 72cec78559..6710abeb98 100644 --- a/mail/em-format-html-display.c +++ b/mail/em-format-html-display.c @@ -40,7 +40,6 @@ #include <gtkhtml/gtkhtml.h> #include <gtkhtml/gtkhtml-embedded.h> -#include <gtkhtml/gtkhtml-search.h> #include <glade/glade.h> @@ -77,13 +76,11 @@ #include "e-mail-display.h" #include "em-format-html-display.h" -#include "e-searching-tokenizer.h" #include "em-icon-stream.h" #include "em-utils.h" #include "em-popup.h" #include "e-attachment.h" #include "e-attachment-bar.h" -#include "e-icon-entry.h" #ifdef G_OS_WIN32 /* Undefine the similar macro from <pthread.h>,it doesn't check if @@ -102,17 +99,6 @@ ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayPrivate)) struct _EMFormatHTMLDisplayPrivate { - /* For the interactive search dialogue */ - /* TODO: Should this be more subtle, like the mozilla one? */ - GtkHBox *search_dialog; - GtkWidget *search_entry; - GtkWidget *search_entry_box; - GtkWidget *search_matches_label; - GtkWidget *search_case_check; - char *search_text; - int search_wrap; /* are we doing a wrap search */ - gboolean search_active; /* if the search is active */ - /* for Attachment bar */ GtkWidget *attachment_bar; GtkWidget *attachment_box; @@ -461,8 +447,6 @@ efhd_finalize (GObject *object) if (priv->files != NULL) g_hash_table_destroy (priv->files); - g_free (priv->search_text); - /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -616,8 +600,10 @@ efhd_format_secure (EMFormat *emf, CamelMimePart *part, CamelCipherValidity *valid) { - EM_FORMAT_CLASS (parent_class)-> - format_secure (emf, stream, part, valid); + EMFormatClass *format_class; + + format_class = g_type_class_peek (EM_TYPE_FORMAT); + format_class->format_secure (emf, stream, part, valid); if (emf->valid == valid && (valid->encrypt.status != CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE @@ -708,10 +694,6 @@ efhd_init (EMFormatHTMLDisplay *efhd) e_mail_display_set_formatter ( E_MAIL_DISPLAY (html), EM_FORMAT_HTML (efhd)); - efhd->search_tok = - (ESearchingTokenizer *) e_searching_tokenizer_new (); - gtk_html_set_tokenizer (html, (HTMLTokenizer *) efhd->search_tok); - /* we want to convert url's etc */ EM_FORMAT_HTML (efhd)->text_html_flags |= CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS | @@ -761,318 +743,6 @@ em_format_html_display_get_bar (EMFormatHTMLDisplay *efhd) } void -em_format_html_display_set_search(EMFormatHTMLDisplay *efhd, int type, GSList *strings) -{ - switch(type&3) { - case EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY: - e_searching_tokenizer_set_primary_case_sensitivity(efhd->search_tok, (type&EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE) == 0); - e_searching_tokenizer_set_primary_search_string(efhd->search_tok, NULL); - while (strings) { - e_searching_tokenizer_add_primary_search_string(efhd->search_tok, strings->data); - strings = strings->next; - } - break; - case EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY: - default: - e_searching_tokenizer_set_secondary_case_sensitivity(efhd->search_tok, (type&EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE) == 0); - e_searching_tokenizer_set_secondary_search_string(efhd->search_tok, NULL); - while (strings) { - e_searching_tokenizer_add_secondary_search_string(efhd->search_tok, strings->data); - strings = strings->next; - } - break; - } - - d(printf("redrawing with search\n")); - em_format_redraw((EMFormat *)efhd); -} - -static void -efhd_update_matches(EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - char *str; - /* message-search popup match count string */ - char *fmt = _("Matches: %d"); - - if (p->search_dialog) { - str = alloca(strlen(fmt)+32); - sprintf(str, fmt, e_searching_tokenizer_match_count(efhd->search_tok)); - gtk_label_set_text((GtkLabel *)p->search_matches_label, str); - } - gtk_widget_show((GtkWidget *)p->search_matches_label); - -} - -static void -efhd_update_search(EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - GSList *words = NULL; - int flags = 0; - - if (!gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check)) - flags = EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE | EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY; - else - flags = EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY; - - if (p->search_text) - words = g_slist_append(words, p->search_text); - - em_format_html_display_set_search(efhd, flags, words); - g_slist_free(words); -} - -static void -efhd_search_response(GtkWidget *w, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - char *txt = g_strdup(gtk_entry_get_text((GtkEntry *)p->search_entry)); - - g_strstrip(txt); - if (p->search_text && strcmp(p->search_text, txt) == 0 && !p->search_wrap) { - gtk_html_engine_search_set_forward (((EMFormatHTML *)efhd)->html, TRUE); - if (!gtk_html_engine_search_next(((EMFormatHTML *)efhd)->html)) - p->search_wrap = TRUE; - g_free(txt); - } else { - g_free(p->search_text); - p->search_text = txt; - if (!p->search_wrap) - efhd_update_search(efhd); - p->search_wrap = FALSE; - gtk_html_engine_search(((EMFormatHTML *)efhd)->html, txt, - gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check), - TRUE, FALSE); - } -} - - -static void -efhd_search_response_back (GtkWidget *w, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - char *txt = g_strdup(gtk_entry_get_text((GtkEntry *)p->search_entry)); - - g_strstrip(txt); - if (p->search_text && strcmp(p->search_text, txt) == 0 && !p->search_wrap) { - gtk_html_engine_search_set_forward (((EMFormatHTML *)efhd)->html, FALSE); - if (!gtk_html_engine_search_next(((EMFormatHTML *)efhd)->html)) - p->search_wrap = TRUE; - g_free(txt); - } else { - g_free(p->search_text); - p->search_text = txt; - if (!p->search_wrap) - efhd_update_search(efhd); - p->search_wrap = FALSE; - gtk_html_engine_search(((EMFormatHTML *)efhd)->html, txt, - gtk_toggle_button_get_active((GtkToggleButton *)p->search_case_check), - FALSE, FALSE); - } -} - - -static void -efhd_search_destroy(GtkWidget *w, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - g_free(p->search_text); - p->search_text = NULL; - gtk_widget_hide((GtkWidget *)p->search_dialog); - em_format_html_display_set_search(efhd, EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY, NULL); - p->search_active = FALSE; -} - -static void -efhd_search_case_toggled(GtkWidget *w, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - g_free(p->search_text); - p->search_text = NULL; - efhd_search_response(w, efhd); -} - -static gboolean -efhd_key_pressed (GtkWidget *w, GdkEventKey *event, EMFormatHTMLDisplay *efhd) -{ - if (event->keyval == GDK_Escape){ - efhd_search_destroy (w, efhd); - return TRUE; - } - return FALSE; -} - -static void -clear_button_clicked_cb (GtkWidget *widget, gpointer dummy, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - gtk_entry_set_text (GTK_ENTRY (p->search_entry), ""); - - g_signal_emit_by_name (p->search_entry, "activate", efhd); -} - -/* Controlls the visibility of icon_entry's visibility */ -static void -icon_entry_changed_cb (GtkWidget *widget, GtkWidget *clear_button) -{ - const char *text = gtk_entry_get_text (GTK_ENTRY (widget)); - - if (text && *text) - gtk_widget_show (clear_button); - else - gtk_widget_hide (clear_button); -} - -GtkWidget * -em_format_html_get_search_dialog (EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - GtkWidget *hbox2, *button3, *button2, *label1; - GtkWidget *icon_entry, *clear_button; - - p->search_entry_box = gtk_hbox_new (FALSE, 0); - - label1 = gtk_label_new_with_mnemonic (_("Fin_d:")); - gtk_widget_show (label1); - gtk_box_pack_start ((GtkBox *)(p->search_entry_box), label1, FALSE, FALSE, 5); - - /* Icon entry */ - icon_entry = e_icon_entry_new (); - p->search_entry = e_icon_entry_get_entry (E_ICON_ENTRY (icon_entry)); - gtk_label_set_mnemonic_widget (GTK_LABEL (label1), p->search_entry); - gtk_widget_show (p->search_entry); -#if 0 /* KILL-BONOBO */ - clear_button = e_icon_entry_create_button ("gtk-clear"); - e_icon_entry_pack_widget (E_ICON_ENTRY (icon_entry), clear_button, FALSE); -#endif - gtk_widget_show_all (icon_entry); - gtk_widget_hide (clear_button); - - g_signal_connect (G_OBJECT (clear_button), "button-press-event", (GCallback) clear_button_clicked_cb, efhd); - g_signal_connect (G_OBJECT (p->search_entry), "changed", (GCallback) icon_entry_changed_cb, clear_button); - - gtk_box_pack_start ((GtkBox *)(p->search_entry_box), icon_entry, FALSE, FALSE, 0); -// gtk_box_pack_start ((GtkBox *)(p->search_entry_box), icon_entry, TRUE, TRUE, 0); - - hbox2 = gtk_hbox_new (FALSE, 0); - gtk_box_pack_start ((GtkBox *)(hbox2), p->search_entry_box, FALSE, FALSE, 5); -// gtk_box_pack_start ((GtkBox *)(hbox2), p->search_entry_box, TRUE, TRUE, 5); - - button3 = gtk_button_new_with_mnemonic (_("_Previous")); - gtk_button_set_image (GTK_BUTTON (button3), GTK_WIDGET(gtk_image_new_from_stock(GTK_STOCK_GO_BACK, GTK_ICON_SIZE_BUTTON))); - gtk_widget_show (button3); - gtk_box_pack_start (GTK_BOX (hbox2), button3, FALSE, FALSE, 5); - - button2 = gtk_button_new_with_mnemonic (_("_Next")); - gtk_button_set_image (GTK_BUTTON (button2), gtk_image_new_from_stock(GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_BUTTON)); - gtk_widget_show (button2); - gtk_box_pack_start (GTK_BOX (hbox2), button2, FALSE, FALSE, 5); - - p->search_case_check = gtk_check_button_new_with_mnemonic (_("M_atch case")); - gtk_widget_show (p->search_case_check); - gtk_box_pack_start (GTK_BOX (hbox2), p->search_case_check, FALSE, FALSE, 0); - - p->search_matches_label = gtk_label_new (""); - gtk_widget_show (p->search_matches_label); - gtk_box_pack_start (GTK_BOX (hbox2), p->search_matches_label, TRUE, TRUE, 0); - p->search_dialog = GTK_HBOX (hbox2); - - p->search_wrap = FALSE; - - g_signal_connect (p->search_entry, "activate", G_CALLBACK(efhd_search_response), efhd); - g_signal_connect (p->search_entry, "key-press-event", G_CALLBACK(efhd_key_pressed), efhd); - g_signal_connect (p->search_case_check, "toggled", G_CALLBACK(efhd_search_case_toggled), efhd); - g_signal_connect (button2, "clicked", G_CALLBACK(efhd_search_response), efhd); - g_signal_connect (button3, "clicked", G_CALLBACK(efhd_search_response_back), efhd); - - p->search_active = FALSE; - - efhd_update_matches(efhd); - - return (GtkWidget *)p->search_dialog; - -} - -static void -set_focus_cb (GtkWidget *window, GtkWidget *widget, EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - GtkWidget *sbar = GTK_WIDGET (p->search_dialog); - - while (widget != NULL && widget != sbar) { - widget = widget->parent; - } - - if (widget != sbar) - efhd_search_destroy(widget, efhd); -} - -/** - * em_format_html_display_search: - * @efhd: - * - * Run an interactive search dialogue. - **/ -void -em_format_html_display_search(EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - if (p->search_dialog){ - GtkWidget *toplevel; - - gtk_widget_show (GTK_WIDGET (p->search_dialog)); - gtk_widget_grab_focus (p->search_entry); - gtk_widget_show (p->search_entry_box); - - p->search_active = TRUE; - - toplevel = gtk_widget_get_toplevel (GTK_WIDGET (p->search_dialog)); - - g_signal_connect (toplevel, "set-focus", - G_CALLBACK (set_focus_cb), efhd); - } - -} -/** - * em_format_html_display_search_with: - * @efhd: - * - * Run an interactive search dialogue. - **/ -void -em_format_html_display_search_with (EMFormatHTMLDisplay *efhd, char *word) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - if (p->search_dialog){ - gtk_widget_show (GTK_WIDGET (p->search_dialog)); - p->search_active = TRUE; - - /* Set the query */ - gtk_entry_set_text (GTK_ENTRY (p->search_entry), word); - gtk_widget_hide (p->search_entry_box); - - /* Trigger the search */ - g_signal_emit_by_name (p->search_entry, "activate", efhd); - } -} - -void -em_format_html_display_search_close (EMFormatHTMLDisplay *efhd) -{ - struct _EMFormatHTMLDisplayPrivate *p = efhd->priv; - - if (p->search_dialog && p->search_active) - efhd_search_destroy(GTK_WIDGET (p->search_dialog), efhd); -} - -void em_format_html_display_cut (EMFormatHTMLDisplay *efhd) { gtk_html_cut (((EMFormatHTML *) efhd)->html); @@ -1115,9 +785,6 @@ efhd_complete(EMFormat *emf) { EMFormatHTMLDisplay *efhd = (EMFormatHTMLDisplay *)emf; - if (efhd->priv->search_dialog && efhd->priv->search_active) - efhd_update_matches(efhd); - if (efhd->priv->files) { g_hash_table_destroy (efhd->priv->files); efhd->priv->files = NULL; diff --git a/mail/em-format-html-display.h b/mail/em-format-html-display.h index a74d87207b..2577b039e7 100644 --- a/mail/em-format-html-display.h +++ b/mail/em-format-html-display.h @@ -48,11 +48,6 @@ (G_TYPE_INSTANCE_GET_CLASS \ ((obj), EM_TYPE_FORMAT_HTML_DISPLAY, EMFormatHTMLDisplayClass)) -/* Search options */ -#define EM_FORMAT_HTML_DISPLAY_SEARCH_PRIMARY (0) -#define EM_FORMAT_HTML_DISPLAY_SEARCH_SECONDARY (1) -#define EM_FORMAT_HTML_DISPLAY_SEARCH_ICASE (1 << 8) - G_BEGIN_DECLS typedef struct _EMFormatHTMLDisplay EMFormatHTMLDisplay; @@ -68,34 +63,11 @@ struct _EMFormatHTMLDisplay { struct _EMFormatHTMLDisplayClass { EMFormatHTMLClass parent_class; - - /* a link clicked normally */ - void (*link_clicked) (EMFormatHTMLDisplay *efhd, - const gchar *uri); - /* a part or a link button pressed event */ - gint (*popup_event) (EMFormatHTMLDisplay *efhd, - GdkEventButton *event, - const gchar *uri, - CamelMimePart *part); - /* the mouse is over a link */ - void (*on_url) (EMFormatHTMLDisplay *efhd, - const gchar *uri); }; GType em_format_html_display_get_type (void); EMFormatHTMLDisplay * em_format_html_display_new (void); -void em_format_html_display_set_search - (EMFormatHTMLDisplay *efhd, - int type, - GSList *strings); -void em_format_html_display_search (EMFormatHTMLDisplay *efhd); -void em_format_html_display_search_with - (EMFormatHTMLDisplay *efhd, - char *word); -void em_format_html_display_search_close - (EMFormatHTMLDisplay *efhd); -GtkWidget * em_format_html_get_search_dialog(EMFormatHTMLDisplay *efhd); void em_format_html_display_cut (EMFormatHTMLDisplay *efhd); void em_format_html_display_copy (EMFormatHTMLDisplay *efhd); void em_format_html_display_paste (EMFormatHTMLDisplay *efhd); diff --git a/mail/mail-types.h b/mail/mail-types.h deleted file mode 100644 index 1873dc8d00..0000000000 --- a/mail/mail-types.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * - * This program 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 of the License, or (at your option) version 3. - * - * 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see <http://www.gnu.org/licenses/> - * - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#ifndef MAIL_TYPES_H -#define MAIL_TYPES_H 1 - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus }*/ - - -typedef struct _FolderBrowser FolderBrowser; -typedef struct _MessageBrowser MessageBrowser; -typedef struct _SubscribeDialog SubscribeDialog; -typedef struct _MessageList MessageList; -typedef struct _MailDisplay MailDisplay; - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* MAIL_TYPES_H */ |