? devhelp.out
? devhelp.patch
? glade.patch
? m4/intltool.m4
? misc/gedit-plugin/Makefile
? misc/gedit-plugin/Makefile.in
? misc/gedit-plugin/devhelp.gedit-plugin
? misc/gedit-plugin/devhelp/Makefile
? misc/gedit-plugin/devhelp/Makefile.in
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/devhelp/ChangeLog,v
retrieving revision 1.333
diff -u -p -r1.333 ChangeLog
--- ChangeLog	28 Apr 2006 07:50:37 -0000	1.333
+++ ChangeLog	29 Apr 2006 03:30:02 -0000
@@ -1,5 +1,18 @@
 2006-04-28  Tristan Van Berkom <tvb@gnome.org>
 
+	* src/dh-parser.c: Now append book & page indexes into the
+	  keyword list.
+
+	* src/dh-keyword-model.c: Now return hits for page and book indexes
+	  (much nicer search results over all)
+
+	* src/dh-link.c: Patch possible segfaults on comparing NULL pointers
+
+	* src/dh-search.c: Patched critical assertions in some searches
+	  (i.e. gtk_entry_set_text called with NULL).
+
+2006-04-28  Tristan Van Berkom <tvb@gnome.org>
+
 	* src/dh-main.c: Added --version option.
 
 	* src/dh-link.[ch]: Added book & page specification
Index: src/dh-keyword-model.c
===================================================================
RCS file: /cvs/gnome/devhelp/src/dh-keyword-model.c,v
retrieving revision 1.15
diff -u -p -r1.15 dh-keyword-model.c
--- src/dh-keyword-model.c	28 Apr 2006 08:06:44 -0000	1.15
+++ src/dh-keyword-model.c	29 Apr 2006 03:30:08 -0000
@@ -28,6 +28,10 @@
 struct _DhKeywordModelPriv {
 	GList *original_list;
 
+	GList *keys_list;
+	GList *book_list;
+	GList *page_list;
+
         GList *keyword_words;
 
         gint   stamp;
@@ -170,6 +174,22 @@ keyword_model_finalize (GObject *object)
 			g_list_free (model->priv->keyword_words);
 		}
 
+		if (model->priv->original_list) {
+			g_list_free (model->priv->original_list);
+		}
+
+		if (model->priv->keys_list) {
+			g_list_free (model->priv->keys_list);
+		}
+
+		if (model->priv->book_list) {
+			g_list_free (model->priv->book_list);
+		}
+
+		if (model->priv->page_list) {
+			g_list_free (model->priv->page_list);
+		}
+
                 g_free (model->priv);
                 model->priv = NULL;
         }
@@ -411,13 +431,45 @@ void
 dh_keyword_model_set_words (DhKeywordModel *model, GList *keyword_words)
 {
 	DhKeywordModelPriv *priv;
+	DhLink             *link;
+	GList              *list;
 
 	g_return_if_fail (DH_IS_KEYWORD_MODEL (model));
 
 	priv = model->priv;
 
 	g_list_free (priv->original_list);
+	g_list_free (priv->keys_list);
+	g_list_free (priv->book_list);
+	g_list_free (priv->page_list);
+
+
 	priv->original_list = g_list_copy (keyword_words);
+	priv->keys_list = priv->book_list = priv->page_list = NULL;
+
+	/* Parse it into usable lists
+	 */
+	for (list = priv->original_list; 
+	     list; list = list->next) {
+		link = list->data;
+		switch (link->type) {
+		case DH_LINK_TYPE_BOOK:
+			priv->book_list = 
+				g_list_prepend (priv->book_list, link);
+			break;
+		case DH_LINK_TYPE_PAGE:
+			priv->page_list = 
+				g_list_prepend (priv->page_list, link);
+			break;
+		case DH_LINK_TYPE_KEYWORD:
+			priv->keys_list = 
+				g_list_prepend (priv->keys_list, link);
+			break;
+		default:
+			g_assert_not_reached();
+		}
+	}
+
 }
 
 DhLink *
@@ -436,7 +488,7 @@ dh_keyword_model_filter (DhKeywordModel 
 	gboolean             found;
 	gboolean             case_sensitive;
 	gchar               *lower, *name;
-	gchar              **stringv, **searchv;
+	gchar              **stringv, **searchv, *search = NULL;
 	gchar               *book_search, *page_search;
 
 	g_return_val_if_fail (DH_IS_KEYWORD_MODEL (model), NULL);
@@ -447,7 +499,6 @@ dh_keyword_model_filter (DhKeywordModel 
 	/* here we want to change the contents of keyword_words,
 	   call update on all rows that is included in the new 
 	   list and remove on all outside it */
-	
 	old_length = g_list_length (priv->keyword_words);
 
 	if (!strcmp ("", string)) {
@@ -461,10 +512,14 @@ dh_keyword_model_filter (DhKeywordModel 
 		searchv        = stringv;
 
 		/* Search for any parameters and position search cursor
-		 * to the next element in the search string.
+		 * to the next element in the search string, also collect
+		 * a search string for exact matches.
 		 */
 		for (i = 0; stringv[i] != NULL; i++) {
 
+			if (stringv[i][0] == '\0')
+				continue;
+
 			/* Parse specifications insensitively
 			 */
 			lower = g_ascii_strdown (stringv[i], -1);
@@ -477,71 +532,132 @@ dh_keyword_model_filter (DhKeywordModel 
 			} else if (!strncmp (lower, "page:", 5)) {
 				page_search = g_strdup (stringv[i] + 5);
 				searchv++;
-			} else
-				/* No more specifications */
-				break;
-
-			g_free (lower);
-		}
+			} else {
 
-		/* determine wether or not we should search with case
-		   sensitivity, searches are case sensitive when upper
-		   case is used in the search terms, matching vim
-		   smartcase behaviour */
-		for (i = 0; searchv[i] != NULL; i++) {
-			lower = g_ascii_strdown (searchv[i], -1);
-			if (strcmp (lower, searchv[i])) {
-				case_sensitive = TRUE;
+				/* determine wether or not we should search with case
+				 * sensitivity, searches are case sensitive when upper
+				 * case is used in the search terms, matching vim
+				 * smartcase behaviour 
+				 */
+				name = g_ascii_strdown (stringv[i], -1);
+				if (strcmp (name, stringv[i])) {
+					case_sensitive = TRUE;
+				}
+				g_free (name);
+				
+				/* Accumulate our search string
+				 */
+				if (search == NULL) {
+					search = g_strdup (stringv[i]);
+				} else { 
+					name = g_strdup_printf ("%s %s", search, stringv[i]);
+					g_free (search);
+					search = name;
+				}
 			}
 			g_free (lower);
 		}
 
-		for (node = priv->original_list; 
-		     node && hits < MAX_HITS; 
-		     node = node->next) {
-
-			link = DH_LINK (node->data);
-			
-			if (book_search &&
-			    strcmp (link->book, book_search))
-				continue;
-			
-			if ((page_search && !link->page) ||
-			    (page_search && strcmp (link->page, page_search)))
-				continue;
+		/* Only return book and page matches with empty 
+		 * search strings
+		 */
+		if (search == NULL) {
 
+			if (book_search && !page_search) {
+				/* Search books first */
+				for (node = priv->book_list; 
+				     node && hits < MAX_HITS; 
+				     node = node->next) {
+					
+					link = node->data;
+					
+					if (strcmp (link->book, book_search))
+						continue;
+					
+					/* Found our book */
+					new_list = g_list_prepend (new_list, link);
+					hits++;
+					
+					exactlink = link;
 					
-			found = TRUE;
-			for (i = 0; searchv[i] != NULL; i++) {
-
-				if (!case_sensitive) {
-					name = g_ascii_strdown (link->name, -1);
-				} else {
-					name = g_strdup (link->name);
 				}
 				
-				if (!g_strrstr (name, searchv[i])) {
-					found = FALSE;
-					g_free (name);
-					break;
+				/* Currently, only searches that specify
+				 * page & book return page indexes.
+				 */
+			} else if (book_search && page_search) {
+				
+				/* Now search pages */
+				for (node = priv->page_list; 
+				     book_search && page_search && 
+					     node && hits < MAX_HITS; node = node->next) {
+					
+					link = node->data;
+					
+					if (strcmp (link->book, book_search))
+						continue;
+					if (strcmp (link->page, page_search))
+						continue;
+					
+					/* Found our page */
+					new_list  = g_list_prepend (new_list, link);
+					exactlink = link;
+					hits++;
 				}
-
-				g_free (name);
 			}
+		} else { /* if (search != NULL) */
+		
+			/* Now search keywords */
+			for (node = priv->keys_list; 
+			     node && hits < MAX_HITS; 
+			     node = node->next) {
 				
-			if (found) {
-				/* Include in the new list */
-				new_list = g_list_prepend (new_list, link);
-				hits++;
-			}
-			
-			if (strcmp (link->name, string) == 0) {
-				exactlink = link;
+				link      = DH_LINK (node->data);
+				found     = FALSE;
+				
+				if (book_search && strcmp (link->book, book_search))
+					continue;
+				if (page_search && strcmp (link->page, page_search))
+					continue;
+				
+				if (!found) {
+					found = TRUE;
+					
+					for (i = 0; searchv[i] != NULL; i++) {
+						
+						if (!case_sensitive) {
+							name = g_ascii_strdown (link->name, -1);
+						} else {
+							name = g_strdup (link->name);
+						}
+						
+						if (!g_strrstr (name, searchv[i])) {
+							found = FALSE;
+							g_free (name);
+							break;
+						}
+						g_free (name);
+					}
+				}
+				
+				if (found) {
+					/* Include in the new list */
+					new_list = g_list_prepend (new_list, link);
+					hits++;
+					
+					if (search && strcmp (link->name, search) == 0) {
+						exactlink = link;
+					}
+				}
 			}
 		}
 		
 		new_list = g_list_sort (new_list, dh_link_compare);
 		g_strfreev (stringv);
+
+		if (search) {
+			g_free (search);
+		}
 
 		if (book_search) {
 			g_free (book_search);
Index: src/dh-link.c
===================================================================
RCS file: /cvs/gnome/devhelp/src/dh-link.c,v
retrieving revision 1.5
diff -u -p -r1.5 dh-link.c
--- src/dh-link.c	28 Apr 2006 07:22:37 -0000	1.5
+++ src/dh-link.c	29 Apr 2006 03:30:08 -0000
@@ -75,7 +75,15 @@ dh_link_compare  (gconstpointer a, gcons
 
 	book_diff = strcmp (((DhLink *)a)->book, ((DhLink *)b)->book);
 	if (book_diff == 0) {
-		page_diff = strcmp (((DhLink *)a)->page, ((DhLink *)b)->page);
+
+		if (((DhLink *)a)->page == 0 &&
+		    ((DhLink *)b)->page == 0) {
+			page_diff = 0;
+		} else {
+			page_diff = 
+				(((DhLink *)a)->page && ((DhLink *)b)->page) ?
+				strcmp (((DhLink *)a)->page, ((DhLink *)b)->page) : -1;
+		}
 
 		if (page_diff == 0)
 			return strcmp (((DhLink *)a)->name, ((DhLink *)b)->name);
Index: src/dh-parser.c
===================================================================
RCS file: /cvs/gnome/devhelp/src/dh-parser.c,v
retrieving revision 1.16
diff -u -p -r1.16 dh-parser.c
--- src/dh-parser.c	28 Apr 2006 07:22:37 -0000	1.16
+++ src/dh-parser.c	29 Apr 2006 03:30:08 -0000
@@ -171,6 +171,9 @@ parser_start_node_cb (GMarkupParseContex
 		dh_link = dh_link_new (DH_LINK_TYPE_BOOK, title, name, NULL, full_link);
 		g_free (full_link);
 
+ 		*parser->keywords = g_list_prepend (*parser->keywords,
+ 						    dh_link);
+
 		parser->book_node = g_node_new (dh_link);
 		g_node_prepend (parser->book_tree, parser->book_node);
 		parser->parent = parser->book_node;
@@ -224,6 +227,9 @@ parser_start_node_cb (GMarkupParseContex
 				       page, full_link);
 		g_free (full_link);
 		g_free (page);
+
+ 		*parser->keywords = g_list_prepend (*parser->keywords,
+ 						    dh_link);
 
 		node = g_node_new (dh_link);
 		g_node_prepend (parser->parent, node);
Index: src/dh-search.c
===================================================================
RCS file: /cvs/gnome/devhelp/src/dh-search.c,v
retrieving revision 1.21
diff -u -p -r1.21 dh-search.c
--- src/dh-search.c	28 Apr 2006 08:06:44 -0000	1.21
+++ src/dh-search.c	29 Apr 2006 03:30:08 -0000
@@ -338,12 +338,15 @@ static void
 search_entry_activated_cb (GtkEntry *entry, DhSearch *search)
 {
 	DhSearchPriv *priv;
+	DhLink       *link;
 	gchar        *str;
 	
 	priv = search->priv;
 	
 	str = search_string (search);
-	dh_keyword_model_filter (priv->model, str);
+
+	link = dh_keyword_model_filter (priv->model, str);
+
 	g_free (str);
 }
 
@@ -563,6 +566,7 @@ dh_search_set_search_string (DhSearch *s
 	priv = search->priv;
 
 	if ((leftover = split = g_strsplit (str, " ", -1)) != NULL) {
+
 		for (i = 0; split[i] != NULL; i++) {
 
 			lower = g_ascii_strdown (split[i], -1);
@@ -584,10 +588,13 @@ dh_search_set_search_string (DhSearch *s
 			g_free (lower);
 		}
 
+
+		/* Collect the search string */
+		string = NULL;
 		for (i = 0; leftover[i] != NULL; i++) {
-			if (string == NULL)
+			if (string == NULL) {
 				string = g_strdup (leftover[i]);
-			else { 
+			} else { 
 				lower = g_strdup_printf ("%s %s", string, leftover[i]);
 				g_free (string);
 				string = lower;
@@ -596,14 +603,16 @@ dh_search_set_search_string (DhSearch *s
 
 		g_strfreev (split);
 		
-		gtk_entry_set_text (GTK_ENTRY (priv->entry), string);
+		gtk_entry_set_text (GTK_ENTRY (priv->entry), 
+				    string ? string : "");
 
 		if (string) {
 			g_free (string);
 		}
 
 	} else {
-		gtk_entry_set_text (GTK_ENTRY (priv->entry), str);
+		gtk_entry_set_text (GTK_ENTRY (priv->entry), 
+				    str ? str : "");
 	}
 	
 	gtk_editable_set_position (GTK_EDITABLE (priv->entry), -1);
