Hi all,

Picked up monodoc recently and noticed one cannot search within the
current page. This is quite useful when looking up APIs. In any case,
I've added a little bar (similar to epiphany's) to search within the
current tab.

Attached is a patch for mono-tools. gnome-sharp also needs to be patched
to bind the search methods in gtkhtml. Comments? Suggestion? Am I way
off here? ;)

Cheers,

Alvaro

ps. The search bar is currently disabled when using gecko renderer. I
plan on adding search to GeckoHtmlRender as well.
Index: sources/Makefile.am
===================================================================
--- sources/Makefile.am	(revision 90460)
+++ sources/Makefile.am	(working copy)
@@ -23,7 +23,9 @@
         gtkhtml-3.0.10/src/gtkhtml-embedded.c \
         gtkhtml-3.0.10/src/gtkhtml-embedded.h \
         gtkhtml-3.0.10/src/gtkhtml-stream.c \
-        gtkhtml-3.0.10/src/gtkhtml-stream.h
+        gtkhtml-3.0.10/src/gtkhtml-stream.h \
+        gtkhtml-3.0.10/src/gtkhtml-search.c \
+        gtkhtml-3.0.10/src/gtkhtml-search.h
 
 api: api-2.16
 
Index: gtkhtml/gtkhtml-api.raw
===================================================================
--- gtkhtml/gtkhtml-api.raw	(revision 90460)
+++ gtkhtml/gtkhtml-api.raw	(working copy)
@@ -856,6 +856,38 @@
       <method name="ZoomReset" cname="gtk_html_zoom_reset">
         <return-type type="void" />
       </method>
+      <method name="Search" cname="gtk_html_engine_search">
+        <return-type type="gboolean" />
+        <parameters>
+          <parameter type="const-gchar*" name="text" />
+          <parameter type="gboolean" name="case_sensitive" />
+          <parameter type="gboolean" name="forward" />
+          <parameter type="gboolean" name="regular" />
+        </parameters>
+      </method>
+      <method name="FullSearch" cname="gtk_html_isearch">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="gboolean" name="forward" />
+        </parameters>
+      </method>
+      <method name="SearchIncremental" cname="gtk_html_engine_search_incremental">
+        <return-type type="gboolean" />
+        <parameters>
+          <parameter type="const-gchar*" name="text" />
+          <parameter type="gboolean" name="forward" />
+        </parameters>
+      </method>
+     <method name="SearchNext" cname="gtk_html_engine_search_next">
+        <return-type type="void" />
+        <parameters/>
+     </method>
+     <method name="SearchSetForward" cname="gtk_html_engine_search_set_forward">
+        <return-type type="void" />
+        <parameters>
+          <parameter type="gboolean" name="forward" />
+        </parameters>
+     </method>
     </object>
     <object name="HTMLEmbedded" cname="GtkHTMLEmbedded" parent="GtkBin">
       <field name="Classid" cname="classid" type="char*" />
@@ -1030,4 +1062,4 @@
       </method>
     </struct>
   </namespace>
-</api>
\ No newline at end of file
+</api>
Index: docbrowser/GeckoHtmlRender.cs
===================================================================
--- docbrowser/GeckoHtmlRender.cs	(revision 90524)
+++ docbrowser/GeckoHtmlRender.cs	(working copy)
@@ -194,5 +194,15 @@
 		md.Destroy();
 #endif
 	}
+
+	public bool Search (string Text, bool Forward) {
+		/* TODO */
+		return false;
+	}
+
+	public void SearchNext (bool Forward) {
+		/* TODO */
+	}
+
 }
 }
Index: docbrowser/IHtmlRender.cs
===================================================================
--- docbrowser/IHtmlRender.cs	(revision 90524)
+++ docbrowser/IHtmlRender.cs	(working copy)
@@ -34,6 +34,10 @@
 	Widget HtmlPanel { get; }
 
 	void Print (string Html);
+
+	bool Search (string Text, bool Forward);
+
+	void SearchNext (bool Forward);
 }
 
 
Index: docbrowser/browser.cs
===================================================================
--- docbrowser/browser.cs	(revision 90524)
+++ docbrowser/browser.cs	(working copy)
@@ -217,6 +217,8 @@
 	// For the status bar.
 	public uint context_id;
 
+	FindToolbar find_toolbar;
+
 	// Control of Bookmark
 	struct BookLink
         {
@@ -239,6 +241,7 @@
 
 		MainWindow = (Gtk.Window) ui["window1"];
 		MainWindow.DeleteEvent += new DeleteEventHandler (delete_event_cb);
+		MainWindow.SetFocus += new SetFocusHandler (OnWindowChildFocusChange);
                 
 		MainWindow.KeyPressEvent += new KeyPressEventHandler (keypress_event_cb);
 		MainWindow.KeyReleaseEvent += new KeyReleaseEventHandler (keyrelease_event_cb);
@@ -278,7 +281,7 @@
 		tabs_nb = new Notebook(); //the Notebook that holds tabs
 		tabs_nb.Scrollable = true;
 		tabs_nb.SwitchPage += new SwitchPageHandler(ChangeTab);
-		help_container.Add(tabs_nb);
+		help_container.PackStart (tabs_nb);
 
 		if (UseGecko) {
 			// Add Menu entries for changing the font
@@ -333,11 +336,26 @@
 		bookList = new ArrayList ();
 
 		index_browser = IndexBrowser.MakeIndexBrowser (this);
-		
+		find_toolbar = new FindToolbar (this);
+
 		AddTab();
 		MainWindow.ShowAll();
+
+		// not implemented in gecko renderer yet, hiding menu items
+		if (UseGecko) {
+			ui ["find_separator"].Hide ();
+			ui ["find_text"].Hide ();
+			ui ["find_next"].Hide ();
+			ui ["find_previous"].Hide ();
+		}
+
+		find_toolbar.Hide();
 	}
 
+	public Glade.XML UiXML {
+		get { return ui; }
+	}
+
 	// Initianlizes the search index
 	void CreateSearchPanel ()
 	{
@@ -442,6 +460,8 @@
 		
 		if (tree_browser.SelectedNode != CurrentTab.CurrentNode)
 			tree_browser.ShowNode (CurrentTab.CurrentNode);
+
+		find_toolbar.Hide();
 	}
 	
 	//
@@ -1638,7 +1658,38 @@
 	{
 		CloseTab();
 	}
-	
+
+	//
+	// Invoked by main Window when focus changes amongst children
+	//
+	public void OnWindowChildFocusChange (object o, SetFocusArgs a)
+	{
+		find_toolbar.HideIfNotFocused(a.Focus);
+	}
+
+	//
+	// Invoked by Find Previous menu entry
+	//
+	void OnFindPreviousTextMenuActivate (object obj, EventArgs args)
+	{
+		find_toolbar.FindNextText (false);
+	}
+
+	//
+	// Invoked by Find Next menu entry
+	//
+	void OnFindNextTextMenuActivate (object obj, EventArgs args)
+	{
+		find_toolbar.FindNextText (true);
+	}
+
+	//
+	// Invoked by Find... menu entry
+	//
+	void OnFindTextMenuActivate (object obj, EventArgs args)
+	{
+		find_toolbar.Find ();
+	}
 }
 
 //
Index: docbrowser/browser.glade
===================================================================
--- docbrowser/browser.glade	(revision 90524)
+++ docbrowser/browser.glade	(working copy)
@@ -159,7 +159,7 @@
 	  </child>
 
 	  <child>
-	    <widget class="GtkMenuItem" id="menuitem5">
+	    <widget class="GtkMenuItem" id="edit_menu">
 	      <property name="visible">True</property>
 	      <property name="label" translatable="yes">_Edit</property>
 	      <property name="use_underline">True</property>
@@ -247,6 +247,54 @@
 		      <accelerator key="A" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 		    </widget>
 		  </child>
+
+		  <child>
+		    <widget class="GtkMenuItem" id="find_separator">
+		      <property name="visible">True</property>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkImageMenuItem" id="find_text">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Find...</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="OnFindTextMenuActivate"/>
+		      <accelerator key="F" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+
+		      <child internal-child="image">
+			<widget class="GtkImage" id="image_find">
+			  <property name="visible">True</property>
+			  <property name="stock">gtk-find</property>
+			  <property name="icon_size">1</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">0</property>
+			  <property name="ypad">0</property>
+			</widget>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkMenuItem" id="find_next">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Find Ne_xt</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="OnFindNextTextMenuActivate" last_modification_time="Tue, 08 Jul 2003 22:56:55 GMT"/>
+		      <accelerator key="G" modifiers="GDK_CONTROL_MASK" signal="activate"/>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkMenuItem" id="find_previous">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Find Pre_vious</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="OnFindPreviousTextMenuActivate" last_modification_time="Tue, 08 Jul 2003 22:56:55 GMT"/>
+		      <accelerator key="G" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK" signal="activate"/>
+		    </widget>
+		  </child>
 		</widget>
 	      </child>
 	    </widget>
@@ -810,17 +858,134 @@
 		</packing>
 	      </child>
 
-	      <child>
-		<widget class="GtkVBox" id="help_container">
-		  <property name="visible">True</property>
-		  <property name="homogeneous">False</property>
-		  <property name="spacing">0</property>
-		</widget>
-		<packing>
-		  <property name="shrink">True</property>
-		  <property name="resize">True</property>
-		</packing>
-	      </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox5">
+                    <property name="visible">True</property>
+                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                    <child>
+                      <widget class="GtkVBox" id="help_container">
+                        <property name="visible">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkHBox" id="find_container">
+                        <property name="visible">True</property>
+                        <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                        <property name="spacing">5</property>
+                        <child>
+                          <widget class="GtkLabel" id="label2">
+                            <property name="visible">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="label" translatable="yes">Find:</property>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkEntry" id="find_text_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                          </widget>
+                          <packing>
+                            <property name="position">2</property>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="find_next_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="response_id">0</property>
+                            <child>
+                              <widget class="GtkHBox" id="hbox9">
+                                <property name="visible">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <child>
+                                  <widget class="GtkImage" id="image2">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <property name="stock">gtk-go-down</property>
+                                  </widget>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label3">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <property name="label" translatable="yes">Next</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">3</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkButton" id="find_previous_button">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                            <property name="response_id">0</property>
+                            <child>
+                              <widget class="GtkHBox" id="hbox13">
+                                <property name="visible">True</property>
+                                <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                <child>
+                                  <widget class="GtkImage" id="image4">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <property name="stock">gtk-go-up</property>
+                                  </widget>
+                                </child>
+                                <child>
+                                  <widget class="GtkLabel" id="label5">
+                                    <property name="visible">True</property>
+                                    <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
+                                    <property name="label" translatable="yes">Previous</property>
+                                  </widget>
+                                  <packing>
+                                    <property name="position">1</property>
+                                  </packing>
+                                </child>
+                              </widget>
+                            </child>
+                          </widget>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">4</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="resize">True</property>
+                    <property name="shrink">True</property>
+                  </packing>
+                </child>
 	    </widget>
 	    <packing>
 	      <property name="padding">0</property>
Index: docbrowser/GtkHtmlHtmlRender.cs
===================================================================
--- docbrowser/GtkHtmlHtmlRender.cs	(revision 90524)
+++ docbrowser/GtkHtmlHtmlRender.cs	(working copy)
@@ -108,5 +108,15 @@
 
 		PrintManager.Print (Html);
 	}
+
+	public bool Search (string Text, bool Forward) {
+		return html_panel.SearchIncremental (Text, Forward);
+	}
+
+	public void SearchNext (bool Forward) {
+		html_panel.SearchSetForward (Forward);
+		html_panel.SearchNext ();
+	}
+
 }
 }
Index: docbrowser/FindToolbar.cs
===================================================================
--- docbrowser/FindToolbar.cs	(revision 0)
+++ docbrowser/FindToolbar.cs	(revision 0)
@@ -0,0 +1,98 @@
+//
+// FindToolbar.cs: Finds text in current html tab
+//
+// Author: Alvaro Ramirez
+// Author:	Alvaro Ramirez <[EMAIL PROTECTED]>
+//
+
+using Gtk;
+using Glade;
+using System;
+
+namespace Monodoc {
+
+	public class FindToolbar {
+
+		Browser doc_browser;
+
+		HBox find_container;
+		Entry find_text_entry;
+		Button find_next_button;
+
+		public FindToolbar (Browser docBrowser)
+		{
+			doc_browser = docBrowser;
+			find_container = (HBox) doc_browser.UiXML ["find_container"];
+			find_text_entry = (Entry) doc_browser.UiXML ["find_text_entry"];
+			find_next_button = (Button) doc_browser.UiXML ["find_next_button"];
+
+			Button find_previous_button = (Button) doc_browser.UiXML ["find_previous_button"];
+
+			find_next_button.Clicked += new EventHandler (OnFindNextButtonClicked);
+			find_previous_button.Clicked += new EventHandler (OnFindPreviousButtonClicked);
+			find_text_entry.Activated += new EventHandler (OnFindEntryActivate);
+			find_text_entry.Changed += new EventHandler (OnFindTextChanged);
+		}
+
+		public void Hide()
+		{
+			find_container.Hide();
+		}
+
+		public void Find()
+		{
+			find_container.Show();
+			find_text_entry.SelectRegion (0, find_text_entry.Text.Length);
+			find_text_entry.GrabFocus ();
+			if (find_text_entry.Text.Length > 0)
+				doc_browser.CurrentTab.html.Search (find_text_entry.Text, true);
+		}
+
+		public void FindNextText (bool goForward)
+		{
+			find_text_entry.SelectRegion (0, find_text_entry.Text.Length);
+			find_text_entry.GrabFocus ();
+
+			if (!find_container.Visible) {
+				doc_browser.CurrentTab.html.Search (find_text_entry.Text, goForward);
+				find_container.Show();
+			}
+			else {
+				doc_browser.CurrentTab.html.SearchNext (goForward);
+			}
+		}
+
+		public void HideIfNotFocused (Widget widgetFocused)
+		{
+			Gtk.Widget widget = widgetFocused;
+
+			while (widget != null && widget != find_container) {
+				widget = widget.Parent;
+			}
+
+			if (widget != find_container) {
+				find_container.Hide ();
+			}
+		}
+
+		private void OnFindNextButtonClicked (object sender, EventArgs a)
+		{
+			doc_browser.CurrentTab.html.SearchNext (true);
+		}
+
+		private void OnFindPreviousButtonClicked (object sender, EventArgs a)
+		{
+			doc_browser.CurrentTab.html.SearchNext (false);
+		}
+
+		private void OnFindEntryActivate (object sender, EventArgs a)
+		{
+			find_next_button.Click ();
+		}
+
+		private void OnFindTextChanged (object sender, EventArgs a)
+		{
+			doc_browser.CurrentTab.html.Search (find_text_entry.Text, true);
+		}
+	}
+}
\ No newline at end of file
Index: docbrowser/Makefile.am
===================================================================
--- docbrowser/Makefile.am	(revision 90524)
+++ docbrowser/Makefile.am	(working copy)
@@ -27,7 +27,8 @@
 	$(srcdir)/XmlNodeWriter.cs	\
 	$(srcdir)/IHtmlRender.cs	\
 	$(srcdir)/BookmarkManager.cs	\
-	$(srcdir)/ProgressPanel.cs
+	$(srcdir)/ProgressPanel.cs	\
+	$(srcdir)/FindToolbar.cs
 
 browser_built_sources = AssemblyInfo.cs
 
_______________________________________________
Gtk-sharp-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list

Reply via email to