Re: unified diff for gnome bug 135093

Dave Malcolm <[email protected]> Mon, 06 Jun 2005 23:01:03 -0400
Newsgroups gmane.editors.conglomerate.devel
Message-ID <[email protected]>
On Mon, 2005-06-06 at 19:51 -0400, Thierry Moisan wrote:
> I put in this e-mail the unified diff resquested earlier for the backend 
> I did for the gnome bug 135093 wich needs a word count implementation. 
> It would be great if someone could test it and do a feedback on this 
> list to know if I have to change anything else.
> 
> Thierry Moisan

Thanks for doing this; sorry for not replying earlier (I've been at
GUADEC and I also moved, so life's been a bit hectic).

I went ahead and committed a fix for 135093 to CVS.

I used your patch as a basis.  I slightly changed the spacing in the
Glade file to match the rest of the dialog (and the recomendations of
the GNOME Human Interface Guidelines).  I also removed the third row
(the "is valid" line), since I'd rather see this in the "document type"
area of the dialog.  Finally, it looks like you're using a very new
version of glade (or maybe gazpacho?) and my old version of libglade
kept giving lots of annoying warnings when the file was loaded in
Conglomerate.  Thankfully these went away when I resaved the file.

The C code in your patch didn't compile, so I reworked it until it did.
I got a bit carried away, and implemented word counting "properly" using
Pango (since word-breaking for arbitrary unicode strings is a hard
problem, and Pango provides the machinery to do this fully) - so we
should now support the difficult cases where e.g. you have Japanese or
Chinese text without spaces separating the words and need to infer the
word breaks based on language analysis - in theory, anyway...

I also put in a call to "refresh_statistics" into the end_edit callback,
so the File->Properties dialog now autoupdates as you type.  Annoyingly,
there seems to be a bug with typing which we'll have to track down, I
suppose :-(

I've attached the patch I finally committed.  Many thanks for your work
on this.

Dave

_______________________________________________
Conglomerate-devel mailing list
[email protected]
http://lists.copyleft.no/mailman/listinfo/conglomerate-devel
statistics.patch (text/x-patch, 18 KB)
? mkinstalldirs
? unified-diff.diff
? doc/reference/conglomerate-undocumented.txt
? doc/reference/conglomerate-unused.txt
? glade/cong-file-properties.gladep
Index: glade/ChangeLog
===================================================================
RCS file: /cvs/gnome/conglomerate/glade/ChangeLog,v
retrieving revision 1.11
diff -u -p -r1.11 ChangeLog
--- glade/ChangeLog	23 Oct 2004 16:03:00 -0000	1.11
+++ glade/ChangeLog	7 Jun 2005 02:56:13 -0000
@@ -1,3 +1,9 @@
+2005-06-06  David Malcolm  <[email protected]>
+
+	* cong-file-properties.glade: 
+
+	Added document statistics area, based on patch by Thierry Moisan
+
 2004-10-23  David Malcolm  <[email protected]>
 
 	* cong-file-properties.glade: 
Index: glade/cong-file-properties.glade
===================================================================
RCS file: /cvs/gnome/conglomerate/glade/cong-file-properties.glade,v
retrieving revision 1.3
diff -u -p -r1.3 cong-file-properties.glade
--- glade/cong-file-properties.glade	23 Oct 2004 16:03:00 -0000	1.3
+++ glade/cong-file-properties.glade	7 Jun 2005 02:56:14 -0000
@@ -11,6 +11,11 @@
   <property name="modal">False</property>
   <property name="resizable">True</property>
   <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
   <property name="has_separator">True</property>
 
   <child internal-child="vbox">
@@ -32,6 +37,7 @@
 	      <property name="label">gtk-close</property>
 	      <property name="use_stock">True</property>
 	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
 	      <property name="response_id">-5</property>
 	      <signal name="clicked" handler="gtk_widget_destroy" object="common_dialog" last_modification_time="Mon, 23 Jun 2003 17:29:47 GMT"/>
 	    </widget>
@@ -181,7 +187,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_location">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_location</property>
+			      <property name="label" translatable="yes">label_location</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -205,7 +211,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_modified">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_modified</property>
+			      <property name="label" translatable="yes">label_modified</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -229,7 +235,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_name">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_name</property>
+			      <property name="label" translatable="yes">label_name</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -380,7 +386,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_typename">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_typename</property>
+			      <property name="label" translatable="yes">label_typename</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -404,7 +410,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_typedesc">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_typedesc</property>
+			      <property name="label" translatable="yes">label_typedesc</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_FILL</property>
@@ -459,6 +465,181 @@
 		  <property name="fill">False</property>
 		</packing>
 	      </child>
+
+	      <child>
+		<widget class="GtkFrame" id="frame_statistics">
+		  <property name="border_width">6</property>
+		  <property name="visible">True</property>
+		  <property name="label_xalign">0</property>
+		  <property name="label_yalign">0.5</property>
+		  <property name="shadow_type">GTK_SHADOW_NONE</property>
+
+		  <child>
+		    <widget class="GtkHBox" id="hbox5">
+		      <property name="visible">True</property>
+		      <property name="homogeneous">False</property>
+		      <property name="spacing">0</property>
+
+		      <child>
+			<widget class="GtkLabel" id="spacer5">
+			  <property name="visible">True</property>
+			  <property name="label" translatable="yes"></property>
+			  <property name="use_underline">False</property>
+			  <property name="use_markup">False</property>
+			  <property name="justify">GTK_JUSTIFY_LEFT</property>
+			  <property name="wrap">False</property>
+			  <property name="selectable">False</property>
+			  <property name="xalign">0.5</property>
+			  <property name="yalign">0.5</property>
+			  <property name="xpad">12</property>
+			  <property name="ypad">0</property>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">False</property>
+			  <property name="fill">False</property>
+			</packing>
+		      </child>
+
+		      <child>
+			<widget class="GtkTable" id="table5">
+			  <property name="visible">True</property>
+			  <property name="n_rows">2</property>
+			  <property name="n_columns">2</property>
+			  <property name="homogeneous">False</property>
+			  <property name="row_spacing">6</property>
+			  <property name="column_spacing">6</property>
+
+			  <child>
+			    <widget class="GtkLabel" id="label34">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Number of words :</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label35">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">Number of elements:</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">0</property>
+			      <property name="right_attach">1</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label_words">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">label_words</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">0</property>
+			      <property name="bottom_attach">1</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+
+			  <child>
+			    <widget class="GtkLabel" id="label_elements">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">label_elements</property>
+			      <property name="use_underline">False</property>
+			      <property name="use_markup">False</property>
+			      <property name="justify">GTK_JUSTIFY_LEFT</property>
+			      <property name="wrap">False</property>
+			      <property name="selectable">False</property>
+			      <property name="xalign">0</property>
+			      <property name="yalign">0.5</property>
+			      <property name="xpad">0</property>
+			      <property name="ypad">0</property>
+			    </widget>
+			    <packing>
+			      <property name="left_attach">1</property>
+			      <property name="right_attach">2</property>
+			      <property name="top_attach">1</property>
+			      <property name="bottom_attach">2</property>
+			      <property name="x_options">fill</property>
+			      <property name="y_options"></property>
+			    </packing>
+			  </child>
+			</widget>
+			<packing>
+			  <property name="padding">0</property>
+			  <property name="expand">True</property>
+			  <property name="fill">True</property>
+			</packing>
+		      </child>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="label32">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Statistics</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">True</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		    </widget>
+		    <packing>
+		      <property name="type">label_item</property>
+		    </packing>
+		  </child>
+		</widget>
+		<packing>
+		  <property name="padding">0</property>
+		  <property name="expand">True</property>
+		  <property name="fill">True</property>
+		</packing>
+	      </child>
 	    </widget>
 	    <packing>
 	      <property name="tab_expand">False</property>
@@ -610,7 +791,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_xml_version">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_xml_version</property>
+			      <property name="label" translatable="yes">label_xml_version</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -634,7 +815,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_xml_encoding">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_xml_encoding</property>
+			      <property name="label" translatable="yes">label_xml_encoding</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -658,7 +839,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_xml_standalone">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_xml_standalone</property>
+			      <property name="label" translatable="yes">label_xml_standalone</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">False</property>
 			      <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -815,7 +996,7 @@
 			      <child>
 				<widget class="GtkLabel" id="label_dtd_external_id">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="no">label_dtd_external_id</property>
+				  <property name="label" translatable="yes">label_dtd_external_id</property>
 				  <property name="use_underline">False</property>
 				  <property name="use_markup">False</property>
 				  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -839,7 +1020,7 @@
 			      <child>
 				<widget class="GtkLabel" id="label_dtd_system_id">
 				  <property name="visible">True</property>
-				  <property name="label" translatable="no">label_dtd_system_id</property>
+				  <property name="label" translatable="yes">label_dtd_system_id</property>
 				  <property name="use_underline">False</property>
 				  <property name="use_markup">False</property>
 				  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -870,7 +1051,7 @@
 			  <child>
 			    <widget class="GtkLabel" id="label_dtd_notes">
 			      <property name="visible">True</property>
-			      <property name="label" translatable="no">label_dtd_notes</property>
+			      <property name="label" translatable="yes">label_dtd_notes</property>
 			      <property name="use_underline">False</property>
 			      <property name="use_markup">True</property>
 			      <property name="justify">GTK_JUSTIFY_FILL</property>
@@ -895,6 +1076,7 @@
 			      <property name="label" translatable="yes">_Associate this DTD</property>
 			      <property name="use_underline">True</property>
 			      <property name="relief">GTK_RELIEF_NORMAL</property>
+			      <property name="focus_on_click">True</property>
 			    </widget>
 			    <packing>
 			      <property name="padding">0</property>
Index: src/ChangeLog
===================================================================
RCS file: /cvs/gnome/conglomerate/src/ChangeLog,v
retrieving revision 1.784
diff -u -p -r1.784 ChangeLog
--- src/ChangeLog	17 May 2005 04:21:44 -0000	1.784
+++ src/ChangeLog	7 Jun 2005 02:56:18 -0000
@@ -1,3 +1,9 @@
+2005-06-06  David Malcolm  <[email protected]>
+
+	* cong-file-properties.c: 
+
+	Implemented word-count routine (#135093)
+
 2005-05-17  David Malcolm  <[email protected]>
 
 	* cong-app.c: 
Index: src/cong-file-properties.c
===================================================================
RCS file: /cvs/gnome/conglomerate/src/cong-file-properties.c,v
retrieving revision 1.26
diff -u -p -r1.26 cong-file-properties.c
--- src/cong-file-properties.c	1 Apr 2005 02:46:43 -0000	1.26
+++ src/cong-file-properties.c	7 Jun 2005 02:56:18 -0000
@@ -70,6 +70,101 @@ on_doc_set_url (CongDocument *doc,
 		const gchar *new_url,
 		gpointer user_data);
 
+static guint 
+count_words (PangoLanguage *language,
+	     const gchar *text)
+{
+	int n_chars;
+	int len_bytes;
+	PangoLogAttr *log_attrs;
+	guint num_words;
+	int i;
+
+	g_return_val_if_fail (text, 0);
+
+	len_bytes = strlen (text);
+
+	n_chars = g_utf8_strlen (text, len_bytes);
+
+	log_attrs = g_new0 (PangoLogAttr, n_chars+1);
+
+	pango_get_log_attrs (text,
+			     len_bytes,
+			     -1,
+			     language,
+			     log_attrs,
+			     n_chars+1);
+
+	num_words = 0;
+
+	for (i=0;i<n_chars;i++) {
+		if (log_attrs[i].is_word_start) {
+			num_words++;
+		}
+	}
+
+	g_free (log_attrs);
+
+	return num_words;
+}
+
+typedef struct CongDocumentStatistics CongDocumentStatistics;
+struct CongDocumentStatistics
+{
+	guint num_nodes;
+	guint num_elements;
+	guint num_words;
+};
+
+gboolean
+refresh_statistics_node_cb (CongDocument *doc,
+			    CongNodePtr node,
+			    gpointer data,
+			    guint recursion_level)
+{
+	CongDocumentStatistics *stats = (CongDocumentStatistics*)data;
+	PangoLanguage* language;
+
+	stats->num_nodes++;
+
+	switch (cong_node_type (node)) {
+	default: 
+		break;
+	case CONG_NODE_TYPE_TEXT:
+		language = cong_document_get_language_for_node (doc, node);
+		stats->num_words += count_words (language, (const gchar*)node->content);
+		break;
+	case CONG_NODE_TYPE_ELEMENT:
+		stats->num_elements++;
+		break;
+	}
+
+	return FALSE;
+}
+
+static void
+refresh_statistics (CongFilePropertiesDialogDetails *dialog_details,
+		    CongDocument *doc)
+{
+	struct CongDocumentStatistics stats;
+	gchar *text;
+	
+	stats.num_nodes = 0;
+	stats.num_elements = 0;
+	stats.num_words = 0;
+	
+	cong_document_for_each_node (doc, refresh_statistics_node_cb, &stats);
+
+	text = g_strdup_printf ("%i", stats.num_words);
+	gtk_label_set_text ( GTK_LABEL (glade_xml_get_widget (dialog_details->xml,"label_words")), 
+			     text);
+	g_free (text);
+
+	text = g_strdup_printf ("%i", stats.num_elements);
+	gtk_label_set_text ( GTK_LABEL (glade_xml_get_widget (dialog_details->xml,"label_elements")), 
+			     text);
+	g_free (text);	
+}
 
 static void
 refresh_filename_and_location (CongFilePropertiesDialogDetails *dialog_details,
@@ -248,6 +343,9 @@ cong_file_properties_dialog_new (CongDoc
 
 	dialog = glade_xml_get_widget(dialog_details->xml, "common_dialog");
 
+	/* Statistics*/
+	refresh_statistics (dialog_details, doc);
+
 	/* Filename & Location: */
 	refresh_filename_and_location (dialog_details, doc);
 	
@@ -403,6 +501,9 @@ on_doc_end_edit (CongDocument *doc,
 
 	refresh_modified (dialog_details, 
 			  doc);
+
+	refresh_statistics (dialog_details,
+			    doc);
 }