Yelp Lovin'
- From: Shaun McCance <shaunm gmail com>
- To: gnome-doc-devel-list gnome org
- Subject: Yelp Lovin'
- Date: Mon, 11 Jul 2005 02:09:06 -0500
Attached is a patch I got from the venerable Chris Lahey.
It implements search using Beagle, printing, and some weird
collapsing TOC thing I haven't played with yet.
It's been sitting in my Inbox for over a week now. You guys
should play with it, then get back to me with three seperate
patches that I can review individually.
If it happens REAL soon, one or more of these might have a
chance of making it in before feature freeze.
--
Shaun
? docbookx.dtd
? examples.html
? test-mozembed
? test-mozembed.cpp
? yelp-libxslt.patch
? yelp-updates.patch
? yelp.patch
? data/ui/yelp.gladep
? src/yelp-toc.c
? src/yelp-toc.h
Index: configure.in
===================================================================
RCS file: /cvs/gnome/yelp/configure.in,v
retrieving revision 1.183
diff -u -p -r1.183 configure.in
--- configure.in 16 May 2005 21:02:32 -0000 1.183
+++ configure.in 6 Jul 2005 19:30:56 -0000
@@ -63,6 +63,8 @@ PKG_CHECK_MODULES(YELP,
libxml-2.0 >= 2.6.5
libxslt >= 1.1.4
libexslt >= 0.8.1
+ libgnome-menu >= 2.11.1
+ libbeagle-0.0 >= 0.2
])
AC_SUBST([YELP_CFLAGS])
AC_SUBST([YELP_LIBS])
Index: data/yelp.js
===================================================================
RCS file: /cvs/gnome/yelp/data/yelp.js,v
retrieving revision 1.2
diff -u -p -r1.2 yelp.js
--- data/yelp.js 9 May 2005 23:40:59 -0000 1.2
+++ data/yelp.js 6 Jul 2005 19:30:56 -0000
@@ -87,3 +87,72 @@ window.addEventListener("load",slt.init,
window.addEventListener("DOMContentLoaded",slt.init,false);
window.addEventListener("resize",slt.init,false);
+function createCookie(name,value,days)
+{
+ if (days)
+ {
+ var date = new Date();
+ date.setTime(date.getTime()+(days*24*60*60*1000));
+ var expires = "; expires="+date.toGMTString();
+ }
+ else var expires = "";
+ document.cookie = name+"="+value+expires+"; path=/";
+}
+
+function readCookie(name)
+{
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(';');
+ for(var i=0;i < ca.length;i++)
+ {
+ var c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
+ }
+ return null;
+}
+
+function eraseCookie(name)
+{
+ createCookie(name,"",-1);
+}
+
+function endsWith (haystack, needle)
+{
+ if (haystack.substring (haystack.length - needle.length, haystack.length) == needle)
+ return true;
+ else
+ return false;
+}
+
+function load_hidden ()
+{
+ var ca = document.cookie.split(';');
+ for (var i=0; i < ca.length; i++) {
+ var c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf('display:') == 0) {
+ var colon = c.indexOf(':');
+ var equal = c.indexOf('=');
+
+ var id = c.substring (colon + 1, equal);
+ var value = c.substring (equal + 1);
+
+ document.getElementById (id).style.display = value;
+ }
+ }
+}
+
+function show_hide (id)
+{
+ var element = document.getElementById (id + '-children');
+ if (element.style.display == "none") {
+ element.style.display = "block";
+ createCookie ('display:' + id + '-children', "block", 1000);
+ } else {
+ element.style.display = "none";
+ createCookie ('display:' + id + '-children', "none", 1000);
+ }
+}
+
+window.addEventListener("DOMContentLoaded",load_hidden,false);
Index: data/ui/yelp-ui.xml
===================================================================
RCS file: /cvs/gnome/yelp/data/ui/yelp-ui.xml,v
retrieving revision 1.8
diff -u -p -r1.8 yelp-ui.xml
--- data/ui/yelp-ui.xml 2 Jan 2005 13:14:10 -0000 1.8
+++ data/ui/yelp-ui.xml 6 Jul 2005 19:30:56 -0000
@@ -6,6 +6,9 @@
<separator/>
<menuitem action="AboutDocument"/>
<separator/>
+ <menuitem action="PrintPage"/>
+ <menuitem action="PrintDocument"/>
+ <separator/>
<menuitem action="CloseWindow"/>
</menu>
<menu action="EditMenu">
@@ -42,6 +45,8 @@
<toolitem action="GoForward"/>
<separator/>
<toolitem action="GoHome"/>
+ <separator/>
+ <toolitem action="Search"/>
</toolbar>
<popup>
<menuitem action="OpenLink"/>
Index: data/ui/yelp.glade
===================================================================
RCS file: /cvs/gnome/yelp/data/ui/yelp.glade,v
retrieving revision 1.10
diff -u -p -r1.10 yelp.glade
--- data/ui/yelp.glade 21 Jan 2005 21:45:30 -0000 1.10
+++ data/ui/yelp.glade 6 Jul 2005 19:30:56 -0000
@@ -19,6 +19,7 @@
<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="focus_on_map">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -102,6 +103,10 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -173,6 +178,10 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -200,7 +209,7 @@
<property name="visible">True</property>
<property name="xalign">0.5</property>
<property name="yalign">1</property>
- <property name="xscale">0.9</property>
+ <property name="xscale">0.899999976158</property>
<property name="yscale">0.5</property>
<property name="top_padding">0</property>
<property name="bottom_padding">0</property>
@@ -233,6 +242,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">find_entry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">3</property>
@@ -340,6 +353,7 @@
<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="focus_on_map">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -409,6 +423,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">location_entry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -461,6 +479,7 @@
<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="focus_on_map">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -521,6 +540,10 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -597,6 +620,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">variable_font</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -622,6 +649,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">fixed_font</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -706,6 +737,10 @@
<property name="yalign">0.5</property>
<property name="xpad">0</property>
<property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -779,6 +814,7 @@
<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="focus_on_map">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -837,6 +873,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">bookmarks_view</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="left_attach">0</property>
@@ -917,6 +957,9 @@
<property name="rules_hint">False</property>
<property name="reorderable">False</property>
<property name="enable_search">True</property>
+ <property name="fixed_height_mode">False</property>
+ <property name="hover_selection">False</property>
+ <property name="hover_expand">False</property>
</widget>
</child>
</widget>
@@ -952,6 +995,7 @@
<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="focus_on_map">True</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
@@ -1033,6 +1077,10 @@
<property name="xpad">0</property>
<property name="ypad">0</property>
<property name="mnemonic_widget">bookmark_title_entry</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
</widget>
<packing>
<property name="padding">0</property>
@@ -1061,6 +1109,248 @@
</packing>
</child>
</widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+</widget>
+
+<widget class="GtkDialog" id="print_dialog">
+ <property name="visible">True</property>
+ <property name="title" translatable="yes">Print</property>
+ <property name="type">GTK_WINDOW_TOPLEVEL</property>
+ <property name="window_position">GTK_WIN_POS_NONE</property>
+ <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="focus_on_map">True</property>
+ <property name="has_separator">True</property>
+
+ <child internal-child="vbox">
+ <widget class="GtkVBox" id="dialog-vbox10">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child internal-child="action_area">
+ <widget class="GtkHButtonBox" id="dialog-action_area10">
+ <property name="visible">True</property>
+ <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+ <child>
+ <widget class="GtkButton" id="button2">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="label">gtk-cancel</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">-6</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkButton" id="button3">
+ <property name="visible">True</property>
+ <property name="can_default">True</property>
+ <property name="has_default">True</property>
+ <property name="can_focus">True</property>
+ <property name="has_focus">True</property>
+ <property name="label">gtk-print</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">0</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="pack_type">GTK_PACK_END</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkVBox" id="vbox135">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">0</property>
+
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton_page">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">True</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment15">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox91">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image8">
+ <property name="visible">True</property>
+ <property name="stock">gtk-file</property>
+ <property name="icon_size">4</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="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1232">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Print current pa_ge</property>
+ <property name="use_underline">True</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">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkRadioButton" id="radiobutton_document">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="relief">GTK_RELIEF_NORMAL</property>
+ <property name="focus_on_click">True</property>
+ <property name="active">False</property>
+ <property name="inconsistent">False</property>
+ <property name="draw_indicator">True</property>
+ <property name="group">radiobutton_page</property>
+
+ <child>
+ <widget class="GtkAlignment" id="alignment16">
+ <property name="visible">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xscale">0</property>
+ <property name="yscale">0</property>
+ <property name="top_padding">0</property>
+ <property name="bottom_padding">0</property>
+ <property name="left_padding">0</property>
+ <property name="right_padding">0</property>
+
+ <child>
+ <widget class="GtkHBox" id="hbox92">
+ <property name="visible">True</property>
+ <property name="homogeneous">False</property>
+ <property name="spacing">2</property>
+
+ <child>
+ <widget class="GtkImage" id="image9">
+ <property name="visible">True</property>
+ <property name="stock">gnome-stock-book-blue</property>
+ <property name="icon_size">4</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="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+
+ <child>
+ <widget class="GtkLabel" id="label1233">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Print entire _document</property>
+ <property name="use_underline">True</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">0</property>
+ <property name="ypad">0</property>
+ <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+ <property name="width_chars">-1</property>
+ <property name="single_line_mode">False</property>
+ <property name="angle">0</property>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="padding">0</property>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ </packing>
</child>
</widget>
<packing>
Index: src/Makefile.am
===================================================================
RCS file: /cvs/gnome/yelp/src/Makefile.am,v
retrieving revision 1.83
diff -u -p -r1.83 Makefile.am
--- src/Makefile.am 16 May 2005 21:02:33 -0000 1.83
+++ src/Makefile.am 6 Jul 2005 19:30:56 -0000
@@ -3,16 +3,20 @@ bin_PROGRAMS = yelp
yelp_SOURCES = \
$(gnome_yelp_idl_sources) \
Yelper.cpp Yelper.h \
+ gtkentryaction.c gtkentryaction.h \
yelp-base.c yelp-base.h \
yelp-bookmarks.c yelp-bookmarks.h \
yelp-cache.c yelp-cache.h \
yelp-db-pager.c yelp-db-pager.h \
+ yelp-db-print-pager.c yelp-db-print-pager.h \
yelp-error.c yelp-error.h \
yelp-gecko-utils.cpp yelp-gecko-utils.h \
yelp-html.cpp yelp-html.h \
yelp-io-channel.c yelp-io-channel.h \
yelp-pager.c yelp-pager.h \
+ yelp-search-pager.c yelp-search-pager.h \
yelp-settings.c yelp-settings.h \
+ yelp-toc.c yelp-toc.h \
yelp-toc-pager.c yelp-toc-pager.h \
yelp-utils.c yelp-utils.h \
yelp-window.c yelp-window.h \
@@ -101,11 +105,13 @@ test_man_parser_LDADD = $(YELP_LIBS) $(Z
test_pager_SOURCES = \
yelp-db-pager.c yelp-db-pager.h \
+ yelp-db-print-pager.c yelp-db-print-pager.h \
yelp-error.c yelp-error.h \
yelp-io-channel.c yelp-io-channel.h \
yelp-man-pager.c yelp-man-pager.h \
yelp-man-parser.c yelp-man-parser.h \
yelp-pager.c yelp-pager.h \
+ yelp-search-pager.c yelp-search-pager.h \
yelp-toc-pager.c yelp-toc-pager.h \
yelp-utils.c yelp-utils.h \
yelp-xslt-pager.c yelp-xslt-pager.h \
Index: src/gtkentryaction.c
===================================================================
RCS file: src/gtkentryaction.c
diff -N src/gtkentryaction.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/gtkentryaction.c 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2003, 2004 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: ephy-location-action.c,v 1.36 2005/02/06 14:37:12 chpe Exp $
+ */
+
+#include "config.h"
+
+#include "gtkentryaction.h"
+
+#include <gtk/gtkentry.h>
+#include <gtk/gtktoolitem.h>
+
+#define GTK_ENTRY_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), GTK_TYPE_ENTRY_ACTION, GtkEntryActionPrivate))
+
+struct _GtkEntryActionPrivate
+{
+ char *text;
+ gboolean editable;
+};
+
+static void gtk_entry_action_init (GtkEntryAction *action);
+static void gtk_entry_action_class_init (GtkEntryActionClass *class);
+static void changed_cb (GtkEntry *entry,
+ GtkEntryAction *action);
+static void sync_text (GtkAction *gaction,
+ GParamSpec *pspec,
+ GtkWidget *proxy);
+
+enum
+{
+ PROP_0,
+ PROP_TEXT,
+ PROP_EDITABLE,
+};
+
+static GObjectClass *parent_class = NULL;
+
+GType
+gtk_entry_action_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (GtkEntryActionClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gtk_entry_action_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GtkEntryAction),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) gtk_entry_action_init,
+ };
+
+ type = g_type_register_static (GTK_TYPE_ACTION,
+ "GtkEntryAction",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+static GtkWidget *
+gtk_entry_action_create_tool_item (GtkAction *action)
+{
+ GtkToolItem *tool_item;
+ GtkWidget *entry;
+
+ tool_item = gtk_tool_item_new ();
+ entry = gtk_entry_new ();
+ gtk_container_add (GTK_CONTAINER (tool_item), entry);
+ gtk_widget_show (entry);
+
+ return GTK_WIDGET (tool_item);
+}
+
+static void
+sync_text (GtkAction *gaction,
+ GParamSpec *pspec,
+ GtkWidget *proxy)
+{
+ GtkEntryAction *action = GTK_ENTRY_ACTION (gaction);
+ GtkToolItem *item = GTK_TOOL_ITEM (proxy);
+ GtkEntry *entry = GTK_ENTRY (GTK_BIN (item)->child);
+
+ g_signal_handlers_block_by_func (entry, G_CALLBACK (changed_cb), action);
+ gtk_entry_set_text (entry, action->priv->text);
+ g_signal_handlers_unblock_by_func (entry, G_CALLBACK (changed_cb), action);
+}
+
+static void
+sync_editable (GtkAction *gaction,
+ GParamSpec *pspec,
+ GtkWidget *proxy)
+{
+ GtkEntryAction *action = GTK_ENTRY_ACTION (gaction);
+ GtkToolItem *item = GTK_TOOL_ITEM (proxy);
+ GtkEntry *entry = GTK_ENTRY (GTK_BIN (item)->child);
+
+ gtk_editable_set_editable (GTK_EDITABLE (entry), action->priv->editable);
+}
+
+static void
+changed_cb (GtkEntry *entry, GtkEntryAction *action)
+{
+ const char *text;
+ GtkWidget *proxy = GTK_WIDGET (entry)->parent;
+
+ text = gtk_entry_get_text (entry);
+
+ g_signal_handlers_block_by_func (action, G_CALLBACK (sync_text), proxy);
+ gtk_entry_action_set_text (action, text);
+ g_signal_handlers_unblock_by_func (action, G_CALLBACK (sync_text), proxy);
+}
+
+static void
+connect_proxy (GtkAction *action, GtkWidget *proxy)
+{
+ if (GTK_IS_TOOL_ITEM (proxy) && GTK_IS_ENTRY (GTK_BIN (proxy)->child))
+ {
+ GtkToolItem *item = GTK_TOOL_ITEM (proxy);
+ GtkEntry *entry = GTK_ENTRY (GTK_BIN (item)->child);
+
+ sync_text (action, NULL, proxy);
+ g_signal_connect_object (action, "notify::text",
+ G_CALLBACK (sync_text), proxy, 0);
+ sync_editable (action, NULL, proxy);
+ g_signal_connect_object (action, "notify::editable",
+ G_CALLBACK (sync_editable), proxy, 0);
+
+ g_signal_connect_object (entry, "activate",
+ G_CALLBACK (gtk_action_activate), action,
+ G_CONNECT_SWAPPED);
+ g_signal_connect_object (entry, "changed",
+ G_CALLBACK (changed_cb), action, 0);
+ }
+
+ GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
+}
+
+static void
+disconnect_proxy (GtkAction *action, GtkWidget *proxy)
+{
+ GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);
+
+ if (GTK_IS_TOOL_ITEM (proxy) && GTK_IS_ENTRY (GTK_BIN (proxy)->child))
+ {
+ GtkToolItem *item = GTK_TOOL_ITEM (proxy);
+ GtkEntry *entry = GTK_ENTRY (GTK_BIN (item)->child);
+
+ g_signal_handlers_disconnect_matched (action, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, proxy);
+ g_signal_handlers_disconnect_matched (entry, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, action);
+ }
+}
+
+static void
+gtk_entry_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEntryAction *action = GTK_ENTRY_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_TEXT:
+ gtk_entry_action_set_text (action, g_value_get_string (value));
+ break;
+ case PROP_EDITABLE:
+ action->priv->editable = g_value_get_boolean (value);
+ break;
+ }
+}
+
+static void
+gtk_entry_action_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkEntryAction *action = GTK_ENTRY_ACTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_TEXT:
+ g_value_set_string (value, gtk_entry_action_get_text (action));
+ break;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, action->priv->editable);
+ break;
+ }
+}
+
+static void
+gtk_entry_action_finalize (GObject *object)
+{
+ GtkEntryAction *action = GTK_ENTRY_ACTION (object);
+ GtkEntryActionPrivate *priv = action->priv;
+
+ g_free (priv->text);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+gtk_entry_action_class_init (GtkEntryActionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkActionClass *action_class = GTK_ACTION_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = gtk_entry_action_finalize;
+ object_class->get_property = gtk_entry_action_get_property;
+ object_class->set_property = gtk_entry_action_set_property;
+
+ action_class->create_tool_item = gtk_entry_action_create_tool_item;
+ action_class->connect_proxy = connect_proxy;
+ action_class->disconnect_proxy = disconnect_proxy;
+
+ g_object_class_install_property (object_class,
+ PROP_TEXT,
+ g_param_spec_string ("text",
+ "Text",
+ "The text",
+ "",
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean ("editable",
+ "Editable",
+ "Editable",
+ TRUE,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (object_class, sizeof (GtkEntryActionPrivate));
+}
+
+static void
+gtk_entry_action_init (GtkEntryAction *action)
+{
+ action->priv = GTK_ENTRY_ACTION_GET_PRIVATE (action);
+
+ action->priv->text = g_strdup ("");
+ action->priv->editable = TRUE;
+}
+
+GtkAction *
+gtk_entry_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id)
+{
+ GtkAction *action;
+
+ action = g_object_new (GTK_TYPE_ENTRY_ACTION,
+ "name", name,
+ "label", label,
+ "tooltip", tooltip,
+ "stock_id", stock_id,
+ NULL);
+
+ return action;
+}
+
+const char *
+gtk_entry_action_get_text (GtkEntryAction *action)
+{
+ g_return_val_if_fail (GTK_IS_ENTRY_ACTION (action), "");
+
+ return action->priv->text;
+}
+
+void
+gtk_entry_action_set_text (GtkEntryAction *action,
+ const char *text)
+{
+ char *old_text;
+ g_return_if_fail (GTK_IS_ENTRY_ACTION (action));
+
+ old_text = action->priv->text;
+ action->priv->text = g_strdup (text);
+ g_free (old_text);
+ g_object_notify (G_OBJECT (action), "text");
+}
Index: src/gtkentryaction.h
===================================================================
RCS file: src/gtkentryaction.h
diff -N src/gtkentryaction.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/gtkentryaction.h 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id: ephy-location-action.h,v 1.11 2005/02/06 14:37:12 chpe Exp $
+ */
+
+#ifndef GTK_ENTRY_ACTION_H
+#define GTK_ENTRY_ACTION_H
+
+#include <gtk/gtkaction.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ENTRY_ACTION (gtk_entry_action_get_type ())
+#define GTK_ENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_ENTRY_ACTION, GtkEntryAction))
+#define GTK_ENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ENTRY_ACTION, GtkEntryActionClass))
+#define GTK_IS_ENTRY_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_ENTRY_ACTION))
+#define GTK_IS_ENTRY_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GTK_TYPE_ENTRY_ACTION))
+#define GTK_ENTRY_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_ENTRY_ACTION, GtkEntryActionClass))
+
+typedef struct _GtkEntryAction GtkEntryAction;
+typedef struct _GtkEntryActionPrivate GtkEntryActionPrivate;
+typedef struct _GtkEntryActionClass GtkEntryActionClass;
+
+struct _GtkEntryAction
+{
+ GtkAction parent;
+
+ /*< private >*/
+ GtkEntryActionPrivate *priv;
+};
+
+struct _GtkEntryActionClass
+{
+ GtkActionClass parent_class;
+};
+
+GType gtk_entry_action_get_type (void);
+
+GtkAction *gtk_entry_action_new (const gchar *name,
+ const gchar *label,
+ const gchar *tooltip,
+ const gchar *stock_id);
+
+const char *gtk_entry_action_get_text (GtkEntryAction *action);
+
+void gtk_entry_action_set_text (GtkEntryAction *action,
+ const char *text);
+
+G_END_DECLS
+
+#endif
Index: src/yelp-db-print-pager.c
===================================================================
RCS file: src/yelp-db-print-pager.c
diff -N src/yelp-db-print-pager.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/yelp-db-print-pager.c 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,298 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xinclude.h>
+#include <libxslt/xslt.h>
+#include <libxslt/templates.h>
+#include <libxslt/transform.h>
+#include <libxslt/extensions.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+
+#include "yelp-error.h"
+#include "yelp-db-print-pager.h"
+#include "yelp-toc-pager.h"
+#include "yelp-settings.h"
+
+#ifdef YELP_DEBUG
+#define d(x) x
+#else
+#define d(x)
+#endif
+
+#define STYLESHEET_PATH DATADIR"/yelp/xslt/"
+#define DB_STYLESHEET STYLESHEET_PATH"db2html.xsl"
+#define DB_TITLE STYLESHEET_PATH"db-title.xsl"
+
+#define BOOK_CHUNK_DEPTH 2
+#define ARTICLE_CHUNK_DEPTH 1
+
+#define EVENTS_PENDING while (yelp_pager_get_state (pager) <= YELP_PAGER_STATE_RUNNING && gtk_events_pending ()) gtk_main_iteration ();
+#define CANCEL_CHECK if (!main_running || yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR) goto done;
+
+extern gboolean main_running;
+
+#define YELP_DB_PRINT_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerPriv))
+
+struct _YelpDBPrintPagerPriv {
+ gchar *root_id;
+};
+
+static void db_print_pager_class_init (YelpDBPrintPagerClass *klass);
+static void db_print_pager_init (YelpDBPrintPager *pager);
+static void db_print_pager_dispose (GObject *gobject);
+
+static void db_print_pager_cancel (YelpPager *pager);
+static xmlDocPtr db_print_pager_parse (YelpPager *pager);
+static gchar ** db_print_pager_params (YelpPager *pager);
+
+static const gchar * db_print_pager_resolve_frag (YelpPager *pager,
+ const gchar *frag_id);
+static GtkTreeModel * db_print_pager_get_sections (YelpPager *pager);
+
+static YelpPagerClass *parent_class;
+
+GType
+yelp_db_print_pager_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (YelpDBPrintPagerClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) db_print_pager_class_init,
+ NULL,
+ NULL,
+ sizeof (YelpDBPrintPager),
+ 0,
+ (GInstanceInitFunc) db_print_pager_init,
+ };
+ type = g_type_register_static (YELP_TYPE_XSLT_PAGER,
+ "YelpDBPrintPager",
+ &info, 0);
+ }
+ return type;
+}
+
+static void
+db_print_pager_class_init (YelpDBPrintPagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass);
+ YelpXsltPagerClass *xslt_class = YELP_XSLT_PAGER_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ object_class->dispose = db_print_pager_dispose;
+
+ pager_class->cancel = db_print_pager_cancel;
+
+ pager_class->resolve_frag = db_print_pager_resolve_frag;
+
+ xslt_class->parse = db_print_pager_parse;
+ xslt_class->params = db_print_pager_params;
+
+ xslt_class->stylesheet = DB_STYLESHEET;
+
+ g_type_class_add_private (klass, sizeof (YelpDBPrintPagerPriv));
+}
+
+static void
+db_print_pager_init (YelpDBPrintPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+
+ pager->priv = priv = YELP_DB_PRINT_PAGER_GET_PRIVATE (pager);
+
+ pager->priv->root_id = NULL;
+}
+
+static void
+db_print_pager_dispose (GObject *object)
+{
+ YelpDBPrintPager *pager = YELP_DB_PRINT_PAGER (object);
+
+ g_free (pager->priv->root_id);
+ g_free (pager->priv);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+/******************************************************************************/
+
+YelpPager *
+yelp_db_print_pager_new (YelpDocInfo *doc_info)
+{
+ YelpDBPrintPager *pager;
+
+ g_return_val_if_fail (doc_info != NULL, NULL);
+
+ pager = (YelpDBPrintPager *) g_object_new (YELP_TYPE_DB_PRINT_PAGER,
+ "document-info", doc_info,
+ NULL);
+
+ return (YelpPager *) pager;
+}
+
+static xmlDocPtr
+db_print_pager_parse (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+ YelpDocInfo *doc_info;
+ gchar *filename = NULL;
+
+ xmlParserCtxtPtr parserCtxt = NULL;
+ xmlDocPtr doc = NULL;
+
+ xmlChar *id;
+ GError *error = NULL;
+
+ d (g_print ("db_print_pager_parse\n"));
+
+ doc_info = yelp_pager_get_doc_info (pager);
+
+ g_return_val_if_fail (pager != NULL, NULL);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL);
+ priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ g_object_ref (pager);
+
+ if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
+ goto done;
+
+ filename = yelp_doc_info_get_filename (doc_info);
+
+ parserCtxt = xmlNewParserCtxt ();
+ doc = xmlCtxtReadFile (parserCtxt,
+ (const char *) filename, NULL,
+ XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
+ XML_PARSE_NOENT | XML_PARSE_NONET );
+ if (doc == NULL) {
+ g_set_error (&error, YELP_ERROR, YELP_ERROR_NO_DOC,
+ _("The file â??%sâ?? could not be parsed. Either the file "
+ "does not exist, or it is not well-formed XML."),
+ filename);
+ yelp_pager_error (pager, error);
+ goto done;
+ }
+
+ xmlXIncludeProcessFlags (doc,
+ XML_PARSE_DTDLOAD | XML_PARSE_NOCDATA |
+ XML_PARSE_NOENT | XML_PARSE_NONET );
+
+
+ priv->root_id = g_strdup ("index");
+
+ EVENTS_PENDING;
+ CANCEL_CHECK;
+
+ done:
+ g_free (filename);
+
+ if (parserCtxt)
+ xmlFreeParserCtxt (parserCtxt);
+
+ g_object_unref (pager);
+
+ return doc;
+}
+
+static gchar **
+db_print_pager_params (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv;
+ YelpDocInfo *doc_info;
+ gchar **params;
+ gint params_i = 0;
+ gint params_max = 20;
+
+ d (g_print ("db_print_pager_process\n"));
+
+ doc_info = yelp_pager_get_doc_info (pager);
+
+ g_return_val_if_fail (pager != NULL, FALSE);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), FALSE);
+ priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ if (yelp_pager_get_state (pager) >= YELP_PAGER_STATE_ERROR)
+ return NULL;
+
+ params = g_new0 (gchar *, params_max);
+
+ yelp_settings_params (¶ms, ¶ms_i, ¶ms_max);
+
+ if ((params_i + 10) >= params_max - 1) {
+ params_max += 20;
+ params = g_renew (gchar *, params, params_max);
+ }
+ params[params_i++] = "db.chunk.extension";
+ params[params_i++] = g_strdup ("\"\"");
+ params[params_i++] = "db.chunk.info_basename";
+ params[params_i++] = g_strdup ("\"x-yelp-titlepage\"");
+ params[params_i++] = "db.chunk.max_depth";
+ params[params_i++] = g_strdup_printf ("0");
+ params[params_i++] = "yelp.javascript";
+ params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js");
+
+ params[params_i] = NULL;
+
+ return params;
+}
+
+static void
+db_print_pager_cancel (YelpPager *pager)
+{
+ YelpDBPrintPagerPriv *priv = YELP_DB_PRINT_PAGER (pager)->priv;
+
+ d (g_print ("db_print_pager_cancel\n"));
+
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID);
+
+ g_free (priv->root_id);
+ priv->root_id = NULL;
+
+ YELP_PAGER_CLASS (parent_class)->cancel (pager);
+}
+
+static const gchar *
+db_print_pager_resolve_frag (YelpPager *pager, const gchar *frag_id)
+{
+ YelpDBPrintPager *db_print_pager;
+
+ g_return_val_if_fail (pager != NULL, NULL);
+ g_return_val_if_fail (YELP_IS_DB_PRINT_PAGER (pager), NULL);
+
+ db_print_pager = YELP_DB_PRINT_PAGER (pager);
+
+ return db_print_pager->priv->root_id;
+}
+
Index: src/yelp-db-print-pager.h
===================================================================
RCS file: src/yelp-db-print-pager.h
diff -N src/yelp-db-print-pager.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/yelp-db-print-pager.h 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,55 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_DB_PRINT_PAGER_H__
+#define __YELP_DB_PRINT_PAGER_H__
+
+#include <glib-object.h>
+
+#include "yelp-pager.h"
+#include "yelp-xslt-pager.h"
+
+#define YELP_TYPE_DB_PRINT_PAGER (yelp_db_print_pager_get_type ())
+#define YELP_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPager))
+#define YELP_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass))
+#define YELP_IS_DB_PRINT_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_DB_PRINT_PAGER))
+#define YELP_IS_DB_PRINT_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_DB_PRINT_PAGER))
+#define YELP_DB_PRINT_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_DB_PRINT_PAGER, YelpDBPrintPagerClass))
+
+typedef struct _YelpDBPrintPager YelpDBPrintPager;
+typedef struct _YelpDBPrintPagerClass YelpDBPrintPagerClass;
+typedef struct _YelpDBPrintPagerPriv YelpDBPrintPagerPriv;
+
+struct _YelpDBPrintPager {
+ YelpXsltPager parent;
+
+ YelpDBPrintPagerPriv *priv;
+};
+
+struct _YelpDBPrintPagerClass {
+ YelpXsltPagerClass parent_class;
+};
+
+GType yelp_db_print_pager_get_type (void);
+YelpPager * yelp_db_print_pager_new (YelpDocInfo *doc_info);
+
+#endif /* __YELP_DB_PRINT_PAGER_H__ */
Index: src/yelp-html.cpp
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-html.cpp,v
retrieving revision 1.1
diff -u -p -r1.1 yelp-html.cpp
--- src/yelp-html.cpp 16 May 2005 21:02:33 -0000 1.1
+++ src/yelp-html.cpp 6 Jul 2005 19:30:56 -0000
@@ -34,14 +34,23 @@
#include "Yelper.h"
+#include "gtkmozembed_internal.h"
+#include "nsIWebBrowserPrint.h"
+#include "nsIInterfaceRequestorUtils.h"
+
+#include <libgnome/gnome-init.h>
+
#ifdef GNOME_ENABLE_DEBUG
#define d(x) x
#else
-#define d(x)
+#define d(x) x
#endif
#define YELP_HTML_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_HTML, YelpHtmlPriv))
+#define MOZILLA_PROFILE_DIR "/mozilla"
+#define MOZILLA_PROFILE_NAME "yelp"
+
struct _YelpHtmlPriv {
Yelper *yelper;
gchar *base_uri;
@@ -51,6 +60,7 @@ struct _YelpHtmlPriv {
static void html_set_fonts (void);
static void html_set_colors (void);
static void html_set_a11y (void);
+static void open_new_window (GtkMozEmbed **newEmbed, guint chrome_mask);
enum {
URI_SELECTED,
@@ -120,6 +130,14 @@ html_realize (GtkWidget *widget)
}
static void
+html_new_window (GtkMozEmbed *embed,
+ GtkMozEmbed **newEmbed,
+ guint chrome_mask)
+{
+ open_new_window (newEmbed, chrome_mask);
+}
+
+static void
html_init (YelpHtml *html)
{
YelpHtmlPriv *priv;
@@ -197,6 +215,7 @@ html_class_init (YelpHtmlClass *klass)
moz_embed_class->title = html_title;
moz_embed_class->dom_mouse_down = html_dom_mouse_down;
moz_embed_class->open_uri = html_open_uri;
+ moz_embed_class->new_window = html_new_window;
klass->font_handler = 0;
@@ -305,7 +324,7 @@ yelp_html_write (YelpHtml *html, const g
if (len == -1) len = strlen (data);
d (g_print ("yelp_html_write\n"));
- d (g_print (" data = %i bytes\n", strlen (data)));
+ d (g_print (" data = %*s\n", len, data));
d (g_print (" len = %i\n", len));
gtk_moz_embed_append_data (GTK_MOZ_EMBED (html),
@@ -385,6 +404,24 @@ yelp_html_select_all (YelpHtml *html)
html->priv->yelper->DoCommand ("cmd_selectAll");
}
+void
+yelp_html_print (YelpHtml *html)
+{
+ nsCOMPtr<nsIWebBrowser> webBrowser;
+
+ gtk_moz_embed_get_nsIWebBrowser (GTK_MOZ_EMBED (html), getter_AddRefs(webBrowser));
+
+ if (webBrowser) {
+
+ nsCOMPtr<nsIWebBrowserPrint> print(do_GetInterface(webBrowser));
+
+ if (print) {
+ /* FIXME: Deal with retval. */
+ print->Print (nsnull, nsnull);
+ }
+ }
+}
+
static void
html_set_fonts (void)
{
@@ -421,4 +458,123 @@ html_set_a11y (void)
caret = yelp_settings_get_caret ();
yelp_gecko_set_caret (caret);
+}
+
+static void
+new_window_orphan_cb (GtkMozEmbedSingle *moz_single,
+ GtkMozEmbed **newEmbed,
+ guint chrome_mask,
+ gpointer user_data)
+{
+ open_new_window (newEmbed, chrome_mask);
+}
+
+void
+yelp_html_initialize (void)
+{
+ static gboolean initialized = FALSE;
+ GtkMozEmbedSingle *single;
+ char *profile_path;
+
+ if (initialized)
+ return;
+ initialized = TRUE;
+
+ /* get single */
+ single = gtk_moz_embed_single_get ();
+ if (single == NULL) {
+ g_warning ("Failed to get singleton embed object!\n");
+ }
+
+ /* allow creation of orphan windows */
+ g_signal_connect (G_OBJECT (single), "new_window_orphan",
+ G_CALLBACK (new_window_orphan_cb),
+ NULL);
+
+ profile_path = g_build_filename (g_get_home_dir (),
+ GNOME_DOT_GNOME,
+ "yelp.d",
+ MOZILLA_PROFILE_DIR,
+ NULL);
+ gtk_moz_embed_set_profile_path (profile_path, MOZILLA_PROFILE_NAME);
+ g_free (profile_path);
+}
+
+static GtkMozEmbed *new_xul_dialog (void);
+
+static void
+xul_visibility_cb (GtkWidget *embed, gboolean visibility, GtkWidget *window)
+{
+ if (visibility) {
+ gtk_widget_show (window);
+ } else {
+ gtk_widget_hide (window);
+ }
+}
+
+static void
+xul_size_to_cb (GtkWidget *embed, gint width, gint height, gpointer dummy)
+{
+ gtk_widget_set_size_request (embed, width, height);
+}
+
+static void
+xul_new_window_cb (GtkMozEmbed *embed,
+ GtkMozEmbed **retval,
+ guint chrome_mask,
+ gpointer dummy)
+{
+ g_assert (chrome_mask & GTK_MOZ_EMBED_FLAG_OPENASCHROME);
+
+ *retval = new_xul_dialog ();
+}
+
+static void
+xul_title_cb (GtkMozEmbed *embed,
+ GtkWindow *window)
+{
+ char *title;
+
+ title = gtk_moz_embed_get_title (embed);
+ gtk_window_set_title (window, title);
+ g_free (title);
+}
+
+static GtkMozEmbed *
+new_xul_dialog (void)
+{
+ GtkWidget *window, *embed;
+
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ embed = gtk_moz_embed_new ();
+ gtk_widget_show (embed);
+ gtk_container_add (GTK_CONTAINER (window), embed);
+
+ g_signal_connect_object (embed, "destroy_browser",
+ G_CALLBACK (gtk_widget_destroy),
+ window, G_CONNECT_SWAPPED);
+ g_signal_connect_object (embed, "visibility",
+ G_CALLBACK (xul_visibility_cb),
+ window, (GConnectFlags) 0);
+ g_signal_connect_object (embed, "size_to",
+ G_CALLBACK (xul_size_to_cb),
+ NULL, (GConnectFlags) 0);
+ g_signal_connect_object (embed, "new_window",
+ G_CALLBACK (xul_new_window_cb),
+ NULL, (GConnectFlags) 0);
+ g_signal_connect_object (embed, "title",
+ G_CALLBACK (xul_title_cb),
+ window, (GConnectFlags) 0);
+
+ return GTK_MOZ_EMBED (embed);
+}
+
+static void
+open_new_window (GtkMozEmbed **newEmbed,
+ guint chrome_mask)
+{
+ if (chrome_mask & GTK_MOZ_EMBED_FLAG_OPENASCHROME) {
+ *newEmbed = new_xul_dialog ();
+ return;
+ }
}
Index: src/yelp-html.h
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-html.h,v
retrieving revision 1.30
diff -u -p -r1.30 yelp-html.h
--- src/yelp-html.h 16 May 2005 21:02:33 -0000 1.30
+++ src/yelp-html.h 6 Jul 2005 19:30:56 -0000
@@ -98,6 +98,10 @@ void yelp_html_copy_selection
void yelp_html_select_all (YelpHtml *html);
+void yelp_html_print (YelpHtml *html);
+
+void yelp_html_initialize (void);
+
G_END_DECLS
#endif /* __YELP_HTML_H__ */
Index: src/yelp-main.c
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-main.c,v
retrieving revision 1.38
diff -u -p -r1.38 yelp-main.c
--- src/yelp-main.c 6 Mar 2005 20:07:11 -0000 1.38
+++ src/yelp-main.c 6 Jul 2005 19:30:56 -0000
@@ -42,6 +42,8 @@
#include "GNOME_Yelp.h"
#include "yelp-window.h"
#include "yelp-base.h"
+#include "yelp-html.h"
+#include "yelp-toc.h"
#define YELP_FACTORY_OAFIID "OAFIID:GNOME_Yelp_Factory"
@@ -365,6 +367,8 @@ main (int argc, char **argv)
if (!factory) { /* Not started, start now */
BonoboGenericFactory *factory;
char *registration_id;
+
+ yelp_html_initialize ();
registration_id = bonobo_activation_make_registration_id (
YELP_FACTORY_OAFIID,
Index: src/yelp-search-pager.c
===================================================================
RCS file: src/yelp-search-pager.c
diff -N src/yelp-search-pager.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/yelp-search-pager.c 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,722 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <libgnomevfs/gnome-vfs.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+#include <libxml/xmlreader.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/HTMLtree.h>
+#include <libxml/tree.h>
+#include <libxslt/xslt.h>
+#include <libxslt/templates.h>
+#include <libxslt/transform.h>
+#include <libxslt/extensions.h>
+#include <libxslt/xsltInternals.h>
+#include <libxslt/xsltutils.h>
+
+#include <beagle/beagle.h>
+
+#include "yelp-error.h"
+#include "yelp-settings.h"
+#include "yelp-search-pager.h"
+#include "yelp-utils.h"
+
+#define DESKTOP_ENTRY_GROUP "Desktop Entry"
+#define KDE_DESKTOP_ENTRY_GROUP "KDE Desktop Entry"
+
+#ifdef YELP_DEBUG
+#define d(x) x
+#else
+#define d(x) x
+#endif
+
+#define YELP_NAMESPACE "http://www.gnome.org/yelp/ns"
+
+#define STYLESHEET_PATH DATADIR"/yelp/xslt/"
+#define SEARCH_STYLESHEET STYLESHEET_PATH"search2html.xsl"
+
+typedef gboolean (*ProcessFunction) (YelpSearchPager *pager);
+
+typedef struct _YelpListing YelpListing;
+
+#define YELP_SEARCH_PAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerPriv))
+
+struct _YelpSearchPagerPriv {
+ xmlDocPtr search_doc;
+ xmlNodePtr root;
+
+ xmlParserCtxtPtr parser;
+
+ gboolean cancel;
+
+ xsltStylesheetPtr stylesheet;
+ xsltTransformContextPtr transformContext;
+ char *search_terms;
+ gboolean hits_finished;
+ int snippet_request_count;
+};
+
+struct _YelpListing {
+ gchar *id;
+ gchar *title;
+
+ GSList *listings;
+ GSList *documents;
+
+ gboolean has_listings;
+};
+
+static void search_pager_class_init (YelpSearchPagerClass *klass);
+static void search_pager_init (YelpSearchPager *pager);
+static void search_pager_dispose (GObject *gobject);
+
+static void search_pager_error (YelpPager *pager);
+static void search_pager_cancel (YelpPager *pager);
+static void search_pager_finish (YelpPager *pager);
+
+gboolean search_pager_process (YelpPager *pager);
+void search_pager_cancel (YelpPager *pager);
+const gchar * search_pager_resolve_frag (YelpPager *pager,
+ const gchar *frag_id);
+GtkTreeModel * search_pager_get_sections (YelpPager *pager);
+
+static gboolean process_xslt (YelpSearchPager *pager);
+
+static void xslt_yelp_document (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp);
+static gboolean search_pager_process_idle (YelpSearchPager *pager);
+
+static YelpPagerClass *parent_class;
+
+static BeagleClient *beagle_client;
+
+GType
+yelp_search_pager_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof (YelpSearchPagerClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) search_pager_class_init,
+ NULL,
+ NULL,
+ sizeof (YelpSearchPager),
+ 0,
+ (GInstanceInitFunc) search_pager_init,
+ };
+ type = g_type_register_static (YELP_TYPE_PAGER,
+ "YelpSearchPager",
+ &info, 0);
+ }
+ return type;
+}
+
+static void
+search_pager_class_init (YelpSearchPagerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ YelpPagerClass *pager_class = YELP_PAGER_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ beagle_client = beagle_client_new (NULL);
+
+ object_class->dispose = search_pager_dispose;
+
+ pager_class->error = search_pager_error;
+ pager_class->cancel = search_pager_cancel;
+ pager_class->finish = search_pager_finish;
+
+ pager_class->process = search_pager_process;
+ pager_class->cancel = search_pager_cancel;
+ pager_class->resolve_frag = search_pager_resolve_frag;
+ pager_class->get_sections = search_pager_get_sections;
+
+ g_type_class_add_private (klass, sizeof (YelpSearchPagerPriv));
+}
+
+static void
+search_pager_init (YelpSearchPager *pager)
+{
+ YelpSearchPagerPriv *priv;
+
+ pager->priv = priv = YELP_SEARCH_PAGER_GET_PRIVATE (pager);
+
+ priv->parser = xmlNewParserCtxt ();
+
+ priv->cancel = 0;
+ priv->search_terms = NULL;
+ priv->hits_finished = FALSE;
+ priv->snippet_request_count = 0;
+}
+
+static void
+search_pager_dispose (GObject *object)
+{
+ YelpSearchPager *pager = YELP_SEARCH_PAGER (object);
+
+ g_free (pager->priv);
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
+/******************************************************************************/
+
+static gboolean
+check_hex (char check)
+{
+ if (check >= '0' && check <= '9')
+ return TRUE;
+ if (check >= 'a' && check <= 'f')
+ return TRUE;
+ if (check >= 'A' && check <= 'F')
+ return TRUE;
+ return FALSE;
+}
+
+static int
+conv_hex (char conv)
+{
+ if (conv >= '0' && conv <= '9')
+ return conv - '0';
+ if (conv >= 'a' && conv <= 'f')
+ return conv - 'a' + 10;
+ if (conv >= 'A' && conv <= 'F')
+ return conv - 'A' + 10;
+ return 0;
+}
+
+static char *
+decode_uri (const char *uri)
+{
+ char *decoded = g_strdup (uri);
+ char *iterator;
+
+ for (iterator = decoded; *iterator; iterator ++) {
+ if (*iterator == '%' && check_hex (iterator[1]) && check_hex(iterator[2])) {
+ *iterator = conv_hex (iterator[1]) * 16 + conv_hex (iterator[2]);
+ memmove (iterator + 1, iterator + 3, strlen (iterator + 3));
+ }
+ }
+
+ return decoded;
+}
+
+YelpSearchPager *
+yelp_search_pager_get (YelpDocInfo *doc_info)
+{
+ static GHashTable *search_hash;
+ YelpSearchPager *search_pager;
+ char *uri;
+ char *search_terms;
+
+ if (search_hash == NULL) {
+ search_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ NULL, g_object_unref);
+ }
+
+ uri = yelp_doc_info_get_uri (doc_info, NULL, YELP_URI_TYPE_SEARCH);
+ search_terms = decode_uri (uri + strlen ("x-yelp-search:"));
+ g_free (uri);
+
+ search_pager = g_hash_table_lookup (search_hash, search_terms);
+
+ if (search_pager == NULL) {
+ search_pager = (YelpSearchPager *) g_object_new (YELP_TYPE_SEARCH_PAGER,
+ "document-info", doc_info,
+ NULL);
+ search_pager->priv->search_terms = search_terms;
+ g_hash_table_insert (search_hash, search_terms, search_pager);
+ yelp_pager_start (YELP_PAGER (search_pager));
+ } else {
+ g_free (search_terms);
+ }
+
+ g_object_ref (search_pager);
+ return search_pager;
+}
+
+/******************************************************************************/
+
+static void
+search_pager_error (YelpPager *pager)
+{
+ d (g_print ("search_pager_error\n"));
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_ERROR);
+}
+
+static void
+search_pager_cancel (YelpPager *pager)
+{
+ YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv;
+
+ d (g_print ("search_pager_cancel\n"));
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_INVALID);
+
+ priv->cancel = TRUE;
+}
+
+static void
+search_pager_finish (YelpPager *pager)
+{
+ d (g_print ("search_pager_finish\n"));
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_FINISHED);
+}
+
+gboolean
+search_pager_process (YelpPager *pager)
+{
+ d (g_print ("search_pager_process\n"));
+
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_PARSING);
+ g_signal_emit_by_name (pager, "parse");
+
+ /* Set it running */
+ yelp_pager_set_state (pager, YELP_PAGER_STATE_RUNNING);
+ g_signal_emit_by_name (pager, "start");
+
+ gtk_idle_add_priority (G_PRIORITY_LOW,
+ (GtkFunction) search_pager_process_idle,
+ pager);
+ return FALSE;
+}
+
+const gchar *
+search_pager_resolve_frag (YelpPager *pager, const gchar *frag_id)
+{
+ if (!frag_id)
+ return "results";
+ else
+ return frag_id;
+}
+
+GtkTreeModel *
+search_pager_get_sections (YelpPager *pager)
+{
+ return NULL;
+}
+
+/******************************************************************************/
+
+static void
+check_finished (YelpSearchPager *pager)
+{
+ if (pager->priv->snippet_request_count == 0 && pager->priv->hits_finished) {
+ gtk_idle_add_priority (G_PRIORITY_LOW,
+ (GtkFunction) process_xslt,
+ pager);
+ }
+}
+
+typedef struct
+{
+ YelpSearchPager *pager;
+ xmlNode *node;
+} SnippetLocation;
+
+static void
+snippet_closed (BeagleSnippetRequest *request, SnippetLocation *snippet_location)
+{
+ YelpSearchPager *pager = snippet_location->pager;
+
+ g_print ("snippet_closed\n");
+
+ pager->priv->snippet_request_count --;
+ check_finished (pager);
+ g_free (snippet_location);
+ g_object_unref (request);
+}
+
+static void
+snippet_response (BeagleSnippetRequest *request, BeagleSnippetResponse *response, SnippetLocation *snippet_location)
+{
+ g_print ("snippet_response: %s\n", beagle_snippet_response_get_snippet (response));
+ xmlSetProp (snippet_location->node, "snippet", beagle_snippet_response_get_snippet (response));
+ snippet_closed (request, snippet_location);
+}
+
+static void
+snippet_error (BeagleSnippetRequest *request, GError *error, SnippetLocation *snippet_location)
+{
+ g_print ("snippet_error\n");
+ snippet_closed (request, snippet_location);
+}
+
+static void
+hits_added_cb (BeagleQuery *query, BeagleHitsAddedResponse *response, YelpSearchPager *pager)
+{
+ YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv;
+
+ GSList *hits, *l;
+ gint i;
+
+ hits = beagle_hits_added_response_get_hits (response);
+
+ for (l = hits, i = 1; l; l = l->next, ++i) {
+ BeagleHit *hit = l->data;
+ xmlNode *child;
+ char *score;
+ BeagleSnippetRequest *request;
+ SnippetLocation *snippet_location;
+
+ child = xmlNewTextChild (priv->root, NULL, "result", NULL);
+ xmlSetProp (child, "uri", beagle_hit_get_uri (hit));
+
+ score = g_strdup_printf ("%lf", beagle_hit_get_score (hit));
+ xmlSetProp (child, "score", score);
+ g_free (score);
+
+ priv->snippet_request_count ++;
+
+ snippet_location = g_new (SnippetLocation, 1);
+
+ snippet_location->pager = pager;
+ snippet_location->node = child;
+
+ request = beagle_snippet_request_new ();
+ beagle_snippet_request_set_hit (request, hit);
+ beagle_snippet_request_add_query_term (request, priv->search_terms);
+
+ g_signal_connect (request, "response",
+ G_CALLBACK (snippet_response), snippet_location);
+ g_signal_connect (request, "error",
+ G_CALLBACK (snippet_error), snippet_location);
+ g_signal_connect (request, "closed",
+ G_CALLBACK (snippet_closed), snippet_location);
+
+ beagle_client_send_request_async (beagle_client, BEAGLE_REQUEST (request),
+ NULL);
+
+ }
+}
+
+static void
+finished_cb (BeagleQuery *query,
+ BeagleFinishedResponse *response,
+ YelpSearchPager *pager)
+{
+ pager->priv->hits_finished = TRUE;
+ check_finished (pager);
+}
+
+static gboolean
+search_pager_process_idle (YelpSearchPager *pager)
+{
+ BeagleQuery *query;
+ YelpSearchPagerPriv *priv = YELP_SEARCH_PAGER (pager)->priv;
+
+ priv->search_doc = xmlNewDoc ("1.0");
+ priv->root = xmlNewNode (NULL, "search");
+ xmlSetProp (priv->root, "title", priv->search_terms);
+ xmlDocSetRootElement (priv->search_doc, priv->root);
+
+ query = beagle_query_new ();
+
+ beagle_query_add_text (query, priv->search_terms);
+ /* beagle_query_add_hit_type (query, "DocBookEntry");*/
+
+ g_signal_connect (query, "hits-added",
+ G_CALLBACK (hits_added_cb),
+ pager);
+
+ g_signal_connect (query, "finished",
+ G_CALLBACK (finished_cb),
+ pager);
+
+ beagle_client_send_request_async (beagle_client, BEAGLE_REQUEST (query),
+ NULL);
+
+ return FALSE;
+}
+
+static gboolean
+process_xslt (YelpSearchPager *pager)
+{
+ GError *error = NULL;
+ xmlDocPtr outdoc = NULL;
+ YelpSearchPagerPriv *priv = pager->priv;
+ gchar **params;
+ gint params_i = 0;
+ gint params_max = 12;
+ GtkIconInfo *info;
+ GtkIconTheme *theme = (GtkIconTheme *) yelp_settings_get_icon_theme ();
+
+ d(xmlDocFormatDump(stdout, priv->search_doc, 1));
+
+ priv->stylesheet = xsltParseStylesheetFile (SEARCH_STYLESHEET);
+ if (!priv->stylesheet) {
+ g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC,
+ _("The table of contents could not be processed. The "
+ "file â??%sâ?? is either missing or is not a valid XSLT "
+ "stylesheet."),
+ SEARCH_STYLESHEET);
+ yelp_pager_error (YELP_PAGER (pager), error);
+ goto done;
+ }
+
+ priv->transformContext = xsltNewTransformContext (priv->stylesheet,
+ priv->search_doc);
+ priv->transformContext->_private = pager;
+ xsltRegisterExtElement (priv->transformContext,
+ "document",
+ YELP_NAMESPACE,
+ (xsltTransformFunction) xslt_yelp_document);
+
+ params = g_new0 (gchar *, params_max);
+ yelp_settings_params (¶ms, ¶ms_i, ¶ms_max);
+
+ if ((params_i + 12) >= params_max - 1) {
+ params_max += 12;
+ params = g_renew (gchar *, params, params_max);
+ }
+
+ info = gtk_icon_theme_lookup_icon (theme, "yelp-icon-big", 192, 0);
+ if (info) {
+ params[params_i++] = "help_icon";
+ params[params_i++] = g_strdup_printf ("\"%s\"",
+ gtk_icon_info_get_filename (info));
+ params[params_i++] = "help_icon_size";
+ params[params_i++] = g_strdup_printf ("%i",
+ gtk_icon_info_get_base_size (info));
+ gtk_icon_info_free (info);
+ }
+
+ params[params_i++] = "yelp.javascript";
+ params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js");
+
+ params[params_i++] = NULL;
+
+ outdoc = xsltApplyStylesheetUser (priv->stylesheet,
+ priv->search_doc,
+ (const gchar **)params, NULL, NULL,
+ priv->transformContext);
+ /* Don't do this */
+ /* g_signal_emit_by_name (pager, "finish");*/
+
+ done:
+ for (params_i = 0; params[params_i] != NULL; params_i++)
+ if (params_i % 2 == 1)
+ g_free ((gchar *) params[params_i]);
+ if (outdoc)
+ xmlFreeDoc (outdoc);
+ if (priv->search_doc) {
+ xmlFreeDoc (priv->search_doc);
+ priv->search_doc = NULL;
+ }
+ if (priv->stylesheet) {
+ xsltFreeStylesheet (priv->stylesheet);
+ priv->stylesheet = NULL;
+ }
+ if (priv->transformContext) {
+ xsltFreeTransformContext (priv->transformContext);
+ priv->transformContext = NULL;
+ }
+
+ g_signal_emit_by_name (pager, "finish");
+ return FALSE;
+}
+
+static void
+xslt_yelp_document (xsltTransformContextPtr ctxt,
+ xmlNodePtr node,
+ xmlNodePtr inst,
+ xsltStylePreCompPtr comp)
+{
+ GError *error;
+ YelpPage *page;
+ xmlChar *page_id = NULL;
+ xmlChar *page_title = NULL;
+ xmlChar *page_buf;
+ gint buf_size;
+ YelpPager *pager;
+ xsltStylesheetPtr style = NULL;
+ const char *old_outfile;
+ xmlDocPtr new_doc = NULL;
+ xmlDocPtr old_doc;
+ xmlNodePtr old_insert;
+ xmlNodePtr cur;
+
+ if (!ctxt || !node || !inst || !comp)
+ return;
+
+ pager = (YelpPager *) ctxt->_private;
+
+ page_id = xsltEvalAttrValueTemplate (ctxt, inst,
+ (const xmlChar *) "href",
+ NULL);
+ if (page_id == NULL) {
+ xsltTransformError (ctxt, NULL, inst,
+ _("No href attribute found on yelp:document"));
+ error = NULL;
+ yelp_pager_error (pager, error);
+ goto done;
+ }
+
+ old_outfile = ctxt->outputFile;
+ old_doc = ctxt->output;
+ old_insert = ctxt->insert;
+ ctxt->outputFile = (const char *) page_id;
+
+ style = xsltNewStylesheet ();
+ if (style == NULL) {
+ xsltTransformError (ctxt, NULL, inst,
+ _("Out of memory"));
+ error = NULL;
+ yelp_pager_error (pager, error);
+ goto done;
+ }
+
+ style->omitXmlDeclaration = TRUE;
+
+ new_doc = xmlNewDoc ("1.0");
+ new_doc->charset = XML_CHAR_ENCODING_UTF8;
+ new_doc->dict = ctxt->dict;
+ xmlDictReference (new_doc->dict);
+
+ ctxt->output = new_doc;
+ ctxt->insert = (xmlNodePtr) new_doc;
+
+ xsltApplyOneTemplate (ctxt, node, inst->children, NULL, NULL);
+
+ xsltSaveResultToString (&page_buf, &buf_size, new_doc, style);
+
+ ctxt->outputFile = old_outfile;
+ ctxt->output = old_doc;
+ ctxt->insert = old_insert;
+
+ for (cur = node->children; cur; cur = cur->next) {
+ if (!xmlStrcmp (cur->name, BAD_CAST "title")) {
+ page_title = xmlNodeGetContent (cur);
+ break;
+ }
+ }
+
+ page = g_new0 (YelpPage, 1);
+
+ if (page_id) {
+ page->page_id = g_strdup (page_id);
+ xmlFree (page_id);
+ }
+ if (page_title) {
+ page->title = g_strdup (page_title);
+ xmlFree (page_title);
+ } else {
+ page->title = g_strdup (_("Help Contents"));
+ }
+ page->contents = page_buf;
+
+ cur = xmlDocGetRootElement (new_doc);
+ for (cur = cur->children; cur; cur = cur->next) {
+ if (!xmlStrcmp (cur->name, (xmlChar *) "head")) {
+ for (cur = cur->children; cur; cur = cur->next) {
+ if (!xmlStrcmp (cur->name, (xmlChar *) "link")) {
+ xmlChar *rel = xmlGetProp (cur, "rel");
+
+ if (!xmlStrcmp (rel, (xmlChar *) "Previous"))
+ page->prev_id = xmlGetProp (cur, "href");
+ else if (!xmlStrcmp (rel, (xmlChar *) "Next"))
+ page->next_id = xmlGetProp (cur, "href");
+ else if (!xmlStrcmp (rel, (xmlChar *) "Top"))
+ page->toc_id = xmlGetProp (cur, "href");
+
+ xmlFree (rel);
+ }
+ }
+ break;
+ }
+ }
+
+ yelp_pager_add_page (pager, page);
+ g_signal_emit_by_name (pager, "page", page->page_id);
+
+ done:
+ if (new_doc)
+ xmlFreeDoc (new_doc);
+ if (style)
+ xsltFreeStylesheet (style);
+}
+
+#ifdef ENABLE_SCROLLKEEPER
+static void
+xml_trim_titles (xmlNodePtr node)
+{
+ xmlNodePtr cur, keep = NULL;
+ xmlChar *keep_lang = NULL;
+ int j, keep_pri = INT_MAX;
+
+ const gchar * const * langs = g_get_language_names ();
+
+ for (cur = node->children; cur; cur = cur->next) {
+ if (!xmlStrcmp (cur->name, BAD_CAST "title")) {
+ xmlChar *cur_lang = NULL;
+ int cur_pri = INT_MAX;
+ cur_lang = xmlNodeGetLang (cur);
+ if (cur_lang) {
+ for (j = 0; langs[j]; j++) {
+ if (g_str_equal (cur_lang, langs[j])) {
+ cur_pri = j;
+ break;
+ }
+ }
+ } else {
+ cur_pri = INT_MAX - 1;
+ }
+ if (cur_pri <= keep_pri) {
+ if (keep_lang)
+ xmlFree (keep_lang);
+ keep_lang = cur_lang;
+ keep_pri = cur_pri;
+ keep = cur;
+ } else {
+ if (cur_lang)
+ xmlFree (cur_lang);
+ }
+ }
+ }
+ cur = node->children;
+ while (cur) {
+ xmlNodePtr this = cur;
+ cur = cur->next;
+ if (!xmlStrcmp (this->name, BAD_CAST "title")) {
+ if (this != keep) {
+ xmlUnlinkNode (this);
+ xmlFreeNode (this);
+ }
+ }
+ }
+ xmlFree (keep_lang);
+}
+#endif
Index: src/yelp-search-pager.h
===================================================================
RCS file: src/yelp-search-pager.h
diff -N src/yelp-search-pager.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ src/yelp-search-pager.h 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,56 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Copyright (C) 2003 Shaun McCance <shaunm gnome org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Shaun McCance <shaunm gnome org>
+ */
+
+#ifndef __YELP_SEARCH_PAGER_H__
+#define __YELP_SEARCH_PAGER_H__
+
+#include <glib-object.h>
+
+#include "yelp-pager.h"
+
+#define YELP_TYPE_SEARCH_PAGER (yelp_search_pager_get_type ())
+#define YELP_SEARCH_PAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), YELP_TYPE_SEARCH_PAGER, YelpSearchPager))
+#define YELP_SEARCH_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerClass))
+#define YELP_IS_SEARCH_PAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), YELP_TYPE_SEARCH_PAGER))
+#define YELP_IS_SEARCH_PAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), YELP_TYPE_SEARCH_PAGER))
+#define YELP_SEARCH_PAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), YELP_TYPE_SEARCH_PAGER, YelpSearchPagerClass))
+
+typedef struct _YelpSearchPager YelpSearchPager;
+typedef struct _YelpSearchPagerClass YelpSearchPagerClass;
+typedef struct _YelpSearchPagerPriv YelpSearchPagerPriv;
+
+struct _YelpSearchPager {
+ YelpPager parent;
+
+ YelpSearchPagerPriv *priv;
+};
+
+struct _YelpSearchPagerClass {
+ YelpPagerClass parent_class;
+};
+
+GType yelp_search_pager_get_type (void);
+
+void yelp_search_pager_init (void);
+YelpSearchPager *yelp_search_pager_get (YelpDocInfo *doc_info);
+
+#endif /* __YELP_SEARCH_PAGER_H__ */
Index: src/yelp-toc-pager.c
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-toc-pager.c,v
retrieving revision 1.47
diff -u -p -r1.47 yelp-toc-pager.c
--- src/yelp-toc-pager.c 19 May 2005 22:41:16 -0000 1.47
+++ src/yelp-toc-pager.c 6 Jul 2005 19:30:56 -0000
@@ -34,6 +34,7 @@
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxml/HTMLtree.h>
+#include <libxml/tree.h>
#include <libxslt/xslt.h>
#include <libxslt/templates.h>
#include <libxslt/transform.h>
@@ -46,6 +47,12 @@
#include "yelp-toc-pager.h"
#include "yelp-utils.h"
+#define GMENU_I_KNOW_THIS_IS_UNSTABLE
+#include <gmenu-tree.h>
+
+#define DESKTOP_ENTRY_GROUP "Desktop Entry"
+#define KDE_DESKTOP_ENTRY_GROUP "KDE Desktop Entry"
+
#ifdef YELP_DEBUG
#define d(x) x
#else
@@ -96,6 +103,9 @@ struct _YelpTocPagerPriv {
xsltStylesheetPtr stylesheet;
xsltTransformContextPtr transformContext;
+
+ GMenuTree *libmenu_tree;
+ GSList *libmenu_stack;
};
struct _YelpListing {
@@ -125,10 +135,14 @@ GtkTreeModel * toc_pager_get_secti
static gboolean toc_process_pending (YelpTocPager *pager);
-static gboolean process_read_menu (YelpTocPager *pager);
+static gboolean process_libmenu (YelpTocPager *pager);
+static gboolean process_libmenu_node (YelpTocPager *pager);
static gboolean process_xslt (YelpTocPager *pager);
+#ifdef ENABLE_SCROLLKEEPER
+static gboolean process_read_menu (YelpTocPager *pager);
static gboolean process_read_scrollkeeper (YelpTocPager *pager);
static gboolean process_omf_pending (YelpTocPager *pager);
+#endif
#ifdef ENABLE_MAN
static gboolean process_mandir_pending (YelpTocPager *pager);
#endif
@@ -137,11 +151,13 @@ static gboolean process_info_dir_pe
static gboolean process_info_pending (YelpTocPager *pager);
#endif
+#ifdef ENABLE_SCROLLKEEPER
static void toc_add_doc_info (YelpTocPager *pager,
YelpDocInfo *doc_info);
static void toc_remove_doc_info (YelpTocPager *pager,
YelpDocInfo *doc_info);
static void xml_trim_titles (xmlNodePtr node);
+#endif
static void xslt_yelp_document (xsltTransformContextPtr ctxt,
xmlNodePtr node,
xmlNodePtr inst,
@@ -213,6 +229,9 @@ toc_pager_init (YelpTocPager *pager)
priv->cancel = 0;
priv->pause_count = 0;
priv->pending_func = NULL;
+
+ priv->libmenu_tree = NULL;
+ priv->libmenu_stack = NULL;
}
static void
@@ -320,7 +339,7 @@ toc_pager_process (YelpPager *pager)
yelp_pager_set_state (pager, YELP_PAGER_STATE_RUNNING);
g_signal_emit_by_name (pager, "start");
- priv->pending_func = (ProcessFunction) process_read_menu;
+ priv->pending_func = (ProcessFunction) process_libmenu;
gtk_idle_add_priority (G_PRIORITY_LOW,
(GtkFunction) toc_process_pending,
@@ -351,10 +370,15 @@ toc_process_pending (YelpTocPager *pager
gboolean readd;
YelpTocPagerPriv *priv = pager->priv;
static gpointer process_funcs[] = {
+ process_libmenu,
+ process_libmenu_node,
+ process_xslt,
+#ifdef ENABLE_SCROLLKEEPER
process_read_menu,
process_read_scrollkeeper,
process_omf_pending,
process_xslt,
+#endif
#ifdef ENABLE_MAN
process_mandir_pending,
process_xslt,
@@ -386,6 +410,303 @@ toc_process_pending (YelpTocPager *pager
return FALSE;
}
+static void
+set_icon (xmlNode *node, const char *icon)
+{
+ if (icon) {
+ GtkIconInfo *info;
+ GtkIconTheme *theme =
+ (GtkIconTheme *) yelp_settings_get_icon_theme ();
+ info = gtk_icon_theme_lookup_icon (theme, icon, 48, 0);
+ if (info) {
+ xmlNodePtr new = xmlNewChild (node, NULL, "icon", NULL);
+ xmlNewNsProp (new, NULL, "file", gtk_icon_info_get_filename (info));
+ gtk_icon_info_free (info);
+ }
+ }
+}
+
+typedef struct {
+ xmlNode *tree;
+ GSList *children;
+ GSList *iterator;
+ gboolean non_empty;
+} LibmenuStackFrame;
+
+static void
+push_stack_frame (YelpTocPager *pager, GMenuTreeDirectory *dir)
+{
+ LibmenuStackFrame *frame;
+ YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv;
+
+ frame = g_new (LibmenuStackFrame, 1);
+ frame->iterator = frame->children = gmenu_tree_directory_get_contents (dir);
+ frame->non_empty = FALSE;
+
+ frame->tree = xmlNewNode (NULL, "toc");
+ xmlSetProp (frame->tree, "id", gmenu_tree_directory_get_menu_id (dir));
+ xmlNewTextChild (frame->tree, NULL, "title", gmenu_tree_directory_get_name (dir));
+ set_icon (frame->tree, gmenu_tree_directory_get_icon (dir));
+
+ priv->libmenu_stack = g_slist_prepend (priv->libmenu_stack, frame);
+}
+
+static void
+pop_stack_frame (YelpTocPager *pager)
+{
+ LibmenuStackFrame *frame;
+ YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv;
+
+ frame = priv->libmenu_stack->data;
+
+ g_slist_free (frame->children);
+ g_free (frame);
+
+ priv->libmenu_stack = g_slist_delete_link (priv->libmenu_stack, priv->libmenu_stack);
+}
+
+static GTimer *timer;
+/* iterator points to next node to process and is incremented at the
+ end of the function. NULL means finished with this level. Parent
+ iterators are incremented before processing the child tree. */
+static gboolean
+process_libmenu_node (YelpTocPager *pager)
+{
+ LibmenuStackFrame *frame;
+ GMenuTreeItem *item;
+ YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv;
+ gulong ms_start;
+
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed (enter process_libmenu_node) ", ms);
+ ms_start = ms;
+}
+
+ frame = priv->libmenu_stack->data;
+
+ if (frame->iterator == NULL) {
+ g_print ("pop");
+ if (priv->libmenu_stack->next) {
+ if (frame->non_empty) {
+ xmlNode *tree = frame->tree;
+ pop_stack_frame (pager);
+
+ frame = priv->libmenu_stack->data;
+ xmlAddChild (frame->tree, tree);
+ frame->non_empty = TRUE;
+ } else {
+ xmlFreeNode (frame->tree);
+ pop_stack_frame(pager);
+ }
+
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("\n%ld elapsed (exit process_libmenu_node (%ld))\n", ms, ((glong)ms - ms_start) % 1000000);
+}
+ return TRUE;
+ } else {
+ YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv;
+
+ priv->toc_doc = xmlNewDoc ("1.0");
+ xmlSetProp (frame->tree, "id", "index");
+ xmlDocSetRootElement (priv->toc_doc, frame->tree);
+
+ pop_stack_frame (pager);
+
+ gmenu_tree_unref (priv->libmenu_tree);
+ priv->libmenu_tree = NULL;
+
+
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("\n%ld elapsed (exit process_libmenu_node (%ld))\n", ms, ((glong)ms - ms_start) % 1000000);
+}
+
+ return FALSE;
+ }
+ }
+
+ item = frame->iterator->data;
+
+ switch (gmenu_tree_item_get_type (item)) {
+ case GMENU_TREE_ITEM_DIRECTORY:
+ {
+ g_print ("directory");
+ push_stack_frame (pager, GMENU_TREE_DIRECTORY (item));
+ }
+ break;
+ case GMENU_TREE_ITEM_ENTRY:
+ {
+ GMenuTreeEntry *entry = GMENU_TREE_ENTRY (item);
+ const char *path = gmenu_tree_entry_get_desktop_file_path (entry);
+ const char *desktop_entry_group;
+ char *docpath = NULL;
+ GKeyFile *key_file;
+
+ key_file = g_key_file_new ();
+
+ g_print ("entry (%s)", path);
+
+ if (!g_key_file_load_from_file (key_file, path, 0, NULL)) {
+ g_key_file_free (key_file);
+ break;
+ }
+
+ if (g_key_file_has_group (key_file, DESKTOP_ENTRY_GROUP)) {
+ desktop_entry_group = DESKTOP_ENTRY_GROUP;
+ } else {
+ if (g_key_file_has_group (key_file, KDE_DESKTOP_ENTRY_GROUP)) {
+ desktop_entry_group = KDE_DESKTOP_ENTRY_GROUP;
+ } else {
+ g_key_file_free (key_file);
+ break;
+ }
+ }
+
+ docpath = g_key_file_get_string (key_file, desktop_entry_group, "DocPath", NULL);
+
+ if (docpath) {
+ xmlNode *new = xmlNewChild (frame->tree, NULL, "doc", NULL);
+ xmlNewNsProp (new, NULL, "href", docpath);
+ xmlNewTextChild (new, NULL, "title", gmenu_tree_entry_get_name (entry));
+ xmlNewTextChild (new, NULL, "description", gmenu_tree_entry_get_comment (entry));
+ set_icon (new, gmenu_tree_entry_get_icon (entry));
+
+ frame->non_empty = TRUE;
+
+ g_free (docpath);
+ }
+ }
+ break;
+ default:
+ /* Ignore */
+ break;
+ }
+
+
+ frame->iterator = frame->iterator->next;
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("\n%ld elapsed (exit process_libmenu_node (%ld))\n", ms, ((glong)ms - ms_start) % 1000000);
+}
+ return TRUE;
+}
+
+#if 0
+static xmlNode *
+build_menu_dir_xml (GMenuTreeDirectory *dir)
+{
+ gboolean non_empty = FALSE;
+ GSList *items;
+ xmlNode *tree;
+
+ tree = xmlNewNode (NULL, "toc");
+ xmlSetProp (tree, "id", gmenu_tree_directory_get_menu_id (dir));
+ xmlNewTextChild (tree, NULL, "title", gmenu_tree_directory_get_name (dir));
+
+ set_icon (tree, gmenu_tree_directory_get_icon (dir));
+
+ for (items = gmenu_tree_directory_get_contents (dir); items; items = items->next) {
+ GMenuTreeItem *item = items->data;
+ switch (gmenu_tree_item_get_type (item)) {
+ case GMENU_TREE_ITEM_DIRECTORY:
+ {
+ xmlNode *child;
+
+ child = build_menu_dir_xml (GMENU_TREE_DIRECTORY (item));
+
+ if (child) {
+ xmlAddChild (tree, child);
+ non_empty = TRUE;
+ }
+ }
+ break;
+ case GMENU_TREE_ITEM_ENTRY:
+ {
+ GMenuTreeEntry *entry = GMENU_TREE_ENTRY (item);
+ const char *path = gmenu_tree_entry_get_desktop_file_path (entry);
+ const char *desktop_entry_group;
+ char *docpath = NULL;
+ GKeyFile *key_file;
+
+ key_file = g_key_file_new ();
+
+ if (!g_key_file_load_from_file (key_file, path, 0, NULL)) {
+ g_key_file_free (key_file);
+ break;
+ }
+
+ if (g_key_file_has_group (key_file, DESKTOP_ENTRY_GROUP)) {
+ desktop_entry_group = DESKTOP_ENTRY_GROUP;
+ } else {
+ if (g_key_file_has_group (key_file, KDE_DESKTOP_ENTRY_GROUP)) {
+ desktop_entry_group = KDE_DESKTOP_ENTRY_GROUP;
+ } else {
+ g_key_file_free (key_file);
+ break;
+ }
+ }
+
+ docpath = g_key_file_get_string (key_file, desktop_entry_group, "DocPath", NULL);
+
+ if (docpath) {
+ xmlNode *new = xmlNewChild (tree, NULL, "doc", NULL);
+ xmlNewNsProp (new, NULL, "href", docpath);
+ xmlNewTextChild (new, NULL, "title", gmenu_tree_entry_get_name (entry));
+ xmlNewTextChild (new, NULL, "description", gmenu_tree_entry_get_comment (entry));
+ set_icon (new, gmenu_tree_entry_get_icon (entry));
+
+ non_empty = TRUE;
+
+ g_free (docpath);
+ }
+ }
+ break;
+ default:
+ /* Ignore */
+ break;
+ }
+ }
+ if (!non_empty) {
+ xmlFreeNode (tree);
+ tree = NULL;
+ }
+ return tree;
+}
+#endif
+
+static gboolean
+process_libmenu (YelpTocPager *pager)
+{
+ YelpTocPagerPriv *priv = YELP_TOC_PAGER (pager)->priv;
+
+ timer = g_timer_new ();
+ g_timer_start(timer);
+
+ priv->libmenu_tree = gmenu_tree_lookup ("applications.menu",
+ GMENU_TREE_FLAGS_NONE);
+
+ push_stack_frame (pager, gmenu_tree_get_root_directory (priv->libmenu_tree));
+
+#if 0
+ priv->toc_doc = xmlNewDoc ("1.0");
+
+ root = build_menu_dir_xml (gmenu_tree_get_root_directory (tree));
+
+ xmlSetProp (root, "id", "index");
+
+ xmlDocSetRootElement (priv->toc_doc, root);
+
+
+ gmenu_tree_unref (tree);
+#endif
+
+ return FALSE;
+}
+
+#ifdef ENABLE_SCROLLKEEPER
+
/** process_read_scrollkeeper *************************************************/
static void
@@ -559,6 +880,7 @@ process_omf_pending (YelpTocPager *pager
else
return FALSE;
}
+#endif
#ifdef ENABLE_MAN
static gboolean
@@ -750,6 +1072,7 @@ process_info_pending (YelpTocPager *page
}
#endif /* ENABLE_INFO */
+#ifdef ENABLE_SCROLLKEEPER
static gboolean
process_read_menu (YelpTocPager *pager)
{
@@ -794,17 +1117,7 @@ process_read_menu (YelpTocPager *pager)
xml_trim_titles (node);
icon = xmlGetProp (node, "icon");
- if (icon) {
- GtkIconInfo *info;
- GtkIconTheme *theme =
- (GtkIconTheme *) yelp_settings_get_icon_theme ();
- info = gtk_icon_theme_lookup_icon (theme, icon, 48, 0);
- if (info) {
- xmlNodePtr new = xmlNewChild (node, NULL, "icon", NULL);
- xmlNewNsProp (new, NULL, "file", gtk_icon_info_get_filename (info));
- gtk_icon_info_free (info);
- }
- }
+ set_icon (node, icon);
xmlFree (icon);
}
@@ -862,19 +1175,28 @@ process_read_menu (YelpTocPager *pager)
return FALSE;
}
+#endif
static gboolean
process_xslt (YelpTocPager *pager)
{
GError *error = NULL;
- xmlDocPtr outdoc;
+ xmlDocPtr outdoc = NULL;
YelpTocPagerPriv *priv = pager->priv;
gchar **params;
gint params_i = 0;
- gint params_max = 10;
+ gint params_max = 12;
GtkIconInfo *info;
GtkIconTheme *theme = (GtkIconTheme *) yelp_settings_get_icon_theme ();
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed\n", ms);
+}
+
+
+ d(xmlDocFormatDump(stdout, priv->toc_doc, 1));
+
priv->stylesheet = xsltParseStylesheetFile (TOC_STYLESHEET);
if (!priv->stylesheet) {
g_set_error (&error, YELP_ERROR, YELP_ERROR_PROC,
@@ -886,6 +1208,10 @@ process_xslt (YelpTocPager *pager)
goto done;
}
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed\n", ms);
+}
priv->transformContext = xsltNewTransformContext (priv->stylesheet,
priv->toc_doc);
priv->transformContext->_private = pager;
@@ -897,11 +1223,15 @@ process_xslt (YelpTocPager *pager)
params = g_new0 (gchar *, params_max);
yelp_settings_params (¶ms, ¶ms_i, ¶ms_max);
- if ((params_i + 10) >= params_max - 1) {
- params_max += 10;
+ if ((params_i + 12) >= params_max - 1) {
+ params_max += 12;
params = g_renew (gchar *, params, params_max);
}
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed\n", ms);
+}
info = gtk_icon_theme_lookup_icon (theme, "yelp-icon-big", 192, 0);
if (info) {
params[params_i++] = "help_icon";
@@ -913,8 +1243,15 @@ process_xslt (YelpTocPager *pager)
gtk_icon_info_free (info);
}
+ params[params_i++] = "yelp.javascript";
+ params[params_i++] = g_strdup_printf ("\"%s\"", DATADIR "/yelp/yelp.js");
+
params[params_i++] = NULL;
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed\n", ms);
+}
outdoc = xsltApplyStylesheetUser (priv->stylesheet,
priv->toc_doc,
(const gchar **)params, NULL, NULL,
@@ -941,9 +1278,15 @@ process_xslt (YelpTocPager *pager)
priv->transformContext = NULL;
}
+{ gulong ms;
+ g_timer_elapsed (timer, &ms);
+ g_print ("%ld elapsed\n", ms);
+}
+
return FALSE;
}
+#ifdef ENABLE_SCROLLKEEPER
static void
toc_add_doc_info (YelpTocPager *pager, YelpDocInfo *doc_info)
{
@@ -1000,6 +1343,8 @@ toc_remove_doc_info (YelpTocPager *pager
#endif
}
+#endif
+
static void
xslt_yelp_document (xsltTransformContextPtr ctxt,
xmlNodePtr node,
@@ -1120,6 +1465,7 @@ xslt_yelp_document (xsltTransformContext
xsltFreeStylesheet (style);
}
+#ifdef ENABLE_SCROLLKEEPER
static void
xml_trim_titles (xmlNodePtr node)
{
@@ -1169,3 +1515,4 @@ xml_trim_titles (xmlNodePtr node)
}
xmlFree (keep_lang);
}
+#endif
Index: src/yelp-uri.c
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-uri.c,v
retrieving revision 1.22
diff -u -p -r1.22 yelp-uri.c
--- src/yelp-uri.c 22 Feb 2005 23:44:28 -0000 1.22
+++ src/yelp-uri.c 6 Jul 2005 19:30:56 -0000
@@ -38,6 +38,7 @@ static gboolean uri_parse_uri
static void uri_parse_toc_uri (YelpURI *uri);
static void uri_parse_man_uri (YelpURI *uri);
static void uri_parse_ghelp_uri (YelpURI *uri);
+static void uri_parse_help_uri (YelpURI *uri);
static gchar * uri_locate_file (gchar *path,
gchar *file);
static gchar * uri_locate_file_lang (gchar *path,
@@ -97,6 +98,7 @@ uri_set_resource_type (YelpURI *uri)
return;
}
+ /* if (scheme != "file") */
if (strcmp (gnome_vfs_uri_get_scheme (uri->uri), "file")) {
uri->resource_type = YELP_URI_TYPE_EXTERNAL;
return;
@@ -158,6 +160,10 @@ uri_parse_uri (YelpURI *uri)
uri_parse_ghelp_uri (uri);
return TRUE;
}
+ if (!strncmp (uri->src_uri, "help:", 5)) {
+ uri_parse_help_uri (uri);
+ return TRUE;
+ }
else if (!strncmp (uri->src_uri, "man:", 4)) {
uri_parse_man_uri (uri);
return TRUE;
@@ -232,7 +238,7 @@ uri_parse_ghelp_uri (YelpURI *uri)
else
goto done;
- if (path[0] && path[0] == '/') {
+ if (path[0] == '/') {
gchar *str = g_strconcat ("file:", path, NULL);
if ((c = strchr (str, '?')))
@@ -301,6 +307,127 @@ uri_parse_ghelp_uri (YelpURI *uri)
if (!uri)
g_warning ("Couldn't resolve ghelp URI: %s", uri->src_uri);
+}
+
+static gboolean
+help_uri_check_file (YelpURI *uri, gchar *filename, gchar *reference) {
+ g_print ("Checking %s\n", filename);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+ gchar *full_uri;
+ if (reference) {
+ full_uri = g_strconcat ("file://", filename, "#", reference, NULL);
+ } else {
+ full_uri = g_strconcat ("file://", filename, NULL);
+ }
+
+ uri->uri = gnome_vfs_uri_new (full_uri);
+ uri_set_resource_type (uri);
+
+ g_free (full_uri);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+help_uri_check_dir (YelpURI *uri, gchar *path, gchar *identifier, gchar *reference)
+{
+ gboolean result;
+
+ gchar *full_path;
+ gchar *full_identifier;
+
+ result = help_uri_check_file (uri, path, reference);
+ if (result)
+ return TRUE;
+
+ full_path = g_build_filename (path, "index.docbook", NULL);
+ result = help_uri_check_file (uri, full_path, reference);
+ g_free (full_path);
+ if (result)
+ return TRUE;
+
+ full_identifier = g_strconcat (identifier, ".xml", NULL);
+ full_path = g_build_filename (path, full_identifier, NULL);
+ result = help_uri_check_file (uri, full_path, reference);
+ g_free (full_path);
+ g_free (full_identifier);
+ if (result)
+ return TRUE;
+}
+
+static gboolean
+help_uri_search (YelpURI *uri, gchar *path, gchar *identifier)
+{
+ gboolean result;
+
+ result = help_uri_check_dir (uri, path, identifier, NULL);
+ if (result)
+ return TRUE;
+
+ if (strlen (path) > 5 && strcmp (path + strlen (path) - 5, ".html")) {
+ gchar *slash = strrchr (path, '/');
+ if (slash != NULL) {
+ gchar *shortened = g_strndup (path, slash - path);
+ gchar *reference = g_strndup (slash + 1, strlen (slash + 1) - 5);
+ result = help_uri_check_dir (uri, shortened, identifier);
+ g_free (reference);
+ g_free (shortened);
+ if (result)
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+uri_parse_help_uri (YelpURI *uri)
+{
+ GSList *locations = NULL;
+ GSList *node;
+ gchar *path, *c;
+ gchar *doc_id = NULL;
+ gchar *file_name = NULL;
+ gchar *link_id = NULL;
+ const gchar * const * langs;
+ gboolean result;
+
+ GnomeProgram *program = gnome_program_get ();
+
+ if ((path = strchr(uri->src_uri, ':')))
+ path++;
+ else
+ goto done;
+
+ while (*path == '/')
+ path++;
+
+ if ((slash = strchr(path, '/'))) {
+ file_name = g_strdup (slash + 1);
+ path = g_strndup (path, slash - path);
+ } else {
+ path = g_strdup (path);
+ file_name = g_strdup ("");
+ }
+
+ langs = g_get_language_names ();
+
+ for (i = 0; langs[i] != NULL; i++) {
+ gnome_path = g_strdup_printf (DATADIR "/gnome/help/%s/%s/%s", path, lang, file_name);
+ result = help_uri_search (uri, gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return;
+ }
+
+ gnome_path = g_strdup_printf (DATADIR "/gnome/help/%s/C/%s", path, file_name);
+ result = help_uri_search (uri, gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return;
+
+ return;
}
static gchar *
Index: src/yelp-utils.c
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-utils.c,v
retrieving revision 1.25
diff -u -p -r1.25 yelp-utils.c
--- src/yelp-utils.c 22 Feb 2005 23:44:28 -0000 1.25
+++ src/yelp-utils.c 6 Jul 2005 19:30:56 -0000
@@ -37,7 +37,7 @@
#ifdef YELP_DEBUG
#define d(x) x
#else
-#define d(x)
+#define d(x) x
#endif
GHashTable *doc_info_table;
@@ -68,6 +68,7 @@ struct _YelpDocInfo {
static YelpDocType get_doc_type (gchar *uri);
static gchar * convert_ghelp_uri (gchar *uri);
+static gchar * convert_help_uri (gchar *uri);
static gchar * convert_man_uri (gchar *uri);
static gchar * convert_info_uri (gchar *uri);
@@ -106,6 +107,12 @@ yelp_doc_info_new (const gchar *uri)
doc_type = get_doc_type (doc_uri);
uri_type = YELP_URI_TYPE_GHELP;
}
+ else if (g_str_has_prefix (full_uri, "help:")) {
+ doc_uri = convert_help_uri (full_uri);
+ if (doc_uri)
+ doc_type = get_doc_type (doc_uri);
+ uri_type = YELP_URI_TYPE_HELP;
+ }
else if (g_str_has_prefix (full_uri, "man:")) {
doc_uri = convert_man_uri (full_uri);
doc_type = YELP_DOC_TYPE_MAN;
@@ -121,6 +128,11 @@ yelp_doc_info_new (const gchar *uri)
doc_type = YELP_DOC_TYPE_TOC;
uri_type = YELP_URI_TYPE_TOC;
}
+ else if (g_str_has_prefix (full_uri, "x-yelp-search:")) {
+ doc_uri = g_strdup (full_uri);
+ doc_type = YELP_DOC_TYPE_SEARCH;
+ uri_type = YELP_URI_TYPE_SEARCH;
+ }
else {
doc_uri = g_strdup (uri);
doc_type = YELP_DOC_TYPE_EXTERNAL;
@@ -562,6 +574,133 @@ yelp_doc_info_add_uri (YelpDocInfo *doc_
/******************************************************************************/
/** Convert fancy URIs to file URIs *******************************************/
+
+static gchar *
+help_uri_check_file (gchar *filename, gchar *reference) {
+ g_print ("Checking %s\n", filename);
+ if (g_file_test (filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR)) {
+ gchar *full_uri;
+ if (reference) {
+ full_uri = g_strconcat ("file://", filename, "#", reference, NULL);
+ } else {
+ full_uri = g_strconcat ("file://", filename, NULL);
+ }
+
+ return full_uri;
+ }
+
+ return NULL;
+}
+
+static gchar *
+help_uri_check_dir (gchar *path, gchar *identifier, gchar *reference)
+{
+ gchar *result;
+
+ gchar *full_path;
+ gchar *full_identifier;
+
+ result = help_uri_check_file (path, reference);
+ if (result)
+ return result;
+
+ full_path = g_build_filename (path, "index.docbook", NULL);
+ result = help_uri_check_file (full_path, reference);
+ g_free (full_path);
+ if (result)
+ return result;
+
+ full_identifier = g_strconcat (identifier, ".xml", NULL);
+ full_path = g_build_filename (path, full_identifier, NULL);
+ result = help_uri_check_file (full_path, reference);
+ g_free (full_path);
+ g_free (full_identifier);
+ if (result)
+ return result;
+
+ return NULL;
+}
+
+static gchar *
+help_uri_search (gchar *path, gchar *identifier)
+{
+ gchar *result;
+
+ result = help_uri_check_dir (path, identifier, NULL);
+ if (result)
+ return result;
+
+ if (strlen (path) > 5 && strcmp (path + strlen (path) - 5, ".html")) {
+ gchar *slash = strrchr (path, '/');
+ if (slash != NULL) {
+ gchar *shortened = g_strndup (path, slash - path);
+ gchar *reference = g_strndup (slash + 1, strlen (slash + 1) - 5);
+ result = help_uri_check_dir (shortened, identifier, reference);
+ g_free (reference);
+ g_free (shortened);
+ if (result)
+ return result;
+ }
+ }
+ return NULL;
+}
+
+static gchar *
+convert_help_uri (gchar *uri)
+{
+ gchar *path;
+ gchar *file_name = NULL;
+ const gchar * const * langs;
+ gchar *result;
+ gchar *gnome_path, *slash;
+ int i;
+
+ if ((path = strchr(uri, ':')))
+ path++;
+ else
+ return NULL;
+
+ while (*path == '/')
+ path++;
+
+ if ((slash = strchr(path, '/'))) {
+ file_name = g_strdup (slash + 1);
+ path = g_strndup (path, slash - path);
+ } else {
+ path = g_strdup (path);
+ file_name = g_strdup ("");
+ }
+
+ langs = g_get_language_names ();
+
+ for (i = 0; langs[i] != NULL; i++) {
+ gnome_path = g_strdup_printf (DATADIR "/gnome/help/%s/%s/%s", path, langs[i], file_name);
+ result = help_uri_search (gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return result;
+
+ gnome_path = g_strdup_printf ("/opt/gnome/share/gnome/help/%s/%s/%s", path, langs[i], file_name);
+ result = help_uri_search (gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return result;
+ }
+
+ gnome_path = g_strdup_printf (DATADIR "/gnome/help/%s/C/%s", path, file_name);
+ result = help_uri_search (gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return result;
+
+ gnome_path = g_strdup_printf ("/opt/gnome/share/gnome/help/%s/C/%s", path, file_name);
+ result = help_uri_search (gnome_path, path);
+ g_free (gnome_path);
+ if (result)
+ return result;
+
+ return NULL;
+}
static gchar *
locate_file_lang (gchar *path, gchar *file, const gchar *lang)
Index: src/yelp-utils.h
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-utils.h,v
retrieving revision 1.11
diff -u -p -r1.11 yelp-utils.h
--- src/yelp-utils.h 22 Feb 2005 19:17:01 -0000 1.11
+++ src/yelp-utils.h 6 Jul 2005 19:30:56 -0000
@@ -37,7 +37,8 @@ typedef enum {
YELP_DOC_TYPE_MAN,
YELP_DOC_TYPE_INFO,
YELP_DOC_TYPE_TOC,
- YELP_DOC_TYPE_EXTERNAL
+ YELP_DOC_TYPE_EXTERNAL,
+ YELP_DOC_TYPE_SEARCH
} YelpDocType;
static gchar *mandirs[] = {
@@ -65,20 +66,20 @@ typedef enum {
YELP_URI_TYPE_INFO = 1 << 3,
YELP_URI_TYPE_TOC = 1 << 4,
YELP_URI_TYPE_EXTERNAL = 1 << 5,
+ YELP_URI_TYPE_HELP = 1 << 6,
+ YELP_URI_TYPE_SEARCH = 1 << 7,
YELP_URI_TYPE_NO_FILE =
YELP_URI_TYPE_GHELP |
YELP_URI_TYPE_MAN |
YELP_URI_TYPE_INFO |
YELP_URI_TYPE_TOC |
- YELP_URI_TYPE_EXTERNAL,
+ YELP_URI_TYPE_EXTERNAL|
+ YELP_URI_TYPE_HELP |
+ YELP_URI_TYPE_SEARCH,
YELP_URI_TYPE_ANY =
YELP_URI_TYPE_FILE |
- YELP_URI_TYPE_GHELP |
- YELP_URI_TYPE_MAN |
- YELP_URI_TYPE_INFO |
- YELP_URI_TYPE_TOC |
- YELP_URI_TYPE_EXTERNAL
+ YELP_URI_TYPE_NO_FILE
} YelpURIType;
#include "yelp-pager.h"
Index: src/yelp-window.c
===================================================================
RCS file: /cvs/gnome/yelp/src/yelp-window.c,v
retrieving revision 1.172
diff -u -p -r1.172 yelp-window.c
--- src/yelp-window.c 16 May 2005 21:02:33 -0000 1.172
+++ src/yelp-window.c 6 Jul 2005 19:30:56 -0000
@@ -41,12 +41,15 @@
#include "yelp-bookmarks.h"
#include "yelp-db-pager.h"
+#include "yelp-search-pager.h"
+#include "yelp-db-print-pager.h"
#include "yelp-error.h"
#include "yelp-html.h"
#include "yelp-pager.h"
#include "yelp-settings.h"
#include "yelp-toc-pager.h"
#include "yelp-window.h"
+#include "gtkentryaction.h"
#ifdef ENABLE_MAN
#include "yelp-man-pager.h"
@@ -66,7 +69,7 @@
#define YELP_CONFIG_WIDTH_DEFAULT "600"
#define YELP_CONFIG_HEIGHT_DEFAULT "420"
-#define BUFFER_SIZE 16384
+#define BUFFER_SIZE 4096
typedef struct {
YelpWindow *window;
@@ -155,6 +158,8 @@ static void window_add_widget
GtkWidget *vbox);
static void window_new_window_cb (GtkAction *action, YelpWindow *window);
static void window_about_document_cb (GtkAction *action, YelpWindow *window);
+static void window_print_document_cb (GtkAction *action, YelpWindow *window);
+static void window_print_page_cb (GtkAction *action, YelpWindow *window);
static void window_open_location_cb (GtkAction *action, YelpWindow *window);
static void window_close_window_cb (GtkAction *action, YelpWindow *window);
static void window_copy_cb (GtkAction *action, YelpWindow *window);
@@ -294,6 +299,16 @@ static const GtkActionEntry entries[] =
"<Control>N",
NULL,
G_CALLBACK (window_new_window_cb) },
+ { "PrintDocument", NULL,
+ N_("Print This Document"),
+ NULL,
+ NULL,
+ G_CALLBACK (window_print_document_cb) },
+ { "PrintPage", NULL,
+ N_("Print This Page"),
+ NULL,
+ NULL,
+ G_CALLBACK (window_print_page_cb) },
{ "AboutDocument", NULL,
N_("About This Document"),
NULL,
@@ -801,6 +816,7 @@ window_do_load (YelpWindow *window,
case YELP_DOC_TYPE_DOCBOOK_XML:
case YELP_DOC_TYPE_TOC:
+ case YELP_DOC_TYPE_SEARCH:
handled = window_do_load_pager (window, doc_info, frag_id);
break;
case YELP_DOC_TYPE_DOCBOOK_SGML:
@@ -882,6 +898,28 @@ window_error (YelpWindow *window, GError
gtk_widget_destroy (dialog);
}
+static char *
+encode_search_uri (const char *search_terms)
+{
+ return g_strdup_printf ("x-yelp-search:%s", search_terms);
+}
+
+static void
+search_activated (GtkAction *action,
+ YelpWindow *window)
+{
+ const char *search_terms;
+ char *uri;
+
+ search_terms = gtk_entry_action_get_text (GTK_ENTRY_ACTION (action));
+
+ uri = encode_search_uri (search_terms);
+
+ yelp_window_load (window, uri);
+
+ g_free (uri);
+}
+
static void
window_populate (YelpWindow *window)
{
@@ -903,6 +941,14 @@ window_populate (YelpWindow *window)
gtk_action_group_add_actions (priv->action_group,
entries, G_N_ELEMENTS (entries),
window);
+
+ action = gtk_entry_action_new ("Search",
+ _("Search"),
+ _("Search for other documentation"),
+ NULL);
+ g_signal_connect (G_OBJECT (action), "activate",
+ G_CALLBACK (search_activated), window);
+ gtk_action_group_add_action (priv->action_group, action);
priv->ui_manager = gtk_ui_manager_new ();
gtk_ui_manager_insert_action_group (priv->ui_manager, priv->action_group, 0);
@@ -1147,6 +1193,8 @@ window_do_load_pager (YelpWindow *windo
case YELP_DOC_TYPE_TOC:
pager = YELP_PAGER (yelp_toc_pager_get ());
break;
+ case YELP_DOC_TYPE_SEARCH:
+ pager = YELP_PAGER (yelp_search_pager_get (doc_info));
default:
break;
}
@@ -1264,61 +1312,45 @@ window_do_load_pager (YelpWindow *windo
}
static gboolean
-window_do_load_html (YelpWindow *window,
- YelpDocInfo *doc_info,
- gchar *frag_id)
+load_html (YelpHtml *html_view,
+ YelpDocInfo *doc_info,
+ gchar *frag_id,
+ GError **error)
{
- YelpWindowPriv *priv;
GnomeVFSHandle *handle;
GnomeVFSResult result;
GnomeVFSFileSize n;
gchar buffer[BUFFER_SIZE];
- GtkAction *action;
gboolean handled = TRUE;
gchar *uri;
- g_return_val_if_fail (YELP_IS_WINDOW (window), FALSE);
+ g_return_val_if_fail (YELP_IS_HTML (html_view), FALSE);
g_return_val_if_fail (doc_info != NULL, FALSE);
- priv = window->priv;
-
uri = yelp_doc_info_get_uri (doc_info, frag_id, YELP_URI_TYPE_FILE);
- window_set_sections (window, NULL);
-
- action = gtk_action_group_get_action (priv->action_group, "GoPrevious");
- if (action)
- g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
- action = gtk_action_group_get_action (priv->action_group, "GoNext");
- if (action)
- g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
- action = gtk_action_group_get_action (priv->action_group, "GoContents");
- if (action)
- g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
-
result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ);
if (result != GNOME_VFS_OK) {
- GError *error = NULL;
- g_set_error (&error, YELP_ERROR, YELP_ERROR_IO,
- _("The file â??%sâ?? could not be read. This file might "
- "be missing, or you might not have permissions to "
- "read it."),
- uri);
- window_error (window, error, TRUE);
+ if (error)
+ g_set_error (error, YELP_ERROR, YELP_ERROR_IO,
+ _("The file â??%sâ?? could not be read. This file might "
+ "be missing, or you might not have permissions to "
+ "read it."),
+ uri);
handled = FALSE;
goto done;
}
- yelp_html_set_base_uri (priv->html_view, uri);
+ yelp_html_set_base_uri (html_view, uri);
switch (yelp_doc_info_get_type (doc_info)) {
case YELP_DOC_TYPE_HTML:
- yelp_html_open_stream (priv->html_view, "text/html");
+ yelp_html_open_stream (html_view, "text/html");
break;
case YELP_DOC_TYPE_XHTML:
- yelp_html_open_stream (priv->html_view, "application/xhtml+xml");
+ yelp_html_open_stream (html_view, "application/xhtml+xml");
break;
default:
g_assert_not_reached ();
@@ -1326,10 +1358,10 @@ window_do_load_html (YelpWindow *wind
while ((result = gnome_vfs_read
(handle, buffer, BUFFER_SIZE, &n)) == GNOME_VFS_OK) {
- yelp_html_write (priv->html_view, buffer, n);
+ yelp_html_write (html_view, buffer, n);
}
- yelp_html_close (priv->html_view);
+ yelp_html_close (html_view);
done:
if (handle)
@@ -1340,6 +1372,43 @@ window_do_load_html (YelpWindow *wind
return handled;
}
+static gboolean
+window_do_load_html (YelpWindow *window,
+ YelpDocInfo *doc_info,
+ gchar *frag_id)
+{
+ YelpWindowPriv *priv;
+ GError *error = NULL;
+ gboolean handled;
+ GtkAction *action;
+
+ g_return_val_if_fail (YELP_IS_WINDOW (window), FALSE);
+
+ priv = window->priv;
+
+ window_set_sections (window, NULL);
+
+ action = gtk_action_group_get_action (priv->action_group, "GoPrevious");
+ if (action)
+ g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+ action = gtk_action_group_get_action (priv->action_group, "GoNext");
+ if (action)
+ g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+ action = gtk_action_group_get_action (priv->action_group, "GoContents");
+ if (action)
+ g_object_set (G_OBJECT (action), "sensitive", FALSE, NULL);
+
+ handled = load_html (priv->html_view,
+ doc_info,
+ frag_id,
+ &error);
+
+ if (error)
+ window_error (window, error, TRUE);
+
+ return handled;
+}
+
static void
window_set_loading (YelpWindow *window)
{
@@ -1816,6 +1885,170 @@ window_new_window_cb (GtkAction *action,
g_return_if_fail (YELP_IS_WINDOW (window));
g_signal_emit (window, signals[NEW_WINDOW_REQUESTED], 0, NULL);
+}
+
+typedef struct {
+ gulong page_handler;
+ gulong error_handler;
+ gulong cancel_handler;
+ gulong finish_handler;
+ YelpPager *pager;
+} PrintStruct;
+
+static void
+print_disconnect (PrintStruct *data)
+{
+ if (data->page_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->page_handler);
+ data->page_handler = 0;
+ }
+ if (data->error_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->error_handler);
+ data->error_handler = 0;
+ }
+ if (data->cancel_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->cancel_handler);
+ data->cancel_handler = 0;
+ }
+ if (data->finish_handler) {
+ g_signal_handler_disconnect (data->pager,
+ data->finish_handler);
+ data->finish_handler = 0;
+ }
+ if (data) {
+ if (data->pager)
+ g_object_unref (data->pager);
+ }
+ g_free (data);
+}
+
+static void
+print_pager_page_cb (YelpPager *pager,
+ gchar *page_id,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ YelpPage *page;
+
+ d (g_print ("print_pager_page_cb\n"));
+ d (g_print (" page_id=\"%s\"\n", page_id));
+
+
+ page = (YelpPage *) yelp_pager_get_page (pager, page_id);
+
+ if (page) {
+ YelpHtml *html;
+ GtkWidget *gtk_window;
+ int length, offset;
+
+ d(g_print (page->contents));
+
+ gtk_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ html = yelp_html_new ();
+ gtk_container_add (GTK_CONTAINER (gtk_window), GTK_WIDGET (html));
+ gtk_widget_realize (gtk_window);
+ gtk_widget_realize (GTK_WIDGET (html));
+
+
+ yelp_html_set_base_uri (html, page->page_id);
+ yelp_html_open_stream (html, "application/xhtml+xml");
+ for (length = strlen (page->contents), offset = 0; length > 0; length -= BUFFER_SIZE, offset += BUFFER_SIZE) {
+ g_print ("data: %.*s\n", MIN (length, BUFFER_SIZE), page->contents + offset);
+ yelp_html_write (html, page->contents + offset, MIN (length, BUFFER_SIZE));
+ }
+ yelp_html_close (html);
+
+ yelp_html_print (html);
+
+ print_disconnect (data);
+
+ /* This needs to be done at some point, but we need to wait until printing is done. */
+ /* gtk_widget_destroy (gtk_window); */
+ }
+}
+
+static void
+print_pager_error_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ /* GError *error = yelp_pager_get_error (pager);*/
+
+ d (g_print ("print_pager_error_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+print_pager_cancel_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+ d (g_print ("print_pager_cancel_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+print_pager_finish_cb (YelpPager *pager,
+ gpointer user_data)
+{
+ PrintStruct *data = user_data;
+
+ d (g_print ("print_pager_finish_cb\n"));
+
+ print_disconnect (data);
+}
+
+static void
+window_print_document_cb (GtkAction *action, YelpWindow *window)
+{
+ PrintStruct *data;
+ YelpPager *pager;
+
+ if (!window->priv->current_doc)
+ return;
+
+ pager = yelp_db_print_pager_new (window->priv->current_doc);
+
+ if (!pager) {
+ return;
+ }
+
+ data = g_new0 (PrintStruct, 1);
+ data->pager = pager;
+
+ data->page_handler =
+ g_signal_connect (data->pager,
+ "page",
+ G_CALLBACK (print_pager_page_cb),
+ data);
+ data->error_handler =
+ g_signal_connect (data->pager,
+ "error",
+ G_CALLBACK (print_pager_error_cb),
+ data);
+ data->cancel_handler =
+ g_signal_connect (data->pager,
+ "error",
+ G_CALLBACK (print_pager_cancel_cb),
+ data);
+ data->finish_handler =
+ g_signal_connect (data->pager,
+ "finish",
+ G_CALLBACK (print_pager_finish_cb),
+ data);
+
+ /* handled = */ yelp_pager_start (data->pager);
+}
+
+static void
+window_print_page_cb (GtkAction *action, YelpWindow *window)
+{
+ yelp_html_print (window->priv->html_view);
}
static void
Index: stylesheets/Makefile.am
===================================================================
RCS file: /cvs/gnome/yelp/stylesheets/Makefile.am,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile.am
--- stylesheets/Makefile.am 16 May 2005 20:07:37 -0000 1.14
+++ stylesheets/Makefile.am 6 Jul 2005 19:30:56 -0000
@@ -7,6 +7,7 @@ xsl_DATA = \
db-title.xsl \
info2html.xsl \
man2html.xsl \
+ search2html.xsl \
toc2html.xsl \
yelp-common.xsl
Index: stylesheets/search2html.xsl
===================================================================
RCS file: stylesheets/search2html.xsl
diff -N stylesheets/search2html.xsl
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ stylesheets/search2html.xsl 6 Jul 2005 19:30:56 -0000
@@ -0,0 +1,136 @@
+<?xml version='1.0' encoding='UTF-8'?><!-- -*- indent-tabs-mode: nil -*- -->
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ xmlns:yelp="http://www.gnome.org/yelp/ns"
+ xmlns="http://www.w3.org/1999/xhtml"
+ extension-element-prefixes="yelp"
+ version="1.0">
+
+<xsl:param name="help_icon"/>
+<xsl:param name="help_icon_size"/>
+
+<xsl:param name="yelp.javascript"/>
+
+<xsl:param name="yelp.color.fg"/>
+<xsl:param name="yelp.color.bg"/>
+<xsl:param name="yelp.color.anchor"/>
+<xsl:param name="yelp.color.rule"/>
+<xsl:param name="yelp.color.gray.fg"/>
+<xsl:param name="yelp.color.gray.bg"/>
+<xsl:param name="yelp.color.gray.bg.dark1"/>
+<xsl:param name="yelp.color.gray.bg.dark2"/>
+<xsl:param name="yelp.color.gray.bg.dark3"/>
+<xsl:param name="yelp.color.selected.fg"/>
+<xsl:param name="yelp.color.selected.bg"/>
+<xsl:param name="yelp.color.selected.bg.dark1"/>
+<xsl:param name="yelp.color.selected.bg.dark2"/>
+<xsl:param name="yelp.color.selected.bg.dark3"/>
+<xsl:param name="yelp.color.admon.fg"/>
+<xsl:param name="yelp.color.admon.bg"/>
+<xsl:param name="yelp.color.admon.bg.dark1"/>
+<xsl:param name="yelp.color.admon.bg.dark2"/>
+<xsl:param name="yelp.color.admon.bg.dark3"/>
+
+<xsl:template match="search">
+ <yelp:document href="results">
+ <html>
+ <head>
+ <title>
+ <xsl:value-of select="@title"/>
+ </title>
+ <script type="text/javascript">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat('file://', $yelp.javascript)"/>
+ </xsl:attribute>
+ </script>
+ <style><xsl:text>
+ body {
+ margin: 0px;
+ padding: 0px;
+ }
+ h1 {
+ position: relative;
+ font-size: 1.6em;
+ margin-bottom: 0.4em;
+ margin-top: 12px;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ -moz-border-radius: 6px;
+ border: solid 1px </xsl:text>
+ <xsl:value-of select="$yelp.color.selected.bg.dark1"/><xsl:text>;
+ background-color: </xsl:text>
+ <xsl:value-of select="$yelp.color.selected.bg"/><xsl:text>;
+ color: </xsl:text>
+ <xsl:value-of select="$yelp.color.selected.fg"/><xsl:text>;
+ margin-left: 12px;
+ padding-left: 12px;
+ }
+ body > div > h1 {
+ padding-left: 204px;
+ margin-right: 12px;
+ }
+ h1 img {
+ position: absolute;
+ top: -6px;
+ right: 18px;
+ }
+ div[class~="body"] { }
+ div[class~="leftbar"] {
+ position: absolute;
+ top: 4em;
+ left: 12px;
+ width: 192px;
+ min-height: 192px;
+ text-align: center;
+ <!-- FIXME: this isn't working -->
+ padding-top: </xsl:text>
+ <xsl:value-of select="$help_icon_size"/><xsl:text> px;
+ background-image: url("</xsl:text>
+ <xsl:value-of select="$help_icon"/><xsl:text>");
+ background-position: </xsl:text>
+ <xsl:value-of select="(192 - $help_icon_size) div 2"/><xsl:text>px 0px;
+ background-repeat: no-repeat;
+ opacity: .3;
+ }
+ div[class~="rightbar"] {
+ margin-left: 12px;
+ padding-bottom: 1em;
+ }
+ body > div > div[class~="rightbar"] {
+ margin-left: 216px;
+ margin-right: 12px;
+ }
+ div[class~="tocs"] + div[class~="docs"] {
+ border-top: solid 1px </xsl:text>
+ <xsl:value-of select="$yelp.color.selected.bg"/><xsl:text>;
+ }
+ ul { font-size: 1em; margin-left: 0em; padding-left: 0em; }
+ li {
+ margin-top: 0.5em;
+ margin-left: 1em;
+ padding-left: 0em;
+ list-style-type: none;
+ }
+ dl { margin-left: 0em; padding-left: 0em; }
+ dt { font-size: 1.2em; margin-top: 1em; }
+ dd { margin-left: 1em; margin-top: 0.5em; }
+ a { text-decoration: none; }
+ a:hover { text-decoration: underline; }
+ </xsl:text></style>
+ </head>
+ <body>
+ <h1>
+ <xsl:value-of select="@title"/>
+ </h1>
+ <xsl:apply-templates select="result">
+ <xsl:sort select="normalize-space(@score)"/>
+ <xsl:sort select="position()"/>
+ </xsl:apply-templates>
+ </body>
+ </html>
+ </yelp:document>
+</xsl:template>
+
+<xsl:template match="result">
+ <p><a href="{ uri}"><xsl:value-of select="@uri"/></a></p>
+</xsl:template>
+</xsl:stylesheet>
Index: stylesheets/toc2html.xsl
===================================================================
RCS file: /cvs/gnome/yelp/stylesheets/toc2html.xsl,v
retrieving revision 1.11
diff -u -p -r1.11 toc2html.xsl
--- stylesheets/toc2html.xsl 11 May 2005 18:19:20 -0000 1.11
+++ stylesheets/toc2html.xsl 6 Jul 2005 19:30:56 -0000
@@ -8,6 +8,8 @@
<xsl:param name="help_icon"/>
<xsl:param name="help_icon_size"/>
+<xsl:param name="yelp.javascript"/>
+
<xsl:param name="yelp.color.fg"/>
<xsl:param name="yelp.color.bg"/>
<xsl:param name="yelp.color.anchor"/>
@@ -35,18 +37,21 @@
<title>
<xsl:value-of select="title[1]"/>
</title>
+ <script type="text/javascript">
+ <xsl:attribute name="src">
+ <xsl:value-of select="concat('file://', $yelp.javascript)"/>
+ </xsl:attribute>
+ </script>
<style><xsl:text>
body {
margin: 0px;
padding: 0px;
}
h1 {
+ position: relative;
font-size: 1.6em;
margin-bottom: 0.4em;
margin-top: 12px;
- margin-left: 12px;
- margin-right: 12px;
- padding-left: 204px;
padding-top: 0.2em;
padding-bottom: 0.2em;
-moz-border-radius: 6px;
@@ -56,10 +61,16 @@
<xsl:value-of select="$yelp.color.selected.bg"/><xsl:text>;
color: </xsl:text>
<xsl:value-of select="$yelp.color.selected.fg"/><xsl:text>;
+ margin-left: 12px;
+ padding-left: 12px;
+ }
+ body > div > h1 {
+ padding-left: 204px;
+ margin-right: 12px;
}
h1 img {
position: absolute;
- top: 6px;
+ top: -6px;
right: 18px;
}
div[class~="body"] { }
@@ -81,20 +92,22 @@
opacity: .3;
}
div[class~="rightbar"] {
- margin-left: 216px;
+ margin-left: 12px;
padding-bottom: 1em;
+ }
+ body > div > div[class~="rightbar"] {
+ margin-left: 216px;
margin-right: 12px;
}
div[class~="tocs"] + div[class~="docs"] {
border-top: solid 1px </xsl:text>
<xsl:value-of select="$yelp.color.selected.bg"/><xsl:text>;
}
- ul { margin-left: 0em; padding-left: 0em; }
+ ul { font-size: 1em; margin-left: 0em; padding-left: 0em; }
li {
margin-top: 0.5em;
- margin-left: 0em;
+ margin-left: 1em;
padding-left: 0em;
- font-size: 1.2em;
list-style-type: none;
}
dl { margin-left: 0em; padding-left: 0em; }
@@ -105,63 +118,91 @@
</xsl:text></style>
</head>
<body>
+ <div class="leftbar">
+ </div>
<xsl:apply-templates mode="body.mode" select="."/>
</body>
</html>
</yelp:document>
- <xsl:apply-templates select="toc[.//doc]"/>
+<!-- <xsl:apply-templates select="toc[.//doc]"/> -->
+</xsl:template>
+
+<xsl:template name="header">
+ <xsl:param name="class"/>
+ <h1 id="{ id}-header" onclick="show_hide ('{ id}');" class="{$class}">
+ <xsl:if test="icon">
+ <img src="{icon/@file}"/>
+ </xsl:if>
+ <xsl:apply-templates select="title[1]/node()"/>
+ </h1>
+</xsl:template>
+
+<xsl:template name="children">
+ <xsl:param name="class"/>
+ <div id="{ id}-children">
+ <xsl:if test="@id != 'index'">
+ <xsl:attribute name="style">
+ <xsl:value-of select="'display: none'"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:if test="@id = 'index' or toc[.//doc]">
+ <div class="tocs">
+ <ul>
+ <xsl:for-each select="toc[../@id = 'index' or .//doc]">
+<!-- <xsl:sort select="number(../@id = 'index') * position()"/>
+ <xsl:sort select="normalize-space(title)"/>-->
+ <li class="toc">
+ <xsl:apply-templates mode="children.mode" select="."/>
+ </li>
+ </xsl:for-each>
+ </ul>
+ </div>
+ </xsl:if>
+ <xsl:if test="doc">
+ <div class="docs">
+ <dl>
+ <xsl:for-each select="doc">
+ <xsl:sort select="normalize-space(title)"/>
+ <dt class="doc">
+ <a href="{ href}" title="{ href}">
+ <xsl:if test="tooltip">
+ <xsl:attribute name="title">
+ <xsl:value-of select="tooltip"/>
+ </xsl:attribute>
+ </xsl:if>
+ <xsl:value-of select="title"/>
+ </a>
+ </dt>
+ <dd>
+ <xsl:value-of select="description"/>
+ </dd>
+ </xsl:for-each>
+ </dl>
+ </div>
+ </xsl:if>
+ </div>
</xsl:template>
<xsl:template mode="body.mode" match="toc">
<div class="body">
- <h1>
- <xsl:if test="icon">
- <img src="{icon/@file}"/>
- </xsl:if>
- <xsl:apply-templates select="title[1]/node()"/>
- </h1>
- <div class="leftbar">
- </div>
+ <xsl:call-template name="header">
+ <xsl:with-param name="class" select="'index'"/>
+ </xsl:call-template>
<div class="rightbar">
- <xsl:if test="toc[.//doc]">
- <div class="tocs">
- <ul>
- <xsl:for-each select="toc[../@id = 'index' or .//doc]">
- <xsl:sort select="number(../@id = 'index') * position()"/>
- <xsl:sort select="normalize-space(title)"/>
- <li class="toc">
- <a href="x-yelp-toc:{ id}">
- <xsl:apply-templates select="title[1]/node()"/>
- </a>
- </li>
- </xsl:for-each>
- </ul>
- </div>
- </xsl:if>
- <xsl:if test="doc">
- <div class="docs">
- <dl>
- <xsl:for-each select="doc">
- <xsl:sort select="normalize-space(title)"/>
- <dt class="doc">
- <a href="{ href}" title="{ href}">
- <xsl:if test="tooltip">
- <xsl:attribute name="title">
- <xsl:value-of select="tooltip"/>
- </xsl:attribute>
- </xsl:if>
- <xsl:value-of select="title"/>
- </a>
- </dt>
- <dd>
- <xsl:value-of select="description"/>
- </dd>
- </xsl:for-each>
- </dl>
- </div>
- </xsl:if>
+ <xsl:call-template name="children">
+ <xsl:with-param name="class" select="'index'"/>
+ </xsl:call-template>
</div>
</div>
+</xsl:template>
+
+<xsl:template mode="children.mode" match="toc">
+ <xsl:call-template name="header">
+ <xsl:with-param name="class" select="'child'"/>
+ </xsl:call-template>
+ <xsl:call-template name="children">
+ <xsl:with-param name="class" select="'child'"/>
+ </xsl:call-template>
</xsl:template>
</xsl:stylesheet>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]