commit 1714d2aad108aff966f2aa5f15e36a399623a7e6 Author: Jean-Francois Dockes Date: Fri Dec 2 10:57:48 2016 +0100 comments and traces diff --git a/.hgignore b/.hgignore new file mode 100644 index 00000000..a5e19eea --- /dev/null +++ b/.hgignore @@ -0,0 +1,97 @@ +syntax: glob +*.dep +*.dep.stamp +*.o +.libs +*.la +stamp-h1 +.dirstamp +libtool +.deps +*.lo +*~ +\#* +*.obj +*.sdf +*.tlog +*.lib +*.idb +*.log +*.pdb +.vs +*.exe +*.ilk +ptrans +src/aclocal.m4 +src/compile +src/config.guess +src/config.sub +src/depcomp +src/install-sh +src/Makefile.in +src/ltmain.sh +src/m4/libtool.m4 +src/m4/ltoptions.m4 +src/m4/ltsugar.m4 +src/m4/ltversion.m4 +src/m4/lt~obsolete.m4 +src/missing +src/config.log +src/config.status +src/configure +src/Makefile +src/autom4te.cache +src/common/autoconfig.h +src/common/rclversion.h +src/doc/user/webhelp/docs/* +src/doc/user/usermanual.pdf +src/filters/rclexecm.pyc +src/filters/rcllatinclass.pyc +src/recollindex +src/kde/kioslave/kio_recoll/builddir +src/python/recoll/Makefile +src/python/recoll/build +src/python/recoll/recoll/__init__.pyc +src/python/recoll/setup.py +src/python/samples/recollgui/rclmain.py +src/python/samples/recollgui/rclmain.pyc +src/recollq +src/xadump +src/qtgui/.moc/* +src/qtgui/.obj/* +src/qtgui/.ui/* +src/qtgui/Makefile +src/qtgui/qrc_recoll.cpp +src/qtgui/recoll +src/qtgui/recoll.pro +src/qtgui/recoll.app +src/sampleconf/rclmon.sh +src/sampleconf/recoll.conf +tests/casediac/aspdict.en.rws +tests/casediac/idxstatus.txt +tests/casediac/index.pid +tests/casediac/mimeview +tests/casediac/missing +tests/casediac/recoll.conf +tests/casediac/xapiandb +tests/config/aspdict.en.rws +tests/config/history +tests/config/idxstatus.txt +tests/config/index.pid +tests/config/missing +tests/config/xapiandb +tests/indexedmimetypes/aspdict.en.rws +tests/indexedmimetypes/idxstatus.txt +tests/indexedmimetypes/index.pid +tests/indexedmimetypes/mimeview +tests/indexedmimetypes/missing +tests/indexedmimetypes/recoll.conf +tests/indexedmimetypes/xapiandb +tests/xattr/mimeview +website/usermanual/* +website/idxthreads/forkingRecoll.html +website/idxthreads/xapDocCopyCrash.html +website/pages/recoll-mingw.html +website/pages/recoll-webui-install-wsgi.html +website/pages/recoll-windows.html +website/pages/recoll-windows-faq.html diff --git a/packaging/FreeBSD/recoll/Makefile b/packaging/FreeBSD/recoll/Makefile new file mode 100644 index 00000000..a2ecc56d --- /dev/null +++ b/packaging/FreeBSD/recoll/Makefile @@ -0,0 +1,34 @@ +# New ports collection makefile for: recoll +# Date created: 5 December 2005 +# Whom: J.F. Dockes +# +# $FreeBSD: ports/deskutils/recoll/Makefile,v 1.44 2010/10/09 17:52:42 makc Exp $ +# + +PORTNAME= recoll +PORTVERSION= 1.16.2 +CATEGORIES= deskutils +MASTER_SITES= http://www.lesbonscomptes.com/recoll/ + +MAINTAINER= jf@dockes.org +COMMENT= A personal full text search package, based on QT and Xapian + +BUILD_DEPENDS= xapian-core>=1.0.12:${PORTSDIR}/databases/xapian-core +RUN_DEPENDS:= ${BUILD_DEPENDS} + +USE_QT_VER= 4 +QT_COMPONENTS= gui qmake_build uic_build moc_build rcc_build +GNU_CONFIGURE= yes +USE_GMAKE= yes +USE_ICONV= yes +INSTALLS_ICONS= yes +USE_FAM= yes + +MAN1= recoll.1 recollindex.1 +MAN5= recoll.conf.5 + +post-patch: + ${REINPLACE_CMD} -e 's/^CXXFLAGS =/CXXFLAGS ?=/' \ + ${WRKSRC}/mk/localdefs.in + +.include diff --git a/packaging/FreeBSD/recoll/distinfo b/packaging/FreeBSD/recoll/distinfo new file mode 100644 index 00000000..305b0c06 --- /dev/null +++ b/packaging/FreeBSD/recoll/distinfo @@ -0,0 +1,2 @@ +SHA256 (recoll-1.16.2.tar.gz) = f0f29dff2d82ef8541c51963870f31daf28472f3c8822c81c17c346769b77355 +SIZE (recoll-1.16.2.tar.gz) = 1422148 diff --git a/packaging/FreeBSD/recoll/pkg-descr b/packaging/FreeBSD/recoll/pkg-descr new file mode 100644 index 00000000..1aa20b03 --- /dev/null +++ b/packaging/FreeBSD/recoll/pkg-descr @@ -0,0 +1,24 @@ +Recoll is a personal full text search package with a QT graphical +interface. It is based on a very strong backend (Xapian), for which it +provides an easy to use and feature-rich interface. + +Features: + * Free, GPL license. + * QT-based GUI. + * Supports the following document types (and their compressed versions): + - Natively: text, html, OpenOffice files, maildir and mailbox + (Mozilla and Thunderbird mail ok) with attachments, gaim log files. + - With external helpers: pdf (pdftotext), postscript (ghostscript), + msword (antiword), excel, ppt (catdoc), rtf (unrtf), + * Powerful query facilities, with boolean searches, phrases, filter on + file types and directory tree. + * Support for multiple charsets. Internal processing and storage uses + Unicode UTF-8. + * Stemming performed at query time (can switch stemming language after + indexing) + * Easy installation. No database daemon, web server or exotic language + necessary. + * An indexer which runs either as a thread inside the GUI or as an + external, cron'able program. + +WWW: http://www.lesbonscomptes.com/recoll/ diff --git a/packaging/FreeBSD/recoll/pkg-plist b/packaging/FreeBSD/recoll/pkg-plist new file mode 100644 index 00000000..bfcd9397 --- /dev/null +++ b/packaging/FreeBSD/recoll/pkg-plist @@ -0,0 +1,100 @@ +bin/recoll +bin/recollindex +share/applications/recoll-searchgui.desktop +share/icons/hicolor/48x48/apps/recoll.png +share/pixmaps/recoll.png +%%DATADIR%%/doc/docbook.css +%%DATADIR%%/doc/usermanual.html +%%DATADIR%%/examples/fields +%%DATADIR%%/examples/mimeconf +%%DATADIR%%/examples/mimemap +%%DATADIR%%/examples/mimeview +%%DATADIR%%/examples/rclmon.sh +%%DATADIR%%/examples/recoll.conf +%%DATADIR%%/filters/hotrecoll.py +%%DATADIR%%/filters/rclabw +%%DATADIR%%/filters/rclaptosidman +%%DATADIR%%/filters/rclaudio +%%DATADIR%%/filters/rclchm +%%DATADIR%%/filters/rcldjvu +%%DATADIR%%/filters/rcldoc +%%DATADIR%%/filters/rcldvi +%%DATADIR%%/filters/rclexecm.py +%%DATADIR%%/filters/rclfb2 +%%DATADIR%%/filters/rclflac +%%DATADIR%%/filters/rclgaim +%%DATADIR%%/filters/rclics +%%DATADIR%%/filters/rclid3 +%%DATADIR%%/filters/rclimg +%%DATADIR%%/filters/rclinfo +%%DATADIR%%/filters/rclkar +%%DATADIR%%/filters/rclkwd +%%DATADIR%%/filters/rcllatinclass.py +%%DATADIR%%/filters/rcllatinstops.zip +%%DATADIR%%/filters/rcllyx +%%DATADIR%%/filters/rclman +%%DATADIR%%/filters/rclnull +%%DATADIR%%/filters/rclogg +%%DATADIR%%/filters/rclopxml +%%DATADIR%%/filters/rclpdf +%%DATADIR%%/filters/rclppt +%%DATADIR%%/filters/rclps +%%DATADIR%%/filters/rclpurple +%%DATADIR%%/filters/rclpython +%%DATADIR%%/filters/rclrar +%%DATADIR%%/filters/rclrtf +%%DATADIR%%/filters/rclscribus +%%DATADIR%%/filters/rclshowinfo +%%DATADIR%%/filters/rclsiduxman +%%DATADIR%%/filters/rclsoff +%%DATADIR%%/filters/rclsvg +%%DATADIR%%/filters/rcltex +%%DATADIR%%/filters/rcltext +%%DATADIR%%/filters/rcluncomp +%%DATADIR%%/filters/rclwar +%%DATADIR%%/filters/rclwpd +%%DATADIR%%/filters/rclxls +%%DATADIR%%/filters/rclzip +%%DATADIR%%/filters/rcl7z +%%DATADIR%%/filters/xdg-open +%%DATADIR%%/images/aptosid-book.png +%%DATADIR%%/images/aptosid-manual.png +%%DATADIR%%/images/document.png +%%DATADIR%%/images/drawing.png +%%DATADIR%%/images/folder.png +%%DATADIR%%/images/html.png +%%DATADIR%%/images/image.png +%%DATADIR%%/images/message.png +%%DATADIR%%/images/mozilla_doc.png +%%DATADIR%%/images/pdf.png +%%DATADIR%%/images/pidgin.png +%%DATADIR%%/images/postscript.png +%%DATADIR%%/images/presentation.png +%%DATADIR%%/images/sidux-book.png +%%DATADIR%%/images/source.png +%%DATADIR%%/images/sownd.png +%%DATADIR%%/images/soffice.png +%%DATADIR%%/images/spreadsheet.png +%%DATADIR%%/images/text-x-python.png +%%DATADIR%%/images/txt.png +%%DATADIR%%/images/wordprocessing.png +%%DATADIR%%/translations/recoll_cs.qm +%%DATADIR%%/translations/recoll_fr.qm +%%DATADIR%%/translations/recoll_it.qm +%%DATADIR%%/translations/recoll_lt.qm +%%DATADIR%%/translations/recoll_de.qm +%%DATADIR%%/translations/recoll_uk.qm +%%DATADIR%%/translations/recoll_ru.qm +%%DATADIR%%/translations/recoll_tr.qm +%%DATADIR%%/translations/recoll_xx.qm +@dirrm %%DATADIR%%/doc +@dirrm %%DATADIR%%/examples +@dirrm %%DATADIR%%/filters +@dirrm %%DATADIR%%/images +@dirrm %%DATADIR%%/translations +@dirrm %%DATADIR%% +@dirrmtry share/applications +@dirrmtry share/icons/hicolor/48x48/apps +@dirrmtry share/icons/hicolor/48x48 +@dirrmtry share/icons/hicolor +@dirrmtry share/icons diff --git a/packaging/debian/buildppa.sh b/packaging/debian/buildppa.sh new file mode 100644 index 00000000..3c9252c3 --- /dev/null +++ b/packaging/debian/buildppa.sh @@ -0,0 +1,192 @@ +#!/bin/sh +# Packages needed +# sudo apt-get install g++ gnupg dput lintian mini-dinstall yaclc bzr devscripts +# For the kio: (and kdesdk?) +# sudo apt-get install pkg-kde-tools cdbs + +RCLVERS=1.22.4 +LENSVERS=1.19.10.3543 +SCOPEVERS=1.20.2.4 +PPAVERS=1 + +# +RCLSRC=/y/home/dockes/projets/fulltext/recoll/src +SCOPESRC=/y/home/dockes/projets/fulltext/unity-scope-recoll +RCLDOWNLOAD=/y/home/dockes/projets/lesbonscomptes/recoll + +case $RCLVERS in + [23]*) PPANAME=recollexp-ppa;; + 1.14*) PPANAME=recoll-ppa;; + *) PPANAME=recoll15-ppa;; +esac +#PPANAME=recollexp-ppa +echo "PPA: $PPANAME. Type CR if Ok, else ^C" +read rep + +fatal() +{ + echo $*; exit 1 +} + +check_recoll_orig() +{ + if test ! -f recoll_${RCLVERS}.orig.tar.gz ; then + cp -p $RCLDOWNLOAD/recoll-${RCLVERS}.tar.gz \ + recoll_${RCLVERS}.orig.tar.gz || \ + fatal "Can find neither recoll_${RCLVERS}.orig.tar.gz nor " \ + "recoll-${RCLVERS}.tar.gz" + fi +} + +# Note: recoll 1.22+ builds on precise fail. precise stays at 1.21 + +####### QT +debdir=debian +# Note: no new releases for lucid: no webkit. Or use old debianrclqt4 dir. +series="trusty xenial yakkety" +series= + +if test "X$series" != X ; then + check_recoll_orig + test -d recoll-${RCLVERS} || tar xvzf recoll_${RCLVERS}.orig.tar.gz +fi + +for series in $series ; do + + rm -rf recoll-${RCLVERS}/debian + cp -rp ${debdir}/ recoll-${RCLVERS}/debian || exit 1 + + if test -f $debdir/control-$series ; then + cp -f -p $debdir/control-$series recoll-${RCLVERS}/debian/control + else + cp -f -p $debdir/control recoll-${RCLVERS}/debian/control + fi + + sed -e s/SERIES/${series}/g \ + -e s/PPAVERS/${PPAVERS}/g \ + < ${debdir}/changelog > recoll-${RCLVERS}/debian/changelog + + (cd recoll-${RCLVERS};debuild -S -sa) || break + + dput $PPANAME recoll_${RCLVERS}-1~ppa${PPAVERS}~${series}1_source.changes +done + +### KIO +series="trusty xenial yakkety" +series="xenial yakkety" + +debdir=debiankio +topdir=kio-recoll-${RCLVERS} +if test "X$series" != X ; then + check_recoll_orig + if test ! -f kio-recoll_${RCLVERS}.orig.tar.gz ; then + cp -p recoll_${RCLVERS}.orig.tar.gz \ + kio-recoll_${RCLVERS}.orig.tar.gz || exit 1 + fi + if test ! -d $topdir ; then + mkdir temp + cd temp + tar xvzf ../recoll_${RCLVERS}.orig.tar.gz || exit 1 + mv recoll-${RCLVERS} ../$topdir || exit 1 + cd .. + fi +fi +for svers in $series ; do + + rm -rf $topdir/debian + cp -rp ${debdir}/ $topdir/debian || exit 1 + + sed -e s/SERIES/$svers/g \ + -e s/PPAVERS/${PPAVERS}/g \ + < ${debdir}/changelog > $topdir/debian/changelog ; + if test $svers = "trusty" ; then + mv -f $topdir/debian/control-4 $topdir/debian/control + mv -f $topdir/debian/rules-4 $topdir/debian/rules + else + rm -f $topdir/debian/control-4 $topdir/debian/rules-4 + fi + (cd $topdir;debuild -S -sa) || exit 1 + + dput $PPANAME kio-recoll_${RCLVERS}-0~ppa${PPAVERS}~${svers}1_source.changes + +done + +### Unity Lens +series="precise" +series= + +debdir=debianunitylens +topdir=recoll-lens-${LENSVERS} +if test "X$series" != X ; then + if test ! -f recoll-lens_${LENSVERS}.orig.tar.gz ; then + if test -f recoll-lens-${LENSVERS}.tar.gz ; then + mv recoll-lens-${LENSVERS}.tar.gz \ + recoll-lens_${LENSVERS}.orig.tar.gz + else + fatal "Can find neither recoll-lens_${LENSVERS}.orig.tar.gz nor " \ + "recoll-lens-${LENSVERS}.tar.gz" + fi + fi + test -d $topdir || tar xvzf recoll-lens_${LENSVERS}.orig.tar.gz || exit 1 +fi + +for series in $series ; do + + rm -rf $topdir/debian + cp -rp ${debdir}/ $topdir/debian || exit 1 + + sed -e s/SERIES/$series/g \ + -e s/PPAVERS/${PPAVERS}/g \ + < ${debdir}/changelog > $topdir/debian/changelog ; + + (cd $topdir;debuild -S -sa) || break + + dput $PPANAME \ + recoll-lens_${LENSVERS}-1~ppa${PPAVERS}~${series}1_source.changes + +done + +### Unity Scope +series="trusty xenial yakkety" +series= + +debdir=debianunityscope +if test ! -d ${debdir}/ ; then + rm -f ${debdir} + ln -s ${SCOPESRC}/debian $debdir +fi +topdir=unity-scope-recoll-${SCOPEVERS} +if test "X$series" != X ; then + if test ! -f unity-scope-recoll_${SCOPEVERS}.orig.tar.gz ; then + if test -f unity-scope-recoll-${SCOPEVERS}.tar.gz ; then + mv unity-scope-recoll-${SCOPEVERS}.tar.gz \ + unity-scope-recoll_${SCOPEVERS}.orig.tar.gz + else + if test -f $RCLDOWNLOAD/unity-scope-recoll-${SCOPEVERS}.tar.gz;then + cp -p $RCLDOWNLOAD/unity-scope-recoll-${SCOPEVERS}.tar.gz \ + unity-scope-recoll_${SCOPEVERS}.orig.tar.gz || fatal copy + else + fatal "Can find neither " \ + "unity-scope-recoll_${SCOPEVERS}.orig.tar.gz nor " \ + "$RCLDOWNLOAD/unity-scope-recoll-${SCOPEVERS}.tar.gz" + fi + fi + fi + test -d $topdir || tar xvzf unity-scope-recoll_${SCOPEVERS}.orig.tar.gz \ + || exit 1 +fi +for series in $series ; do + + rm -rf $topdir/debian + cp -rp ${debdir}/ $topdir/debian || exit 1 + + sed -e s/SERIES/$series/g \ + -e s/PPAVERS/${PPAVERS}/g \ + < ${debdir}/changelog > $topdir/debian/changelog ; + + (cd $topdir;debuild -S -sa) || break + + dput $PPANAME \ + unity-scope-recoll_${SCOPEVERS}-1~ppa${PPAVERS}~${series}1_source.changes + +done diff --git a/packaging/debian/debian/README.Debian b/packaging/debian/debian/README.Debian new file mode 100644 index 00000000..3866c0a6 --- /dev/null +++ b/packaging/debian/debian/README.Debian @@ -0,0 +1,23 @@ +README for Debian +----------------- + + Installing over an older version: 1.18 introduces significant index formats + changes to support optional character case and diacritics sensitivity, and it + will be advisable to reset the index in most cases. This will be best done by + destroying the index directory (rm -rf ~/.recoll/xapiandb). + + If 1.18 is not configured for case and diacritics sensitivity, it is mostly + compatible with 1.17 indexes. + + -- Kartik Mistry Tue, 13 Nov 2012 12:33:00 +0530 + + Installing over an older version: 1.16 is mostly compatible with 1.15 indexes, + except for a few differences for weird terms containing punctuation signs. + Perform a full index pass if installing over an older version. The simplest + way to do this is to quit all recoll programs and just delete the index + directory (rm -rf ~/.recoll/xapiandb), then start recoll or recollindex. + recollindex -z will do the same in most cases. + + Also, using the anchored search feature requires a full reindex. + + -- Kartik Mistry Thu, 22 Sep 2011 21:30:05 +0530 diff --git a/packaging/debian/debian/changelog b/packaging/debian/debian/changelog new file mode 100644 index 00000000..32f27329 --- /dev/null +++ b/packaging/debian/debian/changelog @@ -0,0 +1,639 @@ +recoll (1.22.4-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Fix advanced search 'start search' not doing anything with qt5 + + -- Jean-Francois Dockes Tue, 25 Nov 2016 11:38:00 +0100 + +recoll (1.22.3-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * + + -- Jean-Francois Dockes Tue, 21 Jun 2016 15:11:00 +0200 + +recoll (1.22.2-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Packaging fixes. + + -- Jean-Francois Dockes Thu, 16 Jun 2016 09:11:00 +0200 + +recoll (1.22.1-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Fixed two GUI crashes + * Small other fixes + + -- Jean-Francois Dockes Tue, 14 Jun 2016 17:31:00 +0200 + +recoll (1.22.0-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * New build based on autotools + * Synonyms + * Windows port + + -- Jean-Francois Dockes Tue, 05 Apr 2016 16:01:00 +0200 + +recoll (1.21.5-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Fix query language parser for multiple mime or rclcat entries + + -- Jean-Francois Dockes Fri, 29 Jan 2016 14:48:00 +0200 + +recoll (1.21.4-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Show confirmation dialog when opening temp files + small bug fixes + + -- Jean-Francois Dockes Tue, 12 Jan 2016 16:19:00 +0200 + +recoll (1.21.3-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Fix webcache size being capped at 1 GB + + -- Jean-Francois Dockes Sat, 31 Oct 2015 09:26:00 +0200 + +recoll (1.21.2-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * New special indexing dialog in GUI + * Fix advanced search dialog "Any Clause" mode + * Fixed a few bounds issues catched by Windows VC++ + * Miscellaneous other minor fixes + + -- Jean-Francois Dockes Tue, 01 Oct 2015 09:40:00 +0200 + +recoll (1.21.0-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * New bison-based query parser. + * Improves filter execution performance + * Save/reload queries + + -- Jean-Francois Dockes Tue, 16 Jun 2015 18:10:00 +0200 + +recoll (1.20.6-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Fix some decompression issues with serious performance and + system load consequences in some cases (depending on data): minimum + checking that enough temp space is available before uncompressing, no + need to uncompress tar.gz files, set a default of 20 MBs for + maxcompressedfilekbs. + * rclscribus fixes. + * GUI messages: Danish translation and fix 2 dialogs which were not + translated improvements. + + -- Jean-Francois Dockes Sat, 25 Apr 2015 14:36:00 +0200 + +recoll (1.20.4-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Should have been in 1.20.3: skip compressed fs image files like xxx.img.gz + by default (mimemap:recoll_noindex). + + -- Jean-Francois Dockes Mon, 30 Mar 2015 10:06:00 +0200 + +recoll (1.20.3-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * fixes a bug where the real time indexer did not process the web queue + * miscellaneous usability improvements in the GUI. + * Copy sample fragbuts.xml file if it does not exist + + -- Jean-Francois Dockes Sat, 28 Mar 2015 09:40:00 +0200 + +recoll (1.20.1-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.20.1 brings improved indexing of compound words like email addresses + and miscellaneous usability improvements in the GUI. + + -- Jean-Francois Dockes Fri, 19 Dec 2014 08:14:00 +0200 + +recoll (1.19.14p2-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.14p2 fixes Bengali diacritics processing, a memory leak in the + Python module, and a few minor issues in the filters. + + -- Jean-Francois Dockes Thu, 11 Sep 2014 07:47:00 +0200 + +recoll (1.19.14p1-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.14p1 fixes a descriptor and memory leak in the Python module. The + main programs and library are unchanged. + + -- Jean-Francois Dockes Thu, 26 Jun 2014 13:14:00 +0200 + +recoll (1.19.14-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.14 fixes two relatively minor but ennoying issues in indexing: + + - The use of a separate readonly Database object for querying the index + while indexing would trigger Xapian errors, (bad block reads), and + subsequent up-to-date check failures (leading to unnecessary + reindexing). The jury is out as to the cause, but using the same + object for reading and writing seems to eliminate the problem. + + - A spurious log message in the child process between forking and + executing the filter could block on a mutex, and lead to a 20 mn + timeout for the affected father process thread (happened only in + multithread mode). + + -- Jean-Francois Dockes Sat, 07 Jun 2014 18:56:00 +0200 + +recoll (1.19.13-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.13 hopefully fixes the multithreaded indexing crashes and silences + the noisy ppt extractor failures. + + -- Jean-Francois Dockes Thu, 06 May 2014 14:22:00 +0200 + +recoll (1.19.12p2-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.12 p1 + restable doubleclick + + -- Jean-Francois Dockes Sun, 07 Apr 2014 16:17:00 +0200 + +recoll (1.19.12p1-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * 1.19.12 install forgot the xls filter + + -- Jean-Francois Dockes Sun, 06 Apr 2014 06:57:00 +0200 + +recoll (1.19.12-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Minor fixes to 1.19.11. Make metadata stored length a parameter. + * New xls dumper based on mso-dumper removes catdoc dependancy + * Move out the code for the Ubuntu Unity lens and scope + + -- Jean-Francois Dockes Mon, 02 Apr 2014 15:12:00 +0200 + +recoll (1.19.11p1-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * minor fixes to 1.19.10 + + -- Jean-Francois Dockes Mon, 27 Nov 2013 09:54:00 +0200 + +recoll (1.19.10-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Support for saucy in 1.19. Separate python and python3 packages + + -- Jean-Francois Dockes Sat, 23 Nov 2013 16:01:46 +0100 + +recoll (1.18.1-1) experimental; urgency=low + + * New upstream version: + + Please read README.Debian for changes in index db format. + * debian/patches/txtcsvopen.diff: + + Dropped. Merged upstream. + * debian/patches/fix-manpage-typos.patch: + + Added patch to fix manpage typos and groff errors. + * debian/control: + + Added VCS-* fields. + + -- Kartik Mistry Tue, 13 Nov 2012 12:29:46 +0530 + +recoll (1.17.3-2) unstable; urgency=medium + + * debian/rules: + + Call dh_python2 for python-recoll. (Closes: #681586) + * debian/control: + + Added X-Python-Version field for correct Python version dependency. + + -- Kartik Mistry Sat, 14 Jul 2012 20:20:56 +0530 + +recoll (1.17.3-1) unstable; urgency=low + + * New upstream release. + * debian/patches/txtcsvopen.diff: + + Added patch to fix opening of compressed text-files with gnumeric. + (Closes: #674756) + + -- Kartik Mistry Fri, 08 Jun 2012 11:46:57 +0530 + +recoll (1.17.2-1) unstable; urgency=low + + * New upstream release: + + Dropped patches: fix-kFreeBSD-ftbfs.patch, recoll_ionice_getpid.patch. + These are merged with upstream. + + Refreshed patch: fix-python-install.patch. + * debian/rules, debian/control: + + Added hardening support. + * debian/copyright: + + Fixed duplicate Copyright sections. + + -- Kartik Mistry Fri, 18 May 2012 10:59:21 +0530 + +recoll (1.17.1-2) unstable; urgency=low + + * debian/patches: + + fix-kFreeBSD-ftbfs.patch: Added patch to fix FTBFS on kFreeBSD from + upstream (Closes: #667083) + + recoll_ionice_getpid.patch: Added patch to fix FTBFS with gcc-4.7 from + upstream (Closes: #667352) + + -- Kartik Mistry Wed, 04 Apr 2012 12:16:48 +0530 + +recoll (1.17.1-1) unstable; urgency=low + + * New upstream release. + * Enable Python module resulting into new binary: python-recoll. + * debian/control: + + Updated Build-Deps: libqtwebkit-dev, python-all-dev. + + Added python-recoll binary. + + Updated Standards-Version to 3.9.3 + * debian/rules: + + Build Python module by default. + * debian/recoll.menu, debian/python-recoll.install, debian/recoll.install: + + Changes for new binary package. + * debian/copyright: + + Updated to copyright-format 1.0 + + Updated upstream and Debian copyright. + + Fixed unicode.org/copyright.html URL. + + -- Kartik Mistry Tue, 27 Mar 2012 12:15:51 +0530 + +recoll (1.16.2-1) unstable; urgency=low + + * New upstream release. + * debian/copyright: + + Updated as per DEP-5 format, simplying copyright file. + * debian/control: + + Dropped: flac, vorbis-tools and libid3-tools from Suggests, as + python-mutagen handles audio now. + + Dropped: lyx from Suggests, as it will be too heavy for most of users as + discussed with upstream. + * debian/rules: + + Use STRIP variable to strip during install phase. This makes patch + 01_nostrip_final_binaries_437901.diff obsolete, removed this patch. + + -- Kartik Mistry Wed, 09 Nov 2011 20:35:16 +0530 + +recoll (1.16.1-1) unstable; urgency=low + + * New upstream release. + * debian/copyright: + + Added missing GPL-3 URL in debian/* copyright section. + + -- Kartik Mistry Thu, 29 Sep 2011 10:06:54 +0530 + +recoll (1.16.0-1) unstable; urgency=low + + * New upstream release: + + See README.Debian for upgrade note and information. + * debian/copyright: + + Updated as per latest DEP-5 format. + * debian/control: + + Recommends: xdg-utils now. + * debian/rules: + + Added recommends build targets. + + -- Kartik Mistry Thu, 22 Sep 2011 21:30:25 +0530 + +recoll (1.15.9-1) unstable; urgency=low + + * New upstream release: + + Dropped patch 02_recoll_staticfix_626882.diff, merged upstream + + -- Kartik Mistry Wed, 15 Jun 2011 09:20:20 +0530 + +recoll (1.15.8-2) unstable; urgency=low + + * debian/patches/02_recoll_staticfix_626882.diff: + + Added patch to fix segfault in 1.15.8. Patch from Jean-Francois Dockes + (Closes: #626882) + + -- Kartik Mistry Tue, 17 May 2011 09:57:50 +0530 + +recoll (1.15.8-1) unstable; urgency=low + + * New upstream release. + * debian/patches/02_kfreebsd-ftbfs.diff: + + Removed. Merged with upstream. + * debian/control: + + Updated to Standards-Version 3.9.2 (no changes needed) + + -- Kartik Mistry Thu, 12 May 2011 09:47:21 +0530 + +recoll (1.15.7-2) unstable; urgency=low + + * Applied patch 02_kfreebsd-ftbfs.diff from upstream to fix FTBFS + on kFreeBSD-* (Closes: #618796) + * debian/copyright: + + Updated to latest DEP-5 specification + + -- Kartik Mistry Fri, 15 Apr 2011 18:38:54 +0530 + +recoll (1.15.7-1) unstable; urgency=low + + * New upstream release: + + Fixed: Segmentation fault when file type radio button clicked. + (Closes: #617353) + * debian/patches/02_manpage_fix.diff: + + Removed. Merged with upstream. + + -- Kartik Mistry Sun, 13 Mar 2011 09:07:57 +0530 + +recoll (1.15.2-1) unstable; urgency=low + + * Upload to unstable + * New upstream release + * debian/patches: + + Refreshed 01_nostrip_final_binaries_437901.diff + + Added 02_manpage_fix.diff to fix manpage groff issues + + -- Kartik Mistry Tue, 15 Feb 2011 11:25:58 +0530 + +recoll (1.14.4-1) experimental; urgency=low + + * New upstream release + * debian/copyright: + + Updated for DEP-5 format specification + + -- Kartik Mistry Thu, 02 Dec 2010 00:29:06 +0530 + +recoll (1.14.2-1) experimental; urgency=low + + * New upstream release + * debian/control: + + Added xlstproc as Recommends (Closes: #587684) + + Added python-mutagen as Suggests + * debian/patches: + + Refreshed 01_nostrip_final_binaries_437901.diff + + Removed 02_recoll-prepare-for-xapian-1.2.diff, merged with upstream + + -- Kartik Mistry Mon, 27 Sep 2010 17:52:17 +0530 + +recoll (1.13.04-3) unstable; urgency=low + + * Added patch for xapian 1.2 compatibility from Olly Betts + (Closes: #579929) + + -- Kartik Mistry Mon, 03 May 2010 09:47:16 +0530 + +recoll (1.13.04-2) unstable; urgency=low + + * debian/control: + + Added missing packages to Suggests: flac, libid3-tools, lyx, pstotext, + python-chm, untex, vorbis-tools Thanks to Ivan Vilata i Balaguer + (Closes: #578441) + + -- Kartik Mistry Fri, 23 Apr 2010 11:07:00 +0530 + +recoll (1.13.04-1) unstable; urgency=low + + * New upstream release + + -- Kartik Mistry Fri, 16 Apr 2010 10:39:02 +0530 + +recoll (1.13.02-2) unstable; urgency=low + + * debian/control: + + Don't suggest xpdf (Closes: #569333) + * debian/copyright: + + Updated Debian package copyright year + * Removed unused README.source file + + -- Kartik Mistry Fri, 19 Feb 2010 10:42:53 +0530 + +recoll (1.13.02-1) unstable; urgency=low + + * New upstream release + * debian/control: + + Updated to Standards-Version 3.8.4 (no changes needed) + + -- Kartik Mistry Wed, 03 Feb 2010 11:00:53 +0530 + +recoll (1.13.01-1) unstable; urgency=low + + * New upstream release + + Fixed bug that causes field values ignored for Capitalized words and + phrases + + -- Kartik Mistry Fri, 08 Jan 2010 10:09:15 +0530 + +recoll (1.13.00-1) unstable; urgency=low + + * New upstream release + * debian/control: + + Fixed package descriptions, replaced QT->Qt (Closes: #563725) + * debian/patches/01_nostrip_final_binaries_437901.diff: + + Refreshed patch for upstream changes + * Converted package to new source format '3.0 (quilt)' + + -- Kartik Mistry Tue, 05 Jan 2010 23:23:30 +0530 + +recoll (1.12.4-1) unstable; urgency=low + + * New upstream release: + + Fixed FTBFS with binutils-gold (Closes: #556315) + + -- Kartik Mistry Fri, 11 Dec 2009 00:08:37 +0530 + +recoll (1.12.3-1) unstable; urgency=low + + * New upstream release + * debian/control: + + Updated Build-Depends on libqt4-dev as we are building Qt4 ui now + * debian/rules: + + Make sure that we call qmake-qt4 + + -- Kartik Mistry Thu, 29 Oct 2009 22:44:50 +0530 + +recoll (1.12.2-1) unstable; urgency=low + + * New upstream release: + + Dropped patch 02_manpage_fixes.diff, merged with upstream + * Added debian/README.source file to confirm with latest policy + * Removed debian/docs, we are using dh_installdocs in debian/rules + * debian/control: + + Wrapped up Build-Depends + + Depends on quilt, since patch system is using quilt now + + Updated to Standards-Version 3.8.3 + + Updated dependency on libxapian-dev (>= 1.0.15) + * debian/rules: + + Changes for quilt migration + + -- Kartik Mistry Fri, 23 Oct 2009 10:14:05 +0530 + +recoll (1.12.1-1) unstable; urgency=low + + * New upstream release + * debian/control: + + Updated to Standards-Version 3.8.2 (no changes needed) + * debian/copyright: + + [Lintian] Removed licenses URL links to symlink + + -- Kartik Mistry Sat, 27 Jun 2009 20:08:28 +0530 + +recoll (1.12.0-1) unstable; urgency=low + + * New upstream release + * debian/copyright: + + [Lintian] Updated for use of correct copyright symbol © instead of (C) + + Updated Debian packaging copyright year + * debian/rules: + + Used dh_prep instead of deprecated dh_clean -k + * debian/control: + + Updated debhelper dependency to 7 + * debian/patches: + + Dropped 02_gcc-snapshot-missing-headers-fix.dpatch, merged with upstream + + Added patch 02_manpage_fixes.dpatch for groff warnings + + -- Kartik Mistry Sat, 28 Feb 2009 14:33:53 +0530 + +recoll (1.11.0-2) unstable; urgency=low + + * debian/control: + + Added versioned build-dep on libxapian-dev, Thanks to Brad Sawatzky + for catch (Closes: #507473) + + Add libimage-exiftool-perl as Suggests in which I forgot in + previous upload + * debian/changelog: + + Fixed typo from previous upload entry + + -- Kartik Mistry Wed, 03 Dec 2008 15:05:55 +0530 + +recoll (1.11.0-1) unstable; urgency=low + + * New upstream release: + + Remembers missing filters in first run (Closes: #500690) + * debian/control: + + Added libimage-exiftool-perl as Suggests (Closes: #502427) + + Added Python as recommaded due to filters/rclpython script + although, its not necessary as it will be installed only + when Python is present + * debian/patches: + + Refreshed patch for gcc 4.4 FTBFS (Closes: #505376) + * debian/copyright: + + Updated for newly added filter and image files + + -- Kartik Mistry Thu, 13 Nov 2008 21:18:15 +0530 + +recoll (1.10.6-1) unstable; urgency=low + + * New upstream release + + Fixed typo in tooltip in indexing configuration (Closes: #486689) + + Dropped patch 03_manpage_fixes.dpatch, merged with upstream + * debian/control: + + Updated to Standards-Version 3.8.0 (no changes needed) + + Updated my maintainer email address + * debian/copyright: + + Updated my maintainer email address + + Updated license text to proposed license format + + Updated upstream copyright year + + -- Kartik Mistry Thu, 11 Sep 2008 16:06:48 +0530 + +recoll (1.10.2-1) unstable; urgency=low + + * New upstream release + + Updated patch debian/patches/02_gcc-snapshot-missing-headers-fix.dpatch + Some portions are now merged with upstream + * debian/copyright: + + Fixed indentation to 80 characters + + Updated Debian package copyright year + + -- Kartik Mistry Thu, 29 May 2008 23:25:40 +0530 + +recoll (1.10.1-1) unstable; urgency=low + + * New upstream release + + Updated debian/patches/02_gcc-snapshot-missing-headers-fix.dpatch + Some portions are merged with upstream + * debian/control: + + Fixed short description, Thanks to Mohammed Adnène Trojette + + * debian/patches/03_manpage_fixes.dpatch: + + Added patch to fix manpage groff warnings + + -- Kartik Mistry Wed, 27 Feb 2008 18:41:25 +0530 + +recoll (1.10.0-5) unstable; urgency=low + + * debian/patches/02_gcc-snapshot-missing-headers-fix.dpatch: + + Really fixed the FTBFS with gcc-4.3/g++-4.3 (Closes: #455652) + + -- Kartik Mistry Sun, 27 Jan 2008 14:37:53 +0530 + +recoll (1.10.0-4) unstable; urgency=low + + * debian/patches/02_gcc-snapshot-missing-headers-fix.dpatch: + + Updated patch to fix missing include header in qtgui/main.cpp + (Closes: #455652) + * debian/copyright: + + Updated missing license for qtgui/q3richtext_p.h + + Moved other copyright holders for GPL above license + to make it readable + + -- Kartik Mistry Wed, 23 Jan 2008 10:42:20 +0530 + +recoll (1.10.0-3) unstable; urgency=low + + * debian/control: + + Added external helper programs and utilities to Suggests field + (Closes: #441629, #457033) + + -- Kartik Mistry Fri, 28 Dec 2007 08:12:52 +0530 + +recoll (1.10.0-2) unstable; urgency=low + + * debian/control: + + Updated Standards-Version to 3.7.3 + * debian/patches/02_gcc-snapshot-missing-headers-fix.dpatch: + + Added patch to fix compilation with gcc-snapshot due to + missing headers (Closes: #455652) + * debian/rules: + + Fixed clean target + + -- Kartik Mistry Tue, 11 Dec 2007 14:42:47 +0530 + +recoll (1.10.0-1) unstable; urgency=low + + * New upstream release + * debian/control: + + Moved Homepage: entry to control field + + Dropped unnecessary dependency on qt3-dev-tools + + -- Kartik Mistry Wed, 28 Nov 2007 19:54:58 +0530 + +recoll (1.9.0-1) unstable; urgency=low + + * New upstream release + * debian/patches: dropped 02_desktop_entry_fixes.dpatch, merged with + upstream, rewrote 01_nostrip_final_binary_437901.dpatch after upstream + changes + * debian/menu: used Data Management since it is better and appropriate + * debian/copyright: added missing copyright from index/csguess.cpp + + -- Kartik Mistry Wed, 12 Sep 2007 14:05:39 +0530 + +recoll (1.8.2-3) unstable; urgency=low + + * debian/rules: added better clean target, better configure flags, + separated LDFLAGS + * Added dpatch support + * debian/patches/01_nostrip_final_binary_437901.dpatch: added patch to not + strip binary from upstream (Closes: #437901) + * debian/patches/02_desktop_entry_fixes.dpatch: added patch to fix desktop + menu entry according to freedesktop standards + * debian/menu: fixed according to latest menu policy, changed subsection to + Tools from Databases (hint taken from beagle) + * debian/copyright: moved copyright out of license section, adjusted + copyrights portions under proper license + + -- Kartik Mistry Sat, 18 Aug 2007 20:28:49 +0530 + +recoll (1.8.2-2) unstable; urgency=low + + * debian/rules: xapian is dynamically linked now, Thanks to + Jean-Francois Dockes (Closes: #427783) + * Fixed debian/watch file, Thanks to Vincent Fourmond + + -- Kartik Mistry Fri, 08 Jun 2007 10:51:01 +0530 + +recoll (1.8.2-1) unstable; urgency=low + + * New upstream release + * debian/watch: fixed now + * debian/control: fixed long descriptions + + -- Kartik Mistry Tue, 22 May 2007 15:24:54 +0530 + +recoll (1.8.1-1) unstable; urgency=low + + * Initial release (Closes: #422039) + * Based on package prepared by Jean-Francois Dockes + + -- Kartik Mistry Thu, 3 May 2007 12:15:02 +0530 diff --git a/packaging/debian/debian/compat b/packaging/debian/debian/compat new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/packaging/debian/debian/compat @@ -0,0 +1 @@ +5 diff --git a/packaging/debian/debian/control b/packaging/debian/debian/control new file mode 100644 index 00000000..7263aea4 --- /dev/null +++ b/packaging/debian/debian/control @@ -0,0 +1,85 @@ +Source: recoll +Section: x11 +Priority: optional +Maintainer: Jean-Francois Dockes +Build-Depends: autotools-dev, + debhelper (>= 7), + dh-python, + bison, + libqt4-dev, + libqtwebkit-dev, + libx11-dev, + libxapian-dev (>= 1.2.0), + libz-dev, + python-all-dev (>= 2.6.6-3~), + python3-all-dev, +Standards-Version: 3.9.6 +X-Python-Version: >= 2.7 +Homepage: http://www.lesbonscomptes.com/recoll +Vcs-Git: git://anonscm.debian.org/collab-maint/recoll.git +Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/recoll.git;a=summary + +Package: recoll +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, python +Recommends: python-recoll, aspell, xdg-utils, xsltproc, + python-libxml2, python-libxslt1 +Suggests: antiword, + ghostscript, + libimage-exiftool-perl, + poppler-utils, + pstotext, + python-chm, + python-mutagen, + unrtf, + untex +Description: Personal full text search package with a Qt GUI + This package is a personal full text search package is based on a very strong + backend (Xapian), for which it provides an easy to use and feature-rich + interface. + . + Features: + * Qt-based GUI + * Supports the following document types (and their compressed versions) + - Natively: text, html, OpenOffice files, maildir and mailbox (Mozilla and + IceDove mail) with attachments, pidgin log files + - With external helpers: pdf (pdftotext), postscript (ghostscript), msword + (antiword), excel, ppt (catdoc), rtf (unrtf) + * Powerful query facilities, with boolean searches, phrases, filter on file + types and directory tree + * Support for multiple charsets, Internal processing and storage uses Unicode + UTF-8 + * Stemming performed at query time (can switch stemming language after + indexing) + * Easy installation. No database daemon, web server or exotic language + necessary + * An indexer which runs either as a thread inside the GUI or as an external, + cron'able program + +Package: python-recoll +Architecture: any +Section: python +Depends: recoll (= ${binary:Version}), + ${misc:Depends}, + ${python:Depends}, + ${shlibs:Depends} +Description: Python extension for recoll + Personal full text search package which is based on a very strong backend + (Xapian), for which it provides an easy to use and feature-rich interface. + . + This package provides Python extension module for recoll which can be use to + extend recoll such as an Ubuntu Unity Lens. + +Package: python3-recoll +Architecture: any +Section: python +Depends: recoll (= ${binary:Version}), + ${misc:Depends}, + ${python3:Depends}, + ${shlibs:Depends} +Description: Python extension for recoll + Personal full text search package which is based on a very strong backend + (Xapian), for which it provides an easy to use and feature-rich interface. + . + This package provides Python extension module for recoll which can be use to + extend recoll such as an Ubuntu Unity Lens. diff --git a/packaging/debian/debian/copyright b/packaging/debian/debian/copyright new file mode 100644 index 00000000..95e5bc31 --- /dev/null +++ b/packaging/debian/debian/copyright @@ -0,0 +1,194 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: recoll +Upstream-Contact: Jean-Francois Dockes +Source: http://www.lesbonscomptes.com/recoll/ + +Files: * +Copyright: 2005-2012, Jean-Francois Dockes +License: GPL-2+ + +Files: Binc IMAP project (bincimapmime/*) +Copyright: 2002-2005, Andreas Aardal Hanssen +License: GPL-2+ + +Files: filters/rcl* files index/csguess.cpp internfile/htmlparse.cpp +Copyright: 2000-2004, Mikio Hirabayashi +License: GPL-2+ + +Files: filters/rclpython +Copyright: J\xfcrgen Hermann, Mike Brown, Christopher Arndt + +License: GPL-2+ + +Files: internfile/htmlparse.cpp mh_html.cpp +Copyright: 1999-2001, BrightStation PLC, + 2001, Ananova Ltd, + 2002-2004, Olly Betts. +License: GPL-2+ + +Files: unac/* +Copyright: 2000-2002, Loic Dachary +License: GPL-2+ + +Files: common/* +Copyright: 2004-2005, J.F.Dockes +License: GPL-2+ + +Files: debian/* +Copyright: 2007-2012, Kartik Mistry +License: GPL-2+ + +License: GPL-2+ + This package 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 package 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 package; if not, write to the Free Software Foundation, Inc., 51 Franklin + St, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of the GNU General Public License can be + found in `/usr/share/common-licenses/GPL-2' and + `/usr/share/common-licenses/GPL-3'. + +Files: aspell/* +Copyright: 2001-2002, by Kevin Atkinson +License: LGPL-2+ + +Files: images/text-x-python.png +Copyright: David Vignoni +License: LGPL-2+ + +License: LGPL-2+ + This package is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any + later version. + . + This package is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + details. + . + You should have received a copy of the GNU Lesser General Public License along + with this package; if not, write to the Free Software Foundation, Inc., 51 + Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + . + On Debian systems, the complete text of the GNU Lesser General Public License + can be found in `/usr/share/common-licenses/LGPL-2' and + `/usr/share/common-licenses/LGPL-2.1' and `/usr/share/common-licenses/LGPL-3'. + +Files: common/uproplist.h +Copyright: 1991-2006, Unicode, Inc. +License: Unicode + +License: Unicode + All rights reserved. Distributed under the Terms of Use in + http://www.unicode.org/copyright.html + . + Permission is hereby granted, free of charge, to any person obtaining a copy + of the Unicode data files and any associated documentation (the "Data Files") + or Unicode software and any associated documentation (the "Software") to deal + in the Data Files or Software without restriction, including without + limitation the rights to use, copy, modify, merge, publish, distribute, and/or + sell copies of the Data Files or Software, and to permit persons to whom the + Data Files or Software are furnished to do so, provided that (a) the above + copyright notice(s) and this permission notice appear with all copies of the + Data Files or Software, (b) both the above copyright notice(s) and this + permission notice appear in associated documentation, and (c) there is clear + notice in each modified Data File or in the Software as well as in the + documentation associated with the Data File(s) or Software that the data or + software has been modified. + . + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD + PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL + DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THE + DATA FILES OR SOFTWARE. + . + Except as contained in this notice, the name of a copyright holder shall not + be used in advertising or otherwise to promote the sale, use or other dealings + in these Data Files or Software without prior written authorization of the + copyright holder. + +Files: utils/md5.* +Copyright: 1991-1992, RSA Data Security, Inc. All rights reserved. +License: RSA + +License:RSA + MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + . + License to copy and use this software is granted provided that it is + identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in + all material mentioning or referencing this software or this function. + . + License is also granted to make and use derivative works provided that such + works are identified as "derived from the RSA Data Security, Inc. MD5 + Message-Digest Algorithm" in all material mentioning or referencing the + derived work. + . + RSA Data Security, Inc. makes no representations concerning either the + merchantability of this software or the suitability of this software for any + particular purpose. It is provided "as is" without express or implied warranty + of any kind. + . + These notices must be retained in any copies of any part of this documentation + and/or software. + +Files: desktop/xdg-utils-1.0.1/* +Copyright: 2006, Kevin Krammer , + Jeremy White . +License: MIT + +License: MIT + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + . + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +Files: index/csguess.cpp +Copyright: 2000-2004, Mikio Hirabayashi +License: LGPL-2.1+ + +License: LGPL-2.1+ + This file is part of QDBM, Quick Database Manager. + . + QDBM is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2.1 of the License or any later + version. + . + QDBM is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + . + You should have received a copy of the GNU Lesser General Public License + along with QDBM; if not, write to the Free Software Foundation, Inc., + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + . + On Debian systems, the complete text of the GNU Lesser General Public License + can be found in `/usr/share/common-licenses/LGPL-2.1' and + `/usr/share/common-licenses/LGPL-3'. diff --git a/packaging/debian/debian/patches/series b/packaging/debian/debian/patches/series new file mode 100644 index 00000000..e69de29b diff --git a/packaging/debian/debian/python-recoll.install b/packaging/debian/debian/python-recoll.install new file mode 100644 index 00000000..ae42f11b --- /dev/null +++ b/packaging/debian/debian/python-recoll.install @@ -0,0 +1,2 @@ +usr/lib/python2*/*-packages/*.egg-info +usr/lib/python2*/*-packages/recoll/* diff --git a/packaging/debian/debian/python3-recoll.install b/packaging/debian/debian/python3-recoll.install new file mode 100644 index 00000000..b0bb287d --- /dev/null +++ b/packaging/debian/debian/python3-recoll.install @@ -0,0 +1,2 @@ +usr/lib/python3*/*-packages/*.egg-info +usr/lib/python3*/*-packages/recoll/* diff --git a/packaging/debian/debian/recoll.install b/packaging/debian/debian/recoll.install new file mode 100644 index 00000000..e423a69c --- /dev/null +++ b/packaging/debian/debian/recoll.install @@ -0,0 +1,12 @@ +usr/bin +usr/lib/recoll +usr/share/applications +usr/share/icons +usr/share/man +usr/share/pixmaps +usr/share/recoll/doc +usr/share/recoll/examples +usr/share/recoll/filters +usr/share/recoll/filters +usr/share/recoll/images +usr/share/recoll/translations diff --git a/packaging/debian/debian/recoll.menu b/packaging/debian/debian/recoll.menu new file mode 100644 index 00000000..f0abea35 --- /dev/null +++ b/packaging/debian/debian/recoll.menu @@ -0,0 +1,2 @@ +?package(recoll):needs="X11" section="Applications/Data Management" \ + title="Personal Search Tool" command="/usr/bin/recoll" diff --git a/packaging/debian/debian/rules b/packaging/debian/debian/rules new file mode 100755 index 00000000..5889c8cf --- /dev/null +++ b/packaging/debian/debian/rules @@ -0,0 +1,89 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +DPKG_EXPORT_BUILDFLAGS = 1 +include /usr/share/dpkg/buildflags.mk + +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +CFLAGS += -Wall -g +#LDFLAGS += -Wl,-z,defs + +#build qt4 UI only +export QMAKE=qmake-qt4 + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif + +config.status: configure + dh_testdir + ./configure CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \ + --host=$(DEB_HOST_GNU_TYPE) \ + --build=$(DEB_BUILD_GNU_TYPE) \ + --mandir=\$${prefix}/share/man \ + --prefix=/usr + +build: build-arch build-indep +build-arch: build-stamp +build-indep: build-stamp +build-stamp: config.status + dh_testdir + $(MAKE) -j 5 + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp config.log + [ ! -f Makefile ] || $(MAKE) distclean + dh_clean Makefile + +install: + dh_testdir + dh_testroot + dh_prep + dh_installdirs + $(MAKE) prefix=$(CURDIR)/debian/tmp/usr install + chmod a+x $(CURDIR)/debian/tmp/usr/share/recoll/examples/rclmon.sh + chmod a-x $(CURDIR)/debian/tmp/usr/share/recoll/filters/rclxslt.py + chmod a-x $(CURDIR)/debian/tmp/usr/share/recoll/filters/rclexec1.py + chmod a-x $(CURDIR)/debian/tmp/usr/share/recoll/filters/rclexec1.py + rm -f $(CURDIR)/debian/tmp/usr/lib/recoll/librecoll.la + (cd python/recoll; python setup.py install \ + --install-layout=deb \ + --prefix=$(CURDIR)/debian/tmp/usr ) + (cd python/recoll; python3 setup.py install \ + --install-layout=deb \ + --prefix=$(CURDIR)/debian/tmp/usr ) + +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs README + dh_installmenu + dh_installman + dh_install --sourcedir=debian/tmp + dh_makeshlibs + dh_python2 -p python-recoll + dh_python3 -p python3-recoll + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary-indep: build install + +binary: binary-indep binary-arch +.PHONY: build build-arch build-indep clean binary-indep binary-arch binary install diff --git a/packaging/debian/debian/source/format b/packaging/debian/debian/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/packaging/debian/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/packaging/debian/debian/watch b/packaging/debian/debian/watch new file mode 100644 index 00000000..e5daae09 --- /dev/null +++ b/packaging/debian/debian/watch @@ -0,0 +1,2 @@ +version=3 +http://www.lesbonscomptes.com/recoll/download.html recoll-(.*)\.tar\.gz diff --git a/packaging/debian/debiankio/changelog b/packaging/debian/debiankio/changelog new file mode 100644 index 00000000..ce15e57f --- /dev/null +++ b/packaging/debian/debiankio/changelog @@ -0,0 +1,110 @@ +kio-recoll (1.22.4-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Switch to kf5 for appropriate series. Update to 1.22.4 (same as .3) + + -- Jean-Francois Dockes Sat, 26 Nov 2016 09:46:00 +0100 + +kio-recoll (1.22.3-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * No changes specific to the KIO, just use the 1.22 lib. Update to .3 + + -- Jean-Francois Dockes Fri, 25 Nov 2016 10:59:00 +0100 + +kio-recoll (1.22.2-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * No changes specific to the KIO, just use the 1.22 lib. + + -- Jean-Francois Dockes Tue, 15 Jun 2016 09:57:00 +0200 + +kio-recoll (1.21.0-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * No changes specific to the KIO, just use the 1.21 lib. + + -- Jean-Francois Dockes Tue, 16 Jun 2015 18:21:00 +0200 + +kio-recoll (1.20.6-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + + * Increase the default maximum number of entries displayed in a directory + window (can be adjusted with the kio_max_direntries configuration + variable). + * Display entries incrementally instead of sending the whole + list at once. + + -- Jean-Francois Dockes Sat, 25 Apr 2015 14:47:00 +0200 + +kio-recoll (1.20.1-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to version 1.20.1 + -- Jean-Francois Dockes Fri, 19 Dec 2014 08:14:00 +0200 + +kio-recoll (1.19.14p2-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * No changes, build for Ubuntu Utopic + -- Jean-Francois Dockes Sat, 06 Dec 2014 08:44:00 +0200 + +kio-recoll (1.19.12-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.19.12 + -- Jean-Francois Dockes Wed, 02 Apr 2014 15:50:00 +0200 + +kio-recoll (1.19.10-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.19.10 + -- Jean-Francois Dockes Sat, 25 Nov 2013 18:00:00 +0100 + +kio-recoll (1.19.2-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.19.2 + -- Jean-Francois Dockes Mon, 13 May 2013 12:09:00 +0100 + +kio-recoll (1.18.2-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.18.2 + -- Jean-Francois Dockes Mon, 18 Apr 2013 18:05:00 +0100 + +kio-recoll (1.18.1-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.18.1 + -- Jean-Francois Dockes Mon, 05 Nov 2012 13:25:00 +0100 + +kio-recoll (1.17.0-0~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.17.0 + -- Jean-Francois Dockes Sun, 25 Mar 2012 18:05:00 +0200 + +kio-recoll (1.16.2-0~ppa1~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.16.2 + -- Jean-Francois Dockes Mon, 07 Nov 2011 17:57:00 +0200 + +kio-recoll (1.16.1-0~ppa1~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.16.1 + -- Jean-Francois Dockes Wed, 28 Sep 2011 15:07:00 +0200 + +kio-recoll (1.16.0-0~ppa1~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.16.0 + -- Jean-Francois Dockes Wed, 07 Sep 2011 18:30:00 +0200 + +kio-recoll (1.15.8-0~ppa1~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.15.8 + -- Jean-Francois Dockes Mon, 02 May 2011 17:27:00 +0200 + +kio-recoll (1.15.5-0~ppa1~SERIES1) SERIES; urgency=low + * Update to recoll version 1.15.5 + -- Jean-Francois Dockes Fri, 04 Mar 2011 13:54:00 +0200 + +kio-recoll (1.15.2-0~ppa1~SERIES1) SERIES; urgency=low + * Update to recoll version 1.15.2 + -- Jean-Francois Dockes Thu, 15 Feb 2011 08:43:00 +0200 + +kio-recoll (1.15.0-0~ppa1~SERIES1) SERIES; urgency=low + * Update to recoll version 1.15.0 + -- Jean-Francois Dockes Wed, 02 Feb 2011 09:48:00 +0200 + +kio-recoll (1.14.3-0~ppa1~SERIES1) SERIES; urgency=low + * Update to recoll version 1.14.3 + -- Jean-Francois Dockes Thu, 25 Nov 2010 10:25:00 +0200 + +kio-recoll (1.14.2-0~ppa1~SERIES1) SERIES; urgency=low + * Update to recoll version 1.14.2 + -- Jean-Francois Dockes Sat, 25 Sep 2010 09:37:20 +0200 + +kio-recoll (1.13.01-0~ppa4~SERIES1) SERIES; urgency=low + * Update to recoll version 1.13.01 + -- Jean-Francois Dockes Thu, 07 Jan 2010 11:26:00 +0100 + +kio-recoll (1.12.3-0~ppa4~jaunty1) jaunty; urgency=low + * Initial release + -- Jean-Francois Dockes Tue, 24 Nov 2009 08:55:00 +0100 + diff --git a/packaging/debian/debiankio/compat b/packaging/debian/debiankio/compat new file mode 100644 index 00000000..7f8f011e --- /dev/null +++ b/packaging/debian/debiankio/compat @@ -0,0 +1 @@ +7 diff --git a/packaging/debian/debiankio/control b/packaging/debian/debiankio/control new file mode 100644 index 00000000..28bdac4c --- /dev/null +++ b/packaging/debian/debiankio/control @@ -0,0 +1,36 @@ +Source: kio-recoll +Section: kde +Priority: extra +Maintainer: Jean-Francois Dockes +Build-Depends: cdbs, + cmake, + libtool, + debhelper (>= 7), + bison, + kdelibs5-dev (>= 4:4.2.2), + qtbase5-dev, + extra-cmake-modules, + kio-dev, + pkg-kde-tools (>= 0.4.0), + libxapian-dev, + libz-dev +Standards-Version: 3.9.7 +Homepage: http://www.recoll.org/ + +Package: kio-recoll +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, recoll +Description: Recoll KIO slave for KDE 4 + Recoll KIO slave for KDE 4, allows performing a Recoll search by + entering an appropriate URL in a KDE open dialog, or with an HTML-based + interface displayed in Konqueror. + The HTML-based interface is similar to the Recoll GUI QT-based interface, + slightly less powerful. It allows performing a search while staying fully + within the KDE framework: drag and drop from the result list works + normally and you have your normal choice of applications for opening files. + An alternative interface uses a directory view of search results. Due to + limitations in the current KIO slave interface, it is currently not + obviously useful. + The interface is described in more detail inside a help file which you can + access by entering recoll:/ inside the konqueror URL line (this works only + if the recoll KIO slave has been previously installed). diff --git a/packaging/debian/debiankio/control-4 b/packaging/debian/debiankio/control-4 new file mode 100644 index 00000000..cbc1b236 --- /dev/null +++ b/packaging/debian/debiankio/control-4 @@ -0,0 +1,33 @@ +Source: kio-recoll +Section: kde +Priority: extra +Maintainer: Jean-Francois Dockes +Build-Depends: cdbs, + cmake, + libtool, + debhelper (>= 7), + bison, + kdelibs5-dev (>= 4:4.2.2), + pkg-kde-tools (>= 0.4.0), + libxapian-dev, + libz-dev +Standards-Version: 3.9.5 +Homepage: http://www.recoll.org/ + +Package: kio-recoll +Architecture: any +Depends: ${misc:Depends}, ${shlibs:Depends}, recoll +Description: A Recoll KIO slave for KDE 4 + A Recoll KIO slave for KDE 4, allows performing a Recoll search by + entering an appropriate URL in a KDE open dialog, or with an HTML-based + interface displayed in Konqueror. + The HTML-based interface is similar to the Recoll GUI QT-based interface, + slightly less powerful. It allows performing a search while staying fully + within the KDE framework: drag and drop from the result list works + normally and you have your normal choice of applications for opening files. + An alternative interface uses a directory view of search results. Due to + limitations in the current KIO slave interface, it is currently not + obviously useful. + The interface is described in more detail inside a help file which you can + access by entering recoll:/ inside the konqueror URL line (this works only + if the recoll KIO slave has been previously installed). diff --git a/packaging/debian/debiankio/copyright b/packaging/debian/debiankio/copyright new file mode 100644 index 00000000..fb2496a7 --- /dev/null +++ b/packaging/debian/debiankio/copyright @@ -0,0 +1,113 @@ +This package was debianized by Jean-Francois Dockes on +Wed, 10 Jan 2007 16:04:13 +0100. + +It was downloaded from http://www.recoll.org + +Upstream Author: Jean-Francois Dockes + +Copyright: (C) 2005,2006, Jean-Francois Dockes + +License: + + This package 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 package 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 package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + +The Debian packaging is (C) 2007, Jean-Francois Dockes and +is licensed under the GPL, see above. + +Portions of the software are: + +Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL: +/* This file is part of The New Aspell + * Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL + * license version 2.0 or 2.1. You should have received a copy of the + * LGPL license along with this library if you did not you can find it + * at http://www.gnu.org/. + +On Debian systems, the complete text of the GNU LGPL +can be found in `/usr/share/common-licenses/LGPL-2'. + + +Copyright 2002-2005 Andreas Aardal Hanssen +Copyright (C) 2000-2004 Mikio Hirabayashi +Copyright 1999,2000,2001 BrightStation PLC +Copyright 2001 Ananova Ltd +Copyright 2002 Olly Betts +Copyright (C) 2000, 2001, 2002 Loic Dachary + - GPL V2 or later, same license text as above + +Copyright (c) 1991-2004 Unicode, Inc. + + COPYRIGHT AND PERMISSION NOTICE + + Copyright © 1991-2006 Unicode, Inc. All rights reserved. Distributed under + the Terms of Use in http://www.unicode.org/copyright.html. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of the Unicode data files and any associated documentation (the "Data + Files") or Unicode software and any associated documentation (the + "Software") to deal in the Data Files or Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, and/or sell copies of the Data Files or Software, and + to permit persons to whom the Data Files or Software are furnished to do + so, provided that (a) the above copyright notice(s) and this permission + notice appear with all copies of the Data Files or Software, (b) both the + above copyright notice(s) and this permission notice appear in associated + documentation, and (c) there is clear notice in each modified Data File or + in the Software as well as in the documentation associated with the Data + File(s) or Software that the data or software has been modified. + + THE DATA FILES AND SOFTWARE ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR + CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + PERFORMANCE OF THE DATA FILES OR SOFTWARE. + + Except as contained in this notice, the name of a copyright holder shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in these Data Files or Software without prior written + authorization of the copyright holder. + +Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +/* + * MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + * + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software for any particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ diff --git a/packaging/debian/debiankio/dirs b/packaging/debian/debiankio/dirs new file mode 100644 index 00000000..ec620536 --- /dev/null +++ b/packaging/debian/debiankio/dirs @@ -0,0 +1,2 @@ +usr/lib/kde4 +usr/share/kde4/services diff --git a/packaging/debian/debiankio/docs b/packaging/debian/debiankio/docs new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/packaging/debian/debiankio/docs @@ -0,0 +1 @@ + diff --git a/packaging/debian/debiankio/rules b/packaging/debian/debiankio/rules new file mode 100755 index 00000000..8d9a454d --- /dev/null +++ b/packaging/debian/debiankio/rules @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/pkg-kde-tools/makefiles/1/cdbs/kde.mk + +DEB_SRCDIR = kde/kioslave/kio_recoll diff --git a/packaging/debian/debiankio/rules-4 b/packaging/debian/debiankio/rules-4 new file mode 100755 index 00000000..7798525d --- /dev/null +++ b/packaging/debian/debiankio/rules-4 @@ -0,0 +1,6 @@ +#!/usr/bin/make -f + +include /usr/share/cdbs/1/rules/debhelper.mk +include /usr/share/pkg-kde-tools/makefiles/1/cdbs/kde.mk + +DEB_SRCDIR = kde/kioslave/kio_recoll-kde4 diff --git a/packaging/debian/debiankio/source/format b/packaging/debian/debiankio/source/format new file mode 100644 index 00000000..163aaf8d --- /dev/null +++ b/packaging/debian/debiankio/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/packaging/debian/debiankio/watch b/packaging/debian/debiankio/watch new file mode 100644 index 00000000..6963245c --- /dev/null +++ b/packaging/debian/debiankio/watch @@ -0,0 +1,4 @@ +version=3 + + +http://www.recoll.org/download.html recoll-(.*)\.tar\.gz diff --git a/packaging/debian/debianunitylens/changelog b/packaging/debian/debianunitylens/changelog new file mode 100644 index 00000000..301b6eb6 --- /dev/null +++ b/packaging/debian/debianunitylens/changelog @@ -0,0 +1,30 @@ +recoll-lens (1.19.10.3543-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to release 1.19.10 + -- Jean-Francois Dockes Sat, 23 Nov 2013 18:00:00 +0100 + +recoll-lens (1.19.2.3328-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to release 1.19.2, for consistency, same as 1.19.0 in fact + -- Jean-Francois Dockes Mon, 14 May 2013 08:22:00 +0100 + +recoll-lens (1.19.0.3315-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.19.0 + -- Jean-Francois Dockes Sun, 12 May 2013 14:43:00 +0100 + +recoll-lens (1.18.1.2997-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.18.1 + -- Jean-Francois Dockes Mon, 05 Nov 2012 13:31:00 +0100 +recoll-lens (1.17.2.2697-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.17.1.2697 : display thumbnails when they exist + -- Jean-Francois Dockes Tue, 15 May 2012 13:51:00 +0200 +recoll-lens (1.17.1.2654-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.17.1.2654 : display/open results for embedded files + -- Jean-Francois Dockes Tue, 27 Mar 2012 16:22:00 +0200 +recoll-lens (1.17.0.2648-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.17.0.2648 : don't use app shortcut 'a' + -- Jean-Francois Dockes Mon, 26 Mar 2012 22:05:00 +0200 +recoll-lens (1.17.0.2646-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated lens to vers. 1.17.0.2646 : Unity 5.0/Ubuntu 12.04 compatibility + -- Jean-Francois Dockes Sun, 25 Mar 2012 16:42:00 +0200 +recoll-lens (1.17.0.2645-1~ppaPPAVERS~SERIES1) SERIES; urgency=low + * Updated package to recoll version 1.17.0 + -- Jean-Francois Dockes Sun, 25 Mar 2012 16:42:00 +0200 diff --git a/packaging/debian/debianunitylens/compat b/packaging/debian/debianunitylens/compat new file mode 100644 index 00000000..7ed6ff82 --- /dev/null +++ b/packaging/debian/debianunitylens/compat @@ -0,0 +1 @@ +5 diff --git a/packaging/debian/debianunitylens/control b/packaging/debian/debianunitylens/control new file mode 100644 index 00000000..706ce5e4 --- /dev/null +++ b/packaging/debian/debianunitylens/control @@ -0,0 +1,18 @@ +Source: recoll-lens +Section: x11 +Priority: optional +Maintainer: Jean-Francois Dockes +Build-Depends: debhelper (>= 7), + autotools-dev, + recoll, + python-recoll, + python +Standards-Version: 3.9.3 + +Package: recoll-lens +Architecture: all +Depends: ${misc:Depends}, python, recoll, unity +Description:Unity Lens for searching the Recoll index. + Allows querying the Recoll index from the Unity Dash, optionally + filtering on file category. +Homepage: http://www.recoll.org diff --git a/packaging/debian/debianunitylens/copyright b/packaging/debian/debianunitylens/copyright new file mode 100644 index 00000000..47810ee9 --- /dev/null +++ b/packaging/debian/debianunitylens/copyright @@ -0,0 +1,20 @@ +This package was debianized by Jean-Francois Dockes on +Sun, 25 Mar 2012 16:31:00 +0200. + +It was downloaded from http://www.recoll.org + +Upstream Author: Jean-Francois Dockes + +Copyright: (C) 2012 Jean-Francois Dockes + +License: GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 + +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL'. + +Debian packaging is (C) 2012, Jean-Francois Dockes, same license. + +Derived from Original bliss apps lens by Mikkel Kamstrup Erlandsen: + Copyright 2011, Canonical Ltd + Authored by Mikkel Kamstrup Erlandsen + Distribute under the terms of the GNU General Public License v3 diff --git a/packaging/debian/debianunitylens/docs b/packaging/debian/debianunitylens/docs new file mode 100644 index 00000000..e845566c --- /dev/null +++ b/packaging/debian/debianunitylens/docs @@ -0,0 +1 @@ +README diff --git a/packaging/debian/debianunitylens/rules b/packaging/debian/debianunitylens/rules new file mode 100755 index 00000000..0b244d33 --- /dev/null +++ b/packaging/debian/debianunitylens/rules @@ -0,0 +1,52 @@ +#!/usr/bin/make -f + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + +config.status: configure + dh_testdir + ./configure --host=$(DEB_HOST_GNU_TYPE) \ + --build=$(DEB_BUILD_GNU_TYPE) \ + --mandir=\$${prefix}/share/man \ + --prefix=/usr \ + --sysconfdir=/etc + +build: build-stamp +build-stamp: config.status + dh_testdir + $(MAKE) + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp config.log + [ ! -f Makefile ] || $(MAKE) distclean + dh_clean Makefile + +install: + dh_testdir + dh_testroot + dh_prep + dh_installdirs + $(MAKE) prefix=$(CURDIR)/debian/recoll-lens/usr install + +binary-indep: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs README + dh_python2 + dh_link + dh_compress + dh_fixperms + dh_installdeb + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep +.PHONY: build clean binary-indep binary-arch binary install diff --git a/packaging/debian/debianunitylens/watch b/packaging/debian/debianunitylens/watch new file mode 100644 index 00000000..708fd568 --- /dev/null +++ b/packaging/debian/debianunitylens/watch @@ -0,0 +1,12 @@ +# Example watch control file for uscan +# Rename this file to "watch" and then you can run the "uscan" command +# to check for upstream updates and more. +# See uscan(1) for format + +# Compulsory line, this is a version 3 file +version=3 + +# Uncomment to examine a Webpage +# +http://www.recoll.org/download.html recoll-lens-(.*)\.tar\.gz + diff --git a/packaging/homebrew/00README.txt b/packaging/homebrew/00README.txt new file mode 100644 index 00000000..c76b25d6 --- /dev/null +++ b/packaging/homebrew/00README.txt @@ -0,0 +1,10 @@ + + +Package building file for Mac homebrew: http://brew.sh/ + +Install homebrew following the instructions on the home page, then copy +recoll.rb to /usr/local/Library/Formula/, then "brew install recoll" should +just work. + +Also see: https://github.com/medoc92/homebrew/tree/recoll + diff --git a/packaging/homebrew/recoll.rb b/packaging/homebrew/recoll.rb new file mode 100644 index 00000000..bc2b2b9a --- /dev/null +++ b/packaging/homebrew/recoll.rb @@ -0,0 +1,35 @@ +require 'formula' + +class Recoll < Formula + homepage 'http://www.recoll.org' + url 'http://www.recoll.org/recoll-1.19.11p1.tar.gz' + sha1 'f4259c21faff9f30882d0bf1e8f952c19ed9936b' + + depends_on 'xapian' + depends_on 'qt' + def patches + DATA + end + def install + system "./configure", "--prefix=#{prefix}" + system "make", "install" + end + + test do + system "#{bin}/recollindex", "-h" + end +end + +__END__ +--- a/configure.orig 2014-01-07 12:39:40.606718201 +0100 ++++ b/configure 2014-01-07 12:39:58.574599715 +0100 +@@ -5120,7 +5120,7 @@ + # basically to enable using a Macbook for development + if test X$sys = XDarwin ; then + # The default is xcode +- QMAKE="${QMAKE} -spec macx-g++" ++ QMAKE="${QMAKE}" + fi + + # Discriminate qt3/4. Qt3 qmake prints its version on stderr but we don't + diff --git a/packaging/macports/README.txt b/packaging/macports/README.txt new file mode 100644 index 00000000..90ab3922 --- /dev/null +++ b/packaging/macports/README.txt @@ -0,0 +1,24 @@ +To use/test the port out of the official macports tree: + +- Edit sources.conf /opt/local/etc/macports/sources.conf, and insert a URL + pointing to your local repository before the rsync one: + file:///Users/dockes/projets/fulltext/recoll/packaging/macports + rsync://rsync.macports.org/release/ports [default] + + (inserting before ensures it's used before the macports one) + +- The port should live under category/portname (ie: textproc/ + +- After you create or update your Portfile, use the MacPorts portindex + command in the local repository's directory to create or update the index + of the ports in your local repository. + + %% cd ~/path/to/macports + %% portindex + + Once the local port is added to the PortIndex, it becomes available for + searching or installation as with any other Portfile in the MacPorts + tree + +http://guide.macports.org/#development.local-repositories + diff --git a/packaging/macports/textproc/recoll/Portfile b/packaging/macports/textproc/recoll/Portfile new file mode 100644 index 00000000..850d19fe --- /dev/null +++ b/packaging/macports/textproc/recoll/Portfile @@ -0,0 +1,45 @@ +# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 +# $Id: Portfile 111989 2013-10-08 17:10:55Z ryandesign@macports.org $ + +PortSystem 1.0 +PortGroup app 1.0 + +name recoll +version 1.19.11p1 +categories textproc +platforms darwin +license GPL-2+ +maintainers dockes.org:jf openmaintainer + +description Desktop full text search + +long_description Recoll is a desktop search tool based on Xapian + +homepage http://www.recoll.org/ +master_sites ${homepage} + +checksums rmd160 de98039d80174a5da6e3cdbcc8b7bc0f4407e44a \ + sha256 8d1d040b8de1f65f01bc0a56053a6df7677360031bf9a6779d3496ced4a61186 + +depends_lib port:xapian-core \ + port:qt4-mac \ + port:aspell \ + port:libiconv \ + port:zlib + +depends_run port:antiword \ + port:catdoc \ + port:libxslt \ + port:poppler \ + port:unrtf \ + port:unzip + +patchfiles patch-sampleconf-mimeview.diff + +configure.args --without-x \ + --disable-x11mon + +build.args CC=${configure.cc} CXX=${configure.cxx} + +# g++-4.2: -E, -S, -save-temps and -M options are not allowed with multiple -arch flags +universal_variant no diff --git a/packaging/macports/textproc/recoll/files/patch-sampleconf-mimeview.diff b/packaging/macports/textproc/recoll/files/patch-sampleconf-mimeview.diff new file mode 100644 index 00000000..6db66d5b --- /dev/null +++ b/packaging/macports/textproc/recoll/files/patch-sampleconf-mimeview.diff @@ -0,0 +1,147 @@ +--- sampleconf/mimeview 2013-09-30 18:45:06.000000000 +0200 ++++ sampleconf/mimeview.mac 2013-09-30 18:45:06.000000000 +0200 +@@ -2,7 +2,8 @@ + + ## ########################################## + # External viewers, launched by the recoll GUI when you click on a result +-# 'edit' link ++# 'Open' link - MAC version ++# On the MAC, we use "open" for everything... + + # Mime types which we should not uncompress if they are found gzipped or + # bzipped because the native viewer knows how to handle. These would be +@@ -16,20 +17,17 @@ + # search string + # - For pages of CHM and EPUB documents where we can choose to open the + # parent document instead of a temporary html file. +-xallexcepts = application/pdf application/postscript application/x-dvi \ +- text/html|gnuinfo text/html|chm text/html|epub \ +- application/x-fsdirectory|parentopen inode/directory|parentopen ++#xallexcepts = application/pdf application/postscript application/x-dvi \ ++# text/html|gnuinfo text/html|chm text/html|epub + + [view] + # Pseudo entry used if the 'use desktop' preference is set in the GUI +-application/x-all = xdg-open %u ++application/x-all = open %f + + application/epub+zip = ebook-viewer %f +-# Open the parent epub document for epub parts instead of opening them as +-# html documents. This is almost always what we want. +-text/html|epub = ebook-viewer %F;ignoreipath=1 +- +-application/x-gnote = gnote %f ++# If you want to open the parent epub document for epub parts instead of ++# opening them as html documents: ++#text/html|epub = ebook-viewer %F;ignoreipath=1 + + application/x-mobipocket-ebook = ebook-viewer %f + +@@ -76,13 +74,9 @@ + application/vnd.wordperfect = libreoffice %f + text/rtf = libreoffice %f + ++application/x-chm = kchmviewer %f + application/x-dia-diagram = dia %f +- + application/x-fsdirectory = dolphin %f +-inode/directory = dolphin %f +-application/x-fsdirectory|parentopen = dolphin --select %(childurl) %f +-inode/directory|parentopen = dolphin --select %(childurl) %f +- + application/x-gnuinfo = xterm -e "info -f %f" + application/x-gnumeric = gnumeric %f + +@@ -102,11 +96,6 @@ + image/x-ms-bmp = gwenview %f + image/x-xpmi = gwenview %f + +-# Opening mail messages not always works. +-# - Thunderbird will only open a single-message file if it has an .emf +-# extension +-# - "sylpheed %f" seems to work ok as of version 3.3 +-# - "kmail --view %u" works + message/rfc822 = thunderbird -file %f + text/x-mail = thunderbird -file %f + application/x-mimehtml = thunderbird -file %f +@@ -119,11 +108,11 @@ + application/x-tar = ark %f + application/zip = ark %f + +-application/x-awk = emacsclient --no-wait %f +-application/x-perl = emacsclient --no-wait %f +-text/x-perl = emacsclient --no-wait %f +-application/x-shellscript = emacsclient --no-wait %f +-text/x-shellscript = emacsclient --no-wait %f ++application/x-awk = emacsclient %f ++application/x-perl = emacsclient %f ++text/x-perl = emacsclient %f ++application/x-shellscript = emacsclient %f ++text/x-shellscript = emacsclient %f + + # Or firefox -remote "openFile(%u)" + text/html = firefox %u +@@ -135,41 +124,39 @@ + + application/x-webarchive = konqueror %f + text/x-fictionbook = ebook-viewer %f +-application/x-tex = emacsclient --no-wait %f +-application/xml = emacsclient --no-wait %f +-text/xml = emacsclient --no-wait %f +-text/x-tex = emacsclient --no-wait %f +-text/plain = emacsclient --no-wait %f +-text/x-awk = emacsclient --no-wait %f +-text/x-c = emacsclient --no-wait %f +-text/x-c+ = emacsclient --no-wait %f +-text/x-c++ = emacsclient --no-wait %f ++application/x-tex = emacsclient %f ++application/xml = emacsclient %f ++text/xml = emacsclient %f ++text/x-tex = emacsclient %f ++text/plain = emacsclient %f ++text/x-awk = emacsclient %f ++text/x-c = emacsclient %f ++text/x-c+ = emacsclient %f ++text/x-c++ = emacsclient %f + text/x-csv = libreoffice %f + text/x-html-sidux-man = konqueror %f + text/x-html-aptosid-man = iceweasel %f + +-application/x-chm = kchmviewer %f + # Html pages inside a chm have a chm rclaptg set by the filter. Kchmviewer + # knows how to use the ipath (which is the internal chm path) to open the + # file at the right place + text/html|chm = kchmviewer --url %i %F + +-text/x-ini = emacsclient --no-wait %f ++text/x-ini = emacsclient %f + text/x-man = xterm -u8 -e "groff -T ascii -man %f | more" + text/x-python = idle %f +-text/x-gaim-log = emacsclient --no-wait %f +-text/x-purple-html-log = emacsclient --no-wait %f +-text/x-purple-log = emacsclient --no-wait %f ++text/x-gaim-log = emacsclient %f ++text/x-purple-html-log = emacsclient %f ++text/x-purple-log = emacsclient %f + + # The video types will usually be handled by the desktop default, but they + # need entries here to get an "Open" link +-video/3gpp = vlc %f +-video/mp2p = vlc %f +-video/mp2t = vlc %f +-video/mp4 = vlc %f +-video/mpeg = vlc %f +-video/quicktime = vlc %f +-video/x-matroska = vlc %f +-video/x-ms-asf = vlc %f +-video/x-msvideo = vlc %f +- ++video/3gpp = open %f ++video/mp2p = open %f ++video/mp2t = open %f ++video/mp4 = open %f ++video/mpeg = open %f ++video/quicktime = open %f ++video/x-matroska = open %f ++video/x-ms-asf = open %f ++video/x-msvideo = open %f diff --git a/packaging/rpm/kio_recoll-opensuse.spec b/packaging/rpm/kio_recoll-opensuse.spec new file mode 100644 index 00000000..06ccf97a --- /dev/null +++ b/packaging/rpm/kio_recoll-opensuse.spec @@ -0,0 +1,85 @@ +# +# spec file for package kio_recoll +# +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + +%define rname recoll + +Name: kio_recoll +Version: 1.21.6 +Release: 0 +Summary: Extended Search +License: GPL-2.0+ +Summary: KIO slave for the Recoll full text search tool +Group: Productivity/Text/Utilities +Url: http://www.lesbonscomptes.com/recoll/ +Source: http://www.lesbonscomptes.com/recoll/%{rname}-%{version}.tar.gz +BuildRequires: libkde4-devel +BuildRequires: kio-devel +BuildRequires: libxapian-devel +BuildRequires: recoll = %{version} +Requires: recoll = %{version} +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +Recoll is a personal full text search tool for Unix/Linux. + +This package provides the kio-slave + + +%prep +%setup -q -n %{rname}-%{version} + +%build +pushd kde/kioslave/kio_recoll +%cmake_kde4 -d build +%make_jobs +popd +pushd kde/kioslave/kio_recoll-kde4 +%cmake_kde4 -d build +%make_jobs + +%install +pushd kde/kioslave/kio_recoll +%kde4_makeinstall -C build +popd +pushd kde/kioslave/kio_recoll-kde4 +%kde4_makeinstall -C build + + +%files +%defattr(-,root,root) +%{_libdir}/qt5/plugins/kio_recoll.so +%{_datadir}/kio_recoll/ +%{_datadir}/kservices5/*.protocol +%{_libdir}/kde4/kio_recoll.so +%{_datadir}/kde4/apps/kio_recoll/help.html +%{_datadir}/kde4/apps/kio_recoll/welcome.html +%{_datadir}/kde4/services/recoll.protocol +%{_datadir}/kde4/services/recollf.protocol + +%changelog +* Tue Apr 05 2016 Jean-Francois Dockes 1.21.6-0 +- Also build kde5 versions: works with Dolphin. Keep kde4 version for + Konqueror +* Sun Mar 18 2012 Jean-Francois Dockes 1.17.0-0 +- 1.17.0 +* Mon May 02 2011 Jean-Francois Dockes 1.16.2-0 +- 1.16.2 +* Mon May 02 2011 Jean-Francois Dockes 1.15.8-0 +- 1.15.8 +* Sun Mar 06 2011 Jean-Francois Dockes 1.15.5-0 +- Initial spec file for kio + diff --git a/packaging/rpm/kio_recoll.spec b/packaging/rpm/kio_recoll.spec new file mode 100644 index 00000000..38626e3e --- /dev/null +++ b/packaging/rpm/kio_recoll.spec @@ -0,0 +1,77 @@ +%define name kio_recoll +%define version 1.17.0 +%define release 0 + +Name: %{name} +Version: %{version} +Release: %{release} + +Summary: KIO slave for the Recoll full text search tool +Source0: http://www.recoll.org/recoll-%{version}.tar.gz +URL: http://www.recoll.org/ +Group: Applications/Databases + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +License: GPL + +BuildRequires: libkde4-devel zlib-devel xapian-core-devel libuuid-devel +Requires: recoll + +%description +Recoll is a personal full text search package for Linux, FreeBSD and +other Unix systems. It is based on a very strong backend (Xapian), for +which it provides an easy to use, feature-rich, easy administration +interface. + +# --------------------------------------------------------------------------- + +%prep +%setup -q -n recoll-%{version} + +# --------------------------------------------------------------------------- + +%build + +%cmake_kde4 kde/kioslave/kio_recoll +pwd +make %{?_smp_mflags} + +# --------------------------------------------------------------------------- + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall + +# --------------------------------------------------------------------------- + +%clean +rm -rf $RPM_BUILD_ROOT + +# --------------------------------------------------------------------------- + +%files +%defattr(-,root,root,-) +%{_libdir}/kde4/kio_recoll.so +%{_datadir}/kde4/apps/kio_recoll +%{_datadir}/kde4/apps/kio_recoll/help.html +%{_datadir}/kde4/apps/kio_recoll/welcome.html +%{_datadir}/kde4/services/recoll.protocol +%{_datadir}/kde4/services/recollf.protocol +%if 0%{?suse_version} > 1120 +%dir %{_datadir}/kde4/apps +%dir %{_datadir}/kde4/services +%dir %{_libdir}/kde4 +%endif + +# --------------------------------------------------------------------------- + +%changelog +* Sun Mar 18 2012 Jean-Francois Dockes 1.17.0-0 +- 1.17.0 +* Mon May 02 2011 Jean-Francois Dockes 1.16.2-0 +- 1.16.2 +* Mon May 02 2011 Jean-Francois Dockes 1.15.8-0 +- 1.15.8 +* Sun Mar 06 2011 Jean-Francois Dockes 1.15.5-0 +- Initial spec file for kio + diff --git a/packaging/rpm/recoll-mageia.spec b/packaging/rpm/recoll-mageia.spec new file mode 100644 index 00000000..b44ac0ce --- /dev/null +++ b/packaging/rpm/recoll-mageia.spec @@ -0,0 +1,75 @@ +Name: recoll +Version: 1.19.9 +Release: %mkrel 1 +Summary: Desktop full text search tool with a Qt GUI +URL: http://www.lesbonscomptes.com/recoll/ +Group: Databases +License: GPLv2 + +Source0: http://www.lesbonscomptes.com/recoll/%{name}-%{version}.tar.gz + +BuildRequires: xapian-devel +BuildRequires: pkgconfig(QtCore) +BuildRequires: pkgconfig(QtWebKit) + +Requires: xapian + + +%description +Recoll is a personal full text search package for Linux, FreeBSD and +other Unix systems. It is based on a very strong backend (Xapian), for +which it provides an easy to use, feature-rich, easy administration +interface. + + +%package -n kio-%{name} +Summary: Kioslave for %{name} +Group: Graphical desktop/KDE +BuildRequires: cmake +BuildRequires: kdelibs4-devel +Requires: %{name} = %{version}-%{release} +Requires: kdebase4-workspace + +%description -n kio-%{name} +Kioslave for %{name}. Enables to perform querries and extract +results in konqueror and dolphin. + + + +%prep +%setup -q + +%build +%configure2_5x --disable-python-module +%make + + +%install +%makeinstall_std + +rm lib/librecoll.so* +pushd kde/kioslave/kio_recoll +%cmake_kde4 +%make +%makeinstall_std +popd + + +%files +%doc README +%{_bindir}/* +%{_datadir}/applications/recoll-searchgui.desktop +%{_datadir}/icons/hicolor/48x48/apps/recoll.png +%{_datadir}/pixmaps/recoll.png +%{_datadir}/%{name} +%{_mandir}/man1/recoll* +%{_mandir}/man5/recoll* +%{_kde_libdir}/%name/librecoll.so.%version + + +%files -n kio-%{name} +%{_kde_libdir}/kde4/kio_recoll.so +%{_kde_datadir}/apps/kio_recoll/help.html +%{_kde_datadir}/apps/kio_recoll/welcome.html +%{_kde_datadir}/kde4/services/recoll.protocol +%{_kde_datadir}/kde4/services/recollf.protocol diff --git a/packaging/rpm/recoll-opensuse.spec b/packaging/rpm/recoll-opensuse.spec new file mode 100644 index 00000000..ca1276dc --- /dev/null +++ b/packaging/rpm/recoll-opensuse.spec @@ -0,0 +1,123 @@ +# +# spec file for package recoll +# +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. +# +# All modifications and additions to the file contributed by third parties +# remain the property of their copyright owners, unless otherwise agreed +# upon. The license for this file, and modifications and additions to the +# file, is the same license as for the pristine package itself (unless the +# license for the pristine package is not an Open Source License, in which +# case the license is the MIT License). An "Open Source License" is a +# license that conforms to the Open Source Definition (Version 1.9) +# published by the Open Source Initiative. + +# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# + + +Name: recoll +Version: 1.21.6 +Release: 0 +Summary: Extended Search +License: GPL-2.0+ +Summary: Extended Search +Group: Productivity/Text/Utilities +Url: http://www.lesbonscomptes.com/recoll/ +Source: http://www.lesbonscomptes.com/recoll/%{name}-%{version}.tar.gz +BuildRequires: aspell-devel +%if 0%{?suse_version} > 1320 +BuildRequires: pkgconfig(Qt5Core) +BuildRequires: pkgconfig(Qt5WebKit) +BuildRequires: pkgconfig(Qt5WebKitWidgets) +BuildRequires: pkgconfig(Qt5Xml) +BuildRequires: pkgconfig(Qt5Network) +BuildRequires: pkgconfig(Qt5PrintSupport) +%else +BuildRequires: libQtWebKit-devel +BuildRequires: libqt4-devel +%endif +BuildRequires: bison +BuildRequires: libxapian-devel +BuildRequires: python-devel +BuildRequires: update-desktop-files +# Recommends for the helpers. +Recommends: antiword +Recommends: poppler-tools +Recommends: libwpd-tools +Recommends: libxslt +Recommends: catdoc +Recommends: djvulibre +Recommends: python-mutagen +Recommends: exiftool +Recommends: perl-Image-ExifTool +Recommends: python-base +Recommends: unrar +Recommends: python-rarfile +Recommends: python-PyCHM +Recommends: unrtf +Recommends: pstotext +# Default requires for recoll itself +Requires: sed +Requires: awk +Requires: aspell +Requires: python +Suggests: kio_recoll +BuildRoot: %{_tmppath}/%{name}-%{version}-build + +%description +Recoll is a personal full text search tool for Unix/Linux. + +It is based on the very strong Xapian back-end, for which it provides a feature-rich yet easy to use front-end with a QT graphical interface. + +Recoll is free, open source, and licensed under the GPL. The current version is 1.12.0 . +Features: + +* Easy installation, few dependencies. No database daemon, web server, desktop environment or exotic language necessary. +* Will run on most unix-based systems +* Qt-based GUI. Can use either Qt 3 or Qt 4. +* Searches most common document types, emails and their attachments. +* Powerful query facilities, with boolean searches, phrases, proximity, wildcards, filter on file types and directory tree. +* Multi-language and multi-character set with Unicode based internals. +* (more detail) + +%prep +%setup -q + +%build +%if 0%{?suse_version} > 1320 +export QMAKE=qmake-qt5 +%endif +%configure --with-inotify +make %{?_smp_mflags} + +%install +make DESTDIR=%{buildroot} install %{?_smp_mflags} + +%post -p /sbin/ldconfig + +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%dir %{_libdir}/recoll +%dir %{_datadir}/appdata +%{_bindir}/recoll +%{_bindir}/recollindex +%{_datadir}/recoll +%{_datadir}/applications/recoll-searchgui.desktop +%{_datadir}/appdata/recoll.appdata.xml +%{_datadir}/icons/hicolor +%{_datadir}/pixmaps/recoll.png +%{_libdir}/recoll/librecoll.so.%{version} +%{_libdir}/python2.7/site-packages/recoll +%{_libdir}/python2.7/site-packages/Recoll-1.0-py2.7.egg-info +%{_mandir}/man1/recoll.1.gz +%{_mandir}/man1/recollq.1.gz +%{_mandir}/man1/recollindex.1.gz +%{_mandir}/man5/recoll.conf.5.gz + +%changelog +* Tue Apr 05 2016 Jean-Francois Dockes 1.21.6-0 +- Recoll 1.21.6, esp. for the kde5 kio + diff --git a/packaging/rpm/recoll.spec b/packaging/rpm/recoll.spec new file mode 100644 index 00000000..0f266295 --- /dev/null +++ b/packaging/rpm/recoll.spec @@ -0,0 +1,224 @@ +Summary: Desktop full text search tool with Qt GUI +Name: recoll +Version: 1.20.6 +Release: 1%{?dist} +Group: Applications/Databases +License: GPLv2+ +URL: http://www.lesbonscomptes.com/recoll/ +Source0: http://www.lesbonscomptes.com/recoll/recoll-%{version}.tar.gz +BuildRequires: qt-devel +BuildRequires: qtwebkit-devel +BuildRequires: python-devel +BuildRequires: zlib-devel +BuildRequires: aspell-devel +BuildRequires: xapian-core-devel +BuildRequires: desktop-file-utils +Requires: xdg-utils + +%description +Recoll is a personal full text search package for Linux, FreeBSD and +other Unix systems. It is based on a very strong back end (Xapian), for +which it provides an easy to use, feature-rich, easy administration +interface. +%global __provides_exclude_from ^%{_libdir}/recoll/librecoll\\.so.*$ +%global __requires_exclude ^librecoll\\.so.*$ + +%prep +%setup -q -n %{name}-%{version} +chmod 0644 utils/{conftree.cpp,conftree.h,debuglog.cpp,debuglog.h} + +%build +export QMAKE=qmake-qt4 +%configure +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} STRIP=/bin/true INSTALL='install -p' + +desktop-file-install --delete-original \ + --dir=%{buildroot}/%{_datadir}/applications \ + %{buildroot}/%{_datadir}/applications/%{name}-searchgui.desktop + +# use /usr/bin/xdg-open +rm -f %{buildroot}/usr/share/recoll/filters/xdg-open + +# fix perms +chmod 0755 %{buildroot}/usr/share/recoll/filters/rclexecm.py +chmod 0755 %{buildroot}%{_libdir}/recoll/librecoll.so.* + +%post +touch --no-create %{_datadir}/icons/hicolor +if [ -x %{_bindir}/gtk-update-icon-cache ] ; then + %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor +fi +if [ -x %{_bindir}/update-desktop-database ] ; then + %{_bindir}/update-desktop-database &> /dev/null +fi +exit 0 + +%postun +touch --no-create %{_datadir}/icons/hicolor +if [ -x %{_bindir}/gtk-update-icon-cache ] ; then + %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor +fi +if [ -x %{_bindir}/update-desktop-database ] ; then + %{_bindir}/update-desktop-database &> /dev/null +fi +exit 0 + +%files +%doc COPYING ChangeLog README +%{_bindir}/%{name} +%{_bindir}/%{name}index +%{_datadir}/%{name} +%{_datadir}/appdata/%{name}.appdata.xml +%{_datadir}/applications/%{name}-searchgui.desktop +%{_datadir}/icons/hicolor/48x48/apps/%{name}.png +%{_datadir}/pixmaps/%{name}.png +%{_libdir}/recoll +%{python_sitearch}/recoll +%{python_sitearch}/Recoll*.egg-info +%{_mandir}/man1/%{name}.1* +%{_mandir}/man1/recollq.1* +%{_mandir}/man1/%{name}index.1* +%{_mandir}/man5/%{name}.conf.5* + +%changelog +* Sat Apr 25 2015 Jean-Francois Dockes - 1.20.6-1 +- 1.20.6 + +* Fri Dec 19 2014 Jean-Francois Dockes - 1.20.1-1 +- 1.20.1 + +* Sun Nov 09 2014 Jean-Francois Dockes - 1.19.14p2-1 +- 1.19.14p2 + +* Sun Aug 17 2014 Fedora Release Engineering - 1.19.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 1.19.13-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue May 06 2014 Terje Rosten - 1.19.13-1 +- 1.19.13 + +* Mon Jan 20 2014 Terje Rosten - 1.19.11-1 +- 1.19.11 + +* Mon Nov 11 2013 Terje Rosten - 1.19.9-1 +- 1.19.9 + +* Tue Nov 05 2013 Terje Rosten - 1.19.8-1 +- 1.19.8 + +* Sun Aug 04 2013 Fedora Release Engineering - 1.19.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jun 12 2013 Terje Rosten - 1.19.4-2 +- Fix filter setup + +* Mon Jun 10 2013 Terje Rosten - 1.19.4-1 +- 1.19.4 + +* Thu Feb 14 2013 Fedora Release Engineering - 1.18.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Nov 19 2012 Terje Rosten - 1.18.1-1 +- 1.18.1 + +* Sat Jul 21 2012 Fedora Release Engineering - 1.17.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed May 30 2012 Terje Rosten - 1.17.3-1 +- 1.17.3 + +* Sat Mar 31 2012 Terje Rosten - 1.17.1-1 +- 1.17.1 + +* Sun Mar 25 2012 Terje Rosten - 1.17-1 +- 1.17 + +* Tue Feb 28 2012 Fedora Release Engineering - 1.16.2-3 +- Rebuilt for c++ ABI breakage + +* Wed Feb 15 2012 Terje Rosten - 1.16.2-2 +- Add patch to build with gcc 4.7 + +* Wed Feb 01 2012 Terje Rosten - 1.16.2-1 +- 1.16.2 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.16.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Oct 24 2011 Terje Rosten - 1.16.1-2 +- Add patch to fix crash (bz #747472) + +* Tue Oct 18 2011 Terje Rosten - 1.16.1-1 +- 1.16.1 + +* Tue May 24 2011 Terje Rosten - 1.15.8-2 +- add patch from upstream to fix crash. + +* Sun May 08 2011 Terje Rosten - 1.15.8-1 +- 1.15.8 + +* Wed Feb 09 2011 Fedora Release Engineering - 1.14.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Jan 28 2011 Terje Rosten - 1.14.4-1 +- 1.14.4 + +* Mon Nov 15 2010 Terje Rosten - 1.14.2-2 +- Add patch to fix #631704 + +* Sun Nov 7 2010 Terje Rosten - 1.14.2-1 +- 1.14.2 + +* Thu Jul 15 2010 Terje Rosten - 1.13.04-6 +- add patch to build with xapian 1.2 (from J.F. Dockes, thanks) + +* Sat Jul 10 2010 Terje Rosten - 1.13.04-5 +- use system xdg-open +- trim chagenlog + +* Fri Jul 9 2010 Terje Rosten - 1.13.04-4 +- fix some review comments + +* Mon May 10 2010 Terje Rosten - 1.13.04-3 +- use version macro in source url +- don't strip bins, giving non empty debuginfo package +- more explicit file listing +- try to preserve timestamps +- use proper name for spec file +- fix changelog +- license seems to be GPLv2+ +- include some %%doc files +- add buildroot tag +- some source add execute bit set +- explicit enable inotify +- add aspell-devel to bulldreq +- make with _smp_mflags seems to work +- add post scripts +- add patch to build gui with correct flags (ref: 338791) + +* Sun May 9 2010 J.F. Dockes 1.13.04-2 +- bumped the release number to issue new rpms for fc10 + +* Sun May 9 2010 J.F. Dockes 1.13.04 +- updated to recoll release 1.13.04 + +* Fri Feb 12 2010 Terry Duell 1.13.02 +- updated to release 1.13.02 + +* Tue Jan 12 2010 Terry Duell 1.13.01-3 +- updated to fix Fedora desktop-file-install and install icon + +* Sun Jan 10 2010 Jean-Francois Dockes 1.13.01-2 +- updated for recent fedoras: depend on xapian packages, use qt4 + +* Thu Jan 07 2010 Jean-Francois Dockes 1.13.01-1 +- update to release 1.13.01 + +* Wed Feb 1 2006 Jean-Francois Dockes 1.2.0-1 +- initial packaging + diff --git a/packaging/rpm/recollCooker.spec b/packaging/rpm/recollCooker.spec new file mode 100644 index 00000000..9e81496a --- /dev/null +++ b/packaging/rpm/recollCooker.spec @@ -0,0 +1,88 @@ +Summary: Desktop full text search tool with a qt gui +Name: recoll +Version: 1.12.0 +Release: %mkrel 1 +License: GPL +Group: Databases +URL: http://www.recoll.org/ +Source0: http://www.lesbonscomptes.com/recoll/%{name}-%{version}.tar.bz2 +Patch1: %{name}-configure.patch +BuildRequires: libxapian-devel +BuildRequires: libfam-devel +BuildRequires: libqt-devel >= 3.3.7 +BuildRequires: libaspell-devel +Requires: xapian +BuildRoot: %{_tmppath}/%{name}-%{version}--buildroot + +%description +Recoll is a personal full text search tool for Unix/Linux. +It is based on the very strong Xapian backend, for which +it provides an easy to use, feature-rich, easy administration, +QT graphical interface. + +%prep +%setup -q +%patch1 -p0 + +%build +%configure2_5x \ + --with-fam \ + --with-aspell + +%make + +%install +[ "%{buildroot}" != "/" ] && rm -rf %{buildroot} + +%makeinstall_std +desktop-file-install --vendor="" \ + --add-category="X-MandrivaLinux-MoreApplications-Databases" \ + --dir %{buildroot}%{_datadir}/applications %{buildroot}%{_datadir}/applications/* + +%clean +[ "%{buildroot}" != "/" ] && rm -rf %{buildroot} + +%files +%defattr(644,root,root,755) +%doc %{_datadir}/%{name}/doc +%attr(755,root,root) %{_bindir}/%{name}* +%{_datadir}/applications/recoll-searchgui.desktop +%{_datadir}/icons/hicolor/48x48/apps/recoll-searchgui.png +%dir %{_datadir}/%{name} +%dir %{_datadir}/%{name}/examples +%dir %{_datadir}/%{name}/filters +%dir %{_datadir}/%{name}/images +%dir %{_datadir}/%{name}/translations +%{_datadir}/%{name}/examples/mime* +%{_datadir}/%{name}/examples/*.conf +%attr(755,root,root) %{_datadir}/%{name}/examples/rclmon.sh +%attr(755,root,root) %{_datadir}/%{name}/filters/rc* +%{_datadir}/%{name}/filters/xdg-open +%{_datadir}/%{name}/images/*png +%{_mandir}/man1/recoll* +%{_mandir}/man5/recoll* +%{_datadir}/%{name}/translations/*.qm + + +%changelog +* Fri Apr 20 2007 Tomasz Pawel Gajc 1.12.1-1mdv2008.0 ++ Revision: 16093 +- new version +- drop P0 + + + Mandriva + + +* Tue Mar 06 2007 Tomasz Pawel Gajc 1.7.5-2mdv2007.0 ++ Revision: 134128 +- rebuild + +* Tue Jan 30 2007 Tomasz Pawel Gajc 1.7.5-1mdv2007.1 ++ Revision: 115423 +- add patch 1 - fix build on x86_64 +- add patch 0 - fix menu entry +- fix group +- add buildrequires +- set correct bits on files +- Import recoll + diff --git a/packaging/rpm/recollfedora.spec b/packaging/rpm/recollfedora.spec new file mode 100644 index 00000000..57f08e20 --- /dev/null +++ b/packaging/rpm/recollfedora.spec @@ -0,0 +1,303 @@ +Summary: Desktop full text search tool with Qt GUI +Name: recoll +Version: 1.21.6 +Release: 1%{?dist} +Group: Applications/Databases +License: GPLv2+ +URL: http://www.lesbonscomptes.com/recoll/ +Source0: http://www.lesbonscomptes.com/recoll/recoll-%{version}.tar.gz +# Source10: qmake-qt4.sh +BuildRequires: aspell-devel +BuildRequires: bison +BuildRequires: desktop-file-utils +# kio +BuildRequires: kdelibs4-devel +BuildRequires: qt5-qtbase-devel +BuildRequires: qt5-qtwebkit-devel +BuildRequires: extra-cmake-modules +BuildRequires: kf5-kio-devel +BuildRequires: python2-devel +BuildRequires: xapian-core-devel +BuildRequires: zlib-devel +Requires: xdg-utils + +%description +Recoll is a personal full text search package for Linux, FreeBSD and +other Unix systems. It is based on a very strong back end (Xapian), for +which it provides an easy to use, feature-rich, easy administration +interface. + +%package kio +Summary: KIO support for recoll +Group: Applications/Databases +Requires: %{name} = %{version}-%{release} + +%description kio +The recoll KIO slave allows performing a recoll search by entering an +appropriate URL in a KDE open dialog, or with an HTML-based interface +displayed in Konqueror. + +%prep +%setup -q -n %{name}-%{version} +chmod 0644 utils/{conftree.cpp,conftree.h,debuglog.cpp,debuglog.h} + +%build +CFLAGS="%{optflags}"; export CFLAGS +CXXFLAGS="%{optflags}"; export CXXFLAGS +LDFLAGS="%{?__global_ldflags}"; export LDFLAGS + +# force use of custom/local qmake, to inject proper build flags (above) +#install -m755 -D %{SOURCE10} qmake-qt4.sh +export QMAKE=qmake-qt5 + +%configure +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} STRIP=/bin/true INSTALL='install -p' + +desktop-file-install --delete-original \ + --dir=%{buildroot}/%{_datadir}/applications \ + %{buildroot}/%{_datadir}/applications/%{name}-searchgui.desktop + +# use /usr/bin/xdg-open +rm -f %{buildroot}/usr/share/recoll/filters/xdg-open + +# fix perms +chmod 0755 %{buildroot}/usr/share/recoll/filters/rclexecm.py +chmod 0755 %{buildroot}%{_libdir}/recoll/librecoll.so.* + +# kio_recoll -kde5 +( +mkdir kde/kioslave/kio_recoll/build && pushd kde/kioslave/kio_recoll/build +%cmake .. +make %{?_smp_mflags} VERBOSE=1 +make install DESTDIR=%{buildroot} +popd +) + +# kio_recoll -kde4 +( +mkdir kde/kioslave/kio_recoll-kde4/build && \ + pushd kde/kioslave/kio_recoll-kde4/build +%cmake .. +make %{?_smp_mflags} VERBOSE=1 +make install DESTDIR=%{buildroot} +popd +) + +mkdir -p %{buildroot}%{_sysconfdir}/ld.so.conf.d +echo "%{_libdir}/recoll" > %{buildroot}%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf + +%post +touch --no-create %{_datadir}/icons/hicolor +if [ -x %{_bindir}/gtk-update-icon-cache ] ; then + %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor +fi +if [ -x %{_bindir}/update-desktop-database ] ; then + %{_bindir}/update-desktop-database &> /dev/null +fi +/sbin/ldconfig +exit 0 + +%postun +touch --no-create %{_datadir}/icons/hicolor +if [ -x %{_bindir}/gtk-update-icon-cache ] ; then + %{_bindir}/gtk-update-icon-cache --quiet %{_datadir}/icons/hicolor +fi +if [ -x %{_bindir}/update-desktop-database ] ; then + %{_bindir}/update-desktop-database &> /dev/null +fi +/sbin/ldconfig +exit 0 + +%files +%doc COPYING ChangeLog README +%{_sysconfdir}/ld.so.conf.d/%{name}-%{_arch}.conf +%{_bindir}/%{name} +%{_bindir}/%{name}index +%{_datadir}/%{name} +%{_datadir}/appdata/%{name}.appdata.xml +%{_datadir}/applications/%{name}-searchgui.desktop +%{_datadir}/icons/hicolor/48x48/apps/%{name}.png +%{_datadir}/pixmaps/%{name}.png +%{_libdir}/recoll +%{python_sitearch}/recoll +%{python_sitearch}/Recoll*.egg-info +%{_mandir}/man1/%{name}.1* +%{_mandir}/man1/%{name}q.1* +%{_mandir}/man1/%{name}index.1* +%{_mandir}/man5/%{name}.conf.5* + +%files kio +%{_libdir}/kde4/kio_recoll.so +%{_libdir}/qt5/plugins/kio_recoll.so +%{_datadir}/kde4/apps/kio_recoll/ +%{_datadir}/kde4/services/recoll.protocol +%{_datadir}/kde4/services/recollf.protocol +%{_datadir}/kio_recoll/help.html +%{_datadir}/kio_recoll/welcome.html +%{_datadir}/kservices5/recoll.protocol +%{_datadir}/kservices5/recollf.protocol + +%changelog +* Mon Jan 18 2016 Terje Rosten - 1.21.4-1 +- 1.21.4 + +* Sat Oct 31 2015 Terje Rosten - 1.21.3-1 +- 1.21.3 + +* Sat Oct 03 2015 Terje Rosten - 1.21.2-1 +- 1.21.2 + +* Thu Jun 18 2015 Fedora Release Engineering - 1.20.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue May 05 2015 Terje Rosten - 1.20.6-1 +- 1.20.6 +- Fixes bz#1218161 and bz#1204464 + +* Sat May 02 2015 Kalev Lember - 1.20.5-3 +- Rebuilt for GCC 5 C++11 ABI change + +* Sat Apr 11 2015 Terje Rosten - 1.20.5-2 +- Add KIO subpackage + +* Tue Apr 07 2015 Terje Rosten - 1.20.5-1 +- 1.20.5 +- Include kio support (bz#1203257) + +* Sat Jan 10 2015 Terje Rosten - 1.20.1-1 +- 1.20.1 + +* Sun Nov 09 2014 Terje Rosten - 1.19.14p2-1 +- 1.19.14p2 + +* Sun Aug 17 2014 Fedora Release Engineering - 1.19.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 1.19.13-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Tue May 06 2014 Terje Rosten - 1.19.13-1 +- 1.19.13 + +* Mon Jan 20 2014 Terje Rosten - 1.19.11-1 +- 1.19.11 + +* Mon Nov 11 2013 Terje Rosten - 1.19.9-1 +- 1.19.9 + +* Tue Nov 05 2013 Terje Rosten - 1.19.8-1 +- 1.19.8 + +* Sun Aug 04 2013 Fedora Release Engineering - 1.19.4-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Wed Jun 12 2013 Terje Rosten - 1.19.4-2 +- Fix filter setup + +* Mon Jun 10 2013 Terje Rosten - 1.19.4-1 +- 1.19.4 + +* Thu Feb 14 2013 Fedora Release Engineering - 1.18.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Nov 19 2012 Terje Rosten - 1.18.1-1 +- 1.18.1 + +* Sat Jul 21 2012 Fedora Release Engineering - 1.17.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Wed May 30 2012 Terje Rosten - 1.17.3-1 +- 1.17.3 + +* Sat Mar 31 2012 Terje Rosten - 1.17.1-1 +- 1.17.1 + +* Sun Mar 25 2012 Terje Rosten - 1.17-1 +- 1.17 + +* Tue Feb 28 2012 Fedora Release Engineering - 1.16.2-3 +- Rebuilt for c++ ABI breakage + +* Wed Feb 15 2012 Terje Rosten - 1.16.2-2 +- Add patch to build with gcc 4.7 + +* Wed Feb 01 2012 Terje Rosten - 1.16.2-1 +- 1.16.2 + +* Sat Jan 14 2012 Fedora Release Engineering - 1.16.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Mon Oct 24 2011 Terje Rosten - 1.16.1-2 +- Add patch to fix crash (bz #747472) + +* Tue Oct 18 2011 Terje Rosten - 1.16.1-1 +- 1.16.1 + +* Tue May 24 2011 Terje Rosten - 1.15.8-2 +- add patch from upstream to fix crash. + +* Sun May 08 2011 Terje Rosten - 1.15.8-1 +- 1.15.8 + +* Wed Feb 09 2011 Fedora Release Engineering - 1.14.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Jan 28 2011 Terje Rosten - 1.14.4-1 +- 1.14.4 + +* Mon Nov 15 2010 Terje Rosten - 1.14.2-2 +- Add patch to fix #631704 + +* Sun Nov 7 2010 Terje Rosten - 1.14.2-1 +- 1.14.2 + +* Thu Jul 15 2010 Terje Rosten - 1.13.04-6 +- add patch to build with xapian 1.2 (from J.F. Dockes, thanks) + +* Sat Jul 10 2010 Terje Rosten - 1.13.04-5 +- use system xdg-open +- trim chagenlog + +* Fri Jul 9 2010 Terje Rosten - 1.13.04-4 +- fix some review comments + +* Mon May 10 2010 Terje Rosten - 1.13.04-3 +- use version macro in source url +- don't strip bins, giving non empty debuginfo package +- more explicit file listing +- try to preserve timestamps +- use proper name for spec file +- fix changelog +- license seems to be GPLv2+ +- include some %%doc files +- add buildroot tag +- some source add execute bit set +- explicit enable inotify +- add aspell-devel to bulldreq +- make with _smp_mflags seems to work +- add post scripts +- add patch to build gui with correct flags (ref: 338791) + +* Sun May 9 2010 J.F. Dockes 1.13.04-2 +- bumped the release number to issue new rpms for fc10 + +* Sun May 9 2010 J.F. Dockes 1.13.04 +- updated to recoll release 1.13.04 + +* Fri Feb 12 2010 Terry Duell 1.13.02 +- updated to release 1.13.02 + +* Tue Jan 12 2010 Terry Duell 1.13.01-3 +- updated to fix Fedora desktop-file-install and install icon + +* Sun Jan 10 2010 Jean-Francois Dockes 1.13.01-2 +- updated for recent fedoras: depend on xapian packages, use qt4 + +* Thu Jan 07 2010 Jean-Francois Dockes 1.13.01-1 +- update to release 1.13.01 + +* Wed Feb 1 2006 Jean-Francois Dockes 1.2.0-1 +- initial packaging diff --git a/packaging/rpm/recollmdk.spec b/packaging/rpm/recollmdk.spec new file mode 100644 index 00000000..3b4d1168 --- /dev/null +++ b/packaging/rpm/recollmdk.spec @@ -0,0 +1,130 @@ +%define name recoll +%define version 1.18.1 +%define release %mkrel 1 + +Name: %{name} +Version: %{version} +Release: %{release} + +Summary: Desktop full text search tool with a qt gui +Source0: http://www.recoll.org/%{name}-%{version}.tar.gz +URL: http://www.recoll.org/ +Group: Applications/Databases + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +License: GPL +BuildRequires: libqt4-devel +BuildRequires: libqtwebkit2.2-devel +BuildRequires: libpython-devel +BuildRequires: libxapian-devel + +%description +Recoll is a personal full text search package for Linux, FreeBSD and +other Unix systems. It is based on a very strong backend (Xapian), for +which it provides an easy to use, feature-rich, easy administration +interface. + +# --------------------------------------------------------------------------- + +%prep +%setup -q + +# --------------------------------------------------------------------------- + +%build +[ -n "$QTDIR" ] || . %{_sysconfdir}/profile.d/60qt4.sh +%configure +make %{?_smp_mflags} + +# --------------------------------------------------------------------------- + +%install +rm -rf $RPM_BUILD_ROOT +%makeinstall + +# --------------------------------------------------------------------------- + +%clean +rm -rf $RPM_BUILD_ROOT + +# --------------------------------------------------------------------------- + +%files +%defattr(-,root,root,-) +%{_bindir}/* +%{_datadir}/applications/recoll-searchgui.desktop +%{_datadir}/icons/hicolor/48x48/apps/recoll.png +%{_datadir}/pixmaps/recoll.png +%{_datadir}/%{name} +%{_mandir}/man1/recoll* +%{_mandir}/man5/recoll* +%{python_sitearch}/Recoll*.egg-info +%{python_sitearch}/recoll.so + +# --------------------------------------------------------------------------- + +%changelog +* Mon Nov 05 2012 Jean-Francois Dockes 1.18.1-1 +- Update to release 1.18.1 +* Thu May 17 2012 Jean-Francois Dockes 1.17.2-1 +- Update to release 1.17.2 +* Mon Nov 07 2011 Jean-Francois Dockes 1.16.2-1 +- Update to release 1.16.2 +* Wed Sep 28 2011 Jean-Francois Dockes 1.16.1-1 +- Update to release 1.16.1 +* Wed Sep 21 2011 Jean-Francois Dockes 1.16.0-1 +- Update to release 1.16.0 +* Tue May 03 2011 Jean-Francois Dockes 1.15.8-1 +- Update to release 1.15.8 +* Fri Mar 04 2011 Jean-Francois Dockes 1.15.5-1 +- Update to release 1.15.5 +* Thu Feb 15 2011 Jean-Francois Dockes 1.15.2-1 +- Update to release 1.15.2 +* Wed Feb 02 2011 Jean-Francois Dockes 1.15.0-1 +- Update to release 1.15.0 +* Thu Nov 25 2010 Jean-Francois Dockes 1.14.3-1 +- Update to release 1.14.2 +* Sat Sep 24 2010 Jean-Francois Dockes 1.14.2-1 +- Update to release 1.14.2 +* Mon Sep 13 2010 Jean-Francois Dockes 1.14.0-1 +- Update to release 1.14.0 +* Thu Apr 14 2010 Jean-Francois Dockes 1.13.04-1 +- Update to release 1.13.01 +* Thu Jan 07 2010 Jean-Francois Dockes 1.13.01-1 +- Update to release 1.13.01 +* Thu Dec 10 2009 Jean-Francois Dockes 1.12.4-1 +- Update to release 1.12.2 +* Mon Oct 19 2009 Jean-Francois Dockes 1.12.2-1 +- Update to release 1.12.2 +* Thu Jan 29 2009 Jean-Francois Dockes 1.12.0-1 +- Update to release 1.12.0 +* Mon Oct 13 2008 Jean-Francois Dockes 1.11.0-1 +- Update to release 1.11.0 +* Thu May 27 2008 Jean-Francois Dockes 1.10.2-1 +- Update to release 1.10.2 +* Thu Jan 31 2008 Jean-Francois Dockes 1.10.1-1 +- Update to release 1.10.1 +* Wed Nov 21 2007 Jean-Francois Dockes 1.10.0-1 +- Update to release 1.10.0 +* Tue Sep 11 2007 Jean-Francois Dockes 1.9.0-1 +- Update to release 1.9.0 +* Tue Mar 6 2007 Jean-Francois Dockes 1.8.1-1 +- Update to release 1.8.1 +* Mon Jan 15 2007 Jean-Francois Dockes 1.7.5-1 +- Update to release 1.7.5 +* Mon Jan 08 2007 Jean-Francois Dockes 1.7.3-1 +- Update to release 1.7.3 +* Tue Nov 28 2006 Jean-Francois Dockes 1.6.1-1 +- Update to release 1.6.1 +* Mon Nov 20 2006 Jean-Francois Dockes 1.5.11-1 +- Update to release 1.5.11 +* Mon Oct 2 2006 Jean-Francois Dockes 1.5.2-1 +- Update to release 1.5.2 +* Sun May 7 2006 Jean-Francois Dockes 1.4.3-1 +- Update to release 1.4.3 +* Fri Mar 31 2006 Jean-Francois Dockes 1.3.3-1 +- Update to release 1.3.3 +* Thu Feb 2 2006 Jean-Francois Dockes 1.2.2-1 +- Update to release 1.2.2 +* Thu Jan 10 2006 Jean-Francois Dockes 1.1.0-1 +- Initial packaging diff --git a/src/COPYING b/src/COPYING new file mode 100644 index 00000000..d60c31a9 --- /dev/null +++ b/src/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/src/ChangeLog b/src/ChangeLog new file mode 100644 index 00000000..dd186d2d --- /dev/null +++ b/src/ChangeLog @@ -0,0 +1,10552 @@ +2010-02-02 15:33 +0100 Jean-Francois Dockes (d11da0283f03 [tip]) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/query/plaintorich.cpp, src/query/recollq.cpp, + src/query/wasatorcl.cpp, src/rcldb/rcldb.cpp, + src/rcldb/searchdata.cpp, src/rcldb/stoplist.cpp, + src/rcldb/stoplist.h: + cosmetics: use derived class for actual splitter instead of callback + +2010-02-02 10:24 +0100 Jean-Francois Dockes (a8caf709bcd3) + + * src/qt4gui/rclmain.ui, src/qtgui/rclmain.ui, + src/qtgui/rclmain_w.cpp: + QT GUI: define accelerators for res list page movements + +2010-02-02 08:20 +0100 Jean-Francois Dockes (ec31e285a553) + + * src/qtgui/reslist.cpp, src/query/reslistpager.h: + Qt GUI: ensure that new page size is taken into account ASAP (no + need for restarting app) + +2010-02-01 17:51 +0100 Jean-Francois Dockes (db953bb94c7f) + + * src/qt4gui/rclmain.ui, src/qtgui/preview_w.cpp, + src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h: + QT GUI: add fullscreen mode + +2010-02-01 10:31 +0100 Jean-Francois Dockes (1eda55ae3be9) + + * src/mk/manifest.txt: new file. + * src/excludefile, src/makesrcdist.sh, src/mk/manifest.txt: + Making a source dist: check the new list against old reference + + other checks + +2010-01-31 19:53 +0100 Israel G. Lugo (74d4e25d43c2) + + * src/recollinstall.in: + Install recollq and its manpage when in cmdline mode. Don't install + the recoll.1 manpage when in cmdline mode. + +2010-01-31 19:47 +0100 Jean-Francois Dockes (c88b0ef40512) + + * src/common/autoconfig.h.in: + use 3-arg version of ac_define as the 1-arg one is being obsoleted + +2010-01-31 19:45 +0100 Jean-Francois Dockes (1960435ccb68) + + * src/configure.ac: + Dispense with the x11-monitoring when neither fam nor inotify are + configured + +2010-01-31 19:35 +0100 Jean-Francois Dockes (08e6abfc5fdf) + + * src/configure.ac: + use 3-arg version of ac_define as the 1-arg one is being obsoleted + +2010-01-31 19:34 +0100 Jean-Francois Dockes (c0add9dd8ad4) + + * website/download.html: + none + +2010-01-30 17:47 +0100 Jean-Francois Dockes (5ed138ff2230) + + * src/qtgui/spell_w.cpp, src/qtgui/spell_w.h: + QT GUI: fix small problems in newly native qt4 term expander + +2010-01-30 17:31 +0100 Jean-Francois Dockes (6ecf959a8e01) + + * src/qt4gui/spell.ui: new file. + * src/qt4gui/recollmain.ui: deleted file. + * .hgignore, src/qt4gui/recollmain.ui, src/qt4gui/spell.ui, + src/qt4gui/uifrom3, src/qtgui/spell_w.cpp, src/qtgui/spell_w.h: + QT GUI: converted the qt4 term expander dialog to native qt4 + +2010-01-30 14:09 +0100 Jean-Francois Dockes (df8a91aaff88) + + * src/qt4gui/rclmain.ui: new file. + * .hgignore, src/qt4gui/rclmain.ui, src/qt4gui/uifrom3, + src/qtgui/confgui/confguiindex.h, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h: + Qt GUI: made the Qt4 main window native Qt4 (no more use of + Q3MainWindow) + +2010-01-30 08:23 +0100 Jean-Francois Dockes (ed18703563b7) + + * .hgignore, src/ChangeLog, website/BUGS.html, website/devel.html, + website/doc.html, website/download.html, website/index.html.en: + none + +2010-01-30 08:23 +0100 Jean-Francois Dockes (22044a3b2e2c) + + * src/qtgui/rclmain_w.h: + Qt 4.6.1 Uic bug: change qt version test from == to <= as bug still + here in 4.6.2 + +2010-01-30 08:21 +0100 Jean-Francois Dockes (b1cb8c664953) + + * src/common/autoconfig.h.in, src/configure, src/configure.ac, + src/index/recollindex.cpp, src/utils/x11mon.cpp: + Renamed WITHOUT_X11 to DISABLE_X11MON for clarification + +2010-01-30 08:18 +0100 Israel G. Lugo (be03b72e1258) + + * src/configure.ac: + Rename option without-gui to disable-qtgui. New option disable- + x11mon. Separate control of creation of the gui and X11 session + monitoring. + +2010-01-29 19:00 +0100 Jean-Francois Dockes (d95c21312a15) + + * src/kde/kioslave/recoll/CMakeLists.txt: + KIO slave: fixed CMakeList to configure Recoll with --enable-pic + +2010-01-29 17:22 +0100 Jean-Francois Dockes (266941720a99) + + * src/python/README.txt: new file. + * src/configure, src/configure.ac, src/doc/user/usermanual.sgml, + src/lib/Makefile, src/lib/mkMake, src/mk/commondefs, + src/mk/localdefs.in, src/php/00README.txt, src/python/README.txt, + src/python/recoll/setup.py: + Implemented configure --enable-pic flag to build the main lib with + position-independant objects. This avoids having to edit localdefs + by hand to build the new php extension, and voids the need for the + Python module to recompile Recoll source files. + +2010-01-29 15:47 +0100 Jean-Francois Dockes (69c42078b8d3) + + * src/php/00README.txt: new file. + * src/php/00README.txt, src/php/recoll/make.sh, + src/php/recoll/recoll.cpp: + PHP extension by Wenqiang Song : make ready for external use. + - added minimal doc + - fixed build script to work around php/libtool issue + - have the module default to Query Language (instead of AND) + +2010-01-28 18:22 +0100 Jean-Francois Dockes (45e7ec5e16c5) + + * .hgignore, website/usermanual/README-dir.txt: new file. + * packaging/debian/changelog, packaging/debian/compat, + packaging/debian/control, packaging/debian/copyright, + packaging/debian/docs, packaging/debian/menu, + packaging/debian/rules, packaging/debian/watch: deleted file. + * .hgignore, packaging/debian/changelog, packaging/debian/compat, + packaging/debian/control, packaging/debian/copyright, + packaging/debian/docs, packaging/debian/menu, + packaging/debian/rules, packaging/debian/watch, src/makesrcdist.sh, + website/usermanual/README-dir.txt: + svn->mercurial modifications + +2010-01-28 16:13 +0000 convert-repo (e85c82d42126) + + * .hgtags: new file. + * .hgtags: + update tags + +2010-01-26 13:23 +0000 dockes (c0cb63a2702a) + + * last before trial switch to mercurial. really. Yeah + +2010-01-26 13:22 +0000 dockes (c40e044c63dd) + + * tests/chm/chm.sh, tests/chm/chm.txt, tests/ics/ics.sh, + tests/ics/ics.txt, tests/zip/mcKee.zip, tests/zip/zip.sh, + tests/zip/zip.txt, website/download-1.12.html: new file. + * tests/chm/chm.sh, tests/chm/chm.txt, tests/ics/ics.sh, + tests/ics/ics.txt, tests/zip/mcKee.zip, tests/zip/zip.sh, + tests/zip/zip.txt, website/download-1.12.html: + last before trial switch to mercurial. really + +2010-01-26 13:21 +0000 dockes (7918f7073757) + + * website/BUGS.html, website/CHANGES.html, website/download.html, + website/index.html.en, website/index.html.fr: + last before trial switch to mercurial + +2010-01-26 07:06 +0000 dockes (0b5ec08c2ba2) + + * src/INSTALL, src/README: + + +2010-01-26 07:06 +0000 dockes (f6a420527382) + + * src/VERSION: + 1.13.02 + +2010-01-26 06:50 +0000 dockes (b223f221578a [RECOLL_1_13_02]) + + * src/doc/user/usermanual.sgml: + clarified --prefix et al + +2010-01-25 20:43 +0000 dockes (7d69ae778654) + + * src/qt4gui/ui_rclmain.h-4.5: new file. + * src/qt4gui/ui_rclmain.h-4.5, src/qtgui/rclmain_w.h: + use older ui include file under qt 4.6.1, the one its uic generates + is broken + +2010-01-25 11:08 +0000 dockes (e2e5a1dd802d) + + * src/php/recoll/recollq.h: deleted file. + * src/php/recoll/recollq.h: + not used? + +2010-01-25 11:06 +0000 dockes (1683475297c1) + + * src/php/recoll/config.m4, src/php/recoll/make.sh, + src/php/recoll/php_recoll.h, src/php/recoll/recoll.cpp, + src/php/recoll/recollq.h, src/php/sample/shell.php: new file. + * src/php/recoll/config.m4, src/php/recoll/make.sh, + src/php/recoll/php_recoll.h, src/php/recoll/recoll.cpp, + src/php/recoll/recollq.h, src/php/sample/shell.php: + initial import from W. Song + +2010-01-20 07:42 +0000 dockes (4df8ebfbb72d) + + * packaging/rpm/recoll.spec, packaging/rpm/recollfedora.spec, + packaging/rpm/recollfedora10.spec, packaging/rpm/recollmdk.spec: + change mail address + +2010-01-10 10:18 +0000 dockes (1c62f24a5ca4) + + * packaging/rpm/recollfedora.spec: + updated for fc12: depend on xapian-core, use qt4 + +2010-01-07 15:20 +0000 dockes (01eb4176400c) + + * src/query/recollq.cpp: + add option to print abstracts + +2010-01-07 08:42 +0000 dockes (a41bbccff862) + + * src/VERSION: + 1.13.01 + +2010-01-07 08:41 +0000 dockes (dde7b27846ef) + + * src/Makefile.in: + distclean removes rclexecm.pyc + +2010-01-07 08:34 +0000 dockes (324bea9902a4) + + * src/qtgui/main.cpp, src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/ssearch_w.cpp, src/qtgui/ssearch_w.h: + moved initial db open and possible message boxes from main.cpp to + rclmain_w.cpp first post-init job to avoid random crashes apparently + related to the dialogs being created before app.exec(). Exact cause + not certain, but crashes gone... + +2010-01-07 08:29 +0000 dockes (0629e02f12fe) + + * src/rcldb/searchdata.cpp: + field values were not used in case term expansion was not performed + (phrase or capitalized term) + +2010-01-06 13:29 +0000 dockes (e10bbaeefab5) + + * src/kde/kioslave/recoll/htmlif.cpp, src/query/recollq.cpp, + src/query/xadump.cpp: + adapt kio and recollq to the new internfile interface + +2010-01-06 13:06 +0000 dockes (0f2378be2603) + + * src/kde/kioslave/recoll/CMakeLists.txt: + add libz + +2010-01-05 15:00 +0000 dockes (1ca577447878) + + * src/utils/closefrom.cpp, src/utils/fstreewalk.cpp, + src/utils/fstreewalk.h, tests/Maildir/Maildir.txt, + tests/andor/andor.sh, tests/andor/andor.txt, tests/cjk/cjk.sh, + tests/cjk/cjk.txt, tests/mail/mail.txt, tests/msword/msword.txt, + tests/txt/txt.txt, website/download.html: + 1.13 tests txt mods + solaris port (FNM_LEADING_DIR) + +2010-01-05 13:27 +0000 dockes (0ab6a2dfc2c3) + + * website/BUGS.html, website/CHANGES.html, website/copydocs, + website/credits.html, website/download.html, website/features.html, + website/index.html.en, website/index.html.fr: + web update for 1.13 + +2010-01-05 07:14 +0000 dockes (cb08729afcd2) + + * src/INSTALL, src/README: + + +2010-01-05 07:14 +0000 dockes (a1ba9ba640f7) + + * src/VERSION, src/common/rclconfig.cpp, src/doc/man/recoll.conf.5, + src/doc/user/usermanual.sgml: + 1.13.00: fixed doc ortographic typos + +2009-12-31 08:20 +0000 dockes (c2ae39772161) + + * src/INSTALL, src/README: + + +2009-12-31 08:15 +0000 dockes (851e5b82f3d5) + + * src/VERSION: + 1.13.0 + +2009-12-31 08:15 +0000 dockes (04512125010e) + + * src/recollinstall.in: + handle --without-gui config inside recollinstall.in + +2009-12-20 14:31 +0000 dockes (2cbda11286c5) + + * src/configure, src/configure.ac: + typo in WIHOUT_X11 + +2009-12-17 20:23 +0000 dockes (95eb8a010525) + + * src/doc/user/usermanual.sgml: + There was an error in the mimemap format in the config exemple + +2009-12-14 10:33 +0000 dockes (1e774739395e) + + * src/INSTALL, src/README: + + +2009-12-14 10:33 +0000 dockes (49cdfe826199) + + * src/ChangeLog: + snapshot du jour + +2009-12-14 10:23 +0000 dockes (437be900fa14) + + * src/doc/user/Makefile, src/doc/user/usermanual.sgml: + add --enable-camelcase doc + fix typo in doc Makefile comment + +2009-12-14 10:10 +0000 dockes (009ed00592fd) + + * src/common/autoconfig.h.in, src/common/textsplit.cpp, src/configure, + src/configure.ac: + add --enable-camelcase option to configure + +2009-12-14 09:46 +0000 dockes (1fabd736d16f) + + * src/doc/user/usermanual.sgml, src/index/fsindexer.cpp: + use : as separator in localfields value before parsing as confsimple + +2009-12-14 09:44 +0000 dockes (2b09276dedc8) + + * src/utils/circache.cpp: + fix pointer casting to make gcc happy + +2009-12-14 09:44 +0000 dockes (4ee0085fa59e) + + * src/sampleconf/fields: + typo: keywords->keyword in prefixes + +2009-12-14 09:43 +0000 dockes (87b2caa6ec9c) + + * src/filters/rclabw, src/filters/rcldjvu, src/filters/rcldoc, + src/filters/rcldvi, src/filters/rclflac, src/filters/rclgaim, + src/filters/rclid3, src/filters/rclkwd, src/filters/rcllyx, + src/filters/rclman, src/filters/rclogg, src/filters/rclopxml, + src/filters/rclpdf, src/filters/rclppt, src/filters/rclps, + src/filters/rclpurple, src/filters/rclrtf, src/filters/rclscribus, + src/filters/rclsiduxman, src/filters/rclsoff, src/filters/rclsvg, + src/filters/rcltex, src/filters/rcltext, src/filters/rclwpd, + src/filters/rclxls, src/filters/recfiltcommon: + iscmd: supplement -x with -d test not a dir + +2009-12-14 07:26 +0000 dockes (b8eceb552b3e) + + * src/INSTALL, src/README: + + +2009-12-14 07:25 +0000 dockes (16dc2e0ed9fa) + + * src/makesrcdist.sh: + + +2009-12-14 07:13 +0000 dockes (e5aae08ee26d) + + * src/Makefile.in: + + +2009-12-14 07:07 +0000 dockes (c66c86594b35) + + * src/VERSION: + + +2009-12-14 07:06 +0000 dockes (7229a431d686) + + * src/makesrcdist.sh: + use different release name for beta versions + +2009-12-13 21:40 +0000 dockes (e0033b00df1e) + + * src/doc/user/usermanual.sgml: + anacron + +2009-12-13 16:16 +0000 dockes (e148cd3f92c1) + + * src/sampleconf/recoll.conf.in: + add localfields example + +2009-12-13 16:13 +0000 dockes (89ebf91076d8) + + * src/common/textsplit.cpp, src/internfile/mh_html.cpp, + src/query/plaintorich.cpp, src/utils/base64.cpp: + small amd64 fixes: 64 bits size_type, signed chars + +2009-12-08 07:43 +0000 dockes (026aa6df356f) + + * src/doc/man/recollindex.1, src/doc/man/recollq.1: + clarify stemming options + +2009-12-08 07:43 +0000 dockes (0c698007055e) + + * src/query/recollq.cpp: + add option -s to select stemming language + +2009-12-08 07:42 +0000 dockes (fcb5bca6adf8) + + * src/rcldb/stemdb.cpp: + traces + +2009-12-07 18:47 +0000 dockes (6631c645c9df) + + * src/index/recollindex.cpp: + use setpriority() to be a nice indexer + +2009-12-07 17:43 +0000 dockes (76128d18110e [RECOLL_1_13_0, RECOLL_20091214, RECOLL_1_13_01, RECOLL_1_13_00]) + + * src/qtgui/preview_w.cpp, src/qtgui/preview_w.h: + reimplemented Q3TextDocument::find() to be like the qt3 version + +2009-12-07 14:32 +0000 dockes (b02171ea3078) + + * src/qtgui/preview_w.cpp: + switch preview qtextedit format back to plain text after loading so + that selections copy plain text not html + +2009-12-07 13:27 +0000 dockes (3d37dc441cc9) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/searchdata.cpp: + Term expansion: handle field issues inside rcldb::termmatch, + ensuring that we take the field name into account for all + expansions. Ensures that File Name searches and filename: query + language searches work the same, + overall better consistency + +2009-12-07 13:24 +0000 dockes (fe625ef90a21) + + * src/configure.ac: + Israel G. Lugo: make sure that only one of inotify or FAM gets + enabled, giving priority to inotify. + +2009-11-30 10:04 +0000 dockes (a75cd5af7c71) + + * src/VERSION, src/internfile/mimehandler.cpp, + src/kde/kioslave/recoll/htmlif.cpp, src/qtgui/preview_w.cpp, + src/qtgui/preview_w.h, src/query/plaintorich.cpp, + src/query/plaintorich.h, src/sampleconf/mimeconf: + add
 tag to text/plain translated into qt html to preserve
+	indentation. Removes need for rcltext (which did just this). Allow
+	specifying any text/xxx as internal (allows having specific editor
+	but no filter)
+
+2009-11-30 06:34 +0000  dockes    (c4fdcda7df89)
+
+	* src/index/rclmonrcv.cpp:
+	compile either fam or inotify not both
+
+2009-11-29 15:00 +0000  dockes    (6b9ed9ae0949)
+
+	* src/doc/user/usermanual.sgml:
+	change defaults for big text params
+
+2009-11-29 12:56 +0000  dockes    (a04f5006fe89)
+
+	* src/sampleconf/recoll.conf.in:
+	add new 1.13 variables and defaults
+
+2009-11-28 09:15 +0000  dockes    (4b56c2068545)
+
+	* src/internfile/mh_execm.cpp, src/internfile/mh_text.cpp,
+	src/query/docseqhist.cpp, src/utils/circache.cpp:
+	new glibc missing includes
+
+2009-11-28 08:45 +0000  dockes    (012b4b63e260)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts:
+	
+
+2009-11-28 08:14 +0000  dockes    (b0e70a20b7f1)
+
+	* src/index/beaglequeue.cpp, src/internfile/mh_text.cpp,
+	src/qtgui/confgui/confguiindex.cpp, src/qtgui/guiutils.cpp:
+	set defaults usedesktoprefs, maxtext 20mb pagesz 1000k webcache 40m
+
+2009-11-28 08:11 +0000  dockes    (ed3a574543f5)
+
+	* src/doc/user/usermanual.sgml:
+	clean-up + documented 1.13 new features
+
+2009-11-28 06:39 +0000  dockes    (c45a690ee533)
+
+	* src/internfile/mh_mbox.cpp:
+	converted iostream to stdio because of mysterious read errors at the
+	last position in the offsets file
+
+2009-11-27 13:23 +0000  dockes    (7fa95cd57200)
+
+	* src/internfile/mh_mail.cpp:
+	add cnf(maildefcharset) to set specific mail default charset (mainly
+	for readpst extracts which are utf-8 but have no charset set)
+
+2009-11-27 13:11 +0000  dockes    (385305ee1820)
+
+	* src/rcldb/rcldb.cpp:
+	loglevel
+
+2009-11-27 13:08 +0000  dockes    (8cc1ab099807)
+
+	* src/internfile/mh_mbox.cpp:
+	include sys/stat
+
+2009-11-27 12:41 +0000  dockes    (c3039d4eab51)
+
+	* src/internfile/Filter.h, src/internfile/internfile.cpp,
+	src/internfile/mh_mbox.cpp, src/internfile/mh_mbox.h,
+	src/internfile/mimehandler.h, src/query/docseqhist.cpp:
+	implemented a cache for mbox message header offsets
+
+2009-11-27 07:07 +0000  dockes    (a1a92e0952dd)
+
+	* src/internfile/mh_mbox.cpp:
+	Support From "bla bla" (quoted) From lines
+
+2009-11-27 07:00 +0000  dockes    (64f09e3ad5a7)
+
+	* src/internfile/internfile.cpp:
+	update test driver
+
+2009-11-26 14:03 +0000  dockes    (023c2a8520de)
+
+	* src/aspell/rclaspell.cpp, src/aspell/rclaspell.h,
+	src/qtgui/reslist.cpp, src/qtgui/reslist.h, src/query/docseq.h,
+	src/query/docseqdb.cpp, src/query/docseqdb.h,
+	src/query/reslistpager.cpp, src/query/reslistpager.h,
+	src/rcldb/rcldb.cpp, src/rcldb/searchdata.cpp,
+	src/rcldb/searchdata.h:
+	suggest alternate spellings if no results
+
+2009-11-26 13:52 +0000  dockes    (4270622aa3e0)
+
+	* src/qtgui/guiutils.cpp:
+	suppressed core dump at exit on unexisting config
+
+2009-11-26 07:17 +0000  dockes    (f02bf2b6ea30)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rclquery.cpp, src/rcldb/rclquery.h:
+	use only match terms to build doc abstract, not all query terms
+	(might save a little effort)
+
+2009-11-26 07:15 +0000  dockes    (90776b10554c)
+
+	* src/qtgui/rclmain_w.cpp:
+	spell tool must be created even is USE_ASPELL is undefined
+
+2009-11-25 14:37 +0000  dockes    (e3faedd237b8)
+
+	* src/utils/md5.cpp:
+	suppress unused parm warning
+
+2009-11-25 11:07 +0000  dockes    (f8011c9579c8)
+
+	* packaging/debian/debiankio/changelog,
+	packaging/debian/debiankio/compat,
+	packaging/debian/debiankio/control,
+	packaging/debian/debiankio/copyright,
+	packaging/debian/debiankio/dirs, packaging/debian/debiankio/docs,
+	packaging/debian/debiankio/rules, packaging/debian/debiankio/watch,
+	packaging/debian/debianrecoll/changelog,
+	packaging/debian/debianrecoll/compat,
+	packaging/debian/debianrecoll/control,
+	packaging/debian/debianrecoll/copyright,
+	packaging/debian/debianrecoll/docs,
+	packaging/debian/debianrecoll/menu,
+	packaging/debian/debianrecoll/rules,
+	packaging/debian/debianrecoll/watch: new file.
+	* packaging/debian/debiankio/changelog,
+	packaging/debian/debiankio/compat,
+	packaging/debian/debiankio/control,
+	packaging/debian/debiankio/copyright,
+	packaging/debian/debiankio/dirs, packaging/debian/debiankio/docs,
+	packaging/debian/debiankio/rules, packaging/debian/debiankio/watch,
+	packaging/debian/debianrecoll/changelog,
+	packaging/debian/debianrecoll/compat,
+	packaging/debian/debianrecoll/control,
+	packaging/debian/debianrecoll/copyright,
+	packaging/debian/debianrecoll/docs,
+	packaging/debian/debianrecoll/menu,
+	packaging/debian/debianrecoll/rules,
+	packaging/debian/debianrecoll/watch:
+	added debian dir to build kio-recoll
+
+2009-11-24 10:25 +0000  dockes    (87057b6e2cba)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt:
+	execute minimum recoll config inside cmakelists to create rclversion
+	and autoconfig includes
+
+2009-11-24 10:24 +0000  dockes    (a6e854084ffb)
+
+	* src/utils/smallut.h:
+	gcc4
+
+2009-11-23 19:51 +0000  dockes    (42785e498950)
+
+	* src/index/beaglequeue.cpp:
+	store beagle fields before interning the file
+
+2009-11-23 17:38 +0000  dockes    (aaccb7e813a8)
+
+	* src/qtgui/preview_w.cpp:
+	if text is empty, display fields by default
+
+2009-11-23 17:37 +0000  dockes    (129654f22b3c)
+
+	* src/internfile/internfile.cpp:
+	in FileInterner::FileInterner(Rcl::Doc) (query), declare the
+	BeagleQueue static so that the cache persists between FileInterner
+	objects
+
+2009-11-23 17:36 +0000  dockes    (2292efb797b4)
+
+	* src/internfile/internfile.h:
+	comments
+
+2009-11-23 16:12 +0000  dockes    (a7ed9c85c313)
+
+	* src/query/dynconf.cpp, src/query/dynconf.h: new file.
+	* src/query/history.cpp, src/query/history.h: deleted file.
+	* src/lib/Makefile, src/lib/mkMake, src/qtgui/guiutils.cpp,
+	src/qtgui/main.cpp, src/qtgui/preview_w.cpp,
+	src/qtgui/rclmain_w.cpp, src/qtgui/recoll.h,
+	src/query/docseqhist.cpp, src/query/docseqhist.h,
+	src/query/dynconf.cpp, src/query/dynconf.h, src/query/history.cpp,
+	src/query/history.h:
+	revamped history feature to be udi-based while supporting old format
+
+2009-11-23 16:11 +0000  dockes    (8a494a30e71f)
+
+	* src/rcldb/rcldb.cpp:
+	set udi in meta from getDoc(udi)
+
+2009-11-23 16:10 +0000  dockes    (c432dcb83d8f)
+
+	* src/index/beaglequeue.cpp, src/utils/circache.cpp,
+	src/utils/circache.h:
+	Beaglequeue: simplify index from cache now that udi entries are
+	unique in cache
+
+2009-11-22 17:27 +0000  dockes    (112515ddfd1b)
+
+	* src/index/beaglequeue.cpp, src/utils/circache.cpp,
+	src/utils/circache.h:
+	only keep the latest entry for a given udi in the cache
+
+2009-11-22 17:26 +0000  dockes    (c47346e105ac)
+
+	* src/utils/smallut.h:
+	added tempbuf class
+
+2009-11-21 13:36 +0000  dockes    (d497773469db)
+
+	* src/internfile/mimehandler.cpp, src/qtgui/rclmain_w.cpp:
+	allow setting attrs on mimeview defs, factorize some code with
+	mhExecFactory
+
+2009-11-21 13:35 +0000  dockes    (77639dc8a584)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h:
+	added valueSplitAttributes() method
+
+2009-11-21 11:18 +0000  dockes    (50c2c8c764bb)
+
+	* src/internfile/mimehandler.cpp:
+	use a confsimple to parse the additional filter attributes
+
+2009-11-21 11:14 +0000  dockes    (ba1b73290998)
+
+	* src/qtgui/guiutils.h:
+	add ipath to default paragraph format
+
+2009-11-18 15:32 +0000  dockes    (132c512aacde)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt:
+	added beaglequeue/circache to kio build because of internfile
+	dependancy
+
+2009-11-18 14:27 +0000  dockes    (d1587dd98290)
+
+	* src/utils/circache.cpp:
+	warning
+
+2009-11-18 14:26 +0000  dockes    (812296ef15d8)
+
+	* src/rcldb/rclquery.cpp:
+	query::getrescnt() would only work once following 1.13 mods (affects
+	python api)
+
+2009-11-18 14:25 +0000  dockes    (cc1924f2d969)
+
+	* src/python/samples/recollq.py:
+	
+
+2009-11-18 14:03 +0000  dockes    (e60f229404a4)
+
+	* src/python/recoll/pyrecoll.cpp:
+	add some casts to avoid kwargs const warnings
+
+2009-11-18 13:46 +0000  dockes    (0e29576743b0)
+
+	* src/index/rclmonrcv.cpp:
+	typo
+
+2009-11-18 12:33 +0000  dockes    (da553b8d1e93)
+
+	* src/filters/rclchm, src/filters/rclexecm.py, src/filters/rclics,
+	src/internfile/mh_execm.cpp, src/internfile/mh_execm.h:
+	handle REFILTERROR in execm
+
+2009-11-18 10:26 +0000  dockes    (f28392bec173)
+
+	* src/internfile/mh_mail.cpp, src/rcldb/rcldb.cpp:
+	mh_mail: use truncate_to_word to avoid cutting an utf8 char. rcldb:
+	logdeb text_to_word errors
+
+2009-11-18 08:24 +0000  dockes    (c9b8704e7ffa)
+
+	* src/index/beaglequeue.cpp, src/mk/FreeBSD:
+	beaglequeue fully functional, small fixes remaining?
+
+2009-11-18 07:57 +0000  dockes    (0f863324690f)
+
+	* src/index/beaglequeue.cpp:
+	ok with compression
+
+2009-11-18 07:46 +0000  dockes    (7925e58ac0d9)
+
+	* src/utils/circache.cpp, src/utils/circache.h:
+	compression works
+
+2009-11-17 14:52 +0000  dockes    (122d9a523dc7)
+
+	* src/utils/circache.cpp, src/utils/circache.h:
+	circache ok
+
+2009-11-16 16:18 +0000  dockes    (88021fc84abd)
+
+	* src/internfile/internfile.cpp:
+	Lack of error checking after have_document() in preview case could
+	lead to looping, and cancellation was not checked to make things
+	worse
+
+2009-11-16 16:16 +0000  dockes    (22e0540453bc)
+
+	* src/configure:
+	--without-gui
+
+2009-11-16 16:12 +0000  dockes    (d3e16fb089de)
+
+	* src/qt4gui/recoll.pro.in:
+	stupid mistake in previous cosmetic change
+
+2009-11-16 16:11 +0000  dockes    (a422d8f6d6fd)
+
+	* src/index/fsindexer.cpp:
+	make very sure ~/.beagle is in the skippedPaths
+
+2009-11-16 16:10 +0000  dockes    (effac8983ab5)
+
+	* src/internfile/mh_mail.cpp:
+	reason msg
+
+2009-11-16 12:50 +0000  dockes    (bfc0df6ab067)
+
+	* src/Makefile.in, src/common/autoconfig.h.in, src/configure.ac,
+	src/index/Makefile, src/mk/localdefs.in, src/utils/x11mon.cpp:
+	add --without-gui configure option
+
+2009-11-15 16:41 +0000  dockes    (81edb2c4cef7)
+
+	* src/index/beaglequeue.cpp, src/index/fsindexer.cpp,
+	src/utils/circache.cpp:
+	catch cancel exceptions cast by internfile()
+
+2009-11-15 14:39 +0000  dockes    (4539869b5761)
+
+	* src/index/fsindexer.h, src/qtgui/rclmain_w.cpp,
+	src/query/reslistpager.cpp, src/rcldb/rcldoc.cpp,
+	src/rcldb/rcldoc.h, src/sampleconf/fields:
+	changed apptag field name to rclaptg
+
+2009-11-15 14:18 +0000  dockes    (b41678f5ad12)
+
+	* src/qt4gui/recoll.pro.in, src/qtgui/recoll.pro.in:
+	add -ldl -lX11 for binutils-gold
+
+2009-11-15 08:38 +0000  dockes    (3801ee9a51c6)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/index/fsindexer.cpp, src/index/rclmonrcv.cpp,
+	src/utils/fstreewalk.cpp, src/utils/fstreewalk.h,
+	src/utils/smallut.cpp, src/utils/smallut.h:
+	rationalized how we recompute things on setkeydir. recoll_noindex
+	and skippedNames can now be changed at any point in the tree
+
+2009-11-14 11:34 +0000  dockes    (a922eac98d16)
+
+	* src/index/rclmonprc.cpp:
+	monitor: accumulate mods during 30S before indexing
+
+2009-11-14 10:29 +0000  dockes    (ea134de640e0)
+
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h,
+	src/index/fsindexer.cpp, src/index/indexer.cpp,
+	src/index/rclmonrcv.cpp, src/index/recollindex.cpp,
+	src/utils/circache.cpp:
+	monitor the beagle queue
+
+2009-11-14 10:25 +0000  dockes    (42421f027b94)
+
+	* src/filters/rclchm, src/filters/rclics, src/filters/rcltext:
+	emit helpernotfound
+
+2009-11-14 08:21 +0000  dockes    (93baac7e87ac)
+
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h,
+	src/index/fsindexer.cpp, src/index/fsindexer.h,
+	src/index/indexer.cpp, src/index/indexer.h,
+	src/index/recollindex.cpp, src/index/recollindex.h,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	beaglequeue indexFiles
+
+2009-11-13 13:29 +0000  dockes    (7d0c4d7a917c)
+
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h,
+	src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/confgui/confguiindex.cpp, src/qtgui/preview_w.cpp,
+	src/qtgui/preview_w.h, src/qtgui/rclmain_w.cpp,
+	src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h, src/rcldb/rclquery.cpp,
+	src/sampleconf/fields:
+	1st beagle version with index/preview working
+
+2009-11-13 09:08 +0000  dockes    (71f8c28cbeba)
+
+	* src/qtgui/idxthread.cpp:
+	integrate beaglequeueindexer for indexing. Work remains for
+	indexfiles() at least
+
+2009-11-13 09:08 +0000  dockes    (dda5121a7c45)
+
+	* src/utils/circache.cpp, src/utils/circache.h:
+	integrate beaglequeueindexer for indexing. Work remains for
+	indexfiles() at least
+
+2009-11-13 09:07 +0000  dockes    (364d46e16faf)
+
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h,
+	src/index/fsindexer.cpp, src/index/fsindexer.h,
+	src/index/indexer.cpp, src/index/indexer.h,
+	src/index/recollindex.cpp:
+	integrate beaglequeueindexer for indexing. Work remains for
+	indexfiles() at least
+
+2009-11-13 09:04 +0000  dockes    (7e32466740a7)
+
+	* src/configure.ac:
+	Israel G. Lugo: give priority to the user's PATH when looking for
+	qmake (fixes detecting the wrong qmake when more than one exists).
+
+2009-11-13 09:01 +0000  dockes    (3503bfba6b70)
+
+	* src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h:
+	make dump const
+
+2009-11-13 09:01 +0000  dockes    (b4c8330037e7)
+
+	* src/lib/Makefile, src/lib/mkMake:
+	add beaglequeue, fsindexer
+
+2009-11-13 08:58 +0000  dockes    (63ee628229e7)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h:
+	add panel for beaglequeue parameters + arrange so that a checkbox
+	can enable/disable other params
+
+2009-11-13 08:54 +0000  dockes    (5edf24b7552e)
+
+	* src/sampleconf/fields:
+	comments
+
+2009-11-13 08:15 +0000  dockes    (a829fce15458)
+
+	* src/filters/rclchm, src/filters/rclexecm.py, src/filters/rclics,
+	src/filters/rclimg, src/filters/rclzip, src/internfile/mh_execm.cpp:
+	dont use 0-sized doc to mean eof now
+
+2009-11-11 18:09 +0000  dockes    (21b6ba1309c7)
+
+	* src/filters/rclimg:
+	send mimetype
+
+2009-11-11 18:07 +0000  dockes    (7f2a7a7214fb)
+
+	* src/internfile/mh_execm.cpp:
+	set mimetype for the non-ipath case
+
+2009-11-11 07:47 +0000  dockes    (75f9d10cf2f3)
+
+	* src/index/fsindexer.cpp, src/index/fsindexer.h,
+	src/index/indexer.cpp, src/index/indexer.h,
+	src/index/recollindex.cpp:
+	moved common db code from fsindexer to confindexer
+
+2009-11-10 18:11 +0000  dockes    (e079c8ce273f)
+
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h: new file.
+	* src/index/beaglequeue.cpp, src/index/beaglequeue.h:
+	
+
+2009-11-10 18:10 +0000  dockes    (698e70099ec0)
+
+	* src/index/fsindexer.cpp, src/index/fsindexer.h,
+	src/index/recollindex.h: new file.
+	* src/index/fsindexer.cpp, src/index/fsindexer.h,
+	src/index/indexer.cpp, src/index/indexer.h, src/index/rclmonprc.cpp,
+	src/index/recollindex.cpp, src/index/recollindex.h:
+	dbindexer->fsindexer, split into its own file
+
+2009-11-10 17:42 +0000  dockes    (ccf674432104)
+
+	* src/ChangeLog:
+	
+
+2009-11-10 17:42 +0000  dockes    (065c40b8964d)
+
+	* src/index/recollindex.cpp:
+	small cleanups and add option to call beaglequeue
+
+2009-11-10 17:41 +0000  dockes    (d4ff290d1615)
+
+	* src/index/indexer.cpp:
+	small cleanups and comments
+
+2009-11-10 17:39 +0000  dockes    (00c5f0c09ef9)
+
+	* src/index/indexer.h:
+	comments
+
+2009-11-10 17:38 +0000  dockes    (02b632bcbeca)
+
+	* src/index/rclmonrcv.cpp:
+	remove indexer.h include
+
+2009-11-10 17:38 +0000  dockes    (ba2255ec8b62)
+
+	* src/common/rclinit.h:
+	comment
+
+2009-11-10 17:37 +0000  dockes    (915bf923b8da)
+
+	* src/utils/fstreewalk.cpp, src/utils/fstreewalk.h:
+	add nocanon option
+
+2009-11-10 17:34 +0000  dockes    (29b753cd1f78)
+
+	* src/utils/circache.cpp, src/utils/circache.h:
+	intermediary checkpoint (things work, no index, no compression)
+
+2009-11-10 17:32 +0000  dockes    (16e0d5965055)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	removed the useless keep_updated flag
+
+2009-11-10 17:31 +0000  dockes    (75878eb08588)
+
+	* src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h:
+	added dump function
+
+2009-11-10 17:30 +0000  dockes    (35b43d00db47)
+
+	* src/query/recollq.cpp:
+	added explicit flag parameter to Internfile constructeur for helping
+	with beagle queue integration
+
+2009-11-10 17:29 +0000  dockes    (75255bb8d7a0)
+
+	* src/sampleconf/fields:
+	add dc:description as keywords alias
+
+2009-11-10 09:39 +0000  dockes    (ee6104876da9)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/kde/kioslave/recoll/htmlif.cpp, src/qtgui/preview_w.cpp:
+	added explicit flag parameter to Internfile constructeur for helping
+	with beagle queue integration
+
+2009-11-09 09:26 +0000  dockes    (7c3c0eed036b)
+
+	* src/utils/circache.cpp, src/utils/circache.h: new file.
+	* src/lib/Makefile, src/lib/mkMake, src/utils/Makefile,
+	src/utils/circache.cpp, src/utils/circache.h:
+	circache
+
+2009-11-09 09:26 +0000  dockes    (877bb76973aa)
+
+	* src/utils/conftree.cpp, src/utils/conftree.h:
+	add some constness
+
+2009-11-06 11:33 +0000  dockes    (944e0b9d1d53)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp, src/qtgui/reslist.h,
+	src/query/docseq.h, src/query/docseqdb.cpp, src/query/docseqdb.h,
+	src/query/docseqhist.cpp, src/query/docseqhist.h,
+	src/utils/fileudi.h, src/utils/pathut.cpp, src/utils/pathut.h:
+	allow opening parent/enclosing doc with native editor in reslist
+
+2009-11-06 11:26 +0000  dockes    (1d9a5530d7bf)
+
+	* src/sampleconf/mimeview:
+	added okular as chm viewer
+
+2009-11-04 13:52 +0000  dockes    (226d88ccb6c1)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp:
+	store file names using local8bit qstring conversions
+
+2009-11-04 13:43 +0000  dockes    (b57bd81d3e8e)
+
+	* src/utils/fstreewalk.h:
+	comment
+
+2009-11-04 13:42 +0000  dockes    (2037ae120bcf)
+
+	* src/utils/cancelcheck.h:
+	comment
+
+2009-10-31 09:00 +0000  dockes    (3ad7f6c85ce2)
+
+	* src/internfile/mh_mail.cpp, src/internfile/mh_mail.h:
+	extract msgid + generate abstract at start of txt, excluding headers
+
+2009-10-31 08:59 +0000  dockes    (9e7ae93bd35b)
+
+	* src/utils/mimeparse.cpp:
+	change rfc2047 mail header decoding (=?iso-xx stuff) so that a start
+	of encoding section can be recognized even not after white space
+
+2009-10-30 19:05 +0000  dockes    (eb9ed35f9fe0)
+
+	* src/qtgui/rclmain_w.cpp:
+	allow substituting all doc fields in viewer command line
+
+2009-10-30 19:04 +0000  dockes    (d8065c96ceae)
+
+	* src/qtgui/viewaction.ui:
+	clarify using desktop defs in action choice dialog
+
+2009-10-30 10:16 +0000  dockes    (4a744302db21)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/qtgui/rclmain_w.cpp, src/query/reslistpager.cpp,
+	src/sampleconf/fields:
+	Allow setting fields in fs subtree. Use for an application tag used
+	for starting a specialized viewer
+
+2009-10-30 08:59 +0000  dockes    (bdd54ae7a182)
+
+	* src/VERSION, src/common/rclconfig.h, src/index/indexer.cpp,
+	src/index/indexer.h, src/internfile/mimehandler.cpp,
+	src/rcldb/rcldb.cpp, src/rcldb/rclquery.cpp, src/utils/conftree.cpp,
+	src/utils/conftree.h:
+	Allow fields local to a subtree to be set in the configuration
+
+2009-10-30 08:53 +0000  dockes    (aa8c442a67ec)
+
+	* src/configure.ac:
+	use /bin/sh to execute recollinstall instead of making it executable
+
+2009-10-30 08:53 +0000  dockes    (0faf1f6ccf5f)
+
+	* src/Makefile.in, src/configure:
+	use /bin/sh to execute recollinstall instead of making it executable
+
+2009-10-29 18:11 +0000  dockes    (2338d18226f2)
+
+	* src/qtgui/uiprefs.ui:
+	move the use-desktop-preference checkbox close to the choose editors
+	button
+
+2009-10-29 18:10 +0000  dockes    (4b6f29c1e3c3)
+
+	* src/sampleconf/mimeconf:
+	
+
+2009-10-29 18:09 +0000  dockes    (2de2f1804086)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h:
+	support wildcard filtering in getConfNames() + implement config
+	checking function in test driver
+
+2009-10-29 18:08 +0000  dockes    (78c287d1d2da)
+
+	* src/utils/conftree.cpp, src/utils/conftree.h:
+	bugfix: if last line ended with backslash, entry was ignored. new
+	function: filter by wildcard expr in getNames()
+
+2009-10-29 13:44 +0000  dockes    (26ae4011727a)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimemap:
+	chm+comments
+
+2009-10-29 13:34 +0000  dockes    (178273f496f2)
+
+	* src/sampleconf/recoll.conf.in:
+	comment
+
+2009-10-28 13:08 +0000  dockes    (9435a56f1962)
+
+	* src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	fix signal/slot type mismatch for setSortParams
+
+2009-10-26 13:19 +0000  dockes    (2a369661c70c)
+
+	* src/qtgui/uiprefs_w.cpp:
+	disable app-choosing button when use-desktop-prefs is activated
+
+2009-10-26 11:16 +0000  dockes    (8cdb908a253d)
+
+	* src/qtgui/rclmain_w.cpp:
+	qt4 sometimes doesnt display the status bar if its not created in
+	init
+
+2009-10-26 10:00 +0000  dockes    (758f39788d0c)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h:
+	arrange to send pageup/down and shift-home to the reslist
+
+2009-10-24 15:02 +0000  dockes    (7d98b5c330c1)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb_p.h, src/rcldb/rclquery.cpp,
+	src/rcldb/rclquery_p.h:
+	unified retrying for databaseModified errors
+
+2009-10-24 11:00 +0000  dockes    (9d49d2991eed)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/rcldb_p.h,
+	src/rcldb/rclquery.cpp:
+	renamed fields for clarity
+
+2009-10-24 06:37 +0000  dockes    (1486d8f630fc)
+
+	* src/filters/rclchm, src/filters/rclics, src/filters/rclzip:
+	cleanup
+
+2009-10-24 06:17 +0000  dockes    (6a8a9821c17c)
+
+	* src/filters/rclexecm.py, src/filters/rclzip:
+	use python zipfile
+
+2009-10-23 16:45 +0000  dockes    (436e03b2f0c1)
+
+	* src/filters/rclchm:
+	comments
+
+2009-10-23 16:03 +0000  dockes    (be653b19dd28)
+
+	* src/filters/rclchm: new file.
+	* src/filters/rclchm:
+	first working
+
+2009-10-23 16:03 +0000  dockes    (99a819213c2a)
+
+	* src/filters/rclzip:
+	comment
+
+2009-10-22 17:28 +0000  dockes    (e5f16d6d23db)
+
+	* src/doc/user/usermanual.sgml:
+	%(fldname) specs
+
+2009-10-22 17:27 +0000  dockes    (3e37f6aac6c5)
+
+	* src/doc/user/docbook.css:
+	new freebsd version
+
+2009-10-22 17:27 +0000  dockes    (1535c07dd8a6)
+
+	* src/sampleconf/mimeconf:
+	ics
+
+2009-10-22 17:16 +0000  dockes    (deaef902d7e3)
+
+	* src/sampleconf/mimeconf:
+	add ics + more programming languages
+
+2009-10-22 17:16 +0000  dockes    (98009bab1e61)
+
+	* src/sampleconf/mimemap:
+	add ics + more programming languages
+
+2009-10-22 17:13 +0000  dockes    (bf9a0c5eeb5c)
+
+	* src/filters/rclics: new file.
+	* src/filters/rclexecm.py, src/filters/rclics:
+	initial support for icalendar splitting
+
+2009-10-22 12:24 +0000  dockes    (f97b91cb8153)
+
+	* src/filters/rclexecm.py: new file.
+	* src/filters/rclexecm.py, src/filters/rclzip:
+	made rclexecm a class in a separate module
+
+2009-10-22 11:58 +0000  dockes    (9361ab690eec)
+
+	* src/filters/rclzip:
+	fully extracted common code
+
+2009-10-21 21:00 +0000  dockes    (39b12da95a76)
+
+	* src/filters/rclzip: new file.
+	* src/filters/rclzip:
+	initial
+
+2009-10-21 20:59 +0000  dockes    (ef17d33ea782)
+
+	* website/download.html:
+	1.12.2
+
+2009-10-21 12:02 +0000  dockes    (2baccf2235b6)
+
+	* src/qtgui/rclmain_w.cpp, src/query/docseqdb.cpp,
+	src/query/docseqdb.h, src/query/reslistpager.cpp,
+	src/query/reslistpager.h, src/utils/Makefile, src/utils/smallut.cpp,
+	src/utils/smallut.h:
+	fix queryBuildAbstract option functionality. Allow substituting
+	%(fieldname) in reslist paragraph format
+
+2009-10-21 12:00 +0000  dockes    (30a02a6bada8)
+
+	* src/internfile/mimehandler.h:
+	warning
+
+2009-10-21 11:58 +0000  dockes    (ebc82bec7704)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt, src/utils/closefrom.cpp:
+	linux
+
+2009-10-21 11:32 +0000  dockes    (1cc979921a0d)
+
+	* src/internfile/mh_text.cpp, src/utils/closefrom.cpp:
+	gcc43+linux compile
+
+2009-10-21 07:48 +0000  dockes    (72168c28c9bb)
+
+	* src/makestaticdist.sh:
+	cleanup .svn directories
+
+2009-10-21 07:24 +0000  dockes    (a550073d34d4)
+
+	* src/makestaticdist.sh:
+	get makestaticdist to work with qt4
+
+2009-10-21 07:15 +0000  dockes    (e44497010880)
+
+	* packaging/debian/changelog, packaging/debian/control,
+	packaging/debian/menu, packaging/debian/rules,
+	packaging/rpm/recollmdk.spec, tests/lyx/lyx.txt:
+	1.12.2 release fixes
+
+2009-10-21 07:15 +0000  dockes    (cecbbb5e3c23)
+
+	* website/pics/mario.png, website/pics/smile.png: new file.
+	* website/mario.png, website/smile.png: deleted file.
+	* website/BUGS.html, website/CHANGES.html, website/devel.html,
+	website/download.html, website/features.html, website/index.html.en,
+	website/index.html.fr, website/mario.png, website/pics/index.html,
+	website/pics/mario.png, website/pics/recoll5-thumb.png,
+	website/pics/recoll5.png, website/pics/smile.png, website/smile.png:
+	1.12.2 release
+
+2009-10-19 16:20 +0000  dockes    (b2a9b0c5fc47)
+
+	* src/lib/Makefile, src/lib/mkMake:
+	add closefrom
+
+2009-10-19 16:19 +0000  dockes    (5b3c0f9438a9)
+
+	* src/README, src/doc/man/recoll.conf.5, src/doc/man/recollindex.1,
+	src/doc/user/usermanual.sgml, src/filters/rclsvg:
+	explict(e)ly errors again
+
+2009-10-19 10:51 +0000  dockes    (70ed5ded2a5e)
+
+	* src/qtgui/uiprefs.ui:
+	move the use-desktop-preference checkbox close to the choose editors
+	button
+
+2009-10-19 07:30 +0000  dockes    (d25d7050d60c)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rclquery.cpp:
+	catch xapian exceptions in 2 more places.
+
+2009-10-18 07:57 +0000  dockes    (cbcf397757a1)
+
+	* src/qtgui/reslist.cpp:
+	reslist: rightclick popup would not work inside table
+
+2009-10-17 06:38 +0000  dockes    (cb08cd6b282b)
+
+	* src/Makefile.in, src/index/recollindex.cpp, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	rclversion.h must not include xapian.h. Replace with
+	Rcl::version_string()
+
+2009-10-15 15:50 +0000  dockes    (6d01b54d3cf5)
+
+	* src/qtgui/preview_w.cpp:
+	compile with qt3
+
+2009-10-15 12:32 +0000  dockes    (749d93d72709)
+
+	* src/index/rclmonprc.cpp:
+	only call x11IsAlive from the main thread
+
+2009-10-15 12:32 +0000  dockes    (7339dd810b4c)
+
+	* src/utils/Makefile, src/utils/conftree.cpp, src/utils/execmd.cpp:
+	small linux include and makefile adjustments
+
+2009-10-14 12:25 +0000  dockes    (4bfcb9f6483a)
+
+	* src/utils/execmd.cpp, src/utils/execmd.h:
+	m_cancelRequest->m_killRequest to avoid confusion with cancelcheck +
+	close descriptors before exec
+
+2009-10-14 12:24 +0000  dockes    (834b841865f0)
+
+	* src/internfile/mh_exec.cpp:
+	no timeout if filtermaxseconds is -1
+
+2009-10-14 12:23 +0000  dockes    (894b94a986c2)
+
+	* src/qtgui/confgui/confguiindex.cpp, src/sampleconf/recoll.conf.in:
+	add filtermaxseconds to config
+
+2009-10-14 12:22 +0000  dockes    (eec367c78b29)
+
+	* src/utils/closefrom.cpp, src/utils/closefrom.h: new file.
+	* src/utils/closefrom.cpp, src/utils/closefrom.h:
+	
+
+2009-10-14 06:21 +0000  dockes    (48782c4d99bd)
+
+	* src/filters/rclimg, src/index/recollindex.cpp,
+	src/internfile/mh_execm.cpp, src/internfile/mh_execm.h,
+	src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/utils/execmd.cpp:
+	execm first working zip version
+
+2009-10-13 17:32 +0000  dockes    (ac8388c11bcb)
+
+	* src/utils/idfile.cpp, src/utils/idfile.h:
+	allow working on memory string
+
+2009-10-13 16:37 +0000  dockes    (25cd49e5f3b2)
+
+	* src/internfile/mh_exec.cpp:
+	comments
+
+2009-10-13 12:22 +0000  dockes    (f8f821415451)
+
+	* src/internfile/mh_exec.cpp:
+	handle interrupt requests and set timeout on execs
+
+2009-10-13 12:21 +0000  dockes    (0ec65928f00f)
+
+	* src/utils/execmd.cpp:
+	use process group to control/kill execd processes
+
+2009-10-13 12:20 +0000  dockes    (ad3f88e0578e)
+
+	* src/sampleconf/recoll.conf.in:
+	added loop.ps to skippedFiles
+
+2009-10-12 16:27 +0000  dockes    (2d5321b8e32c)
+
+	* src/common/rclinit.cpp:
+	also block USR1 USR2
+
+2009-10-09 13:58 +0000  dockes    (9ef52b9903d4)
+
+	* src/internfile/mh_execm.cpp, src/internfile/mh_execm.h: new file.
+	* src/filters/rclimg, src/internfile/mh_exec.cpp,
+	src/internfile/mh_exec.h, src/internfile/mh_execm.cpp,
+	src/internfile/mh_execm.h, src/internfile/mimehandler.cpp,
+	src/lib/Makefile, src/lib/mkMake, src/sampleconf/mimeconf:
+	execm persistent filters
+
+2009-10-09 13:57 +0000  dockes    (94243b4ecca6)
+
+	* src/common/textsplit.cpp:
+	process camelCase
+
+2009-10-09 13:34 +0000  dockes    (9129980cfe0e)
+
+	* src/utils/execmd.cpp, src/utils/execmd.h, src/utils/netcon.cpp,
+	src/utils/netcon.h:
+	Execmd: added count parameter to receive(), and new getline()
+	function Netcon: fix receive() to properly handle the case where
+	there is initially data in the line buffer
+
+2009-10-04 13:25 +0000  dockes    (f81cdfd36952)
+
+	* src/utils/readfile.cpp:
+	
+
+2009-10-04 13:24 +0000  dockes    (fe1c983b582e)
+
+	* src/mk/commondefs:
+	remove -I/usr/local/include from commondefs!
+
+2009-09-30 15:53 +0000  dockes    (401a53878320)
+
+	* src/internfile/mh_text.cpp:
+	dont set ipath for the first page in text files to avoid dual
+	records for files under the page size
+
+2009-09-30 15:45 +0000  dockes    (1ce015f48d3a)
+
+	* src/internfile/mh_text.cpp, src/internfile/mh_text.h,
+	src/qtgui/confgui/confguiindex.cpp, src/sampleconf/recoll.conf.in,
+	src/utils/readfile.cpp, src/utils/readfile.h:
+	implemented paged text files
+
+2009-09-29 15:58 +0000  dockes    (b288f2d22754)
+
+	* src/internfile/mh_text.cpp, src/qtgui/confgui/confguiindex.cpp,
+	src/sampleconf/recoll.conf.in:
+	textfilemaxmbs
+
+2009-09-29 15:58 +0000  dockes    (a41ae31020fa)
+
+	* src/utils/execmd.cpp:
+	loglevels
+
+2009-09-29 14:49 +0000  dockes    (89ab6fcd4bef)
+
+	* src/utils/netcon.cpp, src/utils/netcon.h: new file.
+	* src/utils/netcon.cpp, src/utils/netcon.h:
+	
+
+2009-09-29 14:49 +0000  dockes    (254aad5cdd17)
+
+	* src/utils/netcon.cpp, src/utils/netcon.h: deleted file.
+	* src/utils/netcon.cpp, src/utils/netcon.h:
+	
+
+2009-09-29 08:47 +0000  dockes    (302c0dd0dfa0)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	got rid of the preview tabdata array
+
+2009-09-29 07:48 +0000  dockes    (f65d40e808c6)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	make print a slot in the editor, not the preview
+
+2009-09-28 18:19 +0000  dockes    (5c03bd6d7d00)
+
+	* src/doc/user/usermanual.sgml, src/qtgui/preview_w.cpp,
+	src/qtgui/preview_w.h:
+	Preview printing
+
+2009-09-28 17:53 +0000  dockes    (564c8022205f)
+
+	* src/utils/execmd.cpp:
+	adjust log levels
+
+2009-09-26 09:30 +0000  dockes    (231f842cfa1a)
+
+	* src/utils/netcon.cpp, src/utils/netcon.h: new file.
+	* src/lib/Makefile, src/lib/mkMake, src/utils/execmd.cpp,
+	src/utils/execmd.h, src/utils/netcon.cpp, src/utils/netcon.h:
+	execmd uses netcon
+
+2009-09-26 09:05 +0000  dockes    (3883518b318e)
+
+	* src/rcldb/rclquery.cpp:
+	dont abort on get_mset exception
+
+2009-08-13 06:34 +0000  dockes    (71e1aa73c37e)
+
+	* src/utils/refcntr.h:
+	add release() method
+
+2009-08-13 06:32 +0000  dockes    (75501a297534)
+
+	* src/index/indexer.cpp, src/internfile/internfile.cpp,
+	src/internfile/internfile.h, src/internfile/mimehandler.cpp,
+	src/internfile/mimehandler.h:
+	xattrs: make them work with non-text files. Use ctime for up to date
+	checks
+
+2009-08-13 06:29 +0000  dockes    (45721e5ace5a)
+
+	* src/common/autoconfig.h.in:
+	allow choosing the "file" command from configure
+
+2009-08-13 06:28 +0000  dockes    (817bbeb36f34)
+
+	* src/qtgui/rclmain_w.cpp:
+	Make sure db is open at all times (caused problems when sorting
+	query started from the command line)
+
+2009-08-13 06:27 +0000  dockes    (05b809bbb7d0)
+
+	* src/qtgui/preview_w.cpp:
+	
+
+2009-08-13 06:26 +0000  dockes    (b5b49b39dc8a)
+
+	* src/configure, src/configure.ac, src/index/mimetype.cpp:
+	allow choosing the "file" command from configure
+
+2009-08-13 06:24 +0000  dockes    (902b5dc99b09)
+
+	* src/ChangeLog:
+	
+
+2009-08-13 06:23 +0000  dockes    (3ee15899a458)
+
+	* src/sampleconf/recoll.conf.in:
+	add indexedmimetypes to sample file
+
+2009-07-02 13:26 +0000  dockes    (a0f0be9546bb)
+
+	* src/filters/rclman:
+	
+
+2009-07-02 10:26 +0000  dockes    (82d09aa4b256)
+
+	* src/index/indexer.cpp, src/qtgui/rclmain_w.cpp:
+	improve periodic indexing status reporting and timer processing
+
+2009-07-02 06:17 +0000  dockes    (b8cdf0ab08a9)
+
+	* src/qtgui/main.cpp, src/rcldb/searchdata.h, src/utils/mimeparse.cpp,
+	src/utils/mimeparse.h:
+	explicitely->explicitly
+
+2009-06-26 09:25 +0000  dockes    (98153ad73366)
+
+	* src/filters/rclman, src/sampleconf/mimemap:
+	improve man page handling
+
+2009-06-22 16:41 +0000  dockes    (5003fe921249)
+
+	* src/qtgui/main.cpp, src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h:
+	moved periodic timer control from main.cpp to rclmain_w.cpp
+
+2009-06-22 15:25 +0000  dockes    (a420554375c5)
+
+	* src/qtgui/idxthread.cpp, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp:
+	use proper locking/sleeping object for idx thread sync
+
+2009-06-22 08:58 +0000  dockes    (d4fdc68fab47)
+
+	* src/filters/rclman:
+	use groff html output!
+
+2009-06-22 08:57 +0000  dockes    (01a166e9f9e7)
+
+	* src/index/indexer.cpp:
+	debug trace
+
+2009-06-01 06:32 +0000  dockes    (272067257953)
+
+	* src/qtgui/main.cpp:
+	fixed bug in handling remaining arguments as question pieces
+
+2009-05-29 06:28 +0000  dockes    (091488ca1543)
+
+	* src/bincimapmime/convert.h, src/utils/base64.cpp:
+	change strchr() return parameter to const for new libc
+
+2009-05-25 08:59 +0000  dockes    (6231c20d3e23)
+
+	* src/filters/rcllyx:
+	bug report from d.prost: spaces and accents in lyx file names
+
+2009-05-04 08:06 +0000  dockes    (20f1f5746b3e)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/preview_w.h,
+	src/qtgui/spell_w.cpp:
+	gcc44
+
+2009-04-27 11:49 +0000  dockes    (ba8db4a9fcf6)
+
+	* packaging/rpm/recollfedora10.spec: new file.
+	* packaging/rpm/recollfedora10.spec:
+	
+
+2009-04-27 11:42 +0000  dockes    (85e5723e268a)
+
+	* tests/cjk/cjk.txt: new file.
+	* tests/cjk/cjk.txt:
+	
+
+2009-04-27 09:40 +0000  dockes    (a7cf61bb3e6a)
+
+	* website/BUGS.html, website/download.html, website/index.html.en,
+	website/index.html.fr:
+	1.12 release changes
+
+2009-04-27 09:15 +0000  dockes    (eb2d1da3c9ee)
+
+	* website/BUGS.html:
+	
+
+2009-04-27 08:05 +0000  dockes    (c26df870665c)
+
+	* src/utils/md5.cpp, src/utils/readfile.cpp:
+	gcc 4.4 includes fixes
+
+2009-04-27 08:03 +0000  dockes    (5e892d5aa963)
+
+	* src/python/recoll/setup.py:
+	pathhash->fileudi
+
+2009-02-24 18:30 +0000  dockes    (d897d4f128ce)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp:
+	implement option to display the catg filter as a toolbar combobox
+
+2009-02-23 07:57 +0000  dockes    (5eb3b91eca18)
+
+	* src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts:
+	new ru/uk translations from Michael
+
+2009-02-06 16:49 +0000  dockes    (0946c032bea8)
+
+	* src/utils/refcntr.h:
+	make RefCntr(x*) explicit
+
+2009-02-06 16:48 +0000  dockes    (1f50a0e7a3ac)
+
+	* src/internfile/mimehandler.cpp:
+	comments
+
+2009-02-05 14:35 +0000  dockes    (1eb8b93ed85b)
+
+	* src/utils/execmd.cpp, src/utils/execmd.h:
+	1st execcmd cleanup
+
+2009-01-30 13:27 +0000  dockes    (55d06dfa9b04)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts, src/qtgui/reslist.cpp:
+	small pbs with reslist translations
+
+2009-01-30 11:43 +0000  dockes    (af28dae4f689)
+
+	* src/INSTALL, src/README:
+	
+
+2009-01-30 11:43 +0000  dockes    (581a47458445 [RECOLL_1_12_0])
+
+	* website/BUGS.html, website/CHANGES.html:
+	1.12.0?
+
+2009-01-30 11:42 +0000  dockes    (fd6cc84e76ce)
+
+	* src/doc/user/usermanual.sgml:
+	1.12 manual
+
+2009-01-30 10:22 +0000  dockes    (f683b3907dd1)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts:
+	updated message files, translated french
+
+2009-01-29 14:24 +0000  dockes    (f09b8b421535)
+
+	* src/filters/rcltext:
+	simplified rcltext. No need for awk and no assumptions on charset
+
+2009-01-29 11:27 +0000  dockes    (c8b882dea260)
+
+	* src/ChangeLog, website/CHANGES.html, website/doc.html:
+	
+
+2009-01-29 11:04 +0000  dockes    (0bf58162416f)
+
+	* src/VERSION:
+	1.12.0 une
+
+2009-01-29 10:47 +0000  dockes    (40e8e1f2f59b)
+
+	* packaging/debian/changelog, packaging/rpm/recoll.spec,
+	packaging/rpm/recollCooker.spec, packaging/rpm/recollfedora.spec,
+	packaging/rpm/recollmdk.spec:
+	
+
+2009-01-29 10:08 +0000  dockes    (2af56852a361)
+
+	* src/qtgui/main.cpp, src/qtgui/ssearch_w.cpp, src/qtgui/ssearch_w.h:
+	have ssearch install the lang help section when needed
+
+2009-01-28 17:41 +0000  dockes    (8654c9b9d56d)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp:
+	erase history would crash with empty reslist docsource
+
+2009-01-28 17:21 +0000  dockes    (8b56ccfdd91b)
+
+	* src/qtgui/rclmain_w.cpp:
+	fixed status bar messages (were cleared by periodic100 every 100ms)
+
+2009-01-28 17:05 +0000  dockes    (b435cf90abb0)
+
+	* src/qtgui/rclhelp.cpp, src/qtgui/rclhelp.h: new file.
+	* src/qtgui/rclhelp.cpp, src/qtgui/rclhelp.h:
+	F1 context-enhanced help
+
+2009-01-28 16:56 +0000  dockes    (e5410627d9d5)
+
+	* src/qt4gui/recoll.pro.in:
+	F1 context-enhanced help
+
+2009-01-28 16:56 +0000  dockes    (741df5618110)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h,
+	src/qtgui/main.cpp, src/qtgui/preview_w.cpp,
+	src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, src/qtgui/recoll.h,
+	src/qtgui/recoll.pro.in, src/qtgui/reslist.cpp,
+	src/qtgui/sort_w.cpp, src/qtgui/spell_w.cpp:
+	F1 context-enhanced help
+
+2009-01-28 14:58 +0000  dockes    (7e804d156dc5)
+
+	* src/qtgui/rclmain_w.cpp:
+	dont encode urls used for starting help browser
+
+2009-01-28 14:22 +0000  dockes    (e696212a674c)
+
+	* src/Makefile.in:
+	add xapian version to version string
+
+2009-01-28 08:45 +0000  dockes    (46251043fd88)
+
+	* src/qtgui/advsearch.ui, src/qtgui/sort.ui, src/qtgui/spell.ui,
+	src/qtgui/uiprefs.ui:
+	avoid setting 0 sizes
+
+2009-01-28 08:40 +0000  dockes    (1c551a065bdd)
+
+	* src/configure, src/configure.ac:
+	allow setting QMAKE in the environment
+
+2009-01-27 18:12 +0000  dockes    (fb41a05985ed)
+
+	* src/utils/pxattr.cpp:
+	
+
+2009-01-27 11:19 +0000  dockes    (3f5897bb4b8d)
+
+	* tests/stemming/stemming.sh, tests/stemming/stemming.txt: new file.
+	* tests/Maildir1/Maildir1.sh, tests/Maildir1/Maildir1.txt,
+	tests/andor/andor.sh, tests/andor/andor.txt,
+	tests/badsuffs/badsuffs.sh, tests/badsuffs/badsuffs.txt,
+	tests/badsuffs1/badsuffs1.sh, tests/badsuffs1/badsuffs1.txt,
+	tests/boolean/boolean.sh, tests/boolean/boolean.txt,
+	tests/cjk/cjk.sh, tests/delete/delete.sh, tests/delete/delete.txt,
+	tests/dirwithblanks/dirwithblanks.sh,
+	tests/dirwithblanks/dirwithblanks.txt, tests/djvu/djvu.sh,
+	tests/djvu/djvu.txt, tests/dvi/dvi.sh, tests/dvi/dvi.txt,
+	tests/empty/empty.sh, tests/empty/empty.txt, tests/html/html.sh,
+	tests/html/html.txt, tests/images/images.sh,
+	tests/images/images.txt, tests/koi8r/koi8r.sh,
+	tests/koi8r/koi8r.txt, tests/lyx/lyx.sh, tests/lyx/lyx.txt,
+	tests/mail/mail.sh, tests/mail/mail.txt, tests/media/media.sh,
+	tests/media/media.txt, tests/msword/msword.sh,
+	tests/msword/msword.txt, tests/notypes/notypes.sh,
+	tests/notypes/notypes.txt, tests/ooff/ooff.sh, tests/ooff/ooff.txt,
+	tests/pdf/pdf.sh, tests/pdf/pdf.txt, tests/postscript/postscript.sh,
+	tests/postscript/postscript.txt, tests/ppt/ppt.sh,
+	tests/ppt/ppt.txt, tests/rfc2231/rfc2231.sh,
+	tests/rfc2231/rfc2231.txt, tests/rtf/rtf.sh, tests/rtf/rtf.txt,
+	tests/runtests.sh, tests/scribus/scribus.sh,
+	tests/scribus/scribus.txt, tests/skipped/skipped.sh,
+	tests/skipped/skipped.txt, tests/special/special.sh,
+	tests/special/special.txt, tests/stemming/stemming.sh,
+	tests/stemming/stemming.txt, tests/txt/txt.sh, tests/txt/txt.txt,
+	tests/utf8/utf8.sh, tests/utf8/utf8.txt, tests/xls/xls.sh,
+	tests/xls/xls.txt:
+	remove recoll query text from compared test outputs
+
+2009-01-27 10:25 +0000  dockes    (57dd90e8b55d)
+
+	* src/common/textsplit.cpp, src/common/textsplit.h:
+	Emit a_b intermediary span when splitting a_b.c
+
+2009-01-26 18:30 +0000  dockes    (e2238061ec9d)
+
+	* src/query/plaintorich.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h,
+	src/rcldb/searchdata.cpp:
+	modified the time at which we unaccent so that we can do the
+	Capitalized->nostemming test on single words (this had been broken
+	by the change of noac/split order done earlier to get japanese to
+	work)
+
+2009-01-26 18:26 +0000  dockes    (8529cb7d58c7)
+
+	* tests/cjk/cjk.sh:
+	
+
+2009-01-26 17:52 +0000  dockes    (8a5b4971a703)
+
+	* tests/cjk/cjk.sh: new file.
+	* tests/cjk/cjk.sh:
+	
+
+2009-01-26 17:34 +0000  dockes    (e65566ba6690)
+
+	* website/BUGS.html, website/CHANGES.html, website/features.html,
+	website/index.html.en, website/index.html.fr,
+	website/pics/index.html, website/pics/recoll-
+	HTML_search_results.html, website/pics/recoll0.html,
+	website/pics/recoll0.txt, website/pics/recoll1.html,
+	website/pics/recoll2.html, website/pics/recoll3.html,
+	website/pics/recoll4.html, website/pics/recoll5.html,
+	website/pics/recoll_chinese.html:
+	website
+
+2009-01-26 13:29 +0000  dockes    (61198659243f)
+
+	* src/utils/smallut.cpp, src/utils/smallut.h:
+	add overloaded neutchars with different parameters
+
+2009-01-26 13:27 +0000  dockes    (61567bc09eab)
+
+	* src/utils/transcode.cpp:
+	tested and decided against cacheing iconv_open
+
+2009-01-23 15:56 +0000  dockes    (1998b1608eb0)
+
+	* src/ChangeLog, src/qtgui/advsearch_w.cpp, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/qtgui/recoll.h:
+	temp ckpt: need to test on real unix
+
+2009-01-23 11:07 +0000  dockes    (3631372e04f1)
+
+	* src/qtgui/uiprefs.ui:
+	avoid name duplication
+
+2009-01-23 11:03 +0000  dockes    (0dba2718e1aa)
+
+	* src/qtgui/uiprefs.ui:
+	one button for choosing native editors
+
+2009-01-23 10:38 +0000  dockes    (167a153bcf3c)
+
+	* src/kde/kioslave/recoll/data/searchable.html:
+	simplified javascrip: no ie here!
+
+2009-01-23 09:41 +0000  dockes    (b71166d61782)
+
+	* src/qtgui/rclmain_w.cpp:
+	toLocal8Bit->local8bit
+
+2009-01-23 09:30 +0000  dockes    (c3565b4a7244)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/qtgui/recoll.h, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp, src/qtgui/uiprefs_w.h:
+	use normal text/html ext app for viewing help
+
+2009-01-23 09:27 +0000  dockes    (c025fa3fe99d)
+
+	* src/utils/execmd.cpp, src/utils/execmd.h:
+	accept additional path argument to execmd::which
+
+2009-01-22 14:25 +0000  dockes    (967d5e013a33)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	allow toggle show text/fields in preview
+
+2009-01-21 16:42 +0000  dockes    (f950b7d75e66)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h,
+	src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	added saveToFile menu entry to reslist
+
+2009-01-21 13:55 +0000  dockes    (033fe406a666)
+
+	* src/utils/pxattr.cpp, src/utils/pxattr.h: new file.
+	* src/common/autoconfig.h.in, src/common/rclconfig.cpp,
+	src/common/rclconfig.h, src/configure, src/configure.ac,
+	src/internfile/internfile.cpp, src/internfile/mh_exec.h,
+	src/internfile/mh_html.cpp, src/internfile/mh_mail.cpp,
+	src/internfile/mh_mbox.cpp, src/internfile/mh_text.cpp,
+	src/internfile/mh_unknown.h, src/internfile/mimehandler.cpp,
+	src/internfile/mimehandler.h, src/lib/Makefile, src/lib/mkMake,
+	src/sampleconf/fields, src/utils/pxattr.cpp, src/utils/pxattr.h:
+	added optional extended file attributes support
+
+2009-01-21 11:11 +0000  dockes    (f269f00857ec)
+
+	* src/sampleconf/mimeconf:
+	comments
+
+2009-01-21 11:11 +0000  dockes    (fda5a0a6fccb)
+
+	* src/filters/rcldoc:
+	try to use wvWare if present and antiword fails
+
+2009-01-21 10:49 +0000  dockes    (394e160f7032)
+
+	* src/utils/readfile.cpp:
+	initialize the error buffer for gnu strerror_r
+
+2009-01-21 10:24 +0000  dockes    (7580c4ed79ce)
+
+	* src/utils/readfile.cpp:
+	fix errno printing
+
+2009-01-21 10:17 +0000  dockes    (f1dca213efee)
+
+	* src/rcldb/rcldb.cpp:
+	fixed typo that would prevent stopfile use
+
+2009-01-17 14:57 +0000  dockes    (90f03bbd715c)
+
+	* src/doc/man/recoll.conf.5, src/doc/user/usermanual.sgml:
+	added compressedfilemaxkbs
+
+2009-01-17 14:56 +0000  dockes    (78d1dd932d5b)
+
+	* src/internfile/internfile.cpp, src/qtgui/confgui/confguiindex.cpp,
+	src/sampleconf/recoll.conf.in:
+	added compressedfilemaxkbs
+
+2009-01-16 17:40 +0000  dockes    (fcc2539b18b4)
+
+	* src/kde/kioslave/recoll/data/searchable.html:
+	
+
+2009-01-16 16:42 +0000  dockes    (11cc037db8a9)
+
+	* src/kde/kioslave/recoll/00README.txt:
+	
+
+2009-01-16 11:32 +0000  dockes    (baaf38fdbca9)
+
+	* src/kde/kioslave/recoll/00README.txt,
+	src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/notes.txt:
+	fixed docs + removed dead code
+
+2009-01-15 17:07 +0000  dockes    (144b35bd64c0)
+
+	* src/filters/rcluncomp, src/internfile/internfile.cpp:
+	fixed handling of decompression errors, which was wrong but not
+	catastrophly so in most cases
+
+2009-01-15 17:05 +0000  dockes    (4b10b961d158)
+
+	* src/qtgui/reslist.cpp:
+	disable printing to tmp file
+
+2009-01-15 14:37 +0000  dockes    (9392e278bb0a)
+
+	* src/query/docseq.h, src/query/filtseq.cpp, src/query/filtseq.h,
+	src/query/sortseq.cpp, src/query/sortseq.h:
+	refactor operations delegated to subsequence by sortseq and filtspec
+	into superclass
+
+2009-01-15 09:47 +0000  dockes    (f02a34f835b4)
+
+	* src/rcldb/rcldb.cpp:
+	removed unused variable
+
+2009-01-15 09:45 +0000  dockes    (2440f3259cd0)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/reslist.cpp,
+	src/qtgui/uiprefs_w.cpp:
+	ensure reslist parformat is refreshed after edit (1.11 bug)
+
+2009-01-14 07:52 +0000  dockes    (b3c89a56c9a1)
+
+	* src/qtgui/advsearch.ui, src/qtgui/rclmain_w.cpp,
+	src/qtgui/uiprefs_w.cpp, src/qtgui/uiprefs_w.h,
+	src/qtgui/viewaction.ui, src/qtgui/viewaction_w.cpp,
+	src/qtgui/viewaction_w.h:
+	arrange so that the select action dialog is preselected on the right
+	mime type after missing action
+
+2009-01-13 16:03 +0000  dockes    (2d8517785a8e)
+
+	* src/common/textsplit.cpp:
+	add _ to wordsep/spanglue chars. Add non-ascii test to isCJK for
+	optimization
+
+2009-01-13 16:02 +0000  dockes    (cbfb1f939c9d)
+
+	* src/common/uproplist.h:
+	small fix : remove diaeresis from seps + comments
+
+2009-01-13 08:56 +0000  dockes    (ee8989c89330)
+
+	* src/doc/user/usermanual.sgml:
+	
+
+2009-01-13 08:49 +0000  dockes    (93e74953ed0b)
+
+	* src/doc/user/usermanual.sgml:
+	update version
+
+2009-01-13 08:02 +0000  dockes    (051bf6d49898)
+
+	* src/rcldb/rcldb.h, src/rcldb/rcldb_p.h, src/rcldb/rclquery.h:
+	minor visibility cleanup
+
+2009-01-13 08:01 +0000  dockes    (c550fb351f5f)
+
+	* src/qtgui/ssearchb.ui:
+	fix obsolete tooltip message
+
+2009-01-12 18:31 +0000  dockes    (3cefac6eb52d)
+
+	* src/doc/user/usermanual.sgml:
+	doc: better adv search explanation + duplicates collapsing
+
+2009-01-12 17:50 +0000  dockes    (f8cb21911962)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h:
+	simplified dialog structure, apparently allowed to get rid of size
+	hacks
+
+2009-01-12 16:42 +0000  dockes    (48ca278dcd42)
+
+	* src/qtgui/advsearch.ui:
+	suppressed unused vbox
+
+2009-01-12 15:55 +0000  dockes    (b5486bd5b85d)
+
+	* src/qtgui/advsearch.ui, src/qtgui/searchclause_w.cpp,
+	src/qtgui/searchclause_w.h:
+	suppressed unused layout in searchClause
+
+2009-01-09 14:56 +0000  dockes    (073523a33ffe)
+
+	* src/internfile/mh_exec.cpp, src/internfile/mh_html.cpp,
+	src/internfile/mh_mail.cpp, src/internfile/mh_text.cpp,
+	src/qtgui/guiutils.cpp, src/qtgui/guiutils.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h,
+	src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h, src/rcldb/rclquery.cpp,
+	src/rcldb/rclquery.h:
+	compute md5 checksums for all docs and optionally collapse
+	duplicates in results
+
+2009-01-09 12:23 +0000  dockes    (f89119e58f79)
+
+	* src/qtgui/reslist.cpp:
+	add space/backspace as pager keys for reslist
+
+2009-01-09 12:23 +0000  dockes    (36eb326513d5)
+
+	* src/utils/Makefile, src/utils/md5.cpp, src/utils/md5.h,
+	src/utils/readfile.cpp, src/utils/readfile.h:
+	implement md5 convenience file and string wrappers. Modify readfile
+	to support this
+
+2009-01-09 07:27 +0000  dockes    (de3507d26de4)
+
+	* src/rcldb/pathhash.cpp, src/rcldb/pathhash.h: deleted file.
+	* src/lib/Makefile, src/lib/mkMake, src/rcldb/pathhash.cpp,
+	src/rcldb/pathhash.h, src/rcldb/rcldb.cpp:
+	got rid of pathhash in rcldb, not used since 11.0
+
+2009-01-08 09:55 +0000  dockes    (1fc0cdb06859)
+
+	* src/excludefile:
+	adapt to svn
+
+2009-01-08 09:50 +0000  dockes    (867f1a9f6b02)
+
+	* src/makesrcdist.sh:
+	adapt distrib script to svn
+
+2009-01-08 09:40 +0000  dockes    (33a7fbc42386 [RECOLL_1_12_1exp5])
+
+	* src/VERSION:
+	
+
+2009-01-06 18:48 +0000  dockes    (2e111dad7cba)
+
+	* src/doc/user/bldloop: new file.
+	* packaging/FreeBSD/recoll/Makefile,
+	packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg-
+	plist, src/doc/user/bldloop, tests/koi8r/koi8r.sh, tests/shared.sh:
+	*** empty log message ***
+
+2009-01-06 18:40 +0000  dockes    (c82fbe0ee8fc)
+
+	* packaging/debian/changelog, packaging/rpm/recoll.spec,
+	packaging/rpm/recollfedora.spec, packaging/rpm/recollmdk.spec,
+	src/ChangeLog, website/devel.html, website/download.html:
+	*** empty log message ***
+
+2009-01-06 18:40 +0000  dockes    (7ebc18a8b4d7)
+
+	* unac/builder.in, unac/unac.c, unac/unac.h:
+	new unac approach for japanese: dont decompose at all
+
+2009-01-06 17:40 +0000  dockes    (a0b7ed1f2bda)
+
+	* website/xapUpg100.html: new file.
+	* website/BUGS.html, website/BUGS.txt, website/CHANGES.html,
+	website/doc.html, website/download.html, website/index.html.en,
+	website/index.html.fr, website/xapUpg100.html:
+	*** empty log message ***
+
+2009-01-06 17:30 +0000  dockes    (636e0f9f2a77)
+
+	* website/howtos/index.html,
+	website/howtos/prevent_indexing_a_directory/index.html,
+	website/howtos/use_multiple_indexes/index.html,
+	website/pics/piclist.txt, website/pics/recoll-HTML_search_results-
+	thumb.png, website/pics/recoll-HTML_search_results.html,
+	website/pics/recoll-HTML_search_results.png, website/pics/recoll-
+	HTML_search_results.txt, website/pics/recoll0-thumb.png,
+	website/pics/recoll0.html, website/pics/recoll0.png,
+	website/pics/recoll0.txt, website/pics/recoll1-thumb.png,
+	website/pics/recoll1.html, website/pics/recoll1.png,
+	website/pics/recoll1.txt, website/pics/recoll2-thumb.png,
+	website/pics/recoll2.html, website/pics/recoll2.png,
+	website/pics/recoll2.txt, website/pics/recoll3-thumb.png,
+	website/pics/recoll3.html, website/pics/recoll3.png,
+	website/pics/recoll3.txt, website/pics/recoll4-thumb.png,
+	website/pics/recoll4.html, website/pics/recoll4.png,
+	website/pics/recoll4.txt, website/pics/recoll5-thumb.png,
+	website/pics/recoll5.html, website/pics/recoll5.png,
+	website/pics/recoll5.txt, website/pics/recoll_chinese-thumb.png,
+	website/pics/recoll_chinese.html, website/pics/recoll_chinese.png,
+	website/pics/recoll_chinese.txt: new file.
+	* website/howtos/index.html,
+	website/howtos/prevent_indexing_a_directory/index.html,
+	website/howtos/use_multiple_indexes/index.html,
+	website/pics/piclist.txt, website/pics/recoll-HTML_search_results-
+	thumb.png, website/pics/recoll-HTML_search_results.html,
+	website/pics/recoll-HTML_search_results.png, website/pics/recoll-
+	HTML_search_results.txt, website/pics/recoll0-thumb.png,
+	website/pics/recoll0.html, website/pics/recoll0.png,
+	website/pics/recoll0.txt, website/pics/recoll1-thumb.png,
+	website/pics/recoll1.html, website/pics/recoll1.png,
+	website/pics/recoll1.txt, website/pics/recoll2-thumb.png,
+	website/pics/recoll2.html, website/pics/recoll2.png,
+	website/pics/recoll2.txt, website/pics/recoll3-thumb.png,
+	website/pics/recoll3.html, website/pics/recoll3.png,
+	website/pics/recoll3.txt, website/pics/recoll4-thumb.png,
+	website/pics/recoll4.html, website/pics/recoll4.png,
+	website/pics/recoll4.txt, website/pics/recoll5-thumb.png,
+	website/pics/recoll5.html, website/pics/recoll5.png,
+	website/pics/recoll5.txt, website/pics/recoll_chinese-thumb.png,
+	website/pics/recoll_chinese.html, website/pics/recoll_chinese.png,
+	website/pics/recoll_chinese.txt:
+	*** empty log message ***
+
+2008-12-21 13:17 +0000  dockes    (74da01dd27c2)
+
+	* src/unac/unac.c, src/unac/unac.h:
+	new unac approach for japanese: dont decompose at all
+
+2008-12-21 13:05 +0000  dockes    (273dad0916bb)
+
+	* unac/unac_version.h: new file.
+	* unac/unac_version.h:
+	*** empty log message ***
+
+2008-12-19 09:55 +0000  dockes    (1a2dd90e07b4)
+
+	* src/rcldb/rcldb.h, src/rcldb/rclquery.cpp, src/rcldb/searchdata.cpp:
+	getMainConfig not actually needed and possibly harmful
+
+2008-12-19 09:44 +0000  dockes    (3a16629b24f5)
+
+	* src/rcldb/searchdata.cpp, src/unac/unac.c, src/unac/unac.h:
+	dont unaccent japanese + fix bug in unac/split ordering in
+	searchdata
+
+2008-12-19 08:39 +0000  dockes    (b895714a6500)
+
+	* src/python/recoll/setup.py:
+	pyrecoll: port to linux, update
+
+2008-12-18 14:11 +0000  dockes    (33bffc499e78)
+
+	* src/query/xadump.cpp:
+	diag: prevent char combination by inserting spaces
+
+2008-12-18 11:58 +0000  dockes    (a3863a0c1f62)
+
+	* unac/builder.in, unac/unac.c:
+	no going out of the basic plane!
+
+2008-12-18 11:12 +0000  dockes    (ac1315d2a94f)
+
+	* unac/unac.c:
+	added recoll memory allocation checks
+
+2008-12-18 11:05 +0000  dockes    (cfb4210ce7d5)
+
+	* unac/CaseFolding-5.1.0.txt, unac/UnicodeData-5.1.0.txt: new file.
+	* unac/CaseFolding-5.1.0.txt, unac/UnicodeData-5.1.0.txt:
+	*** empty log message ***
+
+2008-12-18 11:04 +0000  dockes    (cc609462a402)
+
+	* unac/builder.in, unac/configure, unac/configure.ac, unac/unac.c,
+	unac/unac.h:
+	use unicode 5.1.0 + dont unaccent katakana/hiragana. Main change in
+	unicode is that letters ae and o with stroke dont decompose anymore
+	into a+e and o+e we may actually want to restore this if it proves a
+	problem
+
+2008-12-17 16:20 +0000  dockes    (65fd4fda84d3)
+
+	* src/rcldb/rcldb.cpp:
+	fix to previous abstract fix
+
+2008-12-17 15:12 +0000  dockes    (9e9e84a23da6)
+
+	* src/qtgui/reslist.cpp:
+	use local hiliter
+
+2008-12-17 14:26 +0000  dockes    (ada853f1e3b8)
+
+	* src/common/Makefile, src/rcldb/rcldb.cpp:
+	fix abstract generation when the match term is a multiword span
+	(esp. for japanese)
+
+2008-12-17 14:26 +0000  dockes    (9705bf172f13)
+
+	* src/rcldb/searchdata.cpp:
+	comment
+
+2008-12-17 08:01 +0000  dockes    (42bc5b3b5abf)
+
+	* src/index/indexer.cpp, src/index/indexer.h,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/python/recoll/pyrecoll.cpp, src/qtgui/main.cpp,
+	src/query/recollq.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	simplified db open by getting rid of the illusion that we could have
+	several writeable dbs per config
+
+2008-12-16 17:43 +0000  dockes    (1d040e634db3 [RECOLL_1_12_1exp4])
+
+	* src/README, src/VERSION,
+	src/kde/kioslave/recoll/data/searchable.html,
+	src/kde/kioslave/recoll/data/welcome.html:
+	*** empty log message ***
+
+2008-12-16 17:30 +0000  dockes    (18f65ef55dd6)
+
+	* src/kde/kioslave/recoll/data/searchable.html:
+	*** empty log message ***
+
+2008-12-16 17:28 +0000  dockes    (e991bdd3d8c7)
+
+	* src/kde/kioslave/recoll/data/searchable.html: new file.
+	* src/kde/kioslave/recoll/data/searchable.html,
+	src/kde/kioslave/recoll/data/welcome.html,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h:
+	updated kioslave for small changes in reslistpager after main i/f
+	integration. + javascript to search page
+
+2008-12-16 14:20 +0000  dockes    (7bc14752b5f3)
+
+	* src/qtgui/preview_w.h, src/qtgui/reslist.cpp, src/qtgui/reslist.h,
+	src/query/plaintorich.h, src/query/reslistpager.cpp,
+	src/query/reslistpager.h, src/utils/debuglog.cpp,
+	src/utils/debuglog.h:
+	converted qt reslist to reslistpager
+
+2008-12-16 08:54 +0000  dockes    (c702627139c8)
+
+	* src/query/wasastringtoquery.cpp:
+	OR chain longer than 2 would swallow preceding AND terms
+
+2008-12-15 15:04 +0000  dockes    (62e1b7eaa7b9)
+
+	* src/kde/kioslave/recoll/htmlif.cpp, src/query/reslistpager.cpp:
+	kio: use right ipath for preview
+
+2008-12-15 14:39 +0000  dockes    (30b71a18e961)
+
+	* src/query/xadump.cpp, src/rcldb/searchdata.cpp:
+	make gcc happy
+
+2008-12-15 13:51 +0000  dockes    (f93dda12024f)
+
+	* website/howtos/template.html:
+	*** empty log message ***
+
+2008-12-15 11:20 +0000  dockes    (4a74871e9823)
+
+	* website/howtos/buildindex.sh, website/howtos/fragend.html,
+	website/howtos/fraghead.html, website/howtos/newdir.sh,
+	website/howtos/template.html: new file.
+	* website/BUGS.html, website/BUGS.txt, website/CHANGES.html,
+	website/copydocs, website/download.html,
+	website/howtos/buildindex.sh, website/howtos/fragend.html,
+	website/howtos/fraghead.html, website/howtos/newdir.sh,
+	website/howtos/template.html, website/index.html.en,
+	website/index.html.fr, website/pics/index.html:
+	*** empty log message ***
+
+2008-12-15 09:33 +0000  dockes    (afc0ef4911b2)
+
+	* src/doc/user/usermanual.sgml:
+	more search tips
+
+2008-12-15 09:24 +0000  dockes    (59cd1bdd4d3f)
+
+	* src/rcldb/searchdata.cpp:
+	reorganize code + add boost to phrase element to match boost of
+	original user terms
+
+2008-12-12 11:53 +0000  dockes    (4121cbc09d70)
+
+	* src/common/textsplit.cpp, src/common/textsplit.h,
+	src/rcldb/rcldb.cpp:
+	dont insert space in cjk abstracts
+
+2008-12-12 11:02 +0000  dockes    (37fd1c31af49)
+
+	* src/rcldb/rcldb.cpp:
+	message level
+
+2008-12-12 11:01 +0000  dockes    (d2a8c016d05c)
+
+	* src/qtgui/reslist.cpp:
+	add %i for displaying ipath
+
+2008-12-12 11:00 +0000  dockes    (151d6a590152)
+
+	* src/qtgui/main.cpp:
+	add all extra cmd line args to the question
+
+2008-12-08 17:43 +0000  dockes    (90b62656b326)
+
+	* src/kde/kioslave/recoll/htmlif.cpp:
+	set name as preview title
+
+2008-12-08 17:42 +0000  dockes    (5717c313d23a)
+
+	* src/kde/kioslave/recoll/dirif.cpp:
+	removed a few traces
+
+2008-12-08 14:34 +0000  dockes    (de392f657f81)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt:
+	previews
+
+2008-12-08 11:22 +0000  dockes    (877b674c328c)
+
+	* src/utils/Makefile, src/utils/readfile.cpp:
+	file_to_string: stat+reserve makes faster
+
+2008-12-05 13:15 +0000  dockes    (19ef9198e3d5)
+
+	* src/VERSION:
+	branched maintenance for 1.11 kio devs on main now 1.12
+
+2008-12-05 11:09 +0000  dockes    (b27d4070bbf8)
+
+	* src/common/textsplit.cpp, src/common/textsplit.h,
+	src/common/uproplist.h, src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/qtgui/ssearch_w.cpp, src/query/recollq.cpp,
+	src/query/wasatorcl.cpp, src/rcldb/searchdata.cpp:
+	take care of splitting user string with respect to unicode white
+	space, not only ascii
+
+2008-12-05 07:38 +0000  dockes    (d102970d3aee)
+
+	* src/utils/smallut.h:
+	comment
+
+2008-12-04 12:41 +0000  dockes    (a3f25963b2da [RECOLL_1_11_1exp3])
+
+	* src/kde/kioslave/recoll/recollf.protocol: new file.
+	* src/kde/kioslave/recoll/recollf.protocol:
+	*** empty log message ***
+
+2008-12-04 12:23 +0000  dockes    (adffbb42e449)
+
+	* src/kde/kioslave/recoll/dirif.cpp:
+	kde 4.0 compile
+
+2008-12-04 11:50 +0000  dockes    (fef6cc6c4c97)
+
+	* src/VERSION:
+	*** empty log message ***
+
+2008-12-04 11:49 +0000  dockes    (d1b1a426ddfa)
+
+	* src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt, src/query/reslistpager.cpp,
+	src/query/reslistpager.h, src/rcldb/rcldb.cpp, src/utils/pathut.h:
+	kio_recoll: html/dir switching
+
+2008-12-03 17:04 +0000  dockes    (a762165399a2)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt:
+	cleaned up virtual tree and url handling. Drag to desktop now works
+	with appropriate name. recollf protocol
+
+2008-12-03 10:02 +0000  dockes    (127dbb400363)
+
+	* src/kde/kioslave/recoll/dirif.cpp:
+	better stat
+
+2008-12-02 13:41 +0000  dockes    (6e55b23fb64f)
+
+	* src/kde/kioslave/recoll/dirif.cpp:
+	*** empty log message ***
+
+2008-12-02 13:38 +0000  dockes    (66b031be3559)
+
+	* src/kde/kioslave/recoll/dirif.cpp:
+	*** empty log message ***
+
+2008-12-02 13:16 +0000  dockes    (619e41b1537b)
+
+	* src/INSTALL, src/README, src/VERSION, src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-12-02 13:14 +0000  dockes    (fff18d4ea953)
+
+	* src/kde/kioslave/recoll/00README.txt,
+	src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/data/welcome.html,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/notes.txt, src/query/reslistpager.cpp:
+	kio goes to testing
+
+2008-12-01 18:42 +0000  dockes    (714fdf15621e)
+
+	* src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h:
+	small cleanups and comments. Still some weirdness
+
+2008-12-01 15:37 +0000  dockes    (8d9ea1f1c645)
+
+	* src/kde/kioslave/recoll/cleancmakestuff.sh:
+	*** empty log message ***
+
+2008-12-01 15:36 +0000  dockes    (8504e2e278dd)
+
+	* src/kde/kioslave/recoll/data/help.html: new file.
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/cleancmakestuff.sh,
+	src/kde/kioslave/recoll/data/help.html,
+	src/kde/kioslave/recoll/data/welcome.html,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt:
+	seems to work by re-rerunning search whenever it changes. Still had
+	one crash, needs cleanup
+
+2008-11-28 09:14 +0000  dockes    (ee6a7d32843e)
+
+	* src/kde/kioslave/recoll/recollnolist.protocol: new file.
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt,
+	src/kde/kioslave/recoll/recoll.protocol,
+	src/kde/kioslave/recoll/recollnolist.protocol:
+	ensured compatibility with kde4.0
+
+2008-11-27 17:48 +0000  dockes    (d461029ef29c)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt,
+	src/kde/kioslave/recoll/recoll.protocol:
+	bits of dual mode working
+
+2008-11-27 14:05 +0000  dockes    (8cc177e8775a)
+
+	* src/query/reslistpager.cpp:
+	safety check
+
+2008-11-27 13:35 +0000  dockes    (4d28c4942bc1)
+
+	* src/sampleconf/mimeconf:
+	*** empty log message ***
+
+2008-11-27 09:49 +0000  dockes    (394d882caa0c)
+
+	* src/sampleconf/mimeconf:
+	remove obsolete [prefixes] section
+
+2008-11-27 09:39 +0000  dockes    (0ec8260d8d7c)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-11-26 15:03 +0000  dockes    (b6a62dc24003)
+
+	* src/kde/kioslave/recoll/cleancmakestuff.sh,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/notes.txt: new file.
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/cleancmakestuff.sh,
+	src/kde/kioslave/recoll/dirif.cpp,
+	src/kde/kioslave/recoll/htmlif.cpp,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h,
+	src/kde/kioslave/recoll/notes.txt,
+	src/kde/kioslave/recoll/recoll.protocol:
+	listdir doesnt work on kde 4.0 because on parent/child assumptions
+	in kdirmodel have to check on kde 4.1
+
+2008-11-24 17:42 +0000  dockes    (9333f13ac4c7)
+
+	* src/VERSION:
+	*** empty log message ***
+
+2008-11-24 17:38 +0000  dockes    (a761936ec65e)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt:
+	check for dlopen
+
+2008-11-24 16:42 +0000  dockes    (0f7e0292212f)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt:
+	have to cc the pic objects, cant use librcl
+
+2008-11-24 15:47 +0000  dockes    (d06dd2891012)
+
+	* src/Makefile.in, src/aspell/Makefile, src/common/Makefile,
+	src/common/autoconfig.h.in, src/common/rclconfig.h, src/configure,
+	src/configure.ac, src/index/Makefile, src/internfile/Makefile,
+	src/lib/Makefile, src/lib/mkMake, src/mk/Darwin, src/mk/FreeBSD,
+	src/mk/OpenBSD, src/mk/SunOS, src/mk/commondefs,
+	src/qt4gui/recoll.pro.in, src/qtgui/recoll.pro.in,
+	src/query/Makefile, src/unac/unac.c, src/utils/pathut.cpp:
+	make it easier to maintain the kio cmake by moving as much stuff as
+	possible to autoconfig.h, merging libmime and librcl etc.
+
+2008-11-24 15:23 +0000  dockes    (7d9add059cc1)
+
+	* src/qtgui/confgui/main.cpp, src/qtgui/guiutils.cpp,
+	src/qtgui/main.cpp, src/qtgui/recoll.h:
+	replace local variable recoll_datadir with access to config
+
+2008-11-24 14:54 +0000  dockes    (7005bf515a0b)
+
+	* src/unac/unac_version.h: new file.
+	* src/unac/unac.c, src/unac/unac_version.h:
+	*** empty log message ***
+
+2008-11-21 16:43 +0000  dockes    (5c4559fa9d49)
+
+	* src/makesrcdist.sh:
+	*** empty log message ***
+
+2008-11-21 16:37 +0000  dockes    (e92347cad84d)
+
+	* src/kde/kioslave/recoll/00README.txt, src/makesrcdist.sh:
+	ccmake cleanup in kio_recoll
+
+2008-11-21 16:02 +0000  dockes    (f691d6ad3333)
+
+	* src/excludefile:
+	*** empty log message ***
+
+2008-11-20 18:00 +0000  dockes    (5063f4280d8d)
+
+	* src/kde/kioslave/recoll/Makefile: deleted file.
+	* src/kde/kioslave/recoll/Makefile:
+	*** empty log message ***
+
+2008-11-20 15:10 +0000  dockes    (dc45badd0c45)
+
+	* src/VERSION:
+	*** empty log message ***
+
+2008-11-20 14:16 +0000  dockes    (c653773059df)
+
+	* src/kde/kioslave/recoll/00README.txt:
+	*** empty log message ***
+
+2008-11-20 13:10 +0000  dockes    (8b5eea7103b5)
+
+	* src/kde/kioslave/recoll/data/welcome.html: new file.
+	* src/kde/kioslave/recoll/00README.txt,
+	src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/data/welcome.html,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h, src/query/reslistpager.cpp,
+	src/query/reslistpager.h:
+	kioslave sort of works
+
+2008-11-19 12:28 +0000  dockes    (93e6b483f5c4)
+
+	* src/kde/kioslave/recoll/kio_recoll.cpp:
+	*** empty log message ***
+
+2008-11-19 12:19 +0000  dockes    (9b0d90b61574)
+
+	* src/query/plaintorich.cpp, src/query/plaintorich.h,
+	src/query/reslistpager.cpp, src/query/reslistpager.h: new file.
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h: deleted file.
+	* src/lib/Makefile, src/lib/mkMake, src/qt4gui/recoll.pro.in,
+	src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/recoll.pro.in, src/query/plaintorich.cpp,
+	src/query/plaintorich.h, src/query/reslistpager.cpp,
+	src/query/reslistpager.h:
+	moved plaintorich from qtgui/ to query/
+
+2008-11-19 10:06 +0000  dockes    (350dd565c80d)
+
+	* src/qtgui/reslist.cpp, src/utils/smallut.cpp, src/utils/smallut.h:
+	moved code from qtgui to smallut
+
+2008-11-18 13:51 +0000  dockes    (fae04b17c778)
+
+	* src/utils/cancelcheck.h:
+	comment
+
+2008-11-18 13:25 +0000  dockes    (4d54c32dbee7)
+
+	* src/index/csguess.cpp, src/index/mimetype.cpp,
+	src/index/rclmonprc.cpp, src/index/rclmonrcv.cpp,
+	src/query/wasatorcl.cpp:
+	add a few includes for new gcc version
+
+2008-11-18 13:24 +0000  dockes    (9455c0affe0a)
+
+	* src/utils/cancelcheck.h:
+	comments
+
+2008-11-18 10:23 +0000  dockes    (d09d14bf2e24)
+
+	* src/utils/debuglog.h:
+	*** empty log message ***
+
+2008-11-17 14:51 +0000  dockes    (9d4e9515342e)
+
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/Makefile.kde3: new file.
+	* src/kde/kioslave/recoll/CMakeLists.txt,
+	src/kde/kioslave/recoll/Makefile,
+	src/kde/kioslave/recoll/Makefile.kde3,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h:
+	1st kde test. cmake doesnt work need to use buildit script
+
+2008-11-14 15:49 +0000  dockes    (13ca00d869a1)
+
+	* src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.h:
+	*** empty log message ***
+
+2008-11-13 10:57 +0000  dockes    (5cd3ce5481df)
+
+	* src/kde/kioslave/recoll/00README.txt,
+	src/kde/kioslave/recoll/Makefile,
+	src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/kde/kioslave/recoll/kio_recoll.la, src/query/docseqdb.cpp:
+	got the kio_slave working again
+
+2008-11-08 11:00 +0000  dockes    (81b9fe1d7644)
+
+	* src/qtgui/reslist.cpp:
+	Copy entries in the rght clck menu copy both to selection and
+	clipboard
+
+2008-10-18 07:04 +0000  dockes    (33b4eec42ac8)
+
+	* website/BUGS.html: new file.
+	* website/BUGS.html, website/download.html:
+	*** empty log message ***
+
+2008-10-18 06:51 +0000  dockes    (b885092a2488)
+
+	* website/CHANGES.html: new file.
+	* website/CHANGES.txt: deleted file.
+	* website/BUGS.txt, website/CHANGES.html, website/CHANGES.txt,
+	website/download.html, website/index.html.en, website/index.html.fr:
+	*** empty log message ***
+
+2008-10-15 08:30 +0000  dockes    (6657f5e0f698)
+
+	* src/sampleconf/recoll.conf.in:
+	add .git .hg .bzr to skipped
+
+2008-10-14 07:50 +0000  dockes    (2321044edfb9 [RECOLL_1_11_0])
+
+	* src/rcldb/searchdata.cpp, src/rcldb/searchdata.h,
+	src/utils/refcntr.h:
+	highlighting would not work with cat filt active because ClausSub
+	did not implement getTerms
+
+2008-10-14 06:07 +0000  dockes    (6ecc84bb82aa)
+
+	* src/index/recollindex.cpp:
+	print version in recollindex help
+
+2008-10-13 11:46 +0000  dockes    (1cd1451bbb74)
+
+	* src/excludefile, src/makesrcdist.sh:
+	change in excludefile handling
+
+2008-10-13 11:46 +0000  dockes    (609bbaa80120)
+
+	* src/qtgui/ssearch_w.cpp, src/query/filtseq.cpp:
+	warnings
+
+2008-10-13 11:44 +0000  dockes    (809f8c3eb265)
+
+	* src/qtgui/plaintorich.cpp:
+	compil warn
+
+2008-10-13 08:35 +0000  dockes    (a5d743b90fe8)
+
+	* src/INSTALL, src/README:
+	*** empty log message ***
+
+2008-10-13 08:23 +0000  dockes    (5874f0e6fc82)
+
+	* src/query/recollq.cpp:
+	dont change recollq output, used for tests!
+
+2008-10-13 07:57 +0000  dockes    (bf5637bbe652)
+
+	* src/doc/user/usermanual.sgml, src/qtgui/i18n/recoll_de.ts,
+	src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_tr.ts,
+	src/qtgui/i18n/recoll_uk.ts, src/qtgui/i18n/recoll_xx.ts,
+	src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp:
+	messages and manual
+
+2008-10-10 08:19 +0000  dockes    (d5a5fb9959b7)
+
+	* src/doc/user/usermanual.sgml:
+	added python api doc
+
+2008-10-10 08:18 +0000  dockes    (4771280faa9c)
+
+	* src/python/recoll/pyrecoll.cpp, src/python/samples/rclmbox.py,
+	src/python/samples/recollqsd.py:
+	fix executesd
+
+2008-10-10 08:05 +0000  dockes    (f613511f9e1a)
+
+	* src/python/recoll/pyrecoll.cpp:
+	add delete purge
+
+2008-10-10 08:04 +0000  dockes    (2547574a0242)
+
+	* src/internfile/internfile.cpp:
+	log levels
+
+2008-10-09 09:36 +0000  dockes    (4fb973a50769)
+
+	* src/python/recoll/pyrecoll.cpp:
+	stemming went from query to searchdata
+
+2008-10-09 09:21 +0000  dockes    (e112c834fca2)
+
+	* src/filters/rclflac, src/filters/rclid3, src/sampleconf/mimeconf:
+	improved mp3/flac filter. use pstotext directly
+
+2008-10-09 09:19 +0000  dockes    (cf2e0559c3d9)
+
+	* src/internfile/mh_exec.cpp, src/internfile/mimehandler.cpp:
+	need to transcode text to utf-8
+
+2008-10-09 09:19 +0000  dockes    (d250c2a0a26f)
+
+	* src/utils/transcode.h:
+	comments
+
+2008-10-09 06:41 +0000  dockes    (721f4b3d08f4)
+
+	* src/filters/rclimg:
+	*** empty log message ***
+
+2008-10-09 06:38 +0000  dockes    (e9d7fde008f9)
+
+	* src/filters/rclimg:
+	*** empty log message ***
+
+2008-10-09 06:31 +0000  dockes    (4b76370655c3)
+
+	* src/filters/rclimg:
+	conform to filter error usual protocol
+
+2008-10-08 16:15 +0000  dockes    (d60a26ce4397)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/filters/rcldvi, src/index/indexer.cpp, src/index/indexer.h,
+	src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h, src/utils/smallut.cpp, src/utils/smallut.h:
+	added menu to display missing helpers
+
+2008-10-08 16:12 +0000  dockes    (30da9114943c)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-10-08 08:27 +0000  dockes    (8a78ee8cc158)
+
+	* src/filters/rclabw, src/filters/rcldjvu, src/filters/rclid3,
+	src/filters/rclkwd, src/filters/rclogg, src/filters/rclopxml,
+	src/filters/rclppt, src/filters/rclsoff, src/filters/rclsvg,
+	src/filters/rclxls, src/sampleconf/fields, src/sampleconf/mimeconf:
+	improved rclid3 and rclogg
+
+2008-10-07 16:19 +0000  dockes    (c922f7984106)
+
+	* src/qtgui/preview_w.cpp:
+	message
+
+2008-10-07 08:07 +0000  dockes    (7e7e59b8a48f)
+
+	* src/doc/user/usermanual.sgml:
+	query language precisions
+
+2008-10-07 06:52 +0000  dockes    (0b46df2d0a1d)
+
+	* src/query/wasatorcl.cpp:
+	*** empty log message ***
+
+2008-10-07 06:44 +0000  dockes    (a6e8f2583e65)
+
+	* src/ChangeLog, src/common/rclconfig.cpp,
+	src/python/recoll/pyrecoll.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/rclquery.cpp, src/sampleconf/fields:
+	let rclconfig take care of field name lowercasing
+
+2008-10-06 06:22 +0000  dockes    (26eae5316b88)
+
+	* src/internfile/mh_exec.cpp, src/internfile/mh_exec.h,
+	src/internfile/mimehandler.cpp, src/utils/execmd.cpp:
+	Disable filters with missing helpers for the whole indexing pass
+
+2008-10-04 14:26 +0000  dockes    (556c7fa5998c)
+
+	* src/index/indexer.cpp, src/internfile/Filter.h,
+	src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/internfile/mh_exec.cpp, src/internfile/mh_exec.h,
+	src/internfile/mh_html.h, src/internfile/mh_mail.cpp,
+	src/internfile/mh_mail.h, src/internfile/mh_mbox.cpp,
+	src/internfile/mh_mbox.h, src/internfile/mh_text.h,
+	src/internfile/mh_unknown.h, src/internfile/mimehandler.cpp,
+	src/internfile/mimehandler.h:
+	allow specifying format and charset for ext filters. Cache and reuse
+	filters
+
+2008-10-03 16:02 +0000  dockes    (6f5d875c2923)
+
+	* src/utils/Makefile:
+	*** empty log message ***
+
+2008-10-03 16:02 +0000  dockes    (8d1e930cc9e2)
+
+	* src/qtgui/preview_w.cpp:
+	message
+
+2008-10-03 08:19 +0000  dockes    (cf75be4a88cf)
+
+	* src/common/rclconfig.cpp:
+	*** empty log message ***
+
+2008-10-03 08:09 +0000  dockes    (068bc565bf8b)
+
+	* src/common/rclconfig.cpp, src/qtgui/guiutils.cpp,
+	src/qtgui/guiutils.h, src/qtgui/plaintorich.cpp,
+	src/qtgui/plaintorich.h, src/qtgui/preview_w.cpp,
+	src/qtgui/preview_w.h, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp:
+	add option to preview html instead of plain text
+
+2008-10-03 06:23 +0000  dockes    (bd1a6a560e25)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h:
+	arrange for setting aside an html version when working for preview
+
+2008-10-03 06:17 +0000  dockes    (b10d8b6906a0)
+
+	* src/internfile/mh_html.cpp, src/internfile/mh_html.h:
+	save transcoded html for preview
+
+2008-10-02 13:30 +0000  dockes    (f469cf040425)
+
+	* src/internfile/mh_exec.cpp, src/internfile/mh_exec.h:
+	comments
+
+2008-09-30 12:38 +0000  dockes    (6ff81f690928)
+
+	* src/index/recollindex.cpp, src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/idxthread.cpp, src/qtgui/idxthread.h, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb_p.h:
+	added index format version checking
+
+2008-09-29 11:33 +0000  dockes    (2691a6abf645)
+
+	* src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/python/recoll/pyrecoll.cpp, src/qtgui/rclmain_w.cpp,
+	src/qtgui/reslist.cpp, src/query/docseq.h, src/query/docseqdb.cpp,
+	src/query/docseqdb.h, src/query/filtseq.cpp, src/query/filtseq.h,
+	src/query/recollq.cpp, src/query/sortseq.cpp, src/query/sortseq.h,
+	src/rcldb/rclquery.cpp, src/rcldb/rclquery.h,
+	src/rcldb/searchdata.cpp, src/rcldb/searchdata.h:
+	move stemlang from RclQuery to SearchData. Allow DocSequences to do
+	the sorting/filtering themselves
+
+2008-09-29 08:59 +0000  dockes    (00bc43d91e91)
+
+	* src/kde/kioslave/recoll/kio_recoll.cpp,
+	src/python/recoll/pyrecoll.cpp, src/qtgui/reslist.cpp,
+	src/query/docseq.cpp, src/query/docseq.h, src/query/docseqdb.cpp,
+	src/query/docseqdb.h, src/query/docseqhist.cpp,
+	src/query/docseqhist.h, src/query/filtseq.cpp, src/query/filtseq.h,
+	src/query/recollq.cpp, src/query/sortseq.cpp, src/query/sortseq.h,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/rclquery.cpp,
+	src/rcldb/rclquery.h:
+	doc.pc now only place where relevancy is stored
+
+2008-09-29 07:13 +0000  dockes    (da809a196cc5)
+
+	* src/qtgui/reslist.h:
+	comments
+
+2008-09-29 06:58 +0000  dockes    (dccf6cb38207)
+
+	* src/python/recoll/pyrecoll.cpp, src/query/recollq.cpp,
+	src/rcldb/rclquery.cpp, src/rcldb/rclquery.h,
+	src/rcldb/searchdata.cpp, src/rcldb/searchdata.h:
+	move sort params from searchdata to rclquery
+
+2008-09-28 14:20 +0000  dockes    (0ce1cca8cac2)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/rclmain.ui,
+	src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h,
+	src/qtgui/reslist.cpp, src/qtgui/reslist.h, src/qtgui/sort_w.cpp,
+	src/query/filtseq.h, src/query/sortseq.cpp, src/query/sortseq.h,
+	src/sampleconf/mimeconf:
+	1st impl of catg filtering in reslist
+
+2008-09-28 07:40 +0000  dockes    (5e29feefc554)
+
+	* src/query/filtseq.cpp, src/query/filtseq.h: new file.
+	* src/lib/Makefile, src/lib/mkMake, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h, src/qtgui/reslist.cpp, src/qtgui/reslist.h,
+	src/query/docseq.h, src/query/docseqdb.cpp, src/query/docseqdb.h,
+	src/query/filtseq.cpp, src/query/filtseq.h:
+	rearranged some reslist/rclmain functions + add but not use filtseq
+	code
+
+2008-09-25 09:08 +0000  dockes    (8588b8cc05d1)
+
+	* src/python/samples/rcldlkp.py, src/python/samples/rclmbox.py:
+	*** empty log message ***
+
+2008-09-25 09:07 +0000  dockes    (40e028763fab)
+
+	* src/python/xesam/xesam-recoll-service:
+	arret apres hackfest
+
+2008-09-25 06:17 +0000  dockes    (811009efeb96)
+
+	* src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_tr.ts,
+	src/qtgui/i18n/recoll_uk.ts, src/qtgui/i18n/recoll_xx.ts:
+	*** empty log message ***
+
+2008-09-25 06:14 +0000  dockes    (ce29702ab7cc)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts:
+	*** empty log message ***
+
+2008-09-25 06:02 +0000  dockes    (a065c833e601)
+
+	* src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts:
+	new russian/ukrainian translations
+
+2008-09-25 06:00 +0000  dockes    (ba80af83d32f)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts, src/qtgui/rclmain_w.cpp,
+	src/qtgui/reslist.cpp, src/qtgui/uiprefs.ui:
+	fixed typos
+
+2008-09-24 06:50 +0000  dockes    (695914bd6d5d)
+
+	* src/kde/recoll_applet/0README.Recoll:
+	*** empty log message ***
+
+2008-09-24 06:44 +0000  dockes    (48bbf0a115cc)
+
+	* src/query/recollq.cpp:
+	command line args must be processed as local 8 bit
+
+2008-09-24 06:34 +0000  dockes    (e90ac2ed62fe)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-09-24 05:35 +0000  dockes    (36e2522b06b2)
+
+	* src/qtgui/main.cpp:
+	command line args must be processed as local 8 bit
+
+2008-09-24 05:31 +0000  dockes    (9b420f1d25f8)
+
+	* src/qtgui/main.cpp:
+	command line args must be processed as local 8 bit
+
+2008-09-23 14:32 +0000  dockes    (cd440e5917d3)
+
+	* src/configure, src/configure.ac:
+	use $QMAKE not qmake when checking version
+
+2008-09-16 10:19 +0000  dockes    (2bc72ad13a9b)
+
+	* src/python/recoll/pyrecoll.cpp:
+	fields, indexing i/f
+
+2008-09-16 10:13 +0000  dockes    (ff10e8072c66)
+
+	* src/qtgui/rclmain_w.cpp:
+	have to setkeydir before calling internfile when opening
+
+2008-09-16 08:18 +0000  dockes    (c78945994f7c)
+
+	* src/python/samples/recollqsd.py: new file.
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/internfile/internfile.cpp, src/python/recoll/pyrecoll.cpp,
+	src/python/recoll/setup.py, src/python/samples/recollqsd.py,
+	src/python/xesam/xesam-recoll-service, src/query/recollq.cpp,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/rcldb_p.h,
+	src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h, src/rcldb/rclquery.cpp,
+	src/rcldb/rclquery.h, src/rcldb/searchdata.cpp,
+	src/rcldb/searchdata.h, src/sampleconf/fields:
+	general field name handling cleanup + sort facility in rclquery
+
+2008-09-16 08:13 +0000  dockes    (bd4c0f6fd812)
+
+	* src/internfile/mh_mail.cpp:
+	emit field for recipients
+
+2008-09-15 08:03 +0000  dockes    (11ba5592559e)
+
+	* src/sampleconf/fields, src/sampleconf/mimeconf,
+	src/sampleconf/mimemap, src/sampleconf/mimeview:
+	added rcltext/python/purple
+
+2008-09-15 08:02 +0000  dockes    (8af411ff9bf6)
+
+	* src/filters/rclpurple: new file.
+	* src/filters/rclpurple, src/qtgui/mtpics/README,
+	src/utils/base64.cpp, src/utils/smallut.cpp, src/utils/smallut.h,
+	src/utils/transcode.cpp:
+	*** empty log message ***
+
+2008-09-15 07:55 +0000  dockes    (49401228a5ef)
+
+	* src/filters/rclpython, src/qtgui/mtpics/pidgin.png,
+	src/qtgui/mtpics/text-x-python.png: new file.
+	* src/filters/rclpython, src/qtgui/mtpics/pidgin.png,
+	src/qtgui/mtpics/text-x-python.png:
+	*** empty log message ***
+
+2008-09-13 12:56 +0000  dockes    (299644545ca0)
+
+	* src/python/xesam/xesam-recoll-service: new file.
+	* src/python/xesam/xesam-recoll-service:
+	*** empty log message ***
+
+2008-09-12 11:35 +0000  dockes    (5c85f26d124d)
+
+	* src/sampleconf/mimeconf:
+	index c code with the new rcltext generic filter
+
+2008-09-12 11:30 +0000  dockes    (b8277032f494)
+
+	* src/filters/rcltext: new file.
+	* src/filters/rcltext:
+	*** empty log message ***
+
+2008-09-09 12:58 +0000  dockes    (a3afe9b35b57)
+
+	* src/rcldb/rcldb.cpp:
+	debug messages
+
+2008-09-08 16:49 +0000  dockes    (a18ab0c682a4)
+
+	* src/rcldb/rcldoc.cpp, src/sampleconf/fields: new file.
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/internfile/internfile.cpp, src/lib/Makefile, src/lib/mkMake,
+	src/python/recoll/pyrecoll.cpp, src/python/samples/recollq.py,
+	src/qtgui/preview_w.cpp, src/qtgui/reslist.cpp, src/query/docseq.h,
+	src/query/docseqdb.cpp, src/query/recollq.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/rcldoc.cpp, src/rcldb/rcldoc.h, src/recollinstall.in,
+	src/sampleconf/fields:
+	foundation work for configurable stored/indexed fields
+
+2008-09-08 15:47 +0000  dockes    (861e4211280b)
+
+	* src/rcldb/searchdata.h:
+	unused args warning
+
+2008-09-08 15:47 +0000  dockes    (3f6468e20038)
+
+	* src/utils/smallut.cpp:
+	test driver
+
+2008-09-08 15:46 +0000  dockes    (581ee503208b)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2008-09-07 07:22 +0000  dockes    (dfe4dd53d0b9)
+
+	* src/Makefile.in, src/qt4gui/uifrom3:
+	cleanup
+
+2008-09-07 07:08 +0000  dockes    (95c2a94321a3)
+
+	* src/Makefile.in:
+	cleaning
+
+2008-09-07 06:43 +0000  dockes    (6294638c2504)
+
+	* src/Makefile.in, src/VERSION, src/mk/localdefs.in:
+	improved cleaning
+
+2008-09-05 11:45 +0000  dockes    (8532ebb84453)
+
+	* src/rcldb/rclquery.cpp:
+	gcc4.3
+
+2008-09-05 10:36 +0000  dockes    (2ada099a7545)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h:
+	strimline and restructure the doctree-exploring loop to make it
+	close to understandable
+
+2008-09-05 10:34 +0000  dockes    (404aa368d498)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb_p.h, src/rcldb/rclquery.cpp:
+	add relevancyrating to the metadata when querying
+
+2008-09-05 10:33 +0000  dockes    (bc0210deda18)
+
+	* src/internfile/myhtmlparse.cpp:
+	accept iso date format (2008-09-05T11:55:32)
+
+2008-09-05 10:26 +0000  dockes    (4b17d6defb3c)
+
+	* src/doc/man/recollindex.1:
+	*** empty log message ***
+
+2008-09-01 20:39 +0000  dockes    (39ff03712b54)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimeview:
+	openxml types
+
+2008-09-01 17:31 +0000  dockes    (f0fde685acc8)
+
+	* src/filters/rclopxml:
+	sort of works
+
+2008-09-01 17:21 +0000  dockes    (dfd3281994ff)
+
+	* src/filters/rclopxml: new file.
+	* src/filters/rclopxml:
+	almost almost ok excepts outputs some formatting directives for ppt
+
+2008-08-31 15:28 +0000  dockes    (7756d792699d [RECOLL_1_11_1exp1, RECOLL_1_11_1exp2, RECOLL_1_11_1exp])
+
+	* packaging/debian/changelog, packaging/debian/control,
+	packaging/debian/rules:
+	*** empty log message ***
+
+2008-08-30 12:21 +0000  dockes    (60b122f6f4d6)
+
+	* src/rcldb/rcldb.cpp:
+	typo in xfsn len fix
+
+2008-08-30 07:38 +0000  dockes    (d516181ad7a0)
+
+	* src/rcldb/rcldb.cpp:
+	truncate simple file names at max term length
+
+2008-08-30 07:34 +0000  dockes    (59326d99e18d)
+
+	* src/utils/smallut.cpp:
+	utf8truncate
+
+2008-08-30 07:31 +0000  dockes    (8f5c5fba53d1)
+
+	* src/utils/smallut.cpp, src/utils/smallut.h:
+	utf8truncate
+
+2008-08-29 14:12 +0000  dockes    (41c405565cd4)
+
+	* tests/boolean/boolean.sh:
+	or->OR
+
+2008-08-29 13:05 +0000  dockes    (6454f838026e)
+
+	* src/internfile/mh_mbox.cpp:
+	accept weird date format in From lines used by (old?) tbird
+
+2008-08-29 09:51 +0000  dockes    (b830b6d6b04d)
+
+	* src/index/recollindex.cpp:
+	be more informative when monitoring not configured
+
+2008-08-28 15:44 +0000  dockes    (27a9bf47f895)
+
+	* src/python/recoll/pyrecoll.cpp, src/python/samples/rcldlkp.py,
+	src/python/samples/rclmbox.py, src/rcldb/rcldb.cpp,
+	src/sampleconf/mimeview:
+	*** empty log message ***
+
+2008-08-28 15:43 +0000  dockes    (d28eac37bdd9)
+
+	* src/query/wasatorcl.cpp, src/rcldb/searchdata.h:
+	use a refcntr for the sub SearchData
+
+2008-08-28 15:42 +0000  dockes    (417a8f1346df)
+
+	* src/rcldb/searchdata.cpp:
+	ensure that a negative clause is not first or only in list
+
+2008-08-27 12:34 +0000  dockes    (658ca4b955c8)
+
+	* src/python/recoll/pyrecoll.cpp:
+	reorganize+traces
+
+2008-08-27 12:12 +0000  dockes    (37791b8e66aa)
+
+	* src/python/recoll/pyrecoll.cpp:
+	doc
+
+2008-08-26 13:50 +0000  dockes    (af43f86ffe99)
+
+	* src/query/wasastringtoquery.cpp:
+	make AND and OR case-sensitive
+
+2008-08-26 13:47 +0000  dockes    (bda91f767e32)
+
+	* src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h,
+	src/query/wasatorcl.cpp:
+	try to parse the whole of Xesam user language 0.95
+
+2008-08-26 07:56 +0000  dockes    (6a17726c7e41)
+
+	* src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py,
+	src/python/samples/rcldlkp.py, src/python/samples/rclmbox.py,
+	src/python/samples/recollq.py:
+	renamed a few things
+
+2008-08-26 07:38 +0000  dockes    (c97de92889e3)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	copy author back from data record to Doc
+
+2008-08-26 07:36 +0000  dockes    (d6e27e630844)
+
+	* src/python/samples/rcldlkp.py, src/python/samples/rclmbox.py,
+	src/python/samples/recollq.py: new file.
+	* src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py,
+	src/python/samples/rcldlkp.py, src/python/samples/rclmbox.py,
+	src/python/samples/recollq.py:
+	*** empty log message ***
+
+2008-08-26 07:33 +0000  dockes    (1d6816c32358)
+
+	* src/rcldb/rcldoc.h:
+	comments
+
+2008-08-26 07:33 +0000  dockes    (4e86d4c4f3d9)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/reslist.cpp:
+	move ipath computations from reslist to internfile
+
+2008-08-26 07:31 +0000  dockes    (b44f4950a084)
+
+	* src/internfile/mh_exec.cpp, src/internfile/mh_exec.h:
+	implement skip_to_document
+
+2008-08-25 16:12 +0000  dockes    (936499917659)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	opxml formats
+
+2008-07-30 13:16 +0000  dockes    (0f1387a8a565)
+
+	* src/rcldb/stemdb.cpp:
+	fixed inocuous but nasty bad string value test
+
+2008-07-29 08:25 +0000  dockes    (a7888d48c2a6)
+
+	* src/rcldb/rcldb.h, src/rcldb/rcldoc.h:
+	comments
+
+2008-07-29 06:25 +0000  dockes    (28ebb7cac39d)
+
+	* src/index/indexer.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h,
+	src/rcldb/rcldb_p.h, src/rcldb/rcldoc.h:
+	use explicit parent udi term instead of Qterm structure to express
+	parent-child relationship
+
+2008-07-28 12:24 +0000  dockes    (5cb926be362f)
+
+	* src/index/indexer.cpp, src/lib/Makefile, src/lib/mkMake,
+	src/query/docseqhist.cpp, src/rcldb/pathhash.cpp,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/rcldoc.h,
+	src/utils/Makefile, src/utils/fileudi.cpp:
+	replaced path|ipath with unique doc id in rcldb i/f. Still depends
+	on udi structure for parent/child
+
+2008-07-28 10:20 +0000  dockes    (07bc933efb70)
+
+	* src/utils/fileudi.cpp, src/utils/fileudi.h: new file.
+	* src/utils/fileudi.cpp, src/utils/fileudi.h:
+	*** empty log message ***
+
+2008-07-28 08:42 +0000  dockes    (825cb66f8be3)
+
+	* src/index/indexer.cpp, src/qtgui/uiprefs_w.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/rcldb.h, src/rcldb/rcldb_p.h, src/rcldb/rcldoc.h,
+	src/utils/base64.h:
+	begin i/f cleanup: opacify doc uptodate sig (size+mtime)
+
+2008-07-04 09:29 +0000  dockes    (6551cb55fa98 [RECOLL_1_10_3])
+
+	* src/qtgui/plaintorich.cpp:
+	turn dbg off
+
+2008-07-01 13:00 +0000  dockes    (19e926f99256)
+
+	* src/ChangeLog, src/VERSION:
+	1.10.3: checkpoint for 1.10 branch maintenance
+
+2008-07-01 12:11 +0000  dockes    (910f409cb0be)
+
+	* src/bincimapmime/convert.h:
+	suppressed a few wasteful string-cstr conversions
+
+2008-07-01 11:57 +0000  dockes    (913963d84bc5)
+
+	* src/bincimapmime/convert.cc, src/bincimapmime/convert.h,
+	src/bincimapmime/mime-parseonlyheader.cc, src/bincimapmime/mime-
+	printheader.cc:
+	suppressed a few wasteful string-cstr conversions
+
+2008-07-01 11:51 +0000  dockes    (54f3a868fb92)
+
+	* src/bincimapmime/address.cc, src/internfile/mh_mail.cpp,
+	src/query/wasastringtoquery.cpp, src/query/xadump.cpp,
+	src/rcldb/rcldb.cpp, src/rcldb/rclquery.cpp, src/rcldb/searchdata.h,
+	src/utils/conftree.cpp, src/utils/conftree.h, src/utils/idfile.cpp,
+	src/utils/mimeparse.cpp, src/utils/pathut.cpp, src/utils/pathut.h,
+	src/utils/smallut.cpp:
+	suppressed a few wasteful string-cstr conversions
+
+2008-07-01 10:29 +0000  dockes    (3e1aa9958af4)
+
+	* src/index/mimetype.cpp, src/index/mimetype.h,
+	src/internfile/mh_mail.cpp:
+	mh_mail now uses mimetype() to try and better identify application
+	/octet-stream
+
+2008-07-01 08:31 +0000  dockes    (3665315a4fdd)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2008-07-01 08:31 +0000  dockes    (928e08cb2cc8)
+
+	* src/rcldb/rclquery.cpp, src/rcldb/rclquery.h,
+	src/rcldb/rclquery_p.h:
+	small cleanups and comments
+
+2008-07-01 08:28 +0000  dockes    (e5847d808877)
+
+	* src/rcldb/rcldb.h:
+	comments
+
+2008-07-01 08:27 +0000  dockes    (97cd50050ecf)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/preview_w.cpp, src/qtgui/preview_w.h,
+	src/qtgui/reslist.cpp:
+	cleaned up plaintorich. Now a proper subclassable class + highlights
+	multiple groups, not just the first
+
+2008-07-01 08:27 +0000  dockes    (3ef1709e5955)
+
+	* src/qtgui/confgui/confguiindex.cpp:
+	typo
+
+2008-07-01 08:26 +0000  dockes    (f6ddabbf59a2)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/utils/pathut.cpp,
+	src/utils/pathut.h:
+	moved printableUrl() to pathut
+
+2008-07-01 08:24 +0000  dockes    (413a8a75c5af)
+
+	* src/python/recoll/pyrecoll.cpp:
+	added abstract i/f
+
+2008-06-17 11:43 +0000  dockes    (009a912c3daf)
+
+	* src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py:
+	basic functionality ok, more funcs and options needed
+
+2008-06-13 18:23 +0000  dockes    (58a4b54fa103)
+
+	* src/utils/refcntr.h:
+	separated rcldb and rclquery
+
+2008-06-13 18:22 +0000  dockes    (a52ef2510839)
+
+	* src/rcldb/rcldb_p.h, src/rcldb/rclquery.cpp, src/rcldb/rclquery.h,
+	src/rcldb/rclquery_p.h: new file.
+	* src/kde/kioslave/recoll/kio_recoll.cpp, src/lib/Makefile,
+	src/lib/mkMake, src/python/recoll/pyrecoll.cpp,
+	src/python/recoll/setup.py, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/query/docseq.h, src/query/docseqdb.cpp,
+	src/query/docseqdb.h, src/query/recollq.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/rcldb.h, src/rcldb/rcldb_p.h, src/rcldb/rclquery.cpp,
+	src/rcldb/rclquery.h, src/rcldb/rclquery_p.h,
+	src/rcldb/searchdata.h, src/utils/pathut.cpp, src/utils/refcntr.h:
+	separated rcldb and rclquery
+
+2008-06-13 18:14 +0000  dockes    (e39af9faad92)
+
+	* src/common/autoconfig.h.in, src/configure, src/configure.ac,
+	src/mk/Darwin, src/mk/FreeBSD, src/mk/Linux, src/mk/OpenBSD:
+	move few things from the mk/sys files to autoconf
+
+2008-06-10 06:30 +0000  dockes    (822b88ae3d1f)
+
+	* src/qtgui/mtpics/License_sidux.txt: new file.
+	* src/qtgui/mtpics/License_sidux.txt:
+	*** empty log message ***
+
+2008-06-09 09:14 +0000  dockes    (c9953f1a54ee)
+
+	* src/filters/rclsiduxman, src/qtgui/mtpics/sidux-book.png: new file.
+	* src/filters/rclsiduxman, src/qtgui/mtpics/sidux-book.png,
+	src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	sidux manual support
+
+2008-05-27 10:46 +0000  dockes    (2afb8b8ec073)
+
+	* 1.10.2
+
+2008-05-27 10:45 +0000  dockes    (62c7f8ba0eb8)
+
+	* packaging/debian/changelog, packaging/rpm/recoll.spec,
+	packaging/rpm/recollfedora.spec, packaging/rpm/recollmdk.spec,
+	src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py,
+	website/BUGS.txt, website/CHANGES.txt, website/download.html,
+	website/features.html, website/index.html.en, website/index.html.fr,
+	website/styles/style.css:
+	1.10.2
+
+2008-05-27 06:47 +0000  dockes    (b120e7a059cd [RECOLL_1_10_2])
+
+	* src/README:
+	*** empty log message ***
+
+2008-05-27 06:46 +0000  dockes    (70d9bb153b58)
+
+	* src/VERSION:
+	1.10.2
+
+2008-05-27 06:18 +0000  dockes    (305829599fb1)
+
+	* src/utils/pathut.cpp:
+	suppress warning
+
+2008-05-27 05:40 +0000  dockes    (f611211f012a)
+
+	* src/internfile/internfile.cpp:
+	log message
+
+2008-05-26 09:07 +0000  dockes    (dbb469971d76)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2008-05-21 07:21 +0000  dockes    (b1ee79619cca)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/confgui/confgui.cpp,
+	src/qtgui/confgui/confgui.h, src/qtgui/preview_w.cpp,
+	src/qtgui/reslist.cpp, src/utils/idfile.cpp:
+	openSuse 11 compile issues
+
+2008-05-20 10:09 +0000  dockes    (f047b0f61753)
+
+	* src/qtgui/advsearch_w.cpp, src/rcldb/rcldb.cpp:
+	*** empty log message ***
+
+2008-05-20 10:09 +0000  dockes    (f2e76fada01c)
+
+	* src/unac/unac.c:
+	make strict gcc happy
+
+2008-05-09 12:34 +0000  dockes    (be08db2c226e)
+
+	* src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py: new
+	file.
+	* src/python/recoll/pyrecoll.cpp, src/python/recoll/setup.py:
+	*** empty log message ***
+
+2008-05-08 10:00 +0000  dockes    (2ff9f42dc279)
+
+	* src/rcldb/searchdata.h:
+	comments
+
+2008-05-08 09:57 +0000  dockes    (bd6106d7f9ab)
+
+	* src/utils/smallut.cpp, src/utils/smallut.h:
+	*** empty log message ***
+
+2008-05-08 09:31 +0000  dockes    (70f8eab20535)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2008-05-07 06:14 +0000  dockes    (f3d36126287d)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-05-05 20:31 +0000  dockes    (d271616c4b99)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-05-05 20:28 +0000  dockes    (02b1484f3eee)
+
+	* src/doc/user/usermanual.sgml, src/qtgui/guiutils.cpp,
+	src/qtgui/guiutils.h, src/qtgui/preview_w.cpp,
+	src/qtgui/reslist.cpp, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp:
+	allow setting query term highlight color in prefs
+
+2008-05-05 16:38 +0000  dockes    (763298305d15)
+
+	* src/qtgui/reslist.cpp:
+	Edit -> Open in links
+
+2008-05-05 13:13 +0000  dockes    (d2fc5c651024)
+
+	* src/bincimapmime/mime-parsefull.cc:
+	part data was sometimes truncated because of bad handling of
+	consecutive mime boundaries. Most common symptom: error in base64
+	decoding
+
+2008-04-18 11:41 +0000  dockes    (32155182993c)
+
+	* src/mk/localdefs.in:
+	get CXXFLAGS from autoconf
+
+2008-04-18 11:39 +0000  dockes    (72073f033a45)
+
+	* src/query/xadump.cpp:
+	xadump would sometimes dump core with -b
+
+2008-04-18 11:38 +0000  dockes    (ef6566c2ac8e)
+
+	* src/qtgui/preview_w.cpp:
+	walking the search terms hits backwards would go forward
+
+2008-04-18 11:37 +0000  dockes    (018890cfdbd7)
+
+	* src/utils/Makefile, src/utils/base64.cpp, src/utils/readfile.cpp:
+	base64 testing code
+
+2008-02-19 08:02 +0000  dockes    (34b45c5acd1c)
+
+	* src/qtgui/main.cpp:
+	make first sort after -q work
+
+2008-02-19 08:02 +0000  dockes    (1293fc15412b)
+
+	* src/qtgui/rclmain_w.cpp:
+	comments+debug
+
+2008-02-19 07:41 +0000  dockes    (efbaeed44ee9)
+
+	* src/rcldb/rcldb.cpp:
+	traces
+
+2008-02-11 10:21 +0000  dockes    (81923201adc7)
+
+	* src/utils/idfile.cpp:
+	hack for Mark B.: allow treating (single-message) mbox files as
+	message/rfc822
+
+2008-02-08 08:37 +0000  dockes    (ddcce838e7d0)
+
+	* src/qtgui/i18n/recoll_de.ts:
+	update by Frank Thieme
+
+2008-02-05 10:45 +0000  dockes    (51a501984fd4)
+
+	* src/sampleconf/mimeconf:
+	*** empty log message ***
+
+2008-02-03 16:24 +0000  dockes    (825bb43d67ca)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	rclsvg
+
+2008-02-03 16:05 +0000  dockes    (81794c3a6d9e)
+
+	* src/filters/rclsvg:
+	*** empty log message ***
+
+2008-02-03 16:04 +0000  dockes    (40c35a7fb1bb)
+
+	* src/filters/rclsvg: new file.
+	* src/filters/rclsvg:
+	*** empty log message ***
+
+2008-01-29 10:14 +0000  dockes    (fd74eae7e8b4 [RECOLL_1_10_1])
+
+	* src/README:
+	*** empty log message ***
+
+2008-01-29 10:11 +0000  dockes    (a1fee09bfc3d)
+
+	* src/rcldb/searchdata.h:
+	m_haveWildCards was sometimes not init
+
+2008-01-29 08:41 +0000  dockes    (ebc971754f92)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2008-01-24 09:34 +0000  dockes    (301425122a56)
+
+	* src/qtgui/main.cpp:
+	*** empty log message ***
+
+2008-01-17 11:15 +0000  dockes    (af11c991aff3)
+
+	* src/qtgui/idxthread.cpp, src/qtgui/idxthread.h,
+	src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h:
+	allow stopping indexing through menu action
+
+2008-01-17 11:14 +0000  dockes    (4c108ac6227a)
+
+	* src/query/wasastringtoquery.h:
+	comment
+
+2008-01-17 11:13 +0000  dockes    (7b2a9225dbef)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-01-16 11:14 +0000  dockes    (ddfe49735bc2)
+
+	* src/query/wasatorcl.cpp, src/rcldb/searchdata.cpp,
+	src/rcldb/searchdata.h:
+	express query language OR chains as rcldb subqueries so that field
+	specs will work inside them
+
+2008-01-16 10:52 +0000  dockes    (6487da12360f)
+
+	* src/ChangeLog, src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2008-01-16 08:43 +0000  dockes    (592d1258c5e4)
+
+	* src/rcldb/searchdata.cpp:
+	splitString filename queries
+
+2007-12-20 09:08 +0000  dockes    (e99decc750eb)
+
+	* src/index/indexer.cpp, src/rcldb/rcldb.cpp:
+	ensure that the names of files with filter errors get indexed anyway
+
+2007-12-13 06:58 +0000  dockes    (de422a0df409)
+
+	* src/aspell/rclaspell.cpp, src/bincimapmime/convert.h,
+	src/common/rclconfig.cpp, src/common/rclinit.cpp,
+	src/common/textsplit.cpp, src/common/unacpp.cpp,
+	src/index/csguess.cpp, src/index/indexer.cpp,
+	src/index/rclmonprc.cpp, src/index/rclmonrcv.cpp,
+	src/index/recollindex.cpp, src/internfile/htmlparse.cpp,
+	src/internfile/mh_mail.cpp, src/internfile/mh_mbox.cpp,
+	src/internfile/myhtmlparse.cpp, src/query/docseqhist.cpp,
+	src/query/history.cpp, src/query/recollq.cpp,
+	src/rcldb/pathhash.cpp, src/rcldb/rcldb.cpp, src/utils/base64.cpp,
+	src/utils/conftree.cpp, src/utils/copyfile.cpp,
+	src/utils/fstreewalk.cpp, src/utils/idfile.cpp,
+	src/utils/mimeparse.cpp, src/utils/pathut.cpp,
+	src/utils/readfile.cpp, src/utils/wipedir.cpp:
+	gcc 4 compat, thanks to Kartik Mistry
+
+2007-12-04 10:17 +0000  dockes    (f2bd537aad87)
+
+	* src/qtgui/rclmain_w.cpp:
+	directly open editor action choice dialog when user says so
+
+2007-12-04 10:16 +0000  dockes    (9a289ca30889)
+
+	* src/qtgui/uiprefs_w.cpp, src/utils/utf8iter.cpp:
+	*** empty log message ***
+
+2007-11-25 07:29 +0000  dockes    (3782c85019d4)
+
+	* src/qtgui/i18n/recoll_tr.ts:
+	*** empty log message ***
+
+2007-11-24 16:51 +0000  dockes    (a41099c58ac0)
+
+	* src/qtgui/i18n/recoll_fr.ts:
+	accents
+
+2007-11-24 16:43 +0000  dockes    (eecb572a0935)
+
+	* src/qtgui/confgui/confguiindex.h:
+	make conftoppanelw a q_object for translations to work
+
+2007-11-24 10:41 +0000  dockes    (343184d41f3b)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts:
+	*** empty log message ***
+
+2007-11-21 16:34 +0000  dockes    (966333a903a9)
+
+	* src/VERSION:
+	*** empty log message ***
+
+2007-11-21 16:34 +0000  dockes    (aed5f0389421)
+
+	* 1.10.0
+
+2007-11-21 16:34 +0000  dockes    (4918fce7a71a)
+
+	* packaging/debian/changelog, packaging/debian/control,
+	packaging/debian/menu, packaging/debian/rules,
+	packaging/rpm/recoll.spec, packaging/rpm/recollfedora.spec,
+	packaging/rpm/recollmdk.spec, tests/shared.sh, website/CHANGES.txt,
+	website/devel.html, website/download.html, website/features.html,
+	website/fr/features.html, website/index.html.en,
+	website/index.html.fr, website/pics/index.html,
+	website/styles/style.css:
+	1.10.0
+
+2007-11-21 14:15 +0000  dockes    (9c57d53ad305 [RECOLL_1_10_0])
+
+	* src/qtgui/confgui/confguiindex.cpp, src/qtgui/main.cpp,
+	src/qtgui/rclmain_w.cpp, src/qtgui/recoll.h:
+	allow opening config gui if no index on first start
+
+2007-11-21 09:42 +0000  dockes    (b1db39055b6d)
+
+	* src/excludefile:
+	*** empty log message ***
+
+2007-11-21 09:34 +0000  dockes    (cca64d1bdb79)
+
+	* src/utils/conftree.cpp:
+	explicitely detect lines beginning with #
+
+2007-11-21 09:00 +0000  dockes    (2cb85a4bd555)
+
+	* src/INSTALL, src/README:
+	*** empty log message ***
+
+2007-11-16 15:20 +0000  dockes    (1f90c7302746)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-11-16 14:28 +0000  dockes    (d7f21b7adf20)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/internfile/internfile.cpp, src/internfile/mimehandler.cpp,
+	src/internfile/mimehandler.h:
+	indexedmimetypes
+
+2007-11-16 12:21 +0000  dockes    (8221e8f1ce4f)
+
+	* src/query/wasastringtoquery.cpp, src/query/wasatorcl.cpp:
+	very small effort to look like xesam simple query
+
+2007-11-16 07:34 +0000  dockes    (1398d49de21d)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-11-16 07:19 +0000  dockes    (eedcef5d56b7)
+
+	* src/qtgui/i18n/recoll_tr.ts:
+	*** empty log message ***
+
+2007-11-15 18:44 +0000  dockes    (99e585288200)
+
+	* src/qtgui/preview_w.cpp:
+	comment
+
+2007-11-15 18:39 +0000  dockes    (1ee213030954)
+
+	* src/qt4gui/q3richtext_p.h: new file.
+	* src/qt4gui/q3richtext_p.h, src/qt4gui/recoll.pro.in:
+	qt4 movetoanchor
+
+2007-11-15 18:39 +0000  dockes    (335db8a5c8cb)
+
+	* src/qtgui/i18n/recoll_it.ts:
+	*** empty log message ***
+
+2007-11-15 18:34 +0000  dockes    (b3bb7b017f2a)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	moveToAnchor qt4
+
+2007-11-15 18:05 +0000  dockes    (1fe63dd4f268)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/preview_w.cpp, src/qtgui/preview_w.h,
+	src/qtgui/recoll.pro.in:
+	finally got anchors to work. qt3
+
+2007-11-15 18:05 +0000  dockes    (3158e59fd92e)
+
+	* src/qtgui/reslist.cpp:
+	*** empty log message ***
+
+2007-11-13 18:42 +0000  dockes    (1a7029e2dd4e)
+
+	* src/doc/man/recoll.1:
+	*** empty log message ***
+
+2007-11-13 18:40 +0000  dockes    (a5a94cfbfa7d)
+
+	* src/query/recollq.cpp:
+	keep format constant
+
+2007-11-13 18:40 +0000  dockes    (09f615e1a305)
+
+	* src/doc/user/usermanual.sgml:
+	text
+
+2007-11-13 18:39 +0000  dockes    (ce5a12bb92bd)
+
+	* tests/badsuffs1/badsuffs1.txt, tests/html/html.txt,
+	tests/mail/mail.txt, tests/ooff/ooff.txt, tests/special/special.txt:
+	1.10+small changes in dataset
+
+2007-11-13 15:35 +0000  dockes    (3a8d3f5af0e8)
+
+	* src/ChangeLog:
+	*** empty log message ***
+
+2007-11-13 15:34 +0000  dockes    (d23b6a94f4c0)
+
+	* src/VERSION:
+	1.10.0?
+
+2007-11-13 10:07 +0000  dockes    (f3338fa8cb4e)
+
+	* src/doc/man/recollq.1: new file.
+	* src/doc/man/recollq.1:
+	*** empty log message ***
+
+2007-11-09 18:48 +0000  dockes    (7859ad070bfc)
+
+	* src/qtgui/i18n/recoll_fr.ts:
+	1.9 ?
+
+2007-11-09 18:07 +0000  dockes    (557d4b9ce60a)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_tr.ts, src/qtgui/i18n/recoll_uk.ts,
+	src/qtgui/i18n/recoll_xx.ts:
+	*** empty log message ***
+
+2007-11-09 15:56 +0000  dockes    (2c201bdce017)
+
+	* src/filters/rcltex:
+	*** empty log message ***
+
+2007-11-09 15:46 +0000  dockes    (7960c1dd4d0a)
+
+	* src/kde/kioslave/recoll/00README.txt,
+	src/kde/kioslave/recoll/Makefile,
+	src/kde/kioslave/recoll/kio_recoll.cpp:
+	get things to compile with recoll 1.9 and suse + kde 3.5.5
+
+2007-11-09 13:44 +0000  dockes    (6196dbaf0aec)
+
+	* src/sampleconf/mimeview:
+	tex
+
+2007-11-09 11:55 +0000  dockes    (10ce7112596d)
+
+	* src/filters/rcltex: new file.
+	* src/filters/rclmedia: deleted file.
+	* src/filters/rclmedia, src/filters/rcltex, src/sampleconf/mimeconf,
+	src/sampleconf/mimemap:
+	added support for indexing TeX text
+
+2007-11-09 11:54 +0000  dockes    (5a35ec87ecf2)
+
+	* src/filters/rclid3:
+	comments
+
+2007-11-08 09:35 +0000  dockes    (bdde14acf3bd)
+
+	* src/query/recollq.h: new file.
+	* src/lib/Makefile, src/lib/mkMake, src/qtgui/main.cpp,
+	src/qtgui/recoll.pro.in, src/query/Makefile, src/query/recollq.cpp,
+	src/query/recollq.h:
+	allow recoll to be used as a recollq driver
+
+2007-11-08 09:34 +0000  dockes    (06e94674b8e2)
+
+	* src/utils/execmd.cpp:
+	include pthread
+
+2007-11-08 09:34 +0000  dockes    (d6e84478935d)
+
+	* src/rcldb/stemdb.cpp:
+	debug
+
+2007-11-08 09:32 +0000  dockes    (9f3349e7358b)
+
+	* src/qt4gui/recoll.pro.in:
+	turkish
+
+2007-11-08 09:31 +0000  dockes    (cd6b8b7d2a36)
+
+	* src/mk/OpenBSD:
+	*** empty log message ***
+
+2007-11-08 07:54 +0000  dockes    (6e986b6d1e64)
+
+	* src/query/recollq.cpp:
+	add -b option to only output url list
+
+2007-11-06 11:55 +0000  dockes    (2b0e2fc0dd88)
+
+	* src/qtgui/i18n/recoll_tr.ts: new file.
+	* src/qtgui/i18n/recoll_tr.ts:
+	*** empty log message ***
+
+2007-10-27 16:40 +0000  dockes    (e8ac0b8f6c46)
+
+	* src/rcldb/rcldb.cpp:
+	comment
+
+2007-10-27 08:40 +0000  dockes    (2ccaf4ef243e)
+
+	* src/ChangeLog, src/qtgui/i18n/recoll_de.ts,
+	src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-10-27 08:40 +0000  dockes    (e647e4592daa)
+
+	* src/filters/rcluncomp:
+	allow uncompressing suffix-less files
+
+2007-10-27 08:40 +0000  dockes    (dc6d97a86685)
+
+	* src/internfile/internfile.cpp:
+	use pcSubst
+
+2007-10-27 08:39 +0000  dockes    (54ba3ef75586)
+
+	* src/rcldb/rcldb.cpp:
+	adjust MatchDecider return type according to xapian version
+
+2007-10-27 07:06 +0000  dockes    (54b798d7fa02)
+
+	* src/qtgui/i18n/recoll_xx.ts:
+	sent to ning
+
+2007-10-26 10:42 +0000  dockes    (acfa4e6c24ba)
+
+	* src/doc/user/usermanual.sgml:
+	index config gui
+
+2007-10-25 15:51 +0000  dockes    (12d12311134a)
+
+	* src/qtgui/confgui/confguiindex.cpp:
+	labels
+
+2007-10-25 15:51 +0000  dockes    (2a1d29582446)
+
+	* src/qtgui/confgui/confgui.cpp:
+	use new style combobox constructor
+
+2007-10-25 15:50 +0000  dockes    (8b45d32c605c)
+
+	* src/internfile/mh_exec.h:
+	cleanup
+
+2007-10-25 08:04 +0000  dockes    (0bf8540b6c22)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-10-25 07:27 +0000  dockes    (5d57c38993af)
+
+	* src/query/recollq.cpp, src/query/wasatorcl.cpp:
+	added option to query language for filtering on directory
+
+2007-10-25 07:09 +0000  dockes    (d1adc7006d08)
+
+	* src/rcldb/rcldb.cpp:
+	add filter topdir to query description
+
+2007-10-24 15:38 +0000  dockes    (5f1863c33239)
+
+	* src/rcldb/rcldb.cpp:
+	use a Xapian MatchDecider to filter on dir path
+
+2007-10-24 08:42 +0000  dockes    (2d337545271f)
+
+	* src/rcldb/rcldb.cpp:
+	make filter a xapian::MatchDecider, dont change mechanism
+
+2007-10-19 15:25 +0000  dockes    (935a92d6db39)
+
+	* src/qtgui/ssearch_w.cpp, src/utils/smallut.cpp:
+	consider cr and lf as whitespace when splitting strings
+
+2007-10-19 14:31 +0000  dockes    (bb88b5f4fc25)
+
+	* src/qtgui/confgui/confgui.h, src/qtgui/confgui/confguiindex.cpp:
+	small sizing adjustments
+
+2007-10-18 10:39 +0000  dockes    (f34f0260a62a)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/preview_w.cpp, src/qtgui/reslist.cpp:
+	let plaintorich do the chunking, easier to make sure we dont confuse
+	textedit by cutting inside a tag
+
+2007-10-18 10:15 +0000  dockes    (7c46f29559fe)
+
+	* src/qtgui/confgui/confguiindex.cpp:
+	qt3
+
+2007-10-17 16:12 +0000  dockes    (41f711edeb0b)
+
+	* src/qtgui/plaintorich.cpp:
+	replaced utf8 cgj with good ole bel
+
+2007-10-17 11:40 +0000  dockes    (102fcc4aa169)
+
+	* src/internfile/mh_mail.cpp, src/internfile/mh_mail.h,
+	src/utils/mimeparse.cpp:
+	text/plain attachments were not transcoded to utf-8
+
+2007-10-17 09:57 +0000  dockes    (dd33128e3a59)
+
+	* src/common/rclconfig.cpp, src/internfile/internfile.cpp:
+	*** empty log message ***
+
+2007-10-15 13:08 +0000  dockes    (0a095e89bfb9)
+
+	* src/kde/recoll_applet/0README.Recoll, src/kde/recoll_applet/AUTHORS,
+	src/kde/recoll_applet/COPYING, src/kde/recoll_applet/ChangeLog,
+	src/kde/recoll_applet/Doxyfile, src/kde/recoll_applet/INSTALL,
+	src/kde/recoll_applet/Makefile.am,
+	src/kde/recoll_applet/Makefile.cvs,
+	src/kde/recoll_applet/Makefile.in, src/kde/recoll_applet/NEWS,
+	src/kde/recoll_applet/README, src/kde/recoll_applet/TODO,
+	src/kde/recoll_applet/acinclude.m4,
+	src/kde/recoll_applet/aclocal.m4,
+	src/kde/recoll_applet/admin/Doxyfile.am,
+	src/kde/recoll_applet/admin/Doxyfile.global,
+	src/kde/recoll_applet/admin/Makefile.common,
+	src/kde/recoll_applet/admin/acinclude.m4.in,
+	src/kde/recoll_applet/admin/am_edit,
+	src/kde/recoll_applet/admin/bcheck.pl,
+	src/kde/recoll_applet/admin/compile,
+	src/kde/recoll_applet/admin/conf.change.pl,
+	src/kde/recoll_applet/admin/config.guess,
+	src/kde/recoll_applet/admin/config.pl,
+	src/kde/recoll_applet/admin/config.sub,
+	src/kde/recoll_applet/admin/configure.in.bot.end,
+	src/kde/recoll_applet/admin/configure.in.min,
+	src/kde/recoll_applet/admin/cvs.sh,
+	src/kde/recoll_applet/admin/debianrules,
+	src/kde/recoll_applet/admin/depcomp,
+	src/kde/recoll_applet/admin/deps.am, src/kde/recoll_applet/admin
+	/detect-autoconf.pl, src/kde/recoll_applet/admin/doxygen.sh,
+	src/kde/recoll_applet/admin/install-sh,
+	src/kde/recoll_applet/admin/libtool.m4.in,
+	src/kde/recoll_applet/admin/ltmain.sh,
+	src/kde/recoll_applet/admin/missing,
+	src/kde/recoll_applet/admin/mkinstalldirs,
+	src/kde/recoll_applet/admin/nmcheck,
+	src/kde/recoll_applet/admin/oldinclude.m4.in,
+	src/kde/recoll_applet/admin/pkg.m4.in,
+	src/kde/recoll_applet/admin/ylwrap,
+	src/kde/recoll_applet/config.h.in, src/kde/recoll_applet/configure,
+	src/kde/recoll_applet/configure.files,
+	src/kde/recoll_applet/configure.in,
+	src/kde/recoll_applet/configure.in.in,
+	src/kde/recoll_applet/doc/Makefile.am,
+	src/kde/recoll_applet/doc/Makefile.in,
+	src/kde/recoll_applet/doc/en/Makefile.am,
+	src/kde/recoll_applet/doc/en/Makefile.in,
+	src/kde/recoll_applet/doc/en/index.docbook,
+	src/kde/recoll_applet/po/Makefile.am,
+	src/kde/recoll_applet/po/Makefile.in,
+	src/kde/recoll_applet/src/Makefile.am,
+	src/kde/recoll_applet/src/Makefile.in,
+	src/kde/recoll_applet/src/kpixmapcombo.cpp,
+	src/kde/recoll_applet/src/kpixmapcombo.h,
+	src/kde/recoll_applet/src/recoll_applet.cpp,
+	src/kde/recoll_applet/src/recoll_applet.desktop,
+	src/kde/recoll_applet/src/recoll_applet.h,
+	src/kde/recoll_applet/src/recoll_applet.lsm,
+	src/kde/recoll_applet/stamp-h.in, src/kde/recoll_applet/subdirs: new
+	file.
+	* src/kde/recoll_applet/0README.Recoll, src/kde/recoll_applet/AUTHORS,
+	src/kde/recoll_applet/COPYING, src/kde/recoll_applet/ChangeLog,
+	src/kde/recoll_applet/Doxyfile, src/kde/recoll_applet/INSTALL,
+	src/kde/recoll_applet/Makefile.am,
+	src/kde/recoll_applet/Makefile.cvs,
+	src/kde/recoll_applet/Makefile.in, src/kde/recoll_applet/NEWS,
+	src/kde/recoll_applet/README, src/kde/recoll_applet/TODO,
+	src/kde/recoll_applet/acinclude.m4,
+	src/kde/recoll_applet/aclocal.m4,
+	src/kde/recoll_applet/admin/Doxyfile.am,
+	src/kde/recoll_applet/admin/Doxyfile.global,
+	src/kde/recoll_applet/admin/Makefile.common,
+	src/kde/recoll_applet/admin/acinclude.m4.in,
+	src/kde/recoll_applet/admin/am_edit,
+	src/kde/recoll_applet/admin/bcheck.pl,
+	src/kde/recoll_applet/admin/compile,
+	src/kde/recoll_applet/admin/conf.change.pl,
+	src/kde/recoll_applet/admin/config.guess,
+	src/kde/recoll_applet/admin/config.pl,
+	src/kde/recoll_applet/admin/config.sub,
+	src/kde/recoll_applet/admin/configure.in.bot.end,
+	src/kde/recoll_applet/admin/configure.in.min,
+	src/kde/recoll_applet/admin/cvs.sh,
+	src/kde/recoll_applet/admin/debianrules,
+	src/kde/recoll_applet/admin/depcomp,
+	src/kde/recoll_applet/admin/deps.am, src/kde/recoll_applet/admin
+	/detect-autoconf.pl, src/kde/recoll_applet/admin/doxygen.sh,
+	src/kde/recoll_applet/admin/install-sh,
+	src/kde/recoll_applet/admin/libtool.m4.in,
+	src/kde/recoll_applet/admin/ltmain.sh,
+	src/kde/recoll_applet/admin/missing,
+	src/kde/recoll_applet/admin/mkinstalldirs,
+	src/kde/recoll_applet/admin/nmcheck,
+	src/kde/recoll_applet/admin/oldinclude.m4.in,
+	src/kde/recoll_applet/admin/pkg.m4.in,
+	src/kde/recoll_applet/admin/ylwrap,
+	src/kde/recoll_applet/config.h.in, src/kde/recoll_applet/configure,
+	src/kde/recoll_applet/configure.files,
+	src/kde/recoll_applet/configure.in,
+	src/kde/recoll_applet/configure.in.in,
+	src/kde/recoll_applet/doc/Makefile.am,
+	src/kde/recoll_applet/doc/Makefile.in,
+	src/kde/recoll_applet/doc/en/Makefile.am,
+	src/kde/recoll_applet/doc/en/Makefile.in,
+	src/kde/recoll_applet/doc/en/index.docbook,
+	src/kde/recoll_applet/po/Makefile.am,
+	src/kde/recoll_applet/po/Makefile.in,
+	src/kde/recoll_applet/src/Makefile.am,
+	src/kde/recoll_applet/src/Makefile.in,
+	src/kde/recoll_applet/src/kpixmapcombo.cpp,
+	src/kde/recoll_applet/src/kpixmapcombo.h,
+	src/kde/recoll_applet/src/recoll_applet.cpp,
+	src/kde/recoll_applet/src/recoll_applet.desktop,
+	src/kde/recoll_applet/src/recoll_applet.h,
+	src/kde/recoll_applet/src/recoll_applet.lsm,
+	src/kde/recoll_applet/stamp-h.in, src/kde/recoll_applet/subdirs:
+	*** empty log message ***
+
+2007-10-14 16:07 +0000  dockes    (aea3ceac265d)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-10-09 14:08 +0000  dockes    (008fb8da2cfe)
+
+	* src/qt4gui/recoll.pro.in, src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h, src/qtgui/idxthread.cpp,
+	src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h, src/qtgui/recoll.pro.in:
+	indexing confgui seems to sort of work
+
+2007-10-09 11:08 +0000  dockes    (8e165638db48)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h, src/qtgui/confgui/conflinkrcl.h,
+	src/qtgui/confgui/main.cpp:
+	*** empty log message ***
+
+2007-10-09 09:43 +0000  dockes    (bda697547b28)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h:
+	modified mechanism for confgui updates
+
+2007-10-09 09:40 +0000  dockes    (314568630e50)
+
+	* src/utils/conftree.h:
+	*** empty log message ***
+
+2007-10-07 20:22 +0000  dockes    (a4407de529dc)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confguiindex.cpp:
+	*** empty log message ***
+
+2007-10-06 07:44 +0000  dockes    (e12dcaba9422)
+
+	* src/sampleconf/mimeconf:
+	*** empty log message ***
+
+2007-10-06 07:26 +0000  dockes    (8c03c83a6353)
+
+	* src/ChangeLog, src/INSTALL, src/README, src/VERSION:
+	*** empty log message ***
+
+2007-10-06 07:13 +0000  dockes    (80c8e77d75e3)
+
+	* src/qtgui/i18n/recoll_xx.ts: new file.
+	* src/doc/user/usermanual.sgml, src/qtgui/i18n/recoll_xx.ts:
+	*** empty log message ***
+
+2007-10-05 14:00 +0000  dockes    (3f47738c7b7f)
+
+	* src/query/wasatorcl.cpp:
+	add rclcat prefix to query languages + adapt find_applet to use it
+
+2007-10-05 08:03 +0000  dockes    (eb9ae456f872)
+
+	* src/qtgui/main.cpp, src/qtgui/ssearch_w.cpp, src/qtgui/ssearch_w.h:
+	add cmd line option to run query when starting
+
+2007-10-04 12:26 +0000  dockes    (479712bd069b)
+
+	* src/rcldb/searchdata.cpp:
+	when search includes composite spans + other terms, increase slack
+	instead of switching to word split
+
+2007-10-04 12:21 +0000  dockes    (67c23cd41df2)
+
+	* src/common/rclconfig.cpp, src/common/textsplit.cpp,
+	src/common/textsplit.h:
+	make cjk ngramlen configurable
+
+2007-10-04 12:20 +0000  dockes    (e9e128bf43ab)
+
+	* src/index/indexer.cpp:
+	trace
+
+2007-10-03 14:53 +0000  dockes    (b8852ea7a80c)
+
+	* src/internfile/Makefile, src/internfile/mh_mbox.cpp,
+	src/internfile/mh_mbox.h:
+	Improve From_ line detection
+
+2007-10-02 14:25 +0000  dockes    (3379ab8d9013)
+
+	* src/doc/user/docbook.css, src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-10-02 14:22 +0000  dockes    (29a402a23d12)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	a few more image files
+
+2007-10-02 14:00 +0000  dockes    (d0e7241eeb0e)
+
+	* src/filters/rclflac, src/filters/rclogg: new file.
+	* src/filters/rcljpeg: deleted file.
+	* src/filters/rclflac, src/filters/rcljpeg, src/filters/rclogg:
+	*** empty log message ***
+
+2007-10-02 13:56 +0000  dockes    (e180ca729bea)
+
+	* src/filters/rclimg:
+	comments,GPL
+
+2007-10-02 11:39 +0000  dockes    (7777fdc5d30a)
+
+	* src/common/rclconfig.cpp, src/common/textsplit.cpp,
+	src/common/textsplit.h:
+	add flag to disable cjk processing
+
+2007-10-01 17:56 +0000  dockes    (29b1aeb75d23)
+
+	* src/filters/rclimg: new file.
+	* src/filters/rclimg:
+	initial version from Cedric Scott
+
+2007-10-01 15:57 +0000  dockes    (b3aeb47d6a43)
+
+	* src/utils/conftree.cpp:
+	added updates/erase tests
+
+2007-10-01 06:35 +0000  dockes    (b29617933c16)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp, src/qtgui/confgui/main.cpp,
+	src/qtgui/confgui/trconf.pro:
+	qt4 port
+
+2007-10-01 06:19 +0000  dockes    (78068b236681)
+
+	* src/VERSION, src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/qtgui/confgui/confgui.cpp, src/utils/conftree.cpp,
+	src/utils/conftree.h:
+	config update enabling functions
+
+2007-09-29 09:06 +0000  dockes    (e38c26097ece)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h, src/qtgui/confgui/conflinkrcl.h,
+	src/qtgui/confgui/main.cpp, src/qtgui/confgui/trconf.pro:
+	*** empty log message ***
+
+2007-09-27 15:47 +0000  dockes    (9ac07bf91591)
+
+	* src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h, src/qtgui/confgui/conflinkrcl.h:
+	new file.
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/confguiindex.cpp,
+	src/qtgui/confgui/confguiindex.h, src/qtgui/confgui/conflinkrcl.h,
+	src/qtgui/confgui/main.cpp, src/qtgui/confgui/trconf.pro:
+	*** empty log message ***
+
+2007-09-27 11:03 +0000  dockes    (436530279a09)
+
+	* src/utils/conftree.h:
+	comment
+
+2007-09-27 11:02 +0000  dockes    (a466c387c485)
+
+	* src/utils/conftree.cpp, src/utils/conftree.h:
+	avoid adding unneeded entries in confstack. fix erase-add resulting
+	in duplicate
+
+2007-09-26 12:16 +0000  dockes    (8e1e4edb4f4a)
+
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/main.cpp, src/qtgui/confgui/trconf.pro: new file.
+	* src/qtgui/confgui/confgui.cpp, src/qtgui/confgui/confgui.h,
+	src/qtgui/confgui/main.cpp, src/qtgui/confgui/trconf.pro:
+	*** empty log message ***
+
+2007-09-22 08:51 +0000  dockes    (8072f3278663)
+
+	* src/common/textsplit.cpp, src/utils/utf8iter.h:
+	include assert.h when needed
+
+2007-09-21 16:45 +0000  dockes    (d85479652341)
+
+	* src/INSTALL, src/README, src/VERSION, src/doc/user/usermanual.sgml,
+	src/qtgui/recoll.pro.in:
+	*** empty log message ***
+
+2007-09-20 12:22 +0000  dockes    (28a9c536ebba)
+
+	* src/common/textsplit.cpp:
+	logs
+
+2007-09-20 08:45 +0000  dockes    (415256bd7508)
+
+	* src/common/textsplit.cpp, src/common/textsplit.h,
+	src/utils/utf8iter.h:
+	initial cjk support
+
+2007-09-20 08:43 +0000  dockes    (66200ff61f31)
+
+	* src/rcldb/searchdata.cpp:
+	comments,formatting
+
+2007-09-20 08:42 +0000  dockes    (750b59dea1e9)
+
+	* src/qtgui/rclmain_w.cpp:
+	restore cursor if cant start query
+
+2007-09-18 20:35 +0000  dockes    (1d01904f2b55)
+
+	* src/common/textsplit.cpp, src/common/textsplit.h:
+	use m_ prefix for members
+
+2007-09-18 20:34 +0000  dockes    (49381b7f40f6)
+
+	* src/qt4gui/recoll.pro.in:
+	add recoll_xx.ts
+
+2007-09-18 07:01 +0000  dockes    (7dea06d57ada)
+
+	* src/qtgui/i18n/recoll_it.ts:
+	changes by Giovanni Cannizzaro
+
+2007-09-11 08:23 +0000  dockes    (615a70a64b94 [RECOLL_1_9_0])
+
+	* src/desktop/recoll-searchgui.desktop:
+	desktop file corrected as per Kartik Mistry patch
+
+2007-09-10 05:44 +0000  dockes    (78b0c9bd47bb)
+
+	* src/qtgui/i18n/recoll_fr.ts:
+	long menu labels cause pbs at least on macosx
+
+2007-09-08 17:26 +0000  dockes    (ef2964b2e49e)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-09-08 17:25 +0000  dockes    (000b2b01844d)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h,
+	src/qtgui/preview_w.cpp, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp:
+	change hghlight text size limit to configurable value
+
+2007-09-08 17:21 +0000  dockes    (c0ab1e961f0a)
+
+	* src/qtgui/viewaction_w.cpp:
+	added missing space in string
+
+2007-09-08 17:21 +0000  dockes    (f70ce9c4c753)
+
+	* src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp:
+	renamed preferencesQuery_PrefsAction to queryPrefsAction
+
+2007-09-08 17:19 +0000  dockes    (17eefeb77500 [RECOLL_1_9_1cjk2, RECOLL_1_9_1cjk1])
+
+	* src/qtgui/plaintorich.cpp:
+	comment
+
+2007-09-08 09:44 +0000  dockes    (8aabe9bc2d85)
+
+	* src/utils/readfile.cpp:
+	small pb in solaris fix
+
+2007-09-08 08:07 +0000  dockes    (4b862559adbb)
+
+	* src/mk/SunOS, src/utils/pathut.cpp, src/utils/readfile.cpp:
+	SunOS 2.8 fixes
+
+2007-09-07 14:58 +0000  dockes    (f0b17af1f5d7)
+
+	* src/configure, src/configure.ac:
+	always add lz to lxapian
+
+2007-09-07 12:39 +0000  dockes    (b10ac30fe130)
+
+	* website/CHANGES.txt:
+	*** empty log message ***
+
+2007-09-07 08:05 +0000  dockes    (f031116372e8)
+
+	* src/rcldb/rcldb.cpp:
+	improve purge error message printing
+
+2007-09-07 08:04 +0000  dockes    (276b259f9ec6)
+
+	* src/qtgui/i18n/recoll_it.ts:
+	new 1.9 translation by C. Rigamont
+
+2007-09-07 08:04 +0000  dockes    (450e1342467c)
+
+	* src/sampleconf/mimemap:
+	fix wordperfect spurious extensions
+
+2007-09-07 08:03 +0000  dockes    (624a100107be [RECOLL_1_9_1cjk])
+
+	* website/BUGS.txt:
+	update xapian near to 1.0.2
+
+2007-09-07 08:03 +0000  dockes    (a0d360caf71e)
+
+	* website/copydocs:
+	to_mac
+
+2007-09-01 19:12 +0000  dockes    (3ebdb5af664f)
+
+	* src/qt4gui/recoll.pro.in, src/qtgui/i18n/recoll_de.ts,
+	src/qtgui/recoll.pro.in:
+	*** empty log message ***
+
+2007-08-31 09:04 +0000  dockes    (32533d0d11d0)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h:
+	pressing CR in advsearch would run query twice because of start
+	autodefault
+
+2007-08-31 07:23 +0000  dockes    (bb17fa4cfaca)
+
+	* src/qtgui/images/d_firstpage.png, src/qtgui/images/firstpage.png:
+	new file.
+	* src/qtgui/images/d_firstpage.png, src/qtgui/images/firstpage.png:
+	*** empty log message ***
+
+2007-08-30 10:11 +0000  dockes    (c75b5f42b33d)
+
+	* src/INSTALL, src/README, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-08-30 10:00 +0000  dockes    (7c4ccceae2a7)
+
+	* website/BUGS.txt, website/CHANGES.txt, website/download.html,
+	website/features.html:
+	*** empty log message ***
+
+2007-08-30 09:01 +0000  dockes    (687cad7b46de)
+
+	* src/doc/user/usermanual.sgml, src/index/indexer.cpp,
+	src/index/indexer.h, src/index/rclmonrcv.cpp,
+	src/sampleconf/recoll.conf.in, src/utils/fstreewalk.cpp,
+	src/utils/fstreewalk.h:
+	add followLinks option
+
+2007-08-30 08:39 +0000  dockes    (6af3a2216074)
+
+	* src/doc/user/usermanual.sgml:
+	add followLinks option
+
+2007-08-28 08:12 +0000  dockes    (6385c6a9c88e)
+
+	* src/index/indexer.cpp:
+	allow symlinks in topdirs
+
+2007-08-28 08:08 +0000  dockes    (a3df89087437)
+
+	* src/utils/fstreewalk.cpp, src/utils/fstreewalk.h:
+	follow top (entry) symlinks even if nofollow is set
+
+2007-08-28 08:07 +0000  dockes    (19ac4f90b7e7)
+
+	* src/internfile/internfile.cpp:
+	error msg
+
+2007-08-26 13:52 +0000  dockes    (fa08f95a4d95)
+
+	* src/doc/user/usermanual.sgml:
+	add wordperfect ext app info
+
+2007-08-26 13:34 +0000  dockes    (ac877cc2e3ad)
+
+	* src/filters/rclwpd: new file.
+	* src/filters/rclwpd, src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	added wordperfect support
+
+2007-08-26 13:34 +0000  dockes    (7472abcdbc4a)
+
+	* src/sampleconf/recoll.conf.in:
+	add commented entries for daem*
+
+2007-08-07 08:45 +0000  dockes    (ad6dad566902)
+
+	* src/qtgui/rclmain_w.cpp:
+	*** empty log message ***
+
+2007-08-07 08:42 +0000  dockes    (2040417c73e4)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp:
+	qt3 adjustments
+
+2007-08-07 08:26 +0000  dockes    (55c7dc79c190)
+
+	* src/aspell/rclaspell.cpp, src/sampleconf/recoll.conf.in:
+	*** empty log message ***
+
+2007-08-05 05:55 +0000  dockes    (3acd192c01d1)
+
+	* src/utils/conftree.h:
+	comments
+
+2007-08-05 05:49 +0000  dockes    (afee970ae166)
+
+	* src/utils/conftree.h:
+	*** empty log message ***
+
+2007-08-04 07:22 +0000  dockes    (9afb2050f462)
+
+	* src/utils/conftree.cpp, src/utils/conftree.h:
+	Allow updates in confstacks
+
+2007-08-03 07:50 +0000  dockes    (28ae2e572dcf)
+
+	* src/utils/Makefile, src/utils/conftree.cpp, src/utils/conftree.h:
+	have conftree preserve comments and ordering
+
+2007-08-02 06:33 +0000  dockes    (4da8b2dbcaa6)
+
+	* src/qt4gui/recoll.qrc, src/qtgui/rclmain.ui,
+	src/qtgui/rclmain_w.cpp, src/qtgui/recoll.pro.in,
+	src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	added gotofirstpage action
+
+2007-08-01 10:04 +0000  dockes    (c91831fab8a0)
+
+	* src/qtgui/guiutils.h, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h, src/qtgui/ssearch_w.cpp,
+	src/qtgui/uiprefs_w.cpp, src/qtgui/uiprefs_w.h,
+	src/rcldb/stemdb.cpp, src/rcldb/stemdb.h:
+	Allow stem expansion for several (all) stemming languages at a time
+
+2007-08-01 07:55 +0000  dockes    (5d13d87e6e14)
+
+	* src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp,
+	src/qtgui/rclmain_w.h, src/qtgui/uiprefs_w.cpp,
+	src/qtgui/uiprefs_w.h:
+	allow setting stemlang from prefs menu
+
+2007-07-20 14:50 +0000  dockes    (573069870fd4)
+
+	* src/configure, src/configure.ac:
+	check for uic3 during qt4 configure
+
+2007-07-20 14:43 +0000  dockes    (32ae47904cca)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	preview: dont search for anchors if we have none
+
+2007-07-20 14:32 +0000  dockes    (eac614c9a725)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	*** empty log message ***
+
+2007-07-20 11:44 +0000  dockes    (6133f68f886f)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h:
+	factorize previewNext/Prev
+
+2007-07-20 11:38 +0000  dockes    (4dfc3942351a)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h:
+	more preview window interface cleanup
+
+2007-07-20 10:55 +0000  dockes    (d57bd5e6cb2d)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h,
+	src/qtgui/rclmain_w.cpp:
+	cleaned up preview window interface
+
+2007-07-14 16:53 +0000  dockes    (35087158d61f)
+
+	* src/common/autoconfig.h.in, src/configure, src/configure.ac,
+	src/mk/AIX, src/mk/Darwin, src/mk/Linux, src/mk/SunOS,
+	src/utils/execmd.cpp:
+	handle putenv arg constness in configure
+
+2007-07-13 10:24 +0000  dockes    (98774298901d)
+
+	* src/INSTALL, src/README, src/doc/man/recoll.conf.5,
+	src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts,
+	website/BUGS.txt, website/CHANGES.txt, website/download.html:
+	*** empty log message ***
+
+2007-07-13 07:17 +0000  dockes    (d2c5a6098bbd)
+
+	* src/doc/user/docbook.css, src/doc/user/usermanual.sgml:
+	1.9 changes
+
+2007-07-13 07:10 +0000  dockes    (2569115962c0)
+
+	* src/qtgui/uiprefs.ui:
+	msg
+
+2007-07-13 07:00 +0000  dockes    (2bd0371b8e12)
+
+	* src/qtgui/plaintorich.cpp:
+	adjust term beacon for better finding ?
+
+2007-07-13 06:31 +0000  dockes    (f7d41e95166c)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h,
+	src/qtgui/rclmain_w.cpp:
+	better handle preview close during load
+
+2007-07-12 17:28 +0000  dockes    (5b6f1204d077)
+
+	* src/rcldb/rcldb.cpp:
+	*** empty log message ***
+
+2007-07-12 17:13 +0000  dockes    (9345d3db5ff2)
+
+	* src/filters/rclpdf:
+	dont use anchored regexps for stripping whitespace, ubuntu mawk
+	ignores the anchor
+
+2007-07-12 13:41 +0000  dockes    (1fb4e582fe5b)
+
+	* src/utils/cancelcheck.h:
+	*** empty log message ***
+
+2007-07-12 10:53 +0000  dockes    (eb352f6c17ae)
+
+	* src/index/rclmonrcv.cpp, src/utils/fstreewalk.cpp,
+	src/utils/fstreewalk.h:
+	monitor: dont add watch on created dir if in skippedXXX
+
+2007-07-12 10:13 +0000  dockes    (d55862505674)
+
+	* src/ChangeLog, src/qtgui/guiutils.cpp, src/qtgui/guiutils.h,
+	src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp:
+	fix v1.8 default format string if we find it
+
+2007-07-12 08:34 +0000  dockes    (b69b14b67cd2)
+
+	* src/rcldb/rcldb.cpp:
+	use uniform code for Xapian exception catching + catch a few more,
+	esp. databaseModified cases
+
+2007-07-12 08:23 +0000  dockes    (ffe9a12f9237)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/reslist.cpp,
+	src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp:
+	icon now part of paragraph format
+
+2007-07-11 10:05 +0000  dockes    (a8d4da32f304)
+
+	* src/qtgui/reslist.cpp:
+	dont create popup in irrelevant areas
+
+2007-07-10 09:24 +0000  dockes    (993776d69bab)
+
+	* src/sampleconf/recoll.conf.in:
+	idxflushnb default 10
+
+2007-07-10 09:23 +0000  dockes    (e800d4e4d1de)
+
+	* src/doc/man/recollindex.1, src/index/indexer.cpp,
+	src/index/indexer.h, src/index/recollindex.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/rcldb.h:
+	recollindex -l
+
+2007-07-10 05:44 +0000  dockes    (7247df0336ab)
+
+	* src/sampleconf/recoll.conf.in:
+	*** empty log message ***
+
+2007-07-09 17:21 +0000  dockes    (ef8eddb1b94a)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-07-01 06:52 +0000  dockes    (03cb707d9122)
+
+	* src/filters/rclid3: new file.
+	* src/filters/rclid3, src/sampleconf/mimeconf, src/sampleconf/mimemap,
+	src/sampleconf/mimeview:
+	audio tags support improvement: flac+ogg. use FORPREVIEW
+
+2007-06-26 17:07 +0000  dockes    (ec5b66db8aea)
+
+	* src/qtgui/i18n/recoll_de.ts, src/qtgui/i18n/recoll_fr.ts,
+	src/qtgui/i18n/recoll_it.ts, src/qtgui/i18n/recoll_ru.ts,
+	src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-06-26 16:58 +0000  dockes    (34658791397a)
+
+	* *** empty log message ***
+
+2007-06-26 16:58 +0000  dockes    (26a811724423)
+
+	* packaging/rpm/recollCooker.spec, website/fr/features.html,
+	website/mario.png, website/perfs.html, website/smile.png: new file.
+	* packaging/rpm/recollCooker.spec, src/doc/user/usermanual.sgml,
+	website/BUGS.txt, website/CHANGES.txt, website/credits.html,
+	website/doc.html, website/download.html, website/features.html,
+	website/fr/features.html, website/index.html.en,
+	website/index.html.fr, website/mario.png, website/perfs.html,
+	website/rclidxfmt.html, website/smile.png, website/styles/style.css:
+	*** empty log message ***
+
+2007-06-26 16:09 +0000  dockes    (d4a3058d613e)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h:
+	comments
+
+2007-06-26 16:08 +0000  dockes    (7115d37ab33d)
+
+	* src/configure, src/configure.ac, src/mk/Darwin,
+	src/qtgui/reslist.cpp, src/recollinstall.in:
+	get things to sort of compile / install on macosx
+
+2007-06-26 15:38 +0000  dockes    (02621fd62ca0)
+
+	* src/ChangeLog: new file.
+	* src/ChangeLog:
+	*** empty log message ***
+
+2007-06-26 11:59 +0000  dockes    (51061217635d)
+
+	* src/excludefile, src/makesrcdist.sh:
+	small mkdist fixes
+
+2007-06-25 18:31 +0000  dockes    (5f173fcd227f)
+
+	* src/INSTALL, src/README:
+	*** empty log message ***
+
+2007-06-25 10:25 +0000  dockes    (048658cd678b)
+
+	* src/rcldb/rcldb.cpp:
+	simplified and hopefully improved abstract generation
+
+2007-06-25 10:13 +0000  dockes    (14ecb9d719e7)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/reslist.cpp:
+	plaintorich: only setup beacons if needed
+
+2007-06-22 06:14 +0000  dockes    (0584daa67e7c)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/query/wasatorcl.cpp, src/rcldb/rcldb.cpp,
+	src/rcldb/searchdata.cpp, src/sampleconf/mimeconf:
+	handle mime: and ext: in qlang
+
+2007-06-21 11:56 +0000  dockes    (e5102468f77e)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	slightly reorganized Db::close/~Db code
+
+2007-06-21 11:14 +0000  dockes    (e360a50fdaa5)
+
+	* src/common/rclconfig.cpp:
+	beware of unsigneds diffs when comparing to 0 !
+
+2007-06-20 13:16 +0000  dockes    (e515c5541bd4)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/rclmain.ui,
+	src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h,
+	src/query/history.cpp, src/query/history.h:
+	menu entry to reset document history
+
+2007-06-19 16:19 +0000  dockes    (675d2fed7a32)
+
+	* src/qtgui/rclmain_w.cpp, src/qtgui/sort_w.cpp:
+	fix sort state restoration which didnt work
+
+2007-06-19 15:48 +0000  dockes    (36fa1c12d616)
+
+	* src/rcldb/rcldb.cpp:
+	try to better print delete exception messages
+
+2007-06-19 15:47 +0000  dockes    (304862edc545)
+
+	* src/query/xadump.cpp:
+	option X
+
+2007-06-19 15:47 +0000  dockes    (23a728d3cdd7)
+
+	* src/query/recollq.cpp:
+	compile
+
+2007-06-19 12:27 +0000  dockes    (5ee1b5e9168e)
+
+	* src/internfile/internfile.cpp, src/internfile/internfile.h:
+	get test driver to compile
+
+2007-06-19 12:17 +0000  dockes    (8974a52d2baa)
+
+	* src/internfile/htmlparse.h, src/internfile/mh_html.cpp,
+	src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h:
+	renamed the html charset values to stick to omega usage
+
+2007-06-19 10:28 +0000  dockes    (e66870aeadb6)
+
+	* src/internfile/htmlparse.cpp, src/internfile/htmlparse.h,
+	src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h:
+	updated html parser to omega 1.0.1 + moved entity decoder to
+	myhtmlparse to minimize amount of diffs
+
+2007-06-19 08:36 +0000  dockes    (e2533617731d)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/internfile/internfile.cpp, src/internfile/mh_html.cpp,
+	src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h,
+	src/qtgui/preview_w.cpp, src/qtgui/reslist.cpp, src/query/docseq.h,
+	src/query/docseqdb.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h,
+	src/rcldb/rcldoc.h, src/rcldb/searchdata.cpp,
+	src/sampleconf/mimeconf:
+	added open-ended field name handling
+
+2007-06-19 07:52 +0000  dockes    (73ccb629ad66)
+
+	* src/common/autoconfig.h.in, src/configure, src/configure.ac,
+	src/index/csguess.cpp, src/utils/transcode.cpp:
+	added test for iconv parm 2 constness
+
+2007-06-18 13:04 +0000  dockes    (bb1262134776)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/rcldb/searchdata.cpp,
+	src/sampleconf/mimeconf:
+	implement dynamic field name to prefix translation, query side
+
+2007-06-15 11:41 +0000  dockes    (5eccc05a2ae7)
+
+	* src/filters/rclabw, src/filters/rclsoff, src/sampleconf/mimeconf,
+	src/sampleconf/mimemap, src/sampleconf/mimeview:
+	added abiword + some oofice cleanup
+
+2007-06-15 09:25 +0000  dockes    (f5b1666a10e6)
+
+	* src/filters/rclabw: new file.
+	* src/filters/rclabw:
+	*** empty log message ***
+
+2007-06-14 08:20 +0000  dockes    (dc698e7b3c84)
+
+	* src/rcldb/rcldb.cpp:
+	removed the "weak" date, not used and not in omega anymore
+
+2007-06-13 17:03 +0000  dockes    (3d509dbc275c)
+
+	* src/qtgui/reslist.cpp:
+	textedit autext sometimes switched to plain at eol?
+
+2007-06-12 13:31 +0000  dockes    (793abec1cee4)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/preview_w.cpp,
+	src/qtgui/preview_w.h, src/qtgui/rclmain_w.cpp,
+	src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	somewhat fixed qt4 selection problems
+
+2007-06-12 10:33 +0000  dockes    (261ca6c11087)
+
+	* src/qtgui/ssearch_w.cpp:
+	adjust event handling for qt4, get esc-spc to work
+
+2007-06-12 10:32 +0000  dockes    (97c9f158e297)
+
+	* src/qtgui/plaintorich.cpp:
+	comments
+
+2007-06-12 08:50 +0000  dockes    (28d503078074)
+
+	* src/qtgui/rclmain_w.cpp:
+	*** empty log message ***
+
+2007-06-12 08:46 +0000  dockes    (d3f305e57522)
+
+	* src/query/recollq.cpp:
+	getMainConfig
+
+2007-06-11 08:33 +0000  dockes    (5542196b466a)
+
+	* src/qtgui/rclmain_w.cpp:
+	set busy cursor while search runs
+
+2007-06-11 05:51 +0000  dockes    (bf5090aed2fd)
+
+	* src/Makefile.in:
+	*** empty log message ***
+
+2007-06-11 05:49 +0000  dockes    (9327b736d7ff)
+
+	* src/Makefile.in, src/qt4gui/uifrom3:
+	*** empty log message ***
+
+2007-06-11 05:45 +0000  dockes    (cbb602782461)
+
+	* src/desktop/recoll.png, src/desktop/recoll.xcf: new file.
+	* src/desktop/recoll-searchgui.png, src/desktop/recoll-searchgui.xcf:
+	deleted file.
+	* src/desktop/recoll-searchgui.desktop, src/desktop/recoll-
+	searchgui.png, src/desktop/recoll-searchgui.xcf,
+	src/desktop/recoll.png, src/desktop/recoll.xcf,
+	src/makestaticdist.sh, src/recollinstall.in:
+	icon named recoll.png
+
+2007-06-11 05:38 +0000  dockes    (9268fba2c65c)
+
+	* src/index/indexer.cpp:
+	changed level of missing helpers message
+
+2007-06-10 12:26 +0000  dockes    (f5b6dcd36de0)
+
+	* src/mk/OpenBSD: new file.
+	* src/mk/OpenBSD:
+	*** empty log message ***
+
+2007-06-08 16:47 +0000  dockes    (96f2807957dd)
+
+	* src/common/rclconfig.h, src/index/indexer.cpp,
+	src/index/recollindex.cpp, src/mk/FreeBSD, src/qtgui/main.cpp,
+	src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	added file system usage check
+
+2007-06-08 16:46 +0000  dockes    (0c11deb1a678)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-06-08 16:46 +0000  dockes    (4f2c0d45e15b)
+
+	* src/desktop/recoll-searchgui.desktop, src/desktop/recoll-
+	searchgui.png, src/desktop/recoll-searchgui.xcf:
+	new icon
+
+2007-06-08 16:05 +0000  dockes    (6835d2fbb56c)
+
+	* src/rcldb/rcldb.h:
+	comments and ordering
+
+2007-06-08 15:30 +0000  dockes    (aeffac1f3f2d)
+
+	* src/utils/pathut.cpp, src/utils/pathut.h:
+	fsocc
+
+2007-06-08 14:01 +0000  dockes    (7c47d8aae3cc)
+
+	* src/filters/rclkwd: new file.
+	* src/filters/rclkwd, src/sampleconf/mimeview:
+	kword support
+
+2007-06-08 13:51 +0000  dockes    (53a1012a564f)
+
+	* src/filters/rcldjvu, src/filters/rcldoc, src/filters/rcldvi,
+	src/filters/rclgaim, src/filters/rcljpeg, src/filters/rcllyx,
+	src/filters/rclman, src/filters/rclmedia, src/filters/rclpdf,
+	src/filters/rclppt, src/filters/rclps, src/filters/rclrtf,
+	src/filters/rclscribus, src/filters/rclsoff, src/filters/rclxls,
+	src/filters/recfiltcommon, src/sampleconf/mimeconf,
+	src/sampleconf/mimemap:
+	kword support
+
+2007-06-08 12:33 +0000  dockes    (a56bc180327b)
+
+	* src/query/recollq.cpp:
+	added stopfile parameter
+
+2007-06-08 12:32 +0000  dockes    (7b3710f69cd0)
+
+	* src/filters/rcljpeg: new file.
+	* src/filters/rcljpeg, src/sampleconf/mimeconf:
+	rcljpeg
+
+2007-06-08 12:31 +0000  dockes    (0b20447d105e)
+
+	* src/common/rclconfig.cpp:
+	improve message about bad config
+
+2007-06-02 08:30 +0000  dockes    (dfa3e5682035)
+
+	* src/rcldb/Makefile, src/rcldb/stoplist.cpp, src/rcldb/stoplist.h:
+	new file.
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/index/indexer.cpp, src/lib/Makefile, src/lib/mkMake,
+	src/qtgui/main.cpp, src/rcldb/Makefile, src/rcldb/rcldb.cpp,
+	src/rcldb/rcldb.h, src/rcldb/searchdata.cpp, src/rcldb/stoplist.cpp,
+	src/rcldb/stoplist.h, src/utils/readfile.cpp, src/utils/readfile.h:
+	minimal experimental stopword functionality
+
+2007-06-01 05:44 +0000  dockes    (b9f3d4b61852)
+
+	* src/qtgui/preview_w.cpp:
+	preview: space and backspace bound to pgdown/pgup
+
+2007-05-30 12:31 +0000  dockes    (105744d9f609)
+
+	* src/index/indexer.cpp, src/internfile/mh_html.cpp,
+	src/internfile/mh_html.h, src/qtgui/plaintorich.cpp,
+	src/query/xadump.cpp, src/utils/transcode.cpp:
+	improve transcode error printing
+
+2007-05-30 12:30 +0000  dockes    (d4fa167018eb)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-05-30 12:30 +0000  dockes    (6027fd8afb12)
+
+	* src/rcldb/rcldb.cpp:
+	improve add_document error message printing
+
+2007-05-30 12:29 +0000  dockes    (234dc300c26b)
+
+	* src/qtgui/reslist.cpp, src/qtgui/reslist.h:
+	escape possibly not html-safe text
+
+2007-05-24 09:35 +0000  dockes    (ec684a070c43)
+
+	* src/rcldb/stemdb.cpp:
+	comment
+
+2007-05-24 07:48 +0000  dockes    (deedeff93a6e)
+
+	* src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/sort_w.cpp,
+	src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp:
+	optionally remember sorting state between invocations
+
+2007-05-24 07:47 +0000  dockes    (e6bb3bced970)
+
+	* src/configure, src/configure.ac, src/qt4gui/uifrom3:
+	make uifrom3 a makefile
+
+2007-05-23 09:19 +0000  dockes    (4f9ab7436818)
+
+	* src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h,
+	src/qtgui/preview.ui, src/qtgui/preview_w.cpp,
+	src/qtgui/preview_w.h:
+	in preview window if search line empty look for search terms
+
+2007-05-23 08:29 +0000  dockes    (644c4e20106b)
+
+	* src/internfile/internfile.cpp:
+	*** empty log message ***
+
+2007-05-23 08:28 +0000  dockes    (1927522b5826)
+
+	* src/common/rclinit.cpp, src/utils/execmd.cpp:
+	cant block sigcld globally cause qt needs it
+
+2007-05-22 08:33 +0000  dockes    (2c0d94ae674a)
+
+	* src/internfile/internfile.cpp, src/internfile/mh_html.cpp:
+	let email attachments inherit date and author from parent message
+
+2007-05-22 07:40 +0000  dockes    (fc644359e793)
+
+	* src/index/indexer.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	implemented adjustable indexing flush threshold
+
+2007-05-21 14:26 +0000  dockes    (d70d7b6988f0)
+
+	* src/qtgui/rclmain_w.cpp:
+	reopen db for each search during query
+
+2007-05-21 13:30 +0000  dockes    (7f65a405e028)
+
+	* src/common/rclinit.cpp, src/common/rclinit.h,
+	src/index/rclmonprc.cpp, src/index/rclmonrcv.cpp,
+	src/index/recollindex.cpp, src/qtgui/idxthread.cpp,
+	src/qtgui/main.cpp, src/rcldb/rcldb.cpp, src/utils/execmd.cpp,
+	src/utils/execmd.h:
+	make sure signals are only handled by the main thread. Fix bus error
+	on rclmon exit (double delete)
+
+2007-05-21 12:03 +0000  dockes    (7af2d0c361be)
+
+	* src/utils/smallut.h:
+	*** empty log message ***
+
+2007-05-21 09:00 +0000  dockes    (9ee50650bd6f)
+
+	* src/index/indexer.cpp, src/index/rclmonprc.cpp:
+	better handle aspell errors: dont exit from monitor on aux db
+	creation failure, and dont retry forever
+
+2007-05-21 07:24 +0000  dockes    (53f18ed9c2f8)
+
+	* src/VERSION, src/configure, src/configure.ac,
+	src/doc/user/usermanual.sgml, src/qt4gui/uifrom3,
+	src/sampleconf/recoll.conf.in:
+	removed --enable-qt4, rely on qmake output instead
+
+2007-05-21 06:46 +0000  dockes    (d6267bb0e30f)
+
+	* website/BUGS.txt, website/CHANGES.txt, website/devel.html,
+	website/doc.html, website/download.html, website/index.html.en,
+	website/index.html.fr:
+	*** empty log message ***
+
+2007-05-19 07:32 +0000  dockes    (cbbd4158e0a8)
+
+	* website/doc.html: new file.
+	* website/doc.html:
+	*** empty log message ***
+
+2007-05-18 12:05 +0000  dockes    (75610b300ee1 [RECOLL_1_8_2])
+
+	* src/recollinstall.in:
+	qt4 install glitches
+
+2007-05-18 11:16 +0000  dockes    (c9a0be6210be)
+
+	* src/README:
+	*** empty log message ***
+
+2007-05-18 07:49 +0000  dockes    (eaf500145dd5)
+
+	* src/VERSION:
+	1.8.2
+
+2007-05-18 07:49 +0000  dockes    (fc64434e87c0)
+
+	* packaging/debian/changelog, tests/runtests.sh, website/BUGS.txt,
+	website/CHANGES.txt, website/download.html:
+	*** empty log message ***
+
+2007-05-18 07:41 +0000  dockes    (6bec0784b8fd)
+
+	* src/doc/user/usermanual.sgml:
+	doc fix
+
+2007-05-18 07:41 +0000  dockes    (022d354a0a2f)
+
+	* src/sampleconf/recoll.conf.in:
+	add .beagle to stops
+
+2007-05-18 07:41 +0000  dockes    (451a13663a00)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/stemdb.cpp:
+	change method name deprecated in xap 1.0
+
+2007-05-18 07:40 +0000  dockes    (54bfc83a6186)
+
+	* src/query/Makefile:
+	*** empty log message ***
+
+2007-05-18 07:40 +0000  dockes    (ef599af3e2e7)
+
+	* src/configure.ac:
+	use $libdir instead of /usr/lib (64bits machs)
+
+2007-05-16 11:28 +0000  dockes    (2cced3d0aa32)
+
+	* src/qtgui/i18n/recoll_it.ts:
+	*** empty log message ***
+
+2007-04-22 07:36 +0000  dockes    (8628fca949e7)
+
+	* src/qtgui/i18n/recoll_de.ts: new file.
+	* src/qtgui/i18n/recoll_de.ts:
+	*** empty log message ***
+
+2007-03-28 19:30 +0000  dockes    (51c5bdb227cd)
+
+	* website/BUGS.txt, website/download.html, website/index.html.en,
+	website/index.html.fr:
+	*** empty log message ***
+
+2007-03-08 12:24 +0000  dockes    (0efcbb1564f2)
+
+	* packaging/FreeBSD/recoll/Makefile,
+	packaging/FreeBSD/recoll/distinfo:
+	1.8.1
+
+2007-03-08 12:04 +0000  dockes    (813c82bcc951 [RECOLL_1_8_1])
+
+	* packaging/FreeBSD/recoll/Makefile,
+	packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg-
+	plist, packaging/debian/changelog, packaging/rpm/recoll.spec,
+	packaging/rpm/recollfedora.spec, packaging/rpm/recollmdk.spec,
+	src/VERSION, src/makestaticdist.sh, website/BUGS.txt,
+	website/CHANGES.txt, website/download.html:
+	version 1.8.1 ?
+
+2007-02-20 09:30 +0000  dockes    (817cdab71c1c [RECOLL_1_8_0])
+
+	* src/recollinstall.in:
+	go back to not using xdg
+
+2007-02-20 07:57 +0000  dockes    (d1f1b31e4a58)
+
+	* website/index.html.en, website/index.html.fr: new file.
+	* website/index.html: deleted file.
+	* packaging/debian/changelog, website/BUGS.txt, website/CHANGES.txt,
+	website/credits.html, website/download.html, website/features.html,
+	website/index.html, website/index.html.en, website/index.html.fr:
+	*** empty log message ***
+
+2007-02-20 07:43 +0000  dockes    (1f4b07f4cb62)
+
+	* src/qtgui/recoll.pro.in:
+	*** empty log message ***
+
+2007-02-20 07:33 +0000  dockes    (dc922603c639)
+
+	* src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_it.ts,
+	src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts:
+	*** empty log message ***
+
+2007-02-20 07:19 +0000  dockes    (d6b63dc759cd)
+
+	* src/INSTALL, src/README:
+	*** empty log message ***
+
+2007-02-19 18:15 +0000  dockes    (a1331ff143f7)
+
+	* src/qtgui/preview_w.cpp, src/qtgui/preview_w.h:
+	make shift-arrow in preview work with qt4 and avoid reentrancy while
+	loading a file
+
+2007-02-19 18:14 +0000  dockes    (66c79bcff30e)
+
+	* src/utils/execmd.cpp:
+	block sigcld, it sometimes causes eintrs during the select() call
+
+2007-02-19 18:05 +0000  dockes    (db9e1830a040)
+
+	* src/internfile/internfile.cpp:
+	check file name not empty on return from uncomp exec
+
+2007-02-19 16:28 +0000  dockes    (19982a948347)
+
+	* src/qtgui/spell_w.cpp:
+	stemming language choice was not observed in term explorer
+
+2007-02-19 16:10 +0000  dockes    (26815f6c7ce0)
+
+	* src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h:
+	cleanup ign file types handling/saving
+
+2007-02-14 15:02 +0000  dockes    (714300cb7780)
+
+	* tests/empty/empty.sh, tests/empty/empty.txt, tests/html/html.sh,
+	tests/html/html.txt, tests/images/images.sh,
+	tests/images/images.txt, tests/koi8r/koi8r.sh,
+	tests/koi8r/koi8r.txt, tests/mail/mail.sh, tests/mail/mail.txt,
+	tests/notypes/notypes.sh, tests/notypes/notypes.txt,
+	tests/rfc2231/rfc2231.sh, tests/rfc2231/rfc2231.txt,
+	tests/special/special.sh, tests/special/special.txt,
+	tests/txt/txt.sh, tests/txt/txt.txt, tests/utf8/utf8.sh,
+	tests/utf8/utf8.txt: new file.
+	* tests/empty/empty.sh, tests/empty/empty.txt, tests/html/html.sh,
+	tests/html/html.txt, tests/images/images.sh,
+	tests/images/images.txt, tests/koi8r/koi8r.sh,
+	tests/koi8r/koi8r.txt, tests/lyx/lyx.txt, tests/mail/mail.sh,
+	tests/mail/mail.txt, tests/notypes/notypes.sh,
+	tests/notypes/notypes.txt, tests/rfc2231/rfc2231.sh,
+	tests/rfc2231/rfc2231.txt, tests/special/special.sh,
+	tests/special/special.txt, tests/txt/txt.sh, tests/txt/txt.txt,
+	tests/utf8/utf8.sh, tests/utf8/utf8.txt:
+	*** empty log message ***
+
+2007-02-14 11:52 +0000  dockes    (b3f3859ce5e5)
+
+	* tests/boolean/boolean.sh, tests/boolean/boolean.txt,
+	tests/delete/delete.sh, tests/delete/delete.txt,
+	tests/dirwithblanks/dirwithblanks.sh,
+	tests/dirwithblanks/dirwithblanks.txt, tests/djvu/djvu.sh,
+	tests/djvu/djvu.txt, tests/dvi/dvi.sh, tests/dvi/dvi.txt,
+	tests/lyx/lyx.sh, tests/lyx/lyx.txt, tests/media/media.sh,
+	tests/media/media.txt, tests/msword/msword.sh,
+	tests/msword/msword.txt, tests/ooff/ooff.sh, tests/ooff/ooff.txt,
+	tests/pdf/pdf.sh, tests/pdf/pdf.txt, tests/postscript/postscript.sh,
+	tests/postscript/postscript.txt, tests/ppt/ppt.sh,
+	tests/ppt/ppt.txt, tests/rtf/rtf.sh, tests/rtf/rtf.txt,
+	tests/scribus/scribus.sh, tests/scribus/scribus.txt,
+	tests/xls/xls.sh, tests/xls/xls.txt: new file.
+	* tests/Maildir1/Maildir1.txt, tests/andor/andor.txt,
+	tests/badsuffs1/badsuffs1.txt, tests/boolean/boolean.sh,
+	tests/boolean/boolean.txt, tests/delete/delete.sh,
+	tests/delete/delete.txt, tests/dirwithblanks/dirwithblanks.sh,
+	tests/dirwithblanks/dirwithblanks.txt, tests/djvu/djvu.sh,
+	tests/djvu/djvu.txt, tests/dvi/dvi.sh, tests/dvi/dvi.txt,
+	tests/lyx/lyx.sh, tests/lyx/lyx.txt, tests/media/media.sh,
+	tests/media/media.txt, tests/msword/msword.sh,
+	tests/msword/msword.txt, tests/ooff/ooff.sh, tests/ooff/ooff.txt,
+	tests/pdf/pdf.sh, tests/pdf/pdf.txt, tests/postscript/postscript.sh,
+	tests/postscript/postscript.txt, tests/ppt/ppt.sh,
+	tests/ppt/ppt.txt, tests/rtf/rtf.sh, tests/rtf/rtf.txt,
+	tests/scribus/scribus.sh, tests/scribus/scribus.txt,
+	tests/shared.sh, tests/skipped/skipped.sh,
+	tests/skipped/skipped.txt, tests/xls/xls.sh, tests/xls/xls.txt:
+	*** empty log message ***
+
+2007-02-14 10:10 +0000  dockes    (04c3156fd4dd)
+
+	* src/doc/user/usermanual.sgml, src/makestaticdist.sh,
+	src/qtgui/guiutils.cpp, src/qtgui/guiutils.h,
+	src/qtgui/rclmain_w.cpp, src/qtgui/uiprefs.ui,
+	src/qtgui/uiprefs_w.cpp, src/recollinstall.in,
+	src/sampleconf/mimeview:
+	add user pref to use xdg-open for all document edits
+
+2007-02-14 10:09 +0000  dockes    (7886dd99d419)
+
+	* src/rcldb/rcldb.cpp:
+	during indexing use simple file name as title if this is empty. This
+	allows storing the sfn for subdocs for which the url sfn doesnt make
+	sense as title
+
+2007-02-14 10:08 +0000  dockes    (fb42e10e5a7b)
+
+	* src/query/recollq.cpp:
+	adjust format to help the test set scripts
+
+2007-02-14 08:54 +0000  dockes    (5e02666b38db)
+
+	* src/desktop/xdg-utils-1.0.1/scripts/xdg-open: new file.
+	* src/desktop/xdg-utils-1.0.1/scripts/xdg-open:
+	*** empty log message ***
+
+2007-02-14 08:16 +0000  dockes    (eb0fd52ef15a)
+
+	* tests/Maildir/Maildir.sh, tests/Maildir/Maildir.txt,
+	tests/Maildir1/Maildir1.sh, tests/Maildir1/Maildir1.txt,
+	tests/andor/andor.sh, tests/andor/andor.txt,
+	tests/badsuffs/badsuffs.sh, tests/badsuffs/badsuffs.txt,
+	tests/badsuffs1/badsuffs1.sh, tests/badsuffs1/badsuffs1.txt,
+	tests/runtests.sh, tests/shared.sh, tests/skipped/skipped.sh,
+	tests/skipped/skipped.txt: new file.
+	* tests/Maildir/Maildir.sh, tests/Maildir/Maildir.txt,
+	tests/Maildir1/Maildir1.sh, tests/Maildir1/Maildir1.txt,
+	tests/andor/andor.sh, tests/andor/andor.txt,
+	tests/badsuffs/badsuffs.sh, tests/badsuffs/badsuffs.txt,
+	tests/badsuffs1/badsuffs1.sh, tests/badsuffs1/badsuffs1.txt,
+	tests/runtests.sh, tests/shared.sh, tests/skipped/skipped.sh,
+	tests/skipped/skipped.txt:
+	*** empty log message ***
+
+2007-02-13 10:58 +0000  dockes    (19c29e100995)
+
+	* src/query/wasatorcl.cpp, src/rcldb/searchdata.cpp,
+	src/rcldb/searchdata.h:
+	propagate wasa nostem modifier
+
+2007-02-12 18:16 +0000  dockes    (bf3060f2e259)
+
+	* src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h:
+	add wasabi modifiers
+
+2007-02-12 18:14 +0000  dockes    (6ae625065d64)
+
+	* src/qtgui/guiutils.cpp:
+	dont set Helvetica as default font
+
+2007-02-08 17:05 +0000  dockes    (f23e18da0362)
+
+	* src/index/indexer.cpp, src/index/indexer.h,
+	src/internfile/internfile.cpp, src/internfile/internfile.h,
+	src/qtgui/preview_w.cpp, src/utils/smallut.cpp, src/utils/smallut.h:
+	improve handling of missing helpers messages
+
+2007-02-08 17:03 +0000  dockes    (f53e952b71cd)
+
+	* src/filters/rcldvi:
+	typos
+
+2007-02-08 12:25 +0000  dockes    (ba982598a66f)
+
+	* src/internfile/internfile.h, src/query/recollq.cpp:
+	clarify temp dir usage in internfile
+
+2007-02-08 09:03 +0000  dockes    (876ec27bd9c0)
+
+	* src/qtgui/reslist.cpp, src/qtgui/uiprefs_w.cpp,
+	src/qtgui/uiprefs_w.h:
+	qt4 compilation glitches
+
+2007-02-07 17:18 +0000  dockes    (2f05854b010a)
+
+	* src/filters/injectcommon.sh, src/filters/recfiltcommon: new file.
+	* src/filters/injectcommon.sh, src/filters/recfiltcommon:
+	*** empty log message ***
+
+2007-02-07 17:17 +0000  dockes    (39e4d9e07461)
+
+	* src/recoll.desktop, src/recoll.png, src/recoll.xcf: deleted file.
+	* src/recoll.desktop, src/recoll.png, src/recoll.xcf,
+	src/recollinstall.in:
+	use xdg scripts to install desktop file and icon
+
+2007-02-07 17:17 +0000  dockes    (3161a2dabc0a)
+
+	* src/common/rclconfig.cpp, src/doc/user/usermanual.sgml:
+	dont autocreate config specified with -c or RECOLL_CONFDIR
+
+2007-02-07 16:31 +0000  dockes    (f89cbedba93f)
+
+	* src/desktop/recoll-searchgui.desktop, src/desktop/recoll-
+	searchgui.png, src/desktop/recoll-searchgui.xcf, src/desktop/xdg-
+	utils-1.0.1/LICENSE, src/desktop/xdg-utils-1.0.1/scripts/xdg-
+	desktop-menu, src/desktop/xdg-utils-1.0.1/scripts/xdg-icon-resource:
+	new file.
+	* src/desktop/recoll-searchgui.desktop, src/desktop/recoll-
+	searchgui.png, src/desktop/recoll-searchgui.xcf, src/desktop/xdg-
+	utils-1.0.1/LICENSE, src/desktop/xdg-utils-1.0.1/scripts/xdg-
+	desktop-menu, src/desktop/xdg-utils-1.0.1/scripts/xdg-icon-resource,
+	src/query/recollq.cpp:
+	*** empty log message ***
+
+2007-02-07 16:31 +0000  dockes    (2494c5157c22)
+
+	* src/aspell/rclaspell.cpp:
+	improve db creation error message
+
+2007-02-07 12:00 +0000  dockes    (3c02ca709886)
+
+	* src/query/recollq.cpp: new file.
+	* src/query/Makefile, src/query/recollq.cpp, src/query/wasatorcl.cpp,
+	src/query/wasatorcl.h:
+	recollq
+
+2007-02-06 18:01 +0000  dockes    (1992c71741c0)
+
+	* src/index/indexer.cpp, src/internfile/internfile.cpp,
+	src/internfile/internfile.h, src/internfile/mh_exec.cpp,
+	src/qtgui/preview_w.cpp:
+	arrange for error info about missing helpers to trickle up to the
+	user
+
+2007-02-06 18:01 +0000  dockes    (d5e12cec5aeb)
+
+	* src/sampleconf/mimeconf, src/sampleconf/mimemap:
+	added config+filter for man pages
+
+2007-02-06 15:08 +0000  dockes    (ef2eef3c33e9)
+
+	* src/filters/rclman: new file.
+	* src/filters/rcldjvu, src/filters/rcldoc, src/filters/rcldvi,
+	src/filters/rclgaim, src/filters/rcllyx, src/filters/rclman,
+	src/filters/rclmedia, src/filters/rclpdf, src/filters/rclppt,
+	src/filters/rclps, src/filters/rclrtf, src/filters/rclscribus,
+	src/filters/rclsoff, src/filters/rclxls:
+	factored out filter script common code
+
+2007-02-06 14:18 +0000  dockes    (7812fc3157a4)
+
+	* src/common/rclconfig.cpp, src/utils/pathut.cpp, src/utils/pathut.h:
+	make sure the -c argument is turned absolute before use
+
+2007-02-06 10:19 +0000  dockes    (243d1fffdfb9)
+
+	* src/qtgui/ssearch_w.cpp:
+	no space in query -> phrase
+
+2007-02-06 10:18 +0000  dockes    (d1b8dd6a7182)
+
+	* src/qtgui/reslist.cpp:
+	try to make sure that the old reslist is cleared while searching
+
+2007-02-06 10:18 +0000  dockes    (24163d1804e5)
+
+	* src/qt4gui/uifrom3:
+	link images/ from qtgui to qt4gui
+
+2007-02-03 16:46 +0000  dockes    (d27849ad572f)
+
+	* website/styles/style.css:
+	*** empty log message ***
+
+2007-02-02 10:27 +0000  dockes    (3c82d463b36c)
+
+	* src/doc/user/usermanual.sgml:
+	add skippedPaths and daemSkippedPaths config variables
+
+2007-02-02 10:12 +0000  dockes    (0232602ba055)
+
+	* src/common/rclconfig.cpp, src/common/rclconfig.h,
+	src/index/indexer.cpp, src/index/rclmonrcv.cpp,
+	src/utils/fstreewalk.cpp:
+	add skippedPaths and daemSkippedPaths config variables
+
+2007-02-02 10:10 +0000  dockes    (12a2a255dedc)
+
+	* src/rcldb/rcldb.cpp, src/rcldb/rcldb.h:
+	sort and uniquify termMatch results out of stem expansion
+
+2007-02-02 10:09 +0000  dockes    (344b11ebced1)
+
+	* src/index/recollindex.cpp:
+	do x11 check between sleeping and starting in recollindex -m
+
+2007-02-02 10:06 +0000  dockes    (3a9bb20130c8)
+
+	* src/doc/user/usermanual-italian.html: new file.
+	* src/doc/user/usermanual-italian.html, src/qtgui/i18n/recoll_it.ts:
+	*** empty log message ***
+
+2007-02-02 10:06 +0000  dockes    (9a6092dbecea)
+
+	* src/lib/Makefile, src/lib/mkMake:
+	fix $(depth) usage for easier kio compilation
+
+2007-02-02 10:05 +0000  dockes    (a645eeae729a)
+
+	* src/doc/user/usermanual.sgml:
+	added config examples
+
+2007-02-02 10:01 +0000  dockes    (a0640e49ab3a)
+
+	* src/recollinstall.in:
+	removed old filter in examples cleanup
+
+2007-02-01 15:01 +0000  dockes    (db53657c868d)
+
+	* src/aspell/rclaspell.cpp, src/mk/localdefs.in:
+	use configure libdir to search for aspell lib (mainly for 64 bits
+	machines)
+
+2007-02-01 12:43 +0000  dockes    (7f3d33405e53)
+
+	* src/kde/kioslave/recoll/Makefile,
+	src/kde/kioslave/recoll/kio_recoll.cpp:
+	fixed kio compilation. Dont know if it works
+
+2007-01-30 11:39 +0000  dockes    (1aa8e8c3d93a)
+
+	* src/filters/rcldjvu, src/filters/rcldoc, src/filters/rcldvi,
+	src/filters/rclpdf, src/filters/rclps, src/filters/rclrtf,
+	src/filters/rclsoff:
+	hide awk BEGIN statements - make debian linda happy
+
+2007-01-29 13:51 +0000  dockes    (f207a83f0617)
+
+	* src/rcldb/searchdata.cpp:
+	more field name synonyms
+
+2007-01-25 15:50 +0000  dockes    (ba53fd450dc5)
+
+	* src/rcldb/searchdata.cpp, src/rcldb/searchdata.h:
+	better wildcards handling. Tuning of user term boosting
+
+2007-01-25 15:47 +0000  dockes    (026e24e9aafc)
+
+	* src/doc/user/usermanual.sgml:
+	*** empty log message ***
+
+2007-01-25 15:47 +0000  dockes    (31cd60d81a3a)
+
+	* src/rcldb/rcldb.cpp:
+	dont explicitely anchor regexp in termMatch
+
+2007-01-25 15:46 +0000  dockes    (8c7afe9df6fb)
+
+	* src/qtgui/ssearch_w.cpp:
+	Dont add auto phrase if there are wildcards
+
+2007-01-25 15:45 +0000  dockes    (d35369f54699)
+
+	* src/query/wasatorcl.cpp:
+	comment
+
+2007-01-25 15:40 +0000  dockes    (2d7b13ebd2c8)
+
+	* src/common/textsplit.cpp:
+	[] are also wildcard chars
+
+2007-01-25 12:04 +0000  dockes    (27310036f46c)
+
+	* src/qtgui/i18n/recoll_it.ts:
+	*** empty log message ***
+
+2007-01-25 08:27 +0000  dockes    (876d5192bdde)
+
+	* src/qtgui/i18n/recoll_it.ts: new file.
+	* src/qtgui/i18n/recoll_it.ts:
+	*** empty log message ***
+
+2007-01-24 12:40 +0000  dockes    (dd470677dbf2)
+
+	* src/qtgui/guiutils.cpp:
+	make AND the initial default for ssearch
+
+2007-01-24 11:20 +0000  dockes    (623c6533e0f0)
+
+	* src/qtgui/uiprefs.ui, src/qtgui/viewaction.ui:
+	change MyDialog and Form1 dialog captions
+
+2007-01-24 11:15 +0000  dockes    (9dc93d749ea8)
+
+	* src/filters/rclscribus:
+	transate \r to 
(for older scribus files) + +2007-01-24 11:00 +0000 dockes (7ea73b206760) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap: + scribus scd files + +2007-01-23 07:23 +0000 dockes (0f9e96c72d1c) + + * src/filters/rcllyx: + *** empty log message *** + +2007-01-23 07:22 +0000 dockes (5fc9550be90c) + + * src/filters/rcllyx: + *** empty log message *** + +2007-01-23 07:16 +0000 dockes (55734c5d16c2) + + * src/filters/rcllyx: + *** empty log message *** + +2007-01-23 07:14 +0000 dockes (dafabbcdaf1a) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/mimeview: + lyx filter + +2007-01-23 07:14 +0000 dockes (d5ac3c0cf64f) + + * src/filters/rcllyx: new file. + * src/filters/rcllyx: + lyx filter + +2007-01-22 16:34 +0000 dockes (e76e39a890d0) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap: + added scribus support + +2007-01-22 16:32 +0000 dockes (0b142f40e0c7) + + * src/filters/rclscribus: new file. + * src/filters/rclscribus: + added scribus support + +2007-01-21 16:41 +0000 dockes (8e06e0f7914e) + + * src/filters/rclsoff: + fix shell syntax for debian + +2007-01-19 15:22 +0000 dockes (084098d57a50) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview_w.cpp, src/qtgui/preview_w.h, + src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp, src/qtgui/reslist.h, + src/query/docseq.h, src/query/docseqdb.cpp, src/query/docseqdb.h, + src/query/docseqhist.h, src/query/sortseq.cpp, src/query/sortseq.h: + try to limit the places which use Rcl:: stuff + +2007-01-19 15:19 +0000 dockes (1d1bdf98f176) + + * src/rcldb/stemdb.cpp: + make sure that both the user term and the stem are in the expanded + list + +2007-01-19 10:32 +0000 dockes (757f49c23d93) + + * src/query/docseqdb.cpp, src/query/docseqdb.h, + src/query/docseqhist.cpp, src/query/docseqhist.h: new file. + * src/lib/Makefile, src/lib/mkMake, src/qtgui/rclmain_w.cpp, + src/qtgui/reslist.cpp, src/qtgui/ssearch_w.cpp, + src/query/docseq.cpp, src/query/docseq.h, src/query/docseqdb.cpp, + src/query/docseqdb.h, src/query/docseqhist.cpp, + src/query/docseqhist.h, src/query/sortseq.cpp, src/query/sortseq.h: + cleanup docseq, arrange things so that we can page reslist past the + initial result count estimate if there are more + +2007-01-19 10:23 +0000 dockes (d4ecd356406a) + + * src/rcldb/searchdata.cpp: + the relevance-boosted original term needs a prefix too + +2007-01-19 10:23 +0000 dockes (cacb9b50f1cf) + + * src/rcldb/rcldb.cpp: + adjust makeAbstract for prefixed terms + +2007-01-19 10:22 +0000 dockes (95d569102c37) + + * src/query/wasatorcl.cpp, src/query/wasatorcl.h: + add direct qstring to rcl function + +2007-01-18 14:23 +0000 dockes (157d8676b256) + + * src/utils/mimeparse.cpp: + debug msg + +2007-01-18 12:09 +0000 dockes (b0647b310dec) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/rcldb/searchdata.cpp: + handle wildcards in search terms + +2007-01-17 14:06 +0000 dockes (65d2617d690c) + + * src/query/Makefile, src/query/wasatorcl.cpp: + *** empty log message *** + +2007-01-17 13:53 +0000 dockes (82c00cf9d054) + + * src/internfile/internfile.cpp, src/internfile/mh_html.cpp, + src/internfile/mh_mail.cpp, src/internfile/myhtmlparse.cpp, + src/internfile/myhtmlparse.h, src/lib/Makefile, src/lib/mkMake, + src/query/Makefile, src/query/wasastringtoquery.cpp, + src/query/wasastringtoquery.h, src/query/wasatorcl.cpp, + src/rcldb/rcldb.cpp, src/rcldb/rcldoc.h, src/rcldb/searchdata.cpp, + src/rcldb/searchdata.h: + added field/prefixes for author and title + command line query + language + +2007-01-16 10:58 +0000 dockes (f56d8a303798) + + * src/sampleconf/recoll.conf.in: + add recollrc to skipped + +2007-01-16 10:58 +0000 dockes (a28d7ea5359b) + + * website/BUGS.txt, website/CHANGES.txt, website/download.html, + website/index.html: + 1.7.5 + +2007-01-16 10:58 +0000 dockes (83b10dc2e5ea) + + * src/bincimapmime/trbinc.cc, src/utils/debuglog.cpp: + wrong copyrights + +2007-01-16 10:56 +0000 dockes (e51d7ee21ffd) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/rpm/recoll.spec, + packaging/rpm/recollfedora.spec, packaging/rpm/recollmdk.spec: + 1.7.5 packaging + +2007-01-16 09:22 +0000 dockes (7f8fea3bed13) + + * packaging/debian/manpages: deleted file. + * packaging/debian/changelog, packaging/debian/control, + packaging/debian/copyright, packaging/debian/manpages, + packaging/debian/rules: + 2007-01-12 comments + +2007-01-15 19:16 +0000 dockes (740528a1cd7d) + + * packaging/debian/dirs: deleted file. + * packaging/debian/dirs: + *** empty log message *** + +2007-01-15 13:06 +0000 dockes (12e31e690f9e) + + * src/internfile/internfile.cpp, src/internfile/internfile.h: + dont stop processing a complex document on the first next_document + error: pop level and go on + +2007-01-15 13:03 +0000 dockes (6d3f8a71e602) + + * src/doc/user/usermanual.sgml: + *** empty log message *** + +2007-01-13 15:21 +0000 dockes (b04adc5188d5) + + * src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs_w.cpp, src/qtgui/uiprefs_w.h: + improved external index dialog with listview + +2007-01-13 14:41 +0000 dockes (f9567f0fed32) + + * src/query/xadump.cpp: + add option to dump raw terms + +2007-01-13 10:28 +0000 dockes (fc890008108f) + + * src/internfile/mh_mail.cpp: + handle multipart/signed + +2007-01-12 09:01 +0000 dockes (1782d39f9d4d) + + * src/qtgui/reslist.cpp: + Use sample from Rcl::Doc if makeAbstract() fails + +2007-01-12 06:42 +0000 dockes (8223a4aa9ad4) + + * packaging/debian/copyright: + include gpl statement + +2007-01-10 16:03 +0000 dockes (66247acdb470) + + * packaging/debian/changelog, packaging/debian/compat, + packaging/debian/control, packaging/debian/copyright, + packaging/debian/dirs, packaging/debian/docs, + packaging/debian/manpages, packaging/debian/menu, + packaging/debian/rules, packaging/debian/watch: new file. + * packaging/debian/changelog, packaging/debian/compat, + packaging/debian/control, packaging/debian/copyright, + packaging/debian/dirs, packaging/debian/docs, + packaging/debian/manpages, packaging/debian/menu, + packaging/debian/rules, packaging/debian/watch, src/Makefile.in, + src/VERSION: + *** empty log message *** + +2007-01-10 12:27 +0000 dockes (733bc11b5526) + + * packaging/FreeBSD/recoll/Makefile: + *** empty log message *** + +2007-01-09 15:34 +0000 dockes (9583ff723edf [RECOLL_1_7_3]) + + * packaging/rpm/recollfedora.spec: new file. + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist, + packaging/rpm/recoll.spec, packaging/rpm/recollfedora.spec, + packaging/rpm/recollmdk.spec: + 1.7.3 + +2007-01-09 14:39 +0000 dockes (f108471cd099) + + * website/BUGS.txt, website/CHANGES.txt, website/download.html: + 1.7.3 + +2007-01-09 07:25 +0000 dockes (e0c1d14a73c5) + + * src/VERSION: + *** empty log message *** + +2007-01-09 07:25 +0000 dockes (f06dbc019ff4) + + * src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts: + french messages + +2007-01-08 15:21 +0000 dockes (906e56e99e81) + + * src/VERSION, src/qtgui/main.cpp: + initial indexation with gui would not work + +2007-01-08 13:00 +0000 dockes (44d2b5d58ac6 [RECOLL_1_7_1]) + + * src/VERSION: + 1.7.1 + +2007-01-08 12:43 +0000 dockes (2cb748432b10) + + * src/qtgui/advsearch.ui: + lost sizers? + +2007-01-08 10:11 +0000 dockes (67c4375292e5) + + * src/qtgui/rclmain_w.cpp: + fix the previous icon fix + +2007-01-08 10:01 +0000 dockes (8eb24fe9db4f) + + * src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/reslist.cpp, src/qtgui/reslist.h: + reslist menu openParent opens containing folder if not a subdoc + +2007-01-08 09:40 +0000 dockes (b38401a650c3) + + * src/qtgui/uiprefs.ui: + fix resizing of prefs dialog + +2007-01-08 07:02 +0000 dockes (5a2fb87a2c55) + + * src/qtgui/rclmain_w.cpp: + get rid of messages about missing d_xxx images + +2007-01-08 07:01 +0000 dockes (8a2c6d2cba46) + + * src/qtgui/reslist.cpp: + synthetic abstracts not displayed + +2006-12-24 08:07 +0000 dockes (e42dca990bea [RECOLL_1_7_0]) + + * src/Makefile.in: + better cleanup -> 1.7.0 NOW + +2006-12-24 08:02 +0000 dockes (916d6e831996 [RECOLL_1_7_2]) + + * packaging/FreeBSD/recoll/pkg-plist, src/excludefile, + website/BUGS.txt, website/CHANGES.txt, website/download.html, + website/features.html, website/index.html, website/pics/index.html, + website/rclidxfmt.html: + 1.7.0 + +2006-12-24 07:53 +0000 dockes (b37a6e3566b9) + + * src/INSTALL, src/README, src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-12-24 07:40 +0000 dockes (69573fe97b89) + + * src/configure, src/configure.ac, src/doc/man/recollindex.1, + src/doc/user/usermanual.sgml, src/index/rclmon.h, + src/index/rclmonprc.cpp, src/index/recollindex.cpp: + option -x to disable x11 session monitoring + +2006-12-23 13:07 +0000 dockes (fb731b7d3ab1) + + * src/configure, src/configure.ac, src/index/Makefile, + src/index/rclmonprc.cpp, src/lib/Makefile, src/lib/mkMake, + src/mk/localdefs.in, src/utils/pathut.cpp: + x11 session end detection + +2006-12-23 12:23 +0000 dockes (00532204c17f) + + * src/utils/x11mon.cpp, src/utils/x11mon.h: new file. + * src/utils/Makefile, src/utils/x11mon.cpp, src/utils/x11mon.h: + *** empty log message *** + +2006-12-22 16:48 +0000 dockes (ee878b9d311e) + + * src/qt4gui/recoll.qrc, src/qtgui/rclmain.ui, + src/qtgui/rclmain_w.cpp, src/qtgui/spell_w.cpp: + get all icons out of .ui files to avoid qt4 startup messages + +2006-12-22 11:01 +0000 dockes (078acb3ab4fd) + + * src/doc/man/recollindex.1, src/doc/user/usermanual.sgml, + src/qtgui/spell_w.h: + *** empty log message *** + +2006-12-21 10:08 +0000 dockes (d36d26d5b5d5) + + * src/index/rclmonprc.cpp: + try to be more responsive to interruptions + +2006-12-21 09:22 +0000 dockes (818387de5d92) + + * src/index/indexer.cpp, src/index/rclmonrcv.cpp, + src/index/recollindex.cpp, src/sampleconf/mimemap, + src/utils/fstreewalk.cpp: + always skip indexing of confdir and dbdir. start index monitor with + normal indexing pass + +2006-12-21 09:21 +0000 dockes (13c7229ee6dc) + + * src/qtgui/advsearch.ui, src/qtgui/ssearchb.ui: + tooltips + +2006-12-21 08:22 +0000 dockes (c1e9892c3ba1) + + * src/utils/fstreewalk.cpp, src/utils/fstreewalk.h: + add skipped paths + +2006-12-20 14:28 +0000 dockes (f580e9aa026a) + + * src/internfile/internfile.cpp: + msg + +2006-12-20 14:09 +0000 dockes (e3d7f975546f) + + * src/qtgui/preview_w.cpp: + try to improve error message for internfile failure + +2006-12-20 13:55 +0000 dockes (0a07075dd464) + + * src/qtgui/preview_w.cpp, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/reslist.cpp, src/qtgui/reslist.h: + reslist: added menu entry to see parent doc of attachment + +2006-12-20 13:12 +0000 dockes (733a59947cfb) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/guiutils.cpp, + src/qtgui/guiutils.h, src/sampleconf/mimeconf: + mime categories + +2006-12-20 10:47 +0000 dockes (591625eb1d38) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-12-20 09:54 +0000 dockes (c563fb138893) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/doc/user/usermanual.sgml, src/index/mimetype.cpp: + changed stopsuffixes processing + +2006-12-20 09:41 +0000 dockes (64488c2687be) + + * src/index/recollindex.cpp: + opt -e + +2006-12-19 12:38 +0000 dockes (6d4a0c0f8cc3) + + * src/qtgui/spell_w.cpp: + qt4 + +2006-12-19 12:11 +0000 dockes (a3e7c86f79d7) + + * src/qtgui/spell.ui, src/qtgui/spell_w.cpp, src/qtgui/spell_w.h, + src/qtgui/ssearch_w.cpp, src/qtgui/viewaction.ui, + src/qtgui/viewaction_w.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/rcldb/searchdata.cpp, src/rcldb/stemdb.cpp, src/rcldb/stemdb.h, + src/utils/smallut.cpp, src/utils/smallut.h: + merge stemExpand into termExpand. return term frequencies from there + and display in spellW + +2006-12-19 08:40 +0000 dockes (3bbff3062a89) + + * src/common/rclconfig.cpp, src/index/indexer.cpp, + src/index/mimetype.cpp, src/index/mimetype.h, + src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mimehandler.cpp, src/qtgui/preview_w.cpp, + src/sampleconf/mimeconf, src/sampleconf/mimeview: + index directory names + +2006-12-19 07:48 +0000 dockes (7301c237649a) + + * src/qtgui/mtpics/folder.png: new file. + * src/qtgui/mtpics/folder.png: + *** empty log message *** + +2006-12-18 16:45 +0000 dockes (0a640477a752) + + * src/qt4gui/recoll.pro.in, src/qtgui/viewaction.ui, + src/qtgui/viewaction_w.cpp, src/qtgui/viewaction_w.h: + qt4 + +2006-12-18 12:06 +0000 dockes (5f17ab347621) + + * src/doc/user/usermanual.sgml, src/internfile/mh_mail.cpp, + src/utils/smallut.cpp, src/utils/smallut.h: + mh_mail needs to lowercase contentypes + +2006-12-18 12:05 +0000 dockes (03363b562546) + + * src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/viewaction_w.cpp, src/qtgui/viewaction_w.h: + dblclick to edit in viewAction + +2006-12-16 15:39 +0000 dockes (a3027dd4b920) + + * src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mh_html.h, src/internfile/mh_mail.cpp, + src/internfile/mh_mail.h, src/internfile/mh_text.h, + src/internfile/mimehandler.h, src/qtgui/main.cpp, + src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h: + mail attachments sort of ok + +2006-12-16 15:31 +0000 dockes (7d335e595c2b) + + * src/utils/pathut.cpp, src/utils/pathut.h: + added TempFile class + +2006-12-16 15:30 +0000 dockes (89fed05a6ace) + + * src/internfile/Filter.h: + *** empty log message *** + +2006-12-16 15:30 +0000 dockes (5f74c84fa800) + + * src/index/indexer.cpp: + dont clobber utf8fn from filter + +2006-12-16 15:30 +0000 dockes (b5f77fb6530b) + + * src/common/rclconfig.cpp, src/common/rclconfig.h: + added getSuffixFromMimeType() + +2006-12-16 07:15 +0000 dockes (ef72575e285c) + + * src/internfile/Filter.h: + *** empty log message *** + +2006-12-15 16:33 +0000 dockes (df6232340341) + + * src/index/indexer.cpp, src/internfile/Filter.h, + src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mh_html.cpp, src/internfile/mh_mail.cpp, + src/internfile/mh_mail.h, src/internfile/myhtmlparse.h: + test data indexing result same terms as 1.6.3 + +2006-12-15 12:40 +0000 dockes (5156a319f219) + + * src/internfile/Filter.h, src/internfile/mh_mbox.cpp, + src/internfile/mh_mbox.h: new file. + * src/internfile/Filter.h, src/internfile/Makefile, + src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mh_exec.cpp, src/internfile/mh_exec.h, + src/internfile/mh_html.cpp, src/internfile/mh_html.h, + src/internfile/mh_mail.cpp, src/internfile/mh_mail.h, + src/internfile/mh_mbox.cpp, src/internfile/mh_mbox.h, + src/internfile/mh_text.cpp, src/internfile/mh_text.h, + src/internfile/mh_unknown.h, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h, src/internfile/myhtmlparse.h, + src/lib/Makefile, src/lib/mkMake, src/utils/smallut.cpp, + src/utils/smallut.h: + Dijon filters 1st step: mostly working needs check and optim + +2006-12-14 14:54 +0000 dockes (2f7d4fb90b31) + + * src/rcldb/rcldoc.h: new file. + * src/rcldb/rcldb.h, src/rcldb/rcldoc.h: + split rcldb.h -> rcldoc.h + +2006-12-14 13:53 +0000 dockes (839454238284) + + * src/qtgui/viewaction.ui, src/qtgui/viewaction_w.cpp, + src/qtgui/viewaction_w.h, src/sampleconf/mimeview: new file. + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/doc/user/usermanual.sgml, src/index/indexer.cpp, + src/qtgui/preview_w.cpp, src/qtgui/rclmain_w.cpp, + src/qtgui/recoll.pro.in, src/qtgui/ssearch_w.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp, + src/qtgui/uiprefs_w.h, src/qtgui/viewaction.ui, + src/qtgui/viewaction_w.cpp, src/qtgui/viewaction_w.h, + src/recollinstall.in, src/sampleconf/mimeconf, + src/sampleconf/mimeview, src/utils/Makefile, src/utils/conftree.cpp, + src/utils/conftree.h, src/utils/execmd.cpp, src/utils/execmd.h, + src/utils/pathut.cpp, src/utils/pathut.h, src/utils/smallut.cpp, + src/utils/smallut.h: + created mimeview and the viewer conf edit dialog + +2006-12-13 09:13 +0000 dockes (ca4c21f5ad44) + + * src/common/rclconfig.cpp, src/internfile/internfile.cpp, + src/internfile/mh_exec.cpp, src/internfile/mimehandler.cpp: + move findFilter usage out of mh_exec + +2006-12-11 14:56 +0000 dockes (dd4f283c9753 [BEFORE_Dijon20061215]) + + * src/qtgui/plaintorich.cpp: + not calling textsplit with onlyspans improves highlighting + +2006-12-11 14:50 +0000 dockes (c6d552528f6c) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/mimetype.cpp, src/utils/smallut.cpp, src/utils/smallut.h: + rationalize stopsuffix list usage + +2006-12-11 09:05 +0000 dockes (87037320fddf) + + * packaging/FreeBSD/recoll/pkg-plist: + try to cleanup the share/icons tree + +2006-12-10 17:03 +0000 dockes (0d0fec69b4e4 [MAPSTRMAPSTRSTR]) + + * src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h, + src/query/wasatorcl.cpp, src/query/wasatorcl.h: + added sort and type specs parsing + +2006-12-08 17:18 +0000 dockes (9d443b2ad416) + + * src/query/wasatorcl.h: + 1st query + +2006-12-08 10:54 +0000 dockes (dc4914858b42) + + * src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h: + *** empty log message *** + +2006-12-08 07:11 +0000 dockes (df1ce4c7c9bf) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/qtgui/ssearch_w.cpp: + only autophrase if query has several terms + +2006-12-08 06:45 +0000 dockes (6b96cd852343) + + * src/qtgui/ssearch_w.cpp: + make autophrase do the right thing: add a subclause, not modify the + query string + +2006-12-07 16:38 +0000 dockes (e0b7c11d4054) + + * src/query/qtry.cpp, src/query/qxtry.cpp: deleted file. + * src/query/Makefile, src/query/qtry.cpp, src/query/qxtry.cpp, + src/query/xadump.cpp: + removed qtry and merged qxtry into xadump + +2006-12-07 13:24 +0000 dockes (11f50dc2ced9) + + * src/rcldb/rcldb.cpp: + comment + +2006-12-07 13:14 +0000 dockes (0137bc80c8a5) + + * website/rclidxfmt.html: new file. + * website/rclidxfmt.html: + *** empty log message *** + +2006-12-07 13:02 +0000 dockes (e36e165c1055) + + * src/rcldb/rcldb.cpp: + comments + +2006-12-07 08:23 +0000 dockes (6bdb3421d1ca) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + plist: + 1.6.3 + +2006-12-07 08:06 +0000 dockes (2ca80dafce2a) + + * src/internfile/mh_mail.cpp: + fix bug with bad message "From " delimiter detection + +2006-12-07 07:07 +0000 dockes (92354b8e641a) + + * src/qtgui/rclmain_w.cpp, src/utils/mimeparse.h, + src/utils/smallut.cpp, src/utils/smallut.h: + fix pb with executing viewer for files with single-quotes in + pathnames + +2006-12-07 07:06 +0000 dockes (b415958c3148) + + * src/internfile/mh_mail.cpp: + fix bug with bad message "From " delimiter detection + +2006-12-05 15:25 +0000 dockes (451489717e47) + + * src/internfile/mh_mail.cpp: + use regexp to better discriminate From delimiter lines in mbox. + Avoid reading mboxes twice + +2006-12-05 15:23 +0000 dockes (282880e83069) + + * src/qtgui/advsearch.ui, src/qtgui/main.cpp, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/reslist.cpp, src/qtgui/reslist.h, + src/qtgui/sort.ui, src/qtgui/sort_w.cpp, src/qtgui/sort_w.h: + avoid generating abstracts before theyre needed (ie: not during + sort). have the sort tools redisplay the results when sort criteria + are applied + +2006-12-05 15:18 +0000 dockes (069f87c83682) + + * src/query/sortseq.cpp, src/query/sortseq.h: + use refcntr to access docsequence + +2006-12-05 15:17 +0000 dockes (f7bad3e61904) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + expose abstract synthesis to let users decide when they want it done + +2006-12-05 15:17 +0000 dockes (57148c851c44) + + * src/rcldb/searchdata.h: + clauseCount + +2006-12-05 15:16 +0000 dockes (d6d5ee7b750b) + + * src/utils/refcntr.h: + fix pbs with empty object + +2006-12-04 09:56 +0000 dockes (1173f38c9de4) + + * src/configure, src/configure.ac, src/qtgui/advsearch_w.h, + src/qtgui/main.cpp, src/qtgui/preview_w.h, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/sort_w.h, src/qtgui/spell_w.h, + src/qtgui/ssearch_w.h, src/qtgui/uiprefs_w.h, src/utils/refcntr.h: + qt4 compiles and sort of works + +2006-12-04 09:49 +0000 dockes (00bc69d47f20) + + * src/qt4gui/recoll.qrc, src/qt4gui/uifrom3: new file. + * src/qt4gui/recoll.pro.in, src/qt4gui/recoll.qrc, src/qt4gui/uifrom3: + *** empty log message *** + +2006-12-04 08:17 +0000 dockes (c92f84765756) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/preview_w.cpp, + src/qtgui/preview_w.h, src/qtgui/sort_w.cpp, + src/qtgui/ssearch_w.cpp, src/qtgui/uiprefs_w.cpp, + src/qtgui/uiprefs_w.h: + compiles (doesnt work) on qt4 + +2006-12-04 06:19 +0000 dockes (5a7d6794967e) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/guiutils.cpp, src/qtgui/main.cpp, + src/qtgui/preview.ui, src/qtgui/preview_w.h, src/qtgui/rclmain.ui, + src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/reslist.cpp, src/qtgui/reslist.h, + src/qtgui/searchclause_w.cpp, src/qtgui/searchclause_w.h, + src/qtgui/sort_w.h, src/qtgui/spell.ui, src/qtgui/spell_w.h, + src/qtgui/ssearch_w.h, src/qtgui/ssearchb.ui, src/qtgui/uiprefs_w.h: + qt4 ckpt + +2006-12-02 07:32 +0000 dockes (45564d318a93) + + * src/utils/idfile.cpp: + improved tests to check for mail + +2006-12-01 10:05 +0000 dockes (8c3b51bc117f) + + * src/query/xadump.cpp: + *** empty log message *** + +2006-11-30 18:12 +0000 dockes (e41c0db701ae) + + * src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h, + src/query/wasatorcl.cpp, src/query/wasatorcl.h: new file. + * src/query/wasastringtoquery.cpp, src/query/wasastringtoquery.h, + src/query/wasatorcl.cpp, src/query/wasatorcl.h: + *** empty log message *** + +2006-11-30 13:44 +0000 dockes (5ef831ae4659) + + * website/download.html: + *** empty log message *** + +2006-11-30 13:38 +0000 dockes (6e49658236c6) + + * src/qtgui/images/cancel.png, src/qtgui/images/close.png: new file. + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + plist, packaging/rpm/recoll.spec, packaging/rpm/recollmdk.spec, + src/README, src/aspell/rclaspell.cpp, src/doc/user/usermanual.sgml, + src/index/indexer.cpp, src/index/indexer.h, src/makesrcdist.sh, + src/makestaticdist.sh, src/mk/SunOS, src/qtgui/advsearch.ui, + src/qtgui/advsearch_w.cpp, src/qtgui/guiutils.cpp, + src/qtgui/guiutils.h, src/qtgui/i18n/recoll_fr.ts, + src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts, + src/qtgui/images/cancel.png, src/qtgui/images/close.png, + src/qtgui/main.cpp, src/qtgui/plaintorich.cpp, + src/qtgui/plaintorich.h, src/qtgui/preview.ui, + src/qtgui/preview_w.cpp, src/qtgui/rclmain.ui, + src/qtgui/recoll.pro.in, src/qtgui/reslist.cpp, + src/qtgui/searchclause_w.cpp, src/qtgui/spell_w.cpp, + src/qtgui/ssearch_w.cpp, src/qtgui/ssearchb.ui, + src/rcldb/searchdata.cpp, src/recoll.desktop, src/recollinstall.in, + src/sampleconf/recoll.conf.in, src/utils/execmd.cpp, + src/utils/mimeparse.cpp, src/utils/smallut.cpp, website/BUGS.txt, + website/CHANGES.txt, website/download.html, website/features.html, + website/index.html: + merged 1.6 maint branch modifs up to MERGED_TO_TRUNK_20061130 + +2006-11-22 09:29 +0000 dockes (568c34cf75e9) + + * src/VERSION, website/BUGS.txt, website/CHANGES.txt, + website/credits.html, website/download.html: + *** empty log message *** + +2006-11-21 14:00 +0000 dockes (f247e019bf08 [RECOLL_1_6_0]) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-11-21 13:05 +0000 dockes (23604b23773d) + + * src/aspell/rclaspell.cpp, src/configure, src/configure.ac: + mdk 2006 aspell quirks + +2006-11-21 09:18 +0000 dockes (17597459707c) + + * packaging/FreeBSD/recoll/pkg-plist, packaging/rpm/recoll.spec, + packaging/rpm/recollmdk.spec, src/doc/user/usermanual.sgml, + src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts, website/BUGS.txt, website/CHANGES.txt, + website/copydocs, website/download.html, website/index.html: + *** empty log message *** + +2006-11-21 08:47 +0000 dockes (f434e776fec8) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/spell.ui, + src/qtgui/spell_w.cpp, src/qtgui/spell_w.h, src/qtgui/uiprefs_w.cpp: + added stem expansion mode to term explorer + +2006-11-20 18:07 +0000 dockes (bc85af9f678c) + + * src/doc/man/recoll.conf.5, src/doc/man/recollindex.1, + src/doc/user/usermanual.sgml: + doc + +2006-11-20 17:46 +0000 dockes (28cb0d8c325a) + + * src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-11-20 17:06 +0000 dockes (9252428377e4) + + * src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts: + *** empty log message *** + +2006-11-20 15:35 +0000 dockes (192c101b8b7c) + + * src/qtgui/advsearch.ui: + tooltip + +2006-11-20 15:29 +0000 dockes (73ca6e78a1dd) + + * src/filters/rclxls, src/utils/transcode.cpp: + *** empty log message *** + +2006-11-20 15:28 +0000 dockes (9bb875d3bfcf) + + * src/rcldb/rcldb.cpp: + clear abstract if its only ... + +2006-11-20 15:28 +0000 dockes (5ef1b603c3be) + + * src/common/rclconfig.cpp: + test driver + +2006-11-20 15:28 +0000 dockes (1c4807a363f9) + + * src/common/rclconfig.h: + fix defaultcharset reset + +2006-11-20 11:17 +0000 dockes (ef95275586d1) + + * src/common/Makefile, src/common/textsplit.cpp, + src/common/textsplit.h: + improved textsplit speed (needs utf8iter modifs too + +2006-11-20 11:16 +0000 dockes (e05653621eb4) + + * src/utils/Makefile, src/utils/utf8iter.cpp, src/utils/utf8iter.h: + cleaned and speeded up utf8iter + +2006-11-19 18:37 +0000 dockes (756bc7569b34) + + * src/common/textsplit.cpp, src/common/textsplit.h: + optim ckpt + +2006-11-18 12:56 +0000 dockes (bf6e4de3a902) + + * src/qtgui/plaintorich.cpp: + firsttermocc init was not always done + +2006-11-18 12:31 +0000 dockes (1703e5a7b03e) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview_w.cpp, src/qtgui/reslist.cpp: + improve positionning on term groups by storing/passing an occurrence + index + +2006-11-18 12:30 +0000 dockes (f065c8063ff3) + + * src/rcldb/searchdata.cpp: + correctly generate highlighting term groups when stem-expanding NEAR + queries + +2006-11-17 15:26 +0000 dockes (ee4a13877b24) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/guiutils.cpp, + src/qtgui/guiutils.h: + Save adv search clause list + add delete button + +2006-11-17 12:55 +0000 dockes (679a2cb3d3e7) + + * src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/reslist.cpp, src/qtgui/reslist.h: + get shift+clicklink to open new preview window instead of tab + +2006-11-17 12:32 +0000 dockes (51f7db5eff83) + + * src/qtgui/plaintorich.cpp: + small opts + fixed near region detection code + +2006-11-17 12:31 +0000 dockes (c0ba08efc3dd) + + * src/qtgui/plaintorich.h: + comments + +2006-11-17 12:31 +0000 dockes (e54183706237) + + * src/utils/utf8iter.h: + removed not strictly needed error checking code + +2006-11-17 10:09 +0000 dockes (7e44d4280e2d) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview_w.cpp, src/qtgui/preview_w.h, + src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp, src/qtgui/reslist.h: + Remember searchData and use it in plaintorich for phrase/group + highlighting + +2006-11-17 10:08 +0000 dockes (c175799e9e72) + + * src/qtgui/advsearch_w.cpp: + better data encap in searchdata + +2006-11-17 10:06 +0000 dockes (0ea302968170) + + * src/rcldb/rcldb.cpp, src/rcldb/searchdata.cpp, + src/rcldb/searchdata.h: + added code to remember search terms and term groups in searchdata + +2006-11-15 14:57 +0000 dockes (188b5b28427d) + + * src/common/Makefile, src/lib/Makefile, src/lib/mkMake, + src/mk/commondefs, src/qtgui/recoll.pro.in, src/rcldb/pathhash.cpp, + src/rcldb/pathhash.h, src/rcldb/rcldb.cpp, src/rcldb/searchdata.h, + src/rcldb/stemdb.h: + distributed files from common/ into rcld, internfile, common + +2006-11-15 07:27 +0000 dockes (5bfc0444c072) + + * src/internfile/Makefile: new file. + * src/internfile/Makefile: + *** empty log message *** + +2006-11-14 18:29 +0000 dockes (c45d7a2b1c63) + + * src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h: + got rid of the static clause names + +2006-11-14 18:17 +0000 dockes (e4789b229585) + + * src/qtgui/advsearch.ui: + *** empty log message *** + +2006-11-14 17:56 +0000 dockes (ae916c13c591) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp: + added conjunction choice in advsearch + +2006-11-14 17:41 +0000 dockes (dfc71f06c1ce) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/searchclause_w.cpp, + src/qtgui/searchclause_w.h, src/rcldb/searchdata.cpp: + use SearchClauseW for all advsearch fields + +2006-11-14 15:13 +0000 dockes (300f3705d6cf) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp: + *** empty log message *** + +2006-11-14 14:58 +0000 dockes (c5f65c6f8fb9) + + * src/qtgui/recoll.pro.in: + *** empty log message *** + +2006-11-14 13:55 +0000 dockes (9e98c3d86016) + + * src/qtgui/searchclause_w.cpp, src/qtgui/searchclause_w.h: new file. + * src/doc/user/usermanual.sgml, src/qtgui/advsearch.ui, + src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h, + src/qtgui/rclmain_w.cpp, src/qtgui/searchclause_w.cpp, + src/qtgui/searchclause_w.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/rcldb/searchdata.cpp, src/rcldb/searchdata.h: + added dynamic clauses to adv search. Still needs work + +2006-11-13 14:51 +0000 dockes (5c9db8d08690) + + * src/rcldb/rcldb.cpp: + *** empty log message *** + +2006-11-13 14:48 +0000 dockes (edec86240778) + + * src/rcldb/rcldb.cpp: + use wdfs for better selection of doc extracts in makeAbstract + +2006-11-13 11:59 +0000 dockes (fdf0f43cd03e) + + * src/utils/smallut.h: + *** empty log message *** + +2006-11-13 08:58 +0000 dockes (c48e54f96603) + + * src/utils/refcntr.h: new file. + * src/utils/refcntr.h: + *** empty log message *** + +2006-11-13 08:58 +0000 dockes (40853ad94507) + + * src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h, + src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/reslist.cpp, src/qtgui/reslist.h, + src/qtgui/ssearch_w.cpp, src/qtgui/ssearch_w.h: + make searchdata a more flexible struct + +2006-11-13 08:50 +0000 dockes (e585bfd6e725) + + * src/rcldb/searchdata.cpp: new file. + * src/lib/Makefile, src/lib/mkMake, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h, src/rcldb/searchdata.cpp, src/rcldb/searchdata.h: + make searchdata a more flexible struct + +2006-11-13 08:49 +0000 dockes (db3490f9b522) + + * src/kde/kioslave/recoll/kio_recoll.cpp: + *** empty log message *** + +2006-11-13 08:15 +0000 dockes (7240ec62ffac) + + * src/qtgui/plaintorich.cpp: + new splitter interface + +2006-11-12 08:35 +0000 dockes (ff9f3aed6a5b) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/rcldb/rcldb.cpp: + phrase queries with bot spans and words must be splitted as words + only + +2006-11-11 15:30 +0000 dockes (25647c7c5aac) + + * src/qtgui/reslist.cpp, src/qtgui/uiprefs.ui: + have more compact list header + %N + +2006-11-10 17:53 +0000 dockes (d423490bea37) + + * src/qtgui/reslist.cpp: + Really use the rich abstracts + +2006-11-10 17:18 +0000 dockes (9fc1a2d1b7af) + + * src/rcldb/rcldb.cpp: + optimized abstract building: bybye big vector + +2006-11-10 13:32 +0000 dockes (8cfbbddd355a) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/rclmain_w.cpp, src/qtgui/reslist.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp: + make result list paragraph format user-adjustable + +2006-11-10 13:30 +0000 dockes (933509968125) + + * src/utils/smallut.cpp, src/utils/smallut.h: + pcSubst() + +2006-11-10 13:29 +0000 dockes (17e0ecfb5834) + + * src/internfile/internfile.cpp: + errlog + +2006-11-09 19:04 +0000 dockes (814af75ba7a8) + + * src/qtgui/preview_w.cpp: + better handle the situation of mbox file name matching search + +2006-11-09 17:38 +0000 dockes (3c996d97497a) + + * src/Makefile.in: + *** empty log message *** + +2006-11-09 17:37 +0000 dockes (c13aab8ac186) + + * src/qtgui/reslist.cpp: + nbsp to prevent line date wrap before tz + +2006-11-09 17:37 +0000 dockes (573934250b27) + + * src/rcldb/rcldb.cpp: + dont continue adding ellipsis into the abstract when its maxlen! + +2006-11-09 08:59 +0000 dockes (baafe52b9d1b) + + * src/utils/mimeparse.cpp: + test driver modifs + +2006-11-08 15:34 +0000 dockes (025fa484738a) + + * src/common/rclinit.cpp, src/utils/debuglog.cpp, + src/utils/debuglog.h: + fix pb with special log file names + +2006-11-08 15:32 +0000 dockes (a32333c18e9f) + + * src/configure, src/configure.ac: + aspell help string + +2006-11-08 13:04 +0000 dockes (f5f0e953f42e) + + * src/qtgui/plaintorich.cpp: + use vector instead of list for positions + +2006-11-08 07:22 +0000 dockes (de7777528655) + + * src/common/rclinit.cpp, src/common/rclinit.h, + src/index/recollindex.cpp: + allow daemon-specific log parameters + +2006-11-08 06:56 +0000 dockes (451b31555bc2) + + * src/utils/conftree.cpp, src/utils/conftree.h: + volatile conf + +2006-11-08 06:49 +0000 dockes (ba1e8fb12e39) + + * src/recollinstall.in: + install rclmon.sh + +2006-11-07 18:28 +0000 dockes (fb26679a6cec) + + * src/qtgui/reslist.cpp, src/utils/mimeparse.cpp: + 1.5.9: fix bad tz correction in email dates + display tz in reslist + +2006-11-07 16:51 +0000 dockes (affd0b42e8ae) + + * src/index/rclmon.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp: + traces + +2006-11-07 12:02 +0000 dockes (70ed645d27f3) + + * src/rcldb/rcldb.cpp: + use both size and mtime changes as updateneeding indicator + +2006-11-07 09:11 +0000 dockes (2491b468f55d) + + * src/qtgui/uiprefs.ui: + improved autophrase tooltip + +2006-11-07 09:04 +0000 dockes (ba7c28e1a205) + + * src/qtgui/uiprefs_w.cpp: + Cancel did not reset uiprefs dialog to stored state + +2006-11-07 08:57 +0000 dockes (c9f2b8c02171) + + * src/qtgui/uiprefs_w.cpp, src/qtgui/uiprefs_w.h: + Cancel did not reset uiprefs dialog to stored state + +2006-11-07 06:41 +0000 dockes (fea8781e4829) + + * src/index/indexer.cpp: + record/show mtime instead of ctime + +2006-11-06 17:37 +0000 dockes (a82b3932ac69) + + * src/doc/user/usermanual.sgml, src/qtgui/rclmain.ui, + src/qtgui/spell_w.cpp, src/rcldb/rcldb.cpp: + wrote manual for term explorer and fixed a few problems + +2006-11-05 21:10 +0000 dockes (f4fc6544cb74) + + * src/bincimapmime/mime-parsefull.cc: + fix binc imap infinite loop on multipart with null boundary + +2006-11-05 18:02 +0000 dockes (9306096cb34f) + + * src/bincimapmime/depot.h, src/bincimapmime/session.h: deleted file. + * src/bincimapmime/address.cc, src/bincimapmime/address.h, + src/bincimapmime/convert.cc, src/bincimapmime/convert.h, + src/bincimapmime/depot.h, src/bincimapmime/iodevice.cc, + src/bincimapmime/iodevice.h, src/bincimapmime/iofactory.h, + src/bincimapmime/mime-getpart.cc, src/bincimapmime/mime- + inputsource.h, src/bincimapmime/mime-parsefull.cc, src/bincimapmime + /mime-parseonlyheader.cc, src/bincimapmime/mime-printbody.cc, + src/bincimapmime/mime-printdoc.cc, src/bincimapmime/mime- + printheader.cc, src/bincimapmime/mime-utils.h, + src/bincimapmime/mime.cc, src/bincimapmime/mime.h, + src/bincimapmime/session.h: + included bincimap 1.3.3 to 1.3.4 diffs (mostly cosmetic) + +2006-11-04 17:09 +0000 dockes (3e0e0d4b152f) + + * src/qtgui/spell.ui, src/qtgui/spell_w.cpp: + fix aspell version of term explorer + +2006-11-04 14:49 +0000 dockes (7f914235875b) + + * src/qtgui/ssearch_w.cpp, src/qtgui/ssearch_w.h: + change ctrl-tab to esc-spc + +2006-10-30 12:59 +0000 dockes (2454d0c418a2) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/rclmain_w.cpp, src/qtgui/spell.ui, src/qtgui/spell_w.cpp, + src/qtgui/ssearch_w.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + Turn spell tool into multimode spell/wild/regexp + +2006-10-25 11:50 +0000 dockes (66843e6e167c) + + * src/index/indexer.cpp: + make tmpdir only once + +2006-10-25 10:52 +0000 dockes (10c2b1b74822) + + * src/index/indexer.cpp, src/index/rclmon.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp, src/rcldb/rcldb.cpp: + added some debugging msgs (too much) + +2006-10-24 15:16 +0000 dockes (1fc3f90d5ee3) + + * src/mk/Darwin: + *** empty log message *** + +2006-10-24 14:28 +0000 dockes (33512e5ceddb) + + * src/index/indexer.cpp, src/index/indexer.h, src/index/rclmon.h, + src/index/rclmonprc.cpp, src/index/recollindex.cpp: + create stemming db on queue timeout if needed + +2006-10-24 13:22 +0000 dockes (21df8a0f4856) + + * src/index/rclmon.sh: new file. + * src/index/rclmon.sh: + *** empty log message *** + +2006-10-24 12:48 +0000 dockes (4af32c44f8ea) + + * src/index/rclmon.h, src/index/rclmonprc.cpp: + setup lockfile for monitor + +2006-10-24 11:42 +0000 dockes (f922b4dda121) + + * src/query/Makefile: + *** empty log message *** + +2006-10-24 11:42 +0000 dockes (f1da6521f1ff) + + * src/qtgui/ssearch_w.cpp: + explain error for C-TAB too many expansions + +2006-10-24 09:28 +0000 dockes (3228b6b8093a) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + fix slowness in needUpdate by using Database instead of + WritableDatabase + +2006-10-24 09:09 +0000 dockes (0d72c341e2eb) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/indexer.cpp, src/index/rclmonrcv.cpp: + centralize skippedNames computation to add dbdir always + +2006-10-23 15:01 +0000 dockes (6a07dc59db99) + + * src/index/rclmon.h, src/index/rclmonrcv.cpp: + handle directory creation + +2006-10-23 15:00 +0000 dockes (672e4b4bfe51) + + * src/utils/pathut.cpp, src/utils/pathut.h: + add path_isdir() + +2006-10-23 14:29 +0000 dockes (d395ca679c7a) + + * src/common/autoconfig.h.in, src/configure, src/configure.ac, + src/index/rclmonrcv.cpp: + raw inotify support + +2006-10-22 15:55 +0000 dockes (de0702a6c5e2) + + * src/mk/Linux: + *** empty log message *** + +2006-10-22 15:54 +0000 dockes (35832011eaf9) + + * src/rcldb/rcldb.cpp: + simplify needUpdate test + +2006-10-22 14:47 +0000 dockes (733c7646ca29) + + * src/configure, src/configure.ac, src/index/Makefile, + src/index/indexer.cpp, src/index/indexer.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp, src/index/recollindex.cpp, + src/mk/localdefs.in, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + monitor: purge docs for deleted files from db + +2006-10-20 08:31 +0000 dockes (6d54039efe79) + + * src/qtgui/i18n/recoll_ru.ts, src/qtgui/i18n/recoll_uk.ts: + new Ukrainian+Russian messages from Michael + +2006-10-20 08:29 +0000 dockes (ebcb12870038) + + * src/qtgui/advsearch.ui, src/qtgui/rclmain.ui, src/qtgui/uiprefs.ui: + small fixes on label strings + +2006-10-17 14:41 +0000 dockes (ea77c15d81a6) + + * src/common/autoconfig.h.in, src/configure, src/configure.ac, + src/index/rclmon.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp, src/index/recollindex.cpp: + fam autoconfig + +2006-10-16 15:33 +0000 dockes (aa570fc97bf9) + + * src/index/rclmon.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp: new file. + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/Makefile, src/index/indexer.cpp, src/index/indexer.h, + src/index/rclmon.h, src/index/rclmonprc.cpp, + src/index/rclmonrcv.cpp, src/index/recollindex.cpp: + 1st version of real time monitor + +2006-10-15 13:07 +0000 dockes (aa97f764d4a6) + + * src/qtgui/rclmain_w.cpp, src/qtgui/spell_w.cpp, src/qtgui/spell_w.h: + dbl click in spell win to add to ssearch + +2006-10-12 14:46 +0000 dockes (78a3a37209ae) + + * src/configure.ac, src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp: + recollindex -i now checks that the files are descendants of topdirs + +2006-10-12 08:39 +0000 dockes (ab66430f3f7d) + + * src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-10-11 16:09 +0000 dockes (1cf66e2b486f) + + * src/aspell/rclaspell.cpp, src/utils/execmd.cpp, src/utils/execmd.h: + improve execcmd to avoid allocating an allterms buffer when creating + dico + +2006-10-11 14:16 +0000 dockes (26e08a8fc135) + + * src/qtgui/images/d_spell.png, src/qtgui/images/spell.png, + src/qtgui/spell.ui, src/qtgui/spell_w.cpp, src/qtgui/spell_w.h: new + file. + * src/aspell/rclaspell.cpp, src/aspell/rclaspell.h, + src/common/autoconfig.h.in, src/common/rclconfig.h, src/configure, + src/configure.ac, src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp, src/mk/commondefs, src/mk/localdefs.in, + src/qtgui/images/d_spell.png, src/qtgui/images/spell.png, + src/qtgui/main.cpp, src/qtgui/rclmain.ui, src/qtgui/rclmain_w.cpp, + src/qtgui/rclmain_w.h, src/qtgui/recoll.h, src/qtgui/recoll.pro.in, + src/qtgui/spell.ui, src/qtgui/spell_w.cpp, src/qtgui/spell_w.h, + src/sampleconf/recoll.conf.in, src/utils/smallut.cpp, + src/utils/smallut.h: + 1st full version of aspell support + +2006-10-10 10:58 +0000 dockes (ed60d657e8e9) + + * src/aspell/aspell-local.h, src/common/autoconfig.h.in: new file. + * src/aspell/aspell-local.h, src/common/autoconfig.h.in: + *** empty log message *** + +2006-10-09 16:37 +0000 dockes (93d9009c4d51) + + * src/VERSION, src/aspell/rclaspell.cpp, src/aspell/rclaspell.h, + src/index/Makefile, src/lib/Makefile, src/lib/mkMake, + src/makesrcdist.sh, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/rcldb/stemdb.cpp, src/utils/execmd.cpp, src/utils/execmd.h: + aspell checkpoint + +2006-10-09 14:05 +0000 dockes (711360b10738) + + * src/aspell/Makefile, src/aspell/rclaspell.cpp, + src/aspell/rclaspell.h: new file. + * src/aspell/Makefile, src/aspell/rclaspell.cpp, + src/aspell/rclaspell.h: + *** empty log message *** + +2006-10-03 08:34 +0000 dockes (4033d57b83da) + + * packaging/rpm/recoll.spec, packaging/rpm/recollmdk.spec: + 1.5 + +2006-10-02 13:30 +0000 dockes (562f54fc8029) + + * src/VERSION, src/makestaticdist.sh: + small glitches in makestaticdist + +2006-10-02 12:33 +0000 dockes (7be5b4b7d6c0) + + * src/VERSION, src/configure, src/configure.ac, src/query/history.h: + small glitches detected on suse / gcc 4.1 + +2006-10-02 11:25 +0000 dockes (8731b62606fe [RECOLL-1_5_8, RECOLL-1_5_3, RECOLL-1_5_6, RECOLL-1_5_7, RECOLL-1_5_4, RECOLL-1_5_5]) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist: + 1.5.2 + +2006-10-02 08:38 +0000 dockes (ee82de281263) + + * src/VERSION: + *** empty log message *** + +2006-10-02 08:26 +0000 dockes (bafb3e762d82) + + * src/sampleconf/mimeconf: + added 2 icons + +2006-10-02 08:25 +0000 dockes (c3d47772ea99) + + * src/qtgui/mtpics/image.png, src/qtgui/mtpics/source.png: new file. + * src/qtgui/mtpics/image.png, src/qtgui/mtpics/source.png: + *** empty log message *** + +2006-10-02 07:50 +0000 dockes (fe9700b5a6fe [RECOLL-1_5_2, RECOLL-1_5_1]) + + * src/INSTALL, src/README, website/BUGS.txt, website/CHANGES.txt, + website/download.html, website/index.html: + *** empty log message *** + +2006-10-02 07:45 +0000 dockes (bc3c93581184) + + * src/VERSION, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts: + 1.5.1 + +2006-09-29 11:43 +0000 dockes (bd51dd85dc0f) + + * src/doc/user/usermanual.sgml: + aspell pass + +2006-09-29 08:26 +0000 dockes (026d0b177533) + + * src/rcldb/rcldb.cpp: + syntabs: remove size limit. Handle overlapping chunks. Make sure we + use only one term per position + +2006-09-29 08:24 +0000 dockes (49342357f800) + + * src/qtgui/reslist.cpp: + reset curPvDoc on setDocSource + +2006-09-29 08:23 +0000 dockes (a9cef42dd219) + + * src/qtgui/uiprefs.ui: + bump up limits on max abstract size parameters + +2006-09-29 07:13 +0000 dockes (7973023d7c1b) + + * src/qtgui/ssearch_w.cpp: + bad/unneeded conversion to utf8 while saving ssearch history would + cause some string sizes in history to double at each program + invocation + +2006-09-28 14:32 +0000 dockes (a5bba26b0ac0) + + * src/qtgui/i18n/recoll_fr.ts: + 1.5 + +2006-09-28 14:31 +0000 dockes (71d5895b7848) + + * src/qtgui/ssearchb.ui: + improved tip + +2006-09-28 14:30 +0000 dockes (903f443a7150) + + * src/doc/user/usermanual.sgml: + reordered the tips + +2006-09-28 11:55 +0000 dockes (3bf818bd1e39) + + * src/qtgui/main.cpp: + debug messages + +2006-09-23 13:32 +0000 dockes (3cf269bf18f0) + + * website/BUGS.txt, website/CHANGES.txt, website/download.html, + website/features.html, website/index.html: + *** empty log message *** + +2006-09-23 13:13 +0000 dockes (06ed627f182d [RECOLL-1_5_0]) + + * src/INSTALL, src/README, src/makesrcdist.sh: + *** empty log message *** + +2006-09-23 13:11 +0000 dockes (0533f47f1c34) + + * src/INSTALL, src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-09-23 13:09 +0000 dockes (9b8fdf62ad07) + + * src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-09-23 07:39 +0000 dockes (33e469ad3a2e) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/preview_w.cpp, src/qtgui/reslist.cpp: + fix file name display in tooltips + +2006-09-23 07:39 +0000 dockes (e47ebb4e22ce) + + * src/internfile/mh_mail.cpp: + fix newlines + +2006-09-23 07:21 +0000 dockes (b5b530ea2ec9) + + * src/rcldb/rcldb.cpp: + message + +2006-09-22 14:11 +0000 dockes (3ef29a8417c7) + + * src/qtgui/i18n/recoll_fr.ts, src/rcldb/rcldb.cpp: + msg + +2006-09-22 10:46 +0000 dockes (9ade76cc0df5) + + * src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts, src/qtgui/uiprefs_w.cpp: + messages + +2006-09-22 08:19 +0000 dockes (c228a1515468) + + * src/qtgui/recoll.pro.in: + *** empty log message *** + +2006-09-22 07:51 +0000 dockes (df858f3508f4) + + * src/qtgui/recoll.pro.in: + names cleanup + +2006-09-22 07:42 +0000 dockes (de54384ab321) + + * src/utils/mimeparse.h: + comment + +2006-09-22 07:41 +0000 dockes (f37052248b5b) + + * src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts, src/qtgui/rclmain.ui, + src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h: new file. + * src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, src/qtgui/recoll_fr.ts, + src/qtgui/recoll_ru.ts, src/qtgui/recoll_uk.ts, + src/qtgui/recollmain.ui: deleted file. + * src/qtgui/i18n/recoll_fr.ts, src/qtgui/i18n/recoll_ru.ts, + src/qtgui/i18n/recoll_uk.ts, src/qtgui/main.cpp, + src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, src/qtgui/rclmain.ui, + src/qtgui/rclmain_w.cpp, src/qtgui/rclmain_w.h, + src/qtgui/recoll_fr.ts, src/qtgui/recoll_ru.ts, + src/qtgui/recoll_uk.ts, src/qtgui/recollmain.ui: + names cleanup: rclmain, translations + +2006-09-22 07:38 +0000 dockes (c17bf757689b) + + * src/recollinstall.in: + names cleanup: translations + +2006-09-22 07:29 +0000 dockes (2d749704a22b) + + * src/qtgui/reslist.cpp, src/qtgui/reslist.h: new file. + * src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h: deleted file. + * src/qtgui/rclmain.cpp, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h, src/qtgui/recollmain.ui, + src/qtgui/reslist.cpp, src/qtgui/reslist.h: + names cleanup: reslist + +2006-09-22 07:22 +0000 dockes (cd9f046bf5e3) + + * src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h: + clarified preview paragraph coloring in reslist + +2006-09-22 07:19 +0000 dockes (c700f9f95168) + + * src/internfile/mh_mail.cpp: + clarified depth processing and increased limit + +2006-09-21 12:56 +0000 dockes (334ef2914129) + + * src/qtgui/preview_w.cpp, src/qtgui/preview_w.h, + src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h: + synchronize preview tab and colored paragraph in result list + +2006-09-21 09:37 +0000 dockes (43c279d4d112) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/rclmain.cpp, + src/qtgui/rclmain.h, src/qtgui/sort_w.cpp, src/qtgui/sort_w.h, + src/query/sortseq.cpp, src/query/sortseq.h: + remember sort criteria + +2006-09-21 05:59 +0000 dockes (e5e9c1ffa44c) + + * src/internfile/myhtmlparse.cpp: + dont throw away text even if html is weird + +2006-09-21 05:59 +0000 dockes (4e99ebec009f) + + * src/common/textsplit.cpp: + 132.jpg was not split + +2006-09-21 05:57 +0000 dockes (3bc572456a49) + + * src/common/Makefile, src/utils/Makefile: + *** empty log message *** + +2006-09-20 06:21 +0000 dockes (5829221e8612) + + * src/rcldb/stemdb.cpp: + comments + +2006-09-19 14:30 +0000 dockes (598f2c534c4c) + + * src/rcldb/stemdb.cpp: + Stems with unique parent must be in db too so that one can search on + stem (which is not a term) + +2006-09-19 14:30 +0000 dockes (98cd92c958bd) + + * src/internfile/mh_mail.cpp, src/internfile/mh_mail.h: + walk the full mime tree instead of staying at level 1 + +2006-09-19 14:19 +0000 dockes (12fcb57186c2) + + * src/configure, src/configure.ac: + *** empty log message *** + +2006-09-19 14:19 +0000 dockes (88bbc8f18b9e) + + * src/utils/mimeparse.cpp: + disable date debug msgs + +2006-09-19 14:18 +0000 dockes (a0016b0e9969) + + * src/query/xadump.cpp: + add option to dump a recoll stemdb + +2006-09-18 12:17 +0000 dockes (e662e0bbe85e) + + * src/README: + *** empty log message *** + +2006-09-15 16:50 +0000 dockes (315f1c1d3dd3) + + * src/VERSION, src/doc/user/usermanual.sgml, + src/internfile/mh_mail.cpp, src/utils/mimeparse.cpp, + src/utils/mimeparse.h: + Use own code to parse rfc822 dates, strptime() cant do + +2006-09-15 16:49 +0000 dockes (ca133771bc5b) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/recoll.pro.in, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs_w.cpp: + small typo fixes + +2006-09-15 12:36 +0000 dockes (47354227e577) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-09-14 07:13 +0000 dockes (b717321f9de4 [RECOLL-1_4_4]) + + * *** empty log message *** + +2006-09-14 07:13 +0000 dockes (919e6e0dfc56) + + * website/BUGS.txt, website/CHANGES.txt, website/copydocs, + website/credits.html, website/devel.html, website/download.html, + website/features.html, website/index.html, website/pics/index.html, + website/styles/style.css: new file. + * website/BUGS.txt, website/CHANGES.txt, website/copydocs, + website/credits.html, website/devel.html, website/download.html, + website/features.html, website/index.html, website/pics/index.html, + website/styles/style.css: + *** empty log message *** + +2006-09-13 15:31 +0000 dockes (9bd2431eaa66) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/ssearch_w.cpp, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs_w.cpp: + autophrase parameter + +2006-09-13 14:57 +0000 dockes (0d952f522055) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/rclreslist.cpp, src/query/docseq.cpp, src/query/docseq.h: + colorize search terms in abstracts + +2006-09-13 13:53 +0000 dockes (5980807171a8) + + * src/index/indexer.cpp, src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/main.cpp, src/qtgui/rclmain.cpp, src/qtgui/ssearch_w.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h, src/sampleconf/recoll.conf.in: + make constant lengths for abstracts config params + +2006-09-13 08:13 +0000 dockes (6e43869ceb61) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/advsearch_w.h, src/qtgui/guiutils.cpp, + src/qtgui/guiutils.h, src/qtgui/main.cpp, src/qtgui/rclmain.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs_w.cpp: + add feature to save asearch ignored file types as startup default + +2006-09-12 10:11 +0000 dockes (9b323c436beb) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/preview_w.cpp, src/qtgui/preview_w.h, + src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h, + src/qtgui/ssearch_w.cpp, src/qtgui/ssearchb.ui: + allow paging through results inside a preview window with shift-up + shift-down + +2006-09-11 14:22 +0000 dockes (f0dd93428e23) + + * src/doc/user/usermanual.sgml, src/qtgui/advsearch.ui: + try to make clearer that adv search fields will accept phrases as + well as single words + +2006-09-11 12:05 +0000 dockes (f455fbc6a42a) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch_w.cpp, + src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, + src/qtgui/ssearch_w.cpp, src/qtgui/ssearchb.ui, + src/query/history.cpp, src/query/history.h: + remember history of restrict subdirs in adv search + +2006-09-11 09:08 +0000 dockes (ad274e633ffb) + + * src/qtgui/guiutils.cpp, src/qtgui/main.cpp, src/qtgui/rclmain.cpp, + src/qtgui/rclmain.h, src/qtgui/recoll.h, src/qtgui/uiprefs.ui, + src/query/docseq.h, src/query/history.cpp, src/query/history.h: + use the (should be renamed) history file to store external databases + lists + +2006-09-11 07:10 +0000 dockes (6cb09384f54a) + + * src/qtgui/ssearch_w.cpp, src/qtgui/ssearchb.ui: + maintain ssearches listbox in mru order + +2006-09-11 06:58 +0000 dockes (b62d0be5650e) + + * src/qtgui/advsearch.ui, src/qtgui/sort.ui, src/qtgui/uiprefs.ui: + ensure dialogs are sized according to font size + +2006-09-08 09:02 +0000 dockes (a5a31c9b0a37) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/rclinit.cpp, src/common/rclinit.h, src/doc/man/recoll.1, + src/doc/man/recoll.conf.5, src/doc/man/recollindex.1, + src/doc/user/usermanual.sgml, src/index/recollindex.cpp, + src/qtgui/guiutils.cpp, src/qtgui/main.cpp: + Add -c option to recoll and recollindex + +2006-09-08 08:51 +0000 dockes (315e0865ec26) + + * src/sampleconf/recoll.conf.in: + The dbdir default value is now relative to the cnf dir + +2006-09-06 09:50 +0000 dockes (e696d98fe7fe) + + * src/qtgui/uiprefs_w.cpp: + Used to reset the buildAbstract replaceAbstract options because of + setDown instead of setChecked + +2006-09-06 09:14 +0000 dockes (0dedd735c86e) + + * src/utils/mimeparse.cpp, src/utils/mimeparse.h: + implement rfc2231 decoding for mime parameter values + +2006-09-05 17:09 +0000 dockes (95fd6b3a5b9a) + + * src/internfile/mh_mail.cpp: + let mimeparse handle decoding or param values + +2006-09-05 09:52 +0000 dockes (44182523e711) + + * src/filters/rclppt, src/filters/rclxls: new file. + * src/filters/rclppt, src/filters/rclxls, src/sampleconf/mimeconf, + src/sampleconf/mimemap: + added support for ppt and xls via catdoc + +2006-09-05 08:05 +0000 dockes (587719349228) + + * src/internfile/mh_mail.cpp, src/internfile/mh_mail.h: + index and display attachment file names + +2006-09-05 08:04 +0000 dockes (6f8b09a74d14) + + * src/utils/mimeparse.cpp, src/utils/mimeparse.h: + comments only + +2006-09-04 15:13 +0000 dockes (0f11e18480b2) + + * src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h, + src/qtgui/preview.ui, src/qtgui/preview.ui.h, + src/qtgui/preview_w.cpp, src/qtgui/preview_w.h, + src/qtgui/sort_w.cpp, src/qtgui/sort_w.h, src/qtgui/ssearch_w.cpp, + src/qtgui/ssearch_w.h, src/qtgui/uiprefs_w.cpp, + src/qtgui/uiprefs_w.h: new file. + * src/qtgui/preview/preview.pro, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/preview/pvmain.cpp: + deleted file. + * src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h, + src/qtgui/advsearch_w.cpp, src/qtgui/advsearch_w.h, + src/qtgui/guiutils.cpp, src/qtgui/main.cpp, src/qtgui/preview.ui, + src/qtgui/preview.ui.h, src/qtgui/preview/preview.pro, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/preview/pvmain.cpp, src/qtgui/preview_w.cpp, + src/qtgui/preview_w.h, src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/recoll.pro.in, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/qtgui/sort.ui, src/qtgui/sort.ui.h, + src/qtgui/sort_w.cpp, src/qtgui/sort_w.h, src/qtgui/ssearch_w.cpp, + src/qtgui/ssearch_w.h, src/qtgui/ssearchb.ui, + src/qtgui/ssearchb.ui.h, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs.ui.h, src/qtgui/uiprefs_w.cpp, + src/qtgui/uiprefs_w.h: + mostly cosmetic changes to prepare for a future qt4 port: better + separate form design from code + +2006-06-29 11:05 +0000 dockes (8f28af2cb548) + + * src/qt4gui/recollmain.ui: + *** empty log message *** + +2006-06-24 09:56 +0000 dockes (fb2180e4d577) + + * src/qt4gui/recollmain.ui: + qt4 cleanup: merged back rclmainbase and rclmain + +2006-06-24 07:40 +0000 dockes (e1b5ffd88b25) + + * src/Makefile.in, src/VERSION, src/configure, src/configure.ac, + src/doc/user/usermanual.sgml, src/qt4gui/recoll.pro.in, + src/qt4gui/recollmain.ui, src/recollinstall.in: + more qt4, unfinished + +2006-06-23 08:07 +0000 dockes (46a46e406504) + + * src/qt4gui/recoll.pro.in, src/qt4gui/recollmain.ui: new file. + * src/qt4gui/recoll.pro.in, src/qt4gui/recollmain.ui: + added qt4gui code from Gennadi Sushko + +2006-05-22 07:04 +0000 dockes (2663a50d4760) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo: + 1.4.3 + +2006-05-09 10:15 +0000 dockes (c9a62f0cb289) + + * src/rcldb/rcldb.cpp: + perform stem expansion using all active dbs + +2006-05-09 07:56 +0000 dockes (29feec461985) + + * src/qtgui/preview/preview.ui.h, src/qtgui/rclreslist.cpp: + esc quits preview + prev/next links + +2006-05-08 07:08 +0000 dockes (185da0be6900) + + * src/recollinstall.in: + install icon + +2006-05-08 07:08 +0000 dockes (7dbebc260389) + + * src/qtgui/rclreslist.cpp: + *** empty log message *** + +2006-05-07 14:18 +0000 dockes (2f273f645a91) + + * packaging/rpm/recoll.spec: + 1.4.3 + +2006-05-07 14:18 +0000 dockes (16b38a704d8e) + + * packaging/rpm/recoll.spec, packaging/rpm/recollmdk.spec: + 1.3.3 + +2006-05-07 14:10 +0000 dockes (4ab20caea142 [RECOLL-1_4_3]) + + * src/VERSION: + Release 1.4.3 + +2006-05-06 17:25 +0000 dockes (e7b4fd0f97fa) + + * src/recoll.png, src/recoll.xcf: new file. + * src/qtgui/recoll.pro.in, src/recoll.png, src/recoll.xcf: + *** empty log message *** + +2006-05-06 17:24 +0000 dockes (aae37ad598a9) + + * src/qtgui/recoll_ru.ts, src/qtgui/recoll_uk.ts: + new from michael + +2006-05-02 09:49 +0000 dockes (fb5bb4665925 [RECOLL-1_4_2]) + + * src/qtgui/guiutils.cpp, src/rcldb/stemdb.cpp, src/unac/unac.c: + more fbsd4 tweaks: Release 1.4.2 + +2006-04-30 07:44 +0000 dockes (d686e45d4b5e) + + * src/rcldb/rcldb.cpp: + fbsd4 tweaks + +2006-04-30 07:39 +0000 dockes (b889e57b87d6) + + * src/VERSION, src/index/indexer.cpp, src/index/indexer.h, + src/lib/Makefile, src/lib/mkMake: + fbsd4 tweaks + +2006-04-30 07:26 +0000 dockes (72f2881955d1 [RECOLL-1_4_1]) + + * src/Makefile.in, src/README: + *** empty log message *** + +2006-04-30 07:23 +0000 dockes (172a9e09b77c) + + * src/Makefile.in: + *** empty log message *** + +2006-04-30 07:20 +0000 dockes (7be76a62e017) + + * src/qtgui/recoll_fr.ts, src/qtgui/recoll_ru.ts, + src/qtgui/recoll_uk.ts: + lupdate+french + +2006-04-28 07:54 +0000 dockes (5b44017502c3) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/indexer.cpp, src/index/recollindex.cpp, + src/kde/kioslave/recoll/kio_recoll.cpp, src/qtgui/main.cpp, + src/query/qtry.cpp: + centralize dbdir computation in rclconfig+cat with conffdir if not + absolute + +2006-04-28 07:23 +0000 dockes (436f58f83459) + + * src/utils/transcode.cpp: + change debug log trace + +2006-04-27 09:23 +0000 dockes (3df68e37cdd9) + + * src/doc/user/usermanual.sgml, src/qtgui/guiutils.cpp, + src/qtgui/guiutils.h, src/qtgui/rclmain.cpp, src/qtgui/ssearchb.ui, + src/qtgui/ssearchb.ui.h: + make ssearch a combobox + +2006-04-27 06:12 +0000 dockes (e7c0f6cd73f0) + + * src/configure, src/configure.ac, src/lib/Makefile, src/lib/mkMake: + fix pb with .deps not existing + +2006-04-27 06:12 +0000 dockes (83e1c6a16ca6) + + * src/qtgui/preview/preview.ui.h, src/qtgui/rclmain.cpp, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + use getmatchingterms instead of getqueryterms for highlighting etc. + in preview + +2006-04-26 11:51 +0000 dockes (fa1cc55f05e9) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-04-26 11:29 +0000 dockes (d92273eb3274) + + * src/qtgui/rclmain.cpp, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h: + dblclck in reslist adds to search lineedit + +2006-04-25 09:59 +0000 dockes (16f32a4eda4c) + + * src/index/indexer.cpp, src/rcldb/rcldb.cpp: + new way for doc unique terms: only path for monodoc, only path+ipath + for doc inside multidoc, add pseudo-doc for file itself + +2006-04-25 08:17 +0000 dockes (4c947b29c23c) + + * src/common/textsplit.cpp, src/rcldb/rcldb.cpp: + fixed small glitch in abstract text splitting + +2006-04-23 13:37 +0000 dockes (ea8caddeb344) + + * src/lib/mkMake: new file. + * src/lib/mkMake: + *** empty log message *** + +2006-04-22 06:27 +0000 dockes (1b0dd24cad31) + + * src/qtgui/main.cpp, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/rclmain.cpp, + src/qtgui/rclmain.h, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h, src/qtgui/ssearchb.ui, + src/qtgui/ssearchb.ui.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/rcldb/searchdata.h: + turn-off abst. build for fname search (no terms) + prototype query + expansion (xapian e-set on chosen doc) + dbl-click in preview adds + term to ssearch + +2006-04-20 09:20 +0000 dockes (4b9c3c7bcb49) + + * src/common/rclconfig.cpp, src/lib/Makefile, src/qtgui/rclmain.cpp, + src/qtgui/rclmain.h, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/qtgui/sort.ui, src/qtgui/sort.ui.h, + src/qtgui/ssearchb.ui.h, src/query/sortseq.cpp, src/query/sortseq.h: + mode 700 on .recoll. move showquerydetails to rclreslist + +2006-04-19 08:26 +0000 dockes (9ec7ff1d0d53) + + * src/rcldb/searchdata.h: new file. + * src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h, + src/qtgui/main.cpp, src/qtgui/rclmain.h, src/qtgui/rclreslist.cpp, + src/qtgui/ssearchb.ui, src/qtgui/ssearchb.ui.h, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h, src/rcldb/searchdata.h: + compacted res list + completions in ssearch + additional or field + +2006-04-18 08:53 +0000 dockes (7c4352949f19) + + * src/index/recollindex.cpp, src/lib/Makefile, src/qtgui/advsearch.ui, + src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/rclmain.cpp, + src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h, + src/qtgui/recollmain.ui, src/qtgui/ssearchb.ui, + src/qtgui/ssearchb.ui.h, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs.ui.h: + new libs Makefile+autoSearchOnWS + +2006-04-15 17:15 +0000 dockes (cc178f316e64) + + * src/qtgui/main.cpp, src/query/Makefile: + small aix tweaks + +2006-04-15 16:51 +0000 dockes (356148054ef1) + + * src/mk/AIX: new file. + * src/mk/AIX: + *** empty log message *** + +2006-04-13 09:50 +0000 dockes (fe982a2684e4) + + * src/rcldb/stemdb.cpp, src/rcldb/stemdb.h: new file. + * src/lib/Makefile, src/rcldb/rcldb.cpp, src/rcldb/stemdb.cpp, + src/rcldb/stemdb.h: + extracted stem database from rcldb to make it smaller + +2006-04-12 10:41 +0000 dockes (6892025a5c8e) + + * src/index/indexer.cpp, src/index/indexer.h, src/qtgui/idxthread.cpp, + src/qtgui/idxthread.h, src/qtgui/rclmain.cpp, + src/qtgui/recollmain.ui, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + improve indexing status reporting + +2006-04-12 07:26 +0000 dockes (44ac63815611) + + * src/qtgui/rclmain.cpp, src/rcldb/rcldb.cpp: + Fix history not working after thread index run + +2006-04-11 07:14 +0000 dockes (bd453ed96f6a) + + * src/rcldb/rcldb.cpp: + fix rare case where stem itself was forgotten in list of possible + derivatives + +2006-04-11 06:49 +0000 dockes (dd7f793fdf8e) + + * src/common/textsplit.cpp, src/rcldb/rcldb.cpp, + src/utils/smallut.cpp, src/utils/smallut.h: + comments and moving some util routines out of rcldb.cpp + +2006-04-08 14:00 +0000 dockes (d60e656c348f) + + * src/VERSION, src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-04-07 13:10 +0000 dockes (dc4ff4178b85) + + * src/qtgui/advsearch.ui.h, src/rcldb/rcldb.cpp: + check for and forbid pure negative query + +2006-04-07 13:08 +0000 dockes (7da00eb0c7aa) + + * src/qtgui/guiutils.cpp: + RECOLL_EXTRA_DBS environment variable + +2006-04-07 13:07 +0000 dockes (f040ff3bf0aa) + + * src/doc/user/usermanual.sgml: + use indexing instead of indexation + +2006-04-07 08:51 +0000 dockes (52451e342e49) + + * src/internfile/mh_mail.cpp, src/internfile/mh_mail.h: + comments+conventions + +2006-04-06 17:39 +0000 dockes (7d2906a0371d) + + * packaging/FreeBSD/recoll/pkg-plist: + merge modif from committer + +2006-04-06 14:28 +0000 dockes (52d4a2c2a341) + + * src/sampleconf/recoll.conf.in: + stem only for english by default + +2006-04-06 13:09 +0000 dockes (fa565da09aa7 [RECOLL-1_4_0]) + + * src/VERSION: + 1.4.0 + +2006-04-06 13:08 +0000 dockes (1436c843e74e) + + * src/VERSION, src/rcldb/rcldb.h, src/recollinstall.in: + rpmlint wants 755 for execs + +2006-04-06 12:34 +0000 dockes (687369f6736c) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-04-05 15:41 +0000 dockes (359711d5fbe3) + + * src/recollinstall.in: + fix the installed file perms + +2006-04-05 13:39 +0000 dockes (fdd0d33d5c2e) + + * src/qtgui/guiutils.cpp, src/qtgui/uiprefs.ui, + src/qtgui/uiprefs.ui.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + small fixes for extra db selection + +2006-04-05 13:30 +0000 dockes (3277935457e9) + + * src/doc/user/usermanual.sgml: + small fixes + +2006-04-05 12:50 +0000 dockes (98d8d7d74aee) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/main.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs.ui.h, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h: + additional search databases + +2006-04-05 06:26 +0000 dockes (e8f1cc7c2bbf) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + simplified class structure + +2006-04-04 16:03 +0000 dockes (ddb66052e3e8 [RECOLL-1_4_0pre1]) + + * src/filters/rcldjvu, src/filters/rclmedia, src/filters/rclps, + src/filters/rclsoff: + handle paths with embedded spaces + +2006-04-04 15:44 +0000 dockes (933f89f10033) + + * src/filters/rcluncomp: + handle paths with embedded spaces + +2006-04-04 13:49 +0000 dockes (dec4932652ae) + + * src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp, src/qtgui/idxthread.cpp, + src/qtgui/idxthread.h, src/qtgui/rclmain.cpp: + make indexation more easily cancellable + +2006-04-04 12:37 +0000 dockes (17342a5b330b) + + * src/doc/user/usermanual.sgml, src/index/indexer.cpp, + src/index/indexer.h: + check for symlinks in the topdirs list. Generate diags in + confIndexer + +2006-04-04 10:38 +0000 dockes (ec632eb29364) + + * src/qtgui/guiutils.cpp, src/qtgui/rclreslist.cpp: + setup initial default window size smaller + +2006-04-04 09:36 +0000 dockes (d175998d9270) + + * src/common/unacpp.cpp, src/unac/unac.c: + clarify/clean up mem buffer handling + +2006-04-04 09:35 +0000 dockes (b14f9df37817) + + * src/utils/conftree.h: + fix potential minor memory leak when copying conftrees + +2006-04-04 09:34 +0000 dockes (aaddcbb06c7a) + + * src/index/indexer.cpp, src/index/indexer.h: + cosmetic: add m_ prefix to private vars + +2006-04-04 07:55 +0000 dockes (1bda0dcafd17) + + * src/qtgui/main.cpp, src/qtgui/preview/preview.ui.h, + src/qtgui/rclmain.cpp: + Get things to compile with QT_NO_STL + +2006-04-03 14:16 +0000 dockes (4957b439000e) + + * packaging/FreeBSD/recoll/Makefile: + add mods from port tree + +2006-04-03 12:59 +0000 dockes (62a51f626e46) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo: + *** empty log message *** + +2006-04-03 11:43 +0000 dockes (0449d2ba4099 [RECOLL-1_3_3]) + + * src/VERSION: + 1.3.3 + +2006-04-03 11:43 +0000 dockes (6b54e368d2d1) + + * src/common/rclconfig.cpp: + small port fixes for fbsd4 and solaris + +2006-04-03 09:42 +0000 dockes (cd9fe4976fae) + + * src/utils/execmd.cpp: + warning + +2006-04-01 21:02 +0000 dockes (eef792b97ce8 [RECOLL-1_3_2]) + + * src/VERSION, src/qtgui/rclmain.cpp: + limit max length of displayed query details. 1.3.2 + +2006-04-01 09:15 +0000 dockes (315da01fb1a5 [RECOLL-1_3_1]) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-04-01 09:15 +0000 dockes (e9f0a85fc18e) + + * src/INSTALL, src/README, src/qtgui/rclreslist.cpp, + src/qtgui/ssearchb.ui: + updated INSTALL+README. Fix tab focus in main window + +2006-04-01 08:07 +0000 dockes (916faf93fb66) + + * src/qtgui/rclmain.cpp: + urlencode file name before executing ext app with url param + +2006-04-01 07:48 +0000 dockes (adbde9cd60b9) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + plist: + 1.3.1 + +2006-04-01 07:34 +0000 dockes (4cd3e4e4074c) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap: + Allow ext edit for c/c++ files. 1.3.1 2? + +2006-03-31 17:19 +0000 dockes (35db6f17bdd8) + + * src/VERSION, src/qtgui/rclmain.cpp, src/qtgui/rclreslist.cpp, + src/qtgui/recoll_ru.ts, src/qtgui/recoll_uk.ts: + fixed reslist header charset issues. 1.3.1 first + +2006-03-31 09:02 +0000 dockes (ae3d9c9deb6d) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-03-31 07:51 +0000 dockes (0fccf51c6905 [RECOLL-1_3_1pre3]) + + * src/qtgui/recoll_uk.ts: new file. + * src/qtgui/recoll_uk.ts: + *** empty log message *** + +2006-03-30 13:00 +0000 dockes (b41828dda0ac) + + * src/common/Makefile: + cleanup rclconfig + +2006-03-30 10:31 +0000 dockes (afbdbc31ff1c) + + * src/sampleconf/recoll.conf.in: + dont set defaultcharset to 8859-1: will let nls info be used + +2006-03-30 10:31 +0000 dockes (582fa2a09db3) + + * src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-03-30 08:19 +0000 dockes (89efa1c78c3c [RECOLL-1_3_1pre2]) + + * src/qtgui/recoll_fr.ts, src/qtgui/recoll_ru.ts: + lupdate + +2006-03-30 07:54 +0000 dockes (0b236faa0b9d) + + * src/qtgui/advsearch.ui: + cleaned up layout + +2006-03-29 17:31 +0000 dockes (7cb115f5789c) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h, src/qtgui/main.cpp, + src/qtgui/ssearchb.ui, src/qtgui/ssearchb.ui.h: + gui: replaced checkboxes for all/filename in simple search with + droplist + +2006-03-29 13:08 +0000 dockes (ce199bb02759) + + * src/VERSION, src/common/Makefile, src/common/rclconfig.cpp, + src/common/rclconfig.h, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h, src/qtgui/rclreslist.cpp, + src/sampleconf/mimeconf, src/sampleconf/mimemap: + result list: show preview and edit links only when they can be used + +2006-03-29 11:18 +0000 dockes (5f22b93705b4) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/rclinit.cpp, src/index/indexer.cpp, + src/qtgui/preview/preview.ui.h, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/pathut.cpp, src/utils/pathut.h, src/utils/transcode.cpp, + src/utils/transcode.h: + try to better handle non-ascii file names + +2006-03-28 12:49 +0000 dockes (a081a1b65de1) + + * src/doc/man/recoll.conf.5, src/doc/user/usermanual.sgml, + src/qtgui/recoll.pro.in, src/recollinstall.in, + src/sampleconf/recoll.conf.in: + 1.3.1pre1 + +2006-03-28 12:18 +0000 dockes (7429c22d162b) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-03-28 09:38 +0000 dockes (25e1ed25acc5) + + * src/filters/rclmedia, src/qtgui/mtpics/sownd.png: new file. + * src/filters/rclmedia, src/qtgui/mtpics/sownd.png, + src/sampleconf/mimeconf, src/sampleconf/mimemap: + filter for indexing mp3 tags + +2006-03-28 09:36 +0000 dockes (fb852147db29) + + * src/internfile/mh_unknown.h: new file. + * src/internfile/mh_unknown.h: + added code to specifically index/search file names + +2006-03-22 16:24 +0000 dockes (4467274ce405) + + * src/index/indexer.cpp, src/index/indexer.h, src/qtgui/idxthread.cpp, + src/qtgui/idxthread.h, src/qtgui/rclmain.cpp, + src/qtgui/recollmain.ui: + show current filename as feedback during indexation + +2006-03-22 14:25 +0000 dockes (5dae5f8a140d) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/utils/conftree.cpp, src/utils/conftree.h: + Replace user config with central values + override + +2006-03-22 11:17 +0000 dockes (1f04e3bfeb4a) + + * src/qtgui/rclreslist.cpp: + fix size display + +2006-03-21 15:11 +0000 dockes (88d6359d2739) + + * src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h: + implement right click menu in result list + +2006-03-21 13:46 +0000 dockes (56610f5d03b3) + + * src/qtgui/rclmain.cpp, src/qtgui/rclreslist.cpp, + src/qtgui/rclreslist.h: + replaced (double)clicks in the result list with links + +2006-03-21 13:27 +0000 dockes (cc41e73a4f5a) + + * src/qtgui/rclreslist.cpp: + ckpt + +2006-03-21 11:04 +0000 dockes (b1dc67961a45) + + * src/index/mimetype.cpp: + sanity check on file -i return + +2006-03-21 09:15 +0000 dockes (8589c7c01f25) + + * src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h: new file. + * src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h: deleted file. + * src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/rclreslist.cpp, src/qtgui/rclreslist.h, + src/qtgui/recollmain.ui, src/qtgui/reslistb.ui, + src/qtgui/reslistb.ui.h: + reslistb form replaced by object derived from QTextBrowser + +2006-03-20 16:05 +0000 dockes (70c0ec0275a9) + + * src/VERSION, src/index/indexer.cpp, src/internfile/internfile.cpp, + src/internfile/mimehandler.cpp, src/qtgui/advsearch.ui, + src/qtgui/advsearch.ui.h, src/qtgui/ssearchb.ui, + src/qtgui/ssearchb.ui.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + added code to specifically index/search file names + +2006-03-20 15:14 +0000 dockes (86bb2d64fdd9) + + * src/internfile/mh_text.cpp: + get rid of unused temp + +2006-03-20 09:54 +0000 dockes (fea74448199d) + + * src/utils/pathut.h: + comments + +2006-03-20 09:54 +0000 dockes (bf4772fd96ff) + + * src/sampleconf/mimemap: + add # to ignd suffixes + +2006-03-20 09:51 +0000 dockes (218c67bcb769) + + * src/common/rclconfig.cpp, src/common/rclconfig.h: + try to get default charset from LANG if not in config + +2006-03-20 09:50 +0000 dockes (2d633e45c451) + + * src/makestaticdist.sh: + desktop file + +2006-03-16 14:00 +0000 dockes (b45dd89bb177) + + * src/recoll.desktop: new file. + * src/recoll.desktop: + initial version from Michael Shigorin + +2006-03-16 13:49 +0000 dockes (e3e216dfacb6) + + * src/qtgui/recoll_ru.ts: new file. + * src/qtgui/recoll_ru.ts: + initial version from Michael Shigorin + +2006-03-04 10:09 +0000 dockes (983d0984e972 [RECOLL-1_2_3]) + + * src/VERSION, src/doc/user/usermanual.sgml: + 1.2.3 + +2006-02-21 12:57 +0000 dockes (29500b27662b) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-02-21 12:56 +0000 dockes (0bc6bf836dfe) + + * src/Makefile.in, src/configure, src/configure.ac: + ensure Makefile uses same qmake as configure + +2006-02-21 12:52 +0000 dockes (9a69d49b1448) + + * src/query/docseq.h, src/query/sortseq.h: + sorted sequence title would never show + +2006-02-07 10:26 +0000 dockes (8881db16fe21) + + * src/qtgui/reslistb.ui.h, src/query/docseq.cpp, src/query/docseq.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + fix problems with doc fetch sequence (have to know where to stop) + +2006-02-07 09:44 +0000 dockes (fbfb30458fc2) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h: + replace computation of term positions in editor text with search for + 1st query term + +2006-02-03 11:47 +0000 dockes (1dbf9bcedfc0) + + * src/filters/rcldvi: + option to use catdvi + +2006-02-03 10:53 +0000 dockes (f219261a580b) + + * src/filters/rcldjvu, src/filters/rcldvi: new file. + * src/filters/rcldjvu, src/filters/rcldvi, src/filters/rclps, + src/sampleconf/mimeconf, src/sampleconf/mimemap: + added dvi and djvu support + +2006-02-02 09:45 +0000 dockes (71a4b9e391e0) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo: + 1.2.2 + +2006-02-02 08:58 +0000 dockes (c2f3b36a7169 [RECOLL-1_2_2]) + + * src/rcldb/rcldb.cpp, src/utils/pathut.cpp: + suppress 2 compilation warnings (one was actual 64bits bug but + inocuous + +2006-02-02 08:35 +0000 dockes (4d473bd0d9a8) + + * src/Makefile.in, src/VERSION, src/configure, src/configure.ac, + src/qtgui/main.cpp, src/qtgui/preview/preview.ui.h: + fix small cc glitches: qt3.1, xapian-config + +2006-02-01 14:34 +0000 dockes (a4deac6ede77 [RECOLL-1_2_1]) + + * src/qtgui/guiutils.cpp, src/qtgui/reslistb.ui.h: + fbsd4 cc + +2006-02-01 14:27 +0000 dockes (b005945089dc) + + * src/VERSION: + *** empty log message *** + +2006-02-01 14:18 +0000 dockes (1f6da4b2f946) + + * src/common/textsplit.cpp: + use string::erase() not clear() + +2006-02-01 09:00 +0000 dockes (09b3a24a6173 [RECOLL-1_2_0]) + + * src/recollinstall.in: + *** empty log message *** + +2006-02-01 08:19 +0000 dockes (bef8d87339d0) + + * packaging/rpm/recoll.spec: + *** empty log message *** + +2006-02-01 07:14 +0000 dockes (5c4deca7b177) + + * src/excludefile, src/utils/base64.cpp: + *** empty log message *** + +2006-02-01 07:12 +0000 dockes (77e021af3fa0) + + * src/INSTALL, src/README, src/doc/user/usermanual.sgml, + src/excludefile, src/makesrcdist.sh: + *** empty log message *** + +2006-01-31 11:39 +0000 dockes (73f22e91d844) + + * src/qtgui/reslistb.ui.h: + Clicking on "No results found" will also display the expanded query + +2006-01-31 11:39 +0000 dockes (c225bd05e9c1) + + * src/qtgui/recoll.h: + close/reopen db by default: let us see results of recollindex -i + +2006-01-30 12:51 +0000 dockes (cd40d5627d38) + + * src/qtgui/recoll_fr.ts: + *** empty log message *** + +2006-01-30 11:15 +0000 dockes (962649c706ef) + + * src/common/rclconfig.h, src/common/rclinit.h, + src/common/textsplit.h, src/common/unacpp.h, src/common/uproplist.h, + src/index/csguess.h, src/index/indexer.h, src/index/mimetype.h, + src/internfile/htmlparse.cpp, src/internfile/htmlparse.h, + src/internfile/indextext.h, src/internfile/internfile.h, + src/internfile/mh_exec.h, src/internfile/mh_html.h, + src/internfile/mh_mail.h, src/internfile/mh_text.h, + src/internfile/mimehandler.h, src/internfile/myhtmlparse.cpp, + src/internfile/myhtmlparse.h, src/qtgui/advsearch.ui.h, + src/qtgui/guiutils.h, src/qtgui/idxthread.h, + src/qtgui/plaintorich.h, src/qtgui/preview/preview.ui.h, + src/qtgui/rclmain.h, src/qtgui/recoll.h, src/qtgui/recollmain.ui.h, + src/qtgui/reslistb.ui.h, src/qtgui/sort.ui.h, + src/qtgui/ssearchb.ui.h, src/qtgui/uiprefs.ui.h, src/query/docseq.h, + src/query/history.h, src/query/sortseq.h, src/rcldb/pathhash.h, + src/rcldb/rcldb.h, src/utils/base64.h, src/utils/cancelcheck.h, + src/utils/conftree.h, src/utils/copyfile.h, src/utils/debuglog.h, + src/utils/execmd.h, src/utils/fstreewalk.h, src/utils/idfile.h, + src/utils/mimeparse.h, src/utils/pathut.h, src/utils/readfile.h, + src/utils/smallut.h, src/utils/transcode.h, src/utils/utf8iter.h, + src/utils/wipedir.h: + *** empty log message *** + +2006-01-30 10:01 +0000 dockes (f683194d38a4) + + * src/qtgui/preview/preview.ui.h: + dont highlight terms in very big docs: too slow + +2006-01-30 09:32 +0000 dockes (dc8cbf051f54) + + * src/mk/localdefs.in: + -O2 + +2006-01-30 09:28 +0000 dockes (af56f00261eb) + + * src/qtgui/guiutils.cpp, src/qtgui/main.cpp, src/qtgui/rclmain.cpp, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs.ui.h: + help browser selection in prefs + +2006-01-30 09:28 +0000 dockes (df275d18bee6) + + * src/utils/execmd.cpp: + *** empty log message *** + +2006-01-30 09:28 +0000 dockes (6d7b08c3bba0) + + * src/common/textsplit.cpp: + moved span cleanup where it belonged + +2006-01-28 15:36 +0000 dockes (b65e6344a9e4) + + * src/common/textsplit.cpp, src/common/textsplit.h: + *** empty log message *** + +2006-01-28 10:23 +0000 dockes (507b05e72779) + + * src/common/textsplit.cpp, src/common/textsplit.h, src/configure, + src/configure.ac, src/query/xadump.cpp, src/utils/utf8iter.h: + more textsplit tweaking + +2006-01-27 13:43 +0000 dockes (8ed38cba7965) + + * src/utils/cancelcheck.h: new file. + * src/utils/cancelcheck.h: + *** empty log message *** + +2006-01-27 13:43 +0000 dockes (fa13d8fe2fc9) + + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h: new file. + * src/qtgui/guiutils.cpp, src/qtgui/guiutils.h: + extracted code from main and others + +2006-01-27 13:42 +0000 dockes (96572eee9528) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/rclmain.cpp: + implement cancellation in preview loading + +2006-01-27 13:38 +0000 dockes (3ad2458e654a) + + * src/internfile/myhtmlparse.cpp: + strip whitespace and newlines (as the original version), except in + pre tags + +2006-01-27 13:37 +0000 dockes (80dbbac5b981) + + * src/filters/rcldoc, src/filters/rclpdf, src/filters/rclps, + src/filters/rclsoff: + fix to output
when needed + other misc pbs + +2006-01-27 13:34 +0000 dockes (538235c10cd7) + + * src/rcldb/rcldb.cpp: + define some constants and increase abstract context width + +2006-01-27 11:25 +0000 dockes (1d381cea9ec3) + + * src/internfile/htmlparse.cpp: + missing amp entity translation + +2006-01-26 17:59 +0000 dockes (15b82e0f9689) + + * src/internfile/mh_exec.cpp: + check for cancellation + +2006-01-26 17:59 +0000 dockes (81f5d1264b7d) + + * src/utils/execmd.cpp, src/utils/execmd.h: + also test cancel on select timeout + +2006-01-26 17:44 +0000 dockes (77efdf7b7e93) + + * src/utils/execmd.cpp, src/utils/execmd.h: + make execCmd exception-safe + +2006-01-26 14:02 +0000 dockes (ffd1ec38fb9f) + + * src/qtgui/main.cpp, src/qtgui/rclmain.cpp, src/qtgui/recoll.h, + src/qtgui/uiprefs.ui, src/qtgui/uiprefs.ui.h: + abstract params + +2006-01-26 14:01 +0000 dockes (c34965eaaa05) + + * src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h: + abstracts + doc sizes + +2006-01-26 12:30 +0000 dockes (c3718d2ceeae) + + * src/query/docseq.cpp: + let the db do whats needed to get a result count + +2006-01-26 12:29 +0000 dockes (bc0a233de310) + + * src/utils/smallut.cpp, src/utils/smallut.h: + chrono + +2006-01-26 12:28 +0000 dockes (69be9a0edd98) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + abstract building from position data + +2006-01-26 07:03 +0000 dockes (2c5403cbdbc1) + + * src/qtgui/recoll.pro: deleted file. + * src/qtgui/recoll.pro: + replaced by recoll.pro.in + +2006-01-26 07:03 +0000 dockes (7a03d26ad54d) + + * src/qtgui/recoll.pro, src/qtgui/recoll.pro.in, src/utils/smallut.h: + *** empty log message *** + +2006-01-26 07:02 +0000 dockes (de94ebf3cb51) + + * src/index/indexer.cpp: + pass size info to db.add + +2006-01-25 08:39 +0000 dockes (fc5ab7249caa) + + * src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h: + reenable stripping newlines + +2006-01-25 08:09 +0000 dockes (1ce613930379) + + * src/query/Makefile, src/query/xadump.cpp: + xadump improvements + +2006-01-24 12:22 +0000 dockes (6a16d14c076e) + + * src/qtgui/rclmain.cpp: + fix signal type + +2006-01-24 12:22 +0000 dockes (322a0f010b59) + + * src/utils/execmd.cpp, src/utils/execmd.h: + add feedback and possible cancellation + +2006-01-23 17:21 +0000 dockes (d16bcca9bc1e) + + * src/qtgui/images/d_nextpage.png, src/qtgui/images/d_prevpage.png: + new file. + * src/qtgui/images/d_nextpage.png, src/qtgui/images/d_prevpage.png, + src/qtgui/rclmain.cpp, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui: + slightly improved the icon situation + +2006-01-23 16:52 +0000 dockes (a51e0cfa77db) + + * src/qtgui/images/asearch.png, src/qtgui/images/history.png, + src/qtgui/images/nextpage.png, src/qtgui/images/prevpage.png, + src/qtgui/images/sortparms.png: + *** empty log message *** + +2006-01-23 15:43 +0000 dockes (907a44f71ddc) + + * src/qtgui/images/editcopy, src/qtgui/images/editcut, + src/qtgui/images/editpaste, src/qtgui/images/filenew, + src/qtgui/images/fileopen, src/qtgui/images/filesave, + src/qtgui/images/print, src/qtgui/images/redo, + src/qtgui/images/searchfind, src/qtgui/images/undo: deleted file. + * src/qtgui/images/editcopy, src/qtgui/images/editcut, + src/qtgui/images/editpaste, src/qtgui/images/filenew, + src/qtgui/images/fileopen, src/qtgui/images/filesave, + src/qtgui/images/print, src/qtgui/images/redo, + src/qtgui/images/searchfind, src/qtgui/images/undo: + *** empty log message *** + +2006-01-23 13:32 +0000 dockes (b27df12a0147) + + * src/common/rclconfig.cpp, src/common/rclinit.cpp, + src/common/textsplit.cpp, src/common/unacpp.cpp, + src/index/csguess.cpp, src/index/indexer.cpp, + src/index/mimetype.cpp, src/index/recollindex.cpp, + src/internfile/internfile.cpp, src/internfile/mh_exec.cpp, + src/internfile/mh_mail.cpp, src/internfile/mh_text.cpp, + src/internfile/mimehandler.cpp, src/query/docseq.cpp, + src/query/history.cpp, src/query/qtry.cpp, src/query/qxtry.cpp, + src/query/sortseq.cpp, src/query/xadump.cpp, src/rcldb/pathhash.cpp, + src/rcldb/rcldb.cpp, src/utils/base64.cpp, src/utils/conftree.cpp, + src/utils/copyfile.cpp, src/utils/debuglog.cpp, + src/utils/execmd.cpp, src/utils/fstreewalk.cpp, + src/utils/idfile.cpp, src/utils/mimeparse.cpp, src/utils/pathut.cpp, + src/utils/readfile.cpp, src/utils/smallut.cpp, + src/utils/transcode.cpp, src/utils/utf8iter.cpp, + src/utils/wipedir.cpp: + reference to GPL in all .cpp files + +2006-01-23 13:32 +0000 dockes (c2c52e3c568f) + + * src/qtgui/idxthread.cpp, src/qtgui/main.cpp, + src/qtgui/plaintorich.cpp, src/qtgui/rclmain.cpp, + src/qtgui/recoll.h, src/qtgui/recoll.pro, src/qtgui/reslistb.ui.h, + src/qtgui/uiprefs.ui.h: + more refactoring + +2006-01-23 07:15 +0000 dockes (639d2208e231) + + * src/qtgui/rclmain.cpp: + *** empty log message *** + +2006-01-23 07:07 +0000 dockes (29cad268f7ba) + + * src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, src/qtgui/reslistb.ui, + src/qtgui/reslistb.ui.h, src/qtgui/ssearchb.ui.h: + more modularization + +2006-01-22 18:46 +0000 dockes (c329a0d633e1) + + * src/qtgui/recoll.pro.in: new file. + * src/qtgui/main.cpp, src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/recoll.pro, src/qtgui/recoll.pro.in, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h, + src/qtgui/ssearchb.ui: + extract functionality from main window + +2006-01-22 15:16 +0000 dockes (f8f81a690e3d) + + * src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h: + *** empty log message *** + +2006-01-22 13:56 +0000 dockes (b62fca0983d3) + + * src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h, + src/qtgui/ssearchb.ui.h: new file. + * src/qtgui/reslistb.ui, src/qtgui/reslistb.ui.h, + src/qtgui/ssearchb.ui.h: + *** empty log message *** + +2006-01-22 07:41 +0000 dockes (50553b4f8d29 [T1_2]) + + * src/qtgui/ssearchb.ui: + *** empty log message *** + +2006-01-22 07:25 +0000 dockes (f5ecee171cca) + + * src/qtgui/ssearchb.ui: new file. + * src/qtgui/ssearchb.ui: + *** empty log message *** + +2006-01-21 15:36 +0000 dockes (283be80e303b) + + * src/configure: + *** empty log message *** + +2006-01-21 15:36 +0000 dockes (57061cf4c252) + + * src/Makefile.in, src/configure, src/configure.ac, + src/makesrcdist.sh, src/qtgui/recoll.pro: + enable building from inside qtgui/ + +2006-01-21 15:25 +0000 dockes (ce790ab8e905) + + * packaging/rpm/recollmdk.spec: new file. + * packaging/rpm/recollmdk.spec: + *** empty log message *** + +2006-01-21 10:47 +0000 dockes (47b92b35b369) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-01-20 14:58 +0000 dockes (9dfcca9b0073) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/qtgui/main.cpp, src/qtgui/preview/preview.ui.h, + src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, src/qtgui/recoll.h: + qt main program cleanup + +2006-01-20 12:46 +0000 dockes (04782d3c08bb) + + * src/qtgui/rclmain.cpp, src/qtgui/rclmain.h: new file. + * src/qtgui/main.cpp, src/qtgui/rclmain.cpp, src/qtgui/rclmain.h, + src/qtgui/recoll.pro, src/qtgui/recoll_fr.ts, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + separated code from design by subclassing recollmain + +2006-01-20 10:01 +0000 dockes (f1c90fc5dd19) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/kde/kioslave/recoll/00README.txt, src/mk/commondefs, + src/mk/localdefs.in, src/qtgui/idxthread.cpp, src/qtgui/idxthread.h, + src/qtgui/main.cpp, src/utils/conftree.h, src/utils/debuglog.h: + cleanup + +2006-01-19 17:11 +0000 dockes (b6465d0ee08c) + + * src/Makefile.in: new file. + * src/Makefile: deleted file. + * src/Makefile, src/Makefile.in, src/common/rclconfig.cpp, + src/common/rclconfig.h, src/configure, src/configure.ac, + src/internfile/internfile.cpp, src/internfile/mh_exec.cpp, + src/mk/localdefs.in, src/qtgui/main.cpp, src/qtgui/recoll.pro, + src/recollinstall.in: + slight config cleanup + +2006-01-19 15:08 +0000 dockes (211c1066ac8f) + + * src/kde/kioslave/recoll/00README.txt: new file. + * src/kde/kioslave/recoll/00README.txt: + end of test, doesnt look very useful + +2006-01-19 14:57 +0000 dockes (302ee688e96a) + + * src/kde/kioslave/recoll/kio_recoll.la: new file. + * src/kde/kioslave/recoll/Makefile, + src/kde/kioslave/recoll/kio_recoll.cpp, + src/kde/kioslave/recoll/kio_recoll.h, + src/kde/kioslave/recoll/kio_recoll.la: + end of initial experimentation + +2006-01-19 12:03 +0000 dockes (ffb549062074) + + * src/utils/Makefile: + *** empty log message *** + +2006-01-19 12:01 +0000 dockes (0e6b7d796f28) + + * packaging/FreeBSD/recoll/Makefile, src/Makefile, src/VERSION, + src/bincimapmime/Makefile, src/common/Makefile, + src/doc/user/usermanual.sgml, src/index/Makefile, + src/kde/kioslave/recoll/Makefile, + src/kde/kioslave/recoll/kio_recoll.cpp, + src/kde/kioslave/recoll/kio_recoll.h, src/lib/Makefile, + src/makestaticdist.sh, src/mk/Darwin, src/mk/FreeBSD, src/mk/Linux, + src/mk/SunOS, src/mk/commondefs, src/mk/localdefs.in, + src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/recollmain.ui.h, src/query/Makefile, src/utils/Makefile, + src/utils/smallut.cpp, src/utils/smallut.h: + misc small mods to help with building kio_recoll + +2006-01-18 13:41 +0000 dockes (ebf94c8fc21c) + + * src/kde/kioslave/recoll/Makefile, + src/kde/kioslave/recoll/kio_recoll.cpp, + src/kde/kioslave/recoll/kio_recoll.h, + src/kde/kioslave/recoll/recoll.protocol: new file. + * src/kde/kioslave/recoll/Makefile, + src/kde/kioslave/recoll/kio_recoll.cpp, + src/kde/kioslave/recoll/kio_recoll.h, + src/kde/kioslave/recoll/recoll.protocol: + *** empty log message *** + +2006-01-17 10:08 +0000 dockes (9784891fd0a7) + + * src/utils/mimeparse.h: + comments and clarification + +2006-01-17 09:31 +0000 dockes (08549e5e4a9e) + + * src/index/indexer.cpp, src/utils/fstreewalk.cpp, + src/utils/fstreewalk.h: + cleanup and comments + +2006-01-14 13:09 +0000 dockes (d7ac146b7dd5) + + * src/configure, src/configure.ac: + do a better search for qt configuration + +2006-01-14 11:48 +0000 dockes (d073ecc93317) + + * src/Makefile, src/configure, src/configure.ac: + do a better search for qt configuration + +2006-01-12 09:29 +0000 dockes (2dfd16f6a9a4 [RECOLL-1_1_0]) + + * src/qtgui/recoll_fr.ts: + *** empty log message *** + +2006-01-12 09:16 +0000 dockes (deb6607d43bf) + + * src/README: + *** empty log message *** + +2006-01-12 09:13 +0000 dockes (7635781b18c5) + + * src/qtgui/recollmain.ui.h, src/rcldb/rcldb.cpp: + handle removed docs in history + +2006-01-11 17:41 +0000 dockes (bd54a740def9) + + * src/qtgui/recollmain.ui.h: + *** empty log message *** + +2006-01-11 15:09 +0000 dockes (108917b10bf3) + + * src/qtgui/uiprefs.ui.h: new file. + * src/qtgui/uiprefs.ui.h: + *** empty log message *** + +2006-01-11 15:08 +0000 dockes (a03b6696412a) + + * src/doc/user/usermanual.sgml, src/index/Makefile, + src/qtgui/recoll_fr.ts, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/query/docseq.h, + src/query/sortseq.cpp, src/query/sortseq.h, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h: + translation of result list title. Show query details when clicking + on header + +2006-01-10 17:46 +0000 dockes (d4cc3428e381) + + * src/recollinstall.in: + *** empty log message *** + +2006-01-10 14:53 +0000 dockes (c873b3133cdd) + + * packaging/rpm/recoll.spec: + *** empty log message *** + +2006-01-10 13:52 +0000 dockes (ab4934e066f9) + + * src/recollinstall.in: + *** empty log message *** + +2006-01-10 13:41 +0000 dockes (23d6e8ae7155) + + * src/recollinstall.in: + *** empty log message *** + +2006-01-10 13:32 +0000 dockes (526cfe52f2e1) + + * src/recollinstall.in: + *** empty log message *** + +2006-01-10 13:27 +0000 dockes (a2f47b62ca03) + + * src/recollinstall.in: + *** empty log message *** + +2006-01-10 13:16 +0000 dockes (72d6ccffea15) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + plist, src/recollinstall.in: + install man pages + +2006-01-10 12:58 +0000 dockes (3a7d0fd4ceb7) + + * src/Makefile, src/common/rclconfig.cpp: + warning + +2006-01-10 12:55 +0000 dockes (aaeb49f89a98) + + * src/rcldb/rcldb.cpp: + include unistd + +2006-01-10 12:06 +0000 dockes (9b804748017f) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-01-10 11:07 +0000 dockes (01e4fe9772b0) + + * src/common/rclconfig.h, src/doc/user/usermanual.sgml, + src/index/recollindex.cpp, src/sampleconf/recoll.conf.in: + doc + got rid of unused defaultlanguage config param + +2006-01-10 09:10 +0000 dockes (34638d9bd009) + + * src/doc/man/recoll.conf.5: new file. + * src/doc/man/recoll.conf.5: + *** empty log message *** + +2006-01-10 08:14 +0000 dockes (a9b485ada811) + + * src/doc/man/recoll.1, src/doc/man/recollindex.1: new file. + * src/doc/man/recoll.1, src/doc/man/recollindex.1: + *** empty log message *** + +2006-01-09 16:53 +0000 dockes (29f37b7888d3) + + * src/excludefile, src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/Makefile, src/utils/pathut.cpp, src/utils/pathut.h: + allow independant creation / deletion of stem dbs + +2006-01-06 13:55 +0000 dockes (8831260252d9) + + * src/rcldb/rcldb.cpp: + do a better test for a capitalized query term (no stem expand) + +2006-01-06 13:20 +0000 dockes (82e02042773f) + + * src/qtgui/uiprefs.ui: new file. + * src/qtgui/uiprefs.ui: + *** empty log message *** + +2006-01-06 13:19 +0000 dockes (29cdbe2390e4) + + * src/utils/CaseFolding.txt, src/utils/caseconvert.cpp, + src/utils/caseconvert.h, src/utils/gencasefold.sh: deleted file. + * src/lib/Makefile, src/rcldb/rcldb.cpp, src/unac/unac.c, + src/unac/unac.h, src/utils/CaseFolding.txt, src/utils/Makefile, + src/utils/caseconvert.cpp, src/utils/caseconvert.h, + src/utils/gencasefold.sh: + integrated case-folding into unac for better performance + +2006-01-06 13:18 +0000 dockes (7840fc0ec48b) + + * src/common/Makefile, src/common/unacpp.cpp, src/common/unacpp.h, + src/rcldb/rcldb.cpp: + integrated case-folding into unac for better performance + +2006-01-06 13:10 +0000 dockes (15e715082e40) + + * unac/CaseFolding-3.2.0.txt: new file. + * unac/CaseFolding-3.2.0.txt, unac/builder.in, unac/unac.c, + unac/unac.h: + implemented additional case-folding + +2006-01-06 13:08 +0000 dockes (f27aa43e32ef [UNAC_1_7_0]) + + * unac/.version, unac/AUTHORS, unac/COPYING, unac/ChangeLog, + unac/INSTALL, unac/Makefile.am, unac/Makefile.in, unac/NEWS, + unac/README, unac/THANKS, unac/UnicodeData-3.2.0.txt, + unac/acinclude.m4, unac/aclocal.m4, unac/builder.in, + unac/config.guess, unac/config.h.in, unac/config.sub, + unac/configure, unac/configure.ac, unac/depcomp, unac/getopt.c, + unac/getopt.h, unac/install-sh, unac/ltconfig, unac/ltmain.sh, + unac/missing, unac/mkinstalldirs, unac/stamp-h.in, unac/t_unac.in, + unac/unac.3, unac/unac.c, unac/unac.h, unac/unac.pc.in, + unac/unac.spec.in, unac/unaccent.1, unac/unaccent.c, + unac/unactest.c, unac/unactest1.c: new file. + * unac/.version, unac/AUTHORS, unac/COPYING, unac/ChangeLog, + unac/INSTALL, unac/Makefile.am, unac/Makefile.in, unac/NEWS, + unac/README, unac/THANKS, unac/UnicodeData-3.2.0.txt, + unac/acinclude.m4, unac/aclocal.m4, unac/builder.in, + unac/config.guess, unac/config.h.in, unac/config.sub, + unac/configure, unac/configure.ac, unac/depcomp, unac/getopt.c, + unac/getopt.h, unac/install-sh, unac/ltconfig, unac/ltmain.sh, + unac/missing, unac/mkinstalldirs, unac/stamp-h.in, unac/t_unac.in, + unac/unac.3, unac/unac.c, unac/unac.h, unac/unac.pc.in, + unac/unac.spec.in, unac/unaccent.1, unac/unaccent.c, + unac/unactest.c, unac/unactest1.c: + initial import + +2006-01-06 07:59 +0000 dockes (52c86ee701fd) + + * src/index/Makefile, src/qtgui/recoll.pro: + ensure relink for changed lib + +2006-01-05 16:37 +0000 dockes (a2ef019b6308) + + * src/common/unacpp.cpp, src/common/unacpp.h, src/lib/Makefile, + src/rcldb/rcldb.cpp, src/utils/Makefile: + Use proper unicode lowercasing + +2006-01-05 16:16 +0000 dockes (158267ddbcb6) + + * src/utils/CaseFolding.txt, src/utils/caseconvert.cpp, + src/utils/caseconvert.h, src/utils/gencasefold.sh: new file. + * src/utils/CaseFolding.txt, src/utils/caseconvert.cpp, + src/utils/caseconvert.h, src/utils/gencasefold.sh: + *** empty log message *** + +2006-01-05 10:27 +0000 dockes (f1af15efef34) + + * packaging/rpm/recoll.spec: new file. + * packaging/rpm/recoll.spec: + *** empty log message *** + +2006-01-05 10:24 +0000 dockes (55284d2ed66e) + + * src/Makefile, src/recollinstall.in: + install tweaks for rpm compatibility + +2006-01-04 11:33 +0000 dockes (236c587eb180) + + * src/VERSION, src/common/rclconfig.h, src/makesrcdist.sh, + src/qtgui/main.cpp, src/qtgui/recoll.h, src/qtgui/recoll_fr.ts, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/recollinstall.in, src/utils/smallut.cpp, src/utils/smallut.h: + add menu entry to start browser on html doc + +2006-01-04 11:16 +0000 dockes (2075c2a6d71e) + + * src/INSTALL, src/README: + *** empty log message *** + +2006-01-04 11:09 +0000 dockes (9a4cceb219aa) + + * src/doc/user/Makefile, src/doc/user/docbook.css, + src/doc/user/usermanual.sgml: new file. + * src/doc/user/Makefile, src/doc/user/docbook.css, + src/doc/user/usermanual.sgml: + *** empty log message *** + +2006-01-03 11:35 +0000 dockes (188ffc87b7d3) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-12-16 10:08 +0000 dockes (789da9d2380c) + + * src/query/Makefile, src/query/xadump.cpp, src/unac/unac.c, + src/utils/mimeparse.cpp: + 64 bits fixes + +2005-12-16 10:06 +0000 dockes (cf18fa6d2a7b) + + * src/Makefile, src/mk/localdefs.in, src/qtgui/main.cpp, + src/qtgui/recoll.pro, src/recollinstall.in: + get prefix to really work + +2005-12-16 08:00 +0000 dockes (cca6b156e460) + + * src/excludefile: + dont copy localdefs + +2005-12-16 07:58 +0000 dockes (7b20df9408ce) + + * src/mk/localdefs: deleted file. + * src/mk/localdefs: + *** empty log message *** + +2005-12-15 14:39 +0000 dockes (959564d835fd) + + * src/qtgui/main.cpp, src/qtgui/recoll.h, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/sampleconf/recoll.conf.in: + user prefs tweaks. Allow switching stemlang from ui + +2005-12-15 13:41 +0000 dockes (bf3c45bf931d) + + * src/qtgui/main.cpp: + *** empty log message *** + +2005-12-14 16:15 +0000 dockes (229d1902798e) + + * src/qtgui/main.cpp, src/qtgui/recoll.h, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + user interface preferences settable from ui + +2005-12-14 11:00 +0000 dockes (3e5f6f1c000d) + + * src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp, src/internfile/mh_html.cpp, + src/internfile/mh_text.cpp, src/qtgui/preview/preview.ui.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/Makefile: + allow indexing individual files. Fix pb with preview and charsets + (local defcharset ignored) + +2005-12-13 17:20 +0000 dockes (0895be2b8196) + + * src/qtgui/main.cpp, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h: + add allTerms checkbutton, save state in settings + +2005-12-13 17:20 +0000 dockes (b522d74e613c) + + * src/qtgui/advsearch.ui: + avoid activating random buttons when typing CR... + +2005-12-13 12:43 +0000 dockes (0448daf8c23e) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist, src/common/rclconfig.cpp, + src/doc/prog/Doxyfile, src/doc/prog/Makefile, + src/doc/prog/filters.txt, src/qtgui/main.cpp, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/utils/fstreewalk.cpp, src/utils/pathut.cpp, + src/utils/pathut.h, src/utils/smallut.cpp, src/utils/wipedir.cpp: + pgup/down in result list + +2005-12-08 08:44 +0000 dockes (ec006d171797) + + * src/common/Makefile, src/internfile/htmlparse.cpp, + src/internfile/htmlparse.h, src/internfile/internfile.cpp, + src/internfile/mh_html.cpp, src/internfile/myhtmlparse.cpp, + src/internfile/myhtmlparse.h: + process text from html files without a tag + +2005-12-07 15:41 +0000 dockes (a44bf0c6a081 [RECOLL-1_0_14]) + + * src/VERSION, src/internfile/mh_mail.cpp, + src/qtgui/preview/preview.ui.h, src/qtgui/recollmain.ui.h, + src/query/docseq.cpp, src/utils/utf8iter.h: + freebsd 4 port + +2005-12-06 15:59 +0000 dockes (812bc8f9232b) + + * packaging/FreeBSD/recoll/distinfo: + 0.13 really now + +2005-12-06 15:41 +0000 dockes (3a7b74624ff4) + + * src/recollinstall.in: + strip execs + +2005-12-06 15:20 +0000 dockes (fa8c19799a41) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + plist: + recoll-0.13 + +2005-12-06 15:10 +0000 dockes (b6df28b0d0e3) + + * src/README: + *** empty log message *** + +2005-12-06 15:10 +0000 dockes (e66dba4d628c [RECOLL-1_0_13]) + + * src/Makefile, src/VERSION, src/recollinstall.in: + no recollinstall install + +2005-12-06 12:55 +0000 dockes (cbfcc5627111) + + * packaging/FreeBSD/recoll/pkg-descr: + *** empty log message *** + +2005-12-06 10:30 +0000 dockes (d132e05e40ac) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist: + *** empty log message *** + +2005-12-06 09:40 +0000 dockes (f93d6a9b2336) + + * src/internfile/mh_html.cpp, src/internfile/myhtmlparse.cpp: + previous html fix didnt work + +2005-12-06 08:35 +0000 dockes (a3eec94f6861) + + * src/VERSION, src/internfile/internfile.cpp, + src/internfile/mh_html.cpp, src/internfile/myhtmlparse.cpp: + fix nasty html parse bug introduced in 1.0.9 + +2005-12-06 07:16 +0000 dockes (c1ccf42bf359 [RECOLL-1_0_12, RECOLL-1_0_11]) + + * src/qtgui/recollmain.ui: + move search/clear buttons to the left side + +2005-12-05 17:47 +0000 dockes (37952b251aee) + + * src/VERSION: + 1.0.11? + +2005-12-05 16:45 +0000 dockes (eecd7a311e8f) + + * src/qtgui/recollmain.ui.h: + no %F on solaris8 + +2005-12-05 16:13 +0000 dockes (cd9899dcdec1) + + * src/utils/copyfile.cpp: + *** empty log message *** + +2005-12-05 16:13 +0000 dockes (7e7e675138b2) + + * src/query/docseq.cpp, src/query/docseq.h: + avoid unneeded getDoc(0) + normalize private var names + +2005-12-05 15:00 +0000 dockes (6aa562bb0180) + + * src/INSTALL, src/Makefile, src/README, src/qtgui/main.cpp: + *** empty log message *** + +2005-12-05 14:09 +0000 dockes (d3954ac2c5ec) + + * src/utils/copyfile.cpp, src/utils/copyfile.h: new file. + * src/common/rclconfig.cpp, src/lib/Makefile, src/mk/localdefs, + src/mk/localdefs.in, src/utils/copyfile.cpp, src/utils/copyfile.h: + create personal config if it does not exist + +2005-12-05 12:02 +0000 dockes (6d38fb24e3b1) + + * src/qtgui/images/asearch.png, src/qtgui/images/history.png, + src/qtgui/images/nextpage.png, src/qtgui/images/prevpage.png, + src/qtgui/images/sortparms.png: new file. + * src/qtgui/images/asearch.png, src/qtgui/images/history.png, + src/qtgui/images/nextpage.png, src/qtgui/images/prevpage.png, + src/qtgui/images/sortparms.png, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/qtgui/sort.ui.h, + src/query/docseq.cpp, src/query/sortseq.cpp: + use toolbar buttons for prev/next + misc cleanups + +2005-12-05 10:39 +0000 dockes (55a212b17808) + + * src/rcldb/rcldb.cpp: + also index file path as terms + +2005-12-04 17:10 +0000 dockes (a4005adeece9) + + * src/qtgui/recoll.pro: + more + +2005-12-04 17:10 +0000 dockes (15ce414ea700) + + * src/common/textsplit.cpp: + split stdin + +2005-12-04 14:58 +0000 dockes (369372321681) + + * src/qtgui/recollmain.ui: + *** empty log message *** + +2005-12-02 16:18 +0000 dockes (b8ea8500fe26) + + * src/qtgui/preview/preview.ui.h, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/qtgui/sort.ui, src/qtgui/sort.ui.h, + src/query/sortseq.cpp, src/query/sortseq.h, src/rcldb/rcldb.h: + 1st version of sorting interface. Needs polishing + +2005-12-02 16:17 +0000 dockes (fba2b55c4ba7) + + * src/filters/rclpdf: + new version of pdftotext broke us + +2005-12-02 16:17 +0000 dockes (a31234c89a73) + + * src/common/rclconfig.cpp, src/recollinstall.in, + src/sampleconf/recoll.conf.in: + install filters to /usr/local + +2005-12-02 14:18 +0000 dockes (7b585689ce4a) + + * src/query/sortseq.cpp: + *** empty log message *** + +2005-12-01 16:23 +0000 dockes (c7393c3bc8b5) + + * src/qtgui/sort.ui, src/qtgui/sort.ui.h, src/query/sortseq.cpp, + src/query/sortseq.h: new file. + * src/lib/Makefile, src/qtgui/recoll.pro, src/qtgui/recollmain.ui.h, + src/qtgui/sort.ui, src/qtgui/sort.ui.h, src/query/sortseq.cpp, + src/query/sortseq.h: + sorting 1st steps + +2005-11-30 18:37 +0000 dockes (ddba9ec4f65f) + + * src/configure: + make recollinstall executable + +2005-11-30 18:28 +0000 dockes (35f236d5ad1f) + + * src/configure.ac: + make recollinstall executable + +2005-11-30 18:26 +0000 dockes (580ae261b629) + + * src/sampleconf/recoll.conf.in: + keep log level at 4 for index feedback + +2005-11-30 18:20 +0000 dockes (2fb51c4552fb) + + * src/sampleconf/recoll.conf.in: + decrease log level + +2005-11-30 18:10 +0000 dockes (0ad46d9bcaa5) + + * src/query/history.cpp: + *** empty log message *** + +2005-11-30 18:05 +0000 dockes (653e0a145731) + + * src/qtgui/form1.ui.h: deleted file. + * src/excludefile, src/qtgui/form1.ui.h: + *** empty log message *** + +2005-11-30 18:04 +0000 dockes (dfff4ecb1918) + + * src/qtgui/form1.ui: deleted file. + * src/excludefile, src/qtgui/form1.ui: + *** empty log message *** + +2005-11-30 18:01 +0000 dockes (a63a8d7c49f3) + + * src/excludefile: + *** empty log message *** + +2005-11-30 17:58 +0000 dockes (7676c325de57) + + * src/excludefile: + *** empty log message *** + +2005-11-30 17:58 +0000 dockes (6ddc4c210c87) + + * src/utils/transcode.cpp: + try harder to convert bad encodings + +2005-11-30 10:36 +0000 dockes (7e0aab848f91 [RECOLL-1_0_10]) + + * src/README, src/qtgui/recollmain.ui: + *** empty log message *** + +2005-11-30 10:35 +0000 dockes (1f97b79ea735) + + * src/VERSION: + v1.0.10 + +2005-11-30 10:25 +0000 dockes (3c2bcb1ec527) + + * src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + disable/enable buttons dep. on state + +2005-11-30 09:46 +0000 dockes (a75b091acbae) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h, + src/sampleconf/mimeconf: + *** empty log message *** + +2005-11-30 09:46 +0000 dockes (30a527e5014f) + + * src/index/indexer.cpp, src/index/indexer.h, + src/index/recollindex.cpp, src/rcldb/rcldb.cpp: + add option to rezero db before index + +2005-11-28 15:31 +0000 dockes (d9e31422258b) + + * src/qtgui/main.cpp, src/qtgui/recoll.h, src/qtgui/recollmain.ui.h, + src/query/docseq.cpp, src/query/docseq.h, src/query/history.cpp, + src/query/history.h: + store and display dates in history. Needs more work + +2005-11-25 14:36 +0000 dockes (18bc54d4e426) + + * src/qtgui/recollmain.ui.h, src/query/history.cpp, + src/utils/conftree.cpp, src/utils/smallut.cpp, src/utils/smallut.h: + show history newest first + prune duplicate entries + +2005-11-25 10:26 +0000 dockes (3ad346d3f29e) + + * src/qtgui/main.cpp, src/qtgui/recoll_fr.ts, src/recollinstall.in: + install translations to share/recoll/translations + +2005-11-25 10:02 +0000 dockes (6ed5669a337b) + + * src/query/docseq.cpp, src/query/docseq.h: new file. + * src/lib/Makefile, src/qtgui/main.cpp, src/qtgui/recoll.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/docseq.cpp, src/query/docseq.h: + 1st version of doc history + +2005-11-25 09:14 +0000 dockes (69bab5c09012) + + * src/index/indexer.cpp, src/index/mimetype.cpp, + src/sampleconf/mimeconf: + *** empty log message *** + +2005-11-25 09:13 +0000 dockes (55e99bcc0a46) + + * src/common/rclconfig.cpp, src/common/rclconfig.h: + get all mime list from mimeconf, not mimemap + +2005-11-25 09:12 +0000 dockes (87febfb9c3be) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + added method to retrieve doc from path/ipath + +2005-11-25 08:53 +0000 dockes (756168516697) + + * src/Makefile, src/internfile/mimehandler.cpp, src/rcldb/rcldb.h: + *** empty log message *** + +2005-11-25 08:50 +0000 dockes (6fda25d19678) + + * src/utils/conftree.cpp, src/utils/conftree.h, src/utils/smallut.cpp, + src/utils/smallut.h: + add methods useful for history. move stuff to smallut + +2005-11-25 08:49 +0000 dockes (bd6b75c162a5) + + * src/utils/base64.cpp: + Strip extra null byte that we were appending + +2005-11-24 18:21 +0000 dockes (ba604719481c) + + * src/query/history.cpp, src/query/history.h: new file. + * src/query/Makefile, src/query/history.cpp, src/query/history.h, + src/query/qtry.cpp, src/query/xadump.cpp: + *** empty log message *** + +2005-11-24 07:16 +0000 dockes (1fc7382994a5) + + * src/recollinstall.in, src/sampleconf/recoll.conf.in: new file. + * src/bincimapmime/address.cc, src/bincimapmime/convert.cc, + src/bincimapmime/iodevice.cc, src/bincimapmime/iofactory.cc, + src/bincimapmime/mime-getpart.cc, src/bincimapmime/mime- + parsefull.cc, src/bincimapmime/mime-parseonlyheader.cc, + src/bincimapmime/mime-printbody.cc, src/bincimapmime/mime- + printdoc.cc, src/bincimapmime/mime-printheader.cc, src/bincimapmime + /mime-utils.h, src/bincimapmime/mime.cc, src/bincimapmime/trbinc.cc, + src/common/rclconfig.cpp, src/common/textsplit.cpp, + src/common/unacpp.cpp, src/configure, src/configure.ac, + src/index/csguess.cpp, src/index/indexer.cpp, + src/index/mimetype.cpp, src/internfile/htmlparse.cpp, + src/internfile/htmlparse.h, src/internfile/internfile.cpp, + src/internfile/mh_exec.cpp, src/internfile/mh_html.cpp, + src/internfile/mh_mail.cpp, src/internfile/mh_text.cpp, + src/internfile/mimehandler.cpp, src/makestaticdist.sh, + src/qtgui/advsearch.ui.h, src/qtgui/main.cpp, + src/qtgui/plaintorich.cpp, src/qtgui/preview/preview.ui.h, + src/qtgui/preview/pvmain.cpp, src/qtgui/recollmain.ui.h, + src/query/qtry.cpp, src/query/qxtry.cpp, src/query/xadump.cpp, + src/rcldb/pathhash.cpp, src/rcldb/rcldb.cpp, src/recollinstall.in, + src/sampleconf/recoll.conf.in, src/utils/base64.cpp, + src/utils/execmd.cpp, src/utils/fstreewalk.cpp, + src/utils/idfile.cpp, src/utils/mimeparse.cpp, src/utils/pathut.cpp, + src/utils/readfile.cpp, src/utils/smallut.cpp, src/utils/smallut.h, + src/utils/transcode.cpp, src/utils/utf8iter.cpp, + src/utils/wipedir.cpp: + *** empty log message *** + +2005-11-23 13:12 +0000 dockes (a8ff464ec720) + + * src/recollinstall, src/sampleconf/recoll.conf: deleted file. + * src/recollinstall, src/sampleconf/recoll.conf: + *** empty log message *** + +2005-11-23 11:11 +0000 dockes (4ba2ad248537) + + * src/utils/execmd.cpp: + *** empty log message *** + +2005-11-23 11:00 +0000 dockes (66cac25635e1) + + * src/INSTALL, src/README, src/rcldb/rcldb.cpp: + *** empty log message *** + +2005-11-23 10:57 +0000 dockes (45f106d04652 [RECOLL-1_0_9]) + + * src/Makefile: + use prefix instead of PREFIX + +2005-11-23 10:19 +0000 dockes (e7a6edd38c56) + + * src/Makefile, src/VERSION, src/filters/rclrtf, src/index/Makefile, + src/index/mimetype.cpp, src/utils/debuglog.cpp, + src/utils/mimeparse.cpp: + *** empty log message *** + +2005-11-23 10:18 +0000 dockes (4e530d6556d2) + + * src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/recollmain.ui.h: + document already shown test was wrong, wouldnt show more docs from + same file + +2005-11-23 10:17 +0000 dockes (9944ac86338d) + + * src/utils/execmd.cpp: + need to do _exit not exit after exec failure + +2005-11-23 10:16 +0000 dockes (085c66533884) + + * src/internfile/mh_html.cpp, src/utils/smallut.cpp, + src/utils/smallut.h: + improve charset name comparison + +2005-11-21 17:18 +0000 dockes (9c398b7ee69e [RECOLL-1_0_8]) + + * src/configure, src/configure.ac, src/index/mimetype.cpp, + src/internfile/myhtmlparse.cpp, src/mk/Linux, src/mk/SunOS, + src/recollinstall, src/utils/execmd.cpp: + glitches in linux/solaris compil. + install + +2005-11-21 16:16 +0000 dockes (7594b3dd0dc5) + + * src/README: + *** empty log message *** + +2005-11-21 16:06 +0000 dockes (8a82b3826a4a) + + * src/VERSION: + *** empty log message *** + +2005-11-21 16:05 +0000 dockes (9cc42706006d) + + * src/filters/rclrtf: new file. + * src/filters/rclrtf, src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/recoll.conf: + add support for rtf + +2005-11-21 16:04 +0000 dockes (8169ca3ae210) + + * src/Makefile, src/makestaticdist.sh, src/recollinstall: + install pics and samples to $PREFIX/local/recoll + +2005-11-21 14:32 +0000 dockes (f0aaac1df843) + + * src/filters/rclgaim: + just needs awk + +2005-11-21 14:31 +0000 dockes (88649af9a0ac [RECOLL-1_0_7]) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/indexer.cpp, src/index/mimetype.cpp, src/index/mimetype.h, + src/internfile/internfile.cpp, src/internfile/mh_html.cpp, + src/internfile/mimehandler.cpp, src/internfile/mimehandler.h, + src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h, + src/lib/Makefile, src/qtgui/recollmain.ui.h, + src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/recoll.conf: + mimemap processing recentered in rclconfig. Handle directory-local + suffix to mime-type definitions. Implement gaim log handling + +2005-11-18 17:03 +0000 dockes (ae7d483398d2) + + * src/filters/rclgaim: new file. + * src/filters/rclgaim: + *** empty log message *** + +2005-11-18 15:19 +0000 dockes (9c8cb27e5749) + + * src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mh_exec.cpp, src/internfile/mimehandler.h, + src/utils/execmd.h: + misc cleanup + tell filters if working for preview or index + +2005-11-18 13:52 +0000 dockes (9d83fd6a7d8c) + + * src/utils/execmd.cpp, src/utils/execmd.h: + add putenv interface + +2005-11-18 13:23 +0000 dockes (c3d0cfc77a9f) + + * src/internfile/mh_exec.cpp, src/internfile/mh_exec.h, + src/internfile/mh_text.cpp, src/internfile/mh_text.h: new file. + * src/internfile/mh_exec.cpp, src/internfile/mh_exec.h, + src/internfile/mh_html.cpp, src/internfile/mh_html.h, + src/internfile/mh_mail.cpp, src/internfile/mh_mail.h, + src/internfile/mh_text.cpp, src/internfile/mh_text.h, + src/internfile/mimehandler.cpp, src/lib/Makefile: + restructuring on mimehandler files + +2005-11-17 17:39 +0000 dockes (e530dcacaf42) + + * src/VERSION: + *** empty log message *** + +2005-11-17 17:36 +0000 dockes (64437283f61f) + + * src/rcldb/rcldb.cpp: + use OP_FILTER instead of OP_AND to filter on file types + +2005-11-17 12:47 +0000 dockes (e9efe66d79c0) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/qtgui/main.cpp, src/qtgui/recollmain.ui, + src/sampleconf/recoll.conf, src/utils/conftree.cpp, + src/utils/conftree.h: + allow tilde expansion for section names in config file + +2005-11-16 18:31 +0000 dockes (e319e6fa047d) + + * src/qtgui/recollmain.ui.h: + *** empty log message *** + +2005-11-16 17:30 +0000 dockes (70dbf29f84e0) + + * src/excludefile: + *** empty log message *** + +2005-11-16 17:29 +0000 dockes (4c957598f6fd [RECOLL-1_0_6]) + + * src/mk/localdefs, src/rcldb/rcldb.cpp: + use and_maybe in adv search + +2005-11-16 15:07 +0000 dockes (a19870cd6761) + + * src/internfile/mimehandler.cpp, src/internfile/mimehandler.h, + src/qtgui/main.cpp, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/recoll.h, + src/qtgui/recollmain.ui.h, src/sampleconf/mimeconf, + src/sampleconf/recoll.conf: + Optionnally show mime type icons in result list + +2005-11-16 15:05 +0000 dockes (6464421540ca) + + * src/qtgui/mtpics/README, src/qtgui/mtpics/document.png, + src/qtgui/mtpics/drawing.png, src/qtgui/mtpics/html.png, + src/qtgui/mtpics/message.png, src/qtgui/mtpics/mozilla_doc.png, + src/qtgui/mtpics/pdf.png, src/qtgui/mtpics/postscript.png, + src/qtgui/mtpics/presentation.png, src/qtgui/mtpics/soffice.png, + src/qtgui/mtpics/spreadsheet.png, src/qtgui/mtpics/txt.png, + src/qtgui/mtpics/wordprocessing.png: new file. + * src/qtgui/mtpics/README, src/qtgui/mtpics/document.png, + src/qtgui/mtpics/drawing.png, src/qtgui/mtpics/html.png, + src/qtgui/mtpics/message.png, src/qtgui/mtpics/mozilla_doc.png, + src/qtgui/mtpics/pdf.png, src/qtgui/mtpics/postscript.png, + src/qtgui/mtpics/presentation.png, src/qtgui/mtpics/soffice.png, + src/qtgui/mtpics/spreadsheet.png, src/qtgui/mtpics/txt.png, + src/qtgui/mtpics/wordprocessing.png: + *** empty log message *** + +2005-11-16 11:22 +0000 dockes (f29236269564) + + * src/qtgui/plaintorich.cpp, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/recollmain.ui.h: + Implemented better feedback during preview loading + +2005-11-16 08:17 +0000 dockes (44b8c2233623) + + * src/Makefile, src/VERSION, src/qtgui/main.cpp, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/recoll_fr.ts, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h: + about dialog, remember previous mainwin geometry + +2005-11-14 09:59 +0000 dockes (f196f00bd521) + + * src/internfile/internfile.cpp, src/internfile/internfile.h, + src/qtgui/recollmain.ui.h: + fix rare case where indexed file could not be previewed because of + change in file identification config param + +2005-11-14 09:57 +0000 dockes (5610887cf602) + + * src/index/indexer.cpp: + comment + +2005-11-14 09:56 +0000 dockes (b6c7dd9504b9) + + * src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + stem expansion was never done for adv search + +2005-11-12 14:36 +0000 dockes (87b02b667eef) + + * src/README, src/mk/Linux: + *** empty log message *** + +2005-11-12 14:33 +0000 dockes (5743f1558790) + + * src/mk/localdefs.in: + typo + +2005-11-12 14:31 +0000 dockes (0dd4948b5c2f) + + * src/Makefile, src/configure, src/configure.ac: + more config tweaks + +2005-11-12 14:24 +0000 dockes (6d47a227c1b2) + + * src/utils/conftree.cpp, src/utils/conftree.h, + src/utils/debuglog.cpp, src/utils/debuglog.h: new file. + * src/utils/conftree.cpp, src/utils/conftree.h, + src/utils/debuglog.cpp, src/utils/debuglog.h: + local versions of utility files + +2005-11-12 14:23 +0000 dockes (c77e47fdc6fb) + + * src/Makefile: + *** empty log message *** + +2005-11-12 14:19 +0000 dockes (49499e32e341) + + * src/configure.ac, src/mk/localdefs, src/mk/localdefs.in: new file. + * src/Makefile, src/configure, src/configure.ac, src/mk/Darwin, + src/mk/FreeBSD, src/mk/Linux, src/mk/SunOS, src/mk/commondefs, + src/mk/localdefs, src/mk/localdefs.in: + introduced some autoconf + +2005-11-12 11:26 +0000 dockes (b13e733c2796) + + * src/Makefile, src/bincimapmime/Makefile, src/common/Makefile, + src/index/Makefile, src/lib/Makefile, src/mk/commondefs, + src/qtgui/recoll.pro, src/query/Makefile, src/sampleconf/mimemap, + src/utils/Makefile: + cleaned-up makes + +2005-11-10 08:47 +0000 dockes (06490e6e7dc1) + + * src/index/Makefile, src/index/indexer.cpp, src/index/indexer.h, + src/index/mimetype.cpp, src/index/mimetype.h, + src/internfile/internfile.cpp, src/sampleconf/recoll.conf: + add config parameter to decide if we use the file command as a final + step of mimetype identification + +2005-11-10 08:46 +0000 dockes (d9a64999d22d) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap: + add .Z compressed files + +2005-11-09 21:40 +0000 dockes (1dd753a59d1c) + + * src/sampleconf/mimemap: + add .odt -> openoffice. Add .php and others to ignored types + +2005-11-09 21:39 +0000 dockes (a8b54cf24c83) + + * src/common/rclinit.cpp: + test cleanup and sigcleanup not zero for small uts that dont need + this + +2005-11-08 21:02 +0000 dockes (344fc56239c8) + + * src/internfile/internfile.cpp, src/internfile/mh_html.cpp, + src/internfile/mh_html.h, src/internfile/mh_mail.cpp, + src/internfile/mh_mail.h, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h: + renamed MimeHandler::worker to mkDoc + comments for doxygen + +2005-11-08 21:02 +0000 dockes (1ac76bfea47d) + + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist, src/doc/prog/filters.txt, + src/doc/prog/top.txt: new file. + * packaging/FreeBSD/recoll/Makefile, + packaging/FreeBSD/recoll/distinfo, packaging/FreeBSD/recoll/pkg- + descr, packaging/FreeBSD/recoll/pkg-plist, src/doc/prog/Doxyfile, + src/doc/prog/Makefile, src/doc/prog/filters.txt, + src/doc/prog/top.txt: + *** empty log message *** + +2005-11-08 21:00 +0000 dockes (54bcdfd186f1) + + * src/doc/prog/Doxyfile, src/doc/prog/Makefile: new file. + * src/doc/prog/Doxyfile, src/doc/prog/Makefile: + *** empty log message *** + +2005-11-07 15:52 +0000 dockes (a0bde5fbc55b [RECOLL-1_0_5]) + + * src/INSTALL, src/Makefile, src/README, src/excludefile, + src/makesrcdist.sh, src/makestaticdist.sh: + *** empty log message *** + +2005-11-07 15:37 +0000 dockes (c6a8f5375981) + + * src/README: + *** empty log message *** + +2005-11-07 15:36 +0000 dockes (5ca00f4db306) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-11-07 15:11 +0000 dockes (8ae633ae4194) + + * src/VERSION: + *** empty log message *** + +2005-11-07 15:06 +0000 dockes (6be191f54656) + + * src/Makefile, src/mk/commondefs, src/recollinstall: + fixed installation script + +2005-11-07 11:21 +0000 dockes (e48ddf065716) + + * src/VERSION: + *** empty log message *** + +2005-11-06 15:07 +0000 dockes (fef6e5d66e29 [RECOLL-1_05]) + + * src/qtgui/idxthread.cpp, src/qtgui/main.cpp, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/utils/base64.cpp: + slightly better status printing while loading preview + +2005-11-06 11:16 +0000 dockes (0fa0ac2c3e5b) + + * src/rcldb/pathhash.cpp, src/rcldb/pathhash.h, src/utils/base64.cpp, + src/utils/base64.h, src/utils/md5.cpp, src/utils/md5.h: new file. + * src/lib/Makefile, src/rcldb/pathhash.cpp, src/rcldb/pathhash.h, + src/rcldb/rcldb.cpp, src/utils/base64.cpp, src/utils/base64.h, + src/utils/md5.cpp, src/utils/md5.h, src/utils/mimeparse.cpp: + limit path therm length through hashing + +2005-11-05 15:30 +0000 dockes (eea6ede9ce9a) + + * src/INSTALL, src/README, src/VERSION: + *** empty log message *** + +2005-11-05 15:29 +0000 dockes (c99e6c9d50df) + + * src/rcldb/rcldb.cpp: + debug message + +2005-11-05 15:17 +0000 dockes (a3463f8f8c63) + + * src/mk/commondefs: + unused def + +2005-11-05 14:40 +0000 dockes (47c04f4507d0 [RECOLL-1_04]) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/rclinit.cpp, src/common/rclinit.h, src/index/indexer.cpp, + src/index/recollindex.cpp, src/internfile/mh_mail.cpp, src/mk/SunOS, + src/qtgui/main.cpp, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + separate file and document dates (mainly for email folders). Better + check configuration at startup + +2005-11-02 12:36 +0000 dockes (e0d52b43cd5c) + + * src/lib/Makefile, src/mk/commondefs: + add def for RANLIB + +2005-11-01 10:55 +0000 dockes (2b858432af00) + + * src/mk/Darwin: new file. + * src/mk/Darwin: + *** empty log message *** + +2005-10-31 08:59 +0000 dockes (65fd4f89de80) + + * src/internfile/mh_mail.cpp, src/utils/mimeparse.cpp: + fixed base64 decoding of email parts: str[x] = ch does not adjust + length! and be more lenient with encoding errors + +2005-10-22 13:10 +0000 dockes (9a5b142d31f3) + + * src/README: + *** empty log message *** + +2005-10-22 13:10 +0000 dockes (d5ccf5480db1 [RECOLL-1_03]) + + * src/VERSION, src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + update status line when starting lengthy operations + +2005-10-22 07:29 +0000 dockes (df8ad947685b) + + * src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + get clicks in res list to behave: drag->no click. dblclick->no + single click + +2005-10-22 05:35 +0000 dockes (c566d157cfd3) + + * src/qtgui/recoll_fr.ts: new file. + * src/qtgui/main.cpp, src/qtgui/recoll.pro, src/qtgui/recoll_fr.ts: + i8n + +2005-10-21 15:45 +0000 dockes (34b797e01868) + + * src/mk/commondefs: new file. + * src/mk/commondefs: + *** empty log message *** + +2005-10-21 15:41 +0000 dockes (08f9ad818cb3 [RECOLL-1_02]) + + * src/makestaticdist.sh, src/recollinstall: + more verbosity in install + +2005-10-21 15:22 +0000 dockes (aa642ead5a8e) + + * src/INSTALL: + *** empty log message *** + +2005-10-21 15:11 +0000 dockes (1c74d6d926b7) + + * src/INSTALL: + *** empty log message *** + +2005-10-21 14:14 +0000 dockes (662fe9bab837) + + * src/excludefile: + *** empty log message *** + +2005-10-21 14:11 +0000 dockes (1856de4bf3f6) + + * src/makestaticdist.sh: new file. + * src/Makefile, src/makestaticdist.sh: + static bin dists + +2005-10-21 13:34 +0000 dockes (0c861c8b6029) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-21 13:33 +0000 dockes (7256b6e4e2ff) + + * src/Makefile, src/excludefile, src/index/Makefile, + src/makesrcdist.sh, src/mk/FreeBSD, src/mk/Linux, src/mk/SunOS, + src/qtgui/recoll.pro: + rearrange make includes+prepare bin static distrib + +2005-10-21 12:15 +0000 dockes (a9773a1a4715) + + * src/unac/unac.c: + fix args to iconv to get rid of warnings + +2005-10-21 08:14 +0000 dockes (f50d252ec29b) + + * src/Makefile, src/VERSION, src/excludefile, src/mk/FreeBSD, + src/mk/Linux, src/qtgui/preview/pvmain.cpp, src/utils/smallut.cpp: + more small build tweaks. use mkdtemp if available + +2005-10-20 16:20 +0000 dockes (b5fe53035720 [RECOLL-1_01]) + + * src/qtgui/advsearch.ui, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h: + CR->search in advanced dialog. ^W close tab in preview + +2005-10-20 15:42 +0000 dockes (a9e9ecfba2d2) + + * src/filters/rcldoc, src/filters/rclpdf, src/filters/rclps, + src/filters/rclsoff, src/mk/SunOS: + small fixes for SunOS + +2005-10-20 12:17 +0000 dockes (bc70bba2564c) + + * src/README, src/makesrcdist.sh: + *** empty log message *** + +2005-10-20 12:17 +0000 dockes (4e8de2aee40d) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-20 12:17 +0000 dockes (39b33b1f4e36) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-20 12:16 +0000 dockes (45a324ad4baa) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-20 12:16 +0000 dockes (73b1f99aef21) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-20 12:12 +0000 dockes (b3a8d1bceb51) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-20 11:38 +0000 dockes (5966cd48c62c) + + * src/sampleconf/recoll.conf: + defaultlanguage->english + +2005-10-20 11:33 +0000 dockes (4ba3bd42973e) + + * src/recollinstall: new file. + * src/bincimapmime/Makefile, src/filters/rcldoc, src/filters/rclpdf, + src/filters/rclps, src/filters/rclsoff, + src/qtgui/preview/preview.ui.h, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/recollinstall: + small installation tweaks + +2005-10-20 08:34 +0000 dockes (8ce6cff4ca9c) + + * src/Makefile, src/VERSION, src/bincimapmime/Makefile, + src/excludefile, src/lib/Makefile, src/mk/FreeBSD, + src/qtgui/plaintorich.cpp, src/qtgui/preview/preview.ui.h, + src/qtgui/recoll.pro: + small warning and compilation adjustments + +2005-10-20 07:51 +0000 dockes (b6f58b26d846 [RECOLL-1_0]) + + * src/configure: new file. + * src/README, src/configure: + *** empty log message *** + +2005-10-19 16:29 +0000 dockes (46a91fdb7a8e) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-10-19 16:27 +0000 dockes (92e16891b11d) + + * src/INSTALL: + *** empty log message *** + +2005-10-19 16:09 +0000 dockes (0dda1bd16921) + + * src/README, src/VERSION: + *** empty log message *** + +2005-10-19 15:22 +0000 dockes (88cadb2e703e) + + * src/qtgui/recollmain.ui: + *** empty log message *** + +2005-10-19 14:14 +0000 dockes (61cd7c267dec) + + * src/common/rclconfig.cpp, src/qtgui/advsearch.ui.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/utils/idfile.cpp, + src/utils/idfile.h: + implemented filtering on file subtree + +2005-10-19 10:21 +0000 dockes (598116a30bfb) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/filters/rcldoc, src/filters/rclpdf, src/filters/rclps, + src/filters/rclsoff, src/qtgui/advsearch.ui, + src/qtgui/advsearch.ui.h, src/qtgui/main.cpp, + src/qtgui/plaintorich.cpp, src/qtgui/recoll.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + most of adv search working. Still need subtree/filename filters + +2005-10-17 13:36 +0000 dockes (6ce40ecb81f6) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/preview/pvmain.cpp, src/qtgui/recoll.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/utils/Makefile: + implemented dialog/glue for advanced search + +2005-10-15 12:18 +0000 dockes (b57626e188f9) + + * src/index/indexer.cpp, src/internfile/mh_mail.cpp, + src/utils/mimeparse.cpp, src/utils/mimeparse.h: + decode encoded mail headers, plus use message date instead of file + mtime + +2005-10-10 13:25 +0000 dockes (3797f12a0832) + + * src/common/textsplit.h: + comments + +2005-10-10 13:24 +0000 dockes (a339c123dcb9) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h: + ckpt + +2005-10-10 12:29 +0000 dockes (e88bad1f996b) + + * src/qtgui/advsearch.ui, src/qtgui/main.cpp, + src/qtgui/preview/preview.ui, src/qtgui/preview/preview.ui.h, + src/qtgui/preview/pvmain.cpp, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h: + ckpt + +2005-09-27 06:20 +0000 dockes (8b147a42b660) + + * src/qtgui/preview/preview.pro, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/preview/pvmain.cpp: new + file. + * src/qtgui/preview/preview.pro, src/qtgui/preview/preview.ui, + src/qtgui/preview/preview.ui.h, src/qtgui/preview/pvmain.cpp: + *** empty log message *** + +2005-09-26 16:17 +0000 dockes (783900fcd3e7) + + * src/qtgui/recoll.pro: + *** empty log message *** + +2005-09-22 16:22 +0000 dockes (1e6ccf2c2fdc) + + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h: new file. + * src/qtgui/plaintorich.cpp, src/qtgui/plaintorich.h: + *** empty log message *** + +2005-09-22 15:00 +0000 dockes (db2d876f2a2b) + + * src/qtgui/recollmain.ui.h: + *** empty log message *** + +2005-09-22 14:09 +0000 dockes (4455c0eeffd4) + + * src/common/textsplit.cpp: + adjust start/end of word when trimming + +2005-09-22 11:10 +0000 dockes (3b9d4fc5b507) + + * src/common/textsplit.cpp: + fix problems with word followed by . + +2005-05-18 08:42 +0000 dockes (03bc1f1290cd) + + * src/qtgui/recoll.pro: + *** empty log message *** + +2005-05-17 11:46 +0000 dockes (cff6e901fde8) + + * src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h: new file. + * src/qtgui/advsearch.ui, src/qtgui/advsearch.ui.h, + src/qtgui/recoll.pro: + *** empty log message *** + +2005-05-17 06:30 +0000 dockes (9a44703bd049 [RECOLL-0_7]) + + * src/README: + *** empty log message *** + +2005-05-17 06:30 +0000 dockes (d2265051082d) + + * src/qtgui/recollmain.ui.h: + escape < to < in rich text + +2005-04-08 07:32 +0000 dockes (3917ab1cc937) + + * src/README: + *** empty log message *** + +2005-04-08 07:32 +0000 dockes (2f2439c9590a) + + * src/mk/SunOS: new file. + * src/Makefile, src/mk/SunOS, src/utils/Makefile: + works on solaris8 + +2005-04-07 09:05 +0000 dockes (0264f1839b92) + + * src/utils/idfile.cpp, src/utils/idfile.h: new file. + * src/index/mimetype.cpp, src/lib/Makefile, src/sampleconf/mimemap, + src/utils/Makefile, src/utils/idfile.cpp, src/utils/idfile.h: + replaced /usr/bin/file exec with internal code + +2005-04-06 10:20 +0000 dockes (ba9162debe5a) + + * src/bincimapmime/AUTHORS, src/bincimapmime/COPYING: new file. + * src/INSTALL, src/VERSION, src/bincimapmime/AUTHORS, + src/bincimapmime/COPYING, src/bincimapmime/mime-inputsource.h, + src/index/indexer.cpp, src/internfile/mh_mail.cpp, + src/makesrcdist.sh, src/mk/FreeBSD, src/mk/Linux, + src/qtgui/main.cpp, src/rcldb/rcldb.cpp, src/sampleconf/recoll.conf, + src/utils/smallut.h, src/utils/wipedir.cpp: + re-port to linux + +2005-04-06 09:18 +0000 dockes (d8add828aa6b) + + * src/README: + *** empty log message *** + +2005-04-06 09:13 +0000 dockes (7d5759a43255) + + * src/README: + *** empty log message *** + +2005-04-05 09:35 +0000 dockes (6232ca052972) + + * src/common/rclinit.cpp, src/common/rclinit.h: new file. + * src/common/rclinit.cpp, src/common/rclinit.h, + src/index/mimetype.cpp, src/index/recollindex.cpp, + src/internfile/internfile.cpp, src/internfile/mh_mail.cpp, + src/lib/Makefile, src/qtgui/main.cpp, src/rcldb/rcldb.cpp, + src/sampleconf/mimemap: + *** empty log message *** + +2005-04-04 13:18 +0000 dockes (e69c810eb5b1) + + * src/index/indexer.cpp, src/index/mimetype.cpp, + src/internfile/mh_html.cpp, src/internfile/mh_mail.cpp, + src/rcldb/rcldb.cpp, src/sampleconf/mimeconf, + src/utils/fstreewalk.cpp, src/utils/fstreewalk.h: + *** empty log message *** + +2005-03-31 10:04 +0000 dockes (9428bb11ff77) + + * src/bincimapmime/mime-inputsource.h, src/bincimapmime/mime- + parsefull.cc, src/bincimapmime/mime-parseonlyheader.cc, + src/bincimapmime/mime-printbody.cc, src/bincimapmime/mime.h, + src/bincimapmime/trbinc.cc, src/common/rclconfig.cpp, + src/internfile/mh_html.cpp, src/internfile/mh_html.h, + src/internfile/mh_mail.cpp, src/internfile/mh_mail.h, + src/rcldb/rcldb.cpp: + mail handling 1st working version + +2005-03-25 09:40 +0000 dockes (408a2650e963 [RECOLL-0_6]) + + * src/bincimapmime/00README.recoll, src/bincimapmime/trbinc.cc, + src/internfile/mh_mail.cpp, src/internfile/mh_mail.h: new file. + * src/bincimapmime/00README.recoll, src/bincimapmime/mime- + printbody.cc, src/bincimapmime/mime.h, src/bincimapmime/trbinc.cc, + src/common/Makefile, src/index/Makefile, src/index/indexer.cpp, + src/index/mimetype.cpp, src/internfile/internfile.cpp, + src/internfile/internfile.h, src/internfile/mh_html.cpp, + src/internfile/mh_html.h, src/internfile/mh_mail.cpp, + src/internfile/mh_mail.h, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h, src/internfile/myhtmlparse.cpp, + src/lib/Makefile, src/mk/FreeBSD, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui.h, src/rcldb/rcldb.h, + src/sampleconf/mimeconf, src/utils/mimeparse.cpp, + src/utils/mimeparse.h: + mail ckpt + +2005-03-17 15:35 +0000 dockes (55a0c15039bf) + + * src/index/indexer.cpp, src/index/indexer.h, + src/internfile/internfile.cpp, src/internfile/mh_html.h: + only comments. Before multidoc files + +2005-03-17 14:02 +0000 dockes (b1f57902f3c1) + + * src/bincimapmime/Makefile, src/bincimapmime/iodevice.cc, + src/index/indexer.cpp, src/qtgui/recollmain.ui.h, + src/sampleconf/mimeconf, src/utils/execmd.cpp, src/utils/execmd.h, + src/utils/mimeparse.cpp, src/utils/smallut.cpp, src/utils/smallut.h, + src/utils/utf8iter.h: + checkpoint after long pause + +2005-03-16 07:35 +0000 dockes (4d4d71cd89ea) + + * src/bincimapmime/Makefile, src/bincimapmime/address.cc, + src/bincimapmime/address.h, src/bincimapmime/config.h, + src/bincimapmime/convert.cc, src/bincimapmime/convert.h, + src/bincimapmime/depot.h, src/bincimapmime/iodevice.cc, + src/bincimapmime/iodevice.h, src/bincimapmime/iofactory.cc, + src/bincimapmime/iofactory.h, src/bincimapmime/mime-getpart.cc, + src/bincimapmime/mime-inputsource.h, src/bincimapmime/mime- + parsefull.cc, src/bincimapmime/mime-parseonlyheader.cc, + src/bincimapmime/mime-printbody.cc, src/bincimapmime/mime- + printdoc.cc, src/bincimapmime/mime-printheader.cc, src/bincimapmime + /mime-utils.h, src/bincimapmime/mime.cc, src/bincimapmime/mime.h, + src/bincimapmime/session.h: new file. + * src/bincimapmime/Makefile, src/bincimapmime/address.cc, + src/bincimapmime/address.h, src/bincimapmime/config.h, + src/bincimapmime/convert.cc, src/bincimapmime/convert.h, + src/bincimapmime/depot.h, src/bincimapmime/iodevice.cc, + src/bincimapmime/iodevice.h, src/bincimapmime/iofactory.cc, + src/bincimapmime/iofactory.h, src/bincimapmime/mime-getpart.cc, + src/bincimapmime/mime-inputsource.h, src/bincimapmime/mime- + parsefull.cc, src/bincimapmime/mime-parseonlyheader.cc, + src/bincimapmime/mime-printbody.cc, src/bincimapmime/mime- + printdoc.cc, src/bincimapmime/mime-printheader.cc, src/bincimapmime + /mime-utils.h, src/bincimapmime/mime.cc, src/bincimapmime/mime.h, + src/bincimapmime/session.h: + initial import from bincimap-1.3.3 + +2005-02-11 11:48 +0000 dockes (7b2bdc5c6ed9) + + * src/README, src/makesrcdist.sh: + *** empty log message *** + +2005-02-11 11:48 +0000 dockes (ffca521040c2) + + * src/README: + *** empty log message *** + +2005-02-11 11:20 +0000 dockes (7c54c58f0fd1) + + * src/common/uproplist.h, src/utils/utf8testin.txt: new file. + * src/common/textsplit.cpp, src/common/uproplist.h, + src/utils/Makefile, src/utils/utf8iter.cpp, src/utils/utf8iter.h, + src/utils/utf8testin.txt: + improved word extraction a bit (unicode punctuation) + +2005-02-10 19:52 +0000 dockes (ba4dd19f41c4) + + * src/utils/utf8iter.cpp, src/utils/utf8iter.h: new file. + * src/common/textsplit.cpp, src/utils/Makefile, + src/utils/utf8iter.cpp, src/utils/utf8iter.h: + *** empty log message *** + +2005-02-10 15:21 +0000 dockes (44892bfc8d49) + + * src/index/indexer.cpp, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/utils/execmd.cpp, + src/utils/fstreewalk.cpp, src/utils/fstreewalk.h, + src/utils/smallut.cpp, src/utils/smallut.h: + implemented stem databases + +2005-02-09 13:34 +0000 dockes (7517469a76b5) + + * src/index/Makefile, src/index/mimetype.cpp: + *** empty log message *** + +2005-02-09 12:07 +0000 dockes (e5d0612227af) + + * src/filters/rcldoc, src/filters/rclsoff, src/utils/wipedir.cpp, + src/utils/wipedir.h: new file. + * src/VERSION, src/filters/rcldoc, src/filters/rclsoff, + src/index/indexer.cpp, src/index/mimetype.cpp, + src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/myhtmlparse.cpp, src/lib/Makefile, + src/qtgui/main.cpp, src/qtgui/recoll.h, src/qtgui/recollmain.ui.h, + src/sampleconf/mimeconf, src/sampleconf/mimemap, src/utils/Makefile, + src/utils/smallut.cpp, src/utils/smallut.h, src/utils/wipedir.cpp, + src/utils/wipedir.h: + added support for openoffice and word + optimized decomp temp dir + usage + +2005-02-08 17:35 +0000 dockes (e5a6d4a27e1f) + + * src/INSTALL, src/README: + *** empty log message *** + +2005-02-08 15:08 +0000 dockes (f89783d5d828) + + * src/excludefile, src/makesrcdist.sh: new file. + * src/README, src/excludefile, src/makesrcdist.sh: + *** empty log message *** + +2005-02-08 15:03 +0000 dockes (4ec10decb898) + + * src/README: + *** empty log message *** + +2005-02-08 14:55 +0000 dockes (07541712859f) + + * src/README: + *** empty log message *** + +2005-02-08 14:54 +0000 dockes (fa3ad0590138 [RECOLL-0_5]) + + * src/Makefile, src/README, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/sampleconf/recoll.conf: + *** empty log message *** + +2005-02-08 14:45 +0000 dockes (d04d78bb1af4) + + * src/INSTALL, src/internfile/myhtmlparse.cpp, src/qtgui/recoll.pro: + *** empty log message *** + +2005-02-08 11:59 +0000 dockes (b5f33d8a83cb) + + * src/common/textsplit.cpp, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + fixed next/prev screen pb + pb with accents when matching in preview + +2005-02-08 10:56 +0000 dockes (ea8c32a3b71e) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/rcldb/rcldb.cpp: + phrases ok except for preview position + +2005-02-08 09:34 +0000 dockes (8f72bd8ca147) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/qtgui/recoll.pro, src/qtgui/recollmain.ui.h, + src/query/xadump.cpp, src/rcldb/rcldb.cpp, src/utils/execmd.cpp: + fixes in textsplit + +2005-02-07 13:17 +0000 dockes (3e10d31a55a9) + + * src/common/textsplit.cpp, src/common/textsplit.h, + src/qtgui/recollmain.ui.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + simple term highlighting in query preview + +2005-02-04 14:21 +0000 dockes (77a59732f8aa) + + * src/COPYING, src/INSTALL, src/README, src/VERSION, + src/filters/rcluncomp, src/internfile/internfile.cpp, + src/internfile/internfile.h, src/mk/Linux, + src/qtgui/images/editcopy, src/qtgui/images/editcut, + src/qtgui/images/editpaste, src/qtgui/images/filenew, + src/qtgui/images/fileopen, src/qtgui/images/filesave, + src/qtgui/images/print, src/qtgui/images/redo, + src/qtgui/images/searchfind, src/qtgui/images/undo: new file. + * src/COPYING, src/INSTALL, src/Makefile, src/README, src/VERSION, + src/common/Makefile, src/common/unacpp.cpp, src/filters/rcluncomp, + src/index/Makefile, src/index/csguess.cpp, src/index/indexer.cpp, + src/internfile/internfile.cpp, src/internfile/internfile.h, + src/internfile/mimehandler.cpp, src/lib/Makefile, src/mk/FreeBSD, + src/mk/Linux, src/qtgui/idxthread.cpp, src/qtgui/images/editcopy, + src/qtgui/images/editcut, src/qtgui/images/editpaste, + src/qtgui/images/filenew, src/qtgui/images/fileopen, + src/qtgui/images/filesave, src/qtgui/images/print, + src/qtgui/images/redo, src/qtgui/images/searchfind, + src/qtgui/images/undo, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/Makefile, src/rcldb/rcldb.cpp, src/utils/Makefile, + src/utils/pathut.cpp, src/utils/transcode.cpp: + uncompression+linux port + +2005-02-04 09:39 +0000 dockes (482687ce34da) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/index/indexer.cpp, src/internfile/mh_html.cpp, + src/internfile/mimehandler.cpp, src/internfile/mimehandler.h, + src/lib/Makefile, src/qtgui/recollmain.ui.h, src/utils/smallut.cpp, + src/utils/smallut.h: + *** empty log message *** + +2005-02-04 09:30 +0000 dockes (5fac5dd8a1c4) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/recoll.conf: + *** empty log message *** + +2005-02-04 09:21 +0000 dockes (2ad004ec5fd7) + + * src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/recoll.conf: new file. + * src/sampleconf/mimeconf, src/sampleconf/mimemap, + src/sampleconf/recoll.conf: + *** empty log message *** + +2005-02-02 17:57 +0000 dockes (4819b0b410e7) + + * src/filters/rclps: new file. + * src/filters/rclps: + *** empty log message *** + +2005-02-01 17:52 +0000 dockes (023ac2c1c87f) + + * src/internfile/mimehandler.cpp, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/rcldb/rcldb.cpp: + *** empty log message *** + +2005-02-01 17:20 +0000 dockes (4eb8337baa03) + + * src/filters/rclpdf, src/internfile/mh_html.h, src/mk/FreeBSD, + src/qtgui/idxthread.h, src/qtgui/recoll.h: new file. + * src/filters/rclpdf, src/index/indexer.cpp, + src/internfile/mh_html.cpp, src/internfile/mh_html.h, + src/internfile/mimehandler.cpp, src/internfile/mimehandler.h, + src/lib/Makefile, src/mk/FreeBSD, src/qtgui/idxthread.h, + src/qtgui/recoll.h, src/qtgui/recollmain.ui.h, src/rcldb/rcldb.cpp, + src/utils/Makefile, src/utils/execmd.cpp: + added external filters and pdf handling + +2005-02-01 08:42 +0000 dockes (b82908e25c6b) + + * src/common/Makefile, src/index/Makefile, src/index/recollindex.cpp, + src/lib/Makefile, src/qtgui/idxthread.cpp, src/qtgui/main.cpp, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/Makefile, src/rcldb/rcldb.cpp, src/utils/Makefile: + *** empty log message *** + +2005-01-31 14:31 +0000 dockes (c8a32d0e0056) + + * src/index/indexer.cpp, src/qtgui/idxthread.cpp, + src/utils/smallut.cpp, src/utils/smallut.h: new file. + * src/common/rclconfig.cpp, src/index/indexer.cpp, + src/index/indexer.h, src/index/recollindex.cpp, src/lib/Makefile, + src/qtgui/idxthread.cpp, src/qtgui/main.cpp, src/qtgui/recoll.pro, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/qtry.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/Makefile, src/utils/pathut.cpp, src/utils/pathut.h, + src/utils/smallut.cpp, src/utils/smallut.h: + first incarnation of indexing thread + +2005-01-29 15:41 +0000 dockes (3dd05c65d8ed) + + * src/index/recollindex.cpp, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h, src/lib/Makefile, src/qtgui/main.cpp, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/utils/Makefile: + external viewer+ deleted doc purging + +2005-01-28 15:25 +0000 dockes (8c6b04552a34) + + * src/Makefile, src/internfile/indextext.h: new file. + * src/Makefile, src/internfile/indextext.h, + src/internfile/myhtmlparse.cpp, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h: + ckpt + +2005-01-28 09:37 +0000 dockes (bf2c00ad72d0) + + * src/internfile/mh_html.cpp, src/internfile/myhtmlparse.cpp, + src/internfile/myhtmlparse.h, src/lib/Makefile, src/rcldb/rcldb.cpp: + merged modifs from xapian/omega 0.8.5 + +2005-01-28 08:56 +0000 dockes (a5e2a08ce1b8) + + * src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h: + import from xapian 0.8.5 + +2005-01-28 08:50 +0000 dockes (73f5b0ed50d8) + + * src/internfile/htmlparse.cpp, src/internfile/htmlparse.h: + Initial recoll modifs for utf8 + +2005-01-28 08:46 +0000 dockes (04f0053d01e4) + + * src/internfile/mh_html.cpp, src/rcldb/rcldb.cpp: + xapian 0.8.3 + +2005-01-28 08:45 +0000 dockes (ec7863976555) + + * src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h: new + file. + * src/internfile/myhtmlparse.cpp, src/internfile/myhtmlparse.h: + *** empty log message *** + +2005-01-28 08:41 +0000 dockes (c5c570040571) + + * src/internfile/htmlparse.cpp, src/internfile/htmlparse.h: new file. + * src/internfile/htmlparse.cpp, src/internfile/htmlparse.h: + xapian 0.8.3 + +2005-01-26 13:03 +0000 dockes (5a37e2aa9a53) + + * src/index/recollindex.cpp, src/internfile/mh_html.cpp, + src/internfile/mimehandler.cpp, src/rcldb/rcldb.cpp: + sort of indexes html + +2005-01-26 11:47 +0000 dockes (eec829a74f2d) + + * src/internfile/mh_html.cpp: new file. + * src/internfile/mh_html.cpp, src/internfile/mimehandler.cpp, + src/internfile/mimehandler.h, src/lib/Makefile, + src/qtgui/recollmain.ui, src/qtgui/recollmain.ui.h, + src/query/qtry.cpp, src/rcldb/rcldb.cpp, src/utils/Makefile: + ckpt + +2005-01-26 11:45 +0000 dockes (1c17d5d56a6b) + + * src/utils/mimeparse.cpp, src/utils/mimeparse.h: new file. + * src/utils/mimeparse.cpp, src/utils/mimeparse.h: + mime header parsing embryo + +2005-01-25 14:37 +0000 dockes (1d5b47c225bf) + + * src/internfile/mimehandler.cpp, src/internfile/mimehandler.h: new + file. + * src/internfile/mimehandler.cpp, src/internfile/mimehandler.h: + *** empty log message *** + +2005-01-25 14:37 +0000 dockes (46d42849ee3a) + + * src/lib/Makefile, src/qtgui/recoll.pro, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h: new file. + * src/common/Makefile, src/common/rclconfig.cpp, src/index/Makefile, + src/index/indexer.h, src/index/recollindex.cpp, src/lib/Makefile, + src/qtgui/main.cpp, src/qtgui/recoll.pro, src/qtgui/recollmain.ui, + src/qtgui/recollmain.ui.h, src/query/Makefile, src/query/qtry.cpp, + src/query/xadump.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/Makefile, src/utils/transcode.h: + gui connected to rcldb (init) + +2005-01-24 13:17 +0000 dockes (e0104075bdd3) + + * src/common/Makefile, src/index/Makefile, src/qtgui/form1.ui, + src/qtgui/form1.ui.h, src/qtgui/main.cpp, src/query/qtry.cpp, + src/query/qxtry.cpp, src/utils/Makefile: new file. + * src/common/Makefile, src/common/rclconfig.cpp, + src/common/textsplit.h, src/common/unacpp.cpp, src/index/Makefile, + src/qtgui/form1.ui, src/qtgui/form1.ui.h, src/qtgui/main.cpp, + src/query/Makefile, src/query/qtry.cpp, src/query/qxtry.cpp, + src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, src/utils/Makefile: + *** empty log message *** + +2004-12-17 15:50 +0000 dockes (4f7a0a26f6d7) + + * src/query/xadump.cpp, src/rcldb/rcldb.cpp: + very basic indexing working + +2004-12-17 15:36 +0000 dockes (325aea11f893) + + * src/common/unacpp.cpp, src/common/unacpp.h: new file. + * src/common/unacpp.cpp, src/common/unacpp.h, src/rcldb/rcldb.cpp: + *** empty log message *** + +2004-12-17 15:04 +0000 dockes (930a5f50b45e) + + * src/unac/AUTHORS, src/unac/COPYING, src/unac/README, + src/unac/README.recoll, src/unac/unac.c, src/unac/unac.h: new file. + * src/unac/AUTHORS, src/unac/COPYING, src/unac/README, + src/unac/README.recoll, src/unac/unac.c, src/unac/unac.h: + unac 1.7.0 + +2004-12-17 13:01 +0000 dockes (70ded59ba246) + + * src/query/Makefile, src/query/xadump.cpp: new file. + * src/common/rclconfig.h, src/common/textsplit.cpp, + src/common/textsplit.h, src/index/recollindex.cpp, + src/query/Makefile, src/query/xadump.cpp, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h: + *** empty log message *** + +2004-12-15 15:00 +0000 dockes (1e3483587b45) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/textsplit.cpp, src/index/csguess.cpp, + src/index/csguess.h, src/index/indexer.h, src/index/mimetype.cpp, + src/index/recollindex.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/transcode.cpp: + warnings cleanup + +2004-12-15 09:43 +0000 dockes (502752de59d5) + + * src/utils/transcode.cpp, src/utils/transcode.h: new file. + * src/utils/transcode.cpp, src/utils/transcode.h: + *** empty log message *** + +2004-12-15 08:21 +0000 dockes (520f5e294f10) + + * src/index/csguess.cpp, src/index/csguess.h: new file. + * src/index/csguess.cpp, src/index/csguess.h: + just converted (indent+comments) from estraier + +2004-12-14 17:54 +0000 dockes (12a23501eee8) + + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/textsplit.h, src/index/indexer.h, src/rcldb/rcldb.cpp, + src/rcldb/rcldb.h, src/utils/readfile.cpp, src/utils/readfile.h: new + file. + * src/common/rclconfig.cpp, src/common/rclconfig.h, + src/common/textsplit.cpp, src/common/textsplit.h, + src/index/indexer.h, src/index/mimetype.cpp, src/index/mimetype.h, + src/index/recollindex.cpp, src/rcldb/rcldb.cpp, src/rcldb/rcldb.h, + src/utils/execmd.cpp, src/utils/pathut.cpp, src/utils/pathut.h, + src/utils/readfile.cpp, src/utils/readfile.h: + *** empty log message *** + +2004-12-13 15:42 +0000 dockes (8c1fce132f19) + + * src/common/textsplit.cpp, src/index/mimetype.cpp, + src/index/mimetype.h, src/index/recollindex.cpp: new file. + * src/common/textsplit.cpp, src/index/mimetype.cpp, + src/index/mimetype.h, src/index/recollindex.cpp: + *** empty log message *** + +2004-12-12 08:58 +0000 dockes (17a132340425) + + * src/utils/execmd.cpp, src/utils/execmd.h: new file. + * src/utils/execmd.cpp, src/utils/execmd.h, src/utils/fstreewalk.cpp: + *** empty log message *** + +2004-12-10 18:13 +0000 dockes (1de12131e4a4) + + * src/utils/fstreewalk.cpp, src/utils/fstreewalk.h, + src/utils/pathut.cpp, src/utils/pathut.h: new file. + * src/utils/fstreewalk.cpp, src/utils/fstreewalk.h, + src/utils/pathut.cpp, src/utils/pathut.h: + *** empty log message *** + +2004-12-10 18:13 +0000 unknown (318176766db7) + + * Standard project directories initialized by cvs2svn. + diff --git a/src/INSTALL b/src/INSTALL new file mode 100644 index 00000000..e8ae6a49 --- /dev/null +++ b/src/INSTALL @@ -0,0 +1,1348 @@ + +More documentation can be found in the doc/ directory or at http://www.recoll.org + + + Link: home: Recoll user manual + Link: up: Recoll user manual + Link: prev: 4.3. API + Link: next: 5.2. Supporting packages + + Chapter 5. Installation and configuration + Prev Next + + ---------------------------------------------------------------------- + +Chapter 5. Installation and configuration + +5.1. Installing a binary copy + + Recoll binary copies are always distributed as regular packages for your + system. They can be obtained either through the system's normal software + distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or + from some type of "backports" repository providing versions newer than the + standard ones, or found on the Recoll WEB site in some cases. + + There used to exist another form of binary install, as pre-compiled source + trees, but these are just less convenient than the packages and don't + exist any more. + + The package management tools will usually automatically deal with hard + dependancies for packages obtained from a proper package repository. You + will have to deal with them by hand for downloaded packages (for example, + when dpkg complains about missing dependancies). + + In all cases, you will have to check or install supporting applications + for the file types that you want to index beyond those that are natively + processed by Recoll (text, HTML, email files, and a few others). + + You should also maybe have a look at the configuration section (but this + may not be necessary for a quick test with default parameters). Most + parameters can be more conveniently set from the GUI interface. + + ---------------------------------------------------------------------- + + Prev Next + 4.3. API Home 5.2. Supporting packages + Link: home: Recoll user manual + Link: up: Chapter 5. Installation and configuration + Link: prev: Chapter 5. Installation and configuration + Link: next: 5.3. Building from source + + 5.2. Supporting packages + Prev Chapter 5. Installation and configuration Next + + ---------------------------------------------------------------------- + +5.2. Supporting packages + + Recoll uses external applications to index some file types. You need to + install them for the file types that you wish to have indexed (these are + run-time optional dependencies. None is needed for building or running + Recoll except for indexing their specific file type). + + After an indexing pass, the commands that were found missing can be + displayed from the recoll File menu. The list is stored in the missing + text file inside the configuration directory. + + A list of common file types which need external commands follows. Many of + the handlers need the iconv command, which is not always listed as a + dependancy. + + Please note that, due to the relatively dynamic nature of this + information, the most up to date version is now kept on + http://www.recoll.org/features.html along with links to the home pages or + best source/patches pages, and misc tips. The list below is not updated + often and may be quite stale. + + For many Linux distributions, most of the commands listed can be installed + from the package repositories. However, the packages are sometimes + outdated, or not the best version for Recoll, so you should take a look at + http://www.recoll.org/features.html if a file type is important to you. + + As of Recoll release 1.14, a number of XML-based formats that were handled + by ad hoc handler code now use the xsltproc command, which usually comes + with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice, svg. + + Now for the list: + + o Openoffice files need unzip and xsltproc. + + o PDF files need pdftotext which is part of Poppler (usually comes with + the poppler-utils package). Avoid the original one from Xpdf. + + o Postscript files need pstotext. The original version has an issue with + shell character in file names, which is corrected in recent packages. + See http://www.recoll.org/features.html for more detail. + + o MS Word needs antiword. It is also useful to have wvWare installed as + it may be be used as a fallback for some files which antiword does not + handle. + + o MS Excel and PowerPoint are processed by internal Python handlers. + + o MS Open XML (docx) needs xsltproc. + + o Wordperfect files need wpd2html from the libwpd (or libwpd-tools on + Ubuntu) package. + + o RTF files need unrtf, which, in its older versions, has much trouble + with non-western character sets. Many Linux distributions carry + outdated unrtf versions. Check http://www.recoll.org/features.html for + details. + + o TeX files need untex or detex. Check + http://www.recoll.org/features.html for sources if it's not packaged + for your distribution. + + o dvi files need dvips. + + o djvu files need djvutxt and djvused from the DjVuLibre package. + + o Audio files: Recoll releases 1.14 and later use a single Python + handler based on mutagen for all audio file types. + + o Pictures: Recoll uses the Exiftool Perl package to extract tag + information. Most image file formats are supported. Note that there + may not be much interest in indexing the technical tags (image size, + aperture, etc.). This is only of interest if you store personal tags + or textual descriptions inside the image files. + + o chm: files in Microsoft help format need Python and the pychm module + (which needs chmlib). + + o ICS: up to Recoll 1.13, iCalendar files need Python and the icalendar + module. icalendar is not needed for newer versions, which use internal + code. + + o Zip archives need Python (and the standard zipfile module). + + o Rar archives need Python, the rarfile Python module and the unrar + utility. + + o Midi karaoke files need Python and the Midi module + + o Konqueror webarchive format with Python (uses the Tarfile module). + + o Mimehtml web archive format (support based on the email handler, which + introduces some mild weirdness, but still usable). + + Text, HTML, email folders, and Scribus files are processed internally. Lyx + is used to index Lyx files. Many handlers need iconv and the standard sed + and awk. + + ---------------------------------------------------------------------- + + Prev Up Next + Chapter 5. Installation and configuration Home 5.3. Building from source + Link: home: Recoll user manual + Link: up: Chapter 5. Installation and configuration + Link: prev: 5.2. Supporting packages + Link: next: 5.4. Configuration overview + + 5.3. Building from source + Prev Chapter 5. Installation and configuration Next + + ---------------------------------------------------------------------- + +5.3. Building from source + + 5.3.1. Prerequisites + + If you can install any or all of the following through the package manager + for your system, all the better. Especially Qt is a very big piece of + software, but you will most probably be able to find a binary package. + + You may have to compile Xapian but this is easy. + + The shopping list: + + o C++ compiler. Up to Recoll version 1.13.04, its absence can manifest + itself by strange messages about a missing iconv_open. + + o Development files for Xapian core. + + Important + + If you are building Xapian for an older CPU (before Pentium 4 or + Athlon 64), you need to add the --disable-sse flag to the configure + command. Else all Xapian application will crash with an illegal + instruction error. + + o Development files for Qt 4 . Recoll has not been tested with Qt 5 yet. + Recoll 1.15.9 was the last version to support Qt 3. If you do not want + to install or build the Qt Webkit module, Recoll has a configuration + option to disable its use (see further). + + o Development files for X11 and zlib. + + o You may also need libiconv. On Linux systems, the iconv interface is + part of libc and you should not need to do anything special. + + Check the Recoll download page for up to date version information. + + 5.3.2. Building + + Recoll has been built on Linux, FreeBSD, Mac OS X, and Solaris, most + versions after 2005 should be ok, maybe some older ones too (Solaris 8 is + ok). If you build on another system, and need to modify things, I would + very much welcome patches. + + Configure options: + + o --without-aspell will disable the code for phonetic matching of search + terms. + + o --with-fam or --with-inotify will enable the code for real time + indexing. Inotify support is enabled by default on recent Linux + systems. + + o --with-qzeitgeist will enable sending Zeitgeist events about the + visited search results, and needs the qzeitgeist package. + + o --disable-webkit is available from version 1.17 to implement the + result list with a Qt QTextBrowser instead of a WebKit widget if you + do not or can't depend on the latter. + + o --disable-idxthreads is available from version 1.19 to suppress + multithreading inside the indexing process. You can also use the + run-time configuration to restrict recollindex to using a single + thread, but the compile-time option may disable a few more unused + locks. This only applies to the use of multithreading for the core + index processing (data input). The Recoll monitor mode always uses at + least two threads of execution. + + o --disable-python-module will avoid building the Python module. + + o --disable-xattr will prevent fetching data from file extended + attributes. Beyond a few standard attributes, fetching extended + attributes data can only be useful is some application stores data in + there, and also needs some simple configuration (see comments in the + fields configuration file). + + o --enable-camelcase will enable splitting camelCase words. This is not + enabled by default as it has the unfortunate side-effect of making + some phrase searches quite confusing: ie, "MySQL manual" would be + matched by "MySQL manual" and "my sql manual" but not "mysql manual" + (only inside phrase searches). + + o --with-file-command Specify the version of the 'file' command to use + (ie: --with-file-command=/usr/local/bin/file). Can be useful to enable + the gnu version on systems where the native one is bad. + + o --disable-qtgui Disable the Qt interface. Will allow building the + indexer and the command line search program in absence of a Qt + environment. + + o --disable-x11mon Disable X11 connection monitoring inside recollindex. + Together with --disable-qtgui, this allows building recoll without Qt + and X11. + + o --disable-pic will compile Recoll with position-dependant code. This + is incompatible with building the KIO or the Python or PHP extensions, + but might yield very marginally faster code. + + o Of course the usual autoconf configure options, like --prefix apply. + + Normal procedure: + + cd recoll-xxx + ./configure + make + (practices usual hardship-repelling invocations) + + + There is little auto-configuration. The configure script will mainly link + one of the system-specific files in the mk directory to mk/sysconf. If + your system is not known yet, it will tell you as much, and you may want + to manually copy and modify one of the existing files (the new file name + should be the output of uname -s). + + 5.3.2.1. Building on Solaris + + We did not test building the GUI on Solaris for recent versions. You will + need at least Qt 4.4. There are some hints on an old web site page, they + may still be valid. + + Someone did test the 1.19 indexer and Python module build, they do work, + with a few minor glitches. Be sure to use GNU make and install. + + 5.3.3. Installation + + Either type make install or execute recollinstall prefix, in the root of + the source tree. This will copy the commands to prefix/bin and the sample + configuration files, scripts and other shared data to prefix/share/recoll. + + If the installation prefix given to recollinstall is different from either + the system default or the value which was specified when executing + configure (as in configure --prefix /some/path), you will have to set the + RECOLL_DATADIR environment variable to indicate where the shared data is + to be found (ie for (ba)sh: export + RECOLL_DATADIR=/some/path/share/recoll). + + You can then proceed to configuration. + + ---------------------------------------------------------------------- + + Prev Up Next + 5.2. Supporting packages Home 5.4. Configuration overview + Link: home: Recoll user manual + Link: up: Chapter 5. Installation and configuration + Link: prev: 5.3. Building from source + + 5.4. Configuration overview + Prev Chapter 5. Installation and configuration + + ---------------------------------------------------------------------- + +5.4. Configuration overview + + Most of the parameters specific to the recoll GUI are set through the + Preferences menu and stored in the standard Qt place + ($HOME/.config/Recoll.org/recoll.conf). You probably do not want to edit + this by hand. + + Recoll indexing options are set inside text configuration files located in + a configuration directory. There can be several such directories, each of + which defines the parameters for one index. + + The configuration files can be edited by hand or through the Index + configuration dialog (Preferences menu). The GUI tool will try to respect + your formatting and comments as much as possible, so it is quite possible + to use both ways. + + The most accurate documentation for the configuration parameters is given + by comments inside the default files, and we will just give a general + overview here. + + By default, for each index, there are two sets of configuration files. + System-wide configuration files are kept in a directory named like + /usr/[local/]share/recoll/examples, and define default values, shared by + all indexes. For each index, a parallel set of files defines the + customized parameters. + + In addition (as of Recoll version 1.19.7), it is possible to specify two + additional configuration directories which will be stacked before and + after the user configuration directory. These are defined by the + RECOLL_CONFTOP and RECOLL_CONFMID environment variables. Values from + configuration files inside the top directory will override user ones, + values from configuration files inside the middle directory will override + system ones and be overriden by user ones. These two variables may be of + use to applications which augment Recoll functionality, and need to add + configuration data without disturbing the user's files. Please note that + the two, currently single, values will probably be interpreted as + colon-separated lists in the future: do not use colon characters inside + the directory paths. + + The default location of the configuration is the .recoll directory in your + home. Most people will only use this directory. + + This location can be changed, or others can be added with the + RECOLL_CONFDIR environment variable or the -c option parameter to recoll + and recollindex. + + If the .recoll directory does not exist when recoll or recollindex are + started, it will be created with a set of empty configuration files. + recoll will give you a chance to edit the configuration file before + starting indexing. recollindex will proceed immediately. To avoid + mistakes, the automatic directory creation will only occur for the default + location, not if -c or RECOLL_CONFDIR were used (in the latter cases, you + will have to create the directory). + + All configuration files share the same format. For example, a short + extract of the main configuration file might look as follows: + + # Space-separated list of directories to index. + topdirs = ~/docs /usr/share/doc + + [~/somedirectory-with-utf8-txt-files] + defaultcharset = utf-8 + + + There are three kinds of lines: + + o Comment (starts with #) or empty. + + o Parameter affectation (name = value). + + o Section definition ([somedirname]). + + Depending on the type of configuration file, section definitions either + separate groups of parameters or allow redefining some parameters for a + directory sub-tree. They stay in effect until another section definition, + or the end of file, is encountered. Some of the parameters used for + indexing are looked up hierarchically from the current directory location + upwards. Not all parameters can be meaningfully redefined, this is + specified for each in the next section. + + When found at the beginning of a file path, the tilde character (~) is + expanded to the name of the user's home directory, as a shell would do. + + White space is used for separation inside lists. List elements with + embedded spaces can be quoted using double-quotes. + + Encoding issues. Most of the configuration parameters are plain ASCII. Two + particular sets of values may cause encoding issues: + + o File path parameters may contain non-ascii characters and should use + the exact same byte values as found in the file system directory. + Usually, this means that the configuration file should use the system + default locale encoding. + + o The unac_except_trans parameter should be encoded in UTF-8. If your + system locale is not UTF-8, and you need to also specify non-ascii + file paths, this poses a difficulty because common text editors cannot + handle multiple encodings in a single file. In this relatively + unlikely case, you can edit the configuration file as two separate + text files with appropriate encodings, and concatenate them to create + the complete configuration. + + 5.4.1. Environment variables + + RECOLL_CONFDIR + + Defines the main configuration directory. + + RECOLL_TMPDIR, TMPDIR + + Locations for temporary files, in this order of priority. The + default if none of these is set is to use /tmp. Big temporary + files may be created during indexing, mostly for decompressing, + and also for processing, e.g. email attachments. + + RECOLL_CONFTOP, RECOLL_CONFMID + + Allow adding configuration directories with priorities below and + above the user directory (see above the Configuration overview + section for details). + + RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS + + Help for setting up external indexes. See this paragraph for + explanations. + + RECOLL_DATADIR + + Defines replacement for the default location of Recoll data files, + normally found in, e.g., /usr/share/recoll). + + RECOLL_FILTERSDIR + + Defines replacement for the default location of Recoll filters, + normally found in, e.g., /usr/share/recoll/filters). + + ASPELL_PROG + + aspell program to use for creating the spelling dictionary. The + result has to be compatible with the libaspell which Recoll is + using. + + VARNAME + + Blabla + + 5.4.2. The main configuration file, recoll.conf + + recoll.conf is the main configuration file. It defines things like what to + index (top directories and things to ignore), and the default character + set to use for document types which do not specify it internally. + + The default configuration will index your home directory. If this is not + appropriate, start recoll to create a blank configuration, click Cancel, + and edit the configuration file before restarting the command. This will + start the initial indexing, which may take some time. + + Most of the following parameters can be changed from the Index + Configuration menu in the recoll interface. Some can only be set by + editing the configuration file. + + 5.4.2.1. Parameters affecting what documents we index: + + topdirs + + Specifies the list of directories or files to index (recursively + for directories). You can use symbolic links as elements of this + list. See the followLinks option about following symbolic links + found under the top elements (not followed by default). + + skippedNames + + A space-separated list of wilcard patterns for names of files or + directories that should be completely ignored. The list defined in + the default file is: + + skippedNames = #* bin CVS Cache cache* caughtspam tmp .thumbnails .svn \ + *~ .beagle .git .hg .bzr loop.ps .xsession-errors \ + .recoll* xapiandb recollrc recoll.conf + + The list can be redefined at any sub-directory in the indexed + area. + + The top-level directories are not affected by this list (that is, + a directory in topdirs might match and would still be indexed). + + The list in the default configuration does not exclude hidden + directories (names beginning with a dot), which means that it may + index quite a few things that you do not want. On the other hand, + email user agents like thunderbird usually store messages in + hidden directories, and you probably want this indexed. One + possible solution is to have .* in skippedNames, and add things + like ~/.thunderbird or ~/.evolution in topdirs. + + Not even the file names are indexed for patterns in this list. See + the noContentSuffixes variable for an alternative approach which + indexes the file names. + + noContentSuffixes + + This is a list of file name endings (not wildcard expressions, nor + dot-delimited suffixes). Only the names of matching files will be + indexed (no attempt at MIME type identification, no decompression, + no content indexing). This can be redefined for subdirectories, + and edited from the GUI. The default value is: + + noContentSuffixes = .md5 .map \ + .o .lib .dll .a .sys .exe .com \ + .mpp .mpt .vsd \ + .img .img.gz .img.bz2 .img.xz .image .image.gz .image.bz2 .image.xz \ + .dat .bak .rdf .log.gz .log .db .msf .pid \ + ,v ~ # + + skippedPaths and daemSkippedPaths + + A space-separated list of patterns for paths of files or + directories that should be skipped. There is no default in the + sample configuration file, but the code always adds the + configuration and database directories in there. + + skippedPaths is used both by batch and real time indexing. + daemSkippedPaths can be used to specify things that should be + indexed at startup, but not monitored. + + Example of use for skipping text files only in a specific + directory: + + skippedPaths = ~/somedir/*.txt + + + skippedPathsFnmPathname + + The values in the *skippedPaths variables are matched by default + with fnmatch(3), with the FNM_PATHNAME flag. This means that '/' + characters must be matched explicitely. You can set + skippedPathsFnmPathname to 0 to disable the use of FNM_PATHNAME + (meaning that /*/dir3 will match /dir1/dir2/dir3). + + zipSkippedNames + + A space-separated list of patterns for names of files or + directories that should be ignored inside zip archives. This is + used directly by the zip handler, and has a function similar to + skippedNames, but works independantly. Can be redefined for + filesystem subdirectories. For versions up to 1.19, you will need + to update the Zip handler and install a supplementary Python + module. The details are described on the Recoll wiki. + + followLinks + + Specifies if the indexer should follow symbolic links while + walking the file tree. The default is to ignore symbolic links to + avoid multiple indexing of linked files. No effort is made to + avoid duplication when this option is set to true. This option can + be set individually for each of the topdirs members by using + sections. It can not be changed below the topdirs level. + + indexedmimetypes + + Recoll normally indexes any file which it knows how to read. This + list lets you restrict the indexed MIME types to what you specify. + If the variable is unspecified or the list empty (the default), + all supported types are processed. Can be redefined for + subdirectories. + + excludedmimetypes + + This list lets you exclude some MIME types from indexing. Can be + redefined for subdirectories. + + compressedfilemaxkbs + + Size limit for compressed (.gz or .bz2) files. These need to be + decompressed in a temporary directory for identification, which + can be very wasteful if 'uninteresting' big compressed files are + present. Negative means no limit, 0 means no processing of any + compressed file. Defaults to -1. + + textfilemaxmbs + + Maximum size for text files. Very big text files are often + uninteresting logs. Set to -1 to disable (default 20MB). + + textfilepagekbs + + If set to other than -1, text files will be indexed as multiple + documents of the given page size. This may be useful if you do + want to index very big text files as it will both reduce memory + usage at index time and help with loading data to the preview + window. A size of a few megabytes would seem reasonable (default: + 1MB). + + membermaxkbs + + This defines the maximum size in kilobytes for an archive member + (zip, tar or rar at the moment). Bigger entries will be skipped. + + indexallfilenames + + Recoll indexes file names in a special section of the database to + allow specific file names searches using wild cards. This + parameter decides if file name indexing is performed only for + files with MIME types that would qualify them for full text + indexing, or for all files inside the selected subtrees, + independently of MIME type. + + usesystemfilecommand + + Decide if we execute a system command (file -i by default) as a + final step for determining the MIME type for a file (the main + procedure uses suffix associations as defined in the mimemap + file). This can be useful for files with suffix-less names, but it + will also cause the indexing of many bogus "text" files. + + systemfilecommand + + Command to use for mime for mime type determination if + usesystefilecommand is set. Recent versions of xdg-mime sometimes + work better than file. + + processwebqueue + + If this is set, process the directory where Web browser plugins + copy visited pages for indexing. + + webqueuedir + + The path to the web indexing queue. This is hard-coded in the + Firefox plugin as ~/.recollweb/ToIndex so there should be no need + to change it. + + 5.4.2.2. Parameters affecting how we generate terms: + + Changing some of these parameters will imply a full reindex. Also, when + using multiple indexes, it may not make sense to search indexes that don't + share the values for these parameters, because they usually affect both + search and index operations. + + indexStripChars + + Decide if we strip characters of diacritics and convert them to + lower-case before terms are indexed. If we don't, searches + sensitive to case and diacritics can be performed, but the index + will be bigger, and some marginal weirdness may sometimes occur. + The default is a stripped index (indexStripChars = 1) for now. + When using multiple indexes for a search, this parameter must be + defined identically for all. Changing the value implies an index + reset. + + maxTermExpand + + Maximum expansion count for a single term (e.g.: when using + wildcards). The default of 10000 is reasonable and will avoid + queries that appear frozen while the engine is walking the term + list. + + maxXapianClauses + + Maximum number of elementary clauses we can add to a single Xapian + query. In some cases, the result of term expansion can be + multiplicative, and we want to avoid using excessive memory. The + default of 100 000 should be both high enough in most cases and + compatible with current typical hardware configurations. + + nonumbers + + If this set to true, no terms will be generated for numbers. For + example "123", "1.5e6", 192.168.1.4, would not be indexed + ("value123" would still be). Numbers are often quite interesting + to search for, and this should probably not be set except for + special situations, ie, scientific documents with huge amounts of + numbers in them. This can only be set for a whole index, not for a + subtree. + + nocjk + + If this set to true, specific east asian (Chinese Korean Japanese) + characters/word splitting is turned off. This will save a small + amount of cpu if you have no CJK documents. If your document base + does include such text but you are not interested in searching it, + setting nocjk may be a significant time and space saver. + + cjkngramlen + + This lets you adjust the size of n-grams used for indexing CJK + text. The default value of 2 is probably appropriate in most + cases. A value of 3 would allow more precision and efficiency on + longer words, but the index will be approximately twice as large. + + indexstemminglanguages + + A list of languages for which the stem expansion databases will be + built. See recollindex(1) or use the recollindex -l command for + possible values. You can add a stem expansion database for a + different language by using recollindex -s, but it will be deleted + during the next indexing. Only languages listed in the + configuration file are permanent. + + defaultcharset + + The name of the character set used for files that do not contain a + character set definition (ie: plain text files). This can be + redefined for any sub-directory. If it is not set at all, the + character set used is the one defined by the nls environment ( + LC_ALL, LC_CTYPE, LANG), or iso8859-1 if nothing is set. + + unac_except_trans + + This is a list of characters, encoded in UTF-8, which should be + handled specially when converting text to unaccented lowercase. + For example, in Swedish, the letter a with diaeresis has full + alphabet citizenship and should not be turned into an a. Each + element in the space-separated list has the special character as + first element and the translation following. The handling of both + the lowercase and upper-case versions of a character should be + specified, as appartenance to the list will turn-off both standard + accent and case processing. Example for Swedish: + + unac_except_trans = aaaa AAaa a:a: A:a: o:o: O:o: + + + Note that the translation is not limited to a single character, + you could very well have something like u:ue in the list. + + The default value set for unac_except_trans can't be listed here + because I have trouble with SGML and UTF-8, but it only contains + ligature decompositions: german ss, oe, ae, fi, fl. + + This parameter can't be defined for subdirectories, it is global, + because there is no way to do otherwise when querying. If you have + document sets which would need different values, you will have to + index and query them separately. + + maildefcharset + + This can be used to define the default character set specifically + for email messages which don't specify it. This is mainly useful + for readpst (libpst) dumps, which are utf-8 but do not say so. + + localfields + + This allows setting fields for all documents under a given + directory. Typical usage would be to set an "rclaptg" field, to be + used in mimeview to select a specific viewer. If several fields + are to be set, they should be separated with a semi-colon (';') + character, which there is currently no way to escape. Also note + the initial semi-colon. Example: localfields= ;rclaptg=gnus;other + = val, then select specifier viewer with mimetype|tag=... in + mimeview. + + testmodifusemtime + + If true, use mtime instead of default ctime to determine if a file + has been modified (in addition to size, which is always used). + Setting this can reduce re-indexing on systems where extended + attributes are modified (by some other application), but not + indexed (changing extended attributes only affects ctime). Notes: + + o This may prevent detection of change in some marginal file + rename cases (the target would need to have the same size and + mtime). + + o You should probably also set noxattrfields to 1 in this case, + except if you still prefer to perform xattr indexing, for + example if the local file update pattern makes it of value + (as in general, there is a risk for pure extended attributes + updates without file modification to go undetected). + + Perform a full index reset after changing the value of this + parameter. + + noxattrfields + + Recoll versions 1.19 and later automatically translate file + extended attributes into document fields (to be processed + according to the parameters from the fields file). Setting this + variable to 1 will disable the behaviour. + + metadatacmds + + This allows executing external commands for each file and storing + the output in Recoll document fields. This could be used for + example to index external tag data. The value is a list of field + names and commands, don't forget an initial semi-colon. Example: + + [/some/area/of/the/fs] + metadatacmds = ; tags = tmsu tags %f; otherfield = somecmd -xx %f + + + As a specially disgusting hack brought by Recoll 1.19.7, if a + "field name" begins with rclmulti, the data returned by the + command is expected to contain multiple field values, in + configuration file format. This allows setting several fields by + executing a single command. Example: + + metadatacmds = ; rclmulti1 = somecmd %f + + + If somecmd returns data in the form of: + + field1 = value1 + field2 = value for field2 + + + field1 and field2 will be set inside the document metadata. + + 5.4.2.3. Parameters affecting where and how we store things: + + dbdir + + The name of the Xapian data directory. It will be created if + needed when the index is initialized. If this is not an absolute + path, it will be interpreted relative to the configuration + directory. The value can have embedded spaces but starting or + trailing spaces will be trimmed. You cannot use quotes here. + + idxstatusfile + + The name of the scratch file where the indexer process updates its + status. Default: idxstatus.txt inside the configuration directory. + + maxfsoccuppc + + Maximum file system occupation before we stop indexing. The value + is a percentage, corresponding to what the "Capacity" df output + column shows. The default value is 0, meaning no checking. + + mboxcachedir + + The directory where mbox message offsets cache files are held. + This is normally $RECOLL_CONFDIR/mboxcache, but it may be useful + to share a directory between different configurations. + + mboxcacheminmbs + + The minimum mbox file size over which we cache the offsets. There + is really no sense in caching offsets for small files. The default + is 5 MB. + + webcachedir + + This is only used by the web browser plugin indexing code, and + defines where the cache for visited pages will live. Default: + $RECOLL_CONFDIR/webcache + + webcachemaxmbs + + This is only used by the web browser plugin indexing code, and + defines the maximum size for the web page cache. Default: 40 MB. + Quite unfortunately, this is only taken into account when creating + the cache file. You need to delete the file for a change to be + taken into account. + + idxflushmb + + Threshold (megabytes of new text data) where we flush from memory + to disk index. Setting this can help control memory usage. A value + of 0 means no explicit flushing, letting Xapian use its own + default, which is flushing every 10000 (or XAPIAN_FLUSH_THRESHOLD) + documents, which gives little memory usage control, as memory + usage also depends on average document size. The default value is + 10, and it is probably a bit low. If your system usually has free + memory, you can try higher values between 20 and 80. In my + experience, values beyond 100 are always counterproductive. + + 5.4.2.4. Parameters affecting multithread processing + + The Recoll indexing process recollindex can use multiple threads to speed + up indexing on multiprocessor systems. The work done to index files is + divided in several stages and some of the stages can be executed by + multiple threads. The stages are: + + 1. File system walking: this is always performed by the main thread. + 2. File conversion and data extraction. + 3. Text processing (splitting, stemming, etc.) + 4. Xapian index update. + + You can also read a longer document about the transformation of Recoll + indexing to multithreading. + + The threads configuration is controlled by two configuration file + parameters. + + thrQSizes + + This variable defines the job input queues configuration. There + are three possible queues for stages 2, 3 and 4, and this + parameter should give the queue depth for each stage (three + integer values). If a value of -1 is used for a given stage, no + queue is used, and the thread will go on performing the next + stage. In practise, deep queues have not been shown to increase + performance. A value of 0 for the first queue tells Recoll to + perform autoconfiguration (no need for the two other values in + this case) - this is the default configuration. + + thrTCounts + + This defines the number of threads used for each stage. If a value + of -1 is used for one of the queue depths, the corresponding + thread count is ignored. It makes no sense to use a value other + than 1 for the last stage because updating the Xapian index is + necessarily single-threaded (and protected by a mutex). + + The following example would use three queues (of depth 2), and 4 threads + for converting source documents, 2 for processing their text, and one to + update the index. This was tested to be the best configuration on the test + system (quadri-processor with multiple disks). + + thrQSizes = 2 2 2 + thrTCounts = 4 2 1 + + The following example would use a single queue, and the complete + processing for each document would be performed by a single thread + (several documents will still be processed in parallel in most cases). The + threads will use mutual exclusion when entering the index update stage. In + practise the performance would be close to the precedent case in general, + but worse in certain cases (e.g. a Zip archive would be performed purely + sequentially), so the previous approach is preferred. YMMV... The 2 last + values for thrTCounts are ignored. + + thrQSizes = 2 -1 -1 + thrTCounts = 6 1 1 + + The following example would disable multithreading. Indexing will be + performed by a single thread. + + thrQSizes = -1 -1 -1 + + 5.4.2.5. Miscellaneous parameters: + + autodiacsens + + IF the index is not stripped, decide if we automatically trigger + diacritics sensitivity if the search term has accented characters + (not in unac_except_trans). Else you need to use the query + language and the D modifier to specify diacritics sensitivity. + Default is no. + + autocasesens + + IF the index is not stripped, decide if we automatically trigger + character case sensitivity if the search term has upper-case + characters in any but the first position. Else you need to use the + query language and the C modifier to specify character-case + sensitivity. Default is yes. + + loglevel,daemloglevel + + Verbosity level for recoll and recollindex. A value of 4 lists + quite a lot of debug/information messages. 2 only lists errors. + The daemversion is specific to the indexing monitor daemon. + + logfilename, daemlogfilename + + Where the messages should go. 'stderr' can be used as a special + value, and is the default. The daemversion is specific to the + indexing monitor daemon. + + checkneedretryindexscript + + This defines the name for a command executed by recollindex when + starting indexing. If the exit status of the command is 0, + recollindex retries to index all files which previously could not + be indexed because of data extraction errors. The default value is + a script which checks if any of the common bin directories have + changed (indicating that a helper program may have been + installed). + + mondelaypatterns + + This allows specify wildcard path patterns (processed with + fnmatch(3) with 0 flag), to match files which change too often and + for which a delay should be observed before re-indexing. This is a + space-separated list, each entry being a pattern and a time in + seconds, separated by a colon. You can use double quotes if a path + entry contains white space. Example: + + mondelaypatterns = *.log:20 "this one has spaces*:10" + + + monixinterval + + Minimum interval (seconds) for processing the indexing queue. The + real time monitor does not process each event when it comes in, + but will wait this time for the queue to accumulate to diminish + overhead and in order to aggregate multiple events to the same + file. Default 30 S. + + monauxinterval + + Period (in seconds) at which the real time monitor will regenerate + the auxiliary databases (spelling, stemming) if needed. The + default is one hour. + + monioniceclass, monioniceclassdata + + These allow defining the ionice class and data used by the indexer + (default class 3, no data). + + filtermaxseconds + + Maximum handler execution time, after which it is aborted. Some + postscript programs just loop... + + filtermaxmbytes + + Recoll 1.20.7 and later. Maximum handler memory utilisation. This + uses setrlimit(RLIMIT_AS) on most systems (total virtual memory + space size limit). Some programs may start with 500 MBytes of + mapped shared libraries, so take this into account when choosing a + value. The default is a liberal 2000MB. + + filtersdir + + A directory to search for the external input handler scripts used + to index some types of files. The value should not be changed, + except if you want to modify one of the default scripts. The value + can be redefined for any sub-directory. + + iconsdir + + The name of the directory where recoll result list icons are + stored. You can change this if you want different images. + + idxabsmlen + + Recoll stores an abstract for each indexed file inside the + database. The text can come from an actual 'abstract' section in + the document or will just be the beginning of the document. It is + stored in the index so that it can be displayed inside the result + lists without decoding the original file. The idxabsmlen parameter + defines the size of the stored abstract. The default value is 250 + bytes. The search interface gives you the choice to display this + stored text or a synthetic abstract built by extracting text + around the search terms. If you always prefer the synthetic + abstract, you can reduce this value and save a little space. + + idxmetastoredlen + + Maximum stored length for metadata fields. This does not affect + indexing (the whole field is processed anyway), just the amount of + data stored in the index for the purpose of displaying fields + inside result lists or previews. The default value is 150 bytes + which may be too low if you have custom fields. + + aspellLanguage + + Language definitions to use when creating the aspell dictionary. + The value must match a set of aspell language definition files. + You can type "aspell config" to see where these are installed + (look for data-dir). The default if the variable is not set is to + use your desktop national language environment to guess the value. + + noaspell + + If this is set, the aspell dictionary generation is turned off. + Useful for cases where you don't need the functionality or when it + is unusable because aspell crashes during dictionary generation. + + mhmboxquirks + + This allows definining location-related quirks for the mailbox + handler. Currently only the tbird flag is defined, and it should + be set for directories which hold Thunderbird data, as their + folder format is weird. + + 5.4.3. The fields file + + This file contains information about dynamic fields handling in Recoll. + Some very basic fields have hard-wired behaviour, and, mostly, you should + not change the original data inside the fields file. But you can create + custom fields fitting your data and handle them just like they were native + ones. + + The fields file has several sections, which each define an aspect of + fields processing. Quite often, you'll have to modify several sections to + obtain the desired behaviour. + + We will only give a short description here, you should refer to the + comments inside the default file for more detailed information. + + Field names should be lowercase alphabetic ASCII. + + [prefixes] + + A field becomes indexed (searchable) by having a prefix defined in + this section. + + [stored] + + A field becomes stored (displayable inside results) by having its + name listed in this section (typically with an empty value). + + [aliases] + + This section defines lists of synonyms for the canonical names + used inside the [prefixes] and [stored] sections + + [queryaliases] + + This section also defines aliases for the canonic field names, + with the difference that the substitution will only be used at + query time, avoiding any possibility that the value would pick-up + random metadata from documents. + + handler-specific sections + + Some input handlers may need specific configuration for handling + fields. Only the email message handler currently has such a + section (named [mail]). It allows indexing arbitrary email headers + in addition to the ones indexed by default. Other such sections + may appear in the future. + + Here follows a small example of a personal fields file. This would extract + a specific email header and use it as a searchable field, with data + displayable inside result lists. (Side note: as the email handler does no + decoding on the values, only plain ascii headers can be indexed, and only + the first occurrence will be used for headers that occur several times). + + [prefixes] + # Index mailmytag contents (with the given prefix) + mailmytag = XMTAG + + [stored] + # Store mailmytag inside the document data record (so that it can be + # displayed - as %(mailmytag) - in result lists). + mailmytag = + + [queryaliases] + filename = fn + containerfilename = cfn + + [mail] + # Extract the X-My-Tag mail header, and use it internally with the + # mailmytag field name + x-my-tag = mailmytag + + 5.4.3.1. Extended attributes in the fields file + + Recoll versions 1.19 and later process user extended file attributes as + documents fields by default. + + Attributes are processed as fields of the same name, after removing the + user prefix on Linux. + + The [xattrtofields] section of the fields file allows specifying + translations from extended attributes names to Recoll field names. An + empty translation disables use of the corresponding attribute data. + + 5.4.4. The mimemap file + + mimemap specifies the file name extension to MIME type mappings. + + For file names without an extension, or with an unknown one, the system's + file -i command will be executed to determine the MIME type (this can be + switched off inside the main configuration file). + + The mappings can be specified on a per-subtree basis, which may be useful + in some cases. Example: gaim logs have a .txt extension but should be + handled specially, which is possible because they are usually all located + in one place. + + The recoll_noindex mimemap variable has been moved to recoll.conf and + renamed to noContentSuffixes, while keeping the same function, as of + Recoll version 1.21. For older Recoll versions, see the documentation for + noContentSuffixes but use recoll_noindex in mimemap. + + 5.4.5. The mimeconf file + + mimeconf specifies how the different MIME types are handled for indexing, + and which icons are displayed in the recoll result lists. + + Changing the parameters in the [index] section is probably not a good idea + except if you are a Recoll developer. + + The [icons] section allows you to change the icons which are displayed by + recoll in the result lists (the values are the basenames of the png images + inside the iconsdir directory (specified in recoll.conf). + + 5.4.6. The mimeview file + + mimeview specifies which programs are started when you click on an Open + link in a result list. Ie: HTML is normally displayed using firefox, but + you may prefer Konqueror, your openoffice.org program might be named + oofice instead of openoffice etc. + + Changes to this file can be done by direct editing, or through the recoll + GUI preferences dialog. + + If Use desktop preferences to choose document editor is checked in the + Recoll GUI preferences, all mimeview entries will be ignored except the + one labelled application/x-all (which is set to use xdg-open by default). + + In this case, the xallexcepts top level variable defines a list of MIME + type exceptions which will be processed according to the local entries + instead of being passed to the desktop. This is so that specific Recoll + options such as a page number or a search string can be passed to + applications that support them, such as the evince viewer. + + As for the other configuration files, the normal usage is to have a + mimeview inside your own configuration directory, with just the + non-default entries, which will override those from the central + configuration file. + + All viewer definition entries must be placed under a [view] section. + + The keys in the file are normally MIME types. You can add an application + tag to specialize the choice for an area of the filesystem (using a + localfields specification in mimeconf). The syntax for the key is + mimetype|tag + + The nouncompforviewmts entry, (placed at the top level, outside of the + [view] section), holds a list of MIME types that should not be + uncompressed before starting the viewer (if they are found compressed, ie: + mydoc.doc.gz). + + The right side of each assignment holds a command to be executed for + opening the file. The following substitutions are performed: + + o %D. Document date + + o %f. File name. This may be the name of a temporary file if it was + necessary to create one (ie: to extract a subdocument from a + container). + + o %i. Internal path, for subdocuments of containers. The format depends + on the container type. If this appears in the command line, Recoll + will not create a temporary file to extract the subdocument, expecting + the called application (possibly a script) to be able to handle it. + + o %M. MIME type + + o %p. Page index. Only significant for a subset of document types, + currently only PDF, Postscript and DVI files. Can be used to start the + editor at the right page for a match or snippet. + + o %s. Search term. The value will only be set for documents with indexed + page numbers (ie: PDF). The value will be one of the matched search + terms. It would allow pre-setting the value in the "Find" entry inside + Evince for example, for easy highlighting of the term. + + o %u. Url. + + In addition to the predefined values above, all strings like %(fieldname) + will be replaced by the value of the field named fieldname for the + document. This could be used in combination with field customisation to + help with opening the document. + + 5.4.7. The ptrans file + + ptrans specifies query-time path translations. These can be useful in + multiple cases. + + The file has a section for any index which needs translations, either the + main one or additional query indexes. The sections are named with the + Xapian index directory names. No slash character should exist at the end + of the paths (all comparisons are textual). An exemple should make things + sufficiently clear + + [/home/me/.recoll/xapiandb] + /this/directory/moved = /to/this/place + + [/path/to/additional/xapiandb] + /server/volume1/docdir = /net/server/volume1/docdir + /server/volume2/docdir = /net/server/volume2/docdir + + + 5.4.8. Examples of configuration adjustments + + 5.4.8.1. Adding an external viewer for an non-indexed type + + Imagine that you have some kind of file which does not have indexable + content, but for which you would like to have a functional Open link in + the result list (when found by file name). The file names end in .blob and + can be displayed by application blobviewer. + + You need two entries in the configuration files for this to work: + + o In $RECOLL_CONFDIR/mimemap (typically ~/.recoll/mimemap), add the + following line: + + .blob = application/x-blobapp + + Note that the MIME type is made up here, and you could call it + diesel/oil just the same. + + o In $RECOLL_CONFDIR/mimeview under the [view] section, add: + + application/x-blobapp = blobviewer %f + + We are supposing that blobviewer wants a file name parameter here, you + would use %u if it liked URLs better. + + If you just wanted to change the application used by Recoll to display a + MIME type which it already knows, you would just need to edit mimeview. + The entries you add in your personal file override those in the central + configuration, which you do not need to alter. mimeview can also be + modified from the Gui. + + 5.4.8.2. Adding indexing support for a new file type + + Let us now imagine that the above .blob files actually contain indexable + text and that you know how to extract it with a command line program. + Getting Recoll to index the files is easy. You need to perform the above + alteration, and also to add data to the mimeconf file (typically in + ~/.recoll/mimeconf): + + o Under the [index] section, add the following line (more about the + rclblob indexing script later): + + application/x-blobapp = exec rclblob + + o Under the [icons] section, you should choose an icon to be displayed + for the files inside the result lists. Icons are normally 64x64 pixels + PNG files which live in /usr/[local/]share/recoll/images. + + o Under the [categories] section, you should add the MIME type where it + makes sense (you can also create a category). Categories may be used + for filtering in advanced search. + + The rclblob handler should be an executable program or script which exists + inside /usr/[local/]share/recoll/filters. It will be given a file name as + argument and should output the text or html contents on the standard + output. + + The filter programming section describes in more detail how to write an + input handler. + + ---------------------------------------------------------------------- + + Prev Up + 5.3. Building from source Home diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 00000000..dad39bc3 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,653 @@ + +CXXFLAGS ?= @CXXFLAGS@ +LIBXAPIAN=@LIBXAPIAN@ +XAPIANCXXFLAGS=@XAPIANCXXFLAGS@ +LIBICONV=@LIBICONV@ +INCICONV=@INCICONV@ +LIBFAM = @LIBFAM@ +RCLLIBVERSION=@RCLLIBVERSION@ +X_CFLAGS=@X_CFLAGS@ +X_PRE_LIBS=@X_PRE_LIBS@ +X_LIBS=@X_LIBS@ +X_EXTRA_LIBS=@X_EXTRA_LIBS@ +X_LIBX11=@X_LIBX11@ +DEFS=@DEFS@ + +COMMONCPPFLAGS = -I. \ + -I$(top_srcdir)/aspell \ + -I$(top_srcdir)/bincimapmime \ + -I$(top_srcdir)/common \ + -I$(top_srcdir)/index \ + -I$(top_srcdir)/internfile \ + -I$(top_srcdir)/rcldb \ + -I$(top_srcdir)/unac \ + -I$(top_srcdir)/utils \ + -I$(top_srcdir)/xaposix \ + -DBUILDING_RECOLL + +AM_CPPFLAGS = -Wall -Wno-unused -std=c++11 \ + $(COMMONCPPFLAGS) \ + $(INCICONV) \ + $(XAPIANCXXFLAGS) \ + $(X_CFLAGS) \ + -DRECOLL_DATADIR=\"${pkgdatadir}\" \ + -D_GNU_SOURCE \ + $(DEFS) + +ACLOCAL_AMFLAGS = -I m4 + +if NOTHREADS + LIBTHREADS= +else + LIBTHREADS= $(LIBSYSTHREADS) +endif + +librcldir = $(libdir)/recoll +librcl_LTLIBRARIES = librecoll.la + +librecoll_la_SOURCES = \ +aspell/aspell-local.h \ +aspell/rclaspell.cpp \ +aspell/rclaspell.h \ +bincimapmime/config.h \ +bincimapmime/convert.cc \ +bincimapmime/convert.h \ +bincimapmime/mime-inputsource.h \ +bincimapmime/mime-parsefull.cc \ +bincimapmime/mime-parseonlyheader.cc \ +bincimapmime/mime-printbody.cc \ +bincimapmime/mime-utils.h \ +bincimapmime/mime.cc \ +bincimapmime/mime.h \ +common/beaglequeuecache.cpp \ +common/beaglequeuecache.h \ +common/conf_post.h \ +common/cstr.cpp \ +common/cstr.h \ +common/rclconfig.cpp \ +common/rclconfig.h \ +common/rclinit.cpp \ +common/rclinit.h \ +common/syngroups.cpp \ +common/syngroups.h \ +common/textsplit.cpp \ +common/textsplit.h \ +common/unacpp.cpp \ +common/unacpp.h \ +common/uproplist.h \ +common/utf8fn.cpp \ +common/utf8fn.h \ +index/beaglequeue.cpp \ +index/beaglequeue.h \ +index/bglfetcher.cpp \ +index/bglfetcher.h \ +index/checkretryfailed.cpp \ +index/checkretryfailed.h \ +index/exefetcher.cpp \ +index/exefetcher.h \ +index/fetcher.cpp \ +index/fetcher.h \ +index/fsfetcher.cpp \ +index/fsfetcher.h \ +index/fsindexer.cpp \ +index/fsindexer.h \ +index/indexer.cpp \ +index/indexer.h \ +index/mimetype.cpp \ +index/mimetype.h \ +index/rclmon.h \ +index/recollindex.h \ +index/subtreelist.cpp \ +index/subtreelist.h \ +internfile/Filter.h \ +internfile/extrameta.cpp \ +internfile/extrameta.h \ +internfile/htmlparse.cpp \ +internfile/htmlparse.h \ +internfile/indextext.h \ +internfile/internfile.cpp \ +internfile/internfile.h \ +internfile/mh_exec.cpp \ +internfile/mh_exec.h \ +internfile/mh_execm.cpp \ +internfile/mh_execm.h \ +internfile/mh_html.cpp \ +internfile/mh_html.h \ +internfile/mh_mail.cpp \ +internfile/mh_mail.h \ +internfile/mh_mbox.cpp \ +internfile/mh_mbox.h \ +internfile/mh_null.h \ +internfile/mh_symlink.h \ +internfile/mh_text.cpp \ +internfile/mh_text.h \ +internfile/mh_unknown.h \ +internfile/mimehandler.cpp \ +internfile/mimehandler.h \ +internfile/myhtmlparse.cpp \ +internfile/myhtmlparse.h \ +internfile/txtdcode.cpp \ +internfile/uncomp.cpp \ +internfile/uncomp.h \ +query/docseq.cpp \ +query/docseq.h \ +query/docseqdb.cpp \ +query/docseqdb.h \ +query/docseqdocs.h \ +query/docseqhist.cpp \ +query/docseqhist.h \ +query/dynconf.cpp \ +query/dynconf.h \ +query/filtseq.cpp \ +query/filtseq.h \ +query/plaintorich.cpp \ +query/plaintorich.h \ +query/recollq.cpp \ +query/recollq.h \ +query/reslistpager.cpp \ +query/reslistpager.h \ +query/sortseq.cpp \ +query/sortseq.h \ +query/wasaparse.ypp \ +query/wasaparseaux.cpp \ +query/wasaparserdriver.h \ +query/wasatorcl.h \ +rcldb/daterange.cpp \ +rcldb/daterange.h \ +rcldb/expansiondbs.cpp \ +rcldb/expansiondbs.h \ +rcldb/rclabstract.cpp \ +rcldb/rcldb.cpp \ +rcldb/rcldb.h \ +rcldb/rcldb_p.h \ +rcldb/rcldoc.cpp \ +rcldb/rcldoc.h \ +rcldb/rcldups.cpp \ +rcldb/rclquery.cpp \ +rcldb/rclquery.h \ +rcldb/rclquery_p.h \ +rcldb/rclterms.cpp \ +rcldb/searchdata.cpp \ +rcldb/searchdata.h \ +rcldb/searchdatatox.cpp \ +rcldb/searchdataxml.cpp \ +rcldb/stemdb.cpp \ +rcldb/stemdb.h \ +rcldb/stoplist.cpp \ +rcldb/stoplist.h \ +rcldb/synfamily.cpp \ +rcldb/synfamily.h \ +rcldb/termproc.h \ +rcldb/xmacros.h \ +unac/unac.cpp \ +unac/unac.h \ +unac/unac_version.h \ +utils/appformime.cpp \ +utils/appformime.h \ +utils/base64.cpp \ +utils/base64.h \ +utils/cancelcheck.cpp \ +utils/cancelcheck.h \ +utils/chrono.h \ +utils/chrono.cpp \ +utils/circache.cpp \ +utils/circache.h \ +utils/closefrom.cpp \ +utils/closefrom.h \ +utils/conftree.cpp \ +utils/conftree.h \ +utils/copyfile.cpp \ +utils/copyfile.h \ +utils/cpuconf.cpp \ +utils/cpuconf.h \ +utils/ecrontab.cpp \ +utils/ecrontab.h \ +utils/execmd.cpp \ +utils/execmd.h \ +utils/fileudi.cpp \ +utils/fileudi.h \ +utils/fstreewalk.cpp \ +utils/fstreewalk.h \ +utils/hldata.h \ +utils/hldata.cpp \ +utils/idfile.cpp \ +utils/idfile.h \ +utils/listmem.cpp \ +utils/listmem.h \ +utils/log.cpp \ +utils/log.h \ +utils/md5.cpp \ +utils/md5.h \ +utils/md5ut.cpp \ +utils/md5ut.h \ +utils/mimeparse.cpp \ +utils/mimeparse.h \ +utils/netcon.cpp \ +utils/netcon.h \ +utils/pathut.cpp \ +utils/pathut.h \ +utils/pxattr.cpp \ +utils/pxattr.h \ +utils/rclionice.cpp \ +utils/rclionice.h \ +utils/rclutil.h \ +utils/rclutil.cpp \ +utils/readfile.cpp \ +utils/readfile.h \ +utils/refcntr.h \ +utils/smallut.cpp \ +utils/smallut.h \ +utils/strmatcher.cpp \ +utils/strmatcher.h \ +utils/transcode.cpp \ +utils/transcode.h \ +utils/utf8iter.h \ +utils/wipedir.cpp \ +utils/wipedir.h \ +utils/workqueue.h \ +xaposix/safefcntl.h \ +xaposix/safesysstat.h \ +xaposix/safesyswait.h \ +xaposix/safeunistd.h + +BUILT_SOURCES = query/wasaparse.cpp +AM_YFLAGS = -d + +# We use -release: the lib is only shared +# between recoll programs from the same release. +# -version-info $(VERSION_INFO) +librecoll_la_LDFLAGS = -release $(VERSION) \ + -Wl,--no-undefined -Wl,--warn-unresolved-symbols + +librecoll_la_LIBADD = $(LIBXAPIAN) $(LIBICONV) $(LIBTHREADS) + +# There is probably a better way to do this. The KIO needs to be linked +# with librecoll, but librecoll is installed into a non-standard place +# (/usr/lib/recoll). Debian packaging has something against setting an +# rpath on the kio (cause it's not the same package as the lib), so I don't +# know how to link it dynamically. The other thing I don't know is how to +# force automake to build a static lib with the PIC objects. So the +# following target, which is only used from the KIO build, deletes any .a +# and .so and rebuilds the .a with the pic objs (the kio build calls +# configured --disable-static). +# Of course this is very uncomfortably close to automake/libtool internals +# and may not work on all systems. +PicStatic: $(librecoll_la_OBJECTS) + rm -f .libs/librecoll.a + rm -f .libs/librecoll.so + libtool --tag=LD --mode=link gcc -g -O -o librecoll.la \ + $(librecoll_la_OBJECTS) + +bin_PROGRAMS = recollindex +if MAKECMDLINE + bin_PROGRAMS += recollq +endif + +if MAKEXADUMP + bin_PROGRAMS += xadump +endif + +recollindex_SOURCES = \ + index/recollindex.cpp \ + index/rclmonprc.cpp \ + index/rclmonrcv.cpp \ + utils/x11mon.cpp \ + utils/x11mon.h +recollindex_LDADD = librecoll.la $(X_LIBX11) + +recollq_SOURCES = query/recollqmain.cpp +recollq_LDADD = librecoll.la + +xadump_SOURCES = query/xadump.cpp +xadump_LDADD = librecoll.la $(LIBXAPIAN) $(LIBICONV) + +# Note: I'd prefer the generated query parser files not to be distributed +# at all, but failed to achieve this +EXTRA_DIST = \ +bincimapmime/00README.recoll bincimapmime/AUTHORS bincimapmime/COPYING \ +\ +desktop/hotrecoll.py \ +desktop/recoll.appdata.xml \ +desktop/recollindex.desktop \ +desktop/recoll_index_on_ac.sh \ +desktop/recoll-searchgui.desktop \ +desktop/recoll.png desktop/recoll.svg desktop/recoll.xcf \ +\ +doc/man \ +doc/prog \ +doc/user/*.html doc/user/*.css doc/user/*.txt doc/user/*.xml doc/user/Makefile \ +\ +filters \ +\ +index/rclmon.sh \ +\ +kde/kioslave/kio_recoll/00README.txt \ +kde/kioslave/kio_recoll/CMakeLists.txt \ +kde/kioslave/kio_recoll/data/help.html \ +kde/kioslave/kio_recoll/data/searchable.html \ +kde/kioslave/kio_recoll/data/welcome.html \ +kde/kioslave/kio_recoll/dirif.cpp \ +kde/kioslave/kio_recoll/htmlif.cpp \ +kde/kioslave/kio_recoll/kio_recoll.cpp \ +kde/kioslave/kio_recoll/kio_recoll.h \ +kde/kioslave/kio_recoll/recollf.protocol \ +kde/kioslave/kio_recoll/recollnolist.protocol \ +kde/kioslave/kio_recoll/recoll.protocol \ +\ +query/location.hh query/position.hh query/stack.hh \ +\ +qtgui/advsearch.ui \ +qtgui/advsearch_w.cpp \ +qtgui/advsearch_w.h \ +qtgui/advshist.cpp \ +qtgui/advshist.h \ +qtgui/confgui/confgui.cpp \ +qtgui/confgui/confgui.h \ +qtgui/confgui/confguiindex.cpp \ +qtgui/confgui/confguiindex.h \ +qtgui/confgui/conflinkrcl.h \ +qtgui/confgui/main.cpp \ +qtgui/crontool.cpp \ +qtgui/crontool.h \ +qtgui/crontool.ui \ +qtgui/firstidx.h \ +qtgui/firstidx.ui \ +qtgui/fragbuts.cpp \ +qtgui/fragbuts.h \ +qtgui/guiutils.cpp \ +qtgui/guiutils.h \ +qtgui/i18n/recoll_cs.qm qtgui/i18n/recoll_cs.ts \ +qtgui/i18n/recoll_da.qm qtgui/i18n/recoll_da.ts \ +qtgui/i18n/recoll_de.qm qtgui/i18n/recoll_de.ts \ +qtgui/i18n/recoll_el.qm qtgui/i18n/recoll_el.ts \ +qtgui/i18n/recoll_es.qm qtgui/i18n/recoll_es.ts \ +qtgui/i18n/recoll_fr.qm qtgui/i18n/recoll_fr.ts \ +qtgui/i18n/recoll_it.qm qtgui/i18n/recoll_it.ts \ +qtgui/i18n/recoll_lt.qm qtgui/i18n/recoll_lt.ts \ +qtgui/i18n/recoll_pl.qm qtgui/i18n/recoll_pl.ts \ +qtgui/i18n/recoll_ru.qm qtgui/i18n/recoll_ru.ts \ +qtgui/i18n/recoll_tr.qm qtgui/i18n/recoll_tr.ts \ +qtgui/i18n/recoll_uk.qm qtgui/i18n/recoll_uk.ts \ +qtgui/i18n/recoll_xx.qm qtgui/i18n/recoll_xx.ts \ +qtgui/i18n/recoll_zh.qm qtgui/i18n/recoll_zh.ts \ +qtgui/i18n/recoll_zh_CN.qm qtgui/i18n/recoll_zh_CN.ts \ +qtgui/idxsched.h \ +qtgui/idxsched.ui \ +qtgui/images/asearch.png \ +qtgui/images/cancel.png \ +qtgui/images/close.png \ +qtgui/images/code-block.png \ +qtgui/images/down.png \ +qtgui/images/firstpage.png \ +qtgui/images/history.png \ +qtgui/images/nextpage.png \ +qtgui/images/prevpage.png \ +qtgui/images/recoll.icns \ +qtgui/images/recoll.png \ +qtgui/images/sortparms.png \ +qtgui/images/spell.png \ +qtgui/images/table.png \ +qtgui/images/up.png \ +qtgui/main.cpp \ +qtgui/mtpics/License_sidux.txt \ +qtgui/mtpics/README \ +qtgui/mtpics/aptosid-book.png \ +qtgui/mtpics/aptosid-manual-copyright.txt \ +qtgui/mtpics/aptosid-manual.png \ +qtgui/mtpics/archive.png \ +qtgui/mtpics/book.png \ +qtgui/mtpics/bookchap.png \ +qtgui/mtpics/document.png \ +qtgui/mtpics/drawing.png \ +qtgui/mtpics/emblem-symbolic-link.png \ +qtgui/mtpics/folder.png \ +qtgui/mtpics/html.png \ +qtgui/mtpics/image.png \ +qtgui/mtpics/message.png \ +qtgui/mtpics/mozilla_doc.png \ +qtgui/mtpics/pdf.png \ +qtgui/mtpics/pidgin.png \ +qtgui/mtpics/postscript.png \ +qtgui/mtpics/presentation.png \ +qtgui/mtpics/sidux-book.png \ +qtgui/mtpics/soffice.png \ +qtgui/mtpics/source.png \ +qtgui/mtpics/sownd.png \ +qtgui/mtpics/spreadsheet.png \ +qtgui/mtpics/text-x-python.png \ +qtgui/mtpics/txt.png \ +qtgui/mtpics/video.png \ +qtgui/mtpics/wordprocessing.png \ +qtgui/multisave.cpp \ +qtgui/multisave.h \ +qtgui/preview_load.cpp \ +qtgui/preview_load.h \ +qtgui/preview_plaintorich.cpp \ +qtgui/preview_plaintorich.h \ +qtgui/preview_w.cpp \ +qtgui/preview_w.h \ +qtgui/ptrans.ui \ +qtgui/ptrans_w.cpp \ +qtgui/ptrans_w.h \ +qtgui/rclhelp.cpp \ +qtgui/rclhelp.h \ +qtgui/rclm_idx.cpp \ +qtgui/rclm_preview.cpp \ +qtgui/rclm_saveload.cpp \ +qtgui/rclm_view.cpp \ +qtgui/rclm_wins.cpp \ +qtgui/rclmain.ui \ +qtgui/rclmain_w.cpp \ +qtgui/rclmain_w.h \ +qtgui/rclzg.cpp \ +qtgui/rclzg.h \ +qtgui/recoll.h \ +qtgui/recoll.pro.in \ +qtgui/recoll.qrc \ +qtgui/reslist.cpp \ +qtgui/reslist.h \ +qtgui/respopup.cpp \ +qtgui/respopup.h \ +qtgui/restable.cpp \ +qtgui/restable.h \ +qtgui/restable.ui \ +qtgui/rtitool.cpp \ +qtgui/rtitool.h \ +qtgui/rtitool.ui \ +qtgui/searchclause_w.cpp \ +qtgui/searchclause_w.h \ +qtgui/snippets.ui \ +qtgui/snippets_w.cpp \ +qtgui/snippets_w.h \ +qtgui/specialindex.h \ +qtgui/specialindex.ui \ +qtgui/spell.ui \ +qtgui/spell_w.cpp \ +qtgui/spell_w.h \ +qtgui/ssearch_w.cpp \ +qtgui/ssearch_w.h \ +qtgui/ssearchb.ui \ +qtgui/systray.cpp \ +qtgui/systray.h \ +qtgui/ui_rclmain.h-4.5 \ +qtgui/uiprefs.ui \ +qtgui/uiprefs_w.cpp \ +qtgui/uiprefs_w.h \ +qtgui/viewaction.ui \ +qtgui/viewaction_w.cpp \ +qtgui/viewaction_w.h \ +qtgui/webcache.ui \ +qtgui/webcache.cpp \ +qtgui/webcache.h \ +qtgui/widgets/editdialog.h \ +qtgui/widgets/editdialog.ui \ +qtgui/widgets/listdialog.h \ +qtgui/widgets/listdialog.ui \ +qtgui/widgets/qxtconfirmationmessage.cpp \ +qtgui/widgets/qxtconfirmationmessage.h \ +qtgui/widgets/qxtglobal.h \ +qtgui/xmltosd.cpp \ +qtgui/xmltosd.h \ +\ +python/README.txt \ +python/recoll/Makefile.in \ +python/recoll/pyrclextract.cpp \ +python/recoll/pyrecoll.cpp \ +python/recoll/pyrecoll.h \ +python/recoll/recoll/__init__.py \ +python/recoll/recoll/rclconfig.py \ +python/recoll/setup.py.in \ +python/samples/docdups.py \ +python/samples/mutt-recoll.py \ +python/samples/rcldlkp.py \ +python/samples/rclmbox.py \ +python/samples/recollgui/Makefile \ +python/samples/recollgui/qrecoll.py \ +python/samples/recollgui/rclmain.ui \ +python/samples/recollq.py \ +python/samples/recollqsd.py \ +\ + \ +sampleconf/fields sampleconf/fragbuts.xml sampleconf/mimeconf \ +sampleconf/mimemap sampleconf/mimeview sampleconf/mimeview.mac \ +sampleconf/recoll.conf sampleconf/recoll.qss \ +\ +unac/AUTHORS unac/COPYING unac/README unac/README.recoll unac/unac.c \ +\ +VERSION + +# EXTRA_DIST: The Php Code does not build anymore. No need to ship it until +# someone fixes it: +# php/00README.txt php/recoll/config.m4 php/recoll/make.sh +# php/recoll/php_recoll.h php/recoll/recoll.cpp php/sample/shell.php + +if MAKEPYTHON +all-local: recollpython +recollpython: librecoll.la + ${MAKE} -C python/recoll libdir=$(libdir) +install-exec-local: recollpython-install +recollpython-install: + (cd python/recoll; \ + if test -f /etc/debian_version ; then \ + OPTSFORPYTHON=--install-layout=deb; \ + fi; \ + set -x; \ + python setup.py install \ + --prefix=${prefix} --root=$${DESTDIR:-/} $${OPTSFORPYTHON}) +clean-local: recollpython-clean +recollpython-clean: + rm -rf python/recoll/build +endif + +if MAKEQT +all-local: recollqt +recollqt: librecoll.la + (cd $(QTGUI); ${QMAKE} PREFIX=${prefix} recoll.pro) + $(MAKE) -C $(QTGUI) LFLAGS="$(LDFLAGS)" prefix=$(prefix) \ + exec_prefix=$(exec_prefix) libdir=$(libdir) +clean-local: recollqt-clean +recollqt-clean: + -$(MAKE) -C $(QTGUI) clean +install-exec-local: recollqt-install +recollqt-install: + $(MAKE) -C $(QTGUI) LFLAGS="$(LDFLAGS)" INSTALL_ROOT=$(DESTDIR) \ + prefix=$(prefix) exec_prefix=$(exec_prefix) libdir=$(libdir) \ + install +endif + +defconfdir = $(pkgdatadir)/examples +defconf_DATA = \ +desktop/recollindex.desktop \ +index/rclmon.sh \ +sampleconf/fragbuts.xml \ +sampleconf/fields \ +sampleconf/recoll.conf \ +sampleconf/mimeconf \ +sampleconf/recoll.qss \ +sampleconf/mimemap \ +sampleconf/mimeview + +filterdir = $(pkgdatadir)/filters +filter_DATA = \ +desktop/hotrecoll.py \ +filters/rcl7z \ +filters/rclabw \ +filters/rclaptosidman \ +filters/rclaudio \ +filters/rclcheckneedretry.sh \ +filters/rclchm \ +filters/rcldia \ +filters/rcldjvu.py \ +filters/rcldoc.py \ +filters/rcldvi \ +filters/rclepub \ +filters/rclexec1.py \ +filters/rclexecm.py \ +filters/rclfb2 \ +filters/rclgaim \ +filters/rclgnm \ +filters/rclics \ +filters/rclimg \ +filters/rclimg.py \ +filters/rclinfo \ +filters/rclkar \ +filters/rclkwd \ +filters/rcllatinclass.py \ +filters/rcllatinstops.zip \ +filters/rcllyx \ +filters/rclman \ +filters/rclpdf.py \ +filters/rclokulnote \ +filters/rclopxml.py \ +filters/rclppt.py \ +filters/rclps \ +filters/rclpurple \ +filters/rclpython \ +filters/rclrar \ +filters/rclrtf.py \ +filters/rclscribus \ +filters/rclshowinfo \ +filters/rclsiduxman \ +filters/rclsoff.py \ +filters/rclsvg.py \ +filters/rcltar \ +filters/rcltex \ +filters/rcltext.py \ +filters/rcluncomp \ +filters/rcluncomp.py \ +filters/rclwar \ +filters/rclwpd \ +filters/rclxls.py \ +filters/rclxml.py \ +filters/rclxmp.py \ +filters/rclxslt.py \ +filters/rclzip \ +filters/ppt-dump.py \ +filters/xls-dump.py \ +filters/xlsxmltocsv.py \ +filters/msodump.zip \ +python/recoll/recoll/rclconfig.py + +install-data-hook: + (cd $(DESTDIR)/$(filterdir); \ + chmod a+x rcl* ppt-dump.py xls-dump.py xlsxmltocsv.py hotrecoll.py; \ + chmod 0644 msodump.zip rclexecm.py rcllatinstops.zip rclconfig.py) + +if MAKEUSERDOC +rdocdir = $(pkgdatadir)/doc +rdoc_DATA = doc/user/usermanual.html doc/user/docbook-xsl.css +doc/user/usermanual.html: doc/user/usermanual.xml + mkdir -p doc/user + test -f doc/user/Makefile || \ + cp -p $(top_srcdir)/doc/user/Makefile doc/user + $(MAKE) -C doc/user VPATH=$(VPATH):$(VPATH)/doc/user usermanual.html +endif + +dist_man1_MANS = doc/man/recoll.1 doc/man/recollq.1 doc/man/recollindex.1 +dist_man5_MANS = doc/man/recoll.conf.5 + +dist-hook: + modified=`hg status | grep -v /$(distdir)/|grep -v debianunitysco`; \ + if test ! -z "$$modified"; then \ + echo Local directory is modified: $$modified ; exit 1; fi + hg tag -f -m "Release $(VERSION) tagged" RECOLL-$(VERSION) diff --git a/src/README b/src/README new file mode 100644 index 00000000..b99332a5 --- /dev/null +++ b/src/README @@ -0,0 +1,4612 @@ + +More documentation can be found in the doc/ directory or at http://www.recoll.org + + + Recoll user manual + + Jean-Francois Dockes + + + + Copyright (c) 2005-2015 Jean-Francois Dockes + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 or any + later version published by the Free Software Foundation; with no Invariant + Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the + license can be found at the following location: GNU web site. + + This document introduces full text search notions and describes the + installation and use of the Recoll application. This version describes + Recoll 1.21. + + ---------------------------------------------------------------------- + + Table of Contents + + 1. Introduction + + 1.1. Giving it a try + + 1.2. Full text search + + 1.3. Recoll overview + + 2. Indexing + + 2.1. Introduction + + 2.1.1. Indexing modes + + 2.1.2. Configurations, multiple indexes + + 2.1.3. Document types + + 2.1.4. Indexing failures + + 2.1.5. Recovery + + 2.2. Index storage + + 2.2.1. Xapian index formats + + 2.2.2. Security aspects + + 2.3. Index configuration + + 2.3.1. Multiple indexes + + 2.3.2. Index case and diacritics sensitivity + + 2.3.3. The index configuration GUI + + 2.4. Indexing WEB pages you wisit + + 2.5. Extended attributes data + + 2.6. Importing external tags + + 2.7. Periodic indexing + + 2.7.1. Running indexing + + 2.7.2. Using cron to automate indexing + + 2.8. Real time indexing + + 2.8.1. Slowing down the reindexing rate for fast + changing files + + 3. Searching + + 3.1. Searching with the Qt graphical user interface + + 3.1.1. Simple search + + 3.1.2. The default result list + + 3.1.3. The result table + + 3.1.4. Running arbitrary commands on result + files (1.20 and later) + + 3.1.5. Displaying thumbnails + + 3.1.6. The preview window + + 3.1.7. The Query Fragments window + + 3.1.8. Complex/advanced search + + 3.1.9. The term explorer tool + + 3.1.10. Multiple indexes + + 3.1.11. Document history + + 3.1.12. Sorting search results and collapsing + duplicates + + 3.1.13. Search tips, shortcuts + + 3.1.14. Saving and restoring queries (1.21 and + later) + + 3.1.15. Customizing the search interface + + 3.2. Searching with the KDE KIO slave + + 3.2.1. What's this + + 3.2.2. Searchable documents + + 3.3. Searching on the command line + + 3.4. Path translations + + 3.5. The query language + + 3.5.1. Modifiers + + 3.6. Search case and diacritics sensitivity + + 3.7. Anchored searches and wildcards + + 3.7.1. More about wildcards + + 3.7.2. Anchored searches + + 3.8. Desktop integration + + 3.8.1. Hotkeying recoll + + 3.8.2. The KDE Kicker Recoll applet + + 4. Programming interface + + 4.1. Writing a document input handler + + 4.1.1. Simple input handlers + + 4.1.2. "Multiple" handlers + + 4.1.3. Telling Recoll about the handler + + 4.1.4. Input handler HTML output + + 4.1.5. Page numbers + + 4.2. Field data processing + + 4.3. API + + 4.3.1. Interface elements + + 4.3.2. Python interface + + 5. Installation and configuration + + 5.1. Installing a binary copy + + 5.2. Supporting packages + + 5.3. Building from source + + 5.3.1. Prerequisites + + 5.3.2. Building + + 5.3.3. Installation + + 5.4. Configuration overview + + 5.4.1. Environment variables + + 5.4.2. The main configuration file, recoll.conf + + 5.4.3. The fields file + + 5.4.4. The mimemap file + + 5.4.5. The mimeconf file + + 5.4.6. The mimeview file + + 5.4.7. The ptrans file + + 5.4.8. Examples of configuration adjustments + +Chapter 1. Introduction + +1.1. Giving it a try + + If you do not like reading manuals (who does?) but wish to give Recoll a + try, just install the application and start the recoll graphical user + interface (GUI), which will ask permission to index your home directory by + default, allowing you to search immediately after indexing completes. + + Do not do this if your home directory contains a huge number of documents + and you do not want to wait or are very short on disk space. In this case, + you may first want to customize the configuration to restrict the indexed + area (for the very impatient with a completed package install, from the + recoll GUI: Preferences -> Indexing configuration, then adjust the Top + directories section). + + Also be aware that you may need to install the appropriate supporting + applications for document types that need them (for example antiword for + Microsoft Word files). + +1.2. Full text search + + Recoll is a full text search application. Full text search finds your data + by content rather than by external attributes (like a file name). You + specify words (terms) which should or should not appear in the text you + are looking for, and receive in return a list of matching documents, + ordered so that the most relevant documents will appear first. + + You do not need to remember in what file or email message you stored a + given piece of information. You just ask for related terms, and the tool + will return a list of documents where these terms are prominent, in a + similar way to Internet search engines. + + Full text search applications try to determine which documents are most + relevant to the search terms you provide. Computer algorithms for + determining relevance can be very complex, and in general are inferior to + the power of the human mind to rapidly determine relevance. The quality of + relevance guessing is probably the most important aspect when evaluating a + search application. + + In many cases, you are looking for all the forms of a word, including + plurals, different tenses for a verb, or terms derived from the same root + or stem (example: floor, floors, floored, flooring...). Queries are + usually automatically expanded to all such related terms (words that + reduce to the same stem). This can be prevented for searching for a + specific form. + + Stemming, by itself, does not accommodate for misspellings or phonetic + searches. A full text search application may also support this form of + approximation. For example, a search for aliterattion returning no result + may propose, depending on index contents, alliteration alteration + alterations altercation as possible replacement terms. + +1.3. Recoll overview + + Recoll uses the Xapian information retrieval library as its storage and + retrieval engine. Xapian is a very mature package using a sophisticated + probabilistic ranking model. + + The Xapian library manages an index database which describes where terms + appear in your document files. It efficiently processes the complex + queries which are produced by the Recoll query expansion mechanism, and is + in charge of the all-important relevance computation task. + + Recoll provides the mechanisms and interface to get data into and out of + the index. This includes translating the many possible document formats + into pure text, handling term variations (using Xapian stemmers), and + spelling approximations (using the aspell speller), interpreting user + queries and presenting results. + + In a shorter way, Recoll does the dirty footwork, Xapian deals with the + intelligent parts of the process. + + The Xapian index can be big (roughly the size of the original document + set), but it is not a document archive. Recoll can only display documents + that still exist at the place from which they were indexed. (Actually, + there is a way to reconstruct a document from the information in the + index, but the result is not nice, as all formatting, punctuation and + capitalization are lost). + + Recoll stores all internal data in Unicode UTF-8 format, and it can index + files of many types with different character sets, encodings, and + languages into the same index. It can process documents embedded inside + other documents (for example a pdf document stored inside a Zip archive + sent as an email attachment...), down to an arbitrary depth. + + Stemming is the process by which Recoll reduces words to their radicals so + that searching does not depend, for example, on a word being singular or + plural (floor, floors), or on a verb tense (flooring, floored). Because + the mechanisms used for stemming depend on the specific grammatical rules + for each language, there is a separate Xapian stemmer module for most + common languages where stemming makes sense. + + Recoll stores the unstemmed versions of terms in the main index and uses + auxiliary databases for term expansion (one for each stemming language), + which means that you can switch stemming languages between searches, or + add a language without needing a full reindex. + + Storing documents written in different languages in the same index is + possible, and commonly done. In this situation, you can specify several + stemming languages for the index. + + Recoll currently makes no attempt at automatic language recognition, which + means that the stemmer will sometimes be applied to terms from other + languages with potentially strange results. In practise, even if this + introduces possibilities of confusion, this approach has been proven quite + useful, and it is much less cumbersome than separating your documents + according to what language they are written in. + + Before version 1.18, Recoll stripped most accents and diacritics from + terms, and converted them to lower case before either storing them in the + index or searching for them. As a consequence, it was impossible to search + for a particular capitalization of a term (US / us), or to discriminate + two terms based on diacritics (sake / sake, mate / mate). + + As of version 1.18, Recoll can optionally store the raw terms, without + accent stripping or case conversion. In this configuration, it is still + possible (and most common) for a query to be insensitive to case and/or + diacritics. Appropriate term expansions are performed before actually + accessing the main index. This is described in more detail in the section + about index case and diacritics sensitivity. + + Recoll has many parameters which define exactly what to index, and how to + classify and decode the source documents. These are kept in configuration + files. A default configuration is copied into a standard location (usually + something like /usr/[local/]share/recoll/examples) during installation. + The default values set by the configuration files in this directory may be + overridden by values that you set inside your personal configuration, + found by default in the .recoll sub-directory of your home directory. The + default configuration will index your home directory with default + parameters and should be sufficient for giving Recoll a try, but you may + want to adjust it later, which can be done either by editing the text + files or by using configuration menus in the recoll GUI. Some other + parameters affecting only the recoll GUI are stored in the standard + location defined by Qt. + + The indexing process is started automatically the first time you execute + the recoll GUI. Indexing can also be performed by executing the + recollindex command. Recoll indexing is multithreaded by default when + appropriate hardware resources are available, and can perform in parallel + multiple tasks among text extraction, segmentation and index updates. + + Searches are usually performed inside the recoll GUI, which has many + options to help you find what you are looking for. However, there are + other ways to perform Recoll searches: mostly a command line interface, a + Python programming interface, a KDE KIO slave module, and Ubuntu Unity + Lens (for older versions) or Scope (for current versions) modules. + +Chapter 2. Indexing + +2.1. Introduction + + Indexing is the process by which the set of documents is analyzed and the + data entered into the database. Recoll indexing is normally incremental: + documents will only be processed if they have been modified since the last + run. On the first execution, all documents will need processing. A full + index build can be forced later by specifying an option to the indexing + command (recollindex -z or -Z). + + recollindex skips files which caused an error during a previous pass. This + is a performance optimization, and a new behaviour in version 1.21 (failed + files were always retried by previous versions). The command line option + -k can be set to retry failed files, for example after updating a filter. + + The following sections give an overview of different aspects of the + indexing processes and configuration, with links to detailed sections. + + Depending on your data, temporary files may be needed during indexing, + some of them possibly quite big. You can use the RECOLL_TMPDIR or TMPDIR + environment variables to determine where they are created (the default is + to use /tmp). Using TMPDIR has the nice property that it may also be taken + into account by auxiliary commands executed by recollindex. + + 2.1.1. Indexing modes + + Recoll indexing can be performed along two different modes: + + o Periodic (or batch) indexing: indexing takes place at discrete times, + by executing the recollindex command. The typical usage is to have a + nightly indexing run programmed into your cron file. + + o Real time indexing: indexing takes place as soon as a file is created + or changed. recollindex runs as a daemon and uses a file system + alteration monitor such as inotify, Fam or Gamin to detect file + changes. + + The choice between the two methods is mostly a matter of preference, and + they can be combined by setting up multiple indexes (ie: use periodic + indexing on a big documentation directory, and real time indexing on a + small home directory). Monitoring a big file system tree can consume + significant system resources. + + The choice of method and the parameters used can be configured from the + recoll GUI: Preferences -> Indexing schedule + + 2.1.2. Configurations, multiple indexes + + The parameters describing what is to be indexed and local preferences are + defined in text files contained in a configuration directory. + + All parameters have defaults, defined in system-wide files. + + Without further configuration, Recoll will index all appropriate files + from your home directory, with a reasonable set of defaults. + + A default personal configuration directory ($HOME/.recoll/) is created + when a Recoll program is first executed. It is possible to create other + configuration directories, and use them by setting the RECOLL_CONFDIR + environment variable, or giving the -c option to any of the Recoll + commands. + + In some cases, it may be interesting to index different areas of the file + system to separate databases. You can do this by using multiple + configuration directories, each indexing a file system area to a specific + database. Typically, this would be done to separate personal and shared + indexes, or to take advantage of the organization of your data to improve + search precision. + + The generated indexes can be queried concurrently in a transparent manner. + + For index generation, multiple configurations are totally independant from + each other. When multiple indexes need to be used for a single search, + some parameters should be consistent among the configurations. + + 2.1.3. Document types + + Recoll knows about quite a few different document types. The parameters + for document types recognition and processing are set in configuration + files. + + Most file types, like HTML or word processing files, only hold one + document. Some file types, like email folders or zip archives, can hold + many individually indexed documents, which may themselves be compound + ones. Such hierarchies can go quite deep, and Recoll can process, for + example, a LibreOffice document stored as an attachment to an email + message inside an email folder archived in a zip file... + + Recoll indexing processes plain text, HTML, OpenDocument + (Open/LibreOffice), email formats, and a few others internally. + + Other file types (ie: postscript, pdf, ms-word, rtf ...) need external + applications for preprocessing. The list is in the installation section. + After every indexing operation, Recoll updates a list of commands that + would be needed for indexing existing files types. This list can be + displayed by selecting the menu option File -> Show Missing Helpers in the + recoll GUI. It is stored in the missing text file inside the configuration + directory. + + By default, Recoll will try to index any file type that it has a way to + read. This is sometimes not desirable, and there are ways to either + exclude some types, or on the contrary to define a positive list of types + to be indexed. In the latter case, any type not in the list will be + ignored. + + Excluding types can be done by adding wildcard name patterns to the + skippedNames list, which can be done from the GUI Index configuration + menu. For versions 1.20 and later, you can alternatively set the + excludedmimetypes list in the configuration file. This can be redefined + for subdirectories. + + You can also define an exclusive list of MIME types to be indexed (no + others will be indexed), by settting the indexedmimetypes configuration + variable. Example: + + indexedmimetypes = text/html application/pdf + + + It is possible to redefine this parameter for subdirectories. Example: + + [/path/to/my/dir] + indexedmimetypes = application/pdf + + + (When using sections like this, don't forget that they remain in effect + until the end of the file or another section indicator). + + excludedmimetypes or indexedmimetypes, can be set either by editing the + main configuration file (recoll.conf), or from the GUI index configuration + tool. + + 2.1.4. Indexing failures + + Indexing may fail for some documents, for a number of reasons: a helper + program may be missing, the document may be corrupt, we may fail to + uncompress a file because no file system space is available, etc. + + Recoll versions prior to 1.21 always retried to index files which had + previously caused an error. This guaranteed that anything that may have + become indexable (for example because a helper had been installed) would + be indexed. However this was bad for performance because some indexing + failures may be quite costly (for example failing to uncompress a big file + because of insufficient disk space). + + The indexer in Recoll versions 1.21 and later do not retry failed file by + default. Retrying will only occur if an explicit option (-k) is set on the + recollindex command line, or if a script executed when recollindex starts + up says so. The script is defined by a configuration variable + (checkneedretryindexscript), and makes a rather lame attempt at deciding + if a helper command may have been installed, by checking if any of the + common bin directories have changed. + + 2.1.5. Recovery + + In the rare case where the index becomes corrupted (which can signal + itself by weird search results or crashes), the index files need to be + erased before restarting a clean indexing pass. Just delete the xapiandb + directory (see next section), or, alternatively, start the next + recollindex with the -z option, which will reset the database before + indexing. + +2.2. Index storage + + The default location for the index data is the xapiandb subdirectory of + the Recoll configuration directory, typically $HOME/.recoll/xapiandb/. + This can be changed via two different methods (with different purposes): + + o You can specify a different configuration directory by setting the + RECOLL_CONFDIR environment variable, or using the -c option to the + Recoll commands. This method would typically be used to index + different areas of the file system to different indexes. For example, + if you were to issue the following commands: + + export RECOLL_CONFDIR=~/.indexes-email + recoll + + + Then Recoll would use configuration files stored in ~/.indexes-email/ + and, (unless specified otherwise in recoll.conf) would look for the + index in ~/.indexes-email/xapiandb/. + + Using multiple configuration directories and configuration options + allows you to tailor multiple configurations and indexes to handle + whatever subset of the available data you wish to make searchable. + + o For a given configuration directory, you can specify a non-default + storage location for the index by setting the dbdir parameter in the + configuration file (see the configuration section). This method would + mainly be of use if you wanted to keep the configuration directory in + its default location, but desired another location for the index, + typically out of disk occupation concerns. + + The size of the index is determined by the size of the set of documents, + but the ratio can vary a lot. For a typical mixed set of documents, the + index size will often be close to the data set size. In specific cases (a + set of compressed mbox files for example), the index can become much + bigger than the documents. It may also be much smaller if the documents + contain a lot of images or other non-indexed data (an extreme example + being a set of mp3 files where only the tags would be indexed). + + Of course, images, sound and video do not increase the index size, which + means that nowadays (2012), typically, even a big index will be negligible + against the total amount of data on the computer. + + The index data directory (xapiandb) only contains data that can be + completely rebuilt by an index run (as long as the original documents + exist), and it can always be destroyed safely. + + 2.2.1. Xapian index formats + + Xapian versions usually support several formats for index storage. A given + major Xapian version will have a current format, used to create new + indexes, and will also support the format from the previous major version. + + Xapian will not convert automatically an existing index from the older + format to the newer one. If you want to upgrade to the new format, or if a + very old index needs to be converted because its format is not supported + any more, you will have to explicitly delete the old index, then run a + normal indexing process. + + Using the -z option to recollindex is not sufficient to change the format, + you will have to delete all files inside the index directory (typically + ~/.recoll/xapiandb) before starting the indexing. + + 2.2.2. Security aspects + + The Recoll index does not hold copies of the indexed documents. But it + does hold enough data to allow for an almost complete reconstruction. If + confidential data is indexed, access to the database directory should be + restricted. + + Recoll (since version 1.4) will create the configuration directory with a + mode of 0700 (access by owner only). As the index data directory is by + default a sub-directory of the configuration directory, this should result + in appropriate protection. + + If you use another setup, you should think of the kind of protection you + need for your index, set the directory and files access modes + appropriately, and also maybe adjust the umask used during index updates. + +2.3. Index configuration + + Variables set inside the Recoll configuration files control which areas of + the file system are indexed, and how files are processed. These variables + can be set either by editing the text files or by using the dialogs in the + recoll GUI. + + The first time you start recoll, you will be asked whether or not you + would like it to build the index. If you want to adjust the configuration + before indexing, just click Cancel at this point, which will get you into + the configuration interface. If you exit at this point, recoll will have + created a ~/.recoll directory containing empty configuration files, which + you can edit by hand. + + The configuration is documented inside the installation chapter of this + document, or in the recoll.conf(5) man page, but the most current + information will most likely be the comments inside the sample file. The + most immediately useful variable you may interested in is probably + topdirs, which determines what subtrees get indexed. + + The applications needed to index file types other than text, HTML or email + (ie: pdf, postscript, ms-word...) are described in the external packages + section. + + As of Recoll 1.18 there are two incompatible types of Recoll indexes, + depending on the treatment of character case and diacritics. The next + section describes the two types in more detail. + + 2.3.1. Multiple indexes + + Multiple Recoll indexes can be created by using several configuration + directories which are usually set to index different areas of the file + system. A specific index can be selected for updating or searching, using + the RECOLL_CONFDIR environment variable or the -c option to recoll and + recollindex. + + A typical usage scenario for the multiple index feature would be for a + system administrator to set up a central index for shared data, that you + choose to search or not in addition to your personal data. Of course, + there are other possibilities. There are many cases where you know the + subset of files that should be searched, and where narrowing the search + can improve the results. You can achieve approximately the same effect + with the directory filter in advanced search, but multiple indexes will + have much better performance and may be worth the trouble. + + A recollindex program instance can only update one specific index. + + The main index (defined by RECOLL_CONFDIR or -c) is always active. If this + is undesirable, you can set up your base configuration to index an empty + directory. + + The different search interfaces (GUI, command line, ...) have different + methods to define the set of indexes to be used, see the appropriate + section. + + If a set of multiple indexes are to be used together for searches, some + configuration parameters must be consistent among the set. These are + parameters which need to be the same when indexing and searching. As the + parameters come from the main configuration when searching, they need to + be compatible with what was set when creating the other indexes (which + came from their respective configuration directories). + + Most importantly, all indexes to be queried concurrently must have the + same option concerning character case and diacritics stripping, but there + are other constraints. Most of the relevant parameters are described in + the linked section. + + 2.3.2. Index case and diacritics sensitivity + + As of Recoll version 1.18 you have a choice of building an index with + terms stripped of character case and diacritics, or one with raw terms. + For a source term of Resume, the former will store resume, the latter + Resume. + + Each type of index allows performing searches insensitive to case and + diacritics: with a raw index, the user entry will be expanded to match all + case and diacritics variations present in the index. With a stripped + index, the search term will be stripped before searching. + + A raw index allows for another possibility which a stripped index cannot + offer: using case and diacritics to discriminate between terms, returning + different results when searching for US and us or resume and resume. Read + the section about search case and diacritics sensitivity for more details. + + The type of index to be created is controlled by the indexStripChars + configuration variable which can only be changed by editing the + configuration file. Any change implies an index reset (not automated by + Recoll), and all indexes in a search must be set in the same way (again, + not checked by Recoll). + + If the indexStripChars is not set, Recoll 1.18 creates a stripped index by + default, for compatibility with previous versions. + + As a cost for added capability, a raw index will be slightly bigger than a + stripped one (around 10%). Also, searches will be more complex, so + probably slightly slower, and the feature is still young, so that a + certain amount of weirdness cannot be excluded. + + One of the most adverse consequence of using a raw index is that some + phrase and proximity searches may become impossible: because each term + needs to be expanded, and all combinations searched for, the + multiplicative expansion may become unmanageable. + + 2.3.3. The index configuration GUI + + Most parameters for a given index configuration can be set from a recoll + GUI running on this configuration (either as default, or by setting + RECOLL_CONFDIR or the -c option.) + + The interface is started from the Preferences -> Index Configuration menu + entry. It is divided in four tabs, Global parameters, Local parameters, + Web history (which is explained in the next section) and Search + parameters. + + The Global parameters tab allows setting global variables, like the lists + of top directories, skipped paths, or stemming languages. + + The Local parameters tab allows setting variables that can be redefined + for subdirectories. This second tab has an initially empty list of + customisation directories, to which you can add. The variables are then + set for the currently selected directory (or at the top level if the empty + line is selected). + + The Search parameters section defines parameters which are used at query + time, but are global to an index and affect all search tools, not only the + GUI. + + The meaning for most entries in the interface is self-evident and + documented by a ToolTip popup on the text label. For more detail, you will + need to refer to the configuration section of this guide. + + The configuration tool normally respects the comments and most of the + formatting inside the configuration file, so that it is quite possible to + use it on hand-edited files, which you might nevertheless want to backup + first... + +2.4. Indexing WEB pages you wisit + + With the help of a Firefox extension, Recoll can index the Internet pages + that you visit. The extension was initially designed for the Beagle + indexer, but it has recently be renamed and better adapted to Recoll. + + The extension works by copying visited WEB pages to an indexing queue + directory, which Recoll then processes, indexing the data, storing it into + a local cache, then removing the file from the queue. + + This feature can be enabled in the GUI Index configuration panel, or by + editing the configuration file (set processwebqueue to 1). + + A current pointer to the extension can be found, along with up-to-date + instructions, on the Recoll wiki. + + A copy of the indexed WEB pages is retained by Recoll in a local cache + (from which previews can be fetched). The cache size can be adjusted from + the Index configuration / Web history panel. Once the maximum size is + reached, old pages are purged - both from the cache and the index - to + make room for new ones, so you need to explicitly archive in some other + place the pages that you want to keep indefinitely. + +2.5. Extended attributes data + + User extended attributes are named pieces of information that most modern + file systems can attach to any file. + + Recoll versions 1.19 and later process extended attributes as document + fields by default. For older versions, this has to be activated at build + time. + + A freedesktop standard defines a few special attributes, which are handled + as such by Recoll: + + mime_type + + If set, this overrides any other determination of the file MIME + type. + + charset + If set, this defines the file character set (mostly useful for + plain text files). + + By default, other attributes are handled as Recoll fields. On Linux, the + user prefix is removed from the name. This can be configured more + precisely inside the fields configuration file. + +2.6. Importing external tags + + During indexing, it is possible to import metadata for each file by + executing commands. For example, this could extract user tag data for the + file and store it in a field for indexing. + + See the section about the metadatacmds field in the main configuration + chapter for more detail. + +2.7. Periodic indexing + + 2.7.1. Running indexing + + Indexing is always performed by the recollindex program, which can be + started either from the command line or from the File menu in the recoll + GUI program. When started from the GUI, the indexing will run on the same + configuration recoll was started on. When started from the command line, + recollindex will use the RECOLL_CONFDIR variable or accept a -c confdir + option to specify a non-default configuration directory. + + If the recoll program finds no index when it starts, it will automatically + start indexing (except if canceled). + + The recollindex indexing process can be interrupted by sending an + interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) signal. Some time may + elapse before the process exits, because it needs to properly flush and + close the index. This can also be done from the recoll GUI File -> Stop + Indexing menu entry. + + After such an interruption, the index will be somewhat inconsistent + because some operations which are normally performed at the end of the + indexing pass will have been skipped (for example, the stemming and + spelling databases will be inexistant or out of date). You just need to + restart indexing at a later time to restore consistency. The indexing will + restart at the interruption point (the full file tree will be traversed, + but files that were indexed up to the interruption and for which the index + is still up to date will not need to be reindexed). + + recollindex has a number of other options which are described in its man + page. Only a few will be described here. + + Option -z will reset the index when starting. This is almost the same as + destroying the index files (the nuance is that the Xapian format version + will not be changed). + + Option -Z will force the update of all documents without resetting the + index first. This will not have the "clean start" aspect of -z, but the + advantage is that the index will remain available for querying while it is + rebuilt, which can be a significant advantage if it is very big (some + installations need days for a full index rebuild). + + Option -k will force retrying files which previously failed to be indexed, + for example because of a missing helper program. + + Of special interest also, maybe, are the -i and -f options. -i allows + indexing an explicit list of files (given as command line parameters or + read on stdin). -f tells recollindex to ignore file selection parameters + from the configuration. Together, these options allow building a custom + file selection process for some area of the file system, by adding the top + directory to the skippedPaths list and using an appropriate file selection + method to build the file list to be fed to recollindex -if. Trivial + example: + + find . -name indexable.txt -print | recollindex -if + + + recollindex -i will not descend into subdirectories specified as + parameters, but just add them as index entries. It is up to the external + file selection method to build the complete file list. + + 2.7.2. Using cron to automate indexing + + The most common way to set up indexing is to have a cron task execute it + every night. For example the following crontab entry would do it every day + at 3:30AM (supposing recollindex is in your PATH): + + 30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1 + + Or, using anacron: + + 1 15 su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1" + + As of version 1.17 the Recoll GUI has dialogs to manage crontab entries + for recollindex. You can reach them from the Preferences -> Indexing + Schedule menu. They only work with the good old cron, and do not give + access to all features of cron scheduling. + + The usual command to edit your crontab is crontab -e (which will usually + start the vi editor to edit the file). You may have more sophisticated + tools available on your system. + + Please be aware that there may be differences between your usual + interactive command line environment and the one seen by crontab commands. + Especially the PATH variable may be of concern. Please check the crontab + manual pages about possible issues. + +2.8. Real time indexing + + Real time monitoring/indexing is performed by starting the recollindex -m + command. With this option, recollindex will detach from the terminal and + become a daemon, permanently monitoring file changes and updating the + index. + + Under KDE, Gnome and some other desktop environments, the daemon can + automatically started when you log in, by creating a desktop file inside + the ~/.config/autostart directory. This can be done for you by the Recoll + GUI. Use the Preferences->Indexing Schedule menu. + + With older X11 setups, starting the daemon is normally performed as part + of the user session script. + + The rclmon.sh script can be used to easily start and stop the daemon. It + can be found in the examples directory (typically + /usr/local/[share/]recoll/examples). + + For example, my out of fashion xdm-based session has a .xsession script + with the following lines at the end: + + recollconf=$HOME/.recoll-home + recolldata=/usr/local/share/recoll + RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start + + fvwm + + + The indexing daemon gets started, then the window manager, for which the + session waits. + + By default the indexing daemon will monitor the state of the X11 session, + and exit when it finishes, it is not necessary to kill it explicitly. (The + X11 server monitoring can be disabled with option -x to recollindex). + + If you use the daemon completely out of an X11 session, you need to add + option -x to disable X11 session monitoring (else the daemon will not + start). + + By default, the messages from the indexing daemon will be setn to the same + file as those from the interactive commands (logfilename). You may want to + change this by setting the daemlogfilename and daemloglevel configuration + parameters. Also the log file will only be truncated when the daemon + starts. If the daemon runs permanently, the log file may grow quite big, + depending on the log level. + + When building Recoll, the real time indexing support can be customised + during package configuration with the --with[out]-fam or + --with[out]-inotify options. The default is currently to include inotify + monitoring on systems that support it, and, as of Recoll 1.17, gamin + support on FreeBSD. + + While it is convenient that data is indexed in real time, repeated + indexing can generate a significant load on the system when files such as + email folders change. Also, monitoring large file trees by itself + significantly taxes system resources. You probably do not want to enable + it if your system is short on resources. Periodic indexing is adequate in + most cases. + + Increasing resources for inotify + + On Linux systems, monitoring a big tree may need increasing the resources + available to inotify, which are normally defined in /etc/sysctl.conf. + + ### inotify + # + # cat /proc/sys/fs/inotify/max_queued_events - 16384 + # cat /proc/sys/fs/inotify/max_user_instances - 128 + # cat /proc/sys/fs/inotify/max_user_watches - 16384 + # + # -- Change to: + # + fs.inotify.max_queued_events=32768 + fs.notify.max_user_instances=256 + fs.inotify.max_user_watches=32768 + + + Especially, you will need to trim your tree or adjust the max_user_watches + value if indexing exits with a message about errno ENOSPC (28) from + inotify_add_watch. + + 2.8.1. Slowing down the reindexing rate for fast changing files + + When using the real time monitor, it may happen that some files need to be + indexed, but change so often that they impose an excessive load for the + system. + + Recoll provides a configuration option to specify the minimum time before + which a file, specified by a wildcard pattern, cannot be reindexed. See + the mondelaypatterns parameter in the configuration section. + +Chapter 3. Searching + +3.1. Searching with the Qt graphical user interface + + The recoll program provides the main user interface for searching. It is + based on the Qt library. + + recoll has two search modes: + + o Simple search (the default, on the main screen) has a single entry + field where you can enter multiple words. + + o Advanced search (a panel accessed through the Tools menu or the + toolbox bar icon) has multiple entry fields, which you may use to + build a logical condition, with additional filtering on file type, + location in the file system, modification date, and size. + + In most cases, you can enter the terms as you think them, even if they + contain embedded punctuation or other non-textual characters. For example, + Recoll can handle things like email addresses, or arbitrary cut and paste + from another text window, punctation and all. + + The main case where you should enter text differently from how it is + printed is for east-asian languages (Chinese, Japanese, Korean). Words + composed of single or multiple characters should be entered separated by + white space in this case (they would typically be printed without white + space). + + Some searches can be quite complex, and you may want to re-use them later, + perhaps with some tweaking. Recoll versions 1.21 and later can save and + restore searches, using XML files. See Saving and restoring queries. + + 3.1.1. Simple search + + 1. Start the recoll program. + + 2. Possibly choose a search mode: Any term, All terms, File name or Query + language. + + 3. Enter search term(s) in the text field at the top of the window. + + 4. Click the Search button or hit the Enter key to start the search. + + The initial default search mode is Query language. Without special + directives, this will look for documents containing all of the search + terms (the ones with more terms will get better scores), just like the All + terms mode which will ignore such directives. Any term will search for + documents where at least one of the terms appear. + + The Query Language features are described in a separate section. + + All search modes allow wildcards inside terms (*, ?, []). You may want to + have a look at the section about wildcards for more information about + this. + + File name will specifically look for file names. The point of having a + separate file name search is that wild card expansion can be performed + more efficiently on a small subset of the index (allowing wild cards on + the left of terms without excessive penality). Things to know: + + o White space in the entry should match white space in the file name, + and is not treated specially. + + o The search is insensitive to character case and accents, independantly + of the type of index. + + o An entry without any wild card character and not capitalized will be + prepended and appended with '*' (ie: etc -> *etc*, but Etc -> etc). + + o If you have a big index (many files), excessively generic fragments + may result in inefficient searches. + + You can search for exact phrases (adjacent words in a given order) by + enclosing the input inside double quotes. Ex: "virtual reality". + + When using a stripped index, character case has no influence on search, + except that you can disable stem expansion for any term by capitalizing + it. Ie: a search for floor will also normally look for flooring, floored, + etc., but a search for Floor will only look for floor, in any character + case. Stemming can also be disabled globally in the preferences. When + using a raw index, the rules are a bit more complicated. + + Recoll remembers the last few searches that you performed. You can use the + simple search text entry widget (a combobox) to recall them (click on the + thing at the right of the text field). Please note, however, that only the + search texts are remembered, not the mode (all/any/file name). + + Typing Esc Space while entering a word in the simple search entry will + open a window with possible completions for the word. The completions are + extracted from the database. + + Double-clicking on a word in the result list or a preview window will + insert it into the simple search entry field. + + You can cut and paste any text into an All terms or Any term search field, + punctuation, newlines and all - except for wildcard characters (single ? + characters are ok). Recoll will process it and produce a meaningful + search. This is what most differentiates this mode from the Query Language + mode, where you have to care about the syntax. + + You can use the Tools -> Advanced search dialog for more complex searches. + + 3.1.2. The default result list + + After starting a search, a list of results will instantly be displayed in + the main list window. + + By default, the document list is presented in order of relevance (how well + the system estimates that the document matches the query). You can sort + the result by ascending or descending date by using the vertical arrows in + the toolbar. + + Clicking on the Preview link for an entry will open an internal preview + window for the document. Further Preview clicks for the same search will + open tabs in the existing preview window. You can use Shift+Click to force + the creation of another preview window, which may be useful to view the + documents side by side. (You can also browse successive results in a + single preview window by typing Shift+ArrowUp/Down in the window). + + Clicking the Open link will start an external viewer for the document. By + default, Recoll lets the desktop choose the appropriate application for + most document types (there is a short list of exceptions, see further). If + you prefer to completely customize the choice of applications, you can + uncheck the Use desktop preferences option in the GUI preferences dialog, + and click the Choose editor applications button to adjust the predefined + Recoll choices. The tool accepts multiple selections of MIME types (e.g. + to set up the editor for the dozens of office file types). + + Even when Use desktop preferences is checked, there is a small list of + exceptions, for MIME types where the Recoll choice should override the + desktop one. These are applications which are well integrated with Recoll, + especially evince for viewing PDF and Postscript files because of its + support for opening the document at a specific page and passing a search + string as an argument. Of course, you can edit the list (in the GUI + preferences) if you would prefer to lose the functionality and use the + standard desktop tool. + + You may also change the choice of applications by editing the mimeview + configuration file if you find this more convenient. + + Each result entry also has a right-click menu with an Open With entry. + This lets you choose an application from the list of those which + registered with the desktop for the document MIME type. + + The Preview and Open edit links may not be present for all entries, + meaning that Recoll has no configured way to preview a given file type + (which was indexed by name only), or no configured external editor for the + file type. This can sometimes be adjusted simply by tweaking the mimemap + and mimeview configuration files (the latter can be modified with the user + preferences dialog). + + The format of the result list entries is entirely configurable by using + the preference dialog to edit an HTML fragment. + + You can click on the Query details link at the top of the results page to + see the query actually performed, after stem expansion and other + processing. + + Double-clicking on any word inside the result list or a preview window + will insert it into the simple search text. + + The result list is divided into pages (the size of which you can change in + the preferences). Use the arrow buttons in the toolbar or the links at the + bottom of the page to browse the results. + + 3.1.2.1. No results: the spelling suggestions + + When a search yields no result, and if the aspell dictionary is + configured, Recoll will try to check for misspellings among the query + terms, and will propose lists of replacements. Clicking on one of the + suggestions will replace the word and restart the search. You can hold any + of the modifier keys (Ctrl, Shift, etc.) while clicking if you would + rather stay on the suggestion screen because several terms need + replacement. + + 3.1.2.2. The result list right-click menu + + Apart from the preview and edit links, you can display a pop-up menu by + right-clicking over a paragraph in the result list. This menu has the + following entries: + + o Preview + + o Open + + o Open With + + o Run Script + + o Copy File Name + + o Copy Url + + o Save to File + + o Find similar + + o Preview Parent document + + o Open Parent document + + o Open Snippets Window + + The Preview and Open entries do the same thing as the corresponding links. + + Open With lets you open the document with one of the applications claiming + to be able to handle its MIME type (the information comes from the + .desktop files in /usr/share/applications). + + Run Script allows starting an arbitrary command on the result file. It + will only appear for results which are top-level files. See further for a + more detailed description. + + The Copy File Name and Copy Url copy the relevant data to the clipboard, + for later pasting. + + Save to File allows saving the contents of a result document to a chosen + file. This entry will only appear if the document does not correspond to + an existing file, but is a subdocument inside such a file (ie: an email + attachment). It is especially useful to extract attachments with no + associated editor. + + The Open/Preview Parent document entries allow working with the higher + level document (e.g. the email message an attachment comes from). Recoll + is sometimes not totally accurate as to what it can or can't do in this + area. For example the Parent entry will also appear for an email which is + part of an mbox folder file, but you can't actually visualize the mbox + (there will be an error dialog if you try). + + If the document is a top-level file, Open Parent will start the default + file manager on the enclosing filesystem directory. + + The Find similar entry will select a number of relevant term from the + current document and enter them into the simple search field. You can then + start a simple search, with a good chance of finding documents related to + the current result. I can't remember a single instance where this function + was actually useful to me... + + The Open Snippets Window entry will only appear for documents which + support page breaks (typically PDF, Postscript, DVI). The snippets window + lists extracts from the document, taken around search terms occurrences, + along with the corresponding page number, as links which can be used to + start the native viewer on the appropriate page. If the viewer supports + it, its search function will also be primed with one of the search terms. + + 3.1.3. The result table + + In Recoll 1.15 and newer, the results can be displayed in spreadsheet-like + fashion. You can switch to this presentation by clicking the table-like + icon in the toolbar (this is a toggle, click again to restore the list). + + Clicking on the column headers will allow sorting by the values in the + column. You can click again to invert the order, and use the header + right-click menu to reset sorting to the default relevance order (you can + also use the sort-by-date arrows to do this). + + Both the list and the table display the same underlying results. The sort + order set from the table is still active if you switch back to the list + mode. You can click twice on a date sort arrow to reset it from there. + + The header right-click menu allows adding or deleting columns. The columns + can be resized, and their order can be changed (by dragging). All the + changes are recorded when you quit recoll + + Hovering over a table row will update the detail area at the bottom of the + window with the corresponding values. You can click the row to freeze the + display. The bottom area is equivalent to a result list paragraph, with + links for starting a preview or a native application, and an equivalent + right-click menu. Typing Esc (the Escape key) will unfreeze the display. + + 3.1.4. Running arbitrary commands on result files (1.20 and later) + + Apart from the Open and Open With operations, which allow starting an + application on a result document (or a temporary copy), based on its MIME + type, it is also possible to run arbitrary commands on results which are + top-level files, using the Run Script entry in the results pop-up menu. + + The commands which will appear in the Run Script submenu must be defined + by .desktop files inside the scripts subdirectory of the current + configuration directory. + + Here follows an example of a .desktop file, which could be named for + example, ~/.recoll/scripts/myscript.desktop (the exact file name inside + the directory is irrelevant): + + [Desktop Entry] + Type=Application + Name=MyFirstScript + Exec=/home/me/bin/tryscript %F + MimeType=*/* + + + The Name attribute defines the label which will appear inside the Run + Script menu. The Exec attribute defines the program to be run, which does + not need to actually be a script, of course. The MimeType attribute is not + used, but needs to exist. + + The commands defined this way can also be used from links inside the + result paragraph. + + As an example, it might make sense to write a script which would move the + document to the trash and purge it from the Recoll index. + + 3.1.5. Displaying thumbnails + + The default format for the result list entries and the detail area of the + result table display an icon for each result document. The icon is either + a generic one determined from the MIME type, or a thumbnail of the + document appearance. Thumbnails are only displayed if found in the + standard freedesktop location, where they would typically have been + created by a file manager. + + Recoll has no capability to create thumbnails. A relatively simple trick + is to use the Open parent document/folder entry in the result list popup + menu. This should open a file manager window on the containing directory, + which should in turn create the thumbnails (depending on your settings). + Restarting the search should then display the thumbnails. + + There are also some pointers about thumbnail generation on the Recoll + wiki. + + 3.1.6. The preview window + + The preview window opens when you first click a Preview link inside the + result list. + + Subsequent preview requests for a given search open new tabs in the + existing window (except if you hold the Shift key while clicking which + will open a new window for side by side viewing). + + Starting another search and requesting a preview will create a new preview + window. The old one stays open until you close it. + + You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window. + Closing the last tab for a window will also close the window. + + Of course you can also close a preview window by using the window manager + button in the top of the frame. + + You can display successive or previous documents from the result list + inside a preview tab by typing Shift+Down or Shift+Up (Down and Up are the + arrow keys). + + A right-click menu in the text area allows switching between displaying + the main text or the contents of fields associated to the document (ie: + author, abtract, etc.). This is especially useful in cases where the term + match did not occur in the main text but in one of the fields. In the case + of images, you can switch between three displays: the image itself, the + image metadata as extracted by exiftool and the fields, which is the + metadata stored in the index. + + You can print the current preview window contents by typing Ctrl-P (Ctrl + + P) in the window text. + + 3.1.6.1. Searching inside the preview + + The preview window has an internal search capability, mostly controlled by + the panel at the bottom of the window, which works in two modes: as a + classical editor incremental search, where we look for the text entered in + the entry zone, or as a way to walk the matches between the document and + the Recoll query that found it. + + Incremental text search + + The preview tabs have an internal incremental search function. You + initiate the search either by typing a / (slash) or CTL-F inside + the text area or by clicking into the Search for: text field and + entering the search string. You can then use the Next and Previous + buttons to find the next/previous occurrence. You can also type F3 + inside the text area to get to the next occurrence. + + If you have a search string entered and you use Ctrl-Up/Ctrl-Down + to browse the results, the search is initiated for each successive + document. If the string is found, the cursor will be positioned at + the first occurrence of the search string. + + Walking the match lists + + If the entry area is empty when you click the Next or Previous + buttons, the editor will be scrolled to show the next match to any + search term (the next highlighted zone). If you select a search + group from the dropdown list and click Next or Previous, the match + list for this group will be walked. This is not the same as a text + search, because the occurences will include non-exact matches (as + caused by stemming or wildcards). The search will revert to the + text mode as soon as you edit the entry area. + + 3.1.7. The Query Fragments window + + Selecting the Tools -> Query Fragments menu entry will open a window with + radio- and check-buttons which can be used to activate query language + fragments for filtering the current query. This can be useful if you have + frequent reusable selectors, for example, filtering on alternate + directories, or searching just one category of files, not covered by the + standard category selectors. + + The contents of the window are entirely customizable, and defined by the + contents of the fragbuts.xml file inside the configuration directory. The + sample file distributed with Recoll (which you should be able to find + under /usr/share/recoll/examples/fragbuts.xml), contains an example which + filters the results from the WEB history. + + Here follows an example: + + + + + + + + + + + + + + + -rclbes:BGL + + + + + rclbes:BGL + + + + + + + + + date:2010-01-01/2010-12-31 + + + + + dir:/my/great/directory + + + + + + Each radiobuttons or buttons section defines a line of checkbuttons or + radiobuttons inside the window. Any number of buttons can be selected, but + the radiobuttons in a line are exclusive. + + Each fragbut section defines the label for a button, and the Query + Language fragment which will be added (as an AND filter) before performing + the query if the button is active. + + This feature is new in Recoll 1.20, and will probably be refined depending + on user feedback. + + 3.1.8. Complex/advanced search + + The advanced search dialog helps you build more complex queries without + memorizing the search language constructs. It can be opened through the + Tools menu or through the main toolbar. + + Recoll keeps a history of searches. See Advanced search history. + + The dialog has two tabs: + + 1. The first tab lets you specify terms to search for, and permits + specifying multiple clauses which are combined to build the search. + + 2. The second tab lets filter the results according to file size, date of + modification, MIME type, or location. + + Click on the Start Search button in the advanced search dialog, or type + Enter in any text field to start the search. The button in the main window + always performs a simple search. + + Click on the Show query details link at the top of the result page to see + the query expansion. + + 3.1.8.1. Avanced search: the "find" tab + + This part of the dialog lets you constructc a query by combining multiple + clauses of different types. Each entry field is configurable for the + following modes: + + o All terms. + + o Any term. + + o None of the terms. + + o Phrase (exact terms in order within an adjustable window). + + o Proximity (terms in any order within an adjustable window). + + o Filename search. + + Additional entry fields can be created by clicking the Add clause button. + + When searching, the non-empty clauses will be combined either with an AND + or an OR conjunction, depending on the choice made on the left (All + clauses or Any clause). + + Entries of all types except "Phrase" and "Near" accept a mix of single + words and phrases enclosed in double quotes. Stemming and wildcard + expansion will be performed as for simple search. + + Phrases and Proximity searches. These two clauses work in similar ways, + with the difference that proximity searches do not impose an order on the + words. In both cases, an adjustable number (slack) of non-matched words + may be accepted between the searched ones (use the counter on the left to + adjust this count). For phrases, the default count is zero (exact match). + For proximity it is ten (meaning that two search terms, would be matched + if found within a window of twelve words). Examples: a phrase search for + quick fox with a slack of 0 will match quick fox but not quick brown fox. + With a slack of 1 it will match the latter, but not fox quick. A proximity + search for quick fox with the default slack will match the latter, and + also a fox is a cunning and quick animal. + + 3.1.8.2. Avanced search: the "filter" tab + + This part of the dialog has several sections which allow filtering the + results of a search according to a number of criteria + + o The first section allows filtering by dates of last modification. You + can specify both a minimum and a maximum date. The initial values are + set according to the oldest and newest documents found in the index. + + o The next section allows filtering the results by file size. There are + two entries for minimum and maximum size. Enter decimal numbers. You + can use suffix multipliers: k/K, m/M, g/G, t/T for 1E3, 1E6, 1E9, 1E12 + respectively. + + o The next section allows filtering the results by their MIME types, or + MIME categories (ie: media/text/message/etc.). + + You can transfer the types between two boxes, to define which will be + included or excluded by the search. + + The state of the file type selection can be saved as the default (the + file type filter will not be activated at program start-up, but the + lists will be in the restored state). + + o The bottom section allows restricting the search results to a sub-tree + of the indexed area. You can use the Invert checkbox to search for + files not in the sub-tree instead. If you use directory filtering + often and on big subsets of the file system, you may think of setting + up multiple indexes instead, as the performance may be better. + + You can use relative/partial paths for filtering. Ie, entering + dirA/dirB would match either /dir1/dirA/dirB/myfile1 or + /dir2/dirA/dirB/someother/myfile2. + + 3.1.8.3. Avanced search history + + The advanced search tool memorizes the last 100 searches performed. You + can walk the saved searches by using the up and down arrow keys while the + keyboard focus belongs to the advanced search dialog. + + The complex search history can be erased, along with the one for simple + search, by selecting the File -> Erase Search History menu entry. + + 3.1.9. The term explorer tool + + Recoll automatically manages the expansion of search terms to their + derivatives (ie: plural/singular, verb inflections). But there are other + cases where the exact search term is not known. For example, you may not + remember the exact spelling, or only know the beginning of the name. + + The search will only propose replacement terms with spelling variations + when no matching document were found. In some cases, both proper spellings + and mispellings are present in the index, and it may be interesting to + look for them explicitely. + + The term explorer tool (started from the toolbar icon or from the Term + explorer entry of the Tools menu) can be used to search the full index + terms list. It has three modes of operations: + + Wildcard + + In this mode of operation, you can enter a search string with + shell-like wildcards (*, ?, []). ie: xapi* would display all index + terms beginning with xapi. (More about wildcards here). + + Regular expression + + This mode will accept a regular expression as input. Example: + word[0-9]+. The expression is implicitely anchored at the + beginning. Ie: press will match pression but not expression. You + can use .*press to match the latter, but be aware that this will + cause a full index term list scan, which can be quite long. + + Stem expansion + + This mode will perform the usual stem expansion normally done as + part user input processing. As such it is probably mostly useful + to demonstrate the process. + + Spelling/Phonetic + + In this mode, you enter the term as you think it is spelled, and + Recoll will do its best to find index terms that sound like your + entry. This mode uses the Aspell spelling application, which must + be installed on your system for things to work (if your documents + contain non-ascii characters, Recoll needs an aspell version newer + than 0.60 for UTF-8 support). The language which is used to build + the dictionary out of the index terms (which is done at the end of + an indexing pass) is the one defined by your NLS environment. + Weird things will probably happen if languages are mixed up. + + Note that in cases where Recoll does not know the beginning of the string + to search for (ie a wildcard expression like *coll), the expansion can + take quite a long time because the full index term list will have to be + processed. The expansion is currently limited at 10000 results for + wildcards and regular expressions. It is possible to change the limit in + the configuration file. + + Double-clicking on a term in the result list will insert it into the + simple search entry field. You can also cut/paste between the result list + and any entry field (the end of lines will be taken care of). + + 3.1.10. Multiple indexes + + See the section describing the use of multiple indexes for generalities. + Only the aspects concerning the recoll GUI are described here. + + A recoll program instance is always associated with a specific index, + which is the one to be updated when requested from the File menu, but it + can use any number of Recoll indexes for searching. The external indexes + can be selected through the external indexes tab in the preferences + dialog. + + Index selection is performed in two phases. A set of all usable indexes + must first be defined, and then the subset of indexes to be used for + searching. These parameters are retained across program executions (there + are kept separately for each Recoll configuration). The set of all indexes + is usually quite stable, while the active ones might typically be adjusted + quite frequently. + + The main index (defined by RECOLL_CONFDIR) is always active. If this is + undesirable, you can set up your base configuration to index an empty + directory. + + When adding a new index to the set, you can select either a Recoll + configuration directory, or directly a Xapian index directory. In the + first case, the Xapian index directory will be obtained from the selected + configuration. + + As building the set of all indexes can be a little tedious when done + through the user interface, you can use the RECOLL_EXTRA_DBS environment + variable to provide an initial set. This might typically be set up by a + system administrator so that every user does not have to do it. The + variable should define a colon-separated list of index directories, ie: + + export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db + + Another environment variable, RECOLL_ACTIVE_EXTRA_DBS allows adding to the + active list of indexes. This variable was suggested and implemented by a + Recoll user. It is mostly useful if you use scripts to mount external + volumes with Recoll indexes. By using RECOLL_EXTRA_DBS and + RECOLL_ACTIVE_EXTRA_DBS, you can add and activate the index for the + mounted volume when starting recoll. + + RECOLL_ACTIVE_EXTRA_DBS is available for Recoll versions 1.17.2 and later. + A change was made in the same update so that recoll will automatically + deactivate unreachable indexes when starting up. + + 3.1.11. Document history + + Documents that you actually view (with the internal preview or an external + tool) are entered into the document history, which is remembered. + + You can display the history list by using the Tools/Doc History menu + entry. + + You can erase the document history by using the Erase document history + entry in the File menu. + + 3.1.12. Sorting search results and collapsing duplicates + + The documents in a result list are normally sorted in order of relevance. + It is possible to specify a different sort order, either by using the + vertical arrows in the GUI toolbox to sort by date, or switching to the + result table display and clicking on any header. The sort order chosen + inside the result table remains active if you switch back to the result + list, until you click one of the vertical arrows, until both are unchecked + (you are back to sort by relevance). + + Sort parameters are remembered between program invocations, but result + sorting is normally always inactive when the program starts. It is + possible to keep the sorting activation state between program invocations + by checking the Remember sort activation state option in the preferences. + + It is also possible to hide duplicate entries inside the result list + (documents with the exact same contents as the displayed one). The test of + identity is based on an MD5 hash of the document container, not only of + the text contents (so that ie, a text document with an image added will + not be a duplicate of the text only). Duplicates hiding is controlled by + an entry in the GUI configuration dialog, and is off by default. + + As of release 1.19, when a result document does have undisplayed + duplicates, a Dups link will be shown with the result list entry. Clicking + the link will display the paths (URLs + ipaths) for the duplicate entries. + + 3.1.13. Search tips, shortcuts + + 3.1.13.1. Terms and search expansion + + Term completion. Typing Esc Space in the simple search entry field while + entering a word will either complete the current word if its beginning + matches a unique term in the index, or open a window to propose a list of + completions. + + Picking up new terms from result or preview text. Double-clicking on a + word in the result list or in a preview window will copy it to the simple + search entry field. + + Wildcards. Wildcards can be used inside search terms in all forms of + searches. More about wildcards. + + Automatic suffixes. Words like odt or ods can be automatically turned into + query language ext:xxx clauses. This can be enabled in the Search + preferences panel in the GUI. + + Disabling stem expansion. Entering a capitalized word in any search field + will prevent stem expansion (no search for gardening if you enter Garden + instead of garden). This is the only case where character case should make + a difference for a Recoll search. You can also disable stem expansion or + change the stemming language in the preferences. + + Finding related documents. Selecting the Find similar documents entry in + the result list paragraph right-click menu will select a set of + "interesting" terms from the current result, and insert them into the + simple search entry field. You can then possibly edit the list and start a + search to find documents which may be apparented to the current result. + + File names. File names are added as terms during indexing, and you can + specify them as ordinary terms in normal search fields (Recoll used to + index all directories in the file path as terms. This has been abandoned + as it did not seem really useful). Alternatively, you can use the specific + file name search which will only look for file names, and may be faster + than the generic search especially when using wildcards. + + 3.1.13.2. Working with phrases and proximity + + Phrases and Proximity searches. A phrase can be looked for by enclosing it + in double quotes. Example: "user manual" will look only for occurrences of + user immediately followed by manual. You can use the This phrase field of + the advanced search dialog to the same effect. Phrases can be entered + along simple terms in all simple or advanced search entry fields (except + This exact phrase). + + AutoPhrases. This option can be set in the preferences dialog. If it is + set, a phrase will be automatically built and added to simple searches + when looking for Any terms. This will not change radically the results, + but will give a relevance boost to the results where the search terms + appear as a phrase. Ie: searching for virtual reality will still find all + documents where either virtual or reality or both appear, but those which + contain virtual reality should appear sooner in the list. + + Phrase searches can strongly slow down a query if most of the terms in the + phrase are common. This is why the autophrase option is off by default for + Recoll versions before 1.17. As of version 1.17, autophrase is on by + default, but very common terms will be removed from the constructed + phrase. The removal threshold can be adjusted from the search preferences. + + Phrases and abbreviations. As of Recoll version 1.17, dotted abbreviations + like I.B.M. are also automatically indexed as a word without the dots: + IBM. Searching for the word inside a phrase (ie: "the IBM company") will + only match the dotted abrreviation if you increase the phrase slack (using + the advanced search panel control, or the o query language modifier). + Literal occurences of the word will be matched normally. + + 3.1.13.3. Others + + Using fields. You can use the query language and field specifications to + only search certain parts of documents. This can be especially helpful + with email, for example only searching emails from a specific originator: + search tips from:helpfulgui + + Ajusting the result table columns. When displaying results in table mode, + you can use a right click on the table headers to activate a pop-up menu + which will let you adjust what columns are displayed. You can drag the + column headers to adjust their order. You can click them to sort by the + field displayed in the column. You can also save the result list in CSV + format. + + Changing the GUI geometry. It is possible to configure the GUI in wide + form factor by dragging the toolbars to one of the sides (their location + is remembered between sessions), and moving the category filters to a menu + (can be set in the Preferences -> GUI configuration -> User interface + panel). + + Query explanation. You can get an exact description of what the query + looked for, including stem expansion, and Boolean operators used, by + clicking on the result list header. + + Advanced search history. As of Recoll 1.18, you can display any of the + last 100 complex searches performed by using the up and down arrow keys + while the advanced search panel is active. + + Browsing the result list inside a preview window. Entering Shift-Down or + Shift-Up (Shift + an arrow key) in a preview window will display the next + or the previous document from the result list. Any secondary search + currently active will be executed on the new document. + + Scrolling the result list from the keyboard. You can use PageUp and + PageDown to scroll the result list, Shift+Home to go back to the first + page. These work even while the focus is in the search entry. + + Result table: moving the focus to the table. You can use Ctrl-r to move + the focus from the search entry to the table, and then use the arrow keys + to change the current row. Ctrl-Shift-s returns to the search. + + Result table: open / preview. With the focus in the result table, you can + use Ctrl-o to open the document from the current row, Ctrl-Shift-o to open + the document and close recoll, Ctrl-d to preview the document. + + Editing a new search while the focus is not in the search entry. You can + use the Ctrl-Shift-S shortcut to return the cursor to the search entry + (and select the current search text), while the focus is anywhere in the + main window. + + Forced opening of a preview window. You can use Shift+Click on a result + list Preview link to force the creation of a preview window instead of a + new tab in the existing one. + + Closing previews. Entering Ctrl-W in a tab will close it (and, for the + last tab, close the preview window). Entering Esc will close the preview + window and all its tabs. + + Printing previews. Entering Ctrl-P in a preview window will print the + currently displayed text. + + Quitting. Entering Ctrl-Q almost anywhere will close the application. + + 3.1.14. Saving and restoring queries (1.21 and later) + + Both simple and advanced query dialogs save recent history, but the amount + is limited: old queries will eventually be forgotten. Also, important + queries may be difficult to find among others. This is why both types of + queries can also be explicitely saved to files, from the GUI menus: File + -> Save last query / Load last query + + The default location for saved queries is a subdirectory of the current + configuration directory, but saved queries are ordinary files and can be + written or moved anywhere. + + Some of the saved query parameters are part of the preferences (e.g. + autophrase or the active external indexes), and may differ when the query + is loaded from the time it was saved. In this case, Recoll will warn of + the differences, but will not change the user preferences. + + 3.1.15. Customizing the search interface + + You can customize some aspects of the search interface by using the GUI + configuration entry in the Preferences menu. + + There are several tabs in the dialog, dealing with the interface itself, + the parameters used for searching and returning results, and what indexes + are searched. + + User interface parameters: + + o Highlight color for query terms: Terms from the user query are + highlighted in the result list samples and the preview window. The + color can be chosen here. Any Qt color string should work (ie red, + #ff0000). The default is blue. + + o Style sheet: The name of a Qt style sheet text file which is applied + to the whole Recoll application on startup. The default value is + empty, but there is a skeleton style sheet (recoll.qss) inside the + /usr/share/recoll/examples directory. Using a style sheet, you can + change most recoll graphical parameters: colors, fonts, etc. See the + sample file for a few simple examples. + + You should be aware that parameters (e.g.: the background color) set + inside the Recoll GUI style sheet will override global system + preferences, with possible strange side effects: for example if you + set the foreground to a light color and the background to a dark one + in the desktop preferences, but only the background is set inside the + Recoll style sheet, and it is light too, then text will appear + light-on-light inside the Recoll GUI. + + o Maximum text size highlighted for preview Inserting highlights on + search term inside the text before inserting it in the preview window + involves quite a lot of processing, and can be disabled over the given + text size to speed up loading. + + o Prefer HTML to plain text for preview if set, Recoll will display HTML + as such inside the preview window. If this causes problems with the Qt + HTML display, you can uncheck it to display the plain text version + instead. + + o Plain text to HTML line style: when displaying plain text inside the + preview window, Recoll tries to preserve some of the original text + line breaks and indentation. It can either use PRE HTML tags, which + will well preserve the indentation but will force horizontal scrolling + for long lines, or use BR tags to break at the original line breaks, + which will let the editor introduce other line breaks according to the + window width, but will lose some of the original indentation. The + third option has been available in recent releases and is probably now + the best one: use PRE tags with line wrapping. + + o Choose editor applicationsr: this opens a dialog which allows you to + select the application to be used to open each MIME type. The default + is nornally to use the xdg-open utility, but you can override it. + + o Exceptions: even wen xdg-open is used by default for opening + documents, you can set exceptions for MIME types that will still be + opened according to Recoll preferences. This is useful for passing + parameters like page numbers or search strings to applications that + support them (e.g. evince). This cannot be done with xdg-open which + only supports passing one parameter. + + o Document filter choice style: this will let you choose if the document + categories are displayed as a list or a set of buttons, or a menu. + + o Start with simple search mode: this lets you choose the value of the + simple search type on program startup. Either a fixed value (e.g. + Query Language, or the value in use when the program last exited. + + o Auto-start simple search on white space entry: if this is checked, a + search will be executed each time you enter a space in the simple + search input field. This lets you look at the result list as you enter + new terms. This is off by default, you may like it or not... + + o Start with advanced search dialog open : If you use this dialog + frequently, checking the entries will get it to open when recoll + starts. + + o Remember sort activation state if set, Recoll will remember the sort + tool stat between invocations. It normally starts with sorting + disabled. + + Result list parameters: + + o Number of results in a result page + + o Result list font: There is quite a lot of information shown in the + result list, and you may want to customize the font and/or font size. + The rest of the fonts used by Recoll are determined by your generic Qt + config (try the qtconfig command). + + o Edit result list paragraph format string: allows you to change the + presentation of each result list entry. See the result list + customisation section. + + o Edit result page HTML header insert: allows you to define text + inserted at the end of the result page HTML header. More detail in the + result list customisation section. + + o Date format: allows specifying the format used for displaying dates + inside the result list. This should be specified as an strftime() + string (man strftime). + + o Abstract snippet separator: for synthetic abstracts built from index + data, which are usually made of several snippets from different parts + of the document, this defines the snippet separator, an ellipsis by + default. + + Search parameters: + + o Hide duplicate results: decides if result list entries are shown for + identical documents found in different places. + + o Stemming language: stemming obviously depends on the document's + language. This listbox will let you chose among the stemming databases + which were built during indexing (this is set in the main + configuration file), or later added with recollindex -s (See the + recollindex manual). Stemming languages which are dynamically added + will be deleted at the next indexing pass unless they are also added + in the configuration file. + + o Automatically add phrase to simple searches: a phrase will be + automatically built and added to simple searches when looking for Any + terms. This will give a relevance boost to the results where the + search terms appear as a phrase (consecutive and in order). + + o Autophrase term frequency threshold percentage: very frequent terms + should not be included in automatic phrase searches for performance + reasons. The parameter defines the cutoff percentage (percentage of + the documents where the term appears). + + o Replace abstracts from documents: this decides if we should synthesize + and display an abstract in place of an explicit abstract found within + the document itself. + + o Dynamically build abstracts: this decides if Recoll tries to build + document abstracts (lists of snippets) when displaying the result + list. Abstracts are constructed by taking context from the document + information, around the search terms. + + o Synthetic abstract size: adjust to taste... + + o Synthetic abstract context words: how many words should be displayed + around each term occurrence. + + o Query language magic file name suffixes: a list of words which + automatically get turned into ext:xxx file name suffix clauses when + starting a query language query (ie: doc xls xlsx...). This will save + some typing for people who use file types a lot when querying. + + External indexes: This panel will let you browse for additional indexes + that you may want to search. External indexes are designated by their + database directory (ie: /home/someothergui/.recoll/xapiandb, + /usr/local/recollglobal/xapiandb). + + Once entered, the indexes will appear in the External indexes list, and + you can chose which ones you want to use at any moment by checking or + unchecking their entries. + + Your main database (the one the current configuration indexes to), is + always implicitly active. If this is not desirable, you can set up your + configuration so that it indexes, for example, an empty directory. An + alternative indexer may also need to implement a way of purging the index + from stale data, + + 3.1.15.1. The result list format + + Newer versions of Recoll (from 1.17) normally use WebKit HTML widgets for + the result list and the snippets window (this may be disabled at build + time). Total customisation is possible with full support for CSS and + Javascript. Conversely, there are limits to what you can do with the older + Qt QTextBrowser, but still, it is possible to decide what data each result + will contain, and how it will be displayed. + + The result list presentation can be exhaustively customized by adjusting + two elements: + + o The paragraph format + + o HTML code inside the header section. For versions 1.21 and later, this + is also used for the snippets window + + The paragraph format and the header fragment can be edited from the Result + list tab of the GUI configuration. + + The header fragment is used both for the result list and the snippets + window. The snippets list is a table and has a snippets class attribute. + Each paragraph in the result list is a table, with class respar, but this + can be changed by editing the paragraph format. + + There are a few examples on the page about customising the result list on + the Recoll web site. + + The paragraph format + + This is an arbitrary HTML string where the following printf-like % + substitutions will be performed: + + o %A. Abstract + + o %D. Date + + o %I. Icon image name. This is normally determined from the MIME type. + The associations are defined inside the mimeconf configuration file. + If a thumbnail for the file is found at the standard Freedesktop + location, this will be displayed instead. + + o %K. Keywords (if any) + + o %L. Precooked Preview, Edit, and possibly Snippets links + + o %M. MIME type + + o %N. result Number inside the result page + + o %P. Parent folder Url. In the case of an embedded document, this is + the parent folder for the top level container file. + + o %R. Relevance percentage + + o %S. Size information + + o %T. Title or Filename if not set. + + o %t. Title or Filename if not set. + + o %U. Url + + The format of the Preview, Edit, and Snippets links is , and where docnum (%N) expands to the document + number inside the result page). + + A link target defined as "F%N" will open the document corresponding to the + %P parent folder expansion, usually creating a file manager window on the + folder where the container file resides. E.g.: + + %P + + A link target defined as R%N|scriptname will run the corresponding script + on the result file (if the document is embedded, the script will be + started on the top-level parent). See the section about defining scripts. + + In addition to the predefined values above, all strings like %(fieldname) + will be replaced by the value of the field named fieldname for this + document. Only stored fields can be accessed in this way, the value of + indexed but not stored fields is not known at this point in the search + process (see field configuration). There are currently very few fields + stored by default, apart from the values above (only author and filename), + so this feature will need some custom local configuration to be useful. An + example candidate would be the recipient field which is generated by the + message input handlers. + + The default value for the paragraph format string is: + + "\n" + "\n" + "\n" + "\n" + "
%L  %S   %T
\n" + "%M %D    %U %i
\n" + "%A %K
\n" + + You may, for example, try the following for a more web-like experience: + + %T
+ %A%U - %S - %L + + Note that the P%N link in the above paragraph makes the title a preview + link. Or the clean looking: + + %L %R +   %T&
%S  + %U + + +
%A
%K + + These samples, and some others are on the web site, with pictures to show + how they look. + + It is also possible to define the value of the snippet separator inside + the abstract section. + +3.2. Searching with the KDE KIO slave + + 3.2.1. What's this + + The Recoll KIO slave allows performing a Recoll search by entering an + appropriate URL in a KDE open dialog, or with an HTML-based interface + displayed in Konqueror. + + The HTML-based interface is similar to the Qt-based interface, but + slightly less powerful for now. Its advantage is that you can perform your + search while staying fully within the KDE framework: drag and drop from + the result list works normally and you have your normal choice of + applications for opening files. + + The alternative interface uses a directory view of search results. Due to + limitations in the current KIO slave interface, it is currently not + obviously useful (to me). + + The interface is described in more detail inside a help file which you can + access by entering recoll:/ inside the konqueror URL line (this works only + if the recoll KIO slave has been previously installed). + + The instructions for building this module are located in the source tree. + See: kde/kio/recoll/00README.txt. Some Linux distributions do package the + kio-recoll module, so check before diving into the build process, maybe + it's already out there ready for one-click installation. + + 3.2.2. Searchable documents + + As a sample application, the Recoll KIO slave could allow preparing a set + of HTML documents (for example a manual) so that they become their own + search interface inside konqueror. + + This can be done by either explicitly inserting + links around some document areas, or automatically by adding a very small + javascript program to the documents, like the following example, which + would initiate a search by double-clicking any term: + + + .... + + + +3.3. Searching on the command line + + There are several ways to obtain search results as a text stream, without + a graphical interface: + + o By passing option -t to the recoll program. + + o By using the recollq program. + + o By writing a custom Python program, using the Recoll Python API. + + The first two methods work in the same way and accept/need the same + arguments (except for the additional -t to recoll). The query to be + executed is specified as command line arguments. + + recollq is not built by default. You can use the Makefile in the query + directory to build it. This is a very simple program, and if you can + program a little c++, you may find it useful to taylor its output format + to your needs. Not that recollq is only really useful on systems where the + Qt libraries (or even the X11 ones) are not available. Otherwise, just use + recoll -t, which takes the exact same parameters and options which are + described for recollq + + recollq has a man page (not installed by default, look in the doc/man + directory). The Usage string is as follows: + + recollq: usage: + -P: Show the date span for all the documents present in the index + [-o|-a|-f] [-q] + Runs a recoll query and displays result lines. + Default: will interpret the argument(s) as a xesam query string + query may be like: + implicit AND, Exclusion, field spec: t1 -t2 title:t3 + OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4) + Phrase: "t1 t2" (needs additional quoting on cmd line) + -o Emulate the GUI simple search in ANY TERM mode + -a Emulate the GUI simple search in ALL TERMS mode + -f Emulate the GUI simple search in filename mode + -q is just ignored (compatibility with the recoll GUI command line) + Common options: + -c : specify config directory, overriding $RECOLL_CONFDIR + -d also dump file contents + -n [first-] define the result slice. The default value for [first] + is 0. Without the option, the default max count is 2000. + Use n=0 for no limit + -b : basic. Just output urls, no mime types or titles + -Q : no result lines, just the processed query and result count + -m : dump the whole document meta[] array for each result + -A : output the document abstracts + -S fld : sort by field + -s stemlang : set stemming language to use (must exist in index...) + Use -s "" to turn off stem expansion + -D : sort descending + -i : additional index, several can be given + -e use url encoding (%xx) for urls + -F : output exactly these fields for each result. + The field values are encoded in base64, output in one line and + separated by one space character. This is the recommended format + for use by other programs. Use a normal query with option -m to + see the field names. + + Sample execution: + + recollq 'ilur -nautique mime:text/html' + Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11) + OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html)) + 4 results + text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html] [comptes.html] 18593 bytes + text/html [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio... + text/html [file:///Users/uncrypted-dockes/projets/pagepers/index.html] [psxtcl/writemime/recoll]... + text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree.... + +3.4. Path translations + + In some cases, the document paths stored inside the index do not match the + actual ones, so that document previews and accesses will fail. This can + occur in a number of circumstances: + + o When using multiple indexes it is a relatively common occurrence that + some will actually reside on a remote volume, for exemple mounted via + NFS. In this case, the paths used to access the documents on the local + machine are not necessarily the same than the ones used while indexing + on the remote machine. For example, /home/me may have been used as a + topdirs elements while indexing, but the directory might be mounted as + /net/server/home/me on the local machine. + + o The case may also occur with removable disks. It is perfectly possible + to configure an index to live with the documents on the removable + disk, but it may happen that the disk is not mounted at the same place + so that the documents paths from the index are invalid. + + o As a last exemple, one could imagine that a big directory has been + moved, but that it is currently inconvenient to run the indexer. + + More generally, the path translation facility may be useful whenever the + documents paths seen by the indexer are not the same as the ones which + should be used at query time. + + Recoll has a facility for rewriting access paths when extracting the data + from the index. The translations can be defined for the main index and for + any additional query index. + + In the above NFS example, Recoll could be instructed to rewrite any + file:///home/me URL from the index to file:///net/server/home/me, allowing + accesses from the client. + + The translations are defined in the ptrans configuration file, which can + be edited by hand or from the GUI external indexes configuration dialog. + +3.5. The query language + + The query language processor is activated in the GUI simple search entry + when the search mode selector is set to Query Language. It can also be + used with the KIO slave or the command line search. It broadly has the + same capabilities as the complex search interface in the GUI. + + The language is based on the (seemingly defunct) Xesam user search + language specification. + + If the results of a query language search puzzle you and you doubt what + has been actually searched for, you can use the GUI Show Query link at the + top of the result list to check the exact query which was finally executed + by Xapian. + + Here follows a sample request that we are going to explain: + + author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes + + + This would search for all documents with John Doe appearing as a phrase in + the author field (exactly what this is would depend on the document type, + ie: the From: header, for an email message), and containing either beatles + or lennon and either live or unplugged but not potatoes (in any part of + the document). + + An element is composed of an optional field specification, and a value, + separated by a colon (the field separator is the last colon in the + element). Examples: Eugenie, author:balzac, dc:title:grandet + dc:title:"eugenie grandet" + + The colon, if present, means "contains". Xesam defines other relations, + which are mostly unsupported for now (except in special cases, described + further down). + + All elements in the search entry are normally combined with an implicit + AND. It is possible to specify that elements be OR'ed instead, as in + Beatles OR Lennon. The OR must be entered literally (capitals), and it has + priority over the AND associations: word1 word2 OR word3 means word1 AND + (word2 OR word3) not (word1 AND word2) OR word3. Explicit parenthesis are + not supported. + + As of Recoll 1.21, you can use parentheses to group elements, which will + sometimes make things clearer, and may allow expressing combinations which + would have been difficult otherwise. + + An element preceded by a - specifies a term that should not appear. + + As usual, words inside quotes define a phrase (the order of words is + significant), so that title:"prejudice pride" is not the same as + title:prejudice title:pride, and is unlikely to find a result. + + Words inside phrases and capitalized words are not stem-expanded. + Wildcards may be used anywhere inside a term. Specifying a wild-card on + the left of a term can produce a very slow search (or even an incorrect + one if the expansion is truncated because of excessive size). Also see + More about wildcards. + + To save you some typing, recent Recoll versions (1.20 and later) interpret + a comma-separated list of terms as an AND list inside the field. Use slash + characters ('/') for an OR list. No white space is allowed. So + + author:john,lennon + + will search for documents with john and lennon inside the author field (in + any order), and + + author:john/ringo + + would search for john or ringo. + + Modifiers can be set on a double-quote value, for example to specify a + proximity search (unordered). See the modifier section. No space must + separate the final double-quote and the modifiers value, e.g. "two + one"po10 + + Recoll currently manages the following default fields: + + o title, subject or caption are synonyms which specify data to be + searched for in the document title or subject. + + o author or from for searching the documents originators. + + o recipient or to for searching the documents recipients. + + o keyword for searching the document-specified keywords (few documents + actually have any). + + o filename for the document's file name. This is not necessarily set for + all documents: internal documents contained inside a compound one (for + example an EPUB section) do not inherit the container file name any + more, this was replaced by an explicit field (see next). Sub-documents + can still have a specific filename, if it is implied by the document + format, for example the attachment file name for an email attachment. + + o containerfilename. This is set for all documents, both top-level and + contained sub-documents, and is always the name of the filesystem + directory entry which contains the data. The terms from this field can + only be matched by an explicit field specification (as opposed to + terms from filename which are also indexed as general document + content). This avoids getting matches for all the sub-documents when + searching for the container file name. + + o ext specifies the file name extension (Ex: ext:html) + + Recoll 1.20 and later have a way to specify aliases for the field names, + which will save typing, for example by aliasing filename to fn or + containerfilename to cfn. See the section about the fields file + + The field syntax also supports a few field-like, but special, criteria: + + o dir for filtering the results on file location (Ex: + dir:/home/me/somedir). -dir also works to find results not in the + specified directory (release >= 1.15.8). Tilde expansion will be + performed as usual (except for a bug in versions 1.19 to 1.19.11p1). + Wildcards will be expanded, but please have a look at an important + limitation of wildcards in path filters. + + Relative paths also make sense, for example, dir:share/doc would match + either /usr/share/doc or /usr/local/share/doc + + Several dir clauses can be specified, both positive and negative. For + example the following makes sense: + + dir:recoll dir:src -dir:utils -dir:common + + + This would select results which have both recoll and src in the path + (in any order), and which have not either utils or common. + + You can also use OR conjunctions with dir: clauses. + + A special aspect of dir clauses is that the values in the index are + not transcoded to UTF-8, and never lower-cased or unaccented, but + stored as binary. This means that you need to enter the values in the + exact lower or upper case, and that searches for names with diacritics + may sometimes be impossible because of character set conversion + issues. Non-ASCII UNIX file paths are an unending source of trouble + and are best avoided. + + You need to use double-quotes around the path value if it contains + space characters. + + o size for filtering the results on file size. Example: size<10000. You + can use <, > or = as operators. You can specify a range like the + following: size>100 size<1000. The usual k/K, m/M, g/G, t/T can be + used as (decimal) multipliers. Ex: size>1k to search for files bigger + than 1000 bytes. + + o date for searching or filtering on dates. The syntax for the argument + is based on the ISO8601 standard for dates and time intervals. Only + dates are supported, no times. The general syntax is 2 elements + separated by a / character. Each element can be a date or a period of + time. Periods are specified as PnYnMnD. The n numbers are the + respective numbers of years, months or days, any of which may be + missing. Dates are specified as YYYY-MM-DD. The days and months parts + may be missing. If the / is present but an element is missing, the + missing element is interpreted as the lowest or highest date in the + index. Examples: + + o 2001-03-01/2002-05-01 the basic syntax for an interval of dates. + + o 2001-03-01/P1Y2M the same specified with a period. + + o 2001/ from the beginning of 2001 to the latest date in the index. + + o 2001 the whole year of 2001 + + o P2D/ means 2 days ago up to now if there are no documents with + dates in the future. + + o /2003 all documents from 2003 or older. + + Periods can also be specified with small letters (ie: p2y). + + o mime or format for specifying the MIME type. This one is quite special + because you can specify several values which will be OR'ed (the normal + default for the language is AND). Ex: mime:text/plain mime:text/html. + Specifying an explicit boolean operator before a mime specification is + not supported and will produce strange results. You can filter out + certain types by using negation (-mime:some/type), and you can use + wildcards in the value (mime:text/*). Note that mime is the ONLY field + with an OR default. You do need to use OR with ext terms for example. + + o type or rclcat for specifying the category (as in + text/media/presentation/etc.). The classification of MIME types in + categories is defined in the Recoll configuration (mimeconf), and can + be modified or extended. The default category names are those which + permit filtering results in the main GUI screen. Categories are OR'ed + like MIME types above. This can't be negated with - either. + + The document input handlers used while indexing have the possibility to + create other fields with arbitrary names, and aliases may be defined in + the configuration, so that the exact field search possibilities may be + different for you if someone took care of the customisation. + + 3.5.1. Modifiers + + Some characters are recognized as search modifiers when found immediately + after the closing double quote of a phrase, as in "some + term"modifierchars. The actual "phrase" can be a single term of course. + Supported modifiers: + + o l can be used to turn off stemming (mostly makes sense with p because + stemming is off by default for phrases). + + o o can be used to specify a "slack" for phrase and proximity searches: + the number of additional terms that may be found between the specified + ones. If o is followed by an integer number, this is the slack, else + the default is 10. + + o p can be used to turn the default phrase search into a proximity one + (unordered). Example:"order any in"p + + o C will turn on case sensitivity (if the index supports it). + + o D will turn on diacritics sensitivity (if the index supports it). + + o A weight can be specified for a query element by specifying a decimal + value at the start of the modifiers. Example: "Important"2.5. + +3.6. Search case and diacritics sensitivity + + For Recoll versions 1.18 and later, and when working with a raw index (not + the default), searches can be made sensitive to character case and + diacritics. How this happens is controlled by configuration variables and + what search data is entered. + + The general default is that searches are insensitive to case and + diacritics. An entry of resume will match any of Resume, RESUME, resume, + Resume etc. + + Two configuration variables can automate switching on sensitivity: + + autodiacsens + + If this is set, search sensitivity to diacritics will be turned on + as soon as an accented character exists in a search term. When the + variable is set to true, resume will start a + diacritics-unsensitive search, but resume will be matched exactly. + The default value is false. + + autocasesens + + If this is set, search sensitivity to character case will be + turned on as soon as an upper-case character exists in a search + term except for the first one. When the variable is set to true, + us or Us will start a diacritics-unsensitive search, but US will + be matched exactly. The default value is true (contrary to + autodiacsens). + + As in the past, capitalizing the first letter of a word will turn off its + stem expansion and have no effect on case-sensitivity. + + You can also explicitely activate case and diacritics sensitivity by using + modifiers with the query language. C will make the term case-sensitive, + and D will make it diacritics-sensitive. Examples: + + "us"C + + + will search for the term us exactly (Us will not be a match). + + "resume"D + + + will search for the term resume exactly (resume will not be a match). + + When either case or diacritics sensitivity is activated, stem expansion is + turned off. Having both does not make much sense. + +3.7. Anchored searches and wildcards + + Some special characters are interpreted by Recoll in search strings to + expand or specialize the search. Wildcards expand a root term in + controlled ways. Anchor characters can restrict a search to succeed only + if the match is found at or near the beginning of the document or one of + its fields. + + 3.7.1. More about wildcards + + All words entered in Recoll search fields will be processed for wildcard + expansion before the request is finally executed. + + The wildcard characters are: + + o * which matches 0 or more characters. + + o ? which matches a single character. + + o [] which allow defining sets of characters to be matched (ex: [abc] + matches a single character which may be 'a' or 'b' or 'c', [0-9] + matches any number. + + You should be aware of a few things when using wildcards. + + o Using a wildcard character at the beginning of a word can make for a + slow search because Recoll will have to scan the whole index term list + to find the matches. However, this is much less a problem for field + searches, and queries like author:*@domain.com can sometimes be very + useful. + + o For Recoll version 18 only, when working with a raw index (preserving + character case and diacritics), the literal part of a wildcard + expression will be matched exactly for case and diacritics. This is + not true any more for versions 19 and later. + + o Using a * at the end of a word can produce more matches than you would + think, and strange search results. You can use the term explorer tool + to check what completions exist for a given term. You can also see + exactly what search was performed by clicking on the link at the top + of the result list. In general, for natural language terms, stem + expansion will produce better results than an ending * (stem expansion + is turned off when any wildcard character appears in the term). + + 3.7.1.1. Wildcards and path filtering + + Due to the way that Recoll processes wildcards inside dir path filtering + clauses, they will have a multiplicative effect on the query size. A + clause containg wildcards in several paths elements, like, for example, + dir:/home/me/*/*/docdir, will almost certainly fail if your indexed tree + is of any realistic size. + + Depending on the case, you may be able to work around the issue by + specifying the paths elements more narrowly, with a constant prefix, or by + using 2 separate dir: clauses instead of multiple wildcards, as in + dir:/home/me dir:docdir. The latter query is not equivalent to the initial + one because it does not specify a number of directory levels, but that's + the best we can do (and it may be actually more useful in some cases). + + 3.7.2. Anchored searches + + Two characters are used to specify that a search hit should occur at the + beginning or at the end of the text. ^ at the beginning of a term or + phrase constrains the search to happen at the start, $ at the end force it + to happen at the end. + + As this function is implemented as a phrase search it is possible to + specify a maximum distance at which the hit should occur, either through + the controls of the advanced search panel, or using the query language, + for example, as in: + + "^someterm"o10 + + which would force someterm to be found within 10 terms of the start of the + text. This can be combined with a field search as in + somefield:"^someterm"o10 or somefield:someterm$. + + This feature can also be used with an actual phrase search, but in this + case, the distance applies to the whole phrase and anchor, so that, for + example, bla bla my unexpected term at the beginning of the text would be + a match for "^my term"o5. + + Anchored searches can be very useful for searches inside somewhat + structured documents like scientific articles, in case explicit metadata + has not been supplied (a most frequent case), for example for looking for + matches inside the abstract or the list of authors (which occur at the top + of the document). + +3.8. Desktop integration + + Being independant of the desktop type has its drawbacks: Recoll desktop + integration is minimal. However there are a few tools available: + + o The KDE KIO Slave was described in a previous section. + + o If you use a recent version of Ubuntu Linux, you may find the Ubuntu + Unity Lens module useful. + + o There is also an independantly developed Krunner plugin. + + Here follow a few other things that may help. + + 3.8.1. Hotkeying recoll + + It is surprisingly convenient to be able to show or hide the Recoll GUI + with a single keystroke. Recoll comes with a small Python script, based on + the libwnck window manager interface library, which will allow you to do + just this. The detailed instructions are on this wiki page. + + 3.8.2. The KDE Kicker Recoll applet + + This is probably obsolete now. Anyway: + + The Recoll source tree contains the source code to the recoll_applet, a + small application derived from the find_applet. This can be used to add a + small Recoll launcher to the KDE panel. + + The applet is not automatically built with the main Recoll programs, nor + is it included with the main source distribution (because the KDE build + boilerplate makes it relatively big). You can download its source from the + recoll.org download page. Use the omnipotent configure;make;make install + incantation to build and install. + + You can then add the applet to the panel by right-clicking the panel and + choosing the Add applet entry. + + The recoll_applet has a small text window where you can type a Recoll + query (in query language form), and an icon which can be used to restrict + the search to certain types of files. It is quite primitive, and launches + a new recoll GUI instance every time (even if it is already running). You + may find it useful anyway. + +Chapter 4. Programming interface + + Recoll has an Application Programming Interface, usable both for indexing + and searching, currently accessible from the Python language. + + Another less radical way to extend the application is to write input + handlers for new types of documents. + + The processing of metadata attributes for documents (fields) is highly + configurable. + +4.1. Writing a document input handler + + Terminology + + The small programs or pieces of code which handle the processing of the + different document types for Recoll used to be called filters, which is + still reflected in the name of the directory which holds them and many + configuration variables. They were named this way because one of their + primary functions is to filter out the formatting directives and keep the + text content. However these modules may have other behaviours, and the + term input handler is now progressively substituted in the documentation. + filter is still used in many places though. + + Recoll input handlers cooperate to translate from the multitude of input + document formats, simple ones as opendocument, acrobat), or compound ones + such as Zip or Email, into the final Recoll indexing input format, which + is plain text. Most input handlers are executable programs or scripts. A + few handlers are coded in C++ and live inside recollindex. This latter + kind will not be described here. + + There are currently (1.18 and since 1.13) two kinds of external executable + input handlers: + + o Simple exec handlers run once and exit. They can be bare programs like + antiword, or scripts using other programs. They are very simple to + write, because they just need to print the converted document to the + standard output. Their output can be plain text or HTML. HTML is + usually preferred because it can store metadata fields and it allows + preserving some of the formatting for the GUI preview. + + o Multiple execm handlers can process multiple files (sparing the + process startup time which can be very significant), or multiple + documents per file (e.g.: for zip or chm files). They communicate with + the indexer through a simple protocol, but are nevertheless a bit more + complicated than the older kind. Most of new handlers are written in + Python, using a common module to handle the protocol. There is an + exception, rclimg which is written in Perl. The subdocuments output by + these handlers can be directly indexable (text or HTML), or they can + be other simple or compound documents that will need to be processed + by another handler. + + In both cases, handlers deal with regular file system files, and can + process either a single document, or a linear list of documents in each + file. Recoll is responsible for performing up to date checks, deal with + more complex embedding and other upper level issues. + + A simple handler returning a document in text/plain format, can transfer + no metadata to the indexer. Generic metadata, like document size or + modification date, will be gathered and stored by the indexer. + + Handlers that produce text/html format can return an arbitrary amount of + metadata inside HTML meta tags. These will be processed according to the + directives found in the fields configuration file. + + The handlers that can handle multiple documents per file return a single + piece of data to identify each document inside the file. This piece of + data, called an ipath element will be sent back by Recoll to extract the + document at query time, for previewing, or for creating a temporary file + to be opened by a viewer. + + The following section describes the simple handlers, and the next one + gives a few explanations about the execm ones. You could conceivably write + a simple handler with only the elements in the manual. This will not be + the case for the other ones, for which you will have to look at the code. + + 4.1.1. Simple input handlers + + Recoll simple handlers are usually shell-scripts, but this is in no way + necessary. Extracting the text from the native format is the difficult + part. Outputting the format expected by Recoll is trivial. Happily enough, + most document formats have translators or text extractors which can be + called from the handler. In some cases the output of the translating + program is completely appropriate, and no intermediate shell-script is + needed. + + Input handlers are called with a single argument which is the source file + name. They should output the result to stdout. + + When writing a handler, you should decide if it will output plain text or + HTML. Plain text is simpler, but you will not be able to add metadata or + vary the output character encoding (this will be defined in a + configuration file). Additionally, some formatting may be easier to + preserve when previewing HTML. Actually the deciding factor is metadata: + Recoll has a way to extract metadata from the HTML header and use it for + field searches.. + + The RECOLL_FILTER_FORPREVIEW environment variable (values yes, no) tells + the handler if the operation is for indexing or previewing. Some handlers + use this to output a slightly different format, for example stripping + uninteresting repeated keywords (ie: Subject: for email) when indexing. + This is not essential. + + You should look at one of the simple handlers, for example rclps for a + starting point. + + Don't forget to make your handler executable before testing ! + + 4.1.2. "Multiple" handlers + + If you can program and want to write an execm handler, it should not be + too difficult to make sense of one of the existing modules. For example, + look at rclzip which uses Zip file paths as identifiers (ipath), and + rclics, which uses an integer index. Also have a look at the comments + inside the internfile/mh_execm.h file and possibly at the corresponding + module. + + execm handlers sometimes need to make a choice for the nature of the ipath + elements that they use in communication with the indexer. Here are a few + guidelines: + + o Use ASCII or UTF-8 (if the identifier is an integer print it, for + example, like printf %d would do). + + o If at all possible, the data should make some kind of sense when + printed to a log file to help with debugging. + + o Recoll uses a colon (:) as a separator to store a complex path + internally (for deeper embedding). Colons inside the ipath elements + output by a handler will be escaped, but would be a bad choice as a + handler-specific separator (mostly, again, for debugging issues). + + In any case, the main goal is that it should be easy for the handler to + extract the target document, given the file name and the ipath element. + + execm handlers will also produce a document with a null ipath element. + Depending on the type of document, this may have some associated data + (e.g. the body of an email message), or none (typical for an archive + file). If it is empty, this document will be useful anyway for some + operations, as the parent of the actual data documents. + + 4.1.3. Telling Recoll about the handler + + There are two elements that link a file to the handler which should + process it: the association of file to MIME type and the association of a + MIME type with a handler. + + The association of files to MIME types is mostly based on name suffixes. + The types are defined inside the mimemap file. Example: + + + .doc = application/msword + + If no suffix association is found for the file name, Recoll will try to + execute the file -i command to determine a MIME type. + + The association of file types to handlers is performed in the mimeconf + file. A sample will probably be of better help than a long explanation: + + + [index] + application/msword = exec antiword -t -i 1 -m UTF-8;\ + mimetype = text/plain ; charset=utf-8 + + application/ogg = exec rclogg + + text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html + + application/x-chm = execm rclchm + + The fragment specifies that: + + o application/msword files are processed by executing the antiword + program, which outputs text/plain encoded in utf-8. + + o application/ogg files are processed by the rclogg script, with default + output type (text/html, with encoding specified in the header, or + utf-8 by default). + + o text/rtf is processed by unrtf, which outputs text/html. The + iso-8859-1 encoding is specified because it is not the utf-8 default, + and not output by unrtf in the HTML header section. + + o application/x-chm is processed by a persistant handler. This is + determined by the execm keyword. + + 4.1.4. Input handler HTML output + + The output HTML could be very minimal like the following example: + + + + + + + Some text content + + + + + You should take care to escape some characters inside the text by + transforming them into appropriate entities. At the very minimum, "&" + should be transformed into "&", "<" should be transformed into "<". + This is not always properly done by translating programs which output + HTML, and of course never by those which output plain text. + + When encapsulating plain text in an HTML body, the display of a preview + may be improved by enclosing the text inside
 tags.
+
+   The character set needs to be specified in the header. It does not need to
+   be UTF-8 (Recoll will take care of translating it), but it must be
+   accurate for good results.
+
+   Recoll will process meta tags inside the header as possible document
+   fields candidates. Documents fields can be processed by the indexer in
+   different ways, for searching or displaying inside query results. This is
+   described in a following section.
+
+   By default, the indexer will process the standard header fields if they
+   are present: title, meta/description, and meta/keywords are both indexed
+   and stored for query-time display.
+
+   A predefined non-standard meta tag will also be processed by Recoll
+   without further configuration: if a date tag is present and has the right
+   format, it will be used as the document date (for display and sorting), in
+   preference to the file modification date. The date format should be as
+   follows:
+
+ 
+ or
+ 
+          
+
+   Example:
+
+ 
+          
+
+   Input handlers also have the possibility to "invent" field names. This
+   should also be output as meta tags:
+
+ 
+
+   You can embed HTML markup inside the content of custom fields, for
+   improving the display inside result lists. In this case, add a (wildly
+   non-standard) markup attribute to tell Recoll that the value is HTML and
+   should not be escaped for display.
+
+ 
+
+   As written above, the processing of fields is described in a further
+   section.
+
+  4.1.5. Page numbers
+
+   The indexer will interpret ^L characters in the handler output as
+   indicating page breaks, and will record them. At query time, this allows
+   starting a viewer on the right page for a hit or a snippet. Currently,
+   only the PDF, Postscript and DVI handlers generate page breaks.
+
+4.2. Field data processing
+
+   Fields are named pieces of information in or about documents, like title,
+   author, abstract.
+
+   The field values for documents can appear in several ways during indexing:
+   either output by input handlers as meta fields in the HTML header section,
+   or extracted from file extended attributes, or added as attributes of the
+   Doc object when using the API, or again synthetized internally by Recoll.
+
+   The Recoll query language allows searching for text in a specific field.
+
+   Recoll defines a number of default fields. Additional ones can be output
+   by handlers, and described in the fields configuration file.
+
+   Fields can be:
+
+     o indexed, meaning that their terms are separately stored in inverted
+       lists (with a specific prefix), and that a field-specific search is
+       possible.
+
+     o stored, meaning that their value is recorded in the index data record
+       for the document, and can be returned and displayed with search
+       results.
+
+   A field can be either or both indexed and stored. This and other aspects
+   of fields handling is defined inside the fields configuration file.
+
+   The sequence of events for field processing is as follows:
+
+     o During indexing, recollindex scans all meta fields in HTML documents
+       (most document types are transformed into HTML at some point). It
+       compares the name for each element to the configuration defining what
+       should be done with fields (the fields file)
+
+     o If the name for the meta element matches one for a field that should
+       be indexed, the contents are processed and the terms are entered into
+       the index with the prefix defined in the fields file.
+
+     o If the name for the meta element matches one for a field that should
+       be stored, the content of the element is stored with the document data
+       record, from which it can be extracted and displayed at query time.
+
+     o At query time, if a field search is performed, the index prefix is
+       computed and the match is only performed against appropriately
+       prefixed terms in the index.
+
+     o At query time, the field can be displayed inside the result list by
+       using the appropriate directive in the definition of the result list
+       paragraph format. All fields are displayed on the fields screen of the
+       preview window (which you can reach through the right-click menu).
+       This is independant of the fact that the search which produced the
+       results used the field or not.
+
+   You can find more information in the section about the fields file, or in
+   comments inside the file.
+
+   You can also have a look at the example on the Wiki, detailing how one
+   could add a page count field to pdf documents for displaying inside result
+   lists.
+
+4.3. API
+
+  4.3.1. Interface elements
+
+   A few elements in the interface are specific and and need an explanation.
+
+   udi
+
+           An udi (unique document identifier) identifies a document. Because
+           of limitations inside the index engine, it is restricted in length
+           (to 200 bytes), which is why a regular URI cannot be used. The
+           structure and contents of the udi is defined by the application
+           and opaque to the index engine. For example, the internal file
+           system indexer uses the complete document path (file path +
+           internal path), truncated to length, the suppressed part being
+           replaced by a hash value.
+
+   ipath
+
+           This data value (set as a field in the Doc object) is stored,
+           along with the URL, but not indexed by Recoll. Its contents are
+           not interpreted, and its use is up to the application. For
+           example, the Recoll internal file system indexer stores the part
+           of the document access path internal to the container file (ipath
+           in this case is a list of subdocument sequential numbers). url and
+           ipath are returned in every search result and permit access to the
+           original document.
+
+   Stored and indexed fields
+
+           The fields file inside the Recoll configuration defines which
+           document fields are either "indexed" (searchable), "stored"
+           (retrievable with search results), or both.
+
+   Data for an external indexer, should be stored in a separate index, not
+   the one for the Recoll internal file system indexer, except if the latter
+   is not used at all). The reason is that the main document indexer purge
+   pass would remove all the other indexer's documents, as they were not seen
+   during indexing. The main indexer documents would also probably be a
+   problem for the external indexer purge operation.
+
+  4.3.2. Python interface
+
+    4.3.2.1. Introduction
+
+   Recoll versions after 1.11 define a Python programming interface, both for
+   searching and indexing. The indexing portion has seen little use, but the
+   searching one is used in the Recoll Ubuntu Unity Lens and Recoll Web UI.
+
+   The API is inspired by the Python database API specification. There were
+   two major changes in recent Recoll versions:
+
+     o The basis for the Recoll API changed from Python database API version
+       1.0 (Recoll versions up to 1.18.1), to version 2.0 (Recoll 1.18.2 and
+       later).
+     o The recoll module became a package (with an internal recoll module) as
+       of Recoll version 1.19, in order to add more functions. For existing
+       code, this only changes the way the interface must be imported.
+
+   We will mostly describe the new API and package structure here. A
+   paragraph at the end of this section will explain a few differences and
+   ways to write code compatible with both versions.
+
+   The Python interface can be found in the source package, under
+   python/recoll.
+
+   The python/recoll/ directory contains the usual setup.py. After
+   configuring the main Recoll code, you can use the script to build and
+   install the Python module:
+
+             cd recoll-xxx/python/recoll
+             python setup.py build
+             python setup.py install
+          
+
+   The normal Recoll installer installs the Python API along with the main
+   code.
+
+   When installing from a repository, and depending on the distribution, the
+   Python API can sometimes be found in a separate package.
+
+    4.3.2.2. Recoll package
+
+   The recoll package contains two modules:
+
+     o The recoll module contains functions and classes used to query (or
+       update) the index.
+
+     o The rclextract module contains functions and classes used to access
+       document data.
+
+    4.3.2.3. The recoll module
+
+      Functions
+
+   connect(confdir=None, extra_dbs=None, writable = False)
+           The connect() function connects to one or several Recoll index(es)
+           and returns a Db object.
+              o confdir may specify a configuration directory. The usual
+                defaults apply.
+              o extra_dbs is a list of additional indexes (Xapian
+                directories).
+              o writable decides if we can index new data through this
+                connection.
+           This call initializes the recoll module, and it should always be
+           performed before any other call or object creation.
+
+      Classes
+
+        The Db class
+
+   A Db object is created by a connect() call and holds a connection to a
+   Recoll index.
+
+   Methods
+
+   Db.close()
+           Closes the connection. You can't do anything with the Db object
+           after this.
+
+   Db.query(), Db.cursor()
+           These aliases return a blank Query object for this index.
+
+   Db.setAbstractParams(maxchars, contextwords)
+           Set the parameters used to build snippets (sets of keywords in
+           context text fragments). maxchars defines the maximum total size
+           of the abstract. contextwords defines how many terms are shown
+           around the keyword.
+
+   Db.termMatch(match_type, expr, field='', maxlen=-1, casesens=False,
+   diacsens=False, lang='english')
+           Expand an expression against the index term list. Performs the
+           basic function from the GUI term explorer tool. match_type can be
+           either of wildcard, regexp or stem. Returns a list of terms
+           expanded from the input expression.
+
+        The Query class
+
+   A Query object (equivalent to a cursor in the Python DB API) is created by
+   a Db.query() call. It is used to execute index searches.
+
+   Methods
+
+   Query.sortby(fieldname, ascending=True)
+           Sort results by fieldname, in ascending or descending order. Must
+           be called before executing the search.
+
+   Query.execute(query_string, stemming=1, stemlang="english")
+           Starts a search for query_string, a Recoll search language string.
+
+   Query.executesd(SearchData)
+           Starts a search for the query defined by the SearchData object.
+
+   Query.fetchmany(size=query.arraysize)
+           Fetches the next Doc objects in the current search results, and
+           returns them as an array of the required size, which is by default
+           the value of the arraysize data member.
+
+   Query.fetchone()
+           Fetches the next Doc object from the current search results.
+
+   Query.close()
+           Closes the query. The object is unusable after the call.
+
+   Query.scroll(value, mode='relative')
+           Adjusts the position in the current result set. mode can be
+           relative or absolute.
+
+   Query.getgroups()
+           Retrieves the expanded query terms as a list of pairs. Meaningful
+           only after executexx In each pair, the first entry is a list of
+           user terms (of size one for simple terms, or more for group and
+           phrase clauses), the second a list of query terms as derived from
+           the user terms and used in the Xapian Query.
+
+   Query.getxquery()
+           Return the Xapian query description as a Unicode string.
+           Meaningful only after executexx.
+
+   Query.highlight(text, ishtml = 0, methods = object)
+           Will insert ,  tags around the match
+           areas in the input text and return the modified text. ishtml can
+           be set to indicate that the input text is HTML and that HTML
+           special characters should not be escaped. methods if set should be
+           an object with methods startMatch(i) and endMatch() which will be
+           called for each match and should return a begin and end tag
+
+   Query.makedocabstract(doc, methods = object))
+           Create a snippets abstract for doc (a Doc object) by selecting
+           text around the match terms. If methods is set, will also perform
+           highlighting. See the highlight method.
+
+   Query.__iter__() and Query.next()
+           So that things like for doc in query: will work.
+
+   Data descriptors
+
+   Query.arraysize
+           Default number of records processed by fetchmany (r/w).
+
+   Query.rowcount
+           Number of records returned by the last execute.
+
+   Query.rownumber
+           Next index to be fetched from results. Normally increments after
+           each fetchone() call, but can be set/reset before the call to
+           effect seeking (equivalent to using scroll()). Starts at 0.
+
+        The Doc class
+
+   A Doc object contains index data for a given document. The data is
+   extracted from the index when searching, or set by the indexer program
+   when updating. The Doc object has many attributes to be read or set by its
+   user. It matches exactly the Rcl::Doc C++ object. Some of the attributes
+   are predefined, but, especially when indexing, others can be set, the name
+   of which will be processed as field names by the indexing configuration.
+   Inputs can be specified as Unicode or strings. Outputs are Unicode
+   objects. All dates are specified as Unix timestamps, printed as strings.
+   Please refer to the rcldb/rcldoc.h C++ file for a description of the
+   predefined attributes.
+
+   At query time, only the fields that are defined as stored either by
+   default or in the fields configuration file will be meaningful in the Doc
+   object. Especially this will not be the case for the document text. See
+   the rclextract module for accessing document contents.
+
+   Methods
+
+   get(key), [] operator
+           Retrieve the named doc attribute
+
+   getbinurl()
+           Retrieve the URL in byte array format (no transcoding), for use as
+           parameter to a system call.
+
+   items()
+           Return a dictionary of doc object keys/values
+
+   keys()
+           list of doc object keys (attribute names).
+
+        The SearchData class
+
+   A SearchData object allows building a query by combining clauses, for
+   execution by Query.executesd(). It can be used in replacement of the query
+   language approach. The interface is going to change a little, so no
+   detailed doc for now...
+
+   Methods
+
+   addclause(type='and'|'or'|'excl'|'phrase'|'near'|'sub', qstring=string,
+   slack=0, field='', stemming=1, subSearch=SearchData)
+
+    4.3.2.4. The rclextract module
+
+   Index queries do not provide document content (only a partial and
+   unprecise reconstruction is performed to show the snippets text). In order
+   to access the actual document data, the data extraction part of the
+   indexing process must be performed (subdocument access and format
+   translation). This is not trivial in general. The rclextract module
+   currently provides a single class which can be used to access the data
+   content for result documents.
+
+      Classes
+
+        The Extractor class
+
+   Methods
+
+   Extractor(doc)
+           An Extractor object is built from a Doc object, output from a
+           query.
+
+   Extractor.textextract(ipath)
+           Extract document defined by ipath and return a Doc object. The
+           doc.text field has the document text converted to either
+           text/plain or text/html according to doc.mimetype. The typical use
+           would be as follows:
+
+ qdoc = query.fetchone()
+ extractor = recoll.Extractor(qdoc)
+ doc = extractor.textextract(qdoc.ipath)
+ # use doc.text, e.g. for previewing
+
+   Extractor.idoctofile(ipath, targetmtype, outfile='')
+           Extracts document into an output file, which can be given
+           explicitly or will be created as a temporary file to be deleted by
+           the caller. Typical use:
+
+ qdoc = query.fetchone()
+ extractor = recoll.Extractor(qdoc)
+ filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
+
+    4.3.2.5. Example code
+
+   The following sample would query the index with a user language string.
+   See the python/samples directory inside the Recoll source for other
+   examples. The recollgui subdirectory has a very embryonic GUI which
+   demonstrates the highlighting and data extraction functions.
+
+ #!/usr/bin/env python
+
+ from recoll import recoll
+
+ db = recoll.connect()
+ db.setAbstractParams(maxchars=80, contextwords=4)
+
+ query = db.query()
+ nres = query.execute("some user question")
+ print "Result count: ", nres
+ if nres > 5:
+     nres = 5
+ for i in range(nres):
+     doc = query.fetchone()
+     print "Result #%d" % (query.rownumber,)
+     for k in ("title", "size"):
+         print k, ":", getattr(doc, k).encode('utf-8')
+     abs = db.makeDocAbstract(doc, query).encode('utf-8')
+     print abs
+     print
+
+
+
+    4.3.2.6. Compatibility with the previous version
+
+   The following code fragments can be used to ensure that code can run with
+   both the old and the new API (as long as it does not use the new abilities
+   of the new API of course).
+
+   Adapting to the new package structure:
+
+
+ try:
+     from recoll import recoll
+     from recoll import rclextract
+     hasextract = True
+ except:
+     import recoll
+     hasextract = False
+
+
+   Adapting to the change of nature of the next Query member. The same test
+   can be used to choose to use the scroll() method (new) or set the next
+   value (old).
+
+
+        rownum = query.next if type(query.next) == int else \
+                  query.rownumber
+
+
+Chapter 5. Installation and configuration
+
+5.1. Installing a binary copy
+
+   Recoll binary copies are always distributed as regular packages for your
+   system. They can be obtained either through the system's normal software
+   distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or
+   from some type of "backports" repository providing versions newer than the
+   standard ones, or found on the Recoll WEB site in some cases.
+
+   There used to exist another form of binary install, as pre-compiled source
+   trees, but these are just less convenient than the packages and don't
+   exist any more.
+
+   The package management tools will usually automatically deal with hard
+   dependancies for packages obtained from a proper package repository. You
+   will have to deal with them by hand for downloaded packages (for example,
+   when dpkg complains about missing dependancies).
+
+   In all cases, you will have to check or install supporting applications
+   for the file types that you want to index beyond those that are natively
+   processed by Recoll (text, HTML, email files, and a few others).
+
+   You should also maybe have a look at the configuration section (but this
+   may not be necessary for a quick test with default parameters). Most
+   parameters can be more conveniently set from the GUI interface.
+
+5.2. Supporting packages
+
+   Recoll uses external applications to index some file types. You need to
+   install them for the file types that you wish to have indexed (these are
+   run-time optional dependencies. None is needed for building or running
+   Recoll except for indexing their specific file type).
+
+   After an indexing pass, the commands that were found missing can be
+   displayed from the recoll File menu. The list is stored in the missing
+   text file inside the configuration directory.
+
+   A list of common file types which need external commands follows. Many of
+   the handlers need the iconv command, which is not always listed as a
+   dependancy.
+
+   Please note that, due to the relatively dynamic nature of this
+   information, the most up to date version is now kept on
+   http://www.recoll.org/features.html along with links to the home pages or
+   best source/patches pages, and misc tips. The list below is not updated
+   often and may be quite stale.
+
+   For many Linux distributions, most of the commands listed can be installed
+   from the package repositories. However, the packages are sometimes
+   outdated, or not the best version for Recoll, so you should take a look at
+   http://www.recoll.org/features.html if a file type is important to you.
+
+   As of Recoll release 1.14, a number of XML-based formats that were handled
+   by ad hoc handler code now use the xsltproc command, which usually comes
+   with libxslt. These are: abiword, fb2 (ebooks), kword, openoffice, svg.
+
+   Now for the list:
+
+     o Openoffice files need unzip and xsltproc.
+
+     o PDF files need pdftotext which is part of Poppler (usually comes with
+       the poppler-utils package). Avoid the original one from Xpdf.
+
+     o Postscript files need pstotext. The original version has an issue with
+       shell character in file names, which is corrected in recent packages.
+       See http://www.recoll.org/features.html for more detail.
+
+     o MS Word needs antiword. It is also useful to have wvWare installed as
+       it may be be used as a fallback for some files which antiword does not
+       handle.
+
+     o MS Excel and PowerPoint are processed by internal Python handlers.
+
+     o MS Open XML (docx) needs xsltproc.
+
+     o Wordperfect files need wpd2html from the libwpd (or libwpd-tools on
+       Ubuntu) package.
+
+     o RTF files need unrtf, which, in its older versions, has much trouble
+       with non-western character sets. Many Linux distributions carry
+       outdated unrtf versions. Check http://www.recoll.org/features.html for
+       details.
+
+     o TeX files need untex or detex. Check
+       http://www.recoll.org/features.html for sources if it's not packaged
+       for your distribution.
+
+     o dvi files need dvips.
+
+     o djvu files need djvutxt and djvused from the DjVuLibre package.
+
+     o Audio files: Recoll releases 1.14 and later use a single Python
+       handler based on mutagen for all audio file types.
+
+     o Pictures: Recoll uses the Exiftool Perl package to extract tag
+       information. Most image file formats are supported. Note that there
+       may not be much interest in indexing the technical tags (image size,
+       aperture, etc.). This is only of interest if you store personal tags
+       or textual descriptions inside the image files.
+
+     o chm: files in Microsoft help format need Python and the pychm module
+       (which needs chmlib).
+
+     o ICS: up to Recoll 1.13, iCalendar files need Python and the icalendar
+       module. icalendar is not needed for newer versions, which use internal
+       code.
+
+     o Zip archives need Python (and the standard zipfile module).
+
+     o Rar archives need Python, the rarfile Python module and the unrar
+       utility.
+
+     o Midi karaoke files need Python and the Midi module
+
+     o Konqueror webarchive format with Python (uses the Tarfile module).
+
+     o Mimehtml web archive format (support based on the email handler, which
+       introduces some mild weirdness, but still usable).
+
+   Text, HTML, email folders, and Scribus files are processed internally. Lyx
+   is used to index Lyx files. Many handlers need iconv and the standard sed
+   and awk.
+
+5.3. Building from source
+
+  5.3.1. Prerequisites
+
+   If you can install any or all of the following through the package manager
+   for your system, all the better. Especially Qt is a very big piece of
+   software, but you will most probably be able to find a binary package.
+
+   You may have to compile Xapian but this is easy.
+
+   The shopping list:
+
+     o C++ compiler. Up to Recoll version 1.13.04, its absence can manifest
+       itself by strange messages about a missing iconv_open.
+
+     o Development files for Xapian core.
+
+  Important
+
+       If you are building Xapian for an older CPU (before Pentium 4 or
+       Athlon 64), you need to add the --disable-sse flag to the configure
+       command. Else all Xapian application will crash with an illegal
+       instruction error.
+
+     o Development files for Qt 4 . Recoll has not been tested with Qt 5 yet.
+       Recoll 1.15.9 was the last version to support Qt 3. If you do not want
+       to install or build the Qt Webkit module, Recoll has a configuration
+       option to disable its use (see further).
+
+     o Development files for X11 and zlib.
+
+     o You may also need libiconv. On Linux systems, the iconv interface is
+       part of libc and you should not need to do anything special.
+
+   Check the Recoll download page for up to date version information.
+
+  5.3.2. Building
+
+   Recoll has been built on Linux, FreeBSD, Mac OS X, and Solaris, most
+   versions after 2005 should be ok, maybe some older ones too (Solaris 8 is
+   ok). If you build on another system, and need to modify things, I would
+   very much welcome patches.
+
+   Configure options: 
+
+     o --without-aspell will disable the code for phonetic matching of search
+       terms.
+
+     o --with-fam or --with-inotify will enable the code for real time
+       indexing. Inotify support is enabled by default on recent Linux
+       systems.
+
+     o --with-qzeitgeist will enable sending Zeitgeist events about the
+       visited search results, and needs the qzeitgeist package.
+
+     o --disable-webkit is available from version 1.17 to implement the
+       result list with a Qt QTextBrowser instead of a WebKit widget if you
+       do not or can't depend on the latter.
+
+     o --disable-idxthreads is available from version 1.19 to suppress
+       multithreading inside the indexing process. You can also use the
+       run-time configuration to restrict recollindex to using a single
+       thread, but the compile-time option may disable a few more unused
+       locks. This only applies to the use of multithreading for the core
+       index processing (data input). The Recoll monitor mode always uses at
+       least two threads of execution.
+
+     o --disable-python-module will avoid building the Python module.
+
+     o --disable-xattr will prevent fetching data from file extended
+       attributes. Beyond a few standard attributes, fetching extended
+       attributes data can only be useful is some application stores data in
+       there, and also needs some simple configuration (see comments in the
+       fields configuration file).
+
+     o --enable-camelcase will enable splitting camelCase words. This is not
+       enabled by default as it has the unfortunate side-effect of making
+       some phrase searches quite confusing: ie, "MySQL manual" would be
+       matched by "MySQL manual" and "my sql manual" but not "mysql manual"
+       (only inside phrase searches).
+
+     o --with-file-command Specify the version of the 'file' command to use
+       (ie: --with-file-command=/usr/local/bin/file). Can be useful to enable
+       the gnu version on systems where the native one is bad.
+
+     o --disable-qtgui Disable the Qt interface. Will allow building the
+       indexer and the command line search program in absence of a Qt
+       environment.
+
+     o --disable-x11mon Disable X11 connection monitoring inside recollindex.
+       Together with --disable-qtgui, this allows building recoll without Qt
+       and X11.
+
+     o --disable-pic will compile Recoll with position-dependant code. This
+       is incompatible with building the KIO or the Python or PHP extensions,
+       but might yield very marginally faster code.
+
+     o Of course the usual autoconf configure options, like --prefix apply.
+
+   Normal procedure:
+
+         cd recoll-xxx
+         ./configure
+         make
+         (practices usual hardship-repelling invocations)
+      
+
+   There is little auto-configuration. The configure script will mainly link
+   one of the system-specific files in the mk directory to mk/sysconf. If
+   your system is not known yet, it will tell you as much, and you may want
+   to manually copy and modify one of the existing files (the new file name
+   should be the output of uname -s).
+
+    5.3.2.1. Building on Solaris
+
+   We did not test building the GUI on Solaris for recent versions. You will
+   need at least Qt 4.4. There are some hints on an old web site page, they
+   may still be valid.
+
+   Someone did test the 1.19 indexer and Python module build, they do work,
+   with a few minor glitches. Be sure to use GNU make and install.
+
+  5.3.3. Installation
+
+   Either type make install or execute recollinstall prefix, in the root of
+   the source tree. This will copy the commands to prefix/bin and the sample
+   configuration files, scripts and other shared data to prefix/share/recoll.
+
+   If the installation prefix given to recollinstall is different from either
+   the system default or the value which was specified when executing
+   configure (as in configure --prefix /some/path), you will have to set the
+   RECOLL_DATADIR environment variable to indicate where the shared data is
+   to be found (ie for (ba)sh: export
+   RECOLL_DATADIR=/some/path/share/recoll).
+
+   You can then proceed to configuration.
+
+5.4. Configuration overview
+
+   Most of the parameters specific to the recoll GUI are set through the
+   Preferences menu and stored in the standard Qt place
+   ($HOME/.config/Recoll.org/recoll.conf). You probably do not want to edit
+   this by hand.
+
+   Recoll indexing options are set inside text configuration files located in
+   a configuration directory. There can be several such directories, each of
+   which defines the parameters for one index.
+
+   The configuration files can be edited by hand or through the Index
+   configuration dialog (Preferences menu). The GUI tool will try to respect
+   your formatting and comments as much as possible, so it is quite possible
+   to use both ways.
+
+   The most accurate documentation for the configuration parameters is given
+   by comments inside the default files, and we will just give a general
+   overview here.
+
+   By default, for each index, there are two sets of configuration files.
+   System-wide configuration files are kept in a directory named like
+   /usr/[local/]share/recoll/examples, and define default values, shared by
+   all indexes. For each index, a parallel set of files defines the
+   customized parameters.
+
+   In addition (as of Recoll version 1.19.7), it is possible to specify two
+   additional configuration directories which will be stacked before and
+   after the user configuration directory. These are defined by the
+   RECOLL_CONFTOP and RECOLL_CONFMID environment variables. Values from
+   configuration files inside the top directory will override user ones,
+   values from configuration files inside the middle directory will override
+   system ones and be overriden by user ones. These two variables may be of
+   use to applications which augment Recoll functionality, and need to add
+   configuration data without disturbing the user's files. Please note that
+   the two, currently single, values will probably be interpreted as
+   colon-separated lists in the future: do not use colon characters inside
+   the directory paths.
+
+   The default location of the configuration is the .recoll directory in your
+   home. Most people will only use this directory.
+
+   This location can be changed, or others can be added with the
+   RECOLL_CONFDIR environment variable or the -c option parameter to recoll
+   and recollindex.
+
+   If the .recoll directory does not exist when recoll or recollindex are
+   started, it will be created with a set of empty configuration files.
+   recoll will give you a chance to edit the configuration file before
+   starting indexing. recollindex will proceed immediately. To avoid
+   mistakes, the automatic directory creation will only occur for the default
+   location, not if -c or RECOLL_CONFDIR were used (in the latter cases, you
+   will have to create the directory).
+
+   All configuration files share the same format. For example, a short
+   extract of the main configuration file might look as follows:
+
+         # Space-separated list of directories to index.
+         topdirs =  ~/docs /usr/share/doc
+
+         [~/somedirectory-with-utf8-txt-files]
+         defaultcharset = utf-8
+        
+
+   There are three kinds of lines:
+
+     o Comment (starts with #) or empty.
+
+     o Parameter affectation (name = value).
+
+     o Section definition ([somedirname]).
+
+   Depending on the type of configuration file, section definitions either
+   separate groups of parameters or allow redefining some parameters for a
+   directory sub-tree. They stay in effect until another section definition,
+   or the end of file, is encountered. Some of the parameters used for
+   indexing are looked up hierarchically from the current directory location
+   upwards. Not all parameters can be meaningfully redefined, this is
+   specified for each in the next section.
+
+   When found at the beginning of a file path, the tilde character (~) is
+   expanded to the name of the user's home directory, as a shell would do.
+
+   White space is used for separation inside lists. List elements with
+   embedded spaces can be quoted using double-quotes.
+
+   Encoding issues. Most of the configuration parameters are plain ASCII. Two
+   particular sets of values may cause encoding issues:
+
+     o File path parameters may contain non-ascii characters and should use
+       the exact same byte values as found in the file system directory.
+       Usually, this means that the configuration file should use the system
+       default locale encoding.
+
+     o The unac_except_trans parameter should be encoded in UTF-8. If your
+       system locale is not UTF-8, and you need to also specify non-ascii
+       file paths, this poses a difficulty because common text editors cannot
+       handle multiple encodings in a single file. In this relatively
+       unlikely case, you can edit the configuration file as two separate
+       text files with appropriate encodings, and concatenate them to create
+       the complete configuration.
+
+  5.4.1. Environment variables
+
+   RECOLL_CONFDIR
+
+           Defines the main configuration directory.
+
+   RECOLL_TMPDIR, TMPDIR
+
+           Locations for temporary files, in this order of priority. The
+           default if none of these is set is to use /tmp. Big temporary
+           files may be created during indexing, mostly for decompressing,
+           and also for processing, e.g. email attachments.
+
+   RECOLL_CONFTOP, RECOLL_CONFMID
+
+           Allow adding configuration directories with priorities below and
+           above the user directory (see above the Configuration overview
+           section for details).
+
+   RECOLL_EXTRA_DBS, RECOLL_ACTIVE_EXTRA_DBS
+
+           Help for setting up external indexes. See this paragraph for
+           explanations.
+
+   RECOLL_DATADIR
+
+           Defines replacement for the default location of Recoll data files,
+           normally found in, e.g., /usr/share/recoll).
+
+   RECOLL_FILTERSDIR
+
+           Defines replacement for the default location of Recoll filters,
+           normally found in, e.g., /usr/share/recoll/filters).
+
+   ASPELL_PROG
+
+           aspell program to use for creating the spelling dictionary. The
+           result has to be compatible with the libaspell which Recoll is
+           using.
+
+   VARNAME
+
+           Blabla
+
+  5.4.2. The main configuration file, recoll.conf
+
+   recoll.conf is the main configuration file. It defines things like what to
+   index (top directories and things to ignore), and the default character
+   set to use for document types which do not specify it internally.
+
+   The default configuration will index your home directory. If this is not
+   appropriate, start recoll to create a blank configuration, click Cancel,
+   and edit the configuration file before restarting the command. This will
+   start the initial indexing, which may take some time.
+
+   Most of the following parameters can be changed from the Index
+   Configuration menu in the recoll interface. Some can only be set by
+   editing the configuration file.
+
+    5.4.2.1. Parameters affecting what documents we index:
+
+   topdirs
+
+           Specifies the list of directories or files to index (recursively
+           for directories). You can use symbolic links as elements of this
+           list. See the followLinks option about following symbolic links
+           found under the top elements (not followed by default).
+
+   skippedNames
+
+           A space-separated list of wilcard patterns for names of files or
+           directories that should be completely ignored. The list defined in
+           the default file is:
+
+ skippedNames = #* bin CVS  Cache cache* caughtspam  tmp .thumbnails .svn \
+                *~ .beagle .git .hg .bzr loop.ps .xsession-errors \
+                .recoll* xapiandb recollrc recoll.conf
+
+           The list can be redefined at any sub-directory in the indexed
+           area.
+
+           The top-level directories are not affected by this list (that is,
+           a directory in topdirs might match and would still be indexed).
+
+           The list in the default configuration does not exclude hidden
+           directories (names beginning with a dot), which means that it may
+           index quite a few things that you do not want. On the other hand,
+           email user agents like thunderbird usually store messages in
+           hidden directories, and you probably want this indexed. One
+           possible solution is to have .* in skippedNames, and add things
+           like ~/.thunderbird or ~/.evolution in topdirs.
+
+           Not even the file names are indexed for patterns in this list. See
+           the noContentSuffixes variable for an alternative approach which
+           indexes the file names.
+
+   noContentSuffixes
+
+           This is a list of file name endings (not wildcard expressions, nor
+           dot-delimited suffixes). Only the names of matching files will be
+           indexed (no attempt at MIME type identification, no decompression,
+           no content indexing). This can be redefined for subdirectories,
+           and edited from the GUI. The default value is:
+
+ noContentSuffixes = .md5 .map \
+        .o .lib .dll .a .sys .exe .com \
+        .mpp .mpt .vsd \
+            .img .img.gz .img.bz2 .img.xz .image .image.gz .image.bz2 .image.xz \
+        .dat .bak .rdf .log.gz .log .db .msf .pid \
+        ,v ~ #
+
+   skippedPaths and daemSkippedPaths
+
+           A space-separated list of patterns for paths of files or
+           directories that should be skipped. There is no default in the
+           sample configuration file, but the code always adds the
+           configuration and database directories in there.
+
+           skippedPaths is used both by batch and real time indexing.
+           daemSkippedPaths can be used to specify things that should be
+           indexed at startup, but not monitored.
+
+           Example of use for skipping text files only in a specific
+           directory:
+
+ skippedPaths = ~/somedir/*.txt
+              
+
+   skippedPathsFnmPathname
+
+           The values in the *skippedPaths variables are matched by default
+           with fnmatch(3), with the FNM_PATHNAME flag. This means that '/'
+           characters must be matched explicitely. You can set
+           skippedPathsFnmPathname to 0 to disable the use of FNM_PATHNAME
+           (meaning that /*/dir3 will match /dir1/dir2/dir3).
+
+   zipSkippedNames
+
+           A space-separated list of patterns for names of files or
+           directories that should be ignored inside zip archives. This is
+           used directly by the zip handler, and has a function similar to
+           skippedNames, but works independantly. Can be redefined for
+           filesystem subdirectories. For versions up to 1.19, you will need
+           to update the Zip handler and install a supplementary Python
+           module. The details are described on the Recoll wiki.
+
+   followLinks
+
+           Specifies if the indexer should follow symbolic links while
+           walking the file tree. The default is to ignore symbolic links to
+           avoid multiple indexing of linked files. No effort is made to
+           avoid duplication when this option is set to true. This option can
+           be set individually for each of the topdirs members by using
+           sections. It can not be changed below the topdirs level.
+
+   indexedmimetypes
+
+           Recoll normally indexes any file which it knows how to read. This
+           list lets you restrict the indexed MIME types to what you specify.
+           If the variable is unspecified or the list empty (the default),
+           all supported types are processed. Can be redefined for
+           subdirectories.
+
+   excludedmimetypes
+
+           This list lets you exclude some MIME types from indexing. Can be
+           redefined for subdirectories.
+
+   compressedfilemaxkbs
+
+           Size limit for compressed (.gz or .bz2) files. These need to be
+           decompressed in a temporary directory for identification, which
+           can be very wasteful if 'uninteresting' big compressed files are
+           present. Negative means no limit, 0 means no processing of any
+           compressed file. Defaults to -1.
+
+   textfilemaxmbs
+
+           Maximum size for text files. Very big text files are often
+           uninteresting logs. Set to -1 to disable (default 20MB).
+
+   textfilepagekbs
+
+           If set to other than -1, text files will be indexed as multiple
+           documents of the given page size. This may be useful if you do
+           want to index very big text files as it will both reduce memory
+           usage at index time and help with loading data to the preview
+           window. A size of a few megabytes would seem reasonable (default:
+           1MB).
+
+   membermaxkbs
+
+           This defines the maximum size in kilobytes for an archive member
+           (zip, tar or rar at the moment). Bigger entries will be skipped.
+
+   indexallfilenames
+
+           Recoll indexes file names in a special section of the database to
+           allow specific file names searches using wild cards. This
+           parameter decides if file name indexing is performed only for
+           files with MIME types that would qualify them for full text
+           indexing, or for all files inside the selected subtrees,
+           independently of MIME type.
+
+   usesystemfilecommand
+
+           Decide if we execute a system command (file -i by default) as a
+           final step for determining the MIME type for a file (the main
+           procedure uses suffix associations as defined in the mimemap
+           file). This can be useful for files with suffix-less names, but it
+           will also cause the indexing of many bogus "text" files.
+
+   systemfilecommand
+
+           Command to use for mime for mime type determination if
+           usesystefilecommand is set. Recent versions of xdg-mime sometimes
+           work better than file.
+
+   processwebqueue
+
+           If this is set, process the directory where Web browser plugins
+           copy visited pages for indexing.
+
+   webqueuedir
+
+           The path to the web indexing queue. This is hard-coded in the
+           Firefox plugin as ~/.recollweb/ToIndex so there should be no need
+           to change it.
+
+    5.4.2.2. Parameters affecting how we generate terms:
+
+   Changing some of these parameters will imply a full reindex. Also, when
+   using multiple indexes, it may not make sense to search indexes that don't
+   share the values for these parameters, because they usually affect both
+   search and index operations.
+
+   indexStripChars
+
+           Decide if we strip characters of diacritics and convert them to
+           lower-case before terms are indexed. If we don't, searches
+           sensitive to case and diacritics can be performed, but the index
+           will be bigger, and some marginal weirdness may sometimes occur.
+           The default is a stripped index (indexStripChars = 1) for now.
+           When using multiple indexes for a search, this parameter must be
+           defined identically for all. Changing the value implies an index
+           reset.
+
+   maxTermExpand
+
+           Maximum expansion count for a single term (e.g.: when using
+           wildcards). The default of 10000 is reasonable and will avoid
+           queries that appear frozen while the engine is walking the term
+           list.
+
+   maxXapianClauses
+
+           Maximum number of elementary clauses we can add to a single Xapian
+           query. In some cases, the result of term expansion can be
+           multiplicative, and we want to avoid using excessive memory. The
+           default of 100 000 should be both high enough in most cases and
+           compatible with current typical hardware configurations.
+
+   nonumbers
+
+           If this set to true, no terms will be generated for numbers. For
+           example "123", "1.5e6", 192.168.1.4, would not be indexed
+           ("value123" would still be). Numbers are often quite interesting
+           to search for, and this should probably not be set except for
+           special situations, ie, scientific documents with huge amounts of
+           numbers in them. This can only be set for a whole index, not for a
+           subtree.
+
+   nocjk
+
+           If this set to true, specific east asian (Chinese Korean Japanese)
+           characters/word splitting is turned off. This will save a small
+           amount of cpu if you have no CJK documents. If your document base
+           does include such text but you are not interested in searching it,
+           setting nocjk may be a significant time and space saver.
+
+   cjkngramlen
+
+           This lets you adjust the size of n-grams used for indexing CJK
+           text. The default value of 2 is probably appropriate in most
+           cases. A value of 3 would allow more precision and efficiency on
+           longer words, but the index will be approximately twice as large.
+
+   indexstemminglanguages
+
+           A list of languages for which the stem expansion databases will be
+           built. See recollindex(1) or use the recollindex -l command for
+           possible values. You can add a stem expansion database for a
+           different language by using recollindex -s, but it will be deleted
+           during the next indexing. Only languages listed in the
+           configuration file are permanent.
+
+   defaultcharset
+
+           The name of the character set used for files that do not contain a
+           character set definition (ie: plain text files). This can be
+           redefined for any sub-directory. If it is not set at all, the
+           character set used is the one defined by the nls environment (
+           LC_ALL, LC_CTYPE, LANG), or iso8859-1 if nothing is set.
+
+   unac_except_trans
+
+           This is a list of characters, encoded in UTF-8, which should be
+           handled specially when converting text to unaccented lowercase.
+           For example, in Swedish, the letter a with diaeresis has full
+           alphabet citizenship and should not be turned into an a. Each
+           element in the space-separated list has the special character as
+           first element and the translation following. The handling of both
+           the lowercase and upper-case versions of a character should be
+           specified, as appartenance to the list will turn-off both standard
+           accent and case processing. Example for Swedish:
+
+ unac_except_trans =  aaaa AAaa a:a: A:a: o:o: O:o:
+            
+
+           Note that the translation is not limited to a single character,
+           you could very well have something like u:ue in the list.
+
+           The default value set for unac_except_trans can't be listed here
+           because I have trouble with SGML and UTF-8, but it only contains
+           ligature decompositions: german ss, oe, ae, fi, fl.
+
+           This parameter can't be defined for subdirectories, it is global,
+           because there is no way to do otherwise when querying. If you have
+           document sets which would need different values, you will have to
+           index and query them separately.
+
+   maildefcharset
+
+           This can be used to define the default character set specifically
+           for email messages which don't specify it. This is mainly useful
+           for readpst (libpst) dumps, which are utf-8 but do not say so.
+
+   localfields
+
+           This allows setting fields for all documents under a given
+           directory. Typical usage would be to set an "rclaptg" field, to be
+           used in mimeview to select a specific viewer. If several fields
+           are to be set, they should be separated with a semi-colon (';')
+           character, which there is currently no way to escape. Also note
+           the initial semi-colon. Example: localfields= ;rclaptg=gnus;other
+           = val, then select specifier viewer with mimetype|tag=... in
+           mimeview.
+
+   testmodifusemtime
+
+           If true, use mtime instead of default ctime to determine if a file
+           has been modified (in addition to size, which is always used).
+           Setting this can reduce re-indexing on systems where extended
+           attributes are modified (by some other application), but not
+           indexed (changing extended attributes only affects ctime). Notes:
+
+              o This may prevent detection of change in some marginal file
+                rename cases (the target would need to have the same size and
+                mtime).
+
+              o You should probably also set noxattrfields to 1 in this case,
+                except if you still prefer to perform xattr indexing, for
+                example if the local file update pattern makes it of value
+                (as in general, there is a risk for pure extended attributes
+                updates without file modification to go undetected).
+
+           Perform a full index reset after changing the value of this
+           parameter.
+
+   noxattrfields
+
+           Recoll versions 1.19 and later automatically translate file
+           extended attributes into document fields (to be processed
+           according to the parameters from the fields file). Setting this
+           variable to 1 will disable the behaviour.
+
+   metadatacmds
+
+           This allows executing external commands for each file and storing
+           the output in Recoll document fields. This could be used for
+           example to index external tag data. The value is a list of field
+           names and commands, don't forget an initial semi-colon. Example:
+
+ [/some/area/of/the/fs]
+ metadatacmds = ; tags = tmsu tags %f; otherfield = somecmd -xx %f
+                
+
+           As a specially disgusting hack brought by Recoll 1.19.7, if a
+           "field name" begins with rclmulti, the data returned by the
+           command is expected to contain multiple field values, in
+           configuration file format. This allows setting several fields by
+           executing a single command. Example:
+
+ metadatacmds = ; rclmulti1 = somecmd %f
+                
+
+           If somecmd returns data in the form of:
+
+ field1 = value1
+ field2 = value for field2
+                
+
+           field1 and field2 will be set inside the document metadata.
+
+    5.4.2.3. Parameters affecting where and how we store things:
+
+   dbdir
+
+           The name of the Xapian data directory. It will be created if
+           needed when the index is initialized. If this is not an absolute
+           path, it will be interpreted relative to the configuration
+           directory. The value can have embedded spaces but starting or
+           trailing spaces will be trimmed. You cannot use quotes here.
+
+   idxstatusfile
+
+           The name of the scratch file where the indexer process updates its
+           status. Default: idxstatus.txt inside the configuration directory.
+
+   maxfsoccuppc
+
+           Maximum file system occupation before we stop indexing. The value
+           is a percentage, corresponding to what the "Capacity" df output
+           column shows. The default value is 0, meaning no checking.
+
+   mboxcachedir
+
+           The directory where mbox message offsets cache files are held.
+           This is normally $RECOLL_CONFDIR/mboxcache, but it may be useful
+           to share a directory between different configurations.
+
+   mboxcacheminmbs
+
+           The minimum mbox file size over which we cache the offsets. There
+           is really no sense in caching offsets for small files. The default
+           is 5 MB.
+
+   webcachedir
+
+           This is only used by the web browser plugin indexing code, and
+           defines where the cache for visited pages will live. Default:
+           $RECOLL_CONFDIR/webcache
+
+   webcachemaxmbs
+
+           This is only used by the web browser plugin indexing code, and
+           defines the maximum size for the web page cache. Default: 40 MB.
+           Quite unfortunately, this is only taken into account when creating
+           the cache file. You need to delete the file for a change to be
+           taken into account.
+
+   idxflushmb
+
+           Threshold (megabytes of new text data) where we flush from memory
+           to disk index. Setting this can help control memory usage. A value
+           of 0 means no explicit flushing, letting Xapian use its own
+           default, which is flushing every 10000 (or XAPIAN_FLUSH_THRESHOLD)
+           documents, which gives little memory usage control, as memory
+           usage also depends on average document size. The default value is
+           10, and it is probably a bit low. If your system usually has free
+           memory, you can try higher values between 20 and 80. In my
+           experience, values beyond 100 are always counterproductive.
+
+    5.4.2.4. Parameters affecting multithread processing
+
+   The Recoll indexing process recollindex can use multiple threads to speed
+   up indexing on multiprocessor systems. The work done to index files is
+   divided in several stages and some of the stages can be executed by
+   multiple threads. The stages are:
+
+    1. File system walking: this is always performed by the main thread.
+    2. File conversion and data extraction.
+    3. Text processing (splitting, stemming, etc.)
+    4. Xapian index update.
+
+   You can also read a longer document about the transformation of Recoll
+   indexing to multithreading.
+
+   The threads configuration is controlled by two configuration file
+   parameters.
+
+   thrQSizes
+
+           This variable defines the job input queues configuration. There
+           are three possible queues for stages 2, 3 and 4, and this
+           parameter should give the queue depth for each stage (three
+           integer values). If a value of -1 is used for a given stage, no
+           queue is used, and the thread will go on performing the next
+           stage. In practise, deep queues have not been shown to increase
+           performance. A value of 0 for the first queue tells Recoll to
+           perform autoconfiguration (no need for the two other values in
+           this case) - this is the default configuration.
+
+   thrTCounts
+
+           This defines the number of threads used for each stage. If a value
+           of -1 is used for one of the queue depths, the corresponding
+           thread count is ignored. It makes no sense to use a value other
+           than 1 for the last stage because updating the Xapian index is
+           necessarily single-threaded (and protected by a mutex).
+
+   The following example would use three queues (of depth 2), and 4 threads
+   for converting source documents, 2 for processing their text, and one to
+   update the index. This was tested to be the best configuration on the test
+   system (quadri-processor with multiple disks).
+
+ thrQSizes = 2 2 2
+ thrTCounts =  4 2 1
+
+   The following example would use a single queue, and the complete
+   processing for each document would be performed by a single thread
+   (several documents will still be processed in parallel in most cases). The
+   threads will use mutual exclusion when entering the index update stage. In
+   practise the performance would be close to the precedent case in general,
+   but worse in certain cases (e.g. a Zip archive would be performed purely
+   sequentially), so the previous approach is preferred. YMMV... The 2 last
+   values for thrTCounts are ignored.
+
+ thrQSizes = 2 -1 -1
+ thrTCounts =  6 1 1
+
+   The following example would disable multithreading. Indexing will be
+   performed by a single thread.
+
+ thrQSizes = -1 -1 -1
+
+    5.4.2.5. Miscellaneous parameters:
+
+   autodiacsens
+
+           IF the index is not stripped, decide if we automatically trigger
+           diacritics sensitivity if the search term has accented characters
+           (not in unac_except_trans). Else you need to use the query
+           language and the D modifier to specify diacritics sensitivity.
+           Default is no.
+
+   autocasesens
+
+           IF the index is not stripped, decide if we automatically trigger
+           character case sensitivity if the search term has upper-case
+           characters in any but the first position. Else you need to use the
+           query language and the C modifier to specify character-case
+           sensitivity. Default is yes.
+
+   loglevel,daemloglevel
+
+           Verbosity level for recoll and recollindex. A value of 4 lists
+           quite a lot of debug/information messages. 2 only lists errors.
+           The daemversion is specific to the indexing monitor daemon.
+
+   logfilename, daemlogfilename
+
+           Where the messages should go. 'stderr' can be used as a special
+           value, and is the default. The daemversion is specific to the
+           indexing monitor daemon.
+
+   checkneedretryindexscript
+
+           This defines the name for a command executed by recollindex when
+           starting indexing. If the exit status of the command is 0,
+           recollindex retries to index all files which previously could not
+           be indexed because of data extraction errors. The default value is
+           a script which checks if any of the common bin directories have
+           changed (indicating that a helper program may have been
+           installed).
+
+   mondelaypatterns
+
+           This allows specify wildcard path patterns (processed with
+           fnmatch(3) with 0 flag), to match files which change too often and
+           for which a delay should be observed before re-indexing. This is a
+           space-separated list, each entry being a pattern and a time in
+           seconds, separated by a colon. You can use double quotes if a path
+           entry contains white space. Example:
+
+ mondelaypatterns = *.log:20 "this one has spaces*:10"
+              
+
+   monixinterval
+
+           Minimum interval (seconds) for processing the indexing queue. The
+           real time monitor does not process each event when it comes in,
+           but will wait this time for the queue to accumulate to diminish
+           overhead and in order to aggregate multiple events to the same
+           file. Default 30 S.
+
+   monauxinterval
+
+           Period (in seconds) at which the real time monitor will regenerate
+           the auxiliary databases (spelling, stemming) if needed. The
+           default is one hour.
+
+   monioniceclass, monioniceclassdata
+
+           These allow defining the ionice class and data used by the indexer
+           (default class 3, no data).
+
+   filtermaxseconds
+
+           Maximum handler execution time, after which it is aborted. Some
+           postscript programs just loop...
+
+   filtermaxmbytes
+
+           Recoll 1.20.7 and later. Maximum handler memory utilisation. This
+           uses setrlimit(RLIMIT_AS) on most systems (total virtual memory
+           space size limit). Some programs may start with 500 MBytes of
+           mapped shared libraries, so take this into account when choosing a
+           value. The default is a liberal 2000MB.
+
+   filtersdir
+
+           A directory to search for the external input handler scripts used
+           to index some types of files. The value should not be changed,
+           except if you want to modify one of the default scripts. The value
+           can be redefined for any sub-directory.
+
+   iconsdir
+
+           The name of the directory where recoll result list icons are
+           stored. You can change this if you want different images.
+
+   idxabsmlen
+
+           Recoll stores an abstract for each indexed file inside the
+           database. The text can come from an actual 'abstract' section in
+           the document or will just be the beginning of the document. It is
+           stored in the index so that it can be displayed inside the result
+           lists without decoding the original file. The idxabsmlen parameter
+           defines the size of the stored abstract. The default value is 250
+           bytes. The search interface gives you the choice to display this
+           stored text or a synthetic abstract built by extracting text
+           around the search terms. If you always prefer the synthetic
+           abstract, you can reduce this value and save a little space.
+
+   idxmetastoredlen
+
+           Maximum stored length for metadata fields. This does not affect
+           indexing (the whole field is processed anyway), just the amount of
+           data stored in the index for the purpose of displaying fields
+           inside result lists or previews. The default value is 150 bytes
+           which may be too low if you have custom fields.
+
+   aspellLanguage
+
+           Language definitions to use when creating the aspell dictionary.
+           The value must match a set of aspell language definition files.
+           You can type "aspell config" to see where these are installed
+           (look for data-dir). The default if the variable is not set is to
+           use your desktop national language environment to guess the value.
+
+   noaspell
+
+           If this is set, the aspell dictionary generation is turned off.
+           Useful for cases where you don't need the functionality or when it
+           is unusable because aspell crashes during dictionary generation.
+
+   mhmboxquirks
+
+           This allows definining location-related quirks for the mailbox
+           handler. Currently only the tbird flag is defined, and it should
+           be set for directories which hold Thunderbird data, as their
+           folder format is weird.
+
+  5.4.3. The fields file
+
+   This file contains information about dynamic fields handling in Recoll.
+   Some very basic fields have hard-wired behaviour, and, mostly, you should
+   not change the original data inside the fields file. But you can create
+   custom fields fitting your data and handle them just like they were native
+   ones.
+
+   The fields file has several sections, which each define an aspect of
+   fields processing. Quite often, you'll have to modify several sections to
+   obtain the desired behaviour.
+
+   We will only give a short description here, you should refer to the
+   comments inside the default file for more detailed information.
+
+   Field names should be lowercase alphabetic ASCII.
+
+   [prefixes]
+
+           A field becomes indexed (searchable) by having a prefix defined in
+           this section.
+
+   [stored]
+
+           A field becomes stored (displayable inside results) by having its
+           name listed in this section (typically with an empty value).
+
+   [aliases]
+
+           This section defines lists of synonyms for the canonical names
+           used inside the [prefixes] and [stored] sections
+
+   [queryaliases]
+
+           This section also defines aliases for the canonic field names,
+           with the difference that the substitution will only be used at
+           query time, avoiding any possibility that the value would pick-up
+           random metadata from documents.
+
+   handler-specific sections
+
+           Some input handlers may need specific configuration for handling
+           fields. Only the email message handler currently has such a
+           section (named [mail]). It allows indexing arbitrary email headers
+           in addition to the ones indexed by default. Other such sections
+           may appear in the future.
+
+   Here follows a small example of a personal fields file. This would extract
+   a specific email header and use it as a searchable field, with data
+   displayable inside result lists. (Side note: as the email handler does no
+   decoding on the values, only plain ascii headers can be indexed, and only
+   the first occurrence will be used for headers that occur several times).
+
+ [prefixes]
+ # Index mailmytag contents (with the given prefix)
+ mailmytag = XMTAG
+
+ [stored]
+ # Store mailmytag inside the document data record (so that it can be
+ # displayed - as %(mailmytag) - in result lists).
+ mailmytag =
+
+ [queryaliases]
+ filename = fn
+ containerfilename = cfn
+
+ [mail]
+ # Extract the X-My-Tag mail header, and use it internally with the
+ # mailmytag field name
+ x-my-tag = mailmytag
+
+    5.4.3.1. Extended attributes in the fields file
+
+   Recoll versions 1.19 and later process user extended file attributes as
+   documents fields by default.
+
+   Attributes are processed as fields of the same name, after removing the
+   user prefix on Linux.
+
+   The [xattrtofields] section of the fields file allows specifying
+   translations from extended attributes names to Recoll field names. An
+   empty translation disables use of the corresponding attribute data.
+
+  5.4.4. The mimemap file
+
+   mimemap specifies the file name extension to MIME type mappings.
+
+   For file names without an extension, or with an unknown one, the system's
+   file -i command will be executed to determine the MIME type (this can be
+   switched off inside the main configuration file).
+
+   The mappings can be specified on a per-subtree basis, which may be useful
+   in some cases. Example: gaim logs have a .txt extension but should be
+   handled specially, which is possible because they are usually all located
+   in one place.
+
+   The recoll_noindex mimemap variable has been moved to recoll.conf and
+   renamed to noContentSuffixes, while keeping the same function, as of
+   Recoll version 1.21. For older Recoll versions, see the documentation for
+   noContentSuffixes but use recoll_noindex in mimemap.
+
+  5.4.5. The mimeconf file
+
+   mimeconf specifies how the different MIME types are handled for indexing,
+   and which icons are displayed in the recoll result lists.
+
+   Changing the parameters in the [index] section is probably not a good idea
+   except if you are a Recoll developer.
+
+   The [icons] section allows you to change the icons which are displayed by
+   recoll in the result lists (the values are the basenames of the png images
+   inside the iconsdir directory (specified in recoll.conf).
+
+  5.4.6. The mimeview file
+
+   mimeview specifies which programs are started when you click on an Open
+   link in a result list. Ie: HTML is normally displayed using firefox, but
+   you may prefer Konqueror, your openoffice.org program might be named
+   oofice instead of openoffice etc.
+
+   Changes to this file can be done by direct editing, or through the recoll
+   GUI preferences dialog.
+
+   If Use desktop preferences to choose document editor is checked in the
+   Recoll GUI preferences, all mimeview entries will be ignored except the
+   one labelled application/x-all (which is set to use xdg-open by default).
+
+   In this case, the xallexcepts top level variable defines a list of MIME
+   type exceptions which will be processed according to the local entries
+   instead of being passed to the desktop. This is so that specific Recoll
+   options such as a page number or a search string can be passed to
+   applications that support them, such as the evince viewer.
+
+   As for the other configuration files, the normal usage is to have a
+   mimeview inside your own configuration directory, with just the
+   non-default entries, which will override those from the central
+   configuration file.
+
+   All viewer definition entries must be placed under a [view] section.
+
+   The keys in the file are normally MIME types. You can add an application
+   tag to specialize the choice for an area of the filesystem (using a
+   localfields specification in mimeconf). The syntax for the key is
+   mimetype|tag
+
+   The nouncompforviewmts entry, (placed at the top level, outside of the
+   [view] section), holds a list of MIME types that should not be
+   uncompressed before starting the viewer (if they are found compressed, ie:
+   mydoc.doc.gz).
+
+   The right side of each assignment holds a command to be executed for
+   opening the file. The following substitutions are performed:
+
+     o %D. Document date
+
+     o %f. File name. This may be the name of a temporary file if it was
+       necessary to create one (ie: to extract a subdocument from a
+       container).
+
+     o %i. Internal path, for subdocuments of containers. The format depends
+       on the container type. If this appears in the command line, Recoll
+       will not create a temporary file to extract the subdocument, expecting
+       the called application (possibly a script) to be able to handle it.
+
+     o %M. MIME type
+
+     o %p. Page index. Only significant for a subset of document types,
+       currently only PDF, Postscript and DVI files. Can be used to start the
+       editor at the right page for a match or snippet.
+
+     o %s. Search term. The value will only be set for documents with indexed
+       page numbers (ie: PDF). The value will be one of the matched search
+       terms. It would allow pre-setting the value in the "Find" entry inside
+       Evince for example, for easy highlighting of the term.
+
+     o %u. Url.
+
+   In addition to the predefined values above, all strings like %(fieldname)
+   will be replaced by the value of the field named fieldname for the
+   document. This could be used in combination with field customisation to
+   help with opening the document.
+
+  5.4.7. The ptrans file
+
+   ptrans specifies query-time path translations. These can be useful in
+   multiple cases.
+
+   The file has a section for any index which needs translations, either the
+   main one or additional query indexes. The sections are named with the
+   Xapian index directory names. No slash character should exist at the end
+   of the paths (all comparisons are textual). An exemple should make things
+   sufficiently clear
+
+           [/home/me/.recoll/xapiandb]
+           /this/directory/moved = /to/this/place
+
+           [/path/to/additional/xapiandb]
+           /server/volume1/docdir = /net/server/volume1/docdir
+           /server/volume2/docdir = /net/server/volume2/docdir
+        
+
+  5.4.8. Examples of configuration adjustments
+
+    5.4.8.1. Adding an external viewer for an non-indexed type
+
+   Imagine that you have some kind of file which does not have indexable
+   content, but for which you would like to have a functional Open link in
+   the result list (when found by file name). The file names end in .blob and
+   can be displayed by application blobviewer.
+
+   You need two entries in the configuration files for this to work:
+
+     o In $RECOLL_CONFDIR/mimemap (typically ~/.recoll/mimemap), add the
+       following line:
+
+ .blob = application/x-blobapp
+
+       Note that the MIME type is made up here, and you could call it
+       diesel/oil just the same.
+
+     o In $RECOLL_CONFDIR/mimeview under the [view] section, add:
+
+ application/x-blobapp = blobviewer %f
+
+       We are supposing that blobviewer wants a file name parameter here, you
+       would use %u if it liked URLs better.
+
+   If you just wanted to change the application used by Recoll to display a
+   MIME type which it already knows, you would just need to edit mimeview.
+   The entries you add in your personal file override those in the central
+   configuration, which you do not need to alter. mimeview can also be
+   modified from the Gui.
+
+    5.4.8.2. Adding indexing support for a new file type
+
+   Let us now imagine that the above .blob files actually contain indexable
+   text and that you know how to extract it with a command line program.
+   Getting Recoll to index the files is easy. You need to perform the above
+   alteration, and also to add data to the mimeconf file (typically in
+   ~/.recoll/mimeconf):
+
+     o Under the [index] section, add the following line (more about the
+       rclblob indexing script later):
+
+ application/x-blobapp = exec rclblob
+
+     o Under the [icons] section, you should choose an icon to be displayed
+       for the files inside the result lists. Icons are normally 64x64 pixels
+       PNG files which live in /usr/[local/]share/recoll/images.
+
+     o Under the [categories] section, you should add the MIME type where it
+       makes sense (you can also create a category). Categories may be used
+       for filtering in advanced search.
+
+   The rclblob handler should be an executable program or script which exists
+   inside /usr/[local/]share/recoll/filters. It will be given a file name as
+   argument and should output the text or html contents on the standard
+   output.
+
+   The filter programming section describes in more detail how to write an
+   input handler.
diff --git a/src/VERSION b/src/VERSION
new file mode 100644
index 00000000..a6c2798a
--- /dev/null
+++ b/src/VERSION
@@ -0,0 +1 @@
+1.23.0
diff --git a/src/aspell/Makefile b/src/aspell/Makefile
new file mode 100644
index 00000000..598acfca
--- /dev/null
+++ b/src/aspell/Makefile
@@ -0,0 +1,12 @@
+PROGS = rclaspell
+all: $(PROGS)
+
+RCLASPELL_OBJS= trrclaspell.o 
+rclaspell : $(RCLASPELL_OBJS)
+	$(CXX) $(ALL_CXXFLAGS) -o rclaspell $(RCLASPELL_OBJS) \
+          $(LIBRECOLL)
+trrclaspell.o : rclaspell.cpp
+	$(CXX) $(ALL_CXXFLAGS) -DTEST_RCLASPELL -c -o trrclaspell.o \
+	       rclaspell.cpp
+
+include ../utils/utmkdefs.mk
diff --git a/src/aspell/aspell-local.h b/src/aspell/aspell-local.h
new file mode 100644
index 00000000..421c9380
--- /dev/null
+++ b/src/aspell/aspell-local.h
@@ -0,0 +1,729 @@
+/* Automatically generated file.  Do not edit directly. */
+
+/* This file is part of The New Aspell
+ * Copyright (C) 2001-2002 by Kevin Atkinson under the GNU LGPL
+ * license version 2.0 or 2.1.  You should have received a copy of the
+ * LGPL license along with this library if you did not you can find it
+ * at http://www.gnu.org/.                                              */
+
+#ifndef ASPELL_ASPELL__H
+#define ASPELL_ASPELL__H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/******************************* type id *******************************/
+
+
+union AspellTypeId {
+
+  unsigned int num;
+
+  char str[4];
+
+};
+
+
+typedef union AspellTypeId AspellTypeId;
+
+
+/************************** mutable container **************************/
+
+
+typedef struct AspellMutableContainer AspellMutableContainer;
+
+
+int aspell_mutable_container_add(struct AspellMutableContainer * ths, const char * to_add);
+
+int aspell_mutable_container_remove(struct AspellMutableContainer * ths, const char * to_rem);
+
+void aspell_mutable_container_clear(struct AspellMutableContainer * ths);
+
+struct AspellMutableContainer * aspell_mutable_container_to_mutable_container(struct AspellMutableContainer * ths);
+
+
+
+/******************************* key info *******************************/
+
+
+
+enum AspellKeyInfoType {AspellKeyInfoString, AspellKeyInfoInt, AspellKeyInfoBool, AspellKeyInfoList};
+typedef enum AspellKeyInfoType AspellKeyInfoType;
+
+
+struct AspellKeyInfo {
+
+  /* The name of the key. */
+  const char * name;
+
+  /* The key type. */
+  enum AspellKeyInfoType type;
+
+  /* The default value of the key. */
+  const char * def;
+
+  /* A brief description of the key or NULL if internal value. */
+  const char * desc;
+
+  int flags;
+
+  int other_data;
+
+};
+
+
+typedef struct AspellKeyInfo AspellKeyInfo;
+
+
+/******************************** config ********************************/
+
+
+typedef struct AspellKeyInfoEnumeration AspellKeyInfoEnumeration;
+
+
+int aspell_key_info_enumeration_at_end(const struct AspellKeyInfoEnumeration * ths);
+
+const struct AspellKeyInfo * aspell_key_info_enumeration_next(struct AspellKeyInfoEnumeration * ths);
+
+void delete_aspell_key_info_enumeration(struct AspellKeyInfoEnumeration * ths);
+
+struct AspellKeyInfoEnumeration * aspell_key_info_enumeration_clone(const struct AspellKeyInfoEnumeration * ths);
+
+void aspell_key_info_enumeration_assign(struct AspellKeyInfoEnumeration * ths, const struct AspellKeyInfoEnumeration * other);
+
+
+
+typedef struct AspellConfig AspellConfig;
+
+
+struct AspellConfig * new_aspell_config();
+
+void delete_aspell_config(struct AspellConfig * ths);
+
+struct AspellConfig * aspell_config_clone(const struct AspellConfig * ths);
+
+void aspell_config_assign(struct AspellConfig * ths, const struct AspellConfig * other);
+
+unsigned int aspell_config_error_number(const struct AspellConfig * ths);
+
+const char * aspell_config_error_message(const struct AspellConfig * ths);
+
+const struct AspellError * aspell_config_error(const struct AspellConfig * ths);
+
+/* Sets extra keys which this config class should
+ * accept. begin and end are expected to point to
+ * the beginning and ending of an array of Aspell
+ * Key Info. */
+void aspell_config_set_extra(struct AspellConfig * ths, const struct AspellKeyInfo * begin, const struct AspellKeyInfo * end);
+
+/* Returns the KeyInfo object for the
+ * corresponding key or returns NULL and sets
+ * error_num to PERROR_UNKNOWN_KEY if the key is
+ * not valid. The pointer returned is valid for
+ * the lifetime of the object. */
+const struct AspellKeyInfo * aspell_config_keyinfo(struct AspellConfig * ths, const char * key);
+
+/* Returns a newly allocated enumeration of all
+ * the possible objects this config class uses. */
+struct AspellKeyInfoEnumeration * aspell_config_possible_elements(struct AspellConfig * ths, int include_extra);
+
+/* Returns the default value for given key which
+ * may involve substituting variables, thus it is
+ * not the same as keyinfo(key)->def returns NULL
+ * and sets error_num to PERROR_UNKNOWN_KEY if
+ * the key is not valid. Uses the temporary
+ * string. */
+const char * aspell_config_get_default(struct AspellConfig * ths, const char * key);
+
+/* Returns a newly allocated enumeration of all
+ * the key/value pairs. This DOES not include ones
+ * which are set to their default values. */
+struct AspellStringPairEnumeration * aspell_config_elements(struct AspellConfig * ths);
+
+/* Inserts an item, if the item already exists it
+ * will be replaced. Returns TRUE if it succeeded
+ * or FALSE on error. If the key in not valid it
+ * sets error_num to PERROR_UNKNOWN_KEY, if the
+ * value is not valid it will set error_num to
+ * PERROR_BAD_VALUE, if the value can not be
+ * changed it sets error_num to
+ * PERROR_CANT_CHANGE_VALUE, and if the value is
+ * a list and you are trying to set its directory,
+ * it sets error_num to PERROR_LIST_SET */
+int aspell_config_replace(struct AspellConfig * ths, const char * key, const char * value);
+
+/* Remove a key and returns TRUE if it exists
+ * otherwise return FALSE. This effectively sets
+ * the key to its default value. Calling replace
+ * with a value of "" will also call
+ * remove. If the key does not exist then it sets
+ * error_num to 0 or PERROR_NOT, if the key is
+ * not valid then it sets error_num to
+ * PERROR_UNKNOWN_KEY, if the value can not be
+ * changed then it sets error_num to
+ * PERROR_CANT_CHANGE_VALUE */
+int aspell_config_remove(struct AspellConfig * ths, const char * key);
+
+int aspell_config_have(const struct AspellConfig * ths, const char * key);
+
+/* Returns NULL on error. */
+const char * aspell_config_retrieve(struct AspellConfig * ths, const char * key);
+
+int aspell_config_retrieve_list(struct AspellConfig * ths, const char * key, struct AspellMutableContainer * lst);
+
+/* Return -1 on error, 0 if false, 1 if true. */
+int aspell_config_retrieve_bool(struct AspellConfig * ths, const char * key);
+
+/* Return -1 on error. */
+int aspell_config_retrieve_int(struct AspellConfig * ths, const char * key);
+
+
+
+/******************************** error ********************************/
+
+
+struct AspellError {
+
+  const char * mesg;
+
+  const struct AspellErrorInfo * err;
+
+};
+
+
+typedef struct AspellError AspellError;
+
+int aspell_error_is_a(const struct AspellError * ths, const struct AspellErrorInfo * e);
+
+
+struct AspellErrorInfo {
+
+  const struct AspellErrorInfo * isa;
+
+  const char * mesg;
+
+  unsigned int num_parms;
+
+  const char * parms[3];
+
+};
+
+
+typedef struct AspellErrorInfo AspellErrorInfo;
+
+
+/**************************** can have error ****************************/
+
+
+typedef struct AspellCanHaveError AspellCanHaveError;
+
+
+unsigned int aspell_error_number(const struct AspellCanHaveError * ths);
+
+const char * aspell_error_message(const struct AspellCanHaveError * ths);
+
+const struct AspellError * aspell_error(const struct AspellCanHaveError * ths);
+
+void delete_aspell_can_have_error(struct AspellCanHaveError * ths);
+
+
+
+/******************************** errors ********************************/
+
+
+extern const struct AspellErrorInfo * const aerror_other;
+extern const struct AspellErrorInfo * const aerror_operation_not_supported;
+extern const struct AspellErrorInfo * const   aerror_cant_copy;
+extern const struct AspellErrorInfo * const   aerror_unimplemented_method;
+extern const struct AspellErrorInfo * const aerror_file;
+extern const struct AspellErrorInfo * const   aerror_cant_open_file;
+extern const struct AspellErrorInfo * const     aerror_cant_read_file;
+extern const struct AspellErrorInfo * const     aerror_cant_write_file;
+extern const struct AspellErrorInfo * const   aerror_invalid_name;
+extern const struct AspellErrorInfo * const   aerror_bad_file_format;
+extern const struct AspellErrorInfo * const aerror_dir;
+extern const struct AspellErrorInfo * const   aerror_cant_read_dir;
+extern const struct AspellErrorInfo * const aerror_config;
+extern const struct AspellErrorInfo * const   aerror_unknown_key;
+extern const struct AspellErrorInfo * const   aerror_cant_change_value;
+extern const struct AspellErrorInfo * const   aerror_bad_key;
+extern const struct AspellErrorInfo * const   aerror_bad_value;
+extern const struct AspellErrorInfo * const   aerror_duplicate;
+extern const struct AspellErrorInfo * const   aerror_key_not_string;
+extern const struct AspellErrorInfo * const   aerror_key_not_int;
+extern const struct AspellErrorInfo * const   aerror_key_not_bool;
+extern const struct AspellErrorInfo * const   aerror_key_not_list;
+extern const struct AspellErrorInfo * const   aerror_no_value_reset;
+extern const struct AspellErrorInfo * const   aerror_no_value_enable;
+extern const struct AspellErrorInfo * const   aerror_no_value_disable;
+extern const struct AspellErrorInfo * const   aerror_no_value_clear;
+extern const struct AspellErrorInfo * const aerror_language_related;
+extern const struct AspellErrorInfo * const   aerror_unknown_language;
+extern const struct AspellErrorInfo * const   aerror_unknown_soundslike;
+extern const struct AspellErrorInfo * const   aerror_language_not_supported;
+extern const struct AspellErrorInfo * const   aerror_no_wordlist_for_lang;
+extern const struct AspellErrorInfo * const   aerror_mismatched_language;
+extern const struct AspellErrorInfo * const aerror_affix;
+extern const struct AspellErrorInfo * const   aerror_corrupt_affix;
+extern const struct AspellErrorInfo * const   aerror_invalid_cond;
+extern const struct AspellErrorInfo * const   aerror_invalid_cond_strip;
+extern const struct AspellErrorInfo * const   aerror_incorrect_encoding;
+extern const struct AspellErrorInfo * const aerror_encoding;
+extern const struct AspellErrorInfo * const   aerror_unknown_encoding;
+extern const struct AspellErrorInfo * const   aerror_encoding_not_supported;
+extern const struct AspellErrorInfo * const   aerror_conversion_not_supported;
+extern const struct AspellErrorInfo * const aerror_pipe;
+extern const struct AspellErrorInfo * const   aerror_cant_create_pipe;
+extern const struct AspellErrorInfo * const   aerror_process_died;
+extern const struct AspellErrorInfo * const aerror_bad_input;
+extern const struct AspellErrorInfo * const   aerror_invalid_string;
+extern const struct AspellErrorInfo * const   aerror_invalid_word;
+extern const struct AspellErrorInfo * const   aerror_invalid_affix;
+extern const struct AspellErrorInfo * const   aerror_inapplicable_affix;
+extern const struct AspellErrorInfo * const   aerror_unknown_unichar;
+extern const struct AspellErrorInfo * const   aerror_word_list_flags;
+extern const struct AspellErrorInfo * const     aerror_invalid_flag;
+extern const struct AspellErrorInfo * const     aerror_conflicting_flags;
+extern const struct AspellErrorInfo * const aerror_version_control;
+extern const struct AspellErrorInfo * const   aerror_bad_version_string;
+extern const struct AspellErrorInfo * const aerror_filter;
+extern const struct AspellErrorInfo * const   aerror_cant_dlopen_file;
+extern const struct AspellErrorInfo * const   aerror_empty_filter;
+extern const struct AspellErrorInfo * const   aerror_no_such_filter;
+extern const struct AspellErrorInfo * const   aerror_confusing_version;
+extern const struct AspellErrorInfo * const   aerror_bad_version;
+extern const struct AspellErrorInfo * const   aerror_identical_option;
+extern const struct AspellErrorInfo * const   aerror_options_only;
+extern const struct AspellErrorInfo * const   aerror_invalid_option_modifier;
+extern const struct AspellErrorInfo * const   aerror_cant_describe_filter;
+extern const struct AspellErrorInfo * const aerror_filter_mode_file;
+extern const struct AspellErrorInfo * const   aerror_mode_option_name;
+extern const struct AspellErrorInfo * const   aerror_no_filter_to_option;
+extern const struct AspellErrorInfo * const   aerror_bad_mode_key;
+extern const struct AspellErrorInfo * const   aerror_expect_mode_key;
+extern const struct AspellErrorInfo * const   aerror_mode_version_requirement;
+extern const struct AspellErrorInfo * const   aerror_confusing_mode_version;
+extern const struct AspellErrorInfo * const   aerror_bad_mode_version;
+extern const struct AspellErrorInfo * const   aerror_missing_magic_expression;
+extern const struct AspellErrorInfo * const   aerror_empty_file_ext;
+extern const struct AspellErrorInfo * const aerror_filter_mode_expand;
+extern const struct AspellErrorInfo * const   aerror_unknown_mode;
+extern const struct AspellErrorInfo * const   aerror_mode_extend_expand;
+extern const struct AspellErrorInfo * const aerror_filter_mode_magic;
+extern const struct AspellErrorInfo * const   aerror_file_magic_pos;
+extern const struct AspellErrorInfo * const   aerror_file_magic_range;
+extern const struct AspellErrorInfo * const   aerror_missing_magic;
+extern const struct AspellErrorInfo * const   aerror_bad_magic;
+extern const struct AspellErrorInfo * const aerror_expression;
+extern const struct AspellErrorInfo * const   aerror_invalid_expression;
+
+
+/******************************* speller *******************************/
+
+
+typedef struct AspellSpeller AspellSpeller;
+
+
+struct AspellCanHaveError * new_aspell_speller(struct AspellConfig * config);
+
+struct AspellSpeller * to_aspell_speller(struct AspellCanHaveError * obj);
+
+void delete_aspell_speller(struct AspellSpeller * ths);
+
+unsigned int aspell_speller_error_number(const struct AspellSpeller * ths);
+
+const char * aspell_speller_error_message(const struct AspellSpeller * ths);
+
+const struct AspellError * aspell_speller_error(const struct AspellSpeller * ths);
+
+struct AspellConfig * aspell_speller_config(struct AspellSpeller * ths);
+
+/* Returns 0 if it is not in the dictionary,
+ * 1 if it is, or -1 on error. */
+int aspell_speller_check(struct AspellSpeller * ths, const char * word, int word_size);
+
+/* Add this word to your own personal word list. */
+int aspell_speller_add_to_personal(struct AspellSpeller * ths, const char * word, int word_size);
+
+/* Add this word to the current spelling session. */
+int aspell_speller_add_to_session(struct AspellSpeller * ths, const char * word, int word_size);
+
+/* This is your own personal word list file plus
+ * any extra words added during this session to
+ * your own personal word list. */
+const struct AspellWordList * aspell_speller_personal_word_list(struct AspellSpeller * ths);
+
+/* This is a list of words added to this session
+ * that are not in the main word list or in your
+ * own personal list but are considered valid for
+ * this spelling session. */
+const struct AspellWordList * aspell_speller_session_word_list(struct AspellSpeller * ths);
+
+/* This is the main list of words used during this
+ * spelling session. */
+const struct AspellWordList * aspell_speller_main_word_list(struct AspellSpeller * ths);
+
+int aspell_speller_save_all_word_lists(struct AspellSpeller * ths);
+
+int aspell_speller_clear_session(struct AspellSpeller * ths);
+
+/* Return NULL on error.
+ * The word list returned by suggest is only
+ * valid until the next call to suggest. */
+const struct AspellWordList * aspell_speller_suggest(struct AspellSpeller * ths, const char * word, int word_size);
+
+int aspell_speller_store_replacement(struct AspellSpeller * ths, const char * mis, int mis_size, const char * cor, int cor_size);
+
+
+
+/******************************** filter ********************************/
+
+
+typedef struct AspellFilter AspellFilter;
+
+
+void delete_aspell_filter(struct AspellFilter * ths);
+
+unsigned int aspell_filter_error_number(const struct AspellFilter * ths);
+
+const char * aspell_filter_error_message(const struct AspellFilter * ths);
+
+const struct AspellError * aspell_filter_error(const struct AspellFilter * ths);
+
+struct AspellFilter * to_aspell_filter(struct AspellCanHaveError * obj);
+
+
+
+/*************************** document checker ***************************/
+
+
+struct AspellToken {
+
+  unsigned int offset;
+
+  unsigned int len;
+
+};
+
+
+typedef struct AspellToken AspellToken;
+
+
+typedef struct AspellDocumentChecker AspellDocumentChecker;
+
+
+void delete_aspell_document_checker(struct AspellDocumentChecker * ths);
+
+unsigned int aspell_document_checker_error_number(const struct AspellDocumentChecker * ths);
+
+const char * aspell_document_checker_error_message(const struct AspellDocumentChecker * ths);
+
+const struct AspellError * aspell_document_checker_error(const struct AspellDocumentChecker * ths);
+
+/* Creates a new document checker.
+ * The speller class is expected to last until
+ * this class is destroyed.
+ * If config is given it will be used to override
+ * any relevent options set by this speller class.
+ * The config class is not once this function is done.
+ * If filter is given then it will take ownership of
+ * the filter class and use it to do the filtering.
+ * You are expected to free the checker when done. */
+struct AspellCanHaveError * new_aspell_document_checker(struct AspellSpeller * speller);
+
+struct AspellDocumentChecker * to_aspell_document_checker(struct AspellCanHaveError * obj);
+
+/* Reset the internal state of the filter.
+ * Should be called whenever a new document is
+ * being filtered. */
+void aspell_document_checker_reset(struct AspellDocumentChecker * ths);
+
+/* Process a string.
+ * The string passed in should only be split on
+ * white space characters.  Furthermore, between
+ * calls to reset, each string should be passed
+ * in exactly once and in the order they appeared
+ * in the document.  Passing in strings out of
+ * order, skipping strings or passing them in
+ * more than once may lead to undefined results. */
+void aspell_document_checker_process(struct AspellDocumentChecker * ths, const char * str, int size);
+
+/* Returns the next misspelled word in the
+ * processed string.  If there are no more
+ * misspelled words, then token.word will be
+ * NULL and token.size will be 0 */
+struct AspellToken aspell_document_checker_next_misspelling(struct AspellDocumentChecker * ths);
+
+/* Returns the underlying filter class. */
+struct AspellFilter * aspell_document_checker_filter(struct AspellDocumentChecker * ths);
+
+
+
+/****************************** word list ******************************/
+
+
+typedef struct AspellWordList AspellWordList;
+
+
+int aspell_word_list_empty(const struct AspellWordList * ths);
+
+unsigned int aspell_word_list_size(const struct AspellWordList * ths);
+
+struct AspellStringEnumeration * aspell_word_list_elements(const struct AspellWordList * ths);
+
+
+
+/************************** string enumeration **************************/
+
+
+typedef struct AspellStringEnumeration AspellStringEnumeration;
+
+
+void delete_aspell_string_enumeration(struct AspellStringEnumeration * ths);
+
+struct AspellStringEnumeration * aspell_string_enumeration_clone(const struct AspellStringEnumeration * ths);
+
+void aspell_string_enumeration_assign(struct AspellStringEnumeration * ths, const struct AspellStringEnumeration * other);
+
+int aspell_string_enumeration_at_end(const struct AspellStringEnumeration * ths);
+
+const char * aspell_string_enumeration_next(struct AspellStringEnumeration * ths);
+
+
+
+/********************************* info *********************************/
+
+
+struct AspellModuleInfo {
+
+  const char * name;
+
+  double order_num;
+
+  const char * lib_dir;
+
+  struct AspellStringList * dict_dirs;
+
+  struct AspellStringList * dict_exts;
+
+};
+
+
+typedef struct AspellModuleInfo AspellModuleInfo;
+
+
+struct AspellDictInfo {
+
+  /* The Name to identify this dictionary by. */
+  const char * name;
+
+  /* The language code to identify this dictionary.
+   * A two letter UPPER-CASE ISO 639 language code
+   * and an optional two letter ISO 3166 country
+   * code after a dash or underscore. */
+  const char * code;
+
+  /* Any extra information to distinguish this
+   * variety of dictionary from other dictionaries
+   * which may have the same language and size. */
+  const char * jargon;
+
+  int size;
+
+  /* A two char digit code describing the size of
+   * the dictionary: 10=tiny, 20=really small,
+   * 30=small, 40=med-small, 50=med, 60=med-large,
+   * 70=large, 80=huge, 90=insane.  Please check
+   * the README in aspell-lang-200?????.tar.bz2 or
+   * see SCOWL (http://wordlist.sourceforge.net)
+   * for an example of how these sizes are used. */
+  const char * size_str;
+
+  struct AspellModuleInfo * module;
+
+};
+
+
+typedef struct AspellDictInfo AspellDictInfo;
+
+
+typedef struct AspellModuleInfoList AspellModuleInfoList;
+
+
+struct AspellModuleInfoList * get_aspell_module_info_list(struct AspellConfig * config);
+
+int aspell_module_info_list_empty(const struct AspellModuleInfoList * ths);
+
+unsigned int aspell_module_info_list_size(const struct AspellModuleInfoList * ths);
+
+struct AspellModuleInfoEnumeration * aspell_module_info_list_elements(const struct AspellModuleInfoList * ths);
+
+
+
+typedef struct AspellDictInfoList AspellDictInfoList;
+
+
+struct AspellDictInfoList * get_aspell_dict_info_list(struct AspellConfig * config);
+
+int aspell_dict_info_list_empty(const struct AspellDictInfoList * ths);
+
+unsigned int aspell_dict_info_list_size(const struct AspellDictInfoList * ths);
+
+struct AspellDictInfoEnumeration * aspell_dict_info_list_elements(const struct AspellDictInfoList * ths);
+
+
+
+typedef struct AspellModuleInfoEnumeration AspellModuleInfoEnumeration;
+
+
+int aspell_module_info_enumeration_at_end(const struct AspellModuleInfoEnumeration * ths);
+
+const struct AspellModuleInfo * aspell_module_info_enumeration_next(struct AspellModuleInfoEnumeration * ths);
+
+void delete_aspell_module_info_enumeration(struct AspellModuleInfoEnumeration * ths);
+
+struct AspellModuleInfoEnumeration * aspell_module_info_enumeration_clone(const struct AspellModuleInfoEnumeration * ths);
+
+void aspell_module_info_enumeration_assign(struct AspellModuleInfoEnumeration * ths, const struct AspellModuleInfoEnumeration * other);
+
+
+
+typedef struct AspellDictInfoEnumeration AspellDictInfoEnumeration;
+
+
+int aspell_dict_info_enumeration_at_end(const struct AspellDictInfoEnumeration * ths);
+
+const struct AspellDictInfo * aspell_dict_info_enumeration_next(struct AspellDictInfoEnumeration * ths);
+
+void delete_aspell_dict_info_enumeration(struct AspellDictInfoEnumeration * ths);
+
+struct AspellDictInfoEnumeration * aspell_dict_info_enumeration_clone(const struct AspellDictInfoEnumeration * ths);
+
+void aspell_dict_info_enumeration_assign(struct AspellDictInfoEnumeration * ths, const struct AspellDictInfoEnumeration * other);
+
+
+
+/***************************** string list *****************************/
+
+
+typedef struct AspellStringList AspellStringList;
+
+
+struct AspellStringList * new_aspell_string_list();
+
+int aspell_string_list_empty(const struct AspellStringList * ths);
+
+unsigned int aspell_string_list_size(const struct AspellStringList * ths);
+
+struct AspellStringEnumeration * aspell_string_list_elements(const struct AspellStringList * ths);
+
+int aspell_string_list_add(struct AspellStringList * ths, const char * to_add);
+
+int aspell_string_list_remove(struct AspellStringList * ths, const char * to_rem);
+
+void aspell_string_list_clear(struct AspellStringList * ths);
+
+struct AspellMutableContainer * aspell_string_list_to_mutable_container(struct AspellStringList * ths);
+
+void delete_aspell_string_list(struct AspellStringList * ths);
+
+struct AspellStringList * aspell_string_list_clone(const struct AspellStringList * ths);
+
+void aspell_string_list_assign(struct AspellStringList * ths, const struct AspellStringList * other);
+
+
+
+/****************************** string map ******************************/
+
+
+typedef struct AspellStringMap AspellStringMap;
+
+
+struct AspellStringMap * new_aspell_string_map();
+
+int aspell_string_map_add(struct AspellStringMap * ths, const char * to_add);
+
+int aspell_string_map_remove(struct AspellStringMap * ths, const char * to_rem);
+
+void aspell_string_map_clear(struct AspellStringMap * ths);
+
+struct AspellMutableContainer * aspell_string_map_to_mutable_container(struct AspellStringMap * ths);
+
+void delete_aspell_string_map(struct AspellStringMap * ths);
+
+struct AspellStringMap * aspell_string_map_clone(const struct AspellStringMap * ths);
+
+void aspell_string_map_assign(struct AspellStringMap * ths, const struct AspellStringMap * other);
+
+int aspell_string_map_empty(const struct AspellStringMap * ths);
+
+unsigned int aspell_string_map_size(const struct AspellStringMap * ths);
+
+struct AspellStringPairEnumeration * aspell_string_map_elements(const struct AspellStringMap * ths);
+
+/* Insert a new element.
+ * Will NOT overwrite an existing entry.
+ * Returns FALSE if the element already exists. */
+int aspell_string_map_insert(struct AspellStringMap * ths, const char * key, const char * value);
+
+/* Insert a new element.
+ * Will overwrite an existing entry.
+ * Always returns TRUE. */
+int aspell_string_map_replace(struct AspellStringMap * ths, const char * key, const char * value);
+
+/* Looks up an element and returns the value.
+ * Returns NULL if the element does not exist.
+ * Returns an empty string if the element exists
+ * but has a NULL value. */
+const char * aspell_string_map_lookup(const struct AspellStringMap * ths, const char * key);
+
+
+
+/***************************** string pair *****************************/
+
+
+struct AspellStringPair {
+
+  const char * first;
+
+  const char * second;
+
+};
+
+
+typedef struct AspellStringPair AspellStringPair;
+
+
+/*********************** string pair enumeration ***********************/
+
+
+typedef struct AspellStringPairEnumeration AspellStringPairEnumeration;
+
+
+int aspell_string_pair_enumeration_at_end(const struct AspellStringPairEnumeration * ths);
+
+struct AspellStringPair aspell_string_pair_enumeration_next(struct AspellStringPairEnumeration * ths);
+
+void delete_aspell_string_pair_enumeration(struct AspellStringPairEnumeration * ths);
+
+struct AspellStringPairEnumeration * aspell_string_pair_enumeration_clone(const struct AspellStringPairEnumeration * ths);
+
+void aspell_string_pair_enumeration_assign(struct AspellStringPairEnumeration * ths, const struct AspellStringPairEnumeration * other);
+
+
+
+/******************************** cache ********************************/
+
+
+/* Reset the global cache(s) so that cache queries will
+ * create a new object. If existing objects are still in
+ * use they are not deleted. If which is NULL then all
+ * caches will be reset. Current caches are "encode",
+ * "decode", "dictionary", "language", and "keyboard". */
+int aspell_reset_cache(const char * which);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* ASPELL_ASPELL__H */
diff --git a/src/aspell/rclaspell.cpp b/src/aspell/rclaspell.cpp
new file mode 100644
index 00000000..297fa75e
--- /dev/null
+++ b/src/aspell/rclaspell.cpp
@@ -0,0 +1,588 @@
+#ifndef TEST_RCLASPELL
+/* Copyright (C) 2006 J.F.Dockes
+ *   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.
+ */
+#ifdef HAVE_CONFIG_H
+#include "autoconfig.h"
+#endif
+
+#ifdef RCL_USE_ASPELL
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include ASPELL_INCLUDE
+
+#include "pathut.h"
+#include "execmd.h"
+#include "rclaspell.h"
+#include "log.h"
+#include "unacpp.h"
+
+using namespace std;
+
+// Just a place where we keep the Aspell library entry points together
+class AspellApi {
+public:
+    struct AspellConfig *(*new_aspell_config)();
+    int (*aspell_config_replace)(struct AspellConfig *, const char * key, 
+				 const char * value);
+    struct AspellCanHaveError *(*new_aspell_speller)(struct AspellConfig *);
+    void (*delete_aspell_config)(struct AspellConfig *);
+    void (*delete_aspell_can_have_error)(struct AspellCanHaveError *);
+    struct AspellSpeller * (*to_aspell_speller)(struct AspellCanHaveError *);
+    struct AspellConfig * (*aspell_speller_config)(struct AspellSpeller *);
+    const struct AspellWordList * (*aspell_speller_suggest)
+	(struct AspellSpeller *, const char *, int);
+    int (*aspell_speller_check)(struct AspellSpeller *, const char *, int);
+    struct AspellStringEnumeration * (*aspell_word_list_elements)
+	(const struct AspellWordList * ths);
+    const char * (*aspell_string_enumeration_next)
+	(struct AspellStringEnumeration * ths);
+    void (*delete_aspell_string_enumeration)(struct AspellStringEnumeration *);
+    const struct AspellError *(*aspell_error)
+	(const struct AspellCanHaveError *);
+    const char *(*aspell_error_message)(const struct AspellCanHaveError *);
+    const char *(*aspell_speller_error_message)(const struct AspellSpeller *);
+    void (*delete_aspell_speller)(struct AspellSpeller *);
+
+};
+static AspellApi aapi;
+static std::mutex o_aapi_mutex;
+
+#define NMTOPTR(NM, TP)							\
+    if ((aapi.NM = TP dlsym(m_data->m_handle, #NM)) == 0) {		\
+	badnames += #NM + string(" ");					\
+    }
+
+static const char *aspell_lib_suffixes[] = {
+  ".so",
+  ".so.15",
+  ".so.16"
+};
+static const unsigned int nlibsuffs  = sizeof(aspell_lib_suffixes) / sizeof(char *);
+
+// Stuff that we don't wish to see in the .h (possible sysdeps, etc.)
+class AspellData {
+public:
+    AspellData() 
+        : m_handle(0), m_speller(0) 
+    {}
+    ~AspellData() {
+        LOGDEB2("~AspellData\n" );
+	if (m_handle) {
+	    dlclose(m_handle);
+            m_handle = 0;
+        }
+        if (m_speller) {
+            // Dumps core if I do this?? 
+            //aapi.delete_aspell_speller(m_speller);
+            m_speller = 0;
+            LOGDEB2("~AspellData: speller done\n" );
+        }
+    }
+
+    void  *m_handle;
+    string m_exec;
+    AspellSpeller *m_speller;    
+};
+
+Aspell::Aspell(RclConfig *cnf)
+    : m_config(cnf), m_data(0) 
+{
+}
+
+Aspell::~Aspell()
+{
+    deleteZ(m_data);
+}
+
+bool Aspell::init(string &reason)
+{
+    std::unique_lock locker(o_aapi_mutex);
+    deleteZ(m_data);
+
+    // Language: we get this from the configuration, else from the NLS
+    // environment. The aspell language names used for selecting language 
+    // definition files (used to create dictionaries) are like en, fr
+    if (!m_config->getConfParam("aspellLanguage", m_lang) || m_lang.empty()) {
+	string lang = "en";
+	const char *cp;
+	if ((cp = getenv("LC_ALL")))
+	    lang = cp;
+	else if ((cp = getenv("LANG")))
+	    lang = cp;
+	if (!lang.compare("C"))
+	    lang = "en";
+	m_lang = lang.substr(0, lang.find_first_of("_"));
+    }
+
+    m_data = new AspellData;
+
+    const char *aspell_prog_from_env = getenv("ASPELL_PROG");
+    if (aspell_prog_from_env && access(aspell_prog_from_env, X_OK) == 0) {
+	m_data->m_exec = aspell_prog_from_env;
+#ifdef ASPELL_PROG
+    } else if (access(ASPELL_PROG, X_OK) == 0) {
+	m_data->m_exec = ASPELL_PROG;
+#endif // ASPELL_PROG
+    } else {
+	ExecCmd::which("aspell", m_data->m_exec);
+    }
+
+    if (m_data->m_exec.empty()) {
+	reason = "aspell program not found or not executable";
+        deleteZ(m_data);
+	return false;
+    }
+
+    reason = "Could not open shared library ";
+    string libbase("libaspell");
+    string lib;
+    for (unsigned int i = 0; i < nlibsuffs; i++) {
+        lib = libbase + aspell_lib_suffixes[i];
+        reason += string("[") + lib + "] ";
+        if ((m_data->m_handle = dlopen(lib.c_str(), RTLD_LAZY)) != 0) {
+            reason.erase();
+            goto found;
+        }
+    }
+    
+ found:
+    if (m_data->m_handle == 0) {
+        reason += string(" : ") + dlerror();
+        deleteZ(m_data);
+        return false;
+    }
+
+    string badnames;
+    NMTOPTR(new_aspell_config, (struct AspellConfig *(*)()));
+    NMTOPTR(aspell_config_replace, (int (*)(struct AspellConfig *, 
+					    const char *, const char *)));
+    NMTOPTR(new_aspell_speller, 
+	    (struct AspellCanHaveError *(*)(struct AspellConfig *)));
+    NMTOPTR(delete_aspell_config, 
+	    (void (*)(struct AspellConfig *)));
+    NMTOPTR(delete_aspell_can_have_error, 
+	    (void (*)(struct AspellCanHaveError *)));
+    NMTOPTR(to_aspell_speller, 
+	    (struct AspellSpeller *(*)(struct AspellCanHaveError *)));
+    NMTOPTR(aspell_speller_config, 
+	    (struct AspellConfig *(*)(struct AspellSpeller *)));
+    NMTOPTR(aspell_speller_suggest, 
+	    (const struct AspellWordList *(*)(struct AspellSpeller *, 
+					       const char *, int)));
+    NMTOPTR(aspell_speller_check, 
+	    (int (*)(struct AspellSpeller *, const char *, int)));
+    NMTOPTR(aspell_word_list_elements, 
+	    (struct AspellStringEnumeration *(*)
+	     (const struct AspellWordList *)));
+    NMTOPTR(aspell_string_enumeration_next, 
+	    (const char * (*)(struct AspellStringEnumeration *)));
+    NMTOPTR(delete_aspell_string_enumeration, 
+	    (void (*)(struct AspellStringEnumeration *)));
+    NMTOPTR(aspell_error, 
+	    (const struct AspellError*(*)(const struct AspellCanHaveError *)));
+    NMTOPTR(aspell_error_message,
+	    (const char *(*)(const struct AspellCanHaveError *)));
+    NMTOPTR(aspell_speller_error_message, 
+	    (const char *(*)(const struct AspellSpeller *)));
+    NMTOPTR(delete_aspell_speller, (void (*)(struct AspellSpeller *)));
+
+    if (!badnames.empty()) {
+	reason = string("Aspell::init: symbols not found:") + badnames;
+        deleteZ(m_data);
+	return false;
+    }
+
+    return true;
+}
+
+bool Aspell::ok() const
+{
+    return m_data != 0 && m_data->m_handle != 0;
+}
+
+string Aspell::dicPath()
+{
+    string ccdir = m_config->getAspellcacheDir();
+    return path_cat(ccdir, string("aspdict.") + m_lang + string(".rws"));
+}
+
+
+// The data source for the create dictionary aspell command. We walk
+// the term list, filtering out things that are probably not words.
+// Note that the manual for the current version (0.60) of aspell
+// states that utf-8 is not well supported, so that we should maybe
+// also filter all 8bit chars.
+class AspExecPv : public ExecCmdProvide {
+public:
+    string *m_input; // pointer to string used as input buffer to command
+    Rcl::TermIter *m_tit;
+    Rcl::Db &m_db;
+    AspExecPv(string *i, Rcl::TermIter *tit, Rcl::Db &db) 
+	: m_input(i), m_tit(tit), m_db(db)
+    {}
+    void newData() {
+	while (m_db.termWalkNext(m_tit, *m_input)) {
+	    LOGDEB2("Aspell::buildDict: term: ["  << (m_input) << "]\n" );
+	    if (!Rcl::Db::isSpellingCandidate(*m_input)) {
+		LOGDEB2("Aspell::buildDict: SKIP\n" );
+		continue;
+	    }
+	    if (!o_index_stripchars) {
+		string lower;
+		if (!unacmaybefold(*m_input, lower, "UTF-8", UNACOP_FOLD))
+		    continue;
+		m_input->swap(lower);
+	    }
+	    // Got a non-empty sort-of appropriate term, let's send it to
+	    // aspell
+	    LOGDEB2("Apell::buildDict: SEND\n" );
+	    m_input->append("\n");
+	    return;
+	}
+	// End of data. Tell so. Exec will close cmd.
+	m_input->erase();
+    }
+};
+
+
+bool Aspell::buildDict(Rcl::Db &db, string &reason)
+{
+    if (!ok())
+	return false;
+
+    string addCreateParam;
+    m_config->getConfParam("aspellAddCreateParam", addCreateParam);
+
+    // We create the dictionary by executing the aspell command:
+    // aspell --lang=[lang] create master [dictApath]
+    string cmdstring(m_data->m_exec);
+    ExecCmd aspell;
+    vector args;
+    args.push_back(string("--lang=")+ m_lang);
+    cmdstring += string(" ") + string("--lang=") + m_lang;
+    args.push_back("--encoding=utf-8");
+    cmdstring += string(" ") + "--encoding=utf-8";
+    if (!addCreateParam.empty()) {
+	args.push_back(addCreateParam);
+	cmdstring += string(" ") + addCreateParam;
+    }
+    args.push_back("create");
+    cmdstring += string(" ") + "create";
+    args.push_back("master");
+    cmdstring += string(" ") + "master";
+    args.push_back(dicPath());
+    cmdstring += string(" ") + dicPath();
+
+    // Have to disable stderr, as numerous messages about bad strings are
+    // printed. We'd like to keep errors about missing databases though, so
+    // make it configurable for diags
+    bool keepStderr = false;
+    m_config->getConfParam("aspellKeepStderr", &keepStderr);
+    if (!keepStderr)
+	aspell.setStderr("/dev/null");
+
+    Rcl::TermIter *tit = db.termWalkOpen();
+    if (tit == 0) {
+	reason = "termWalkOpen failed\n";
+	return false;
+    }
+    string termbuf;
+    AspExecPv pv(&termbuf, tit, db);
+    aspell.setProvide(&pv);
+    
+    if (aspell.doexec(m_data->m_exec, args, &termbuf)) {
+	ExecCmd cmd;
+	args.clear();
+	args.push_back("dicts");
+	string dicts;
+	bool hasdict = false;
+	if (cmd.doexec(m_data->m_exec, args, 0, &dicts)) {
+	    vector vdicts;
+	    stringToTokens(dicts, vdicts, "\n\r\t ");
+	    if (find(vdicts.begin(), vdicts.end(), m_lang) != vdicts.end()) {
+		hasdict = true;
+	    }
+	}
+	if (hasdict)
+	    reason = string(
+		"\naspell dictionary creation command [") +
+                cmdstring + string("] failed. Reason unknown.\n"
+		"Try to set aspellKeepStderr = 1 in recoll.conf, and execute \n"
+		"the indexing command in a terminal to see the aspell "
+		"diagnostic output.\n");
+	else
+	    reason = string("aspell dictionary creation command failed:\n") +
+                cmdstring + "\n"
+                "One possible reason might be missing language "
+                "data files for lang = " + m_lang +
+                ". Maybe try to execute the command by hand for a better diag.";
+	return false;
+    }
+    db.termWalkClose(tit);
+    return true;
+}
+
+
+bool Aspell::make_speller(string& reason)
+{
+    if (!ok())
+	return false;
+    if (m_data->m_speller != 0)
+        return true;
+
+    AspellCanHaveError *ret;
+
+    AspellConfig *config = aapi.new_aspell_config();
+    aapi.aspell_config_replace(config, "lang", m_lang.c_str());
+    aapi.aspell_config_replace(config, "encoding", "utf-8");
+    aapi.aspell_config_replace(config, "master", dicPath().c_str());
+    aapi.aspell_config_replace(config, "sug-mode", "fast");
+    //    aapi.aspell_config_replace(config, "sug-edit-dist", "2");
+    ret = aapi.new_aspell_speller(config);
+    aapi.delete_aspell_config(config);
+
+    if (aapi.aspell_error(ret) != 0) {
+	reason = aapi.aspell_error_message(ret);
+	aapi.delete_aspell_can_have_error(ret);
+	return false;
+    }
+    m_data->m_speller = aapi.to_aspell_speller(ret);
+    return true;
+}
+
+bool Aspell::check(const string &iterm, string& reason)
+{
+    LOGDEB2("Aspell::check ["  << (iterm) << "]\n" );
+    string mterm(iterm);
+
+    if (!ok() || !make_speller(reason))
+	return false;
+    if (iterm.empty())
+        return true; //??
+
+    if (!o_index_stripchars) {
+	string lower;
+	if (!unacmaybefold(mterm, lower, "UTF-8", UNACOP_FOLD)) {
+	    LOGERR("Aspell::check : cant lowercase input\n" );
+	    return false;
+	}
+	mterm.swap(lower);
+    }
+
+    int ret = aapi.aspell_speller_check(m_data->m_speller, 
+                                        mterm.c_str(), mterm.length());
+    reason.clear();
+    switch (ret) {
+    case 0: return false;
+    case 1: return true;
+    default:
+    case -1:
+        reason.append("Aspell error: ");
+        reason.append(aapi.aspell_speller_error_message(m_data->m_speller));
+        return false;
+    }
+}
+
+bool Aspell::suggest(Rcl::Db &db, const string &_term, 
+                     list& suggestions, string& reason)
+{
+    if (!ok() || !make_speller(reason))
+	return false;
+    string mterm(_term);
+    if (mterm.empty())
+        return true; //??
+
+    if (!o_index_stripchars) {
+	string lower;
+	if (!unacmaybefold(mterm, lower, "UTF-8", UNACOP_FOLD)) {
+	    LOGERR("Aspell::check : cant lowercase input\n" );
+	    return false;
+	}
+	mterm.swap(lower);
+    }
+
+    AspellCanHaveError *ret;
+
+    const AspellWordList *wl = 
+	aapi.aspell_speller_suggest(m_data->m_speller, 
+                                    mterm.c_str(), mterm.length());
+    if (wl == 0) {
+	reason = aapi.aspell_speller_error_message(m_data->m_speller);
+	return false;
+    }
+    AspellStringEnumeration *els = aapi.aspell_word_list_elements(wl);
+    const char *word;
+    while ((word = aapi.aspell_string_enumeration_next(els)) != 0) {
+	// Check that the word exists in the index (we don't want
+	// aspell computed stuff, only exact terms from the
+	// dictionary).  We used to also check that it stems
+	// differently from the base word but this is complicated
+	// (stemming on/off + language), so we now leave this to the
+	// caller.
+	if (db.termExists(word))
+	    suggestions.push_back(word);
+    }
+    aapi.delete_aspell_string_enumeration(els);
+    return true;
+}
+
+#endif // RCL_USE_ASPELL
+
+#else // TEST_RCLASPELL test driver ->
+
+#ifdef HAVE_CONFIG_H
+#include "autoconfig.h"
+#endif
+
+#ifdef RCL_USE_ASPELL
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+using namespace std;
+
+#include "rclinit.h"
+#include "rclconfig.h"
+#include "rcldb.h"
+#include "rclaspell.h"
+
+static char *thisprog;
+RclConfig *rclconfig;
+
+static char usage [] =
+" -b : build dictionary\n"
+" -s : suggestions for term\n"
+" -c : check term\n"
+"\n"
+;
+static void
+Usage(void)
+{
+    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
+    exit(1);
+}
+
+static int     op_flags;
+#define OPT_MOINS 0x1
+#define OPT_s	  0x2 
+#define OPT_b	  0x4 
+#define OPT_c     0x8
+
+int main(int argc, char **argv)
+{
+    string word;
+    
+    thisprog = argv[0];
+    argc--; argv++;
+
+    while (argc > 0 && **argv == '-') {
+	(*argv)++;
+	if (!(**argv))
+	    /* Cas du "adb - core" */
+	    Usage();
+	while (**argv)
+	    switch (*(*argv)++) {
+	    case 'b':	op_flags |= OPT_b; break;
+	    case 'c':	op_flags |= OPT_c; if (argc < 2)  Usage();
+		word = *(++argv);
+		argc--; 
+		goto b1;
+	    case 's':	op_flags |= OPT_s; if (argc < 2)  Usage();
+		word = *(++argv);
+		argc--; 
+		goto b1;
+	    default: Usage();	break;
+	    }
+    b1: argc--; argv++;
+    }
+
+    if (argc != 0 || op_flags == 0)
+	Usage();
+
+    string reason;
+    rclconfig = recollinit(0, 0, reason);
+    if (!rclconfig || !rclconfig->ok()) {
+	fprintf(stderr, "Configuration problem: %s\n", reason.c_str());
+	exit(1);
+    }
+
+    string dbdir = rclconfig->getDbDir();
+    if (dbdir.empty()) {
+	fprintf(stderr, "No db directory in configuration");
+	exit(1);
+    }
+
+    Rcl::Db rcldb(rclconfig);
+
+    if (!rcldb.open(Rcl::Db::DbRO, 0)) {
+	fprintf(stderr, "Could not open database in %s\n", dbdir.c_str());
+	exit(1);
+    }
+
+    Aspell aspell(rclconfig);
+
+    if (!aspell.init(reason)) {
+	cerr << "Init failed: " << reason << endl;
+	exit(1);
+    }
+    if (op_flags & OPT_b) {
+	if (!aspell.buildDict(rcldb, reason)) {
+	    cerr << "buildDict failed: " << reason << endl;
+	    exit(1);
+	}
+    } else if (op_flags & OPT_c) {
+	bool ret = aspell.check(word, reason);
+	if (!ret && reason.size()) {
+	    cerr << "Aspell error: " << reason << endl;
+	    return 1;
+	}
+	cout << word;
+	if (ret) {
+	    cout << " is in dictionary" << endl;
+	} else {
+	    cout << " not in dictionary" << endl;
+	}
+    } else {
+	list suggs;
+	if (!aspell.suggest(rcldb, word, suggs, reason)) {
+	    cerr << "suggest failed: " << reason << endl;
+	    exit(1);
+	}
+	cout << "Suggestions for " << word << ":" << endl;
+	for (list::iterator it = suggs.begin(); 
+	     it != suggs.end(); it++) {
+	    cout << *it << endl;
+	}
+    }
+    exit(0);
+}
+#else
+int main(int argc, char **argv)
+{return 1;}
+#endif // RCL_USE_ASPELL
+
+#endif // TEST_RCLASPELL test driver
+
diff --git a/src/aspell/rclaspell.h b/src/aspell/rclaspell.h
new file mode 100644
index 00000000..a493b5d9
--- /dev/null
+++ b/src/aspell/rclaspell.h
@@ -0,0 +1,79 @@
+/* Copyright (C) 2006 J.F.Dockes
+ *   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.
+ */
+#ifndef _RCLASPELL_H_INCLUDED_
+#define _RCLASPELL_H_INCLUDED_
+
+/* autoconfig.h must be included before this file */
+#ifdef RCL_USE_ASPELL
+
+/**
+ * Aspell speller interface class.
+ *
+ * Aspell is used to let the user find about spelling variations that may 
+ * exist in the document set for a given word.
+ * A specific aspell dictionary is created out of all the terms in the 
+ * xapian index, and we then use it to expand a term to spelling neighbours.
+ * We use the aspell C api for term expansion, but have 
+ * to execute the program to create dictionaries.
+ */
+
+#include 
+#include 
+
+#include "rclconfig.h"
+#include "rcldb.h"
+
+class AspellData;
+
+class Aspell {
+ public:
+    Aspell(RclConfig *cnf);
+    ~Aspell();
+
+    /** Check health */
+    bool ok() const;
+
+    /** Find the aspell command and shared library, init function pointers */
+    bool init(std::string &reason); 
+
+    /**  Build dictionary out of index term list. This is done at the end
+     * of an indexing pass. */
+    bool buildDict(Rcl::Db &db, std::string &reason);
+
+    /** Check that word is in dictionary. Note that this would mean
+     * that the EXACT word is: aspell just does a lookup, no
+     * grammatical, case or diacritics magic of any kind
+     *
+     * @return true if word in dic, false if not. reason.size() -> error
+     */
+    bool check(const std::string& term, std::string& reason);
+
+    /** Return a list of possible expansions for a given word */
+    bool suggest(Rcl::Db &db, const std::string& term, 
+		 std::list &suggestions, std::string &reason);
+
+ private:
+    std::string dicPath();
+    RclConfig  *m_config;
+    std::string      m_lang;
+    AspellData *m_data;
+
+    bool make_speller(std::string& reason);
+};
+
+#endif /* RCL_USE_ASPELL */
+#endif /* _RCLASPELL_H_INCLUDED_ */
diff --git a/src/autogen.sh b/src/autogen.sh
new file mode 100755
index 00000000..60c50f0c
--- /dev/null
+++ b/src/autogen.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+aclocal
+libtoolize --copy
+automake --add-missing --force-missing --copy
+autoconf
diff --git a/src/bincimapmime/00README.recoll b/src/bincimapmime/00README.recoll
new file mode 100644
index 00000000..38fb36c8
--- /dev/null
+++ b/src/bincimapmime/00README.recoll
@@ -0,0 +1,3 @@
+Most of the code in this directory was taken from the Binc IMAP project
+(http://www.bincimap.org/), version 1.3.3
+
diff --git a/src/bincimapmime/AUTHORS b/src/bincimapmime/AUTHORS
new file mode 100644
index 00000000..1ece119f
--- /dev/null
+++ b/src/bincimapmime/AUTHORS
@@ -0,0 +1,45 @@
+The following parties have participated in writing code or otherwise
+contributed to the Binc IMAP project:
+
+Author:
+Andreas Aardal Hanssen                  
+
+Several users have been very helpful with bug reports and suggestions, and
+the author is very grateful for their contributions.
+
+Some users have also gone to the extra effort of debugging the cause of a
+bug, or have found a way of implementing a feature, and have either provided
+a very good description of what is needed, or they have actually provided a
+patch that has been added to Binc IMAP.
+
+While adding extra value to the discussion around the discovery of a bug or
+the evaluation of a new feature, these contributors also take some load of
+the author's back, so they deserve extra thanks.
+
+In this list are also included people who have contributed with mirrors and
+translations of the web pages.
+
+Henry Baragar                           
+Jrgen Botz                             
+Charlie Brady                           
+Caskey Dickson                          
+Ketil Froyn                             
+Gary Gordon                             
+Marek Gutkowski                         
+Daniel James                            
+Zak Johnson                             
+Sergei Kolobov                          
+Rafal Kupka                             
+Eivind Kvedalen                         
+HIROSHIMA Naoki                         
+Greger Stolt Nilsen			
+John Starks                             
+Peter Stuge                             
+Gerrit Pape                             
+Jeremy Rossi                            
+Dale Woolridge                          
+
+If you have contributed to the Binc IMAP project but are not listed here
+(this happens quite often), please send a mail to andreas-binc@bincimap.org
+and I'll add you to the list.
+
diff --git a/src/bincimapmime/COPYING b/src/bincimapmime/COPYING
new file mode 100644
index 00000000..e4397077
--- /dev/null
+++ b/src/bincimapmime/COPYING
@@ -0,0 +1,356 @@
+This software is released under the GPL. Find a full copy of the GNU
+General Public License below.
+
+In addition, as a special exception, Andreas Aardal Hanssen, author of
+Binc IMAP, gives permission to link the code of this program with the
+OpenSSL library (or with modified versions of OpenSSL that use the
+same license as OpenSSL, listed in the included COPYING.OpenSSL file),
+and distribute linked combinations including the two.
+
+You must obey the GNU General Public License in all respects for all
+of the code used other than OpenSSL.  If you modify this file, you may
+extend this exception to your version of the file, but you are not
+obligated to do so. If you do not wish to do so, delete this exception
+statement from your version.
+
+---------------------------------------------------------------------
+                   GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    
+    Copyright (C)   
+
+    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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  , 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/src/bincimapmime/Makefile b/src/bincimapmime/Makefile
new file mode 100644
index 00000000..218b1d52
--- /dev/null
+++ b/src/bincimapmime/Makefile
@@ -0,0 +1,11 @@
+PROGS = trbinc
+all: $(PROGS)
+
+TRBINCOBJS = trbinc.o
+trbinc: trbinc.o
+	$(CXX) -o trbinc trbinc.o $(LIBRECOLL)
+
+trbinc.o: trbinc.cc
+	$(CXX) $(ALL_CXXFLAGS) -c -o trbinc.o trbinc.cc
+
+include ../utils/utmkdefs.mk
diff --git a/src/bincimapmime/convert.cc b/src/bincimapmime/convert.cc
new file mode 100644
index 00000000..80dd892e
--- /dev/null
+++ b/src/bincimapmime/convert.cc
@@ -0,0 +1,129 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    convert.cc
+ *  
+ *  Description:
+ *    Implementation of miscellaneous convertion functions.
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#include "convert.h"
+#include 
+
+#ifndef NO_NAMESPACES
+using namespace ::std;
+using namespace Binc;
+#endif /* NO_NAMESPACES */
+
+//------------------------------------------------------------------------
+BincStream::BincStream(void)
+{
+}
+
+//------------------------------------------------------------------------
+BincStream::~BincStream(void)
+{
+  clear();
+}
+
+//------------------------------------------------------------------------
+string BincStream::popString(std::string::size_type size)
+{
+  if (size > nstr.length())
+    size = nstr.length();
+  string tmp = nstr.substr(0, size);
+  nstr = nstr.substr(size);
+  return tmp;
+}
+
+//------------------------------------------------------------------------
+char BincStream::popChar(void)
+{
+  if (nstr.length() == 0)
+    return '\0';
+
+  char c = nstr[0];
+  nstr = nstr.substr(1);
+  return c;
+}
+
+//------------------------------------------------------------------------
+void BincStream::unpopChar(char c)
+{
+  nstr = c + nstr;
+}
+
+//------------------------------------------------------------------------
+void BincStream::unpopStr(const string &s)
+{
+  nstr = s + nstr;
+}
+
+//------------------------------------------------------------------------
+const string &BincStream::str(void) const
+{
+  return nstr;
+}
+
+//------------------------------------------------------------------------
+void BincStream::clear(void)
+{
+  nstr.clear();
+}
+
+//------------------------------------------------------------------------
+unsigned int BincStream::getSize(void) const
+{
+  return (unsigned int) nstr.length();
+}
+
+//------------------------------------------------------------------------
+BincStream &BincStream::operator << (std::ostream&(*)(std::ostream&))
+{
+  nstr += "\r\n";
+  return *this;
+}
+
+//------------------------------------------------------------------------
+BincStream &BincStream::operator << (const string &t)
+{
+  nstr += t;
+  return *this;
+}
+
+//------------------------------------------------------------------------
+BincStream &BincStream::operator << (int t)
+{
+  nstr += toString(t);
+  return *this;
+}
+
+//------------------------------------------------------------------------
+BincStream &BincStream::operator << (unsigned int t)
+{
+  nstr += toString(t);
+  return *this;
+}
+
+//------------------------------------------------------------------------
+BincStream &BincStream::operator << (char t)
+{
+  nstr += t;
+  return *this;
+}
diff --git a/src/bincimapmime/convert.h b/src/bincimapmime/convert.h
new file mode 100644
index 00000000..2ed9b3a7
--- /dev/null
+++ b/src/bincimapmime/convert.h
@@ -0,0 +1,316 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    src/util/convert.h
+ *  
+ *  Description:
+ *    Declaration of miscellaneous convertion functions.
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#ifndef convert_h_included
+#define convert_h_included
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+namespace Binc {
+
+  //----------------------------------------------------------------------
+  inline std::string toString(int i_in)
+  {
+    char intbuf[16];
+    snprintf(intbuf, sizeof(intbuf), "%d", i_in);
+    return std::string(intbuf);
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string toString(unsigned int i_in)
+  {
+    char intbuf[16];
+    snprintf(intbuf, sizeof(intbuf), "%u", i_in);
+    return std::string(intbuf);
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string toString(unsigned long i_in)
+  {
+    char longbuf[40];
+    snprintf(longbuf, sizeof(longbuf), "%lu", i_in);
+    return std::string(longbuf);
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string toString(const char *i_in)
+  {
+    return std::string(i_in);
+  }
+
+  //----------------------------------------------------------------------
+  inline int atoi(const std::string &s_in)
+  {
+    return ::atoi(s_in.c_str());
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string toHex(const std::string &s)
+  {
+    const char hexchars[] = "0123456789abcdef";
+    std::string tmp;
+    for (std::string::const_iterator i = s.begin(); i != s.end(); ++i) {
+      unsigned char c = (unsigned char)*i;
+      tmp += hexchars[((c & 0xf0) >> 4)];
+      tmp += hexchars[c & 0x0f];
+    }
+    
+    return tmp;
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string fromHex(const std::string &s)
+  {
+    const char hexchars[] = "0123456789abcdef";
+    std::string tmp;
+    for (std::string::const_iterator i = s.begin();
+	 i != s.end() && i + 1 != s.end(); i += 2) {
+      ptrdiff_t n;
+      unsigned char c = *i;
+      unsigned char d = *(i + 1);
+      
+      const char *t;
+      if ((t = strchr(hexchars, c)) == 0)
+	return "out of range";
+      n = (t - hexchars) << 4;
+      
+      
+      if ((t = strchr(hexchars, d)) == 0)
+	return "out of range";
+      n += (t - hexchars);
+      
+      if (n >= 0 && n <= 255)
+	tmp += (char) n;
+      else
+	return "out of range";
+    }
+    
+    return tmp;
+  }
+  
+  //----------------------------------------------------------------------
+  inline std::string toImapString(const std::string &s_in)
+  {
+    for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+      unsigned char c = (unsigned char)*i;
+      if (c <= 31 || c >= 127 || c == '\"' || c == '\\')
+	return "{" + toString((unsigned long)s_in.length()) + "}\r\n" + s_in;
+    }
+    
+    return "\"" + s_in + "\"";
+  }
+
+  //----------------------------------------------------------------------
+  inline void uppercase(std::string &input)
+  {
+    for (std::string::iterator i = input.begin(); i != input.end(); ++i)
+      *i = toupper(*i);
+  }
+
+  //----------------------------------------------------------------------
+  inline void lowercase(std::string &input)
+  {
+    for (std::string::iterator i = input.begin(); i != input.end(); ++i)
+      *i = tolower(*i);
+  }
+
+  //----------------------------------------------------------------------
+  inline void chomp(std::string &s_in, const std::string &chars = " \t\r\n")
+  {
+    std::string::size_type n = s_in.length();
+    while (n > 1 && chars.find(s_in[n - 1]) != std::string::npos)
+      s_in.resize(n-- - 1);
+  }
+
+  //----------------------------------------------------------------------
+  inline void trim(std::string &s_in, const std::string &chars = " \t\r\n")
+  {
+    while (s_in != "" && chars.find(s_in[0]) != std::string::npos)
+      s_in = s_in.substr(1);
+    chomp(s_in, chars);
+  }
+
+  //----------------------------------------------------------------------
+  inline const std::string unfold(const std::string &a, 
+				  bool removecomment = true)
+  {
+    std::string tmp;
+    bool incomment = false;
+    bool inquotes = false;
+    for (std::string::const_iterator i = a.begin(); i != a.end(); ++i) {
+      unsigned char c = (unsigned char)*i;
+      if (!inquotes && removecomment) {
+	if (c == '(') {
+	  incomment = true; 
+	  tmp += " ";
+	} else if (c == ')') {
+	  incomment = false; 
+	} else if (c != 0x0a && c != 0x0d) {
+	  tmp += *i;
+        }
+      } else if (c != 0x0a && c != 0x0d) {
+	tmp += *i;
+      }
+
+      if (!incomment) {
+        if (*i == '\"') 
+          inquotes = !inquotes;
+      }
+    }
+
+    trim(tmp);
+    return tmp;
+  }
+  
+  //----------------------------------------------------------------------
+  inline void split(const std::string &s_in, const std::string &delim, 
+	     std::vector &dest, bool skipempty = true)
+  {
+    std::string token;
+    for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+      if (delim.find(*i) != std::string::npos) {
+	if (!skipempty || token != "")
+	  dest.push_back(token);
+	token.clear();
+      } else
+	token += *i;
+    }
+
+    if (token != "")
+      dest.push_back(token);
+  }
+
+  //----------------------------------------------------------------------
+  inline void splitAddr(const std::string &s_in,
+			std::vector &dest, bool skipempty = true)
+  {
+    static const std::string delim = ",";
+    std::string token;
+    bool inquote = false;
+    for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+      if (inquote && *i == '\"') inquote = false;
+      else if (!inquote && *i == '\"') inquote = true;
+
+      if (!inquote && delim.find(*i) != std::string::npos) {
+	if (!skipempty || token != "")
+	  dest.push_back(token);
+	token.clear();
+      } else
+	token += *i;
+    }
+    if (token != "")
+      dest.push_back(token);
+  }
+
+  //----------------------------------------------------------------------
+  inline std::string toCanonMailbox(const std::string &s_in)
+  {
+    if (s_in.find("..") != std::string::npos) return std::string();
+
+    if (s_in.length() >= 5) {
+      std::string a = s_in.substr(0, 5);
+      uppercase(a);
+      return a == "INBOX" ?
+	a + (s_in.length() > 5 ? s_in.substr(5) : std::string()) : s_in;
+    }
+    
+    return s_in;
+  }
+
+  //------------------------------------------------------------------------
+  inline std::string toRegex(const std::string &s_in, char delimiter)
+  {
+    std::string regex = "^";
+    for (std::string::const_iterator i = s_in.begin(); i != s_in.end(); ++i) {
+      if (*i == '.' || *i == '[' || *i == ']' || *i == '{' || *i == '}' ||
+	  *i == '(' || *i == ')' || *i == '^' || *i == '$' || *i == '?' ||
+	  *i == '+' || *i == '\\') {
+	regex += "\\";
+	regex += *i;
+      } else if (*i == '*')
+	regex += ".*?";
+       else if (*i == '%') {
+        regex += "(\\";
+        regex += delimiter;
+        regex += "){0,1}";
+	regex += "[^\\";
+	regex += delimiter;
+	regex += "]*?";
+      } else regex += *i;
+    }
+    
+    if (regex[regex.length() - 1] == '?')
+      regex[regex.length() - 1] = '$';
+    else
+      regex += "$";
+
+    return regex;
+  }
+
+  //------------------------------------------------------------------------
+  class BincStream {
+  private:
+    std::string nstr;
+
+  public:
+
+    //--
+    BincStream &operator << (std::ostream&(*)(std::ostream&));
+    BincStream &operator << (const std::string &t);
+    BincStream &operator << (unsigned int t);
+    BincStream &operator << (int t);
+    BincStream &operator << (char t);
+
+    //--
+    std::string popString(std::string::size_type size);
+
+    //--
+    char popChar(void);
+    void unpopChar(char c);
+    void unpopStr(const std::string &s);
+
+    //--
+    const std::string &str(void) const;
+
+    //--
+    unsigned int getSize(void) const;
+
+    //--
+    void clear(void);
+
+    //--
+    BincStream(void);
+    ~BincStream(void);
+  };
+}
+
+#endif
diff --git a/src/bincimapmime/mime-inputsource.h b/src/bincimapmime/mime-inputsource.h
new file mode 100644
index 00000000..977d7689
--- /dev/null
+++ b/src/bincimapmime/mime-inputsource.h
@@ -0,0 +1,222 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    src/mime-inputsource.h
+ *  
+ *  Description:
+ *    The base class of the MIME input source
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#ifndef mime_inputsource_h_included
+#define mime_inputsource_h_included
+#include "autoconfig.h"
+// Data source for MIME parser
+
+// Note about large files: we might want to change the unsigned int
+// used for offsets into an off_t for intellectual satisfaction, but
+// in the context of recoll, we could only get into trouble if a
+// *single message* exceeded 2GB, which seems rather unlikely. When
+// parsing a mailbox files, we read each message in memory and use the
+// stream input source (from a memory buffer, no file offsets). When
+// parsing a raw message file, it's only one message.
+
+#include 
+#include "safeunistd.h"
+
+#include 
+
+namespace Binc {
+
+  class MimeInputSource {
+  public:
+    // Note that we do NOT take ownership of fd, won't close it on delete
+    inline MimeInputSource(int fd, unsigned int start = 0);
+    virtual inline ~MimeInputSource(void);
+
+    virtual inline ssize_t fillRaw(char *raw, size_t nbytes);
+    virtual inline void reset(void);
+
+    virtual inline bool fillInputBuffer(void);
+    inline void seek(unsigned int offset);
+    inline bool getChar(char *c);
+    inline void ungetChar(void);
+    inline int getFileDescriptor(void) const;
+
+    inline unsigned int getOffset(void) const;
+
+  private:
+    int fd;
+    char data[16384];
+    unsigned int offset;
+    unsigned int tail;
+    unsigned int head;
+    unsigned int start;
+    char lastChar;
+  };
+
+  inline MimeInputSource::MimeInputSource(int fd, unsigned int start)
+  {
+    this->fd = fd;
+    this->start = start;
+    offset = 0;
+    tail = 0;
+    head = 0;
+    lastChar = '\0';
+    memset(data, '\0', sizeof(data));
+
+    seek(start);
+  }
+
+  inline MimeInputSource::~MimeInputSource(void)
+  {
+  }
+
+  inline ssize_t MimeInputSource::fillRaw(char *raw, size_t nbytes)
+  {
+      return read(fd, raw, nbytes);
+  }
+
+  inline bool MimeInputSource::fillInputBuffer(void)
+  {
+    char raw[4096];
+    ssize_t nbytes = fillRaw(raw, 4096);
+    if (nbytes <= 0) {
+      // FIXME: If ferror(crlffile) we should log this.
+      return false;
+    }
+
+    for (ssize_t i = 0; i < nbytes; ++i) {
+      const char c = raw[i];
+      if (c == '\r') {
+	if (lastChar == '\r') {
+	  data[tail++ & (0x4000-1)] = '\r';
+	  data[tail++ & (0x4000-1)] = '\n';
+	}
+      } else if (c == '\n') {
+	data[tail++ & (0x4000-1)] = '\r';
+	data[tail++ & (0x4000-1)] = '\n';
+      } else {
+	if (lastChar == '\r') {
+	  data[tail++ & (0x4000-1)] = '\r';
+	  data[tail++ & (0x4000-1)] = '\n';
+	}
+
+	data[tail++ & (0x4000-1)] = c;
+      }
+      
+      lastChar = c;
+    }
+
+    return true;
+  }
+
+  inline void MimeInputSource::reset(void)
+  {
+    offset = head = tail = 0;
+    lastChar = '\0';
+
+    if (fd != -1)
+      lseek(fd, 0, SEEK_SET);
+  }
+
+  inline void MimeInputSource::seek(unsigned int seekToOffset)
+  {
+    if (offset > seekToOffset)
+      reset();
+   
+    char c;
+    int n = 0;
+    while (seekToOffset > offset) {
+      if (!getChar(&c))
+	break;
+      ++n;
+    }
+  }
+
+  inline bool MimeInputSource::getChar(char *c)
+  {
+    if (head == tail && !fillInputBuffer())
+      return false;
+
+    *c = data[head++ & (0x4000-1)];
+    ++offset;
+    return true;
+  }
+
+  inline void MimeInputSource::ungetChar()
+  {
+    --head;
+    --offset;
+  }
+
+  inline int MimeInputSource::getFileDescriptor(void) const
+  {
+    return fd;
+  }
+
+  inline unsigned int MimeInputSource::getOffset(void) const
+  {
+    return offset;
+  }
+
+    ///////////////////////////////////
+    class MimeInputSourceStream : public MimeInputSource {
+  public:
+    inline MimeInputSourceStream(istream& s, unsigned int start = 0);
+    virtual inline ssize_t fillRaw(char *raw, size_t nb);
+    virtual inline void reset(void);
+  private:
+      istream& s;
+  };
+
+  inline MimeInputSourceStream::MimeInputSourceStream(istream& si, 
+						      unsigned int start)
+      : MimeInputSource(-1, start), s(si)
+  {
+  }
+
+  inline ssize_t MimeInputSourceStream::fillRaw(char *raw, size_t nb)
+  {
+    // Why can't streams tell how many characters were actually read
+    // when hitting eof ?
+    std::streampos st = s.tellg();
+    s.seekg(0, ios::end);
+    std::streampos lst = s.tellg();
+    s.seekg(st);
+    size_t nbytes = size_t(lst - st);
+    if (nbytes > nb) {
+	nbytes = nb;
+    }
+    if (nbytes <= 0) {
+	return (ssize_t)-1;
+    }
+
+    s.read(raw, nbytes);
+    return static_cast(nbytes);
+  }
+
+  inline void MimeInputSourceStream::reset(void)
+  {
+      MimeInputSource::reset();
+      s.seekg(0);
+  }
+
+}
+
+#endif
diff --git a/src/bincimapmime/mime-parsefull.cc b/src/bincimapmime/mime-parsefull.cc
new file mode 100644
index 00000000..2c81b5a7
--- /dev/null
+++ b/src/bincimapmime/mime-parsefull.cc
@@ -0,0 +1,625 @@
+ /* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    mime-parsefull.cc
+ *  
+ *  Description:
+ *    Implementation of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifndef NO_NAMESPACES
+using namespace ::std;
+#endif /* NO_NAMESPACES */
+
+#include "mime.h"
+#include "mime-utils.h"
+#include "mime-inputsource.h"
+#include "convert.h"
+
+// #define MPF
+#ifdef MPF
+#define MPFDEB(X) fprintf X
+#else
+#define MPFDEB(X)
+#endif
+
+//------------------------------------------------------------------------
+void Binc::MimeDocument::parseFull(int fd)
+{
+  if (allIsParsed)
+    return;
+
+  allIsParsed = true;
+
+  delete doc_mimeSource;
+  doc_mimeSource = new MimeInputSource(fd);
+
+  headerstartoffsetcrlf = 0;
+  headerlength = 0;
+  bodystartoffsetcrlf = 0;
+  bodylength = 0;
+  size = 0;
+  messagerfc822 = false;
+  multipart = false;
+
+  int bsize = 0;
+  string bound;
+  doParseFull(doc_mimeSource, bound, bsize);
+
+  // eat any trailing junk to get the correct size
+  char c;
+  while (doc_mimeSource->getChar(&c));
+
+  size = doc_mimeSource->getOffset();
+}
+
+void Binc::MimeDocument::parseFull(istream& s)
+{
+  if (allIsParsed)
+    return;
+
+  allIsParsed = true;
+
+  delete doc_mimeSource;
+  doc_mimeSource = new MimeInputSourceStream(s);
+
+  headerstartoffsetcrlf = 0;
+  headerlength = 0;
+  bodystartoffsetcrlf = 0;
+  bodylength = 0;
+  size = 0;
+  messagerfc822 = false;
+  multipart = false;
+
+  int bsize = 0;
+  string bound;
+  doParseFull(doc_mimeSource, bound, bsize);
+
+  // eat any trailing junk to get the correct size
+  char c;
+  while (doc_mimeSource->getChar(&c));
+
+  size = doc_mimeSource->getOffset();
+}
+
+//------------------------------------------------------------------------
+bool Binc::MimePart::parseOneHeaderLine(Binc::Header *header, 
+					unsigned int *nlines)
+{
+  using namespace ::Binc;
+  char c;
+  bool eof = false;
+  char cqueue[4];
+  string name;
+  string content;
+
+  while (mimeSource->getChar(&c)) {
+    // If we encounter a \r before we got to the first ':', then
+    // rewind back to the start of the line and assume we're at the
+    // start of the body.
+    if (c == '\r') {
+      for (int i = 0; i < (int) name.length() + 1; ++i)
+	mimeSource->ungetChar();
+      return false;
+    }
+
+    // A colon marks the end of the header name
+    if (c == ':') break;
+
+    // Otherwise add to the header name
+    name += c;
+  }
+
+  cqueue[0] = '\0';
+  cqueue[1] = '\0';
+  cqueue[2] = '\0';
+  cqueue[3] = '\0';
+
+  // Read until the end of the header.
+  bool endOfHeaders = false;
+  while (!endOfHeaders) {
+    if (!mimeSource->getChar(&c)) {
+      eof = true;
+      break;
+    }
+
+    if (c == '\n') ++*nlines;
+
+    for (int i = 0; i < 3; ++i)
+      cqueue[i] = cqueue[i + 1];
+    cqueue[3] = c;
+
+    if (strncmp(cqueue, "\r\n\r\n", 4) == 0) {
+      endOfHeaders = true;
+      break;
+    }
+
+    // If the last character was a newline, and the first now is not
+    // whitespace, then rewind one character and store the current
+    // key,value pair.
+    if (cqueue[2] == '\n' && c != ' ' && c != '\t') {
+      if (content.length() > 2)
+	content.resize(content.length() - 2);
+
+      trim(content);
+      header->add(name, content);
+
+      if (c != '\r') {
+	mimeSource->ungetChar();
+	if (c == '\n') --*nlines;
+	return true;
+      }
+	
+      mimeSource->getChar(&c);
+      return false;
+    }
+
+    content += c;
+  }
+
+  if (name != "") {
+    if (content.length() > 2)
+      content.resize(content.length() - 2);
+    header->add(name, content);
+  }
+
+  return !(eof || endOfHeaders);
+}
+
+//------------------------------------------------------------------------
+void Binc::MimePart::parseHeader(Binc::Header *header, unsigned int *nlines)
+{
+  while (parseOneHeaderLine(header, nlines))
+  { }
+}
+
+//------------------------------------------------------------------------
+void Binc::MimePart::analyzeHeader(Binc::Header *header, bool *multipart,
+				   bool *messagerfc822, string *subtype,
+				   string *boundary)
+{
+  using namespace ::Binc;
+
+  // Do simple parsing of headers to determine the
+  // type of message (multipart,messagerfc822 etc)
+  HeaderItem ctype;
+  if (header->getFirstHeader("content-type", ctype)) {
+    vector types;
+    split(ctype.getValue(), ";", types);
+
+    if (types.size() > 0) {
+      // first element should describe content type
+      string tmp = types[0];
+      trim(tmp);
+      vector v;
+      split(tmp, "/", v);
+      string key, value;
+
+      key = (v.size() > 0) ? v[0] : "text";
+      value = (v.size() > 1) ? v[1] : "plain";
+      lowercase(key);
+
+      if (key == "multipart") {
+	*multipart = true;
+	lowercase(value);
+	*subtype = value;
+      } else if (key == "message") {
+	lowercase(value);
+	if (value == "rfc822")
+	  *messagerfc822 = true;
+      }
+    }
+
+    for (vector::const_iterator i = types.begin();
+	 i != types.end(); ++i) {
+      string element = *i;
+      trim(element);
+
+      if (element.find("=") != string::npos) {
+	string::size_type pos = element.find('=');
+	string key = element.substr(0, pos);
+	string value = element.substr(pos + 1);
+	
+	lowercase(key);
+	trim(key);
+
+	if (key == "boundary") {
+	  trim(value, " \"");
+	  *boundary = value;
+	}
+      }
+    }
+  }
+}
+
+void Binc::MimePart::parseMessageRFC822(vector *members,
+					bool *foundendofpart,
+					unsigned int *bodylength,
+					unsigned int *nbodylines,
+					const string &toboundary)
+{
+  using namespace ::Binc;
+
+  // message rfc822 means a completely enclosed mime document. we
+  // call the parser recursively, and pass on the boundary string
+  // that we got. when parse() finds this boundary, it returns 0. if
+  // it finds the end boundary (boundary + "--"), it returns != 0.
+  MimePart m;
+
+  unsigned int bodystartoffsetcrlf = mimeSource->getOffset();
+    
+  // parsefull returns the number of bytes that need to be removed
+  // from the body because of the terminating boundary string.
+  int bsize = 0;
+  if (m.doParseFull(mimeSource, toboundary, bsize))
+    *foundendofpart = true;
+
+  // make sure bodylength doesn't overflow    
+  *bodylength = mimeSource->getOffset();
+  if (*bodylength >= bodystartoffsetcrlf) {
+    *bodylength -= bodystartoffsetcrlf;
+    if (*bodylength >= (unsigned int) bsize) {
+      *bodylength -= (unsigned int) bsize;
+    } else {
+      *bodylength = 0;
+    }
+  } else {
+    *bodylength = 0;
+  }
+
+  *nbodylines += m.getNofLines();
+
+  members->push_back(m);
+}
+
+bool Binc::MimePart::skipUntilBoundary(const string &delimiter,
+				       unsigned int *nlines, bool *eof)
+{
+  string::size_type endpos = delimiter.length();
+  char *delimiterqueue = 0;
+  string::size_type delimiterpos = 0;
+  const char *delimiterStr = delimiter.c_str();
+  if (delimiter != "") {
+    delimiterqueue = new char[endpos];
+    memset(delimiterqueue, 0, endpos);
+  }
+
+  // first, skip to the first delimiter string. Anything between the
+  // header and the first delimiter string is simply ignored (it's
+  // usually a text message intended for non-mime clients)
+  char c;
+
+  bool foundBoundary = false;
+  for (;;) {    
+    if (!mimeSource->getChar(&c)) {
+      *eof = true;
+      break;
+    }
+
+    if (c == '\n')
+      ++*nlines;
+
+    // if there is no delimiter, we just read until the end of the
+    // file.
+    if (!delimiterqueue)
+      continue;
+
+    delimiterqueue[delimiterpos++] = c;
+    if (delimiterpos ==  endpos)
+      delimiterpos = 0;
+      
+    if (compareStringToQueue(delimiterStr, delimiterqueue,
+			     delimiterpos, int(endpos))) {
+      foundBoundary = true;
+      break;
+    }
+  }
+
+  delete [] delimiterqueue;
+  delimiterqueue = 0;
+
+  return foundBoundary;
+}
+
+// JFD: Things we do after finding a boundary (something like CRLF--somestring)
+// Need to see if this is a final one (with an additional -- at the end),
+// and need to check if it is immediately followed by another boundary 
+// (in this case, we give up our final CRLF in its favour)
+inline void Binc::MimePart::postBoundaryProcessing(bool *eof,
+						   unsigned int *nlines,
+						   int *boundarysize,
+						   bool *foundendofpart)
+{
+    // Read two more characters. This may be CRLF, it may be "--" and
+    // it may be any other two characters.
+    char a = '\0';
+    if (!mimeSource->getChar(&a))
+      *eof = true;
+    if (a == '\n')
+      ++*nlines; 
+
+    char b = '\0';
+    if (!mimeSource->getChar(&b))
+      *eof = true;
+    if (b == '\n')
+      ++*nlines;
+    
+    // If eof, we're done here
+    if (*eof)
+      return;
+
+    // If we find two dashes after the boundary, then this is the end
+    // of boundary marker, and we need to get 2 more chars
+    if (a == '-' && b == '-') {
+      *foundendofpart = true;
+      *boundarysize += 2;
+	
+      if (!mimeSource->getChar(&a))
+	*eof = true;
+      if (a == '\n')
+	++*nlines; 
+	
+      if (!mimeSource->getChar(&b))
+	*eof = true;
+      if (b == '\n')
+	++*nlines;
+    }
+
+    // If the boundary is followed by CRLF, we need to handle the
+    // special case where another boundary line follows
+    // immediately. In this case we consider the CRLF to be part of
+    // the NEXT boundary.
+    if (a == '\r' && b == '\n') {
+      // Get 2 more
+      if (!mimeSource->getChar(&a) || !mimeSource->getChar(&b)) {
+	*eof = true; 
+      } else if (a == '-' && b == '-') {
+	MPFDEB((stderr, "BINC: consecutive delimiters, giving up CRLF\n"));
+	mimeSource->ungetChar();
+	mimeSource->ungetChar();
+	mimeSource->ungetChar();
+	mimeSource->ungetChar();
+      } else {
+	// We unget the 2 chars, and keep our crlf (increasing our own size)
+	MPFDEB((stderr, "BINC: keeping my CRLF\n"));
+	mimeSource->ungetChar();
+	mimeSource->ungetChar();
+	*boundarysize += 2;
+      }
+
+    } else {
+      // Boundary string not followed by CRLF, don't read more and let
+      // others skip the rest. Note that this is allowed but quite uncommon
+      mimeSource->ungetChar();
+      mimeSource->ungetChar();
+    }
+}
+
+void Binc::MimePart::parseMultipart(const string &boundary,
+				    const string &toboundary,
+				    bool *eof,
+				    unsigned int *nlines,
+				    int *boundarysize,
+				    bool *foundendofpart,
+				    unsigned int *bodylength,
+				    vector *members)
+{
+  MPFDEB((stderr, "BINC: ParseMultipart: boundary [%s], toboundary[%s]\n", 
+	  boundary.c_str(),
+	  toboundary.c_str()));
+  using namespace ::Binc;
+  unsigned int bodystartoffsetcrlf = mimeSource->getOffset();
+
+  // multipart parsing starts with skipping to the first
+  // boundary. then we call parse() for all parts. the last parse()
+  // command will return a code indicating that it found the last
+  // boundary of this multipart. Note that the first boundary does
+  // not have to start with CRLF.
+  string delimiter = "--" + boundary;
+
+  skipUntilBoundary(delimiter, nlines, eof);
+
+  if (!eof)
+    *boundarysize = int(delimiter.size());
+
+  postBoundaryProcessing(eof, nlines, boundarysize, foundendofpart);
+
+  // read all mime parts.
+  if (!*foundendofpart && !*eof) {
+    bool quit = false;
+    do {
+      MimePart m;
+
+      // If parseFull returns != 0, then it encountered the multipart's
+      // final boundary.
+      int bsize = 0;
+      if (m.doParseFull(mimeSource, boundary, bsize)) {
+	quit = true;
+	*boundarysize = bsize;
+      }
+
+      members->push_back(m);
+
+    } while (!quit);
+  }
+
+  if (!*foundendofpart && !*eof) {
+    // multipart parsing starts with skipping to the first
+    // boundary. then we call parse() for all parts. the last parse()
+    // command will return a code indicating that it found the last
+    // boundary of this multipart. Note that the first boundary does
+    // not have to start with CRLF.
+    string delimiter = "\r\n--" + toboundary;
+    skipUntilBoundary(delimiter, nlines, eof);
+
+    if (!*eof)
+      *boundarysize = int(delimiter.size());
+
+    postBoundaryProcessing(eof, nlines, boundarysize, foundendofpart);
+  }
+
+  // make sure bodylength doesn't overflow    
+  *bodylength = mimeSource->getOffset();
+  if (*bodylength >= bodystartoffsetcrlf) {
+    *bodylength -= bodystartoffsetcrlf;
+    if (*bodylength >= (unsigned int) *boundarysize) {
+      *bodylength -= (unsigned int) *boundarysize;
+    } else {
+      *bodylength = 0;
+    }
+  } else {
+    *bodylength = 0;
+  }
+  MPFDEB((stderr, "BINC: ParseMultipart return\n"));
+}
+
+void Binc::MimePart::parseSinglePart(const string &toboundary,
+			    int *boundarysize,
+			    unsigned int *nbodylines,
+			    unsigned int *nlines,
+			    bool *eof, bool *foundendofpart,
+			    unsigned int *bodylength)
+{
+  MPFDEB((stderr, "BINC: parseSinglePart, boundary [%s]\n", 
+	  toboundary.c_str()));
+  using namespace ::Binc;
+  unsigned int bodystartoffsetcrlf = mimeSource->getOffset();
+
+  // If toboundary is empty, then we read until the end of the
+  // file. Otherwise we will read until we encounter toboundary.
+  string _toboundary; 
+  if (toboundary != "") {
+    _toboundary = "\r\n--";
+    _toboundary += toboundary;
+  }
+
+  //  if (skipUntilBoundary(_toboundary, nlines, eof))
+  //    *boundarysize = _toboundary.length();
+
+  char *boundaryqueue = 0;
+  size_t endpos = _toboundary.length();
+  if (toboundary != "") {
+    boundaryqueue = new char[endpos];
+    memset(boundaryqueue, 0, endpos);
+  }
+
+  *boundarysize = 0;
+
+  const char *_toboundaryStr = _toboundary.c_str();
+  string line;
+  bool toboundaryIsEmpty = (toboundary == "");
+  char c;
+  string::size_type boundarypos = 0;
+  while (mimeSource->getChar(&c)) {
+    if (c == '\n') { ++*nbodylines; ++*nlines; }
+
+    if (toboundaryIsEmpty)
+      continue;
+
+    // find boundary
+    boundaryqueue[boundarypos++] = c;
+    if (boundarypos == endpos)
+      boundarypos = 0;
+      
+    if (compareStringToQueue(_toboundaryStr, boundaryqueue,
+			     boundarypos, int(endpos))) {
+      *boundarysize = static_cast(_toboundary.length());
+      break;
+    }
+  }
+
+  delete [] boundaryqueue;
+
+  if (toboundary != "") {
+    postBoundaryProcessing(eof, nlines, boundarysize, foundendofpart);
+  } else {
+    // Recoll: in the case of a multipart body with a null
+    // boundary (probably illegal but wtf), eof was not set and
+    // multipart went into a loop until bad alloc.
+    *eof = true;
+  }
+
+  // make sure bodylength doesn't overflow    
+  *bodylength = mimeSource->getOffset();
+  if (*bodylength >= bodystartoffsetcrlf) {
+    *bodylength -= bodystartoffsetcrlf;
+    if (*bodylength >= (unsigned int) *boundarysize) {
+      *bodylength -= (unsigned int) *boundarysize;
+    } else {
+      *bodylength = 0;
+    }
+  } else {
+    *bodylength = 0;
+  }
+  MPFDEB((stderr, "BINC: parseSimple ret: bodylength %d, boundarysize %d\n",
+	  *bodylength, *boundarysize));
+}
+
+//------------------------------------------------------------------------
+int Binc::MimePart::doParseFull(MimeInputSource *ms, const string &toboundary,
+				int &boundarysize)
+{
+  MPFDEB((stderr, "BINC: doParsefull, toboundary[%s]\n", toboundary.c_str()));
+  mimeSource = ms;
+  headerstartoffsetcrlf = mimeSource->getOffset();
+
+  // Parse the header of this mime part.
+  parseHeader(&h, &nlines);
+
+  // Headerlength includes the seperating CRLF. Body starts after the
+  // CRLF.
+  headerlength = mimeSource->getOffset() - headerstartoffsetcrlf;
+  bodystartoffsetcrlf = mimeSource->getOffset();
+  MPFDEB((stderr, "BINC: doParsefull, bodystartoffsetcrlf %d\n", bodystartoffsetcrlf));
+  bodylength = 0;
+
+  // Determine the type of mime part by looking at fields in the
+  // header.
+  analyzeHeader(&h, &multipart, &messagerfc822, &subtype, &boundary);
+
+  bool eof = false;
+  bool foundendofpart = false;
+
+  if (messagerfc822) {
+    parseMessageRFC822(&members, &foundendofpart, &bodylength,
+		       &nbodylines, toboundary);
+
+  } else if (multipart) {
+    parseMultipart(boundary, toboundary, &eof, &nlines, &boundarysize,
+		   &foundendofpart, &bodylength,
+		   &members);
+  } else {
+    parseSinglePart(toboundary, &boundarysize, &nbodylines, &nlines,
+		    &eof, &foundendofpart, &bodylength);
+  }
+
+  MPFDEB((stderr, "BINC: doParsefull ret, toboundary[%s]\n", toboundary.c_str()));
+  return (eof || foundendofpart) ? 1 : 0;
+}
diff --git a/src/bincimapmime/mime-parseonlyheader.cc b/src/bincimapmime/mime-parseonlyheader.cc
new file mode 100644
index 00000000..233cb858
--- /dev/null
+++ b/src/bincimapmime/mime-parseonlyheader.cc
@@ -0,0 +1,189 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    mime-parseonlyheader.cc
+ *  
+ *  Description:
+ *    Implementation of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#include "mime.h"
+#include "mime-utils.h"
+#include "mime-inputsource.h"
+#include "convert.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#ifndef NO_NAMESPACES
+using namespace ::std;
+#endif /* NO_NAMESPACES */
+
+//------------------------------------------------------------------------
+void Binc::MimeDocument::parseOnlyHeader(int fd)
+{
+  if (allIsParsed || headerIsParsed)
+    return;
+  
+  headerIsParsed = true;
+
+  delete doc_mimeSource;
+  doc_mimeSource = new MimeInputSource(fd);
+
+  headerstartoffsetcrlf = 0;
+  headerlength = 0;
+  bodystartoffsetcrlf = 0;
+  bodylength = 0;
+  messagerfc822 = false;
+  multipart = false;
+
+  nlines = 0;
+  nbodylines = 0;
+
+  doParseOnlyHeader(doc_mimeSource, "");
+}
+
+void Binc::MimeDocument::parseOnlyHeader(istream& s)
+{
+  if (allIsParsed || headerIsParsed)
+    return;
+  
+  headerIsParsed = true;
+
+  delete doc_mimeSource;
+  doc_mimeSource = new MimeInputSourceStream(s);
+
+  headerstartoffsetcrlf = 0;
+  headerlength = 0;
+  bodystartoffsetcrlf = 0;
+  bodylength = 0;
+  messagerfc822 = false;
+  multipart = false;
+
+  nlines = 0;
+  nbodylines = 0;
+
+  doParseOnlyHeader(doc_mimeSource, "");
+}
+
+//------------------------------------------------------------------------
+int Binc::MimePart::doParseOnlyHeader(MimeInputSource *ms, 
+				      const string &toboundary)
+{
+  mimeSource = ms;
+  string name;
+  string content;
+  char cqueue[4];
+  memset(cqueue, 0, sizeof(cqueue));
+
+  headerstartoffsetcrlf = mimeSource->getOffset();
+
+  bool quit = false;
+  char c = '\0';
+
+  while (!quit) {
+    // read name
+    while (1) {
+      if (!mimeSource->getChar(&c)) {
+	quit = true;
+	break;
+      }
+
+      if (c == '\n') ++nlines;
+      if (c == ':') break;
+      if (c == '\n') {
+    for (int i = int(name.length()) - 1; i >= 0; --i)
+	  mimeSource->ungetChar();
+
+	quit = true;
+	name.clear();
+	break;
+      }
+
+      name += c;
+
+      if (name.length() == 2 && name.substr(0, 2) == "\r\n") {
+	name.clear();
+	quit = true;
+	break;
+      }
+    }
+
+    if (name.length() == 1 && name[0] == '\r') {
+      name.clear();
+      break;
+    }
+
+    if (quit) break;
+
+    while (!quit) {
+      if (!mimeSource->getChar(&c)) {
+	quit = true;
+	break;
+      }
+
+      if (c == '\n') ++nlines;
+
+      for (int i = 0; i < 3; ++i)
+	cqueue[i] = cqueue[i + 1];
+      cqueue[3] = c;
+
+      if (strncmp(cqueue, "\r\n\r\n", 4) == 0) {
+	quit = true;
+	break;
+      }
+
+      if (cqueue[2] == '\n') {
+
+	// guess the mime rfc says what can not appear on the beginning
+	// of a line.
+	if (!isspace(cqueue[3])) {
+	  if (content.length() > 2)
+	    content.resize(content.length() - 2);
+
+	  trim(content);
+	  h.add(name, content);
+
+	  name = c;
+	  content.clear();
+	  break;
+	}
+      }
+
+      content += c;
+    }
+  }
+
+  if (name != "") {
+    if (content.length() > 2)
+      content.resize(content.length() - 2);
+    h.add(name, content);
+  }
+
+  headerlength = mimeSource->getOffset() - headerstartoffsetcrlf;
+
+  return 1;
+}
diff --git a/src/bincimapmime/mime-printbody.cc b/src/bincimapmime/mime-printbody.cc
new file mode 100644
index 00000000..6f8268f6
--- /dev/null
+++ b/src/bincimapmime/mime-printbody.cc
@@ -0,0 +1,52 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    mime-printbody.cc
+ *  
+ *  Description:
+ *    Implementation of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+
+#include "mime.h"
+#include "mime-utils.h"
+#include "mime-inputsource.h"
+
+#include 
+
+using namespace ::std;
+
+void Binc::MimePart::getBody(string &s,
+			     unsigned int startoffset,
+			     unsigned int length) const
+{
+  mimeSource->reset();
+  mimeSource->seek(bodystartoffsetcrlf + startoffset);
+  s.reserve(length);
+  if (startoffset + length > bodylength)
+    length = bodylength - startoffset;
+
+  char c = '\0';
+  for (unsigned int i = 0; i < length; ++i) {
+    if (!mimeSource->getChar(&c))
+      break;
+
+    s += (char)c;
+  }
+}
diff --git a/src/bincimapmime/mime-utils.h b/src/bincimapmime/mime-utils.h
new file mode 100644
index 00000000..93b5707f
--- /dev/null
+++ b/src/bincimapmime/mime-utils.h
@@ -0,0 +1,50 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    mime.cc
+ *  
+ *  Description:
+ *    Implementation of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#ifndef mime_utils_h_included
+#define mime_utils_h_included
+#include 
+#include 
+#include 
+#include 
+
+#ifndef NO_NAMESPACES
+using namespace ::std;
+#endif /* NO_NAMESPACES */
+
+inline bool compareStringToQueue(const char *s_in, char *bqueue,
+				 int pos, int size)
+{
+  for (int i = 0; i < size; ++i)  {
+    if (s_in[i] != bqueue[pos])
+      return false;
+    if (++pos == size)
+      pos = 0;
+  }
+
+  return true;
+}
+
+#endif
diff --git a/src/bincimapmime/mime.cc b/src/bincimapmime/mime.cc
new file mode 100644
index 00000000..7b1ba842
--- /dev/null
+++ b/src/bincimapmime/mime.cc
@@ -0,0 +1,164 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    mime.cc
+ *  
+ *  Description:
+ *    Implementation of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#ifndef NO_NAMESPACES
+using namespace ::std;
+#endif /* NO_NAMESPACES */
+
+
+#include "mime.h"
+#include "convert.h"
+#include "mime-inputsource.h"
+
+//------------------------------------------------------------------------
+Binc::MimeDocument::MimeDocument(void)
+{
+  allIsParsed = false;
+  headerIsParsed = false;
+  doc_mimeSource = 0;
+}
+
+//------------------------------------------------------------------------
+Binc::MimeDocument::~MimeDocument(void)
+{
+  delete doc_mimeSource;
+  doc_mimeSource = 0;
+}
+
+//------------------------------------------------------------------------
+void Binc::MimeDocument::clear(void)
+{
+  members.clear();
+  h.clear();
+  headerIsParsed = false;
+  allIsParsed = false;
+  delete doc_mimeSource;
+  doc_mimeSource = 0;
+}
+
+//------------------------------------------------------------------------
+void Binc::MimePart::clear(void)
+{
+  members.clear();
+  h.clear();
+  mimeSource = 0;
+}
+
+//------------------------------------------------------------------------
+Binc::MimePart::MimePart(void)
+{
+  size = 0;
+  messagerfc822 = false;
+  multipart = false;
+
+  nlines = 0;
+  nbodylines = 0;
+  mimeSource = 0;
+}
+
+//------------------------------------------------------------------------
+Binc::MimePart::~MimePart(void)
+{
+}
+
+//------------------------------------------------------------------------
+Binc::HeaderItem::HeaderItem(void)
+{
+}
+
+//------------------------------------------------------------------------
+Binc::HeaderItem::HeaderItem(const string &key, const string &value)
+{
+  this->key = key;
+  this->value = value;
+}
+
+//------------------------------------------------------------------------
+Binc::Header::Header(void)
+{
+}
+
+//------------------------------------------------------------------------
+Binc::Header::~Header(void)
+{
+}
+
+//------------------------------------------------------------------------
+bool Binc::Header::getFirstHeader(const string &key, HeaderItem &dest) const
+{
+  string k = key;
+  lowercase(k);
+
+  for (vector::const_iterator i = content.begin();
+       i != content.end(); ++i) {
+    string tmp = (*i).getKey();
+    lowercase(tmp);
+
+    if (tmp == k) {
+      dest = *i;
+      return true;
+    }
+  }
+  return false;
+}
+
+//------------------------------------------------------------------------
+bool Binc::Header::getAllHeaders(const string &key, vector &dest) const
+{
+  string k = key;
+  lowercase(k);
+
+  for (vector::const_iterator i = content.begin();
+       i != content.end(); ++i) {
+    string tmp = (*i).getKey();
+    lowercase(tmp);
+    if (tmp == k)
+      dest.push_back(*i);
+  }
+
+  return (dest.size() != 0);
+}
+
+//------------------------------------------------------------------------
+void Binc::Header::clear(void)
+{
+  content.clear();
+}
+
+//------------------------------------------------------------------------
+void Binc::Header::add(const string &key, const string &value)
+{
+  content.push_back(HeaderItem(key, value));
+}
diff --git a/src/bincimapmime/mime.h b/src/bincimapmime/mime.h
new file mode 100644
index 00000000..d047c917
--- /dev/null
+++ b/src/bincimapmime/mime.h
@@ -0,0 +1,187 @@
+/* -*- mode:c++;c-basic-offset:2 -*- */
+/*  --------------------------------------------------------------------
+ *  Filename:
+ *    src/parsers/mime/mime.h
+ *  
+ *  Description:
+ *    Declaration of main mime parser components
+ *  --------------------------------------------------------------------
+ *  Copyright 2002-2005 Andreas Aardal Hanssen
+ *
+ *  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 Street #330, Boston, MA 02111-1307, USA.
+ *  --------------------------------------------------------------------
+ */
+#ifndef mime_h_included
+#define mime_h_included
+#include 
+#include 
+#include 
+#include 
+
+namespace Binc {
+
+  class MimeInputSource;
+
+
+  //---------------------------------------------------------------------- 
+  class HeaderItem {
+  private:
+    mutable std::string key;
+    mutable std::string value;
+
+  public:
+    inline const std::string &getKey(void) const { return key; }
+    inline const std::string &getValue(void) const { return value; }
+
+    //--
+    HeaderItem(void);
+    HeaderItem(const std::string &key, const std::string &value);
+  };
+
+  //---------------------------------------------------------------------- 
+  class Header {
+  private:
+    mutable std::vector content;
+
+  public:
+    bool getFirstHeader(const std::string &key, HeaderItem &dest) const;
+    bool getAllHeaders(const std::string &key, std::vector &dest) const;
+    void add(const std::string &name, const std::string &content);
+    void clear(void);
+
+    //--
+    Header(void);
+    ~Header(void);
+  };
+
+  //----------------------------------------------------------------------
+  class IODevice;
+  class MimeDocument;
+  class MimePart {
+  protected:
+  public:
+    mutable bool multipart;
+    mutable bool messagerfc822;
+    mutable std::string subtype;
+    mutable std::string boundary;
+
+    mutable unsigned int headerstartoffsetcrlf;
+    mutable unsigned int headerlength;
+
+    mutable unsigned int bodystartoffsetcrlf;
+    mutable unsigned int bodylength;
+    mutable unsigned int nlines;
+    mutable unsigned int nbodylines;
+    mutable unsigned int size;
+
+  public:
+    enum FetchType {
+      FetchBody,
+      FetchHeader,
+      FetchMime
+    };
+
+    mutable Header h;
+
+    mutable std::vector members;
+
+    inline const std::string &getSubType(void) const { return subtype; }
+    inline bool isMultipart(void) const { return multipart; }
+    inline bool isMessageRFC822(void) const { return messagerfc822; }
+    inline unsigned int getSize(void) const { return bodylength; }
+    inline unsigned int getNofLines(void) const { return nlines; }
+    inline unsigned int getNofBodyLines(void) const { return nbodylines; }
+    inline unsigned int getBodyLength(void) const { return bodylength; }
+    inline unsigned int getBodyStartOffset(void) const { return bodystartoffsetcrlf; }
+
+    void printBody(Binc::IODevice &output, unsigned int startoffset, unsigned int length) const;
+      void getBody(std::string& s, unsigned int startoffset, unsigned int length) const;
+    virtual void clear(void);
+
+    virtual int doParseOnlyHeader(MimeInputSource *ms, 
+				  const std::string &toboundary);
+    virtual int doParseFull(MimeInputSource *ms, 
+			    const std::string &toboundary, int &boundarysize);
+
+    MimePart(void);
+    virtual ~MimePart(void);
+
+  private:
+    MimeInputSource *mimeSource;
+
+    bool parseOneHeaderLine(Binc::Header *header, unsigned int *nlines);
+
+    bool skipUntilBoundary(const std::string &delimiter,
+			   unsigned int *nlines, bool *eof);
+    inline void postBoundaryProcessing(bool *eof,
+				       unsigned int *nlines,
+				       int *boundarysize,
+				       bool *foundendofpart);
+      void parseMultipart(const std::string &boundary,
+			   const std::string &toboundary,
+			   bool *eof,
+			   unsigned int *nlines,
+			   int *boundarysize,
+			   bool *foundendofpart,
+			   unsigned int *bodylength,
+			  std::vector *members);
+      void parseSinglePart(const std::string &toboundary,
+			    int *boundarysize,
+			    unsigned int *nbodylines,
+			    unsigned int *nlines,
+			    bool *eof, bool *foundendofpart,
+			   unsigned int *bodylength);
+    void parseHeader(Binc::Header *header, unsigned int *nlines);
+    void analyzeHeader(Binc::Header *header, bool *multipart,
+		       bool *messagerfc822, std::string *subtype,
+		       std::string *boundary);
+    void parseMessageRFC822(std::vector *members,
+			    bool *foundendofpart,
+			    unsigned int *bodylength,
+			    unsigned int *nbodylines,
+			    const std::string &toboundary);
+  };
+
+  //----------------------------------------------------------------------
+  class MimeDocument : public MimePart {
+  public:
+    MimeDocument(void);
+    ~MimeDocument(void);
+
+    void parseOnlyHeader(int fd);
+    void parseFull(int fd);
+    void parseOnlyHeader(std::istream& s);
+    void parseFull(std::istream& s);
+
+    void clear(void);
+    
+    bool isHeaderParsed(void) const 
+    {
+      return headerIsParsed; 
+    }
+    bool isAllParsed(void) const 
+    { 
+      return allIsParsed; 
+    }
+
+  private:
+    bool headerIsParsed;
+    bool allIsParsed;
+    MimeInputSource *doc_mimeSource;
+  };
+
+};
+
+#endif
diff --git a/src/bincimapmime/trbinc.cc b/src/bincimapmime/trbinc.cc
new file mode 100644
index 00000000..fe2db3d1
--- /dev/null
+++ b/src/bincimapmime/trbinc.cc
@@ -0,0 +1,126 @@
+/* Copyright (C) 2006 J.F.Dockes
+ *   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.
+ */
+
+#include 
+#include 
+#include 
+#include "safefcntl.h"
+#include "safeunistd.h"
+#include 
+
+#include 
+
+#ifndef NO_NAMESPACES
+using namespace std;
+#endif /* NO_NAMESPACES */
+
+#include "mime.h"
+
+static char *thisprog;
+
+static char usage [] =
+    "trbinc  \n\n"
+    ;
+static void
+Usage(void)
+{
+    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
+    exit(1);
+}
+
+static int     op_flags;
+#define OPT_MOINS 0x1
+#define OPT_s	  0x2 
+#define OPT_b	  0x4 
+
+#define DEFCOUNT 10
+
+const char *hnames[] = {"Subject", "Content-type"};
+int nh = sizeof(hnames) / sizeof(char *);
+
+int main(int argc, char **argv)
+{
+    int count = DEFCOUNT;
+    
+    thisprog = argv[0];
+    argc--; argv++;
+
+    while (argc > 0 && **argv == '-') {
+	(*argv)++;
+	if (!(**argv))
+	    /* Cas du "adb - core" */
+	    Usage();
+	while (**argv)
+	    switch (*(*argv)++) {
+	    case 's':	op_flags |= OPT_s; break;
+	    case 'b':	op_flags |= OPT_b; if (argc < 2)  Usage();
+		if ((sscanf(*(++argv), "%d", &count)) != 1) 
+		    Usage(); 
+		argc--; 
+		goto b1;
+	    default: Usage();	break;
+	    }
+    b1: argc--; argv++;
+    }
+
+    if (argc != 1)
+	Usage();
+
+    char *mfile = *argv++;argc--;
+    int fd;
+    if ((fd = open(mfile, 0)) < 0) {
+	perror("Opening");
+	exit(1);
+    }
+    Binc::MimeDocument doc;
+
+#if 0
+    doc.parseFull(fd);
+#else
+    char *cp;
+    int size = lseek(fd, 0, SEEK_END);
+    lseek(fd, 0, 0);
+    fprintf(stderr, "Size: %d\n", size);
+    cp = (char *)malloc(size);
+    if (cp==0) {
+	fprintf(stderr, "Malloc %d failed\n", size);
+	exit(1);
+    }
+    int n;
+    if ((n=read(fd, cp, size)) != size) {
+	fprintf(stderr, "Read failed: requested %d, got %d\n", size, n);
+	exit(1);
+    }
+    std::stringstream s(string(cp, size), ios::in);
+    doc.parseFull(s);
+#endif
+
+    if (!doc.isHeaderParsed() && !doc.isAllParsed()) {
+	fprintf(stderr, "Parse error\n");
+	exit(1);
+    }
+    close(fd);
+    Binc::HeaderItem hi;
+    for (int i = 0; i < nh ; i++) {
+	if (!doc.h.getFirstHeader(hnames[i], hi)) {
+	    fprintf(stderr, "No %s\n", hnames[i]);
+	    exit(1);
+	}
+	printf("%s: %s\n", hnames[i], hi.getValue().c_str());
+    }
+    exit(0);
+}
diff --git a/src/common/Makefile b/src/common/Makefile
new file mode 100644
index 00000000..c30268bc
--- /dev/null
+++ b/src/common/Makefile
@@ -0,0 +1,33 @@
+
+PROGS = unacpp textsplit rclconfig syngroups
+
+all: $(PROGS) 
+
+UNACPP_OBJS= trunacpp.o
+unacpp : $(UNACPP_OBJS)
+	$(CXX) $(ALL_CXXFLAGS) -o unacpp $(UNACPP_OBJS) $(LIBRECOLL)
+trunacpp.o : unacpp.cpp unacpp.h
+	$(CXX) $(ALL_CXXFLAGS) -DTEST_UNACPP -c -o trunacpp.o unacpp.cpp
+
+TEXTSPLIT_OBJS= trtextsplit.o  
+textsplit : $(TEXTSPLIT_OBJS)
+	$(CXX) $(ALL_CXXFLAGS) -o textsplit $(TEXTSPLIT_OBJS) $(LIBRECOLL)
+trtextsplit.o : textsplit.cpp 
+	$(CXX) $(ALL_CXXFLAGS) -DTEST_TEXTSPLIT -c -o trtextsplit.o \
+	       textsplit.cpp
+
+RCLCONFIG_OBJS= trrclconfig.o 
+rclconfig : $(RCLCONFIG_OBJS) 
+	$(CXX) $(ALL_CXXFLAGS) -o rclconfig $(RCLCONFIG_OBJS) $(LIBRECOLL) 
+trrclconfig.o : rclconfig.cpp 
+	$(CXX) $(ALL_CXXFLAGS) -DTEST_RCLCONFIG -c -o trrclconfig.o \
+	       rclconfig.cpp
+
+SYNGROUPS_OBJS= trsyngroups.o 
+syngroups : $(SYNGROUPS_OBJS) 
+	$(CXX) $(ALL_CXXFLAGS) -o syngroups $(SYNGROUPS_OBJS) $(LIBRECOLL) 
+trsyngroups.o : syngroups.cpp 
+	$(CXX) $(ALL_CXXFLAGS) -DTEST_SYNGROUPS -c -o trsyngroups.o \
+	       syngroups.cpp
+
+include ../utils/utmkdefs.mk
diff --git a/src/common/autoconfig-win.h b/src/common/autoconfig-win.h
new file mode 100644
index 00000000..948f7a3e
--- /dev/null
+++ b/src/common/autoconfig-win.h
@@ -0,0 +1,183 @@
+/* Manually edited version of autoconfig.h for windows. Many things are
+overriden in the c++ code by ifdefs _WIN32 anyway  */
+#ifndef _AUTOCONFIG_H_INCLUDED
+#define _AUTOCONFIG_H_INCLUDED
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* Path to the aspell api include file */
+/* #undef ASPELL_INCLUDE "aspell-local.h" */
+
+/* Path to the aspell program */
+/* #define ASPELL_PROG "/usr/bin/aspell" */
+
+/* No X11 session monitoring support */
+#define DISABLE_X11MON
+
+/* Path to the fam api include file */
+/* #undef FAM_INCLUDE */
+
+/* Path to the file program */
+#define FILE_PROG "/usr/bin/file"
+
+/* "Have C++0x" */
+#define HAVE_CXX0X_UNORDERED 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#define HAVE_LIBDL 1
+
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mkdtemp' function. */
+/* #undef HAVE_MKDTEMP */
+
+/* Define to 1 if you have the `posix_spawn,' function. */
+/* #undef HAVE_POSIX_SPAWN_ */
+
+/* Define to 1 if you have the `setrlimit' function. */
+#define HAVE_SETRLIMIT 1
+
+/* Has std::shared_ptr */
+#define HAVE_SHARED_PTR_STD
+
+/* Has std::tr1::shared_ptr */
+/* #undef HAVE_SHARED_PTR_TR1 */
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_SPAWN_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_SYS_MOUNT_H */
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_SYS_PARAM_H_ */
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_SYS_STATFS_H */
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_SYS_STATVFS_H */
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the  header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_SYS_VFS_H */
+
+/* "Have tr1" */
+/* #undef HAVE_TR1_UNORDERED */
+
+/* Define to 1 if you have the  header file. */
+/* #undef HAVE_UNISTD_H */
+
+/* Use multiple threads for indexing */
+#define IDX_THREADS 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Recoll"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Recoll 1.23.0-x"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "recoll"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.23.0-x"
+
+/* putenv parameter is const */
+/* #undef PUTENV_ARG_CONST */
+
+/* iconv parameter 2 is const char** */
+#define RCL_ICONV_INBUF_CONST 1
+
+/* Real time monitoring option */
+#undef RCL_MONITOR
+
+/* Split camelCase words */
+/* #undef RCL_SPLIT_CAMELCASE */
+
+/* Compile the aspell interface */
+/* #undef RCL_USE_ASPELL */
+
+/* Compile the fam interface */
+/* #undef RCL_USE_FAM */
+
+/* Compile the inotify interface */
+#define RCL_USE_INOTIFY 1
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Use posix_spawn() */
+/* #undef USE_POSIX_SPAWN */
+
+/* Enable using the system's 'file' command to id mime if we fail internally
+   */
+/* #undef USE_SYSTEM_FILE_COMMAND */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if the X Window System is missing or not being used. */
+/* #undef X_DISPLAY_MISSING */
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+/* #undef _FILE_OFFSET_BITS */
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+#define DISABLE_WEB_INDEXER
+
+#include "conf_post.h"
+#endif // already included
diff --git a/src/common/autoconfig.h.in b/src/common/autoconfig.h.in
new file mode 100644
index 00000000..545d914c
--- /dev/null
+++ b/src/common/autoconfig.h.in
@@ -0,0 +1,180 @@
+/* common/autoconfig.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+#undef AC_APPLE_UNIVERSAL_BUILD
+
+/* Path to the aspell api include file */
+#undef ASPELL_INCLUDE
+
+/* Path to the aspell program */
+#undef ASPELL_PROG
+
+/* No X11 session monitoring support */
+#undef DISABLE_X11MON
+
+/* Path to the fam api include file */
+#undef FAM_INCLUDE
+
+/* Path to the file program */
+#undef FILE_PROG
+
+/* "Have C++0x" */
+#undef HAVE_CXX0X_UNORDERED
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
+/* Define to 1 if you have the `posix_spawn,' function. */
+#undef HAVE_POSIX_SPAWN_
+
+/* Define to 1 if you have the `setrlimit' function. */
+#undef HAVE_SETRLIMIT
+
+/* Has std::shared_ptr */
+#undef HAVE_SHARED_PTR_STD
+
+/* Has std::tr1::shared_ptr */
+#undef HAVE_SHARED_PTR_TR1
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SPAWN_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_PARAM_H_
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_STATFS_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_STATVFS_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_SYS_VFS_H
+
+/* "Have tr1" */
+#undef HAVE_TR1_UNORDERED
+
+/* Define to 1 if you have the  header file. */
+#undef HAVE_UNISTD_H
+
+/* Use multiple threads for indexing */
+#undef IDX_THREADS
+
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
+#undef LT_OBJDIR
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* putenv parameter is const */
+#undef PUTENV_ARG_CONST
+
+/* iconv parameter 2 is const char** */
+#undef RCL_ICONV_INBUF_CONST
+
+/* Real time monitoring option */
+#undef RCL_MONITOR
+
+/* Split camelCase words */
+#undef RCL_SPLIT_CAMELCASE
+
+/* Compile the aspell interface */
+#undef RCL_USE_ASPELL
+
+/* Compile the fam interface */
+#undef RCL_USE_FAM
+
+/* Compile the inotify interface */
+#undef RCL_USE_INOTIFY
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Use posix_spawn() */
+#undef USE_POSIX_SPAWN
+
+/* Enable using the system's 'file' command to id mime if we fail internally
+   */
+#undef USE_SYSTEM_FILE_COMMAND
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+#  undef WORDS_BIGENDIAN
+# endif
+#endif
+
+/* Define to 1 if the X Window System is missing or not being used. */
+#undef X_DISPLAY_MISSING
+
+/* Enable large inode numbers on Mac OS X 10.5.  */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
+#include "conf_post.h"
diff --git a/src/common/beaglequeuecache.cpp b/src/common/beaglequeuecache.cpp
new file mode 100644
index 00000000..c14b12fb
--- /dev/null
+++ b/src/common/beaglequeuecache.cpp
@@ -0,0 +1,88 @@
+/* Copyright (C) 2011 J.F.Dockes
+ *   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.
+ */
+
+#include "autoconfig.h"
+
+#include "cstr.h"
+#include "beaglequeuecache.h"
+#include "circache.h"
+#include "log.h"
+#include "rclconfig.h"
+#include "pathut.h"
+#include "rcldoc.h"
+
+const string cstr_bgc_mimetype("mimetype");
+
+BeagleQueueCache::BeagleQueueCache(RclConfig *cnf) 
+{
+    string ccdir = cnf->getWebcacheDir();
+
+    int maxmbs = 40;
+    cnf->getConfParam("webcachemaxmbs", &maxmbs);
+    if ((m_cache = new CirCache(ccdir)) == 0) {
+	LOGERR("BeagleQueueCache: cant create CirCache object\n" );
+	return;
+    }
+    if (!m_cache->create(off_t(maxmbs)*1000*1024, CirCache::CC_CRUNIQUE)) {
+	LOGERR("BeagleQueueCache: cache file creation failed: "  << (m_cache->getReason()) << "\n" );
+	delete m_cache;
+	m_cache = 0;
+	return;
+    }
+}
+
+BeagleQueueCache::~BeagleQueueCache()
+{
+    delete m_cache;
+}
+
+// Read  document from cache. Return the metadata as an Rcl::Doc
+// @param htt Beagle Hit Type 
+bool BeagleQueueCache::getFromCache(const string& udi, Rcl::Doc &dotdoc, 
+				    string& data, string *htt)
+{
+    string dict;
+
+    if (m_cache == 0) {
+	LOGERR("BeagleQueueCache::getFromCache: cache is null\n" );
+	return false;
+    }
+    if (!m_cache->get(udi, dict, &data)) {
+	LOGDEB("BeagleQueueCache::getFromCache: get failed\n" );
+	return false;
+    }
+
+    ConfSimple cf(dict, 1);
+    
+    if (htt)
+        cf.get(Rcl::Doc::keybght, *htt, cstr_null);
+
+    // Build a doc from saved metadata 
+    cf.get(cstr_url, dotdoc.url, cstr_null);
+    cf.get(cstr_bgc_mimetype, dotdoc.mimetype, cstr_null);
+    cf.get(cstr_fmtime, dotdoc.fmtime, cstr_null);
+    cf.get(cstr_fbytes, dotdoc.pcbytes, cstr_null);
+    dotdoc.sig.clear();
+    vector names = cf.getNames(cstr_null);
+    for (vector::const_iterator it = names.begin();
+         it != names.end(); it++) {
+        cf.get(*it, dotdoc.meta[*it], cstr_null);
+    }
+    dotdoc.meta[Rcl::Doc::keyudi] = udi;
+    return true;
+}
+
diff --git a/src/common/beaglequeuecache.h b/src/common/beaglequeuecache.h
new file mode 100644
index 00000000..5297d61c
--- /dev/null
+++ b/src/common/beaglequeuecache.h
@@ -0,0 +1,50 @@
+/* Copyright (C) 2009 J.F.Dockes
+ *   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.
+ */
+#ifndef _beaglequeuecache_h_included_
+#define _beaglequeuecache_h_included_
+
+#include 
+using std::string;
+
+class RclConfig;
+namespace Rcl {
+    class Db;
+    class Doc;
+}
+class CirCache;
+
+/**
+ * Manage the CirCache for the Beagle Queue indexer. Separated from the main
+ * indexer code because it's also used for querying (getting the data for a
+ * preview 
+ */
+class BeagleQueueCache {
+public:
+    BeagleQueueCache(RclConfig *config);
+    ~BeagleQueueCache();
+
+    bool getFromCache(const string& udi, Rcl::Doc &doc, string& data,
+                      string *hittype = 0);
+    // We could write proxies for all the circache ops, but why bother?
+    CirCache *cc() {return m_cache;}
+
+private:
+    CirCache *m_cache;
+};
+extern const string cstr_bgc_mimetype;
+
+#endif /* _beaglequeuecache_h_included_ */
diff --git a/src/common/conf_post.h b/src/common/conf_post.h
new file mode 100644
index 00000000..43fa5c54
--- /dev/null
+++ b/src/common/conf_post.h
@@ -0,0 +1,51 @@
+
+#ifdef _WIN32
+#include "safewindows.h"
+
+
+#ifdef _MSC_VER
+// gmtime is supposedly thread-safe on windows
+#define gmtime_r(A, B) gmtime(A)
+#define localtime_r(A,B) localtime(A)
+typedef int mode_t;
+#define fseeko _fseeki64
+#define ftello (off_t)_ftelli64
+#define ftruncate _chsize_s
+#define PATH_MAX MAX_PATH
+#define RCL_ICONV_INBUF_CONST 1
+#define HAVE_STRUCT_TIMESPEC
+#define strdup _strdup
+#define timegm _mkgmtime
+
+#else // End _MSC_VER -> Gminw
+
+#undef RCL_ICONV_INBUF_CONST
+#define timegm portable_timegm
+
+#endif // GMinw only
+
+typedef int pid_t;
+inline int readlink(const char *cp, void *buf, int cnt)
+{
+    return -1;
+}
+
+#define MAXPATHLEN PATH_MAX
+typedef DWORD32 u_int32_t;
+typedef DWORD64 u_int64_t;
+typedef unsigned __int8 u_int8_t;
+typedef int ssize_t;
+#define strncasecmp _strnicmp
+#define strcasecmp _stricmp
+#define chdir _chdir
+
+#define R_OK 4
+#define W_OK 2
+#ifndef X_OK
+#define X_OK 4
+#endif
+
+#define S_ISLNK(X) false
+#define lstat stat
+
+#endif // _WIN32
diff --git a/src/common/cstr.cpp b/src/common/cstr.cpp
new file mode 100644
index 00000000..0119e809
--- /dev/null
+++ b/src/common/cstr.cpp
@@ -0,0 +1,6 @@
+
+#include "cstr.h"
+#define RCLIN_CSTR_CPPFILE
+#undef _CSTR_H_INCLUDED_
+#include "cstr.h"
+
diff --git a/src/common/cstr.h b/src/common/cstr.h
new file mode 100644
index 00000000..7f41099b
--- /dev/null
+++ b/src/common/cstr.h
@@ -0,0 +1,85 @@
+/* Copyright (C) 2011 J.F.Dockes
+ *   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.
+ */
+
+#ifndef _CSTR_H_INCLUDED_
+#define _CSTR_H_INCLUDED_
+
+// recoll mostly uses STL strings. In many places we had automatic
+// conversion from a C string to an STL one. This costs, and can
+// become significant if used often.
+//
+// This file and the associated .cpp file declares/defines constant
+// strings used in the program. Strings are candidates for a move here
+// when they are used in a fast loop or are shared.
+
+#include 
+using std::string;
+
+// The following slightly hacky preprocessing directives and the
+// companion code in the cpp file looks complicated, but it just
+// ensures that we only have to write the strings once to get the
+// extern declaration and the definition.
+#ifdef RCLIN_CSTR_CPPFILE
+#undef DEF_CSTR
+#define DEF_CSTR(NM, STR) const string cstr_##NM(STR)
+#else
+#define DEF_CSTR(NM, STR) extern const string cstr_##NM
+#endif
+
+DEF_CSTR(caption, "caption");
+DEF_CSTR(colon, ":");
+DEF_CSTR(dmtime, "dmtime");
+DEF_CSTR(dquote, "\"");
+DEF_CSTR(fbytes, "fbytes");
+DEF_CSTR(fileu, "file://");
+DEF_CSTR(fmtime, "fmtime");
+DEF_CSTR(iso_8859_1, "ISO-8859-1");
+DEF_CSTR(utf8, "UTF-8");
+DEF_CSTR(cp1252, "CP1252");
+DEF_CSTR(minwilds, "*?[");
+DEF_CSTR(newline, "\n");
+DEF_CSTR(null, "");
+DEF_CSTR(plus, "+");
+DEF_CSTR(textplain, "text/plain");
+DEF_CSTR(url, "url");
+// Marker for HTML format fields
+DEF_CSTR(fldhtm, "\007");
+// Characters that can -begin- a wildcard or regexp expression. 
+DEF_CSTR(wildSpecStChars, "*?[");
+DEF_CSTR(regSpecStChars, "(.[{");
+
+// Values used as keys inside Dijon::Filter::metaData[]. This structure is 
+// used to store all data generated by format-translating filters. It is
+// different from Rcl::Doc for mostly historical reasons. The translation
+// from Filter to Doc occurs inside internfile.cpp
+DEF_CSTR(dj_keyds, "description");
+DEF_CSTR(dj_keyfn, "filename");
+DEF_CSTR(dj_keymd, "modificationdate");
+DEF_CSTR(dj_keyorigcharset, "origcharset");
+DEF_CSTR(dj_keytitle, "title");
+DEF_CSTR(dj_keyrecipient, "recipient");
+DEF_CSTR(dj_keymsgid, "msgid");
+DEF_CSTR(dj_keyabstract, "abstract");
+DEF_CSTR(dj_keyauthor, "author");
+DEF_CSTR(dj_keycharset, "charset");
+DEF_CSTR(dj_keycontent, "content");
+DEF_CSTR(dj_keyipath, "ipath");
+DEF_CSTR(dj_keymd5, "md5");
+DEF_CSTR(dj_keymt, "mimetype");
+DEF_CSTR(dj_keyanc, "rclanc");
+
+#endif /* _CSTR_H_INCLUDED_ */
diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp
new file mode 100644
index 00000000..fd767a79
--- /dev/null
+++ b/src/common/rclconfig.cpp
@@ -0,0 +1,1716 @@
+/* Copyright (C) 2004 J.F.Dockes 
+ *   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.
+ */
+#ifndef TEST_RCLCONFIG
+#include "autoconfig.h"
+
+#include 
+#include 
+#ifndef _WIN32
+#include 
+#include 
+#else
+#include "wincodepages.h"
+#endif
+#include 
+#include "safesysstat.h"
+#include "safeunistd.h"
+#ifdef __FreeBSD__
+#include 
+#endif
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cstr.h"
+#include "pathut.h"
+#include "rclutil.h"
+#include "rclconfig.h"
+#include "conftree.h"
+#include "log.h"
+#include "smallut.h"
+#include "textsplit.h"
+#include "readfile.h"
+#include "fstreewalk.h"
+#include "cpuconf.h"
+#include "execmd.h"
+
+using namespace std;
+
+// Static, logically const, RclConfig members are initialized once from the
+// first object build during process initialization.
+
+// We default to a case- and diacritics-less index for now
+bool o_index_stripchars = true;
+
+bool o_uptodate_test_use_mtime = false;
+
+string RclConfig::o_localecharset; 
+string RclConfig::o_origcwd; 
+
+bool ParamStale::needrecompute()
+{
+    LOGDEB2("ParamStale:: needrecompute. parent gen "  << (parent->m_keydirgen) << " mine "  << (savedkeydirgen) << "\n" );
+    if (active && parent->m_keydirgen != savedkeydirgen) {
+	LOGDEB2("ParamState:: needrecompute. conffile "  << (conffile) << "\n" );
+
+        savedkeydirgen = parent->m_keydirgen;
+        string newvalue;
+        if (!conffile)
+            return false;
+        conffile->get(paramname, newvalue, parent->m_keydir);
+        if (newvalue.compare(savedvalue)) {
+            savedvalue = newvalue;
+	    LOGDEB2("ParamState:: needrecompute. return true newvalue ["  << (newvalue) << "]\n" );
+            return true;
+        }
+    }
+    return false;
+}
+
+void ParamStale::init(ConfNull *cnf)
+{
+    conffile = cnf;
+    active = false;
+    if (conffile)
+      active = conffile->hasNameAnywhere(paramname);
+    savedkeydirgen = -1;
+}
+
+ParamStale::ParamStale(RclConfig *rconf, const string& nm)
+    : parent(rconf), conffile(0), paramname(nm),
+      active(false), savedkeydirgen(-1)
+{
+}
+
+void RclConfig::zeroMe() {
+    m_ok = false; 
+    m_keydirgen = 0;
+    m_conf = 0; 
+    mimemap = 0; 
+    mimeconf = 0; 
+    mimeview = 0; 
+    m_fields = 0;
+    m_ptrans = 0;
+    m_stopsuffixes = 0;
+    m_maxsufflen = 0;
+    initParamStale(0, 0);
+}
+
+bool RclConfig::isDefaultConfig() const
+{
+    string defaultconf = path_cat(path_homedata(),
+                                  path_defaultrecollconfsubdir());
+    path_catslash(defaultconf);
+    string specifiedconf = path_canon(m_confdir);
+    path_catslash(specifiedconf);
+    return !defaultconf.compare(specifiedconf);
+}
+
+RclConfig::RclConfig(const string *argcnf)
+    : m_oldstpsuffstate(this, "recoll_noindex"),
+      m_stpsuffstate(this, "noContentSuffixes"),
+      m_skpnstate(this, "skippedNames"),
+      m_rmtstate(this, "indexedmimetypes"),
+      m_xmtstate(this, "excludedmimetypes"),
+      m_mdrstate(this, "metadatacmds")
+{
+    zeroMe();
+
+    if (o_origcwd.empty()) {
+	char buf[MAXPATHLEN];
+	if (getcwd(buf, MAXPATHLEN)) {
+	    o_origcwd = string(buf);
+	} else {
+	    fprintf(stderr, "recollxx: can't retrieve current working directory: relative path translations will fail\n");
+	}
+    }
+
+    // Compute our data dir name, typically /usr/local/share/recoll
+    m_datadir = path_pkgdatadir();
+    // We only do the automatic configuration creation thing for the default
+    // config dir, not if it was specified through -c or RECOLL_CONFDIR
+    bool autoconfdir = false;
+
+    // Command line config name overrides environment
+    if (argcnf && !argcnf->empty()) {
+	m_confdir = path_absolute(*argcnf);
+	if (m_confdir.empty()) {
+	    m_reason = 
+		string("Cant turn [") + *argcnf + "] into absolute path";
+	    return;
+	}
+    } else {
+	const char *cp = getenv("RECOLL_CONFDIR");
+	if (cp) {
+	    m_confdir = path_canon(cp);
+	} else {
+	    autoconfdir = true;
+	    m_confdir = path_cat(path_homedata(), path_defaultrecollconfsubdir());
+	}
+    }
+
+    // Note: autoconfdir and isDefaultConfig() are normally the same. We just 
+    // want to avoid the imperfect test in isDefaultConfig() if we actually know
+    // this is the default conf
+    if (!autoconfdir && !isDefaultConfig()) {
+	if (!path_exists(m_confdir)) {
+	    m_reason = "Explicitly specified configuration "
+		"directory must exist"
+		" (won't be automatically created). Use mkdir first";
+	    return;
+	}
+    }
+
+    if (!path_exists(m_confdir)) {
+	if (!initUserConfig()) 
+	    return;
+    }
+
+    // This can't change once computed inside a process. It would be
+    // nicer to move this to a static class initializer to avoid
+    // possible threading issues but this doesn't work (tried) as
+    // things would not be ready. In practise we make sure that this
+    // is called from the main thread at once, by constructing a config
+    // from recollinit
+    if (o_localecharset.empty()) {
+#ifndef _WIN32
+	const char *cp;
+	cp = nl_langinfo(CODESET);
+	// We don't keep US-ASCII. It's better to use a superset
+	// Ie: me have a C locale and some french file names, and I
+	// can't imagine a version of iconv that couldn't translate
+	// from iso8859?
+	// The 646 thing is for solaris. 
+	if (cp && *cp && strcmp(cp, "US-ASCII") 
+#ifdef sun
+	    && strcmp(cp, "646")
+#endif
+	    ) {
+	    o_localecharset = string(cp);
+	} else {
+	    // Use cp1252 instead of iso-8859-1, it's a superset.
+	    o_localecharset = string(cstr_cp1252);
+	}
+#else
+        o_localecharset = winACPName();
+#endif
+	LOGDEB1("RclConfig::getDefCharset: localecharset ["  <<
+                o_localecharset << "]\n");
+    }
+
+    const char *cp;
+
+    // Additional config directory, values override user ones
+    if ((cp = getenv("RECOLL_CONFTOP"))) {
+	m_cdirs.push_back(cp);
+    } 
+
+    // User config
+    m_cdirs.push_back(m_confdir);
+
+    // Additional config directory, overrides system's, overridden by user's
+    if ((cp = getenv("RECOLL_CONFMID"))) {
+	m_cdirs.push_back(cp);
+    } 
+
+    // Base/installation config
+    m_cdirs.push_back(path_cat(m_datadir, "examples"));
+
+    string cnferrloc;
+    for (vector::const_iterator it = m_cdirs.begin();
+	 it != m_cdirs.end(); it++) {
+	if (it != m_cdirs.begin())
+	    cnferrloc += string(" or ");
+	cnferrloc += *it;
+    }
+
+    // Read and process "recoll.conf"
+    if (!updateMainConfig())
+	return;
+    // Other files
+    mimemap = new ConfStack("mimemap", m_cdirs, true);
+    if (mimemap == 0 || !mimemap->ok()) {
+	m_reason = string("No or bad mimemap file in: ") + cnferrloc;
+	return;
+    }
+    mimeconf = new ConfStack("mimeconf", m_cdirs, true);
+    if (mimeconf == 0 || !mimeconf->ok()) {
+	m_reason = string("No/bad mimeconf in: ") + cnferrloc;
+	return;
+    }
+    mimeview = new ConfStack("mimeview", m_cdirs, false);
+    if (mimeview == 0)
+	mimeview = new ConfStack("mimeview", m_cdirs, true);
+    if (mimeview == 0 || !mimeview->ok()) {
+	m_reason = string("No/bad mimeview in: ") + cnferrloc;
+	return;
+    }
+    if (!readFieldsConfig(cnferrloc))
+	return;
+
+    // Default is no threading
+    m_thrConf = {{-1, 0}, {-1, 0}, {-1, 0}};
+
+    m_ptrans = new ConfSimple(path_cat(m_confdir, "ptrans").c_str());
+
+    m_ok = true;
+    setKeyDir(cstr_null);
+
+    initParamStale(m_conf, mimemap);
+
+    return;
+}
+
+bool RclConfig::updateMainConfig()
+{
+    ConfStack *newconf = 
+	new ConfStack("recoll.conf", m_cdirs, true);
+    if (newconf == 0 || !newconf->ok()) {
+	if (m_conf)
+	    return false;
+	string where;
+	stringsToString(m_cdirs, where);
+	m_reason = string("No/bad main configuration file in: ") + where;
+	m_ok = false;
+        initParamStale(0, 0);
+	return false;
+    }
+
+    delete m_conf;
+    m_conf = newconf;
+
+    initParamStale(m_conf, mimemap);
+
+    setKeyDir(cstr_null);
+
+    bool bvalue = false;
+    if (getConfParam("nocjk", &bvalue) && bvalue == true) {
+	TextSplit::cjkProcessing(false);
+    } else {
+	int ngramlen;
+	if (getConfParam("cjkngramlen", &ngramlen)) {
+	    TextSplit::cjkProcessing(true, (unsigned int)ngramlen);
+	} else {
+	    TextSplit::cjkProcessing(true);
+	}
+    }
+
+    bvalue = false;
+    if (getConfParam("nonumbers", &bvalue) && bvalue == true) {
+	TextSplit::noNumbers();
+    }
+
+    bvalue = false;
+    if (getConfParam("dehyphenate", &bvalue)) {
+	TextSplit::deHyphenate(bvalue);
+    }
+
+    bvalue = true;
+    if (getConfParam("skippedPathsFnmPathname", &bvalue) && bvalue == false) {
+	FsTreeWalker::setNoFnmPathname();
+    }
+
+    static int m_index_stripchars_init = 0;
+    if (!m_index_stripchars_init) {
+	getConfParam("indexStripChars", &o_index_stripchars);
+        getConfParam("testmodifusemtime", &o_uptodate_test_use_mtime);
+	m_index_stripchars_init = 1;
+    }
+
+    if (getConfParam("cachedir", m_cachedir)) {
+        m_cachedir = path_canon(path_tildexpand(m_cachedir));
+    }
+    return true;
+}
+
+ConfNull *RclConfig::cloneMainConfig()
+{
+    ConfNull *conf = new ConfStack("recoll.conf", m_cdirs, false);
+    if (conf == 0 || !conf->ok()) {
+	m_reason = string("Can't read config");
+	return 0;
+    }
+    return conf;
+}
+
+// Remember what directory we're under (for further conf->get()s), and 
+// prefetch a few common values.
+void RclConfig::setKeyDir(const string &dir) 
+{
+    if (!dir.compare(m_keydir))
+        return;
+
+    m_keydirgen++;
+    m_keydir = dir;
+    if (m_conf == 0)
+	return;
+
+    if (!m_conf->get("defaultcharset", m_defcharset, m_keydir))
+	m_defcharset.erase();
+}
+
+bool RclConfig::getConfParam(const string &name, int *ivp, bool shallow) const
+{
+    string value;
+    if (!getConfParam(name, value, shallow))
+	return false;
+    errno = 0;
+    long lval = strtol(value.c_str(), 0, 0);
+    if (lval == 0 && errno)
+	return 0;
+    if (ivp)
+	*ivp = int(lval);
+    return true;
+}
+
+bool RclConfig::getConfParam(const string &name, bool *bvp, bool shallow) const
+{
+    if (!bvp) 
+	return false;
+
+    *bvp = false;
+    string s;
+    if (!getConfParam(name, s, shallow))
+	return false;
+    *bvp = stringToBool(s);
+    return true;
+}
+
+bool RclConfig::getConfParam(const string &name, vector *svvp,
+    bool shallow) const
+{
+    if (!svvp) 
+	return false;
+    svvp->clear();
+    string s;
+    if (!getConfParam(name, s, shallow))
+	return false;
+    return stringToStrings(s, *svvp);
+}
+
+bool RclConfig::getConfParam(const string &name, vector *vip,
+    bool shallow) const
+{
+    if (!vip) 
+	return false;
+    vip->clear();
+    vector vs;
+    if (!getConfParam(name, &vs, shallow))
+	return false;
+    vip->reserve(vs.size());
+    for (unsigned int i = 0; i < vs.size(); i++) {
+	char *ep;
+	vip->push_back(strtol(vs[i].c_str(), &ep, 0));
+	if (ep == vs[i].c_str()) {
+	    LOGDEB("RclConfig::getConfParam: bad int value in ["  << (name) << "]\n" );
+	    return false;
+	}
+    }
+    return true;
+}
+
+void RclConfig::initThrConf()
+{
+    // Default is no threading
+    m_thrConf = {{-1, 0}, {-1, 0}, {-1, 0}};
+
+    vector vq;
+    vector vt;
+    if (!getConfParam("thrQSizes", &vq)) {
+	LOGINFO("RclConfig::initThrConf: no thread info (queues)\n" );
+	goto out;
+    }
+
+    // If the first queue size is 0, autoconf is requested.
+    if (vq.size() > 0 && vq[0] == 0) {
+	CpuConf cpus;
+	if (!getCpuConf(cpus) || cpus.ncpus < 1) {
+	    LOGERR("RclConfig::initThrConf: could not retrieve cpu conf\n" );
+	    cpus.ncpus = 1;
+	}
+        if (cpus.ncpus != 1) {
+            LOGDEB("RclConfig::initThrConf: autoconf requested. " <<
+                   cpus.ncpus << " concurrent threads available.\n");
+        }
+
+	// Arbitrarily set threads config based on number of CPUS. This also
+	// depends on the IO setup actually, so we're bound to be wrong...
+	if (cpus.ncpus == 1) {
+	    // Somewhat counter-intuitively (because of possible IO//)
+	    // it seems that the best config here is no threading
+	} else if (cpus.ncpus < 4) {
+	    // Untested so let's guess...
+            m_thrConf = {{2, 2}, {2, 2}, {2, 1}};
+	} else if (cpus.ncpus < 6) {
+	    m_thrConf = {{2, 4}, {2, 2}, {2, 1}};
+	} else {
+	    m_thrConf = {{2, 5}, {2, 3}, {2, 1}};
+	}
+	goto out;
+    } else if (vq.size() > 0 && vq[0] < 0) {
+	// threads disabled by config
+	goto out;
+    }
+
+    if (!getConfParam("thrTCounts", &vt) ) {
+	LOGINFO("RclConfig::initThrConf: no thread info (threads)\n" );
+	goto out;
+    }
+
+    if (vq.size() != 3 || vt.size() != 3) {
+	LOGINFO("RclConfig::initThrConf: bad thread info vector sizes\n" );
+	goto out;
+    }
+
+    // Normal case: record info from config
+    m_thrConf.clear();
+    for (unsigned int i = 0; i < 3; i++) {
+	m_thrConf.push_back({vq[i], vt[i]});
+    }
+
+out:
+    ostringstream sconf;
+    for (unsigned int i = 0; i < 3; i++) {
+	sconf << "(" << m_thrConf[i].first << ", " << m_thrConf[i].second <<
+	    ") ";
+    }
+
+    LOGDEB("RclConfig::initThrConf: chosen config (ql,nt): "  << (sconf.str()) << "\n" );
+}
+
+pair RclConfig::getThrConf(ThrStage who) const
+{
+    if (m_thrConf.size() != 3) {
+	LOGERR("RclConfig::getThrConf: bad data in rclconfig\n" );
+	return pair(-1,-1);
+    }
+    return m_thrConf[who];
+}
+
+vector RclConfig::getTopdirs() const
+{
+    vector tdl;
+    if (!getConfParam("topdirs", &tdl)) {
+	LOGERR("RclConfig::getTopdirs: no top directories in config or bad list format\n" );
+	return tdl;
+    }
+
+    for (vector::iterator it = tdl.begin(); it != tdl.end(); it++) {
+	*it = path_tildexpand(*it);
+	*it = path_canon(*it);
+    }
+    return tdl;
+}
+
+const string& RclConfig::getLocaleCharset()
+{
+    return o_localecharset;
+}
+
+// Get charset to be used for transcoding to utf-8 if unspecified by doc
+// For document contents:
+//  If defcharset was set (from the config or a previous call, this
+//   is done in setKeydir), use it.
+//  Else, try to guess it from the locale
+//  Use cp1252 (as a superset of iso8859-1) as ultimate default
+//
+// For filenames, same thing except that we do not use the config file value
+// (only the locale).
+const string& RclConfig::getDefCharset(bool filename) const
+{
+    if (filename) {
+	return o_localecharset;
+    } else {
+	return m_defcharset.empty() ? o_localecharset : m_defcharset;
+    }
+}
+
+// Get all known document mime values. We get them from the mimeconf
+// 'index' submap.
+// It's quite possible that there are other mime types in the index
+// (defined in mimemap and not mimeconf, or output by "file -i"). We
+// just ignore them, because there may be myriads, and their contents
+// are not indexed. 
+//
+// This unfortunately means that searches by file names and mime type
+// filtering don't work well together.
+vector RclConfig::getAllMimeTypes() const
+{
+    return mimeconf ? mimeconf->getNames("index") : vector();
+}
+
+// Things for suffix comparison. We define a string class and string 
+// comparison with suffix-only sensitivity
+class SfString {
+public:
+    SfString(const string& s) : m_str(s) {}
+    bool operator==(const SfString& s2) {
+	string::const_reverse_iterator r1 = m_str.rbegin(), re1 = m_str.rend(),
+	    r2 = s2.m_str.rbegin(), re2 = s2.m_str.rend();
+	while (r1 != re1 && r2 != re2) {
+	    if (*r1 != *r2) {
+		return 0;
+	    }
+	    ++r1; ++r2;
+	}
+	return 1;
+    }
+    string m_str;
+};
+
+class SuffCmp {
+public:
+    int operator()(const SfString& s1, const SfString& s2) {
+	//cout << "Comparing " << s1.m_str << " and " << s2.m_str << endl;
+	string::const_reverse_iterator 
+	    r1 = s1.m_str.rbegin(), re1 = s1.m_str.rend(),
+	    r2 = s2.m_str.rbegin(), re2 = s2.m_str.rend();
+	while (r1 != re1 && r2 != re2) {
+	    if (*r1 != *r2) {
+		return *r1 < *r2 ? 1 : 0;
+	    }
+	    ++r1; ++r2;
+	}
+	return 0;
+    }
+};
+typedef multiset SuffixStore;
+
+#define STOPSUFFIXES ((SuffixStore *)m_stopsuffixes)
+
+bool RclConfig::inStopSuffixes(const string& fni)
+{
+    LOGDEB2("RclConfig::inStopSuffixes("  << (fni) << ")\n" );
+    // Beware: both needrecompute() need to be called always hence the
+    // bizarre way we do things
+    bool needrecompute = m_stpsuffstate.needrecompute();
+    needrecompute = m_oldstpsuffstate.needrecompute() || needrecompute;
+    if (needrecompute || m_stopsuffixes == 0) {
+	// Need to initialize the suffixes
+        delete STOPSUFFIXES;
+	if ((m_stopsuffixes = new SuffixStore) == 0) {
+	    LOGERR("RclConfig::inStopSuffixes: out of memory\n" );
+	    return false;
+	}
+        // Let the old customisation have priority: if recoll_noindex
+        // from mimemap is set, it the user's (the default value is
+        // gone). Else use the new variable
+	vector stoplist;
+        if (!m_oldstpsuffstate.savedvalue.empty()) {
+            stringToStrings(m_oldstpsuffstate.savedvalue, stoplist);
+        } else {
+            stringToStrings(m_stpsuffstate.savedvalue, stoplist);
+        }
+	for (vector::const_iterator it = stoplist.begin(); 
+	     it != stoplist.end(); it++) {
+	    STOPSUFFIXES->insert(SfString(stringtolower(*it)));
+	    if (m_maxsufflen < it->length())
+		m_maxsufflen = int(it->length());
+	}
+    }
+
+    // Only need a tail as long as the longest suffix.
+    int pos = MAX(0, int(fni.length() - m_maxsufflen));
+    string fn(fni, pos);
+
+    stringtolower(fn);
+    SuffixStore::const_iterator it = STOPSUFFIXES->find(fn);
+    if (it != STOPSUFFIXES->end()) {
+	LOGDEB2("RclConfig::inStopSuffixes: Found ("  << (fni) << ") ["  << ((*it).m_str) << "]\n" );
+	return true;
+    } else {
+	LOGDEB2("RclConfig::inStopSuffixes: not found ["  << (fni) << "]\n" );
+	return false;
+    }
+}
+
+string RclConfig::getMimeTypeFromSuffix(const string& suff) const
+{
+    string mtype;
+    mimemap->get(suff, mtype, m_keydir);
+    return mtype;
+}
+
+string RclConfig::getSuffixFromMimeType(const string &mt) const
+{
+    string suffix;
+    vectorsfs = mimemap->getNames(cstr_null);
+    string mt1;
+    for (vector::const_iterator it = sfs.begin(); 
+	 it != sfs.end(); it++) {
+	if (mimemap->get(*it, mt1, cstr_null))
+	    if (!stringicmp(mt, mt1))
+		return *it;
+    }
+    return cstr_null;
+}
+
+/** Get list of file categories from mimeconf */
+bool RclConfig::getMimeCategories(vector& cats) const
+{
+    if (!mimeconf)
+	return false;
+    cats = mimeconf->getNames("categories");
+    return true;
+}
+
+bool RclConfig::isMimeCategory(string& cat) const
+{
+    vectorcats;
+    getMimeCategories(cats);
+    for (vector::iterator it = cats.begin(); it != cats.end(); it++) {
+	if (!stringicmp(*it,cat))
+	    return true;
+    }
+    return false;
+}
+
+/** Get list of mime types for category from mimeconf */
+bool RclConfig::getMimeCatTypes(const string& cat, vector& tps) const
+{
+    tps.clear();
+    if (!mimeconf)
+	return false;
+    string slist;
+    if (!mimeconf->get(cat, slist, "categories"))
+	return false;
+
+    stringToStrings(slist, tps);
+    return true;
+}
+
+string RclConfig::getMimeHandlerDef(const string &mtype, bool filtertypes)
+{
+    string hs;
+
+    if (filtertypes) {
+        if(m_rmtstate.needrecompute()) {
+            m_restrictMTypes.clear();
+            stringToStrings(stringtolower((const string&)m_rmtstate.savedvalue),
+                            m_restrictMTypes);
+        }
+        if (m_xmtstate.needrecompute()) {
+            m_excludeMTypes.clear();
+            stringToStrings(stringtolower((const string&)m_xmtstate.savedvalue),
+                            m_excludeMTypes);
+        }
+        if (!m_restrictMTypes.empty() && 
+            !m_restrictMTypes.count(stringtolower(mtype))) {
+            LOGDEB2("RclConfig::getMimeHandlerDef: not in mime type list\n" );
+            return hs;
+        }
+        if (!m_excludeMTypes.empty() && 
+            m_excludeMTypes.count(stringtolower(mtype))) {
+            LOGDEB2("RclConfig::getMimeHandlerDef: in excluded mime list\n" );
+            return hs;
+        }
+    }
+
+    if (!mimeconf->get(mtype, hs, "index")) {
+	LOGDEB1("getMimeHandler: no handler for '"  << (mtype) << "'\n" );
+    }
+    return hs;
+}
+
+const vector& RclConfig::getMDReapers()
+{
+    string hs;
+    if (m_mdrstate.needrecompute()) {
+        m_mdreapers.clear();
+	// New value now stored in m_mdrstate.savedvalue
+	string& sreapers = m_mdrstate.savedvalue;
+	if (sreapers.empty())
+	  return m_mdreapers;
+	string value;
+	ConfSimple attrs;
+	valueSplitAttributes(sreapers, value, attrs);
+	vector nmlst = attrs.getNames(cstr_null);
+	for (vector::const_iterator it = nmlst.begin();
+	     it != nmlst.end(); it++) {
+	  MDReaper reaper;
+	  reaper.fieldname = fieldCanon(*it);
+	  string s;
+	  attrs.get(*it, s);
+	  stringToStrings(s, reaper.cmdv);
+	  m_mdreapers.push_back(reaper);
+	}
+    }
+    return m_mdreapers;
+}
+
+bool RclConfig::getGuiFilterNames(vector& cats) const
+{
+    if (!mimeconf)
+	return false;
+    cats = mimeconf->getNamesShallow("guifilters");
+    return true;
+}
+
+bool RclConfig::getGuiFilter(const string& catfiltername, string& frag) const
+{
+    frag.clear();
+    if (!mimeconf)
+	return false;
+    if (!mimeconf->get(catfiltername, frag, "guifilters"))
+	return false;
+    return true;
+}
+
+bool RclConfig::valueSplitAttributes(const string& whole, string& value, 
+				     ConfSimple& attrs)
+{
+    /* There is currently no way to escape a semi-colon */
+    string::size_type semicol0 = whole.find_first_of(";");
+    value = whole.substr(0, semicol0);
+    trimstring(value);
+    string attrstr;
+    if (semicol0 != string::npos && semicol0 < whole.size() - 1) {
+        attrstr = whole.substr(semicol0+1);
+    }
+
+    // Handle additional attributes. We substitute the semi-colons
+    // with newlines and use a ConfSimple
+    if (!attrstr.empty()) {
+        for (string::size_type i = 0; i < attrstr.size(); i++) {
+            if (attrstr[i] == ';')
+                attrstr[i] = '\n';
+	}
+        attrs.reparse(attrstr);
+    } else {
+	attrs.clear();
+    }
+    
+    return true;
+}
+
+bool RclConfig::getMissingHelperDesc(string& out) const
+{
+    string fmiss = path_cat(getConfDir(), "missing");
+    out.clear();
+    if (!file_to_string(fmiss, out))
+	return false;
+    return true;
+}
+
+void RclConfig::storeMissingHelperDesc(const string &s)
+{
+    string fmiss = path_cat(getCacheDir(), "missing");
+    FILE *fp = fopen(fmiss.c_str(), "w");
+    if (fp) {
+	if (s.size() > 0 && fwrite(s.c_str(), s.size(), 1, fp) != 1) {
+            LOGERR("storeMissingHelperDesc: fwrite failed\n" );
+        }
+	fclose(fp);
+    }
+}
+
+// Read definitions for field prefixes, aliases, and hierarchy and arrange 
+// things for speed (theses are used a lot during indexing)
+bool RclConfig::readFieldsConfig(const string& cnferrloc)
+{
+    LOGDEB2("RclConfig::readFieldsConfig\n" );
+    m_fields = new ConfStack("fields", m_cdirs, true);
+    if (m_fields == 0 || !m_fields->ok()) {
+	m_reason = string("No/bad fields file in: ") + cnferrloc;
+	return false;
+    }
+
+    // Build a direct map avoiding all indirections for field to
+    // prefix translation
+    // Add direct prefixes from the [prefixes] section
+    vectortps = m_fields->getNames("prefixes");
+    for (vector::const_iterator it = tps.begin(); 
+	 it != tps.end(); it++) {
+	string val;
+	m_fields->get(*it, val, "prefixes");
+	ConfSimple attrs;
+	FieldTraits ft;
+	if (!valueSplitAttributes(val, ft.pfx, attrs)) {
+	    LOGERR("readFieldsConfig: bad config line for ["  << *it << "]: ["  << (val) << "]\n" );
+	    return 0;
+	}
+	string tval;
+	if (attrs.get("wdfinc", tval))
+	    ft.wdfinc = atoi(tval.c_str());
+	if (attrs.get("boost", tval))
+	    ft.boost = atof(tval.c_str());
+	if (attrs.get("pfxonly", tval))
+	    ft.pfxonly = stringToBool(tval);
+	if (attrs.get("noterms", tval))
+	    ft.noterms = stringToBool(tval);
+	m_fldtotraits[stringtolower(*it)] = ft;
+	LOGDEB2("readFieldsConfig: ["  << *it << "] -> ["  << (ft.pfx) << "] "  << (ft.wdfinc) << " "  << (ft.boost) << "\n" );
+    }
+
+    // Add prefixes for aliases and build alias-to-canonic map while
+    // we're at it. Having the aliases in the prefix map avoids an
+    // additional indirection at index time.
+    tps = m_fields->getNames("aliases");
+    for (vector::const_iterator it = tps.begin(); 
+         it != tps.end(); it++){
+	string canonic = stringtolower(*it); // canonic name
+	FieldTraits ft;
+	map::const_iterator pit = 
+	    m_fldtotraits.find(canonic);
+	if (pit != m_fldtotraits.end()) {
+	    ft = pit->second;
+	}
+	string aliases;
+	m_fields->get(canonic, aliases, "aliases");
+	vector l;
+	stringToStrings(aliases, l);
+	for (vector::const_iterator ait = l.begin();
+	     ait != l.end(); ait++) {
+	    if (pit != m_fldtotraits.end())
+		m_fldtotraits[stringtolower(*ait)] = ft;
+	    m_aliastocanon[stringtolower(*ait)] = canonic;
+	}
+    }
+
+    // Query aliases map
+    tps = m_fields->getNames("queryaliases");
+    for (vector::const_iterator it = tps.begin(); 
+         it != tps.end(); it++){
+	string canonic = stringtolower(*it); // canonic name
+	string aliases;
+	m_fields->get(canonic, aliases, "queryaliases");
+	vector l;
+	stringToStrings(aliases, l);
+	for (vector::const_iterator ait = l.begin();
+	     ait != l.end(); ait++) {
+	    m_aliastoqcanon[stringtolower(*ait)] = canonic;
+	}
+    }
+
+#if 0
+    for (map::const_iterator it = m_fldtotraits.begin();
+	 it != m_fldtotraits.end(); it++) {
+	LOGDEB("readFieldsConfig: ["  << *it << "] -> ["  << (it->second.pfx) << "] "  << (it->second.wdfinc) << " "  << (it->second.boost) << "\n" );
+    }
+#endif
+
+    vector sl = m_fields->getNames("stored");
+    if (!sl.empty()) {
+	for (vector::const_iterator it = sl.begin(); 
+	     it != sl.end(); it++) {
+	    string fld = fieldCanon(stringtolower(*it));
+	    m_storedFields.insert(fld);
+	}
+    }
+
+    // Extended file attribute to field translations
+    vectorxattrs = m_fields->getNames("xattrtofields");
+    for (vector::const_iterator it = xattrs.begin(); 
+	 it != xattrs.end(); it++) {
+	string val;
+	m_fields->get(*it, val, "xattrtofields");
+	m_xattrtofld[*it] = val;
+    }
+
+    return true;
+}
+
+// Return specifics for field name:
+bool RclConfig::getFieldTraits(const string& _fld, const FieldTraits **ftpp,
+    bool isquery) const
+{
+    string fld = isquery ? fieldQCanon(_fld) : fieldCanon(_fld);
+    map::const_iterator pit = m_fldtotraits.find(fld);
+    if (pit != m_fldtotraits.end()) {
+	*ftpp = &pit->second;
+	LOGDEB1("RclConfig::getFieldTraits: ["  << (_fld) << "]->["  << (pit->second.pfx) << "]\n" );
+	return true;
+    } else {
+	LOGDEB1("RclConfig::getFieldTraits: no prefix for field ["  << (fld) << "]\n" );
+	*ftpp = 0;
+	return false;
+    }
+}
+
+set RclConfig::getIndexedFields() const
+{
+    set flds;
+    if (m_fields == 0)
+	return flds;
+
+    vector sl = m_fields->getNames("prefixes");
+    flds.insert(sl.begin(), sl.end());
+    return flds;
+}
+
+string RclConfig::fieldCanon(const string& f) const
+{
+    string fld = stringtolower(f);
+    map::const_iterator it = m_aliastocanon.find(fld);
+    if (it != m_aliastocanon.end()) {
+	LOGDEB1("RclConfig::fieldCanon: ["  << (f) << "] -> ["  << (it->second) << "]\n" );
+	return it->second;
+    }
+    LOGDEB1("RclConfig::fieldCanon: ["  << (f) << "] -> ["  << (fld) << "]\n" );
+    return fld;
+}
+
+string RclConfig::fieldQCanon(const string& f) const
+{
+    string fld = stringtolower(f);
+    map::const_iterator it = m_aliastoqcanon.find(fld);
+    if (it != m_aliastoqcanon.end()) {
+	LOGDEB1("RclConfig::fieldQCanon: ["  << (f) << "] -> ["  << (it->second) << "]\n" );
+	return it->second;
+    }
+    return fieldCanon(f);
+}
+
+vector RclConfig::getFieldSectNames(const string &sk, const char* patrn)
+    const
+{
+    if (m_fields == 0)
+        return vector();
+    return m_fields->getNames(sk, patrn);
+}
+
+bool RclConfig::getFieldConfParam(const string &name, const string &sk, 
+                                  string &value) const
+{
+    if (m_fields == 0)
+        return false;
+    return m_fields->get(name, value, sk);
+}
+
+string RclConfig::getMimeViewerAllEx() const
+{
+    string hs;
+    if (mimeview == 0)
+	return hs;
+    mimeview->get("xallexcepts", hs, "");
+    return hs;
+}
+
+bool RclConfig::setMimeViewerAllEx(const string& allex)
+{
+    if (mimeview == 0)
+        return false;
+    if (!mimeview->set("xallexcepts", allex, "")) {
+	m_reason = string("RclConfig:: cant set value. Readonly?");
+	return false;
+    }
+
+    return true;
+}
+
+string RclConfig::getMimeViewerDef(const string &mtype, const string& apptag,
+				   bool useall) const
+{
+    LOGDEB2("RclConfig::getMimeViewerDef: mtype ["  << (mtype) << "] apptag ["  << (apptag) << "]\n" );
+    string hs;
+    if (mimeview == 0)
+	return hs;
+
+    if (useall) {
+	// Check for exception
+	string excepts = getMimeViewerAllEx();
+	vector vex;
+	stringToTokens(excepts, vex);
+	bool isexcept = false;
+	for (vector::iterator it = vex.begin();
+	     it != vex.end(); it++) {
+	    vector mita;
+	    stringToTokens(*it, mita, "|");
+	    if ((mita.size() == 1 && apptag.empty() && mita[0] == mtype) ||
+		(mita.size() == 2 && mita[1] == apptag && mita[0] == mtype)) {
+		// Exception to x-all
+		isexcept = true;
+		break;
+	    }
+	}
+
+	if (isexcept == false) {
+	    mimeview->get("application/x-all", hs, "view");
+	    return hs;
+	}
+	// Fallthrough to normal case.
+    }
+
+    if (apptag.empty() || !mimeview->get(mtype + string("|") + apptag,
+                                         hs, "view"))
+        mimeview->get(mtype, hs, "view");
+    return hs;
+}
+
+bool RclConfig::getMimeViewerDefs(vector >& defs) const
+{
+    if (mimeview == 0)
+	return false;
+    vectortps = mimeview->getNames("view");
+    for (vector::const_iterator it = tps.begin(); 
+	 it != tps.end();it++) {
+	defs.push_back(pair(*it, getMimeViewerDef(*it, "", 0)));
+    }
+    return true;
+}
+
+bool RclConfig::setMimeViewerDef(const string& mt, const string& def)
+{
+    if (mimeview == 0)
+        return false;
+    bool status;
+    if (!def.empty()) 
+	status = mimeview->set(mt, def, "view");
+    else 
+	status = mimeview->erase(mt, "view");
+
+    if (!status) {
+	m_reason = string("RclConfig:: cant set value. Readonly?");
+	return false;
+    }
+    return true;
+}
+
+bool RclConfig::mimeViewerNeedsUncomp(const string &mimetype) const
+{
+    string s;
+    vector v;
+    if (mimeview != 0 && mimeview->get("nouncompforviewmts", s, "") && 
+        stringToStrings(s, v) && 
+        find_if(v.begin(), v.end(), StringIcmpPred(mimetype)) != v.end()) 
+        return false;
+    return true;
+}
+
+string RclConfig::getMimeIconPath(const string &mtype, const string &apptag)
+    const
+{
+    string iconname;
+    if (!apptag.empty())
+	mimeconf->get(mtype + string("|") + apptag, iconname, "icons");
+    if (iconname.empty())
+        mimeconf->get(mtype, iconname, "icons");
+    if (iconname.empty())
+	iconname = "document";
+
+    string iconpath;
+#if defined (__FreeBSD__) && __FreeBSD_version < 500000
+    // gcc 2.95 dies if we call getConfParam here ??
+    if (m_conf) m_conf->get(string("iconsdir"), iconpath, m_keydir);
+#else
+    getConfParam("iconsdir", iconpath);
+#endif
+
+    if (iconpath.empty()) {
+	iconpath = path_cat(m_datadir, "images");
+    } else {
+	iconpath = path_tildexpand(iconpath);
+    }
+    return path_cat(iconpath, iconname) + ".png";
+}
+
+// Return path defined by varname. May be absolute or relative to
+// confdir, with default in confdir
+string RclConfig::getConfdirPath(const char *varname, const char *dflt) const
+{
+    string result;
+    if (!getConfParam(varname, result)) {
+	result = path_cat(getConfDir(), dflt);
+    } else {
+	result = path_tildexpand(result);
+	// If not an absolute path, compute relative to config dir
+	if (!path_isabsolute(result)) {
+	    result = path_cat(getConfDir(), result);
+	}
+    }
+    return path_canon(result);
+
+}
+
+string RclConfig::getCacheDir() const
+{
+    return m_cachedir.empty() ? getConfDir() : m_cachedir;
+}
+
+// Return path defined by varname. May be absolute or relative to
+// confdir, with default in confdir
+string RclConfig::getCachedirPath(const char *varname, const char *dflt) const
+{
+    string result;
+    if (!getConfParam(varname, result)) {
+	result = path_cat(getCacheDir(), dflt);
+    } else {
+	result = path_tildexpand(result);
+	// If not an absolute path, compute relative to cache dir
+	if (!path_isabsolute(result)) {
+	    result = path_cat(getCacheDir(), result);
+	}
+    }
+    return path_canon(result);
+}
+
+string RclConfig::getDbDir() const
+{
+    return getCachedirPath("dbdir", "xapiandb");
+}
+string RclConfig::getWebcacheDir() const
+{
+    return getCachedirPath("webcachedir", "webcache");
+}
+string RclConfig::getMboxcacheDir() const
+{
+    return getCachedirPath("mboxcachedir", "mboxcache");
+}
+string RclConfig::getAspellcacheDir() const
+{
+    return getCachedirPath("aspellDicDir", "");
+}
+
+string RclConfig::getStopfile() const
+{
+    return getConfdirPath("stoplistfile", "stoplist.txt");
+}
+
+string RclConfig::getSynGroupsFile() const
+{
+    return getConfdirPath("syngroupsfile", "syngroups.txt");
+}
+
+// The index status file is fast changing, so it's possible to put it outside
+// of the config directory (for ssds, not sure this is really useful).
+// To enable being quite xdg-correct we should add a getRundirPath()
+string RclConfig::getIdxStatusFile() const
+{
+    return getCachedirPath("idxstatusfile", "idxstatus.txt");
+}
+string RclConfig::getPidfile() const
+{
+    return path_cat(getCacheDir(), "index.pid");
+}
+
+void RclConfig::urlrewrite(const string& dbdir, string& url) const
+{
+    LOGDEB2("RclConfig::urlrewrite: dbdir ["  << (dbdir) << "] url ["  << (url) << "]\n" );
+
+    // Do path translations exist for this index ?
+    if (m_ptrans == 0 || !m_ptrans->hasSubKey(dbdir)) {
+	LOGDEB2("RclConfig::urlrewrite: no paths translations (m_ptrans "  << (m_ptrans) << ")\n" );
+	return;
+    }
+
+    string path = fileurltolocalpath(url);
+    if (path.empty()) {
+	LOGDEB2("RclConfig::urlrewrite: not file url\n" );
+	return;
+    }
+
+    // For each translation check if the prefix matches the input path,
+    // replace and return the result if it does.
+    vector opaths = m_ptrans->getNames(dbdir);
+    for (vector::const_iterator it = opaths.begin(); 
+	 it != opaths.end(); it++) {
+	if (it->size() <= path.size() && !path.compare(0, it->size(), *it)) {
+	    string npath;
+	    // This call always succeeds because the key comes from getNames()
+	    if (m_ptrans->get(*it, npath, dbdir)) { 
+		path = path.replace(0, it->size(), npath);
+		url = path_pathtofileurl(path);
+	    }
+	    break;
+	}
+    }
+}
+
+bool RclConfig::sourceChanged() const
+{
+    if (m_conf && m_conf->sourceChanged())
+	return true;
+    if (mimemap && mimemap->sourceChanged())
+	return true;
+    if (mimeconf && mimeconf->sourceChanged())
+	return true;
+    if (mimeview && mimeview->sourceChanged())
+	return true;
+    if (m_fields && m_fields->sourceChanged())
+	return true;
+    if (m_ptrans && m_ptrans->sourceChanged())
+	return true;
+    return false;
+}
+
+string RclConfig::getWebQueueDir() const
+{
+    string webqueuedir;
+    if (!getConfParam("webqueuedir", webqueuedir))
+	webqueuedir = "~/.recollweb/ToIndex/";
+    webqueuedir = path_tildexpand(webqueuedir);
+    return webqueuedir;
+}
+
+vector& RclConfig::getSkippedNames()
+{
+    if (m_skpnstate.needrecompute()) {
+	stringToStrings(m_skpnstate.savedvalue, m_skpnlist);
+    }
+    return m_skpnlist;
+}
+
+vector RclConfig::getSkippedPaths() const
+{
+    vector skpl;
+    getConfParam("skippedPaths", &skpl);
+
+    // Always add the dbdir and confdir to the skipped paths. This is 
+    // especially important for the rt monitor which will go into a loop if we
+    // don't do this.
+    skpl.push_back(getDbDir());
+    skpl.push_back(getConfDir());
+    if (getCacheDir().compare(getConfDir())) {
+        skpl.push_back(getCacheDir());
+    }
+    // And the web queue dir
+    skpl.push_back(getWebQueueDir());
+    for (vector::iterator it = skpl.begin(); it != skpl.end(); it++) {
+	*it = path_tildexpand(*it);
+	*it = path_canon(*it);
+    }
+    sort(skpl.begin(), skpl.end());
+    vector::iterator uit = unique(skpl.begin(), skpl.end());
+    skpl.resize(uit - skpl.begin());
+    return skpl;
+}
+
+vector RclConfig::getDaemSkippedPaths() const
+{
+    vector dskpl;
+    getConfParam("daemSkippedPaths", &dskpl);
+
+    for (vector::iterator it = dskpl.begin(); it != dskpl.end(); it++) {
+	*it = path_tildexpand(*it);
+	*it = path_canon(*it);
+    }
+
+    vector skpl1 = getSkippedPaths();
+    vector skpl;
+    if (dskpl.empty()) {
+	skpl = skpl1;
+    } else {
+	sort(dskpl.begin(), dskpl.end());
+	merge(dskpl.begin(), dskpl.end(), skpl1.begin(), skpl1.end(), 
+	      skpl.begin());
+	vector::iterator uit = unique(skpl.begin(), skpl.end());
+	skpl.resize(uit - skpl.begin());
+    }
+    return skpl;
+}
+
+
+// Look up an executable filter.  We add $RECOLL_FILTERSDIR,
+// and filtersdir from the config file to the PATH, then use execmd::which()
+string RclConfig::findFilter(const string &icmd) const
+{
+    // If the path is absolute, this is it
+    if (path_isabsolute(icmd))
+	return icmd;
+
+    const char *cp = getenv("PATH");
+    if (!cp) //??
+        cp = "";
+    string PATH(cp);
+
+    // For historical reasons: check in personal config directory
+    PATH = getConfDir() + path_PATHsep() + PATH;
+
+    string temp;
+    // Prepend $datadir/filters
+    temp = path_cat(m_datadir, "filters");
+    PATH = temp + path_PATHsep() + PATH;
+
+    // Prepend possible configuration parameter?
+    if (getConfParam(string("filtersdir"), temp)) {
+        temp = path_tildexpand(temp);
+        PATH = temp + path_PATHsep() + PATH;
+    }
+
+    // Prepend possible environment variable
+    if ((cp = getenv("RECOLL_FILTERSDIR"))) {
+        PATH = string(cp) + path_PATHsep() + PATH;
+    } 
+
+    string cmd;
+    if (ExecCmd::which(icmd, cmd, PATH.c_str())) {
+        return cmd;
+    } else {
+        // Let the shell try to find it...
+        return icmd;
+    }
+}
+
+/** 
+ * Return decompression command line for given mime type
+ */
+bool RclConfig::getUncompressor(const string &mtype, vector& cmd) const
+{
+    string hs;
+
+    mimeconf->get(mtype, hs, cstr_null);
+    if (hs.empty())
+	return false;
+    vector tokens;
+    stringToStrings(hs, tokens);
+    if (tokens.empty()) {
+	LOGERR("getUncompressor: empty spec for mtype "  << (mtype) << "\n" );
+	return false;
+    }
+    vector::iterator it = tokens.begin();
+    if (tokens.size() < 2)
+	return false;
+    if (stringlowercmp("uncompress", *it++)) 
+	return false;
+    cmd.clear();
+    cmd.push_back(findFilter(*it));
+
+    // Special-case python and perl on windows: we need to also locate the
+    // first argument which is the script name "python somescript.py". 
+    // On Unix, thanks to #!, we usually just run "somescript.py", but need
+    // the same change if we ever want to use the same cmdling as windows
+    if (!stringlowercmp("python", *it) || !stringlowercmp("perl", *it)) {
+        it++;
+        if (tokens.size() < 3) {
+            LOGERR("getUncpressor: python/perl cmd: no script?. ["  << (mtype) << "]\n" );
+        } else {
+            *it = findFilter(*it);
+        }
+    } else {
+        it++;
+    }
+    
+    cmd.insert(cmd.end(), it, tokens.end());
+    return true;
+}
+
+static const char blurb0[] = 
+"# The system-wide configuration files for recoll are located in:\n"
+"#   %s\n"
+"# The default configuration files are commented, you should take a look\n"
+"# at them for an explanation of what can be set (you could also take a look\n"
+"# at the manual instead).\n"
+"# Values set in this file will override the system-wide values for the file\n"
+"# with the same name in the central directory. The syntax for setting\n"
+"# values is identical.\n"
+    ;
+
+// Use uni2ascii -a K to generate these from the utf-8 strings
+// Swedish and Danish. 
+static const char swedish_ex[] = "unac_except_trans = \303\244\303\244 \303\204\303\244 \303\266\303\266 \303\226\303\266 \303\274\303\274 \303\234\303\274 \303\237ss \305\223oe \305\222oe \303\246ae \303\206ae \357\254\201fi \357\254\202fl \303\245\303\245 \303\205\303\245";
+// German:
+static const char german_ex[] = "unac_except_trans = \303\244\303\244 \303\204\303\244 \303\266\303\266 \303\226\303\266 \303\274\303\274 \303\234\303\274 \303\237ss \305\223oe \305\222oe \303\246ae \303\206ae \357\254\201fi \357\254\202fl";
+
+// Create initial user config by creating commented empty files
+static const char *configfiles[] = {"recoll.conf", "mimemap", "mimeconf", 
+				    "mimeview"};
+static int ncffiles = sizeof(configfiles) / sizeof(char *);
+bool RclConfig::initUserConfig()
+{
+    // Explanatory text
+    const int bs = sizeof(blurb0)+PATH_MAX+1;
+    char blurb[bs];
+    string exdir = path_cat(m_datadir, "examples");
+    snprintf(blurb, bs, blurb0, exdir.c_str());
+
+    // Use protective 700 mode to create the top configuration
+    // directory: documents can be reconstructed from index data.
+    if (!path_exists(m_confdir) && 
+	mkdir(m_confdir.c_str(), 0700) < 0) {
+	m_reason += string("mkdir(") + m_confdir + ") failed: " + 
+	    strerror(errno);
+	return false;
+    }
+    string lang = localelang();
+    for (int i = 0; i < ncffiles; i++) {
+	string dst = path_cat(m_confdir, string(configfiles[i])); 
+	if (!path_exists(dst)) {
+	    FILE *fp = fopen(dst.c_str(), "w");
+	    if (fp) {
+		fprintf(fp, "%s\n", blurb);
+		if (!strcmp(configfiles[i], "recoll.conf")) {
+		    // Add improved unac_except_trans for some languages
+		    if (lang == "se" || lang == "dk" || lang == "no" || 
+			lang == "fi") {
+			fprintf(fp, "%s\n", swedish_ex);
+		    } else if (lang == "de") {
+			fprintf(fp, "%s\n", german_ex);
+		    }
+		}
+		fclose(fp);
+	    } else {
+		m_reason += string("fopen ") + dst + ": " + strerror(errno);
+		return false;
+	    }
+	}
+    }
+    return true;
+}
+
+void RclConfig::freeAll() 
+{
+    delete m_conf;
+    delete mimemap;
+    delete mimeconf; 
+    delete mimeview; 
+    delete m_fields;
+    delete m_ptrans;
+    delete STOPSUFFIXES;
+    // just in case
+    zeroMe();
+}
+
+void RclConfig::initFrom(const RclConfig& r)
+{
+    zeroMe();
+    if (!(m_ok = r.m_ok))
+	return;
+    m_reason = r.m_reason;
+    m_confdir = r.m_confdir;
+    m_cachedir = r.m_cachedir;
+    m_datadir = r.m_datadir;
+    m_keydir = r.m_keydir;
+    m_cdirs = r.m_cdirs;
+    if (r.m_conf)
+	m_conf = new ConfStack(*(r.m_conf));
+    if (r.mimemap)
+	mimemap = new ConfStack(*(r.mimemap));
+    if (r.mimeconf)
+	mimeconf = new ConfStack(*(r.mimeconf));
+    if (r.mimeview)
+	mimeview = new ConfStack(*(r.mimeview));
+    if (r.m_fields)
+	m_fields = new ConfStack(*(r.m_fields));
+    if (r.m_ptrans)
+	m_ptrans = new ConfSimple(*(r.m_ptrans));
+    m_fldtotraits = r.m_fldtotraits;
+    m_aliastocanon = r.m_aliastocanon;
+    m_aliastoqcanon = r.m_aliastoqcanon;
+    m_storedFields = r.m_storedFields;
+    m_xattrtofld = r.m_xattrtofld;
+    if (r.m_stopsuffixes)
+	m_stopsuffixes = new SuffixStore(*((SuffixStore*)r.m_stopsuffixes));
+    m_maxsufflen = r.m_maxsufflen;
+    m_defcharset = r.m_defcharset;
+
+    initParamStale(m_conf, mimemap);
+
+    m_thrConf = r.m_thrConf;
+}
+
+void RclConfig::initParamStale(ConfNull *cnf, ConfNull *mimemap)
+{
+    m_oldstpsuffstate.init(mimemap);
+    m_stpsuffstate.init(cnf);
+    m_skpnstate.init(cnf);
+    m_rmtstate.init(cnf);
+    m_xmtstate.init(cnf);
+    m_mdrstate.init(cnf);
+}
+
+#else // -> Test
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+using namespace std;
+
+#include "log.h"
+
+#include "rclinit.h"
+#include "rclconfig.h"
+#include "cstr.h"
+
+static char *thisprog;
+
+static char usage [] = "\n"
+"-c: check a few things in the configuration files\n"
+"[-s subkey] -q param : query parameter value\n"
+"-f : print some field data\n"
+"  : default: print parameters\n"
+
+;
+static void
+Usage(void)
+{
+    fprintf(stderr, "%s: usage: %s\n", thisprog, usage);
+    exit(1);
+}
+
+static int     op_flags;
+#define OPT_MOINS 0x1
+#define OPT_s	  0x2 
+#define OPT_q	  0x4 
+#define OPT_c     0x8
+#define OPT_f     0x10
+
+int main(int argc, char **argv)
+{
+    string pname, skey;
+    
+    thisprog = argv[0];
+    argc--; argv++;
+
+    while (argc > 0 && **argv == '-') {
+	(*argv)++;
+	if (!(**argv))
+	    /* Cas du "adb - core" */
+	    Usage();
+	while (**argv)
+	    switch (*(*argv)++) {
+	    case 'c':	op_flags |= OPT_c; break;
+	    case 'f':	op_flags |= OPT_f; break;
+	    case 's':	op_flags |= OPT_s; if (argc < 2)  Usage();
+		skey = *(++argv);
+		argc--; 
+		goto b1;
+	    case 'q':	op_flags |= OPT_q; if (argc < 2)  Usage();
+		pname = *(++argv);
+		argc--; 
+		goto b1;
+	    default: Usage();	break;
+	    }
+    b1: argc--; argv++;
+    }
+
+    if (argc != 0)
+	Usage();
+
+    string reason;
+    RclConfig *config = recollinit(0, 0, reason);
+    if (config == 0 || !config->ok()) {
+	cerr << "Configuration problem: " << reason << endl;
+	exit(1);
+    }
+    if (op_flags & OPT_s)
+	config->setKeyDir(skey);
+    if (op_flags & OPT_q) {
+	string value;
+	if (!config->getConfParam(pname, value)) {
+	    fprintf(stderr, "getConfParam failed for [%s]\n", pname.c_str());
+	    exit(1);
+	}
+	printf("[%s] -> [%s]\n", pname.c_str(), value.c_str());
+    } else if (op_flags & OPT_f) {
+	set stored = config->getStoredFields();
+	set indexed = config->getIndexedFields();
+	cout << "Stored fields: ";
+        for (set::const_iterator it = stored.begin(); 
+             it != stored.end(); it++) {
+            cout << "[" << *it << "] ";
+        }
+	cout << endl;	
+	cout << "Indexed fields: ";
+        for (set::const_iterator it = indexed.begin(); 
+             it != indexed.end(); it++) {
+	    const FieldTraits *ftp;
+	    config->getFieldTraits(*it, &ftp);
+	    if (ftp)
+		cout << "[" << *it << "]" << " -> [" << ftp->pfx << "] ";
+	    else 
+		cout << "[" << *it << "]" << " -> [" << "(none)" << "] ";
+
+        }
+	cout << endl;	
+    } else if (op_flags & OPT_c) {
+	// Checking the configuration consistency
+	
+	// Find and display category names
+        vector catnames;
+        config->getMimeCategories(catnames);
+        cout << "Categories: ";
+        for (vector::const_iterator it = catnames.begin(); 
+             it != catnames.end(); it++) {
+            cout << *it << " ";
+        }
+        cout << endl;
+
+	// Compute union of all types from each category. Check that there
+	// are no duplicates while we are at it.
+        set allmtsfromcats;
+        for (vector::const_iterator it = catnames.begin(); 
+             it != catnames.end(); it++) {
+            vector cts;
+            config->getMimeCatTypes(*it, cts);
+            for (vector::const_iterator it1 = cts.begin(); 
+                 it1 != cts.end(); it1++) {
+                // Already in map -> duplicate
+                if (allmtsfromcats.find(*it1) != allmtsfromcats.end()) {
+                    cout << "Duplicate: [" << *it1 << "]" << endl;
+                }
+                allmtsfromcats.insert(*it1);
+            }
+        }
+
+	// Retrieve complete list of mime types 
+        vector mtypes = config->getAllMimeTypes();
+
+	// And check that each mime type is found in exactly one category
+        for (vector::const_iterator it = mtypes.begin();
+             it != mtypes.end(); it++) {
+            if (allmtsfromcats.find(*it) == allmtsfromcats.end()) {
+                cout << "Not found in catgs: [" << *it << "]" << endl;
+            }
+        }
+
+	// List mime types not in mimeview
+        for (vector::const_iterator it = mtypes.begin();
+             it != mtypes.end(); it++) {
+	    if (config->getMimeViewerDef(*it, "", false).empty()) {
+		cout << "No viewer: [" << *it << "]" << endl;
+	    }
+        }
+
+	// Check that each mime type has an indexer
+        for (vector::const_iterator it = mtypes.begin();
+             it != mtypes.end(); it++) {
+	    if (config->getMimeHandlerDef(*it, false).empty()) {
+		cout << "No filter: [" << *it << "]" << endl;
+	    }
+        }
+
+	// Check that each mime type has a defined icon
+        for (vector::const_iterator it = mtypes.begin();
+             it != mtypes.end(); it++) {
+	    if (config->getMimeIconPath(*it, "") == "document") {
+		cout << "No or generic icon: [" << *it << "]" << endl;
+	    }
+        }
+
+    } else {
+        config->setKeyDir(cstr_null);
+	vector names = config->getConfNames();
+	for (vector::iterator it = names.begin(); 
+	     it != names.end();it++) {
+	    string value;
+	    config->getConfParam(*it, value);
+	    cout << *it << " -> [" << value << "]" << endl;
+	}
+    }
+    exit(0);
+}
+
+#endif // TEST_RCLCONFIG
+
diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h
new file mode 100644
index 00000000..95a49c29
--- /dev/null
+++ b/src/common/rclconfig.h
@@ -0,0 +1,422 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef _RCLCONFIG_H_INCLUDED_
+#define _RCLCONFIG_H_INCLUDED_
+#include "autoconfig.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using std::string;
+using std::vector;
+using std::pair;
+using std::set;
+using std::map;
+
+#include "conftree.h"
+#include "smallut.h"
+
+class RclConfig;
+
+// A small class used for parameters that need to be computed from the
+// config string, and which can change with the keydir. Minimize work
+// by using the keydirgen and a saved string to avoid unneeded
+// recomputations
+class ParamStale {
+public:
+    RclConfig *parent;
+    ConfNull  *conffile;
+    string    paramname;
+    bool      active; // Check at init if config defines name at all
+    int       savedkeydirgen;
+    string    savedvalue;
+
+    ParamStale(RclConfig *rconf, const string& nm);
+    void init(ConfNull *cnf);
+    bool needrecompute();
+};
+
+// Hold the description for an external metadata-gathering command
+struct MDReaper {
+  string fieldname;
+  vector cmdv;
+};
+
+// Data associated to a indexed field name: 
+struct FieldTraits {
+    string pfx; // indexing prefix, 
+    int    wdfinc; // Index time term frequency increment (default 1)
+    double boost; // Query time boost (default 1.0)
+    bool   pfxonly; // Suppress prefix-less indexing
+    bool   noterms; // Don't add term to highlight data (e.g.: rclbes)
+    FieldTraits() 
+        : wdfinc(1), boost(1.0), pfxonly(false), noterms(false)
+        {}
+};
+
+class RclConfig {
+ public:
+
+    // Constructor: we normally look for a configuration file, except
+    // if this was specified on the command line and passed through
+    // argcnf
+    RclConfig(const string *argcnf = 0);
+
+    RclConfig(const RclConfig &r) 
+    : m_oldstpsuffstate(this, "recoll_noindex"),
+      m_stpsuffstate(this, "noContentSuffixes"),
+      m_skpnstate(this, "skippedNames"),
+      m_rmtstate(this, "indexedmimetypes"),
+      m_xmtstate(this, "excludedmimetypes"),
+      m_mdrstate(this, "metadatacmds") {
+        initFrom(r);
+    }
+
+    ~RclConfig() {
+	freeAll();
+    }
+
+    // Return a writable clone of the main config. This belongs to the
+    // caller (must delete it when done)
+    ConfNull *cloneMainConfig();
+
+    /** (re)Read recoll.conf */
+    bool updateMainConfig();
+
+    bool ok() const {return m_ok;}
+    const string &getReason() const {return m_reason;}
+
+    /** Return the directory where this configuration is stored. 
+     *  This was possibly silently created by the rclconfig
+     *  constructor it it is the default one (~/.recoll) and it did 
+     *  not exist yet. */
+    string getConfDir() const {return m_confdir;}
+    string getCacheDir() const;
+
+    /** Check if the config files were modified since we read them */
+    bool sourceChanged() const;
+
+    /** Returns true if this is ~/.recoll */
+    bool isDefaultConfig() const;
+    /** Get the local value for /usr/local/share/recoll/ */
+    const string& getDatadir() const {return m_datadir;}
+
+    /** Set current directory reference, and fetch automatic parameters. */
+    void setKeyDir(const string &dir);
+    string getKeyDir() const {return m_keydir;}
+
+    /** Get generic configuration parameter according to current keydir */
+    bool getConfParam(const string &name, string &value, 
+                      bool shallow=false) const
+    {
+	if (m_conf == 0)
+	    return false;
+	return m_conf->get(name, value, m_keydir, shallow);
+    }
+    /** Variant with autoconversion to int */
+    bool getConfParam(const string &name, int *value, bool shallow=false) const;
+    /** Variant with autoconversion to bool */
+    bool getConfParam(const string &name, bool *value, 
+                      bool shallow=false) const;
+    /** Variant with conversion to vector
+     *  (stringToStrings). Can fail if the string is malformed. */
+    bool getConfParam(const string &name, vector *value, 
+                      bool shallow=false) const;
+    /** Variant with conversion to vector */
+    bool getConfParam(const string &name, vector *value, 
+                      bool shallow=false) const;
+
+    enum ThrStage {ThrIntern=0, ThrSplit=1, ThrDbWrite=2};
+    pair getThrConf(ThrStage who) const;
+
+    /** 
+     * Get list of config names under current sk, with possible 
+     * wildcard filtering 
+     */
+    vector getConfNames(const char *pattern = 0) const
+    {
+	return m_conf->getNames(m_keydir, pattern);
+    }
+
+    /** Check if name exists anywhere in config */
+    bool hasNameAnywhere(const string& nm) const
+    {
+        return m_conf? m_conf->hasNameAnywhere(nm) : false;
+    }
+
+
+    /** Get default charset for current keydir (was set during setKeydir) 
+     * filenames are handled differently */
+    const string &getDefCharset(bool filename = false) const;
+
+    /** Get list of top directories. This is needed from a number of places
+     * and needs some cleaning-up code. An empty list is always an error, no
+     * need for other status */
+    vector getTopdirs() const;
+
+    string getConfdirPath(const char *varname, const char *dflt) const;
+    string getCachedirPath(const char *varname, const char *dflt) const;
+    /** Get database and other directories */
+    string getDbDir() const;
+    string getWebcacheDir() const;
+    string getMboxcacheDir() const;
+    string getAspellcacheDir() const;
+    /** Get stoplist file name */
+    string getStopfile() const;
+    /** Get synonym groups file name */
+    string getSynGroupsFile() const;
+    /** Get indexing pid file name */
+    string getPidfile() const;
+    /** Get indexing status file name */
+    string getIdxStatusFile() const;
+    /** Do path translation according to the ptrans table */
+    void urlrewrite(const string& dbdir, string& url) const;
+    ConfSimple *getPTrans()
+    {
+	return m_ptrans;
+    }
+    /** Get Web Queue directory name */
+    string getWebQueueDir() const;
+
+    /** Get list of skipped file names for current keydir */
+    vector& getSkippedNames();
+
+    /** Get list of skipped paths patterns. Doesn't depend on the keydir */
+    vector getSkippedPaths() const;
+    /** Get list of skipped paths patterns, daemon version (may add some)
+	Doesn't depend on the keydir */
+    vector getDaemSkippedPaths() const;
+
+    /** 
+     * mimemap: Check if file name should be ignored because of suffix
+     *
+     * The list of ignored suffixes is initialized on first call, and
+     * not changed for subsequent setKeydirs.
+     */
+    bool inStopSuffixes(const string& fn);
+
+    /** 
+     * Check in mimeconf if input mime type is a compressed one, and
+     * return command to uncompress if it is.
+     *
+     * The returned command has substitutable places for input file name 
+     * and temp dir name, and will return output name
+     */
+    bool getUncompressor(const string &mtpe, vector& cmd) const;
+
+    /** mimemap: compute mimetype */
+    string getMimeTypeFromSuffix(const string &suffix) const;
+    /** mimemap: get a list of all indexable mime types defined */
+    vector getAllMimeTypes() const;
+    /** mimemap: Get appropriate suffix for mime type. This is inefficient */
+    string getSuffixFromMimeType(const string &mt) const;
+
+    /** mimeconf: get input filter for mimetype */
+    string getMimeHandlerDef(const string &mimetype, bool filtertypes=false);
+
+    /** For lines like: "name = some value; attr1 = value1; attr2 = val2"
+     * Separate the value and store the attributes in a ConfSimple 
+     * @param whole the raw value. No way to escape a semi-colon in there.
+     */
+    static bool valueSplitAttributes(const string& whole, string& value, 
+				     ConfSimple& attrs) ;
+
+    /** Return the locale's character set */
+    static const std::string& getLocaleCharset();
+    
+    /** Return icon path for mime type and tag */
+    string getMimeIconPath(const string &mt, const string& apptag) const;
+
+    /** mimeconf: get list of file categories */
+    bool getMimeCategories(vector&) const;
+    /** mimeconf: is parameter one of the categories ? */
+    bool isMimeCategory(string&) const;
+    /** mimeconf: get list of mime types for category */
+    bool getMimeCatTypes(const string& cat, vector&) const;
+
+    /** mimeconf: get list of gui filters (doc cats by default */
+    bool getGuiFilterNames(vector&) const;
+    /** mimeconf: get query lang frag for named filter */
+    bool getGuiFilter(const string& filtername, string& frag) const;
+
+    /** fields: get field prefix from field name. Use additional query
+       aliases if isquery is set */
+    bool getFieldTraits(const string& fldname, const FieldTraits **,
+        bool isquery = false) const;
+
+    const set& getStoredFields() const {return m_storedFields;}
+
+    set getIndexedFields() const;
+
+    /** Get canonic name for possible alias */
+    string fieldCanon(const string& fld) const;
+
+    /** Get canonic name for possible alias, including query-only aliases */
+    string fieldQCanon(const string& fld) const;
+
+    /** Get xattr name to field names translations */
+    const map& getXattrToField() const {return m_xattrtofld;}
+
+    /** Get value of a parameter inside the "fields" file. Only some filters 
+     * use this (ie: mh_mail). The information specific to a given filter
+     * is typically stored in a separate section(ie: [mail]) 
+     */
+    vector getFieldSectNames(const string &sk, const char* = 0) const;
+    bool getFieldConfParam(const string &name, const string &sk, string &value)
+    const;
+
+    /** mimeview: get/set external viewer exec string(s) for mimetype(s) */
+    string getMimeViewerDef(const string &mimetype, const string& apptag, 
+			    bool useall) const;
+    string getMimeViewerAllEx() const;
+    bool setMimeViewerAllEx(const string& allex);
+    bool getMimeViewerDefs(vector >&) const;
+    bool setMimeViewerDef(const string& mimetype, const string& cmd);
+    /** Check if mime type is designated as needing no uncompress before view
+     * (if a file of this type is found compressed). Default is true,
+     *  exceptions are found in the nouncompforviewmts mimeview list */
+    bool mimeViewerNeedsUncomp(const string &mimetype) const;
+
+    /** Retrieve extra metadata-gathering commands */
+    const vector& getMDReapers();
+
+    /** Store/retrieve missing helpers description string */
+    bool getMissingHelperDesc(string&) const;
+    void storeMissingHelperDesc(const string &s);
+
+    /** Find exec file for external filter. 
+     *
+     * If the input is an absolute path, we just return it. Else We
+     * look in $RECOLL_FILTERSDIR, "filtersdir" from the config file,
+     * $RECOLL_CONFDIR/. If nothing is found, we return the input with
+     * the assumption that this will be used with a PATH-searching
+     * exec.
+     *
+     * @param cmd is normally the command name from the command string 
+     *    returned by getMimeHandlerDef(), but this could be used for any 
+     *    command. If cmd begins with a /, we return cmd without
+     *    further processing.
+     */
+    string findFilter(const string& cmd) const;
+
+    /** Thread config init is not done automatically because not all
+	programs need it and it uses the debug log so that it's better to
+	call it after primary init */
+    void initThrConf();
+
+    const string& getOrigCwd() 
+    {
+	return o_origcwd;
+    }
+
+    RclConfig& operator=(const RclConfig &r) {
+	if (this != &r) {
+	    freeAll();
+	    initFrom(r);
+	}
+	return *this;
+    }
+
+    friend class ParamStale;
+
+ private:
+    int m_ok;
+    string m_reason;    // Explanation for bad state
+    string m_confdir;   // User directory where the customized files are stored
+    // Normally same as confdir. Set to store all bulk data elsewhere.
+    // Provides defaults top location for dbdir, webcachedir,
+    // mboxcachedir, aspellDictDir, which can still be used to
+    // override.
+    string m_cachedir;  
+    string m_datadir;   // Example: /usr/local/share/recoll
+    string m_keydir;    // Current directory used for parameter fetches.
+    int    m_keydirgen; // To help with knowing when to update computed data.
+
+    vector m_cdirs; // directory stack for the confstacks
+
+    ConfStack *m_conf;   // Parsed configuration files
+    ConfStack *mimemap;  // The files don't change with keydir, 
+    ConfStack *mimeconf; // but their content may depend on it.
+    ConfStack *mimeview; // 
+    ConfStack *m_fields;
+    ConfSimple            *m_ptrans; // Paths translations
+    map  m_fldtotraits; // Field to field params
+    map  m_aliastocanon;
+    map  m_aliastoqcanon;
+    set          m_storedFields;
+    map  m_xattrtofld;
+
+    void        *m_stopsuffixes;
+    unsigned int m_maxsufflen;
+    ParamStale   m_oldstpsuffstate; // Values from user mimemap, now obsolete
+    ParamStale   m_stpsuffstate;
+
+    ParamStale   m_skpnstate;
+    vector m_skpnlist;
+
+    // Original current working directory. Set once at init before we do any
+    // chdir'ing and used for converting user args to absolute paths.
+    static string o_origcwd;
+
+    // Parameters auto-fetched on setkeydir
+    string m_defcharset;
+    static string o_localecharset;
+    // Limiting set of mime types to be processed. Normally empty.
+    ParamStale    m_rmtstate;
+    std::unordered_set   m_restrictMTypes; 
+    // Exclusion set of mime types. Normally empty
+    ParamStale    m_xmtstate;
+    std::unordered_set   m_excludeMTypes; 
+
+    vector > m_thrConf;
+
+    // Same idea with the metadata-gathering external commands,
+    // (e.g. used to reap tagging info: "tmsu tags %f")
+    ParamStale    m_mdrstate;
+    vector m_mdreapers;
+
+    /** Create initial user configuration */
+    bool initUserConfig();
+    /** Init all ParamStale members */
+    void initParamStale(ConfNull *cnf, ConfNull *mimemap);
+    /** Copy from other */
+    void initFrom(const RclConfig& r);
+    /** Init pointers to 0 */
+    void zeroMe();
+    /** Free data then zero pointers */
+    void freeAll();
+    bool readFieldsConfig(const string& errloc);
+};
+
+// This global variable defines if we are running with an index
+// stripped of accents and case or a raw one. Ideally, it should be
+// constant, but it needs to be initialized from the configuration, so
+// there is no way to do this. It never changes after initialization
+// of course. Changing the value on a given index imposes a
+// reset. When using multiple indexes, all must have the same value
+extern bool o_index_stripchars;
+
+// This global variable defines if we use mtime instead of ctime for
+// up-to-date tests. This is mostly incompatible with xattr indexing,
+// in addition to other issues. See recoll.conf comments. 
+extern bool o_uptodate_test_use_mtime;
+
+#endif /* _RCLCONFIG_H_INCLUDED_ */
diff --git a/src/common/rclinit.cpp b/src/common/rclinit.cpp
new file mode 100644
index 00000000..c9dd0ae2
--- /dev/null
+++ b/src/common/rclinit.cpp
@@ -0,0 +1,392 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#include "autoconfig.h"
+
+#include 
+#ifdef _WIN32
+#include "safewindows.h"
+#endif
+#include 
+#include 
+#include 
+#if !defined(PUTENV_ARG_CONST)
+#include 
+#endif
+
+#include 
+
+#include "log.h"
+#include "rclconfig.h"
+#include "rclinit.h"
+#include "pathut.h"
+#include "rclutil.h"
+#include "unac.h"
+#include "smallut.h"
+#include "execmd.h"
+
+std::thread::id mainthread_id;
+
+// Signal etc. processing. We want to be able to properly close the
+// index if we are currently writing to it.
+//
+// This is active if the sigcleanup parameter to recollinit is set,
+// which only recollindex does. We arrange for the handler to be
+// called when process termination is requested either by the system
+// or a user keyboard intr.
+//
+// The recollindex handler just sets a global termination flag (plus
+// the cancelcheck thing), which are tested in all timeout loops
+// etc. When the flag is seen, the main thread processing returns, and
+// recollindex calls exit().
+//
+// The other parameter, to recollinit(), cleanup, is set as an
+// atexit() routine, it does the job of actually signalling the
+// workers to stop and tidy up. It's automagically called by exit().
+
+#ifndef _WIN32
+static void siglogreopen(int)
+{
+    if (recoll_ismainthread())
+        Logger::getTheLog("")->reopen("");
+}
+
+// We would like to block SIGCHLD globally, but we can't because
+// QT uses it. Have to block it inside execmd.cpp
+static const int catchedSigs[] = {SIGINT, SIGQUIT, SIGTERM, SIGUSR1, SIGUSR2};
+void initAsyncSigs(void (*sigcleanup)(int))
+{
+    // We ignore SIGPIPE always. All pieces of code which can write to a pipe
+    // must check write() return values.
+    signal(SIGPIPE, SIG_IGN);
+
+    // Install app signal handler
+    if (sigcleanup) {
+	struct sigaction action;
+	action.sa_handler = sigcleanup;
+	action.sa_flags = 0;
+	sigemptyset(&action.sa_mask);
+	for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
+	    if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN) {
+		if (sigaction(catchedSigs[i], &action, 0) < 0) {
+		    perror("Sigaction failed");
+		}
+	    }
+    }
+
+    // Install log rotate sig handler
+    {
+	struct sigaction action;
+	action.sa_handler = siglogreopen;
+	action.sa_flags = 0;
+	sigemptyset(&action.sa_mask);
+	if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
+	    if (sigaction(SIGHUP, &action, 0) < 0) {
+		perror("Sigaction failed");
+	    }
+	}
+    }
+}
+void recoll_exitready()
+{
+}
+
+#else // _WIN32 ->
+
+// Windows signals etc.
+//
+// ^C can be caught by the signal() emulation, but not ^Break
+// apparently, which is why we use the native approach too
+//
+// When a keyboard interrupt occurs, windows creates a thread inside
+// the process and calls the handler. The process exits when the
+// handler returns or after at most 10S
+//
+// This should also work, with different signals (CTRL_LOGOFF_EVENT,
+// CTRL_SHUTDOWN_EVENT) when the user exits or the system shuts down).
+//
+// Unfortunately, this is not the end of the story. It seems that in
+// recent Windows version "some kinds" of apps will not reliably
+// receive the signals. "Some kind" is variably defined, for example a
+// simple test program works when built with vs 2015, but not
+// mingw. See the following discussion thread for tentative
+// explanations, it seems that importing or not from user32.dll is the
+// determining factor.
+// https://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/abf09824-4e4c-4f2c-ae1e-5981f06c9c6e/windows-7-console-application-has-no-way-of-trapping-logoffshutdown-event?forum=windowscompatibility
+// In any case, it appears that the only reliable way to be advised of
+// system shutdown or user exit is to create an "invisible window" and
+// process window messages, which we now do.
+
+static void (*l_sigcleanup)(int);
+static HANDLE eWorkFinished = INVALID_HANDLE_VALUE;
+
+static BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
+{
+    LOGDEB("CtrlHandler\n" );
+    if (l_sigcleanup == 0)
+        return FALSE;
+
+    switch(fdwCtrlType) { 
+    case CTRL_C_EVENT: 
+    case CTRL_CLOSE_EVENT: 
+    case CTRL_BREAK_EVENT: 
+    case CTRL_LOGOFF_EVENT: 
+    case CTRL_SHUTDOWN_EVENT:
+    {
+        l_sigcleanup(SIGINT);
+        LOGDEB0("CtrlHandler: waiting for exit ready\n" );
+	DWORD res = WaitForSingleObject(eWorkFinished, INFINITE);
+	if (res != WAIT_OBJECT_0) {
+            LOGERR("CtrlHandler: exit ack wait failed\n" );
+	}
+        LOGDEB0("CtrlHandler: got exit ready event, exiting\n" );
+        return TRUE;
+    }
+    default: 
+        return FALSE; 
+    } 
+} 
+
+LRESULT CALLBACK MainWndProc(HWND hwnd , UINT msg , WPARAM wParam,
+                             LPARAM lParam)
+{
+    switch (msg) {
+    case WM_QUERYENDSESSION:
+    case WM_ENDSESSION:
+    case WM_DESTROY:
+    case WM_CLOSE:
+    {
+        l_sigcleanup(SIGINT);
+        LOGDEB("MainWndProc: got end message, waiting for work finished\n" );
+	DWORD res = WaitForSingleObject(eWorkFinished, INFINITE);
+	if (res != WAIT_OBJECT_0) {
+            LOGERR("MainWndProc: exit ack wait failed\n" );
+	}
+        LOGDEB("MainWindowProc: got exit ready event, exiting\n" );
+        return TRUE;
+    }
+    default:
+        return DefWindowProc(hwnd, msg, wParam, lParam);
+    }
+    return TRUE;
+}
+
+bool CreateInvisibleWindow()
+{
+    HWND hwnd;
+    WNDCLASS wc = {0};
+
+    wc.lpfnWndProc = (WNDPROC)MainWndProc;
+    wc.hInstance = GetModuleHandle(NULL);
+    wc.hIcon = LoadIcon(GetModuleHandle(NULL), "TestWClass");
+    wc.lpszClassName = "TestWClass";
+    RegisterClass(&wc);
+
+    hwnd =
+        CreateWindowEx(0, "TestWClass", "TestWClass", WS_OVERLAPPEDWINDOW,
+                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
+                       CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL,
+                       GetModuleHandle(NULL), (LPVOID) NULL);
+    if (!hwnd) {
+        return FALSE;
+    }
+    return TRUE;
+}
+
+DWORD WINAPI RunInvisibleWindowThread(LPVOID lpParam)
+{
+    MSG msg;
+    CreateInvisibleWindow();
+    while (GetMessage(&msg, (HWND) NULL , 0 , 0)) {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+    return 0;
+}
+
+static const int catchedSigs[] = {SIGINT, SIGTERM};
+void initAsyncSigs(void (*sigcleanup)(int))
+{
+    DWORD tid;
+    // Install app signal handler
+    if (sigcleanup) {
+        l_sigcleanup = sigcleanup;
+	for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++) {
+	    if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN) {
+		signal(catchedSigs[i], sigcleanup);
+	    }
+        }
+    }
+    HANDLE hInvisiblethread =
+        CreateThread(NULL, 0, RunInvisibleWindowThread, NULL, 0, &tid);
+    SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlHandler, TRUE);
+    eWorkFinished = CreateEvent(NULL, TRUE, FALSE, NULL);
+    if (eWorkFinished == INVALID_HANDLE_VALUE) {
+        LOGERR("initAsyncSigs: error creating exitready event\n" );
+    }
+}
+void recoll_exitready()
+{
+    LOGDEB("recoll_exitready()\n" );
+    if (!SetEvent(eWorkFinished)) {
+        LOGERR("recoll_exitready: SetEvent failed\n" );
+    }
+}
+
+#endif
+
+RclConfig *recollinit(RclInitFlags flags, 
+		      void (*cleanup)(void), void (*sigcleanup)(int), 
+		      string &reason, const string *argcnf)
+{
+    if (cleanup)
+	atexit(cleanup);
+
+    // Make sure the locale is set. This is only for converting file names 
+    // to utf8 for indexing.
+    setlocale(LC_CTYPE, "");
+
+    Logger::getTheLog("")->setLogLevel(Logger::LLDEB1);
+
+    initAsyncSigs(sigcleanup);
+    
+    RclConfig *config = new RclConfig(argcnf);
+    if (!config || !config->ok()) {
+	reason = "Configuration could not be built:\n";
+	if (config)
+	    reason += config->getReason();
+	else
+	    reason += "Out of memory ?";
+	return 0;
+    }
+
+    // Retrieve the log file name and level. Daemon and batch indexing
+    // processes may use specific values, else fall back on common
+    // ones.
+    string logfilename, loglevel;
+    if (flags & RCLINIT_DAEMON) {
+	config->getConfParam(string("daemlogfilename"), logfilename);
+	config->getConfParam(string("daemloglevel"), loglevel);
+    }
+    if ((flags & RCLINIT_IDX) && logfilename.empty())
+	config->getConfParam(string("idxlogfilename"), logfilename);
+    if ((flags & RCLINIT_IDX) && loglevel.empty()) 
+	config->getConfParam(string("idxloglevel"), loglevel);
+
+    if (logfilename.empty())
+	config->getConfParam(string("logfilename"), logfilename);
+    if (loglevel.empty())
+	config->getConfParam(string("loglevel"), loglevel);
+
+    // Initialize logging
+    if (!logfilename.empty()) {
+	logfilename = path_tildexpand(logfilename);
+	// If not an absolute path or , compute relative to config dir
+	if (!path_isabsolute(logfilename) &&
+            logfilename.compare("stderr")) {
+	    logfilename = path_cat(config->getConfDir(), logfilename);
+	}
+        Logger::getTheLog("")->reopen(logfilename);
+    }
+    if (!loglevel.empty()) {
+	int lev = atoi(loglevel.c_str());
+        Logger::getTheLog("")->setLogLevel(Logger::LogLevel(lev));
+    }
+
+    // Make sure the locale charset is initialized (so that multiple
+    // threads don't try to do it at once).
+    config->getDefCharset();
+
+    mainthread_id = std::this_thread::get_id();
+
+    // Init smallut and pathut static values
+    pathut_init_mt();
+    smallut_init_mt();
+    rclutil_init_mt();
+    
+    // Init execmd.h static PATH and PATHELT splitting
+    {string bogus;
+        ExecCmd::which("nosuchcmd", bogus);
+    }
+    
+    // Init Unac translation exceptions
+    string unacex;
+    if (config->getConfParam("unac_except_trans", unacex) && !unacex.empty()) 
+	unac_set_except_translations(unacex.c_str());
+
+#ifndef IDX_THREADS
+    ExecCmd::useVfork(true);
+#else
+    // Keep threads init behind log init, but make sure it's done before
+    // we do the vfork choice ! The latter is not used any more actually, 
+    // we always use vfork except if forbidden by config.
+    if ((flags & RCLINIT_IDX)) {
+        config->initThrConf();
+    }
+
+    bool novfork;
+    config->getConfParam("novfork", &novfork);
+    if (novfork) {
+	LOGDEB0("rclinit: will use fork() for starting commands\n" );
+        ExecCmd::useVfork(false);
+    } else {
+	LOGDEB0("rclinit: will use vfork() for starting commands\n" );
+	ExecCmd::useVfork(true);
+    }
+#endif
+
+    int flushmb;
+    if (config->getConfParam("idxflushmb", &flushmb) && flushmb > 0) {
+	LOGDEB1("rclinit: idxflushmb="  << (flushmb) << ", set XAPIAN_FLUSH_THRESHOLD to 10E6\n" );
+	static const char *cp = "XAPIAN_FLUSH_THRESHOLD=1000000";
+#ifdef PUTENV_ARG_CONST
+	::putenv(cp);
+#else
+	::putenv(strdup(cp));
+#endif
+    }
+
+    return config;
+}
+
+// Signals are handled by the main thread. All others should call this
+// routine to block possible signals
+void recoll_threadinit()
+{
+#ifndef _WIN32
+    sigset_t sset;
+    sigemptyset(&sset);
+
+    for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++)
+	sigaddset(&sset, catchedSigs[i]);
+    sigaddset(&sset, SIGHUP);
+    pthread_sigmask(SIG_BLOCK, &sset, 0);
+#else
+    // Not sure that this is needed at all or correct under windows.
+    for (unsigned int i = 0; i < sizeof(catchedSigs) / sizeof(int); i++) {
+        if (signal(catchedSigs[i], SIG_IGN) != SIG_IGN) {
+            signal(catchedSigs[i], SIG_IGN);
+        }
+    }
+#endif
+}
+
+bool recoll_ismainthread()
+{
+    return std::this_thread::get_id() == mainthread_id;
+}
+
+
diff --git a/src/common/rclinit.h b/src/common/rclinit.h
new file mode 100644
index 00000000..470da903
--- /dev/null
+++ b/src/common/rclinit.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef _RCLINIT_H_INCLUDED_
+#define _RCLINIT_H_INCLUDED_
+
+#include 
+
+class RclConfig;
+/**
+ * Initialize by reading configuration, opening log file, etc.
+ *
+ * This must be called from the main thread before starting any others. It sets
+ * up the global signal handling. other threads must call recoll_threadinit()
+ * when starting.
+ *
+ * @param flags   misc modifiers. These are currently only used to customize
+ *      the log file and verbosity.
+ * @param cleanup function to call before exiting (atexit)
+ * @param sigcleanup function to call on terminal signal (INT/HUP...) This
+ *       should typically set a flag which tells the program (recoll,
+ *       recollindex etc.. to exit as soon as possible (after closing the db,
+ *       etc.). cleanup will then be called by exit().
+ * @param reason in case of error: output string explaining things
+ * @param argcnf Configuration directory name from the command line (overriding
+ *               default and environment
+ * @return the parsed configuration.
+ */
+enum RclInitFlags {RCLINIT_NONE = 0, RCLINIT_DAEMON = 1, RCLINIT_IDX = 2};
+extern RclConfig *recollinit(RclInitFlags flags,
+                             void (*cleanup)(void), void (*sigcleanup)(int),
+                             std::string& reason, const string *argcnf = 0);
+inline RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int),
+                             std::string& reason,
+                             const std::string *argcnf = 0)
+{
+    return recollinit(RCLINIT_NONE, cleanup, sigcleanup, reason, argcnf);
+}
+
+// Threads need to call this to block signals.
+// The main thread handles all signals.
+extern void recoll_threadinit();
+
+// Check if main thread
+extern bool recoll_ismainthread();
+
+// Should be called while exiting asap when critical cleanup (db
+// close) has been performed. Only useful for the indexer (writes to
+// the db), and only actually does something on Windows.
+extern void recoll_exitready();
+
+#endif /* _RCLINIT_H_INCLUDED_ */
diff --git a/src/common/rclversion.h.in b/src/common/rclversion.h.in
new file mode 100644
index 00000000..4b8fe507
--- /dev/null
+++ b/src/common/rclversion.h.in
@@ -0,0 +1 @@
+static const char *rclversionstr = "@RCLVERSION@";
diff --git a/src/common/syngroups.cpp b/src/common/syngroups.cpp
new file mode 100644
index 00000000..efbc42e9
--- /dev/null
+++ b/src/common/syngroups.cpp
@@ -0,0 +1,250 @@
+/* Copyright (C) 2014 J.F.Dockes
+ *   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.
+ */
+#ifndef TEST_SYNGROUPS
+#include "autoconfig.h"
+
+#include "syngroups.h"
+
+#include "log.h"
+#include "smallut.h"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace std;
+
+// Note that we are storing each term twice. I don't think that the
+// size could possibly be a serious issue, but if it was, we could
+// reduce the storage a bit by storing (short hash)-> vector
+// correspondances in the direct map, and then checking all the
+// resulting groups for the input word.
+//
+// As it is, a word can only index one group (the last it is found
+// in). It can be part of several groups though (appear in
+// expansions). I really don't know what we should do with multiple
+// groups anyway
+class SynGroups::Internal {
+public:
+    Internal() : ok(false) {
+    }
+    bool ok;
+    // Term to group num 
+    std::unordered_map terms;
+    // Group num to group
+    vector > groups;
+};
+
+bool SynGroups::ok() 
+{
+    return m && m->ok;
+}
+
+SynGroups::~SynGroups()
+{
+    delete m;
+}
+
+SynGroups::SynGroups()
+    : m(new Internal)
+{
+}
+
+bool SynGroups::setfile(const string& fn)
+{
+    LOGDEB("SynGroups::setfile("  << (fn) << ")\n" );
+    if (!m) {
+        m = new Internal;
+        if (!m) {
+            LOGERR("SynGroups:setfile:: new Internal failed: no mem ?\n" );
+            return false;
+        }
+    }
+
+    if (fn.empty()) {
+        delete m;
+        m = 0;
+	return true;
+    }
+
+    ifstream input;
+    input.open(fn.c_str(), ios::in);
+    if (!input.is_open()) {
+	LOGERR("SynGroups:setfile:: could not open "  << (fn) << " errno "  << (errno) << "\n" );
+	return false;
+    }	    
+
+    string cline;
+    bool appending = false;
+    string line;
+    bool eof = false;
+    int lnum = 0;
+
+    for (;;) {
+        cline.clear();
+	getline(input, cline);
+	if (!input.good()) {
+	    if (input.bad()) {
+                LOGERR("Syngroup::setfile("  << (fn) << "):Parse: input.bad()\n" );
+		return false;
+	    }
+	    // Must be eof ? But maybe we have a partial line which
+	    // must be processed. This happens if the last line before
+	    // eof ends with a backslash, or there is no final \n
+            eof = true;
+	}
+	lnum++;
+
+        {
+            string::size_type pos = cline.find_last_not_of("\n\r");
+            if (pos == string::npos) {
+                cline.clear();
+            } else if (pos != cline.length()-1) {
+                cline.erase(pos+1);
+            }
+        }
+
+	if (appending)
+	    line += cline;
+	else
+	    line = cline;
+
+	// Note that we trim whitespace before checking for backslash-eol
+	// This avoids invisible whitespace problems.
+	trimstring(line);
+	if (line.empty() || line.at(0) == '#') {
+            if (eof)
+                break;
+	    continue;
+	}
+	if (line[line.length() - 1] == '\\') {
+	    line.erase(line.length() - 1);
+	    appending = true;
+	    continue;
+	}
+	appending = false;
+
+	vector words;
+	if (!stringToStrings(line, words)) {
+	    LOGERR("SynGroups:setfile: "  << (fn) << ": bad line "  << (lnum) << ": "  << (line) << "\n" );
+	    continue;
+	}
+
+	if (words.empty())
+	    continue;
+	if (words.size() == 1) {
+	    LOGERR("Syngroup::setfile("  << (fn) << "):single term group at line "  << (lnum) << " ??\n" );
+	    continue;
+	}
+
+	m->groups.push_back(words);
+	for (vector::const_iterator it = words.begin();
+	     it != words.end(); it++) {
+	    m->terms[*it] = m->groups.size()-1;
+	}
+	LOGDEB1("SynGroups::setfile: group: ["  << (stringsToString(m->groups.back())) << "]\n" );
+    }
+    m->ok = true;
+    return true;
+}
+
+vector SynGroups::getgroup(const string& term)
+{
+    vector ret;
+    if (!ok())
+	return ret;
+
+    std::unordered_map::const_iterator it1 =
+        m->terms.find(term);
+    if (it1 == m->terms.end()) {
+	LOGDEB1("SynGroups::getgroup: ["  << (term) << "] not found in direct map\n" );
+	return ret;
+    }
+
+    unsigned int idx = it1->second;
+    if (idx >= m->groups.size()) {
+        LOGERR("SynGroups::getgroup: line index higher than line count !\n" );
+        return ret;
+    }
+    return m->groups[idx];
+}
+
+#else
+
+#include "syngroups.h"
+#include "log.h"
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+using namespace std;
+
+static char *thisprog;
+
+static char usage [] =
+    "syngroups  \n"
+    "  \n\n"
+    ;
+static void Usage(void)
+{
+    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
+    exit(1);
+}
+
+static int     op_flags;
+#define OPT_MOINS 0x1
+#define OPT_s     0x2
+#define OPT_b     0x4
+
+int main(int argc, char **argv)
+{
+    thisprog = argv[0];
+    argc--; argv++;
+
+    if (argc != 2) {
+        Usage();
+    }
+    string fn = *argv++;argc--;
+    string word = *argv++;argc--;
+
+    DebugLog::getdbl()->setloglevel(DEBDEB1);
+    DebugLog::setfilename("stderr");
+    SynGroups syns;
+    syns.setfile(fn);
+    if (!syns.ok()) {
+	cerr << "Initialization failed\n";
+	return 1;
+    }
+
+    vector group = syns.getgroup(word);
+    cout << group.size() << " terms in group\n";
+    for (vector::const_iterator it = group.begin();
+	 it != group.end(); it++) {
+	cout << "[" << *it << "] ";
+    }
+    cout << endl;
+    return 0;
+}
+
+#endif
+
diff --git a/src/common/syngroups.h b/src/common/syngroups.h
new file mode 100644
index 00000000..62a71523
--- /dev/null
+++ b/src/common/syngroups.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2015 J.F.Dockes
+ *   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.
+ */
+
+#ifndef _SYNGROUPS_H_INCLUDED_
+#define _SYNGROUPS_H_INCLUDED_
+
+#include 
+#include 
+
+// Manage synonym groups. This is very different from stemming and
+// case/diac expansion because there is no reference form: all terms
+// in a group are equivalent.
+class SynGroups {
+public:
+    SynGroups();
+    ~SynGroups();
+    bool setfile(const std::string& fname);
+    std::vector getgroup(const std::string& term);
+    bool ok();
+private:
+    class Internal;
+    Internal *m;
+    SynGroups(const SynGroups&);
+    SynGroups& operator=(const SynGroups&);
+};
+
+#endif /* _SYNGROUPS_H_INCLUDED_ */
diff --git a/src/common/textsplit.cpp b/src/common/textsplit.cpp
new file mode 100644
index 00000000..7b797421
--- /dev/null
+++ b/src/common/textsplit.cpp
@@ -0,0 +1,1240 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef TEST_TEXTSPLIT
+#include "autoconfig.h"
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "textsplit.h"
+#include "log.h"
+//#define UTF8ITER_CHECK
+#include "utf8iter.h"
+#include "uproplist.h"
+
+using namespace std;
+
+/**
+ * Splitting a text into words. The code in this file works with utf-8
+ * in a semi-clean way (see uproplist.h). Ascii still gets special
+ * treatment in the sense that many special characters can only be
+ * ascii (e.g. @, _,...). However, this compromise works quite well
+ * while being much more light-weight than a full-blown Unicode
+ * approach (ICU...)
+ */
+
+// Ascii character classes: we have three main groups, and then some chars
+// are their own class because they want special handling.
+// 
+// We have an array with 256 slots where we keep the character types. 
+// The array could be fully static, but we use a small function to fill it 
+// once.
+// The array is actually a remnant of the original version which did no utf8.
+// Only the lower 127 slots are  now used, but keep it at 256
+// because it makes some tests in the code simpler.
+const unsigned int charclasses_size = 256;
+enum CharClass {LETTER=256, SPACE=257, DIGIT=258, WILD=259, 
+                A_ULETTER=260, A_LLETTER=261, SKIP=262};
+static int charclasses[charclasses_size];
+
+// Non-ascii UTF-8 characters are handled with sets holding all
+// characters with interesting properties. This is far from full-blown
+// management of Unicode properties, but seems to do the job well
+// enough in most common cases
+static vector vpuncblocks;
+static std::unordered_set spunc;
+static std::unordered_set visiblewhite;
+static std::unordered_set sskip;
+
+class CharClassInit {
+public:
+    CharClassInit() 
+    {
+	unsigned int i;
+
+	// Set default value for all: SPACE
+	for (i = 0 ; i < 256 ; i ++)
+	    charclasses[i] = SPACE;
+
+	char digits[] = "0123456789";
+	for (i = 0; i  < strlen(digits); i++)
+	    charclasses[int(digits[i])] = DIGIT;
+
+	char upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	for (i = 0; i  < strlen(upper); i++)
+	    charclasses[int(upper[i])] = A_ULETTER;
+
+	char lower[] = "abcdefghijklmnopqrstuvwxyz";
+	for (i = 0; i  < strlen(lower); i++)
+	    charclasses[int(lower[i])] = A_LLETTER;
+
+	char wild[] = "*?[]";
+	for (i = 0; i  < strlen(wild); i++)
+	    charclasses[int(wild[i])] = WILD;
+
+        // Characters with special treatment:
+        //
+        // The first ones are mostly span-constructing "glue"
+        // characters, for example those typically allowing us to
+        // search for an email address as a whole (bob@isp.org instead
+        // of as a phrase "bob isp org"
+        //
+        // The case of the minus sign is a complicated one. It went
+        // from glue to non-glue to glue along Recoll versions. 
+        // See minus-hyphen-dash.txt in doc/notes
+	char special[] = ".@+-#'_\n\r\f";
+	for (i = 0; i  < strlen(special); i++)
+	    charclasses[int(special[i])] = special[i];
+
+	for (i = 0; i < sizeof(unipunc) / sizeof(int); i++) {
+	    spunc.insert(unipunc[i]);
+	}
+	spunc.insert((unsigned int)-1);
+
+	for (i = 0; i < sizeof(unipuncblocks) / sizeof(int); i++) {
+	    vpuncblocks.push_back(unipuncblocks[i]);
+	}
+	assert((vpuncblocks.size() % 2) == 0);
+
+	for (i = 0; i < sizeof(avsbwht) / sizeof(int); i++) {
+	    visiblewhite.insert(avsbwht[i]);
+	}
+	for (i = 0; i < sizeof(uniskip) / sizeof(int); i++) {
+	    sskip.insert(uniskip[i]);
+	}
+    }
+};
+static const CharClassInit charClassInitInstance;
+
+static inline int whatcc(unsigned int c)
+{
+    if (c <= 127) {
+	return charclasses[c]; 
+    } else {
+        if (c == 0x2010) {
+            // Special treatment for hyphen: handle as ascii minus. See
+            // doc/notes/minus-hyphen-dash.txt
+            return 0x2010;
+        } else if (sskip.find(c) != sskip.end()) {
+	    return SKIP;
+	} else if (spunc.find(c) != spunc.end()) {
+	    return SPACE;
+	} else {
+	    vector::iterator it = 
+		lower_bound(vpuncblocks.begin(), vpuncblocks.end(), c);
+		if (it == vpuncblocks.end())
+			return LETTER;
+	    if (c == *it)
+		return SPACE;
+	    if ((it - vpuncblocks.begin()) % 2 == 1) {
+		return SPACE;
+	    } else {
+		return LETTER;
+	    }
+	} 
+    }
+}
+
+// testing whatcc...
+#if 0
+  unsigned int testvalues[] = {'a', '0', 0x80, 0xbf, 0xc0, 0x05c3, 0x1000, 
+			       0x2000, 0x2001, 0x206e, 0x206f, 0x20d0, 0x2399, 
+			       0x2400, 0x2401, 0x243f, 0x2440, 0xff65};
+  int ntest = sizeof(testvalues) / sizeof(int);
+  for (int i = 0; i < ntest; i++) {
+      int ret = whatcc(testvalues[i]);
+      printf("Tested value 0x%x, returned value %d %s\n",
+	     testvalues[i], ret, ret == LETTER ? "LETTER" : 
+	     ret == SPACE ? "SPACE" : "OTHER");
+  }
+#endif
+
+// CJK Unicode character detection:
+//
+// 2E80..2EFF; CJK Radicals Supplement
+// 3000..303F; CJK Symbols and Punctuation
+// 3040..309F; Hiragana
+// 30A0..30FF; Katakana
+// 3100..312F; Bopomofo
+// 3130..318F; Hangul Compatibility Jamo
+// 3190..319F; Kanbun
+// 31A0..31BF; Bopomofo Extended
+// 31C0..31EF; CJK Strokes
+// 31F0..31FF; Katakana Phonetic Extensions
+// 3200..32FF; Enclosed CJK Letters and Months
+// 3300..33FF; CJK Compatibility
+// 3400..4DBF; CJK Unified Ideographs Extension A
+// 4DC0..4DFF; Yijing Hexagram Symbols
+// 4E00..9FFF; CJK Unified Ideographs
+// A700..A71F; Modifier Tone Letters
+// AC00..D7AF; Hangul Syllables
+// F900..FAFF; CJK Compatibility Ideographs
+// FE30..FE4F; CJK Compatibility Forms
+// FF00..FFEF; Halfwidth and Fullwidth Forms
+// 20000..2A6DF; CJK Unified Ideographs Extension B
+// 2F800..2FA1F; CJK Compatibility Ideographs Supplement
+// Note: the p > 127 test is not necessary, but optimizes away the ascii case
+#define UNICODE_IS_CJK(p)						\
+    ((p) > 127 &&							\
+     (((p) >= 0x2E80 && (p) <= 0x2EFF) ||				\
+      ((p) >= 0x3000 && (p) <= 0x9FFF) ||				\
+      ((p) >= 0xA700 && (p) <= 0xA71F) ||				\
+      ((p) >= 0xAC00 && (p) <= 0xD7AF) ||				\
+      ((p) >= 0xF900 && (p) <= 0xFAFF) ||				\
+      ((p) >= 0xFE30 && (p) <= 0xFE4F) ||				\
+      ((p) >= 0xFF00 && (p) <= 0xFFEF) ||				\
+      ((p) >= 0x20000 && (p) <= 0x2A6DF) ||				\
+      ((p) >= 0x2F800 && (p) <= 0x2FA1F)))
+
+bool TextSplit::isCJK(int c)
+{
+    return UNICODE_IS_CJK(c);
+}
+
+bool          TextSplit::o_processCJK = true;
+unsigned int  TextSplit::o_CJKNgramLen = 2;
+bool          TextSplit::o_noNumbers = false;
+bool          TextSplit::o_deHyphenate = false;
+
+// Final term checkpoint: do some checking (the kind which is simpler
+// to do here than in the main loop), then send term to our client.
+inline bool TextSplit::emitterm(bool isspan, string &w, int pos, 
+				size_t btstart, size_t btend)
+{
+    LOGDEB2("TextSplit::emitterm: ["  << (w) << "] pos "  << (pos) << "\n" );
+
+    int l = int(w.length());
+
+#ifdef TEXTSPLIT_STATS
+    // Update word length statistics. Do this before we filter out
+    // long words because stats are used to detect bad text
+    if (!isspan || m_wordLen == m_span.length())
+	m_stats.newsamp(m_wordChars);
+#endif
+
+    if (l > 0 && l < m_maxWordLength) {
+	// 1 byte word: we index single ascii letters and digits, but
+	// nothing else. We might want to turn this into a test for a
+	// single utf8 character instead ?
+	if (l == 1) {
+	    unsigned int c = ((unsigned int)w[0]) & 0xff;
+	    if (charclasses[c] != A_ULETTER && charclasses[c] != A_LLETTER && 
+                charclasses[c] != DIGIT &&
+		(!(m_flags & TXTS_KEEPWILD) || charclasses[c] != WILD)
+		) {
+		//cerr << "ERASING single letter term " << c << endl;
+		return true;
+	    }
+	}
+	if (pos != m_prevpos || l != m_prevlen) {
+	    bool ret = takeword(w, pos, int(btstart), int(btend));
+	    m_prevpos = pos;
+	    m_prevlen = int(w.length());
+	    return ret;
+	}
+	LOGDEB2("TextSplit::emitterm:dup: ["  << (w) << "] pos "  << (pos) << "\n" );
+    }
+    return true;
+}
+
+// Check for an acronym/abbreviation ie I.B.M. This only works with
+// ascii (no non-ascii utf-8 acronym are possible)
+bool TextSplit::span_is_acronym(string *acronym)
+{
+    bool acron = false;
+
+    if (m_wordLen != m_span.length() && 
+        m_span.length() > 2 && m_span.length() <= 20) {
+        acron = true;
+        // Check odd chars are '.'
+        for (unsigned int i = 1 ; i < m_span.length(); i += 2) {
+            if (m_span[i] != '.') {
+                acron = false;
+                break;
+            }
+        }
+        if (acron) {
+            // Check that even chars are letters
+            for (unsigned int i = 0 ; i < m_span.length(); i += 2) {
+                int c = m_span[i];
+                if (!((c >= 'a' && c <= 'z')||(c >= 'A' && c <= 'Z'))) {
+                    acron = false;
+                    break;
+                }
+            }
+        }
+    }
+    if (acron) {
+        for (unsigned int i = 0; i < m_span.length(); i += 2) {
+            *acronym += m_span[i];
+        }
+    }
+    return acron;
+}
+
+
+// Generate terms from span. Have to take into account the
+// flags: ONLYSPANS, NOSPANS, noNumbers
+bool TextSplit::words_from_span(size_t bp)
+{
+#if 0
+    cerr << "Span: [" << m_span << "] " << " w_i_s size: " << 
+        m_words_in_span.size() <<  " : ";
+    for (unsigned int i = 0; i < m_words_in_span.size(); i++) {
+        cerr << " [" << m_words_in_span[i].first << " " <<
+            m_words_in_span[i].second << "] ";
+                
+    }
+    cerr << endl;
+#endif
+    int spanwords = int(m_words_in_span.size());
+    int pos = m_spanpos;
+    // Byte position of the span start
+    size_t spboffs = bp - m_span.size();
+
+    if (o_deHyphenate && spanwords == 2 && 
+	m_span[m_words_in_span[0].second] == '-') {
+	unsigned int s0 = m_words_in_span[0].first;
+	unsigned int l0 = m_words_in_span[0].second - m_words_in_span[0].first;
+	unsigned int s1 = m_words_in_span[1].first;
+	unsigned int l1 = m_words_in_span[1].second - m_words_in_span[1].first;
+	string word = m_span.substr(s0, l0) + m_span.substr(s1, l1);
+	if (l0 && l1) 
+	    emitterm(false, word,
+		     m_spanpos, spboffs, spboffs + m_words_in_span[1].second);
+    }
+
+    for (int i = 0; 
+         i < ((m_flags&TXTS_ONLYSPANS) ? 1 : spanwords); 
+         i++) {
+
+        int deb = m_words_in_span[i].first;
+        bool noposinc = m_words_in_span[i].second == deb;
+        for (int j = ((m_flags&TXTS_ONLYSPANS) ? spanwords-1 : i);
+             j < ((m_flags&TXTS_NOSPANS) ? i+1 : spanwords);
+             j++) {
+
+            int fin = m_words_in_span[j].second;
+            //cerr << "i " << i << " j " << j << " deb " << deb << 
+            //" fin " << fin << endl;
+            if (fin - deb > int(m_span.size()))
+                break;
+            string word(m_span.substr(deb, fin-deb));
+            if (!emitterm(j != i+1, word, pos, spboffs+deb, spboffs+fin))
+                return false;
+        }
+        if (!noposinc)
+            ++pos;
+    }
+    return true;
+}
+
+/**
+ * A method called at word boundaries (different places in
+ * text_to_words()), to adjust the current state of the parser, and
+ * possibly generate term(s). While inside a span (words linked by
+ * glue characters), we just keep track of the word boundaries. Once
+ * actual white-space is reached, we get called with spanerase set to
+ * true, and we process the span, calling the emitterm() routine for
+ * each generated term.
+ * 
+ * The object flags can modify our behaviour, deciding if we only emit
+ * single words (bill, recoll, org), only spans (bill@recoll.org), or
+ * words and spans (bill@recoll.org, recoll.org, jf, recoll...)
+ * 
+ * @return true if ok, false for error. Splitting should stop in this case.
+ * @param spanerase Set if the current span is at its end. Process it.
+ * @param bp        The current BYTE position in the stream
+ */
+inline bool TextSplit::doemit(bool spanerase, size_t _bp)
+{
+    int bp = int(_bp);
+    LOGDEB2("TextSplit::doemit: sper "  << (spanerase) << " bp "  << (bp) << " spp "  << (m_spanpos) << " spanwords "  << (m_words_in_span.size()) << " wS "  << (m_wordStart) << " wL "  << (m_wordLen) << " inn "  << (m_inNumber) << " span ["  << (m_span) << "]\n" );
+
+    if (m_wordLen) {
+        // We have a current word. Remember it
+
+        // Limit max span word count
+        if (m_words_in_span.size() >= 6) {
+            spanerase = true;
+        } 
+
+        m_words_in_span.push_back(pair(m_wordStart, 
+                                                m_wordStart + m_wordLen));
+	m_wordpos++;
+	m_wordLen = m_wordChars = 0;
+    }
+
+    if (spanerase) {
+        // We encountered a span-terminating character. Produce terms.
+
+        string acronym;
+        if (span_is_acronym(&acronym)) {
+            if (!emitterm(false, acronym, m_spanpos, bp - m_span.length(), bp))
+                return false;
+        }
+
+	// Maybe trim at end. These are chars that we might keep
+	// inside a span, but not at the end.
+	while (m_span.length() > 0) {
+	    switch (*(m_span.rbegin())) {
+	    case '.':
+	    case '-':
+	    case ',':
+	    case '@':
+	    case '_':
+	    case '\'':
+		m_span.resize(m_span.length()-1);
+                if (m_words_in_span.size() &&
+                    m_words_in_span.back().second > int(m_span.size()))
+                    m_words_in_span.back().second = int(m_span.size());
+		if (--bp < 0) 
+		    bp = 0;
+		break;
+	    default:
+		goto breaktrimloop;
+	    }
+	}
+    breaktrimloop:
+
+        if (!words_from_span(bp)) {
+            return false;
+        }
+	discardspan();
+
+    } else {
+    
+	m_wordStart = int(m_span.length());
+
+    }
+
+    return true;
+}
+
+void TextSplit::discardspan()
+{
+    m_words_in_span.clear();
+    m_span.erase();
+    m_spanpos = m_wordpos;
+    m_wordStart = 0;
+    m_wordLen = m_wordChars = 0;
+}
+
+static inline bool isalphanum(int what, unsigned int flgs)
+{
+    return what == A_LLETTER || what == A_ULETTER ||
+	what == DIGIT || what == LETTER ||
+	((flgs & TextSplit::TXTS_KEEPWILD) && what == WILD);
+}
+static inline bool isdigit(int what, unsigned int flgs)
+{
+    return what == DIGIT || ((flgs & TextSplit::TXTS_KEEPWILD) && what == WILD);
+}
+
+#ifdef TEXTSPLIT_STATS
+#define STATS_INC_WORDCHARS ++m_wordChars
+#else
+#define STATS_INC_WORDCHARS
+#endif
+
+/** 
+ * Splitting a text into terms to be indexed.
+ * We basically emit a word every time we see a separator, but some chars are
+ * handled specially so that special cases, ie, c++ and jfd@recoll.com etc, 
+ * are handled properly,
+ */
+bool TextSplit::text_to_words(const string &in)
+{
+    LOGDEB1("TextSplit::text_to_words: docjk " << o_processCJK << "(" <<
+            o_CJKNgramLen <<  ")" << 
+            (m_flags & TXTS_NOSPANS ? " nospans" : "") << 
+            (m_flags & TXTS_ONLYSPANS ? " onlyspans" : "") << 
+            (m_flags & TXTS_KEEPWILD ? " keepwild" : "") << 
+            "[" << in.substr(0,50) << "]\n");
+
+    if (in.empty())
+	return true;
+
+    m_span.erase();
+    m_inNumber = false;
+    m_wordStart = m_wordLen = m_wordChars = m_prevpos = m_prevlen = m_wordpos 
+	= m_spanpos = 0;
+    bool pagepending = false;
+    bool softhyphenpending = false;
+
+    // Running count of non-alphanum chars. Reset when we see one;
+    int nonalnumcnt = 0;
+
+    Utf8Iter it(in);
+
+    for (; !it.eof(); it++) {
+	unsigned int c = *it;
+	nonalnumcnt++;
+
+	if (c == (unsigned int)-1) {
+	    LOGERR("Textsplit: error occured while scanning UTF-8 string\n" );
+	    return false;
+	}
+
+	if (o_processCJK && UNICODE_IS_CJK(c)) {
+	    // CJK character hit. 
+	    // Do like at EOF with the current non-cjk data.
+	    if (m_wordLen || m_span.length()) {
+		if (!doemit(true, it.getBpos()))
+		    return false;
+	    }
+
+	    // Hand off situation to the cjk routine.
+	    if (!cjk_to_words(&it, &c)) {
+		LOGERR("Textsplit: scan error in cjk handler\n" );
+		return false;
+	    }
+
+	    // Check for eof, else c contains the first non-cjk
+	    // character after the cjk sequence, just go on.
+	    if (it.eof())
+		break;
+	}
+
+	int cc = whatcc(c);
+
+	switch (cc) {
+	case SKIP:
+	    // Special-case soft-hyphen. To work, this depends on the
+	    // fact that only SKIP calls "continue" inside the
+	    // switch. All the others will do the softhyphenpending
+	    // reset after the switch
+	    if (c == 0xad) {
+		softhyphenpending = true;
+	    } else {
+		softhyphenpending = false;
+	    }
+	    // Skips the softhyphenpending reset
+	    continue;
+
+	case DIGIT:
+	    nonalnumcnt = 0;
+	    if (m_wordLen == 0)
+		m_inNumber = true;
+	    m_wordLen += it.appendchartostring(m_span);
+	    STATS_INC_WORDCHARS;
+	    break;
+
+	case SPACE:
+	    nonalnumcnt = 0;
+	SPACE:
+	    if (m_wordLen || m_span.length()) {
+		if (!doemit(true, it.getBpos()))
+		    return false;
+		m_inNumber = false;
+	    }
+	    if (pagepending) {
+		pagepending = false;
+		newpage(m_wordpos);
+	    }
+	    break;
+
+	case WILD:
+	    if (m_flags & TXTS_KEEPWILD)
+		goto NORMALCHAR;
+	    else
+		goto SPACE;
+	    break;
+
+	case '-':
+	case '+':
+	    if (m_wordLen == 0) {
+		// + or - don't start a term except if this looks like
+		// it's going to be to be a number
+		if (isdigit(whatcc(it[it.getCpos()+1]), m_flags)) {
+		    // -10
+		    m_inNumber = true;
+		    m_wordLen += it.appendchartostring(m_span);
+		    STATS_INC_WORDCHARS;
+                    break;
+		} 
+	    } else if (m_inNumber) {
+                if ((m_span[m_span.length() - 1] == 'e' ||
+				      m_span[m_span.length() - 1] == 'E')) {
+                    if (isdigit(whatcc(it[it.getCpos()+1]), m_flags)) {
+                        m_wordLen += it.appendchartostring(m_span);
+                        STATS_INC_WORDCHARS;
+                        break;
+                    }
+                }
+	    } else {
+                if (cc == '+') {
+                    int nextc = it[it.getCpos()+1];
+                    if (nextc == '+' || nextc == -1 || visiblewhite.find(nextc) 
+                        != visiblewhite.end()) {
+                        // someword++[+...] !
+                        m_wordLen += it.appendchartostring(m_span);
+                        STATS_INC_WORDCHARS;
+                        break;
+                    }
+                } else {
+                    // Treat '-' inside span as glue char
+                    if (!doemit(false, it.getBpos()))
+                        return false;
+                    m_inNumber = false;
+                    m_wordStart += it.appendchartostring(m_span);
+                    break;
+                }
+	    }
+            goto SPACE;
+	    break;
+
+	case 0x2010:
+            // Hyphen is replaced with ascii minus
+	    if (m_wordLen != 0) {
+                // Treat '-' inside span as glue char
+                if (!doemit(false, it.getBpos()))
+                    return false;
+                m_inNumber = false;
+                m_span += '-';
+                m_wordStart++;
+                break;
+            }
+            goto SPACE;
+
+	case '.':
+	{
+	    // Need a little lookahead here. At worse this gets the end null
+	    int nextc = it[it.getCpos()+1];
+	    int nextwhat = whatcc(nextc);
+	    if (m_inNumber) {
+		if (!isdigit(nextwhat, m_flags))
+		    goto SPACE;
+                m_wordLen += it.appendchartostring(m_span);
+                STATS_INC_WORDCHARS;
+		break;
+	    } else {
+		// Found '.' while not in number
+
+		// Only letters and digits make sense after
+		if (!isalphanum(nextwhat, m_flags))
+		    goto SPACE;
+
+		// Keep an initial '.' for catching .net, and .34 (aka
+		// 0.34) but this adds quite a few spurious terms !
+                if (m_span.length() == 0) {
+                    // Check for number like .1
+                    if (isdigit(nextwhat, m_flags)) {
+                        m_inNumber = true;
+                        m_wordLen += it.appendchartostring(m_span);
+                    } else {
+                        m_words_in_span.
+                            push_back(pair(m_wordStart, m_wordStart));
+                        m_wordStart += it.appendchartostring(m_span);
+                    }
+                    STATS_INC_WORDCHARS;
+                    break;
+                }
+
+                // '.' between words: span glue
+                if (m_wordLen) {
+                    if (!doemit(false, it.getBpos()))
+                        return false;
+                    m_wordStart += it.appendchartostring(m_span);
+                }
+	    }
+	}
+        break;
+
+	case '@':
+	case '_':
+	case '\'':
+	    // If in word, potential span: o'brien, jf@dockes.org,
+	    // else just ignore
+	    if (m_wordLen) {
+		if (!doemit(false, it.getBpos()))
+		    return false;
+		m_inNumber = false;
+                m_wordStart += it.appendchartostring(m_span);
+	    }
+	    break;
+
+	case '#':  {
+	    int w = whatcc(it[it.getCpos()+1]);
+	    // Keep it only at the beginning of a word (hashtag), 
+            if (m_wordLen == 0 && isalphanum(w, m_flags)) {
+                m_wordLen += it.appendchartostring(m_span);
+                STATS_INC_WORDCHARS;
+                break;
+            }
+            // or at the end (special case for c# ...)
+	    if (m_wordLen > 0) {
+		if (w == SPACE || w == '\n' || w == '\r') {
+		    m_wordLen += it.appendchartostring(m_span);
+		    STATS_INC_WORDCHARS;
+		    break;
+		}
+	    }
+	    goto SPACE;
+	}
+	    break;
+
+	case '\n':
+	case '\r':
+	    if (m_span.length() && *m_span.rbegin() == '-') {
+                // if '-' is the last char before end of line, we
+                // strip it.  We have no way to know if this is added
+                // because of the line split or if it was part of an
+                // actual compound word (would need a dictionary to
+                // check).  As soft-hyphen *should* be used if the '-'
+                // is not part of the text, it is better to properly
+                // process a real compound word, and produce wrong
+                // output from wrong text. The word-emitting routine
+                // will strip the trailing '-'.
+                goto SPACE;
+            } else if (softhyphenpending) {
+		// Don't reset soft-hyphen
+		continue;
+	    } else {
+		// Normal case: EOL is white space
+		goto SPACE;
+	    }
+	    break;
+
+	case '\f':
+	    pagepending = true;
+	    goto SPACE;
+	    break;
+
+#ifdef RCL_SPLIT_CAMELCASE
+            // Camelcase handling. 
+            // If we get uppercase ascii after lowercase ascii, emit word.
+            // This emits "camel" when hitting the 'C' of camelCase
+            // Not enabled by defaults as this makes phrase searches quite 
+            // confusing. 
+            // ie "MySQL manual" is matched by "MySQL manual" and 
+            // "my sql manual" but not "mysql manual"
+
+            // A possibility would be to emit both my and sql at the
+            // same position. All non-phrase searches would work, and
+            // both "MySQL manual" and "mysql manual" phrases would
+            // match too. "my sql manual" would not match, but this is
+            // not an issue.
+	case A_ULETTER:
+	    if (m_span.length() && 
+                charclasses[(unsigned char)m_span[m_span.length() - 1]] == 
+                A_LLETTER) {
+                if (m_wordLen) {
+                    if (!doemit(false, it.getBpos()))
+                        return false;
+                }
+            }
+            goto NORMALCHAR;
+
+            // CamelCase handling.
+            // If we get lowercase after uppercase and the current
+            // word length is bigger than one, it means we had a
+            // string of several upper-case letters:  an
+            // acronym (readHTML) or a single letter article (ALittleHelp).
+            // Emit the uppercase word before proceeding
+        case A_LLETTER:
+	    if (m_span.length() && 
+                charclasses[(unsigned char)m_span[m_span.length() - 1]] == 
+                A_ULETTER && m_wordLen > 1) {
+                // Multiple upper-case letters. Single letter word
+                // or acronym which we want to emit now
+                m_wordLen--;
+                if (!doemit(false, it.getBpos()))
+                    return false;
+                // m_wordstart could be 0 here if the span was reset
+                // for excessive length
+                if (m_wordStart)
+                    m_wordStart--;
+                m_wordLen++;
+            }
+            goto NORMALCHAR;
+#endif /* CAMELCASE */
+
+	default:
+	NORMALCHAR:
+	    nonalnumcnt = 0;
+            if (m_inNumber && c != 'e' && c != 'E') {
+                m_inNumber = false;
+            }
+	    m_wordLen += it.appendchartostring(m_span);
+	    STATS_INC_WORDCHARS;
+	    break;
+	}
+	softhyphenpending = false;
+    }
+    if (m_wordLen || m_span.length()) {
+	if (!doemit(true, it.getBpos()))
+	    return false;
+    }
+    return true;
+}
+
+// Using an utf8iter pointer just to avoid needing its definition in
+// textsplit.h
+//
+// We output ngrams for exemple for char input a b c and ngramlen== 2, 
+// we generate: a ab b bc c as words
+//
+// This is very different from the normal behaviour, so we don't use
+// the doemit() and emitterm() routines
+//
+// The routine is sort of a mess and goes to show that we'd probably
+// be better off converting the whole buffer to utf32 on entry...
+bool TextSplit::cjk_to_words(Utf8Iter *itp, unsigned int *cp)
+{
+    LOGDEB1("cjk_to_words: m_wordpos "  << (m_wordpos) << "\n" );
+    Utf8Iter &it = *itp;
+
+    // We use an offset buffer to remember the starts of the utf-8
+    // characters which we still need to use.
+    assert(o_CJKNgramLen < o_CJKMaxNgramLen);
+    unsigned int boffs[o_CJKMaxNgramLen+1];
+
+    // Current number of valid offsets;
+    unsigned int nchars = 0;
+    unsigned int c = 0;
+    for (; !it.eof(); it++) {
+	c = *it;
+	if (!UNICODE_IS_CJK(c)) {
+	    // Return to normal handler
+	    break;
+	}
+	if (whatcc(c) == SPACE) {
+	    // Flush the ngram buffer and go on
+	    nchars = 0;
+	    continue;
+	}
+	if (nchars == o_CJKNgramLen) {
+	    // Offset buffer full, shift it. Might be more efficient
+	    // to have a circular one, but things are complicated
+	    // enough already...
+	    for (unsigned int i = 0; i < nchars-1; i++) {
+		boffs[i] = boffs[i+1];
+	    }
+	}  else {
+	    nchars++;
+	}
+
+	// Take note of byte offset for this character.
+	boffs[nchars-1] = int(it.getBpos());
+
+	// Output all new ngrams: they begin at each existing position
+	// and end after the new character. onlyspans->only output
+	// maximum words, nospans=> single chars
+	if (!(m_flags & TXTS_ONLYSPANS) || nchars == o_CJKNgramLen) {
+	    int btend = int(it.getBpos() + it.getBlen());
+	    int loopbeg = (m_flags & TXTS_NOSPANS) ? nchars-1 : 0;
+	    int loopend = (m_flags & TXTS_ONLYSPANS) ? 1 : nchars;
+	    for (int i = loopbeg; i < loopend; i++) {
+		if (!takeword(it.buffer().substr(boffs[i], 
+						       btend-boffs[i]),
+				m_wordpos - (nchars-i-1), boffs[i], btend)) {
+		    return false;
+		}
+	    }
+
+	    if ((m_flags & TXTS_ONLYSPANS)) {
+		// Only spans: don't overlap: flush buffer
+		nchars = 0;
+	    }
+	}
+	// Increase word position by one, other words are at an
+	// existing position. This could be subject to discussion...
+	m_wordpos++;
+    }
+
+    // If onlyspans is set, there may be things to flush in the buffer
+    // first
+    if ((m_flags & TXTS_ONLYSPANS) && nchars > 0 && nchars != o_CJKNgramLen)  {
+	int btend = int(it.getBpos()); // Current char is out
+	if (!takeword(it.buffer().substr(boffs[0], btend-boffs[0]),
+			    m_wordpos - nchars,
+			    boffs[0], btend)) {
+	    return false;
+	}
+    }
+
+    m_span.erase();
+    m_inNumber = false;
+    m_wordStart = m_wordLen = m_wordChars = m_prevpos = m_prevlen = 0;
+    m_spanpos = m_wordpos;
+    *cp = c;
+    return true;
+}
+
+// Specialization for countWords 
+class TextSplitCW : public TextSplit {
+ public:
+    int wcnt;
+    TextSplitCW(Flags flags) : TextSplit(flags), wcnt(0) {}
+    bool takeword(const string &, int, int, int) {
+	wcnt++;
+	return true;
+    }
+};
+
+int TextSplit::countWords(const string& s, TextSplit::Flags flgs)
+{
+    TextSplitCW splitter(flgs);
+    splitter.text_to_words(s);
+    return splitter.wcnt;
+}
+
+bool TextSplit::hasVisibleWhite(const string &in)
+{
+    Utf8Iter it(in);
+    for (; !it.eof(); it++) {
+	unsigned int c = (unsigned char)*it;
+	if (c == (unsigned int)-1) {
+	    LOGERR("hasVisibleWhite: error while scanning UTF-8 string\n" );
+	    return false;
+	}
+	if (visiblewhite.find(c) != visiblewhite.end())
+	    return true;
+    }
+    return false;
+}
+
+template  bool u8stringToStrings(const string &s, T &tokens)
+{
+    Utf8Iter it(s);
+
+    string current;
+    tokens.clear();
+    enum states {SPACE, TOKEN, INQUOTE, ESCAPE};
+    states state = SPACE;
+    for (; !it.eof(); it++) {
+	unsigned int c = *it;
+	if (visiblewhite.find(c) != visiblewhite.end()) 
+	    c = ' ';
+	if (c == (unsigned int)-1) {
+	    LOGERR("TextSplit::stringToStrings: error while scanning UTF-8 string\n" );
+	    return false;
+	}
+
+	switch (c) {
+	    case '"': 
+	    switch(state) {
+	    case SPACE: state = INQUOTE; continue;
+	    case TOKEN: goto push_char;
+	    case ESCAPE: state = INQUOTE; goto push_char;
+	    case INQUOTE: tokens.push_back(current);current.clear();
+		state = SPACE; continue;
+	    }
+	    break;
+	    case '\\': 
+	    switch(state) {
+	    case SPACE: 
+	    case TOKEN: state=TOKEN; goto push_char;
+	    case INQUOTE: state = ESCAPE; continue;
+	    case ESCAPE: state = INQUOTE; goto push_char;
+	    }
+	    break;
+
+	    case ' ': 
+	    case '\t': 
+	    case '\n': 
+	    case '\r': 
+	    switch(state) {
+	      case SPACE: continue;
+	      case TOKEN: tokens.push_back(current); current.clear();
+		state = SPACE; continue; 
+	    case INQUOTE: 
+	    case ESCAPE: goto push_char;
+	    }
+	    break;
+
+	    default:
+	    switch(state) {
+	      case ESCAPE: state = INQUOTE; break;
+	      case SPACE:  state = TOKEN;  break;
+	      case TOKEN: 
+	      case INQUOTE: break;
+	    }
+	push_char:
+	    it.appendchartostring(current);
+	}
+    }
+
+    // End of string. Process residue, and possible error (unfinished quote)
+    switch(state) {
+    case SPACE: break;
+    case TOKEN: tokens.push_back(current); break;
+    case INQUOTE: 
+    case ESCAPE: return false;
+    }
+    return true;
+}
+
+bool TextSplit::stringToStrings(const string &s, vector &tokens)
+{
+    return u8stringToStrings >(s, tokens);
+}
+
+#else  // TEST driver ->
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include "textsplit.h"
+#include "readfile.h"
+#include "log.h"
+
+#include "transcode.h"
+#include "unacpp.h"
+#include "termproc.h"
+
+using namespace std;
+
+class myTermProc : public Rcl::TermProc {
+    int first;
+    bool nooutput;
+public:
+    myTermProc() : TermProc(0), first(1), nooutput(false) {}
+    void setNoOut(bool val) {nooutput = val;}
+    virtual bool takeword(const string &term, int pos, int bs, int be)
+    {
+	if (nooutput)
+	    return true;
+	FILE *fp = stdout;
+	if (first) {
+	    fprintf(fp, "%3s %-20s %4s %4s\n", "pos", "Term", "bs", "be");
+	    first = 0;
+	}
+	fprintf(fp, "%3d %-20s %4d %4d\n", pos, term.c_str(), bs, be);
+	return true;
+    }
+};
+
+#define OPT_s	  0x1 
+#define OPT_w	  0x2
+#define OPT_q	  0x4
+#define OPT_c     0x8
+#define OPT_k     0x10
+#define OPT_C     0x20
+#define OPT_n     0x40
+#define OPT_S     0x80
+#define OPT_u     0x100
+#define OPT_p     0x200
+
+bool dosplit(const string& data, TextSplit::Flags flags, int op_flags)
+{
+    myTermProc printproc;
+
+    Rcl::TermProc *nxt = &printproc;
+
+//    Rcl::TermProcCommongrams commonproc(nxt, stoplist);
+//    if (op_flags & OPT_S)
+//        nxt = &commonproc;
+
+    Rcl::TermProcPrep preproc(nxt);
+    if (op_flags & OPT_u) 
+        nxt = &preproc;
+
+    Rcl::TextSplitP splitter(nxt, flags);
+
+    if (op_flags & OPT_q)
+        printproc.setNoOut(true);
+
+    splitter.text_to_words(data);
+
+#ifdef TEXTSPLIT_STATS
+	TextSplit::Stats::Values v = splitter.getStats();
+	cout << "Average length: " 
+	     <<  v.avglen
+	     << " Standard deviation: " 
+	     << v.sigma
+	     << " Coef of variation "
+	     << v.sigma / v.avglen
+	     << endl;
+#endif
+    return true;
+}
+
+static const char *teststrings[] = {
+    "Un bout de texte \nnormal. 2eme phrase.3eme;quatrieme.\n",
+    "\"Jean-Francois Dockes\" \n",
+    "n@d @net .net net@ t@v@c c# c++ o'brien 'o'brien'",
+    "_network_ some_span",
+    "data123\n",
+    "134 +134 -14 0.1 .1 2. -1.5 +1.5 1,2 1.54e10 1,2e30 .1e10 1.e-8\n",
+    "@^#$(#$(*)\n",
+    "192.168.4.1 one\n\rtwo\r",
+    "[olala][ululu]  (valeur) (23)\n",
+    "utf-8 ucs-4© \\nodef\n",
+    "A b C 2 . +",
+    "','this\n",
+    " ,able,test-domain",
+    " -wl,--export-dynamic",
+    " ~/.xsession-errors",
+    "this_very_long_span_this_very_long_span_this_very_long_span",
+    "soft\xc2\xadhyphen",
+    "soft\xc2\xad\nhyphen",
+    "soft\xc2\xad\n\rhyphen",
+    "real\xe2\x80\x90hyphen",
+    "real\xe2\x80\x90\nhyphen",
+    "hyphen-\nminus",
+};
+const int teststrings_cnt = sizeof(teststrings)/sizeof(char *);
+
+static string teststring1 = " nouvel-an ";
+
+static string thisprog;
+
+static string usage =
+    " textsplit [opts] [filename]\n"
+    "   -q : no output\n"
+    "   -s :  only spans\n"
+    "   -w :  only words\n"
+    "   -n :  no numbers\n"
+    "   -k :  preserve wildcards (?*)\n"
+    "   -c : just count words\n"
+    "   -u : use unac\n"
+    "   -C [charset] : input charset\n"
+    "   -S [stopfile] : stopfile to use for commongrams\n"
+    " if filename is 'stdin', will read stdin for data (end with ^D)\n\n"
+    " textplit -p somephrase : display results from stringToStrings()\n"
+    "  \n"
+    ;
+
+static void
+Usage(void)
+{
+    cerr << thisprog  << ": usage:\n" << usage;
+    exit(1);
+}
+
+static int        op_flags;
+
+int main(int argc, char **argv)
+{
+    string charset, stopfile;
+
+    thisprog = argv[0];
+    argc--; argv++;
+
+    while (argc > 0 && **argv == '-') {
+	(*argv)++;
+	if (!(**argv))
+	    /* Cas du "adb - core" */
+	    Usage();
+	while (**argv)
+	    switch (*(*argv)++) {
+	    case 'c':	op_flags |= OPT_c; break;
+            case 'C':	op_flags |= OPT_C; if (argc < 2)  Usage();
+                charset = *(++argv); argc--; 
+                goto b1;
+	    case 'k':	op_flags |= OPT_k; break;
+	    case 'n':	op_flags |= OPT_n; break;
+	    case 'p':	op_flags |= OPT_p; break;
+	    case 'q':	op_flags |= OPT_q; break;
+	    case 's':	op_flags |= OPT_s; break;
+            case 'S':	op_flags |= OPT_S; if (argc < 2)  Usage();
+                stopfile = *(++argv); argc--; 
+                goto b1;
+	    case 'u':	op_flags |= OPT_u; break;
+	    case 'w':	op_flags |= OPT_w; break;
+	    default: Usage();	break;
+	    }
+    b1: argc--; argv++;
+    }
+
+    TextSplit::Flags flags = TextSplit::TXTS_NONE;
+
+    if (op_flags&OPT_s)
+	flags = TextSplit::TXTS_ONLYSPANS;
+    else if (op_flags&OPT_w)
+	flags = TextSplit::TXTS_NOSPANS;
+    if (op_flags & OPT_k) 
+	flags = (TextSplit::Flags)(flags | TextSplit::TXTS_KEEPWILD); 
+    if (op_flags & OPT_n)
+	TextSplit::noNumbers();
+
+    Rcl::StopList stoplist;
+    if (op_flags & OPT_S) {
+	if (!stoplist.setFile(stopfile)) {
+	    cerr << "Can't read stopfile: " << stopfile << endl;
+	    exit(1);
+	}
+    }
+    string odata, reason;
+    if (argc == 1) {
+	const char *filename = *argv++;	argc--;
+        if (op_flags& OPT_p) {
+            vector tokens;
+            TextSplit::stringToStrings(filename, tokens);
+            for (vector::const_iterator it = tokens.begin();
+                 it != tokens.end(); it++) {
+                cout << "[" << *it << "] ";
+            }
+            cout << endl;
+            exit(0);
+        }
+	if (!strcmp(filename, "stdin")) {
+	    char buf[1024];
+	    int nread;
+	    while ((nread = read(0, buf, 1024)) > 0) {
+		odata.append(buf, nread);
+	    }
+	} else if (!file_to_string(filename, odata, &reason)) {
+            cerr << "Failed: file_to_string(" << filename << ") failed: " 
+                 << reason << endl;
+	    exit(1);
+        }
+    } else {
+        if (op_flags & OPT_p)
+            Usage();
+        for (int i = 0; i < teststrings_cnt; i++) {
+            cout << endl << teststrings[i] << endl;  
+            dosplit(teststrings[i], flags, op_flags);
+        }
+        exit(0);
+    }
+
+    string& data = odata;
+    string ndata;
+    if ((op_flags & OPT_C)) {
+        if (!transcode(odata, ndata, charset, "UTF-8")) {
+            cerr << "Failed: transcode error" << endl;
+            exit(1);
+        } else {
+            data = ndata;
+        }
+    }
+
+    if (op_flags & OPT_c) {
+	int n = TextSplit::countWords(data, flags);
+	cout << n << " words" << endl;
+    } else {
+        dosplit(data, flags, op_flags);
+    }    
+}
+#endif // TEST
+
diff --git a/src/common/textsplit.h b/src/common/textsplit.h
new file mode 100644
index 00000000..d408bb2e
--- /dev/null
+++ b/src/common/textsplit.h
@@ -0,0 +1,225 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef _TEXTSPLIT_H_INCLUDED_
+#define _TEXTSPLIT_H_INCLUDED_
+
+#include 
+
+#include 
+#include 
+
+class Utf8Iter;
+
+/** 
+ * Split text into words. 
+ * See comments at top of .cpp for more explanations.
+ * This uses a callback function. It could be done with an iterator instead,
+ * but 'ts much simpler this way...
+ */
+class TextSplit {
+public:
+    // Should we activate special processing of Chinese characters ? This
+    // needs a little more cpu, so it can be turned off globally. This is set
+    // by rclconfig, changing it means reindexing
+    static bool o_processCJK;
+    static unsigned int  o_CJKNgramLen;
+    static const unsigned int o_CJKMaxNgramLen =  5;
+    static void cjkProcessing(bool onoff, unsigned int ngramlen = 2) 
+    {
+	o_processCJK = onoff;
+	o_CJKNgramLen = ngramlen <= o_CJKMaxNgramLen ? 
+	    ngramlen : o_CJKMaxNgramLen;
+    }
+
+    // Are we indexing numbers ? Set by rclconfig. Change needs reindex
+    static bool o_noNumbers;
+    static void noNumbers()
+    {
+	o_noNumbers = true;
+    }
+
+    // Given [co-worker] as input, do we also generate [coworker] ?
+    // Set by rclconfig
+    static bool o_deHyphenate;
+    static void deHyphenate(bool on) {
+	o_deHyphenate = on;
+    }
+
+    enum Flags {
+        // Default: will return spans and words (a_b, a, b)
+        TXTS_NONE = 0, 
+        // Only return maximum spans (a@b.com, not a, b, or com) 
+        TXTS_ONLYSPANS = 1,  
+        // Special: Only return atomic words (a, b, com).  This is not
+        // used for indexing, but for position computation during
+        // abstract generation,
+        TXTS_NOSPANS = 2,  
+        // Handle wildcards as letters. This is used with ONLYSPANS
+        // for parsing a user query (never alone).
+        TXTS_KEEPWILD = 4 
+    };
+    
+    TextSplit(Flags flags = Flags(TXTS_NONE))
+	: m_flags(flags), m_maxWordLength(40), m_prevpos(-1)
+    {
+    }
+    virtual ~TextSplit() {}
+
+    /** Split text, emit words and positions. */
+    virtual bool text_to_words(const std::string &in);
+
+    /** Process one output word: to be implemented by the actual user class */
+    virtual bool takeword(const std::string& term, 
+			  int pos,  // term pos
+			  int bts,  // byte offset of first char in term
+			  int bte   // byte offset of first char after term
+			  ) = 0; 
+
+    /** Called when we encounter formfeed \f 0x0c. Override to use the event.
+     * Mostly or exclusively used with pdftoxx output. Other filters mostly 
+     * just don't know about pages. */
+    virtual void newpage(int /*pos*/)
+    {
+    }
+
+    // Static utility functions:
+
+    /** Count words in string, as the splitter would generate them */
+    static int countWords(const std::string &in, Flags flgs = TXTS_ONLYSPANS);
+
+    /** Check if this is visibly not a single block of text */
+    static bool hasVisibleWhite(const std::string &in);
+
+    /** Split text span into strings, at white space, allowing for substrings
+     * quoted with " . Escaping with \ works as usual inside the quoted areas.
+     * This has to be kept separate from smallut.cpp's stringsToStrings, which
+     * basically works only if whitespace is ascii, and which processes 
+     * non-utf-8 input (iso-8859 config files work ok). This hopefully
+     * handles all Unicode whitespace, but needs correct utf-8 input
+     */
+    static bool stringToStrings(const std::string &s, std::vector &tokens);
+
+    /** Is char CJK ? */
+    static bool isCJK(int c);
+
+    /** Statistics about word length (average and dispersion) can
+     * detect bad data like undecoded base64 or other mis-identified
+     * pieces of data taken as text. In practise, this keeps some junk out 
+     * of the index, but does not decrease the index size much, and is
+     * probably not worth the trouble in general. Code kept because it
+     * probably can be useful in special cases. Base64 data does has
+     * word separators in it (+/) and is characterised by high average
+     * word length (>10, often close to 20) and high word length
+     * dispersion (avg/sigma > 0.8). In my tests, most natural
+     * language text has average word lengths around 5-8 and avg/sigma
+     * < 0.7
+     */
+#ifdef TEXTSPLIT_STATS
+    class Stats {
+    public:
+	Stats()
+	{
+	    reset();
+	}
+	void reset()
+	{
+	    count = 0;
+	    totlen = 0;
+	    sigma_acc = 0;
+	}
+	void newsamp(unsigned int len)
+	{
+	    ++count;
+	    totlen += len;
+	    double avglen = double(totlen) / double(count);
+	    sigma_acc += (avglen - len) * (avglen - len);
+	}
+	struct Values {
+	    int count;
+	    double avglen;
+	    double sigma;
+	};
+	Values get()
+	{
+	    Values v;
+	    v.count = count;
+	    v.avglen = double(totlen) / double(count);
+	    v.sigma = sqrt(sigma_acc / count);
+	    return v;
+	}
+    private:
+	int count;
+	int totlen;
+	double sigma_acc;
+    };
+
+    Stats::Values getStats()
+    {
+	return m_stats.get();
+    }
+    void resetStats()
+    {
+	m_stats.reset();
+    }
+#endif // TEXTSPLIT_STATS
+
+private:
+    Flags         m_flags;
+    int           m_maxWordLength;
+
+    // Current span. Might be jf.dockes@wanadoo.f
+    std::string        m_span; 
+
+    std::vector  > m_words_in_span;
+
+    // Current word: no punctuation at all in there. Byte offset
+    // relative to the current span and byte length
+    int           m_wordStart;
+    unsigned int  m_wordLen;
+
+    // Currently inside number
+    bool          m_inNumber;
+
+    // Term position of current word and span
+    int           m_wordpos; 
+    int           m_spanpos;
+
+    // It may happen that our cleanup would result in emitting the
+    // same term twice. We try to avoid this
+    int           m_prevpos;
+    int           m_prevlen;
+
+#ifdef TEXTSPLIT_STATS
+    // Stats counters. These are processed in TextSplit rather than by a 
+    // TermProc so that we can take very long words (not emitted) into
+    // account.
+    Stats         m_stats;
+#endif
+    // Word length in characters. Declared but not updated if !TEXTSPLIT_STATS
+    unsigned int  m_wordChars;
+
+    // This processes cjk text:
+    bool cjk_to_words(Utf8Iter *it, unsigned int *cp);
+
+    bool emitterm(bool isspan, std::string &term, int pos, size_t bs,size_t be);
+    bool doemit(bool spanerase, size_t bp);
+    void discardspan();
+    bool span_is_acronym(std::string *acronym);
+    bool words_from_span(size_t bp);
+};
+
+#endif /* _TEXTSPLIT_H_INCLUDED_ */
diff --git a/src/common/unacpp.cpp b/src/common/unacpp.cpp
new file mode 100644
index 00000000..a613619e
--- /dev/null
+++ b/src/common/unacpp.cpp
@@ -0,0 +1,250 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+
+#ifndef TEST_UNACPP
+#include 
+#include 
+#include 
+
+#include 
+
+#include "unacpp.h"
+#include "unac.h"
+#include "log.h"
+#include "utf8iter.h"
+
+bool unacmaybefold(const string &in, string &out, 
+		   const char *encoding, UnacOp what)
+{
+    char *cout = 0;
+    size_t out_len;
+    int status = -1;
+
+    switch (what) {
+    case UNACOP_UNAC:
+	status = unac_string(encoding, in.c_str(), in.length(), 
+			     &cout, &out_len);
+	break;
+    case UNACOP_UNACFOLD:
+	status = unacfold_string(encoding, in.c_str(), in.length(), 
+				 &cout, &out_len);
+	break;
+    case UNACOP_FOLD:
+	status = fold_string(encoding, in.c_str(), in.length(), 
+			     &cout, &out_len);
+	break;
+    }
+
+    if (status < 0) {
+	if (cout)
+	    free(cout);
+	char cerrno[20];
+	sprintf(cerrno, "%d", errno);
+	out = string("unac_string failed, errno : ") + cerrno;
+	return false;
+    }
+    out.assign(cout, out_len);
+    if (cout)
+	free(cout);
+    return true;
+}
+
+// Functions to determine upper-case or accented status could be implemented
+// hugely more efficiently inside the unac c code, but there only used for
+// testing user-entered terms, so we don't really care.
+bool unaciscapital(const string& in)
+{
+    LOGDEB2("unaciscapital: ["  << (in) << "]\n" );
+    if (in.empty())
+	return false;
+    Utf8Iter it(in);
+    string shorter;
+    it.appendchartostring(shorter);
+
+    string lower;
+    if (!unacmaybefold(shorter, lower, "UTF-8", UNACOP_FOLD)) {
+	LOGINFO("unaciscapital: unac/fold failed for ["  << (in) << "]\n" );
+	return false;
+    } 
+    Utf8Iter it1(lower);
+    if (*it != *it1)
+	return true;
+    else
+	return false;
+}
+bool unachasuppercase(const string& in)
+{
+    LOGDEB2("unachasuppercase: ["  << (in) << "]\n" );
+    if (in.empty())
+	return false;
+
+    string lower;
+    if (!unacmaybefold(in, lower, "UTF-8", UNACOP_FOLD)) {
+	LOGINFO("unachasuppercase: unac/fold failed for ["  << (in) << "]\n" );
+	return false;
+    } 
+    if (lower != in)
+	return true;
+    else
+	return false;
+}
+bool unachasaccents(const string& in)
+{
+    LOGDEB2("unachasaccents: ["  << (in) << "]\n" );
+    if (in.empty())
+	return false;
+
+    string noac;
+    if (!unacmaybefold(in, noac, "UTF-8", UNACOP_UNAC)) {
+	LOGINFO("unachasaccents: unac/unac failed for ["  << (in) << "]\n" );
+	return false;
+    } 
+    if (noac != in)
+	return true;
+    else
+	return false;
+}
+
+#else // not testing
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+using namespace std;
+
+#include "unacpp.h"
+#include "readfile.h"
+#include "rclinit.h"
+
+static char *thisprog;
+
+static char usage [] = "\n"
+    "[-c|-C]   \n"
+    "   Default : unaccent\n"
+    "   -c : unaccent and casefold\n"
+    "   -C : casefold only\n"
+    "-t  test string as capitalized, upper-case anywhere, accents\n"
+    "   the parameter is supposedly utf-8 so this can only work in an utf-8\n"
+    "   locale\n"
+    "\n";
+;
+
+static void
+Usage(void)
+{
+    fprintf(stderr, "%s: usage: %s\n", thisprog, usage);
+    exit(1);
+}
+
+static int     op_flags;
+#define OPT_c	  0x2 
+#define OPT_C	  0x4 
+#define OPT_t     0x8
+
+int main(int argc, char **argv)
+{
+    UnacOp op = UNACOP_UNAC;
+
+    thisprog = argv[0];
+    argc--; argv++;
+
+    while (argc > 0 && **argv == '-') {
+	(*argv)++;
+	if (!(**argv))
+	    /* Cas du "adb - core" */
+	    Usage();
+	while (**argv)
+	    switch (*(*argv)++) {
+	    case 'c':	op_flags |= OPT_c; break;
+	    case 'C':	op_flags |= OPT_C; break;
+	    case 't':	op_flags |= OPT_t; break;
+	    default: Usage();	break;
+	    }
+	argc--; argv++;
+    }
+
+    if (op_flags & OPT_t) {
+	if (argc != 1)
+	    Usage();
+	string in = *argv++;argc--;
+	bool capital, upper, accent;
+	capital = unaciscapital(in);
+	upper = unachasuppercase(in);
+	accent = unachasaccents(in);
+	cout << "[" << in << "] : " << 
+	    "capitalized: " << (capital ? "Yes. " : "No. ") <<
+	    "has uppercase: " << (upper ? "Yes. " : "No. ") <<
+	    "has accents: " << (accent ? "Yes. " : "No. ") << 
+	    endl;
+	return 0;
+    } else {
+	if (argc != 3)
+	    Usage();
+	if (op_flags & OPT_c) {
+	    op = UNACOP_UNACFOLD;
+	} else if (op_flags & OPT_C) {
+	    op = UNACOP_FOLD;
+	}
+
+	const char *encoding = *argv++; argc--;
+	string ifn = *argv++; argc--;
+	if (!ifn.compare("stdin"))
+	    ifn.clear();
+	const char *ofn = *argv++; argc--;
+
+	string reason;
+	(void)recollinit(RCLINIT_NONE, 0, 0, reason, 0);
+
+	string odata;
+	if (!file_to_string(ifn, odata)) {
+	    cerr << "file_to_string " << ifn << " : " << odata << endl;
+	    return 1;
+	}
+	string ndata;
+	if (!unacmaybefold(odata, ndata, encoding, op)) {
+	    cerr << "unac: " << ndata << endl;
+	    return 1;
+	}
+    
+	int fd;
+	if (strcmp(ofn, "stdout")) {
+	    fd = open(ofn, O_CREAT|O_EXCL|O_WRONLY, 0666);
+	} else {
+	    fd = 1;
+	}
+	if (fd < 0) {
+	    cerr << "Open/Create " << ofn << " failed: " << strerror(errno) 
+		 << endl;
+	    return 1;
+	}
+	if (write(fd, ndata.c_str(), ndata.length()) != (int)ndata.length()) {
+	    cerr << "Write(2) failed: " << strerror(errno)  << endl;
+	    return 1;
+	}
+	close(fd);
+	return 0;
+    }
+}
+
+#endif
+
diff --git a/src/common/unacpp.h b/src/common/unacpp.h
new file mode 100644
index 00000000..643b6ad3
--- /dev/null
+++ b/src/common/unacpp.h
@@ -0,0 +1,40 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef _UNACPP_H_INCLUDED_
+#define _UNACPP_H_INCLUDED_
+
+#include 
+
+#ifndef NO_NAMESPACES
+using std::string;
+#endif /* NO_NAMESPACES */
+
+// A small stringified wrapper for unac.c
+enum UnacOp {UNACOP_UNAC = 1, UNACOP_FOLD = 2, UNACOP_UNACFOLD = 3};
+extern bool unacmaybefold(const string& in, string& out, 
+			  const char *encoding, UnacOp what);
+
+// Utility function to determine if string begins with capital
+extern bool unaciscapital(const string& in);
+// Utility function to determine if string has upper-case anywhere
+extern bool unachasuppercase(const string& in);
+// Utility function to determine if any character is accented. This
+// approprialey ignores the characters from unac_except_chars which
+// are really separate letters
+extern bool unachasaccents(const string& in);
+
+#endif /* _UNACPP_H_INCLUDED_ */
diff --git a/src/common/uproplist.h b/src/common/uproplist.h
new file mode 100644
index 00000000..d8254ec7
--- /dev/null
+++ b/src/common/uproplist.h
@@ -0,0 +1,202 @@
+/* Copyright (C) 2004 J.F.Dockes
+ *   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.
+ */
+#ifndef _PROPLIST_H_INCLUDED_
+#define _PROPLIST_H_INCLUDED_
+
+
+/** 
+ * A subset of Unicode chars that we consider word breaks when we
+ * split text in words. 
+ *
+ * This is used as a quick fix to the ascii-based code, and is not correct.
+ * the correct way would be to do what http://www.unicode.org/reports/tr29/ 
+ * says. 
+*/
+
+// Punctuation chararacters blocks array.  Each block is defined by a
+// starting and ending code point (both included). MUST BE SORTED.
+static const unsigned unipuncblocks[] = {
+    // Start of latin-1 supplement block, up to capital A grave
+    0x0080, 0x00BF,
+    // General punctuation
+    0x2000, 0x206F,
+    // Superscripts and subscripts
+    0x2070, 0x209F,
+    // Currency symbols
+    0x20A0, 0x20CF,
+    // Letterlike symbols
+    0x2100, 0x214f,
+    // Number forms
+    0x2150, 0x218F,
+    // Arrows
+    0x2190, 0x21FF,
+    // Mathematical Operators
+    0x2200, 0x22FF,
+    // Miscellaneous Technical
+    0x2300, 0x23FF,
+    // Control Pictures
+    0x2400, 0x243F,
+    // Optical Character Recognition
+    0x2440, 0x245F,
+    // Enclosed Alphanumerics
+    0x2460, 0x24FF,
+    // Box Drawing
+    0x2500, 0x257F,
+    // Block Elements
+    0x2580, 0x259F,
+    // Geometric Shapes
+    0x25A0, 0x25FF,
+    // Miscellaneous Symbols
+    0x2600, 0x26FF,
+    // Dingbats
+    0x2700, 0x27BF,
+    // Miscellaneous Mathematical Symbols-A 	
+    0x27C0, 0x27EF,
+    // Supplemental Arrows-A
+    0x27F0, 0x27FF,
+    // Supplemental Arrows-B
+    0x2900, 0x297F,
+    // Miscellaneous Mathematical Symbols-B 	
+    0x2980,  0x29FF,
+    // Supplemental Mathematical Operators
+    0x2A00, 0x2AFF,
+    // Miscellaneous Symbols and Arrows
+    0x2B00, 0x2BFF,
+};
+
+// Other punctuation characters list. Not all punctuation is in a
+// separate block some is found in the middle of alphanumeric codes.
+static const unsigned int unipunc[] = {
+    0x00D7, /* MULTIPLICATION SIGN */
+    0x00F7, /* DIVISION SIGN */
+    0x037E, /* GREEK QUESTION MARK */
+    0x0387, /* GREEK ANO TELEIA */
+    0x055C, /* ARMENIAN EXCLAMATION MARK */
+    0x055E, /* ARMENIAN QUESTION MARK */
+    0x0589, /* ARMENIAN FULL STOP */
+    0x058A, /* ARMENIAN HYPHEN */
+    0x05C3, /* HEBREW PUNCTUATION SOF PASUQ */
+    0x060C, /* ARABIC COMMA */
+    0x061B, /* ARABIC SEMICOLON */
+    0x061F, /* ARABIC QUESTION MARK */
+    0x06D4, /* ARABIC FULL STOP */
+    0x0964, /* DEVANAGARI DANDA */
+    0x0965, /* DEVANAGARI DOUBLE DANDA */
+    0x166E, /* CANADIAN SYLLABICS FULL STOP */
+    0x1680, /* OGHAM SPACE MARK */
+    0x16EB, /* RUNIC SINGLE PUNCTUATION */
+    0x16EC, /* RUNIC MULTIPLE PUNCTUATION */
+    0x16ED, /* RUNIC CROSS PUNCTUATION */
+    0x1803, /* MONGOLIAN FULL STOP */
+    0x1806, /* MONGOLIAN TODO SOFT HYPHEN */
+    0x1809, /* MONGOLIAN MANCHU FULL STOP */
+    0x180E, /* MONGOLIAN VOWEL SEPARATOR */
+    0x2E2E, /* REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;; */
+    0x3000, /* IDEOGRAPHIC SPACE*/
+    0x3002, /* IDEOGRAPHIC FULL STOP*/
+    0x300C, /* LEFT CORNER BRACKET*/
+    0x300D, /* RIGHT CORNER BRACKET*/
+    0x300E, /* LEFT WHITE CORNER BRACKET*/
+    0x300F, /* RIGHT WHITE CORNER BRACKET*/
+    0x301C, /* WAVE DASH*/
+    0x301D, /* REVERSED DOUBLE PRIME QUOTATION MARK*/
+    0x301E, /* LOW DOUBLE PRIME QUOTATION MARK*/
+    0x3030, /* WAVY DASH*/
+    0x30FB, /* KATAKANA MIDDLE DOT*/
+    0xC2B6, /* PILCROW SIGN;So;0;ON;;;;;N;PARAGRAPH SIGN;;;; */
+    0xC3B7, /* DIVISION SIGN;Sm;0;ON;;;;;N;;;;; */
+    0xFE31, /* PRESENTATION FORM FOR VERTICAL EM DASH*/
+    0xFE32, /* PRESENTATION FORM FOR VERTICAL EN DASH*/
+    0xFE41, /* PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET*/
+    0xFE42, /* PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET*/
+    0xFE43, /* PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET*/
+    0xFE44, /* PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET*/
+    0xFE50, /* [3] SMALL COMMA..SMALL FULL STOP*/
+    0xFE51, /* [3] SMALL COMMA..SMALL FULL STOP*/
+    0xFE52, /* STOP*/
+    0xFE52, /* [3] SMALL COMMA..SMALL FULL STOP*/
+    0xFE54, /* [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK*/
+    0xFE55, /* [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK*/
+    0xFE56, /* [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK*/
+    0xFE57, /* [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK*/
+    0xFE58, /* SMALL EM DASH */
+    0xFE63, /* SMALL HYPHEN-MINUS */
+    0xFF01, /* FULLWIDTH EXCLAMATION MARK */
+    0xFF02, /* FULLWIDTH QUOTATION MARK */
+    0xFF03, /* FULLWIDTH NUMBER SIGN */
+    0xFF04, /* FULLWIDTH DOLLAR SIGN */
+    0xFF05, /* FULLWIDTH PERCENT SIGN */
+    0xFF06, /* FULLWIDTH AMPERSAND */
+    0xFF07, /* FULLWIDTH APOSTROPHE */
+    0xFF08, /* FULLWIDTH LEFT PARENTHESIS */
+    0xFF09, /* FULLWIDTH RIGHT PARENTHESIS */
+    0xFF0A, /* FULLWIDTH ASTERISK */
+    0xFF0B, /* FULLWIDTH PLUS SIGN */
+    0xFF0C, /* FULLWIDTH COMMA */
+    0xFF0D, /* FULLWIDTH HYPHEN-MINUS */
+    0xFF0E, /* FULLWIDTH FULL STOP */
+    0xFF0F, /* FULLWIDTH SOLIDUS  */
+    0xFF1A, /* [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON*/
+    0xFF1B, /* [2] FULLWIDTH COLON..FULLWIDTH SEMICOLON*/
+    0xFF1F, /* FULLWIDTH QUESTION MARK*/
+    0xFF61, /* HALFWIDTH IDEOGRAPHIC FULL STOP*/
+    0xFF62, /* HALFWIDTH LEFT CORNER BRACKET*/
+    0xFF63, /* HALFWIDTH RIGHT CORNER BRACKET*/
+    0xFF64, /* HALFWIDTH IDEOGRAPHIC COMMA*/
+    0xFF65, /* HALFWIDTH KATAKANA MIDDLE DOT*/
+};
+
+// Characters that should just be discarded. Some of these are in the
+// above blocks, but this array is tested first, so it's not worth
+// breaking the blocks
+static const unsigned int uniskip[] = {
+    0x00AD, /* SOFT HYPHEN */
+    0x034F, /* COMBINING GRAPHEME JOINER */
+    0x2027, /* HYPHENATION POINT */
+    0x200C, /* ZERO WIDTH NON-JOINER */
+    0x200D, /* ZERO WIDTH JOINER */
+    0x2060, /* WORD JOINER . Actually this should not be ignored but used to 
+	     * prevent a word break... */
+};
+
+/* Things that would visibly break a block of text, rendering obvious the need
+ * of quotation if a phrase search is wanted */
+static const unsigned int avsbwht[] = {
+    0x0009, /* CHARACTER TABULATION */
+    0x000A, /* LINE FEED */
+    0x000D, /* CARRIAGE RETURN */
+    0x0020, /* SPACE;Zs;0;WS */
+    0x00A0, /* NO-BREAK SPACE;Zs;0;CS */
+    0x1680, /* OGHAM SPACE MARK;Zs;0;WS */
+    0x180E, /* MONGOLIAN VOWEL SEPARATOR;Zs;0;WS */
+    0x2000, /* EN QUAD;Zs;0;WS */
+    0x2001, /* EM QUAD;Zs;0;WS */
+    0x2002, /* EN SPACE;Zs;0;WS */
+    0x2003, /* EM SPACE;Zs;0;WS */
+    0x2004, /* THREE-PER-EM SPACE;Zs;0;WS */
+    0x2005, /* FOUR-PER-EM SPACE;Zs;0;WS */
+    0x2006, /* SIX-PER-EM SPACE;Zs;0;WS */
+    0x2007, /* FIGURE SPACE;Zs;0;WS */
+    0x2008, /* PUNCTUATION SPACE;Zs;0;WS */
+    0x2009, /* THIN SPACE;Zs;0;WS */
+    0x200A, /* HAIR SPACE;Zs;0;WS */
+    0x202F, /* NARROW NO-BREAK SPACE;Zs;0;CS */
+    0x205F, /* MEDIUM MATHEMATICAL SPACE;Zs;0;WS */
+    0x3000, /* IDEOGRAPHIC SPACE;Zs;0;WS */
+};
+
+#endif // _PROPLIST_H_INCLUDED_
diff --git a/src/common/utf8fn.cpp b/src/common/utf8fn.cpp
new file mode 100644
index 00000000..e427f27c
--- /dev/null
+++ b/src/common/utf8fn.cpp
@@ -0,0 +1,24 @@
+#include "utf8fn.h"
+#include "rclconfig.h"
+#include "transcode.h"
+#include "log.h"
+
+using namespace std;
+
+string compute_utf8fn(const RclConfig *config, const string& ifn, bool simple)
+{
+    string charset = config->getDefCharset(true);
+    string utf8fn; 
+    int ercnt;
+    string lfn(simple ? path_getsimple(ifn) : ifn);
+    if (!transcode(lfn, utf8fn, charset, "UTF-8", &ercnt)) {
+	LOGERR("compute_utf8fn: fn transcode failure from ["  << charset <<
+               "] to UTF-8 for: [" << lfn << "]\n");
+    } else if (ercnt) {
+	LOGDEB("compute_utf8fn: "  << ercnt << " transcode errors from [" <<
+               charset << "] to UTF-8 for: ["  << lfn << "]\n");
+    }
+    LOGDEB1("compute_utf8fn: transcoded from ["  << lfn << "] to ["  <<
+            utf8fn << "] ("  << charset << "->"  << "UTF-8)\n");
+    return utf8fn;
+}
diff --git a/src/common/utf8fn.h b/src/common/utf8fn.h
new file mode 100644
index 00000000..c4f70814
--- /dev/null
+++ b/src/common/utf8fn.h
@@ -0,0 +1,16 @@
+#ifndef _UTF8FN_H_
+#define _UTF8FN_H_
+
+#include 
+
+class RclConfig;
+
+// Translate file name/path to utf8 for indexing.
+// 
+// @param simple If true we extract and process only the simple file name
+// (ignore the path)
+std::string compute_utf8fn(const RclConfig *config, const std::string& ifn,
+                           bool simple);
+
+#endif // _UTF8FN_H_
+
diff --git a/src/configure.ac b/src/configure.ac
new file mode 100644
index 00000000..0226b253
--- /dev/null
+++ b/src/configure.ac
@@ -0,0 +1,569 @@
+AC_INIT([Recoll], m4_esyscmd_s(cat VERSION))
+AC_CONFIG_HEADERS([common/autoconfig.h])
+AH_BOTTOM([#include "conf_post.h"])
+AC_PREREQ(2.53)
+AC_CONFIG_SRCDIR(index/recollindex.cpp)
+
+AM_INIT_AUTOMAKE([1.10 no-define subdir-objects foreign])
+AC_DISABLE_STATIC
+LT_INIT
+AC_CONFIG_MACRO_DIR([m4])
+
+AC_PROG_CXX
+if test C$CXX = C ; then
+   AC_MSG_ERROR([C++ compiler needed. Please install one (ie: gnu g++)])
+fi
+
+AC_PROG_YACC
+
+AC_PROG_LIBTOOL
+AC_C_BIGENDIAN
+
+AC_SYS_LARGEFILE
+
+# OpenBSD needs sys/param.h for mount.h to compile
+AC_CHECK_HEADERS([sys/param.h, spawn.h])
+
+AC_CHECK_FUNCS([posix_spawn, setrlimit])
+
+if test "x$ac_cv_func_posix_spawn" = xyes; then :
+   AC_ARG_ENABLE(posix_spawn,
+    AC_HELP_STRING([--enable-posix_spawn],
+   [Enable the use of posix_spawn().]),
+        posixSpawnEnabled=$enableval, posixSpawnEnabled=no)
+fi
+if test X$posixSpawnEnabled = Xyes ; then
+  AC_DEFINE(USE_POSIX_SPAWN, 1, [Use posix_spawn()])
+fi
+
+# Check for where to find unordered_map etc.
+AC_LANG_PUSH([C++])
+AC_CHECK_HEADER(tr1/unordered_map,[AC_DEFINE([HAVE_TR1_UNORDERED],
+    [],["Have tr1"])],[])
+AC_CHECK_HEADER(unordered_map,[AC_DEFINE([HAVE_CXX0X_UNORDERED],
+    [],["Have C++0x"])],[])
+AC_TRY_COMPILE([
+    #include 
+  ],[
+    std::shared_ptr ptr;
+  ], rcl_shared_ptr_std="1", rcl_shared_ptr_std="0")
+AC_TRY_COMPILE([
+    #include 
+  ],[
+    std::tr1::shared_ptr ptr;
+  ], rcl_shared_ptr_tr1="1", rcl_shared_ptr_tr1="0")
+if test X$rcl_shared_ptr_std = X1; then 
+   AC_DEFINE(HAVE_SHARED_PTR_STD, [], [Has std::shared_ptr])
+elif test X$rcl_shared_ptr_tr1 = X1; then 
+   AC_DEFINE(HAVE_SHARED_PTR_TR1, [], [Has std::tr1::shared_ptr])
+fi
+AC_LANG_POP([C++])
+
+AC_CHECK_HEADERS([sys/mount.h sys/statfs.h sys/statvfs.h sys/vfs.h], [], [],
+[#ifdef HAVE_SYS_PARAM_H
+# include 
+#endif
+])
+
+# Use specific 'file' command ? (Useful on solaris to specify
+# /usr/local/bin/file instead of the system's which doesn't understand '-i'
+AC_ARG_WITH(file-command, 
+    AC_HELP_STRING([--with-file-command],
+   [Specify version of 'file' command (ie: --with-file-command=/usr/local/bin/file)]),
+        withFileCommand=$withval, withFileCommand=file)
+case $withFileCommand in
+  file)
+    AC_PATH_PROG(fileProg, file);;
+  *) 
+    fileProg=$withFileCommand;;
+esac
+
+if test ! -x "$fileProg"; then
+   AC_MSG_ERROR([$fileProg does not exist or is not executable])
+fi
+AC_DEFINE_UNQUOTED(FILE_PROG, "$fileProg", [Path to the file program])
+
+# Can't use Solaris standard 'file' command, it doesn't support -i
+if test X$sys != XSunOS -o X$fileProg != X/usr/bin/file; then
+   AC_DEFINE(USE_SYSTEM_FILE_COMMAND, 1, [Enable using the system's 'file' command to id mime if we fail internally])
+fi
+
+
+# Use aspell to provide spelling expansions ?
+# The default is yes. If we do find an aspell installation, we use it. Else
+# we do compile the aspell module using an internal copy of aspell.h
+# Only --with-aspell=no will completely disable aspell support
+AC_ARG_WITH(aspell, 
+    AC_HELP_STRING([--without-aspell],
+   [Disable use of aspell spelling package to provide term expansion to other spellings]),
+        withAspell=$withval, withAspell=yes)
+case $withAspell in
+     no);;
+     yes)
+     AC_PATH_PROG(aspellProg, aspell)
+     ;;
+     *) # The argument should be the path to the aspell program
+     aspellProg=$withAspell
+     ;;
+esac
+
+if test X$withAspell != Xno ; then
+   AC_DEFINE(RCL_USE_ASPELL, 1, [Compile the aspell interface])
+   if test X$aspellProg != X ; then
+      aspellBase=`dirname $aspellProg`
+      aspellBase=`dirname $aspellBase`
+      AC_DEFINE_UNQUOTED(ASPELL_PROG, "$aspellProg",
+	[Path to the aspell program])
+      if test -f $aspellBase/include/aspell.h ; then	
+          AC_DEFINE_UNQUOTED(ASPELL_INCLUDE, "$aspellBase/include/aspell.h",
+	    [Path to the aspell api include file])
+      else
+	AC_MSG_NOTICE([aspell support enabled but aspell package not found. Compiling with internal aspell interface file])
+	 AC_DEFINE(ASPELL_INCLUDE, ["aspell-local.h"])
+      fi
+   else
+     # aspell support enabled but no aspell install yet
+	AC_MSG_NOTICE([aspell support enabled but aspell package not found. Compiling with internal aspell interface file])
+	AC_DEFINE(ASPELL_INCLUDE, ["aspell-local.h"])
+   fi
+fi
+
+if test -f /usr/include/sys/inotify.h -o -f /usr/include/linux/inotify.h; then
+   inot_default=yes
+else
+   inot_default=no
+fi
+
+# Real time monitoring with inotify
+AC_ARG_WITH(inotify, 
+    AC_HELP_STRING([--with-inotify],
+   [Use inotify for almost real time indexing of modified files (the default
+    is yes on Linux).]),
+        withInotify=$withval, withInotify=$inot_default)
+
+if test X$withInotify != Xno ; then
+   AC_MSG_NOTICE([enabled support for inotify monitoring])
+   AC_DEFINE(RCL_MONITOR, 1, [Real time monitoring option])
+   AC_DEFINE(RCL_USE_INOTIFY, 1, [Compile the inotify interface])
+else
+   AC_MSG_NOTICE([inotify not found, inotify monitoring disabled])
+fi
+
+# Real time monitoring with FAM
+AC_ARG_WITH(fam, 
+    AC_HELP_STRING([--with-fam],
+   [Use File Alteration Monitor for almost real time indexing of modified files. Give the fam/gamin library as argument (ie: /usr/lib/libfam.so) if configure does not find the right one.]),
+        withFam=$withval, withFam=yes)
+
+if test X$withFam != Xno -a X$withInotify != Xno ; then
+   AC_MSG_NOTICE([FAM support enabled but inotify support also enabled. Disabling FAM support and using inotify])
+   withFam=no
+fi
+
+famLib=""
+case $withFam in
+     no);;
+     yes)
+	for dir in /usr/local/lib ${libdir};do 
+	 if test -f $dir/libfam.so ; then famLib=$dir/libfam.so;break;fi
+	done
+        if test X$famLib = X ; then
+	  AC_MSG_NOTICE([FAM library not found, disabling FAM and real time indexing support])
+	  withFam=no
+        fi
+     ;;
+     *) # The argument should be the path to the fam library
+     famLib=$withFam
+     ;;
+esac
+
+if test X$withFam != Xno ; then
+   AC_DEFINE(RCL_MONITOR, 1, [Real time monitoring option])
+   AC_DEFINE(RCL_USE_FAM, 1, [Compile the fam interface])
+   if test X$famLib != X ; then
+      famLibDir=`dirname $famLib`
+      famBase=`dirname $famLibDir`
+      famBLib=`basename $famLib .so | sed -e s/lib//`
+      if test ! -f $famBase/include/fam.h ; then
+	 AC_MSG_ERROR([fam.h not found in $famBase/include. Specify --with-fam=no to disable fam support])
+      fi
+      LIBFAM="-L$famLibDir -l$famBLib"
+      AC_MSG_NOTICE([fam library directive: $LIBFAM])
+      AC_DEFINE_UNQUOTED(FAM_INCLUDE, "$famBase/include/fam.h",
+	[Path to the fam api include file])
+   else
+	AC_MSG_ERROR([fam library not found])
+   fi
+fi
+
+# Enable use of threads in the indexing pipeline.  
+# This is disabled by default as we usually care little about indexing 
+# absolute performance (more about impact on usability and total 
+# resources used).
+AC_ARG_ENABLE(idxthreads,
+    AC_HELP_STRING([--disable-idxthreads],
+   [Disable multithread indexing.]),
+        idxthreadsEnabled=$enableval, idxthreadsEnabled=yes)
+AM_CONDITIONAL(NOTHREADS, [test X$idxthreadsEnabled = Xno])
+if test X$idxthreadsEnabled = Xyes ; then
+  AC_DEFINE(IDX_THREADS, 1, [Use multiple threads for indexing])
+fi
+
+# Enable CamelCase word splitting. This is optional because it causes 
+# problems with phrases: with camelcase enabled, "MySQL manual"
+# will be matched by "MySQL manual" and "my sql manual" but not 
+# "mysql manual" (which would need increased slack as manual is now at pos
+# 2 instead of 1
+AC_ARG_ENABLE(camelcase,
+    AC_HELP_STRING([--enable-camelcase],
+   [Enable splitting camelCase words. This is not enabled by default as
+   this makes phrase matches more difficult: you need to use matching
+   case in the phrase query to get a match. Ie querying for 
+   "MySQL manual" and "my sql manual" are the same, but not the same as
+   "mysql manual" (in phrases only and you could raise the phrase slack to
+   get a match).]),
+        camelcaseEnabled=$enableval, camelcaseEnabled=no)
+if test X$camelcaseEnabled = Xyes ; then
+  AC_DEFINE(RCL_SPLIT_CAMELCASE, 1, [Split camelCase words])
+fi
+
+# Disable building the python module.
+if test X$sys != XDarwin ; then
+  AC_ARG_ENABLE(python-module,
+    AC_HELP_STRING([--disable-python-module],
+    [Do not build the Python module.]),
+        pythonEnabled=$enableval, pythonEnabled=yes)
+else
+  pythonEnabled=no
+fi
+
+AM_CONDITIONAL(MAKEPYTHON, [test X$pythonEnabled = Xyes])
+
+
+AC_CHECK_FUNCS(mkdtemp)
+AC_CHECK_LIB([pthread], [pthread_create], [], [])
+AC_CHECK_LIB([dl], [dlopen], [], [])
+AC_CHECK_LIB([z], [zlibVersion], [], [])
+
+##### Look for iconv. This can exist in either libc (ie: Linux, solaris) or
+##### libiconv. We'd need a --with-libiconv= option
+AC_LANG(C++)
+LIBICONV=""
+S_LIBS=$LIBS
+S_CPPFLAGS=$CPPFLAGS
+for dir in ${libdir} /opt/local/lib /usr/local/lib;do
+  CPPFLAGS="$S_CPPFLAGS -I$dir/../include"
+
+  LIBS="$S_LIBS -L$dir"
+  AC_TRY_LINK([#include 
+#include ],
+      [iconv_t cd = iconv_open("","");
+       iconv(cd,NULL,NULL,NULL,NULL);
+       iconv_close(cd);],
+      LIBICONV="-L$dir";INCICONV=-I$dir/../include)
+  if test A"$LIBICONV" != A ; then
+     break
+  fi
+
+  LIBS="$S_LIBS -L$dir -liconv"
+  AC_TRY_LINK([#include 
+#include ],
+      [iconv_t cd = iconv_open("","");
+       iconv(cd,NULL,NULL,NULL,NULL);
+       iconv_close(cd);],
+      LIBICONV="-L$dir -liconv";INCICONV=-I$dir/../include)
+  if test A"$LIBICONV" != A ; then
+     break
+  fi
+
+done
+
+LIBS=$S_LIBS
+CPPFLAGS=$S_CPPFLAGS
+
+if test A"$LIBICONV" = A ; then
+   AC_MSG_ERROR([Cannot find iconv_open anywhere. Please install iconv])
+   exit 1
+fi
+#echo LIBICONV $LIBICONV
+#echo INCICONV $INCICONV
+
+CPPFLAGS="$CPPFLAGS $INCICONV"
+AC_MSG_CHECKING(for type of inbuf parameter to iconv)
+AC_TRY_COMPILE([
+    #include 
+    #include 
+  ],[
+    iconv(0,(const char **)0,(size_t *)0,(char **)0,(size_t *)0);
+  ], rcl_iconv_inbuf_const="1", rcl_iconv_inbuf_const="0")
+if test X$rcl_iconv_inbuf_const = X1 ; then
+  AC_DEFINE(RCL_ICONV_INBUF_CONST, 1, [iconv parameter 2 is const char**])
+fi
+
+
+############# Putenv
+AC_MSG_CHECKING(for type of string parameter to putenv)
+AC_TRY_COMPILE([
+    #include 
+  ],[
+    putenv((const char *)0);
+  ], rcl_putenv_string_const="1", rcl_putenv_string_const="0")
+if test X$rcl_putenv_string_const = X1 ; then
+  AC_DEFINE(PUTENV_ARG_CONST, 1, [putenv parameter is const])
+fi
+
+
+#### Look for Xapian. Done in a strange way to work around autoconf
+# cache
+XAPIAN_CONFIG=${XAPIAN_CONFIG:-no}
+if test "$XAPIAN_CONFIG" = "no"; then 
+    AC_PATH_PROG(XAPIAN_CONFIG0, [xapian-config], no)
+    XAPIAN_CONFIG=$XAPIAN_CONFIG0
+fi
+if test "$XAPIAN_CONFIG" = "no"; then 
+   AC_PATH_PROG(XAPIAN_CONFIG1, [xapian-config-1.3], no)
+   XAPIAN_CONFIG=$XAPIAN_CONFIG1
+fi
+if test "$XAPIAN_CONFIG" = "no"; then 
+   AC_PATH_PROG(XAPIAN_CONFIG2, [xapian-config-1.1], no)
+   XAPIAN_CONFIG=$XAPIAN_CONFIG2
+fi
+
+if test "$XAPIAN_CONFIG" = "no" ; then
+   AC_MSG_ERROR([Cannot find xapian-config command in $PATH. Is
+xapian-core installed ?])
+   exit 1
+fi
+LIBXAPIAN=`$XAPIAN_CONFIG --libs`
+# The --static thing fails with older Xapians. Happily enough they don't
+# need it either (because there are no needed libraries (no uuid and we
+# deal explicitely with libz)
+LIBXAPIANSTATICEXTRA=`$XAPIAN_CONFIG --static --libs 2> /dev/null`
+# Workaround for problem in xapian-config in some versions: wrongly lists
+# libstdc++.la in the lib list
+for i in $LIBXAPIAN ; do
+    case $i in
+    *stdc++*|-lm|-lgcc_s|-lc);;
+    *) tmpxaplib="$tmpxaplib $i";;
+    esac
+done
+LIBXAPIAN=$tmpxaplib
+LIBXAPIANDIR=`$XAPIAN_CONFIG --libs | awk '{print $1}'`
+case A"$LIBXAPIANDIR" in
+  A-L*) LIBXAPIANDIR=`echo $LIBXAPIANDIR | sed -e 's/-L//'`;;
+  *) LIBXAPIANDIR="";;
+esac
+XAPIANCXXFLAGS=`$XAPIAN_CONFIG --cxxflags`
+
+#echo XAPIAN_CONFIG: $XAPIAN_CONFIG 
+#echo LIBXAPIAN: $LIBXAPIAN
+#echo LIBXAPIANDIR: $LIBXAPIANDIR
+#echo LIBXAPIANSTATICEXTRA: $LIBXAPIANSTATICEXTRA
+#echo XAPIANCXXFLAGS: $XAPIANCXXFLAGS
+
+AC_ARG_ENABLE(xadump, 
+    AC_HELP_STRING([--enable-xadump],
+   [Enable building the xadump low level Xapian access program.]),
+        enableXADUMP=$enableval, enableXADUMP="no")
+AM_CONDITIONAL(MAKEXADUMP, [test X$enableXADUMP = Xyes])
+
+AC_ARG_ENABLE(userdoc,
+    AC_HELP_STRING([--disable-userdoc],
+       [Disable building the user manual. (Avoids the need for docbook xml/xsl files and TeX tools.]),
+        enableUserdoc=$enableval, enableUserdoc="yes")
+AM_CONDITIONAL(MAKEUSERDOC, [test X$enableUserdoc = Xyes])
+
+
+
+#### QT
+# The way qt and its tools (qmake especially) are installed is very
+# different between systems (and maybe qt versions)
+#
+# In general we need QTDIR to be set, because it is used inside the
+# qmake-generated makefiles. But there are exceptions: ie on debian3.1 (at
+# least on the sourceforge compile farm), QTDIR is not needed because qmake
+# generates hard paths (and is installed in /usr/bin). We don't want to
+# force the user to set QTDIR if it is not needed.
+#
+# The logic is then to first look for qmake, possibly using QTDIR if it is
+# set.
+# 
+# If QTDIR is not set, we then generate a bogus qt project and check if
+# QTDIR is needed in the Makefile, in which case we complain.
+#
+# QMAKESPEC: on most Linux system, there is a 'default' link inside the
+# mkspecs directory, so that QMAKESPEC is not needed.
+# If QMAKESPEC is not set and needed, the qmake test at the previous test
+# will have failed, and we tell the user to check his environment.
+#
+AC_ARG_ENABLE(qtgui, 
+    AC_HELP_STRING([--disable-qtgui],
+   [Disable the QT-based graphical user interface.]),
+        enableQT=$enableval, enableQT="yes")
+AM_CONDITIONAL(MAKEQT, [test X$enableQT = Xyes])
+
+AC_ARG_ENABLE(recollq, 
+    AC_HELP_STRING([--enable-recollq],
+   [Enable building the recollq command line query tool (recoll -t without
+   need for Qt). This is done by default if --disable-qtgui is set but this
+   option enables forcing it.]),
+        enableRECOLLQ=$enableval, enableRECOLLQ="no")
+if test X"$enableRECOLLQ" != X ; then
+    AM_CONDITIONAL(MAKECMDLINE, [test X$enableRECOLLQ = Xyes])
+else
+    AM_CONDITIONAL(MAKECMDLINE, [test X$enableQT = Xno])
+fi
+
+
+if test X$enableQT = Xyes ; then
+
+  if test X$QTDIR != X ; then
+     PATH=$PATH:$QTDIR/bin
+     export PATH
+  fi
+  
+  if test X$QMAKE = X ; then
+     QMAKE=qmake
+  fi
+  case $QMAKE in
+    */*) QMAKEPATH=$QMAKE;;
+    *) AC_PATH_PROG([QMAKEPATH], $QMAKE, NOTFOUND);;
+  esac
+
+  if test X$QMAKEPATH = XNOTFOUND ; then 
+     AC_MSG_ERROR([Cannot find the qmake program. Maybe you need to install
+  qt development files and tools and/or set the QTDIR environment variable?])
+  fi
+  QMAKE=$QMAKEPATH
+  
+  # MAC OS X: we don't support this (the native search tool is more than
+  # good enough), but we make things work just enough so that the program can
+  # be compiled and roughly installed (not as a .app, but to /usr/local),
+  # basically to enable using a Macbook for development
+  if test X$sys = XDarwin ; then
+     # The default is xcode
+     QMAKE="${QMAKE} -spec macx-g++"
+  fi
+  
+  # Check Qt version
+  qmakevers="`${QMAKE} --version 2>&1`"
+  #echo "qmake version: $qmakevers"
+  v4=`expr "$qmakevers" : '.*Qt[ ][ ]*version[ ][ ]*4.*'`
+  v5=`expr "$qmakevers" : '.*Qt[ ][ ]*version[ ][ ]*5.*'`
+  if test X$v4 = X0 -a X$v5 = X0; then 
+     AC_MSG_ERROR([qmake seems to be using Qt version 3 which is not supported any more])
+  else
+    if test X$v4 != X0 ; then
+       AC_MSG_NOTICE([using qt version 4 user interface])
+    else
+       AC_MSG_NOTICE([using qt version 5 user interface])
+    fi
+    QTGUI=qtgui
+  fi
+
+
+ ##### Using Qt webkit for reslist display? Else Qt textbrowser
+  AC_ARG_ENABLE(webkit,
+    AC_HELP_STRING([--disable-webkit],
+      [Disable use of qt-webkit (only meaningful if qtgui is enabled).]),
+        enableWebkit=$enableval, enableWebkit="yes")
+
+  if test "$enableWebkit" = "yes" ; then
+   QMAKE_ENABLE_WEBKIT=""
+   QMAKE_DISABLE_WEBKIT="#"
+  else
+   QMAKE_ENABLE_WEBKIT="#"
+   QMAKE_DISABLE_WEBKIT=""
+  fi
+
+ ##### Using QZeitGeist lib ? Default no for now
+  AC_ARG_WITH(qzeitgeist,
+    AC_HELP_STRING([--with-qzeitgeist],
+      [Enable the use of the qzeitgeist library to send zeitgeist events.]),
+        withQZeitgeist=$withval, withQZeitgeist="no")
+
+  case "$withQZeitgeist" in 
+    no)  LIBQZEITGEIST=;;
+    yes) LIBQZEITGEIST=-lqzeitgeist;;
+    *)   LIBQZEITGEIST=$withQZeitgeist;;
+  esac	
+
+  if test "$withQZeitgeist" != "no" ; then
+   QMAKE_ENABLE_ZEITGEIST=""
+   QMAKE_DISABLE_ZEITGEIST="#"
+  else
+   QMAKE_ENABLE_ZEITGEIST="#"
+   QMAKE_DISABLE_ZEITGEIST=""
+  fi
+
+  AC_CONFIG_FILES($QTGUI/recoll.pro)
+
+  ##################### End QT stuff
+fi
+
+
+### X11: this is needed for the session monitoring code (in recollindex -m)
+AC_ARG_ENABLE(x11mon, 
+    AC_HELP_STRING([--disable-x11mon],
+   [Disable recollindex support for X11 session monitoring.]),
+        enableX11mon=$enableval, enableX11mon="yes")
+
+if test X$withInotify = Xno -a X$withFam = Xno ; then
+  enableX11mon=no
+fi
+
+if test "$enableX11mon" = "yes" ; then
+  AC_PATH_XTRA
+  X_LIBX11=-lX11
+else
+  AC_DEFINE(DISABLE_X11MON, 1, [No X11 session monitoring support])
+  X_LIBX11=""
+fi
+#echo X_CFLAGS "'$X_CFLAGS'" X_PRE_LIBS "'$X_PRE_LIBS'" X_LIBS \
+#      "'$X_LIBS'" X_LIBX11 "'$X_LIBX11'" X_EXTRA_LIBS "'$X_EXTRA_LIBS'"
+
+# For communicating the value of RECOLL_DATADIR to non-make-based
+# subpackages like python-recoll, we have to expand prefix in here, because
+# things like "datadir = ${prefix}/share" (which is what we'd get by
+# expanding @datadir@) don't mean a thing in Python... I guess we could
+# have a piece of shell-script text to be substituted into and executed by
+# setup.py for getting the value of pkgdatadir, but really...
+m_prefix=$prefix
+test "X$m_prefix" = "XNONE" && m_prefix=/usr/local
+m_datadir=${m_prefix}/share
+RECOLL_DATADIR=${m_datadir}/recoll
+
+RCLVERSION=$PACKAGE_VERSION
+RCLLIBVERSION=$RCLVERSION
+
+AC_SUBST(RECOLL_DATADIR)
+AC_SUBST(X_CFLAGS)
+AC_SUBST(X_PRE_LIBS)
+AC_SUBST(X_LIBS)
+AC_SUBST(X_LIBX11)
+AC_SUBST(X_EXTRA_LIBS)
+AC_SUBST(INCICONV)
+AC_SUBST(LIBICONV)
+AC_SUBST(LIBXAPIAN)
+AC_SUBST(LIBXAPIANDIR)
+AC_SUBST(LIBXAPIANSTATICEXTRA)
+AC_SUBST(LIBFAM)
+AC_SUBST(QMAKE)
+AC_SUBST(QTGUI)
+AC_SUBST(XAPIANCXXFLAGS)
+AC_SUBST(QMAKE_ENABLE_WEBKIT)
+AC_SUBST(QMAKE_DISABLE_WEBKIT)
+AC_SUBST(QMAKE_ENABLE_ZEITGEIST)
+AC_SUBST(QMAKE_DISABLE_ZEITGEIST)
+AC_SUBST(LIBQZEITGEIST)
+AC_SUBST(RCLVERSION)
+AC_SUBST(RCLLIBVERSION)
+
+# All object files depend on localdefs which has the cc flags. Avoid
+# changing it unless necessary
+AC_CONFIG_FILES(Makefile)
+AC_CONFIG_FILES(common/rclversion.h)
+AC_CONFIG_FILES(python/recoll/setup.py)
+AC_CONFIG_FILES(python/recoll/Makefile)
+
+AC_OUTPUT
diff --git a/src/desktop/hotrecoll.py b/src/desktop/hotrecoll.py
new file mode 100755
index 00000000..28cb7c35
--- /dev/null
+++ b/src/desktop/hotrecoll.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+#
+# This script should be linked to a keyboard shortcut. Under gnome,
+# you can do this from the main preferences menu, or directly execute
+# "gnome-keybinding-properties"
+#
+# Make the script executable. Install it somewhere in the executable
+# path ("echo $PATH" to check what's in there), and then just enter
+# its name as the action to perform, or copy it anywhere and copy the
+# full path as the action.
+
+import gtk
+import wnck
+import os
+import sys
+from optparse import OptionParser
+
+def main():
+    parser = OptionParser()
+    parser.add_option("-m", "--move-away", action="store_true", default=False,
+                      dest="clear_workspace", 
+                      help="iconify to other workspace to avoid crowding panel")
+    (options, args) = parser.parse_args()
+
+    screen = wnck.screen_get_default()
+    while gtk.events_pending():
+        gtk.main_iteration()
+
+    recollMain = ""
+    recollwins = [];
+    for window in screen.get_windows():
+        if window.get_class_group().get_name() == "Recoll":
+            if window.get_name() == "Recoll":
+                recollMain = window
+            recollwins.append(window)
+
+    if not recollMain:
+        os.system("recoll&")
+        sys.exit(0)
+
+    # Check the main window state, and either activate or minimize all
+    # recoll windows.
+    workspace = screen.get_active_workspace()
+    if not recollMain.is_visible_on_workspace(workspace):
+        for win in recollwins:
+            win.move_to_workspace(workspace)
+            if win != recollMain:
+                win.unminimize(gtk.get_current_event_time())
+        recollMain.activate(gtk.get_current_event_time())
+    else:
+        otherworkspace = None
+        if options.clear_workspace:
+            # We try to minimize to another workspace
+            wkspcs = screen.get_workspaces()
+            for wkspc in wkspcs:
+                if wkspc.get_number() != workspace.get_number():
+                    otherworkspace = wkspc
+                    break
+        for win in recollwins:
+            if otherworkspace:
+                win.move_to_workspace(otherworkspace)
+            win.minimize()
+
+if __name__ == '__main__':
+  main()
+  
diff --git a/src/desktop/recoll-searchgui.desktop b/src/desktop/recoll-searchgui.desktop
new file mode 100644
index 00000000..28b90ece
--- /dev/null
+++ b/src/desktop/recoll-searchgui.desktop
@@ -0,0 +1,10 @@
+[Desktop Entry]
+Categories=Utility;Filesystem;Database;
+Comment=Find documents by specifying search terms
+Exec=recoll
+GenericName=Local Text Search
+Icon=recoll
+Name=Recoll
+Terminal=false
+Type=Application
+Keywords=Search;Full Text;
diff --git a/src/desktop/recoll.appdata.xml b/src/desktop/recoll.appdata.xml
new file mode 100644
index 00000000..3a9a1ff0
--- /dev/null
+++ b/src/desktop/recoll.appdata.xml
@@ -0,0 +1,24 @@
+
+
+
+ recoll.desktop
+ CC0-1.0
+ GPL-2.0+
+ Recoll
+ Find documents by specifying search terms
+ 
+ 

Recoll finds keywords inside documents text as well as file names.

+
    +
  • It can search most document formats.
  • +
  • It can reach any storage place: files, archive members, email + attachments, transparently handling decompression.
  • +
  • One click will open the document inside a native editor or + display an even quicker text preview.
  • +
+
+ + http://www.recoll.org/files/recoll-mainwin-h-1248x702.png + + http://www.recoll.org/ + contact@recoll.org +
diff --git a/src/desktop/recoll.ico b/src/desktop/recoll.ico new file mode 100644 index 00000000..9e53065a Binary files /dev/null and b/src/desktop/recoll.ico differ diff --git a/src/desktop/recoll.png b/src/desktop/recoll.png new file mode 100644 index 00000000..42e78483 Binary files /dev/null and b/src/desktop/recoll.png differ diff --git a/src/desktop/recoll.svg b/src/desktop/recoll.svg new file mode 100644 index 00000000..b27b9fdc --- /dev/null +++ b/src/desktop/recoll.svg @@ -0,0 +1,275 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/desktop/recoll.xcf b/src/desktop/recoll.xcf new file mode 100644 index 00000000..3c93d9e7 Binary files /dev/null and b/src/desktop/recoll.xcf differ diff --git a/src/desktop/recoll_index_on_ac.sh b/src/desktop/recoll_index_on_ac.sh new file mode 100755 index 00000000..751fefce --- /dev/null +++ b/src/desktop/recoll_index_on_ac.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# This is a shell script that starts and stops the recollindex daemon +# depending on whether or not the power supply is plugged in. It should be +# called from the file ~/.config/autostart/recollindex.desktop. +# +# That is: make the script executable (chmod +x) and replace in +# recollindex.desk the line: +# Exec=recollindex -w 60 -m +# With +# Exec=/path/to/recoll_index_on_ac.sh +# +# +# By: The Doctor (drwho at virtadpt dot net) +# License: GPLv3 +# +# Modifications by J.F Dockes +# - replaced "acpi" usage with "on_ac_power" which seems to be both +# more common and more universal. +# - Changed the default to be that we run recollindex if we can't determine +# power status (ie: on_ac_power not installed or not working: we're most +# probably not running on a laptop). + +INDEXER="recollindex -w 60 -m" +ACPI=`which on_ac_power` + +# If the on_ac_power script isn't installed, warn, but run anyway. Maybe +# this is not a laptop or not linux. +if test "x$ACPI" = "x" ; then + echo "on_ac_power utility not found. Starting recollindex anyway." +fi + +while true; do + # Determine whether or not the power supply is plugged in. + if test "x$ACPI" != "x" ; then + on_ac_power + STATUS=$? + else + STATUS=0 + fi + + # Get the PID of the indexing daemon. + if test -f ~/.recoll/index.pid ; then + PID=`cat ~/.recoll/index.pid` + # Make sure that this is recollindex running. pid could have + # been reallocated + ps ax | egrep "^[ \t]*$PID " | grep -q recollindex || PID="" + fi +# echo "Recollindex pid is $PID" + + if test $STATUS -eq 1 ; then + # The power supply is not plugged in. See if the indexing daemon is + # running, and if it is, kill it. The indexing daemon will not be + # started. + if test x"$PID" != x; then + kill $PID + fi + else + # The power supply is plugged in or we just don't know. + # See if the indexing daemon is running, and if it's not start it. + if test -z "$PID" ; then + $INDEXER + fi + fi + + # Go to sleep for a while. + sleep 120 + continue +done diff --git a/src/desktop/recollindex.desktop b/src/desktop/recollindex.desktop new file mode 100644 index 00000000..ef75ea26 --- /dev/null +++ b/src/desktop/recollindex.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Name=Recoll real time indexer +Comment=Runs in background to extract and index text from modified documents +Icon=system-run +Exec=recollindex -w 60 -m +Terminal=false +TerminalOptions= +Type=Application +Categories=Utility;Filesystem;Database; +NoDisplay=true +X-GNOME-Autostart-enabled=true +X-KDE-autostart-after=panel +X-KDE-UniqueApplet=true diff --git a/src/desktop/xdg-utils-1.0.1/LICENSE b/src/desktop/xdg-utils-1.0.1/LICENSE new file mode 100644 index 00000000..1edf08c3 --- /dev/null +++ b/src/desktop/xdg-utils-1.0.1/LICENSE @@ -0,0 +1,18 @@ +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/desktop/xdg-utils-1.0.1/scripts/xdg-desktop-menu b/src/desktop/xdg-utils-1.0.1/scripts/xdg-desktop-menu new file mode 100755 index 00000000..a252ba01 --- /dev/null +++ b/src/desktop/xdg-utils-1.0.1/scripts/xdg-desktop-menu @@ -0,0 +1,1261 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-desktop-menu +# +# Utility script to install menu items on a Linux desktop. +# Refer to the usage() function below for usage. +# +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + +xdg-desktop-menu - command line tool for (un)installing desktop menu items + +Synopsis + +xdg-desktop-menu install [--noupdate] [--novendor] [--mode mode] directory-file +(s) desktop-file(s) + +xdg-desktop-menu uninstall [--noupdate] [--mode mode] directory-file(s) +desktop-file(s) + +xdg-desktop-menu forceupdate [--mode mode] + +xdg-desktop-menu { --help | --manual | --version } + +Description + +The xdg-desktop-menu program can be used to install new menu entries to the +desktop's application menu. + +The application menu works according to the XDG Desktop Menu Specification at +http://www.freedesktop.org/Standards/menu-spec + +Commands + +install + + Install one or more applications in a submenu of the desktop menu system. + + desktop-file: A desktop file represents a single menu entry in the menu. + Desktop files are defined by the freedesktop.org Desktop Entry + Specification. The most important aspects of *.desktop files are summarized + below. + + Menu entries can be added to the menu system in two different ways. They + can either be added to a predefined submenu in the menu system based on one + or more category keywords, or they can be added to a new submenu. + + To add a menu entry to a predefined submenu the desktop file that + represents the menu entry must have a Categories= entry that lists one or + more keywords. The menu item will be included in an appropriate submenu + based on the included keywords. + + To add menu items to a new submenu the desktop-files must be preceded by a + directory-file that describes the submenu. If multiple desktop-files are + specified, all entries will be added to the same menu. If entries are + installed to a menu that has been created with a previous call to + xdg-desktop-menu the entries will be installed in addition to any already + existing entries. + + directory-file: The *.directory file indicated by directory-file represents + a submenu. The directory file provides the name and icon for a submenu. The + name of the directory file is used to identify the submenu. + + If multiple directory files are provided each file will represent a submenu + within the menu that preceeds it, creating a nested menu hierarchy + (sub-sub-menus). The menu entries themselves will be added to the last + submenu. + + Directory files follow the syntax defined by the freedesktop.org Desktop + Entry Specification. + +uninstall + + Remove applications or submenus from the desktop menu system previously + installed with xdg-desktop-menu install. + + A submenu and the associated directory file is only removed when the + submenu no longer contains any menu entries. + +forceupdate + + Force an update of the menu system. + + This command is only useful if the last call to xdg-desktop-menu included + the --noupdate option. + +Options + +--noupdate + Postpone updating the menu system. If multiple updates to the menu system + are made in sequence this flag can be used to indicate that additional + changes will follow and that it is not necassery to update the menu system + right away. +--novendor + + Normally, xdg-desktop-menu checks to ensure that any *.directory and + *.desktop files to be installed has a vendor prefix. This option can be + used to disable that check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated + with a dash ("-"). Companies and organizations are encouraged to use a word + or phrase, preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the vendor prefix is to + prevent name conflicts. + +--mode mode + + mode can be user or system. In user mode the file is (un)installed for the + current user only. In system mode the file is (un)installed for all users + on the system. Usually only root is allowed to install in system mode. + + The default is to use system mode when called by root and to use user mode + when called by a non-root user. + +--help + Show command synopsis. +--manual + Show this manualpage. +--version + Show the xdg-utils version information. + +Desktop Files + +An application item in the application menu is represented by a *.desktop file. +A *.desktop file consists of a [Desktop Entry] header followed by several Key= +Value lines. + +A *.desktop file can provide a name and description for an application in +several different languages. This is done by adding a language code as used by +LC_MESSAGES in square brackets behind the Key. This way one can specify +different values for the same Key depending on the currently selected language. + +The following keys are often used: + +Value=1.0 + This is a mandatory field to indicate that the *.desktop file follows the + 1.0 version of the specification. +Type=Application + This is a mandatory field that indicates that the *.desktop file describes + an application launcher. +Name=Application Name + The name of the application. For example Mozilla +GenericName=Generic Name + A generic description of the application. For example Web Browser +Comment=Comment + Optional field to specify a tooltip for the application. For example Visit + websites on the Internet +Icon=Icon File + The icon to use for the application. This can either be an absolute path to + an image file or an icon-name. If an icon-name is provided an image lookup + by name is done in the user's current icon theme. The xdg-icon-resource + command can be used to install image files into icon themes. The advantage + of using an icon-name instead of an absolute path is that with an icon-name + the application icon can be provided in several different sizes as well as + in several differently themed styles. +Exec=Command Line + The command line to start the application. If the application can open + files the %f placeholder should be specified. When a file is dropped on the + application launcher the %f is replaced with the file path of the dropped + file. If multiple files can be specified on the command line the %F + placeholder should be used instead of %f. If the application is able to + open URLs in addition to local files then %u or %U can be used instead of + %f or %F. +Categories=Categories + + A list of categories separated by semi-colons. A category is a keyword that + describes and classifies the application. By default applications are + organized in the application menu based on category. When menu entries are + explicitly assigned to a new submenu it is not necassery to list any + categories. + + When using categories it is recommended to include one of the following + categories: AudioVideo, Development, Education, Game, Graphics, Network, + Office, Settings, System, Utility. + + See Appendix A of the XDG Desktop Menu Specification for information about + additional categories. http://standards.freedesktop.org/menu-spec/ + menu-spec-1.0.html + +MimeType=Mimetypes + A list of mimetypes separated by semi-colons. This field is used to + indicate which file types the application is able to open. + +For a complete oveview of the *.desktop file format please visit http:// +www.freedesktop.org/wiki/Standards/desktop-entry-spec + +Directory Files + +The appearance of submenu in the application menu is provided by a *.directory +file. In particular it provides the title of the submenu and a possible icon. A +*.directory file consists of a [Desktop Entry] header followed by several Key= +Value lines. + +A *.directory file can provide a title (name) for the submenu in several +different languages. This is done by adding a language code as used by +LC_MESSAGES in square brackets behind the Key. This way one can specify +different values for the same Key depending on the currently selected language. + +The following keys are relevqnt for submenus: + +Value=1.0 + This is a mandatory field to indicate that the *.directory file follows the + 1.0 version of the Desktop Entry specification. +Type=Directory + This is a mandatory field that indicates that the *.directory file + describes a submenu. +Name=Menu Name + The title of submenu. For example Mozilla +Comment=Comment + Optional field to specify a tooltip for the submenu. +Icon=Icon File + The icon to use for the submenu. This can either be an absolute path to an + image file or an icon-name. If an icon-name is provided an image lookup by + name is done in the user's current icon theme. The xdg-icon-resource + command can be used to install image files into icon themes. The advantage + of using an icon-name instead of an absolute path is that with an icon-name + the submenu icon can be provided in several different sizes as well as in + several differently themed styles. + +Environment Variables + +xdg-desktop-menu honours the following environment variables: + +XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero numerical value makes + xdg-desktop-menu do more verbose reporting on stderr. Setting a higher + value increases the verbosity. +XDG_UTILS_INSTALL_MODE + This environment variable can be used by the user or administrator to + override the installation mode. Valid values are user and system. + +Exit Codes + +An exit code of 0 indicates success while a non-zero exit code indicates +failure. The following failure codes can be returned: + +1 + Error in command line syntax. +2 + One of the files passed on the command line did not exist. +3 + A required tool could not be found. +4 + The action failed. +5 + No permission to read one of the files passed on the command line. + +See Also + +xdg-desktop-icon(1), xdg-icon-resource(1), xdg-mime(1) + +Examples + +The company ShinyThings Inc. has developed an application named "WebMirror" and +would like to add it to the application menu. The company will use +"shinythings" as its vendor id. In order to add the application to the menu +there needs to be a .desktop file with a suitable Categories entry: + +shinythings-webmirror.desktop: + + [Desktop Entry] + Encoding=UTF-8 + Type=Application + + Exec=webmirror + Icon=webmirror + + Name=WebMirror + Name[nl]=WebSpiegel + + Categories=Network;WebDevelopment; + +Now the xdg-desktop-menu tool can be used to add the +shinythings-webmirror.desktop file to the desktop application menu: + +xdg-desktop-menu install ./shinythings-webmirror.desktop + +Note that for the purpose of this example the menu items are available in two +languages, English and Dutch. The language code for Dutch is nl. + +In the next example the company ShinyThings Inc. will add its own submenu to +the desktop application menu consisting of a "WebMirror" menu item and a +"WebMirror Admin Tool" menu item. + +First the company needs to create two .desktop files that describe the two menu +items. Since the items are to be added to a new submenu it is not necassery to +include a Categories= line: + +shinythings-webmirror.desktop: + + [Desktop Entry] + Encoding=UTF-8 + Type=Application + + Exec=webmirror + Icon=shinythings-webmirror + + Name=WebMirror + Name[nl]=WebSpiegel + + +shinythings-webmirror-admin.desktop: + + [Desktop Entry] + Encoding=UTF-8 + Type=Application + + Exec=webmirror-admintool + Icon=shinythings-webmirror-admintool + + Name=WebMirror Admin Tool + Name[nl]=WebSpiegel Administratie Tool + +In addition a .directory file needs to be created to provide a title and icon +for the sub-menu itself: + +shinythings-webmirror.directory: + + [Desktop Entry] + Encoding=UTF-8 + + Icon=shinythings-webmirror-menu + + Name=WebMirror + Name[nl]=WebSpiegel + +These file can now be installed with: + +xdg-desktop-menu install ./shinythings-webmirror.directory \ + ./shinythings-webmirror.desktop ./shinythings-webmirror-admin.desktop + +The menu entries could also be installed one by one: + +xdg-desktop-menu install --noupdate ./shinythings-webmirror.directory \ + ./shinythings-webmirror.desktop +xdg-desktop-menu install --noupdate ./shinythings-webmirror.directory \ + ./shinythings-webmirror-admin.desktop +xdg-desktop-menu forceupdate + +Although the result is the same it is slightly more efficient to install all +files at the same time. + +The *.desktop and *.directory files reference icons with the names webmirror, +webmirror-admin and webmirror-menu which should also be installed. In this +example the icons are installed in two different sizes, once with a size of +22x22 pixels and once with a size of 64x64 pixels: + +xdg-icon-resource install --size 22 ./wmicon-22.png shinythings-webmirror +xdg-icon-resource install --size 22 ./wmicon-menu-22.png shinythings-webmirror-menu +xdg-icon-resource install --size 22 ./wmicon-admin-22.png shinythings-webmirror-admin +xdg-icon-resource install --size 64 ./wmicon-64.png shinythings-webmirror +xdg-icon-resource install --size 64 ./wmicon-menu-64.png shinythings-webmirror-menu +xdg-icon-resource install --size 64 ./wmicon-admin-64.png shinythings-webmirror-admin + +_MANUALPAGE +} + +usage() +{ +cat << _USAGE +xdg-desktop-menu - command line tool for (un)installing desktop menu items + +Synopsis + +xdg-desktop-menu install [--noupdate] [--novendor] [--mode mode] directory-file +(s) desktop-file(s) + +xdg-desktop-menu uninstall [--noupdate] [--mode mode] directory-file(s) +desktop-file(s) + +xdg-desktop-menu forceupdate [--mode mode] + +xdg-desktop-menu { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + echo "Try 'xdg-desktop-menu --help' for more information." >&2 + else + usage + echo "Use 'man xdg-desktop-menu' or 'xdg-desktop-menu --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-desktop-menu: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-desktop-menu: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-desktop-menu --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-desktop-menu' or 'xdg-desktop-menu --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-desktop-menu 1.0.1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`kde-config --version 2>/dev/null | grep KDE` + major=`echo $version | sed 's/KDE: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +update_desktop_database() +{ +# echo Update desktop database: $mode + if [ "$mode" = "system" ] ; then + for x in `echo $PATH | sed 's/:/ /g'` /opt/gnome/bin; do + if [ -x $x/update-desktop-database ] ; then + DEBUG 1 "Running $x/update-desktop-database" + eval '$x/update-desktop-database'$xdg_redirect_output + return + fi + done + fi +} + +fixup_mandriva_categories() +{ + DEBUG 1 "fixup_mandriva_categories $1" + awk ' +BEGIN { + xlat["AudioVideo"]="X-Mandrakelinux-Multimedia;X-MandrivaLinux-Multimedia" + xlat["Development"]="X-Mandrakelinux-MoreApplications-Development;X-MandrivaLinux-MoreApplications-Development" + xlat["Education"]="X-Mandrakelinux-MoreApplications;X-MandrivaLinux-MoreApplications-Education" + xlat["Game"]="X-Mandrakelinux-MoreApplications;X-MandrivaLinux-MoreApplications-Games" + xlat["Graphics"]="X-Mandrakelinux-Multimedia-Graphics" + xlat["Network"]="X-Mandrakelinux-Internet;X-MandrivaLinux-Internet" + xlat["Office"]="X-Mandrakelinux-Office;X-MandrivaLinux-Office" + xlat["System"]="X-Mandrakelinux-System;X-MandrivaLinux-System" + xlat["Utility"]="X-Mandrakelinux-Office-Accessories;X-MandrivaLinux-Office-Accessories" +} +{ + if (match($0,/Categories=/)) { + split(substr($0,RSTART+11),categories,";") + result="" + for (n in categories) + { + if (categories[n] in xlat) + categories[n]=categories[n] ";" xlat[categories[n]] + if (categories[n]) + result=result categories[n] ";" + } + print "Categories=" result + } + else + { + print $0 + } +}' $1 > $1.new + mv $1.new $1 +} + +# Make application $1/$2 the default for all the mimetypes it support, +# iff such mimetype didn't had a default application already. +# $1 Install dir for desktop file +# $2 base name of desktop file +make_lazy_default() +{ + local mimetypes + local xdg_user_dir + local xdg_default_dirs + + DEBUG 1 "make_lazy_default $1/$2" + mimetypes=`awk ' +{ + if (match($0,/MimeType=/)) { + split(substr($0,RSTART+9),mimetypes,";") + for (n in mimetypes) + { + if (mimetypes[n]) + print mimetypes[n] + } + } +}' "$1/$2" 2> /dev/null` + + for MIME in $mimetypes ; do + xdg_default_dirs="$XDG_DATA_DIRS" + [ -n "$xdg_default_dirs" ] || xdg_default_dirs=/usr/local/share/:/usr/share/ + if [ x"$mode" = x"user" ] ; then + xdg_user_dir="$XDG_DATA_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" + xdg_default_dirs="$xdg_user_dir:$xdg_default_dirs" + fi + local default_app + for x in `echo "$xdg_default_dirs" | sed 's/:/ /g'`; do + DEBUG 2 "Checking $x/applications/defaults.list" + default_app=`grep "$MIME=" $x/applications/defaults.list 2> /dev/null | cut -d '=' -f 2` + if [ -n "$default_app" ] ; then + DEBUG 2 "Found default apps for $MIME: $default_app" + default_app="$default_app;" + break; + fi + done + DEBUG 2 "Current default apps for $MIME: $default_app" + if echo "$default_app" | grep "$2" > /dev/null 2> /dev/null; then + # App already listed as default + continue; + fi + default_file="$1/defaults.list" + DEBUG 1 "Updating $default_file" + grep -v "$MIME=" $default_file > ${default_file}.new 2> /dev/null + if ! grep "[Default Applications]" ${default_file}.new > /dev/null; then + echo "[Default Applications]" >> ${default_file}.new + fi + echo $MIME="$default_app$2" >> ${default_file}.new + mv ${default_file}.new $default_file + done +} + +update_submenu() +{ + DEBUG 1 "update_submenu $1" + menu_file="$1" + + xdg_dir_name=menus + xdg_user_dir="$XDG_CONFIG_HOME" + [ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.config" + xdg_user_dir="$xdg_user_dir/$xdg_dir_name" + + xdg_system_dirs="$XDG_CONFIG_DIRS" + [ -n "$xdg_system_dirs" ] || xdg_system_dirs=/etc/xdg + xdg_global_dir= + for x in `echo $xdg_system_dirs | sed 's/:/ /g'` ; do + if [ -w $x/$xdg_dir_name ] ; then + xdg_global_dir="$x/$xdg_dir_name" + break + fi + done + xdg_user_dir="$xdg_user_dir/applications-merged" + xdg_global_dir="$xdg_global_dir/applications-merged" + + DEBUG 3 "Install locations for *.menu file:" + DEBUG 3 "xdg_user_dir: $xdg_user_dir" + DEBUG 3 "xdg_global_dir: $xdg_global_dir" + DEBUG 3 "kde_user_dir: $kde_user_dir" + DEBUG 3 "kde_global_dir: $kde_global_dir" + DEBUG 3 "gnome_user_dir: $gnome_user_dir" + DEBUG 3 "gnome_global_dir: $gnome_global_dir" + + if [ x"$mode" = x"user" ] ; then + xdg_dir="$xdg_user_dir" + kde_dir="$kde_user_dir" + gnome_dir="$gnome_user_dir" + my_umask=077 + my_chmod=0600 + else + xdg_dir="$xdg_global_dir" + kde_dir="$kde_global_dir" + gnome_dir="$gnome_global_dir" + my_umask=022 + my_chmod=0644 + if [ -z "${xdg_dir}${kde_dir}${gnome_dir}" ] ; then + exit_failure_operation_impossible "No writable system menu directory found." + fi + fi + + if [ -z "$menu_file" ] ; then + # Work around for SUSE/gnome 2.12 to pick up new ~/.local/share/applications + save_umask=`umask` + umask $my_umask + + mkdir -p $xdg_dir + touch $xdg_dir/xdg-desktop-menu-dummy.menu + + umask $save_umask + return + fi + + if [ $action = "install" -a -f "/etc/xdg/menus/gnome-applications.menu" ] ; then + # Work around for Debian Gnome + gnome_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/gnome-applications-merged^'` + if [ ! -e "$gnome_xdg_dir" ] ; then + DEBUG 1 "Debian Workaround: Link '$xdg_dir' to '$gnome_xdg_dir'" + mkdir -p `dirname "$gnome_xdg_dir"` + eval 'ln -s "applications-merged" "$gnome_xdg_dir"'$xdg_redirect_output + fi + fi + if [ $action = "install" -a -f "/etc/mandrake-release" ] ; then + # Work around for Mandriva 2006 + mandrake_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/applications-mdk-merged^'` + if [ ! -e "$mandrake_xdg_dir" ] ; then + DEBUG 1 "Mandriva Workaround: Link '$xdg_dir' to '$mandrake_xdg_dir'" + mkdir -p `dirname "$mandrake_xdg_dir"` + eval 'ln -s "applications-merged" "$mandrake_xdg_dir"'$xdg_redirect_output + fi + fi + if [ $action = "install" -a x"$mode" = x"user" -a -d "/etc/xdg/menus/kde-applications-merged" ] ; then + # Work around for Fedora Core 5 + patched KDE + kde_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/kde-applications-merged^'` + if [ ! -e "$kde_xdg_dir" ] ; then + DEBUG 1 "Fedora Workaround: Link '$xdg_dir' to '$kde_xdg_dir'" + mkdir -p `dirname "$kde_xdg_dir"` + eval 'ln -s "applications-merged" "$kde_xdg_dir"'$xdg_redirect_output + fi + fi + if [ $action = "install" -a x"$mode" = x"system" -a -d "/etc/xdg/menus/kde-applications-merged" -a ! -d "/etc/xdg/menus/applications-merged" ] ; then + # Work around for Kubuntu 6.06 + kde_xdg_dir=`echo "$xdg_dir" | sed -e 's^/applications-merged^/kde-applications-merged^'` + DEBUG 1 "Kubuntu Workaround: Link '$xdg_dir' to 'kde-applications-merged'" + eval 'ln -s "kde-applications-merged" "$xdg_dir"'$xdg_redirect_output + fi + + orig_menu_file=$xdg_dir/$menu_file + + DEBUG 1 "Updating $orig_menu_file ($action)" + + tmpfile=`mktemp` + orig_desktop_files= + if [ -r "$orig_menu_file" ] ; then + awk ' +# List all files within tags +BEGIN { + RS="<" +} +/^Filename/ { + if (match($0,/>/)) { + print substr($0,RSTART+1) + } +}' $orig_menu_file > $tmpfile + fi + + orig_desktop_files=`cat $tmpfile` + new_desktop_files= + if [ $action = "install" ] ; then + for desktop_file in $desktop_files; do + basefile=`basename $desktop_file` + if ! grep '^'$basefile'$' $tmpfile > /dev/null 2> /dev/null ; then + # Append + echo "$basefile" >> $tmpfile + fi + done + new_desktop_files=`cat $tmpfile` + fi + if [ $action = "uninstall" ] ; then + echo > $tmpfile + for desktop_file in $desktop_files; do + echo "$desktop_file" >> $tmpfile + done + # Files to uninstall are listed in $tmpfile + # Existing files are in $orig_desktop_files + for desktop_file in $orig_desktop_files; do + if ! grep '^'$desktop_file'$' $tmpfile > /dev/null 2> /dev/null; then + # Keep this file, it's not in the uninstall list + new_desktop_files="$new_desktop_files $desktop_file" + fi + done + fi + rm -f "$tmpfile" + + DEBUG 3 "Files to list in $menu_file: $new_desktop_files" + + if [ -n "$new_desktop_files" ] ; then + # Install/update + tmpfile=`mktemp` + ( + echo '' + echo '' + echo '' + echo ' Applications' + + for desktop_file in $directory_files; do + basefile=`basename $desktop_file` + basefilename=`echo "$basefile"|cut -d '.' -f 1` + echo "" + echo " $basefilename" + echo " $basefile" + done + + echo " " + for desktop_file in $new_desktop_files; do + echo " $desktop_file" + done + echo " " + + for desktop_file in $directory_files; do + echo "" + done + + echo '' + ) > $tmpfile + chmod $my_chmod $tmpfile + + save_umask=`umask` + umask $my_umask + + mkdir -p $xdg_dir + eval 'cp $tmpfile $xdg_dir/$menu_file'$xdg_redirect_output + + umask $save_umask + rm -f "$tmpfile" + else + # Uninstall + rm -f $xdg_dir/$menu_file + fi + + # Uninstall .directory files only if no longer referenced + if [ $action = "uninstall" ] ; then + tmpfile=`mktemp` + for menu_file in $xdg_dir/*; do + if grep 'generated and managed by xdg-desktop-menu' $menu_file > /dev/null 2> /dev/null; then + awk ' +# List all files within tags +BEGIN { + RS="<" +} +/^Directory/ { + if (match($0,/>/)) { + print substr($0,RSTART+1) + } +}' $menu_file >> $tmpfile + fi + done + orig_directory_files="$directory_files" + directory_files= + for desktop_file in $orig_directory_files; do + if ! grep '^'$desktop_file'$' $tmpfile > /dev/null 2> /dev/null; then + # No longer in use, safe to delete + directory_files="$directory_files $desktop_file" + fi + done + rm -f "$tmpfile" + fi +} + + +[ x"$1" != x"" ] || exit_failure_syntax + +mode= +action= +update=yes +desktop_files= +directory_files= + +case $1 in + install) + action=install + ;; + + uninstall) + action=uninstall + ;; + + forceupdate) + action=forceupdate + ;; + + *) + exit_failure_syntax "unknown command '$1'" + ;; +esac + +shift + +vendor=true +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --noupdate) + update=no + ;; + + --mode) + if [ -z "$1" ] ; then + exit_failure_syntax "mode argument missing for --mode" + fi + case "$1" in + user) + mode="user" + ;; + + system) + mode="system" + ;; + + *) + exit_failure_syntax "unknown mode '$1'" + ;; + esac + shift + ;; + + --novendor) + vendor=false + ;; + + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ "$action" = "install" ] ; then + check_input_file "$parm" + fi + case "$parm" in + *.directory) + if [ -n "$desktop_files" ] ; then + exit_failure_syntax "'$parm' must preceed any *.desktop file" + fi + directory_files="$directory_files $parm" + ;; + *.desktop) + desktop_files="$desktop_files $parm" + ;; + *) + exit_failure_syntax "file to $action must be a *.directory or *.desktop file" + ;; + esac + ;; + esac +done + +# Shouldn't happen +if [ -z "$action" ] ; then + exit_failure_syntax "command argument missing" +fi + +if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then + if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then + mode="system" + elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then + mode="user" + fi +fi + +if [ -z "$mode" ] ; then + if [ `whoami` = "root" ] ; then + mode="system" + else + mode="user" + fi +fi + +if [ x"$action" = x"forceupdate" ] ; then + update_desktop_database + exit_success +fi + +if [ -z "$desktop_files" ] ; then + exit_failure_syntax "desktop-file argument missing" +fi + +menu_name= +for desktop_file in $directory_files; do + if [ "$vendor" = "true" -a "$action" = "install" ] ; then + check_vendor_prefix "$desktop_file" + fi + + basefilename=`basename "$desktop_file"|cut -d '.' -f 1` + if [ -z "$menu_name" ] ; then + menu_name="$basefilename" + else + menu_name="$menu_name-$basefilename" + fi +done + +if [ -n "$menu_name" ] ; then + if [ x"$mode" = x"user" ] ; then + update_submenu "user-$menu_name.menu" + else + update_submenu "$menu_name.menu" + fi +else + # Work around for SUSE/gnome 2.12 to pick up new ~/.local/share/applications + if [ x"$mode" = x"user" ] ; then + update_submenu + fi +fi + +# Install *.directory files + +xdg_dir_name=desktop-directories + +xdg_user_dir="$XDG_DATA_HOME" +[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" +xdg_user_dir="$xdg_user_dir/$xdg_dir_name" + +xdg_system_dirs="$XDG_DATA_DIRS" +[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ +xdg_global_dir= +for x in `echo $xdg_system_dirs | sed 's/:/ /g'` ; do + if [ -w $x/$xdg_dir_name ] ; then + xdg_global_dir="$x/$xdg_dir_name" + break + fi +done + +DEBUG 3 "Install locations for *.directory files:" +DEBUG 3 "xdg_user_dir: $xdg_user_dir" +DEBUG 3 "xdg_global_dir: $xdg_global_dir" +DEBUG 3 "kde_user_dir: $kde_user_dir" +DEBUG 3 "kde_global_dir: $kde_global_dir" +DEBUG 3 "gnome_user_dir: $gnome_user_dir" +DEBUG 3 "gnome_global_dir: $gnome_global_dir" + +if [ x"$mode" = x"user" ] ; then + xdg_dir="$xdg_user_dir" + kde_dir="$kde_user_dir" + gnome_dir="$gnome_user_dir" + my_umask=077 +else + xdg_dir="$xdg_global_dir" + kde_dir="$kde_global_dir" + gnome_dir="$gnome_global_dir" + my_umask=022 + if [ -z "${xdg_dir}${kde_dir}${gnome_dir}" ] ; then + exit_failure_operation_impossible "No writable system menu directory found." + fi +fi + +for desktop_file in $directory_files; do + basefile=`basename $desktop_file` + + DEBUG 1 "$action $desktop_file in $xdg_dir $kde_dir $gnome_dir" + + case $action in + install) + save_umask=`umask` + umask $my_umask + + for x in $xdg_dir $kde_dir $gnome_dir ; do + mkdir -p $x + eval 'cp $desktop_file $x/$basefile'$xdg_redirect_output + done + + umask $save_umask + ;; + + uninstall) + for x in $xdg_dir $kde_dir $gnome_dir ; do + rm -f $x/$basefile + done + + ;; + esac +done + +# Install *.desktop files +xdg_dir_name=applications + +xdg_user_dir="$XDG_DATA_HOME" +[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" +xdg_user_dir="$xdg_user_dir/$xdg_dir_name" + +xdg_system_dirs="$XDG_DATA_DIRS" +[ -n "$xdg_system_dirs" ] || xdg_system_dirs=/usr/local/share/:/usr/share/ +xdg_global_dir= +for x in `echo $xdg_system_dirs | sed 's/:/ /g'` ; do + if [ -w $x/$xdg_dir_name ] ; then + xdg_global_dir="$x/$xdg_dir_name" + break + fi +done + +kde_user_dir="$HOME/.kde/share/applnk" +kde_global_dir="/usr/share/applnk" +[ -w $kde_global_dir ] || kde_global_dir= + +gnome_user_dir="$HOME/.gnome/apps" +gnome_global_dir="/usr/share/gnome/apps" +[ -w $gnome_global_dir ] || gnome_global_dir= + +[ -f /etc/mandriva-release ] && need_mandriva_fix=true +[ -n "$need_mandriva_fix" ] && DEBUG 1 "Fixing up .desktop categories (Mandriva work around)" + +DEBUG 3 "Install locations for *.desktop files:" +DEBUG 3 "xdg_user_dir: $xdg_user_dir" +DEBUG 3 "xdg_global_dir: $xdg_global_dir" +DEBUG 3 "kde_user_dir: $kde_user_dir" +DEBUG 3 "kde_global_dir: $kde_global_dir" +DEBUG 3 "gnome_user_dir: $gnome_user_dir" +DEBUG 3 "gnome_global_dir: $gnome_global_dir" + +if [ x"$mode" = x"user" ] ; then + xdg_dir="$xdg_user_dir" + kde_dir="$kde_user_dir" + gnome_dir="$gnome_user_dir" + my_umask=077 +else + xdg_dir="$xdg_global_dir" + kde_dir="$kde_global_dir" + gnome_dir="$gnome_global_dir" + my_umask=022 + if [ -z "${xdg_dir}${kde_dir}${gnome_dir}" ] ; then + exit_failure_operation_impossible "No writable system menu directory found." + fi +fi + +for desktop_file in $desktop_files; do + if [ "$vendor" = "true" -a "$action" = "install" ] ; then + check_vendor_prefix "$desktop_file" + fi + + basefile=`basename $desktop_file` + + DEBUG 1 "$action $desktop_file in $xdg_dir $kde_dir $gnome_dir" + + case $action in + install) + save_umask=`umask` + umask $my_umask + + for x in $xdg_dir $kde_dir $gnome_dir ; do + mkdir -p $x + eval 'cp $desktop_file $x/$basefile'$xdg_redirect_output + done + + if [ -n "$need_mandriva_fix" ] ; then + fixup_mandriva_categories $xdg_dir/$basefile + fi + + if [ -f $kde_dir/$basefile ] ; then + echo "OnlyShowIn=Old;" >> $kde_dir/$basefile + fi + + if [ -f $gnome_dir/$basefile ] ; then + echo "OnlyShowIn=Old;" >> $gnome_dir/$basefile + fi + + make_lazy_default "$xdg_dir" "$basefile" + + umask $save_umask + ;; + + uninstall) + for x in $xdg_dir $kde_dir $gnome_dir ; do + rm -f $x/$basefile + done + + ;; + esac +done + +if [ x"$update" = x"yes" ] ; then + update_desktop_database +fi + +exit_success diff --git a/src/desktop/xdg-utils-1.0.1/scripts/xdg-icon-resource b/src/desktop/xdg-utils-1.0.1/scripts/xdg-icon-resource new file mode 100755 index 00000000..df34ccaf --- /dev/null +++ b/src/desktop/xdg-utils-1.0.1/scripts/xdg-icon-resource @@ -0,0 +1,837 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-icon-resource +# +# Utility script to install icons on a Linux desktop. +# +# Refer to the usage() function below for usage. +# +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + +xdg-icon-resource - command line tool for (un)installing icon resources + +Synopsis + +xdg-icon-resource install [--noupdate] [--novendor] [--theme theme] [--context +context] [--mode mode] --size size icon-file [icon-name] + +xdg-icon-resource uninstall [--noupdate] [--theme theme] [--context context] +[--mode mode] --size size icon-name + +xdg-icon-resource forceupdate [--theme theme] [--mode mode] + +xdg-icon-resource { --help | --manual | --version } + +Description + +The xdg-icon-resource program can be used to install icon resources into the +desktop icon system in order to illustrate menu entries, to depict desktop +icons or to graphically represent file types. + +The desktop icon system identifies icons by name. Depending on the required +size, the choice of icon theme and the context in which the icon is used, the +desktop icon system locates an appropriate icon resource to depict an icon. +Icon resources can be XPM files, PNG files or SVG files. + +The desktop icon system works according to the XDG Icon Theme Specification at +http://www.freedesktop.org/Standards/icon-theme-spec + +Commands + +install + Installs the icon file indicated by icon-file to the desktop icon system + under the name icon-name. Icon names do not have an extension. If icon-name + is not provided the name is derived from icon-file. The icon file must have + .png or .xpm as extension. If a corresponding .icon file exists in the same + location as icon-file it will be installed as well. +uninstall + Removes the icon indicated by icon-name from the desktop icon system. Note + that icon names do not have an extension. +forceupdate + Force an update of the desktop icon system. This is only useful if the last + call to xdg-icon-resource included the --noupdate option. + +Options + +--noupdate + Postpone updating the desktop icon system. If multiple icons are added in + sequence this flag can be used to indicate that additional changes will + follow and that it is not necassery to update the desktop icon system right + away. +--novendor + + Normally, xdg-icon-resource checks to ensure that an icon file to be + installed in the apps context has a proper vendor prefix. This option can + be used to disable that check. + + A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated + with a dash ("-"). Companies and organizations are encouraged to use a word + or phrase, preferably the organizations name, for which they hold a + trademark as their vendor prefix. The purpose of the vendor prefix is to + prevent name conflicts. + +--theme theme + Installs or removes the icon file as part of theme. If no theme is + specified the icons will be installed as part of the default hicolor theme. + Applications may install icons under multiple themes but should at least + install icons for the default hicolor theme. +--context context + Specifies the context for the icon. Icons to be used in the application + menu and as desktop icon should use apps as context which is the default + context. Icons to be used as file icons should use mimetypes as context. + Other common contexts are actions, devices, emblems, filesystems and stock. +--size size + Specifies the size of the icon. All icons must be square. Common sizes for + icons in the apps context are: 16, 22, 32, 48, 64 and 128. Common sizes for + icons in the mimetypes context are: 16, 22, 32, 48, 64 and 128 +--mode mode + + mode can be user or system. In user mode the file is (un)installed for the + current user only. In system mode the file is (un)installed for all users + on the system. Usually only root is allowed to install in system mode. + + The default is to use system mode when called by root and to use user mode + when called by a non-root user. + +--help + Show command synopsis. +--manual + Show this manualpage. +--version + Show the xdg-utils version information. + +Environment Variables + +xdg-icon-resource honours the following environment variables: + +XDG_UTILS_DEBUG_LEVEL + Setting this environment variable to a non-zero numerical value makes + xdg-icon-resource do more verbose reporting on stderr. Setting a higher + value increases the verbosity. +XDG_UTILS_INSTALL_MODE + This environment variable can be used by the user or administrator to + override the installation mode. Valid values are user and system. + +Exit Codes + +An exit code of 0 indicates success while a non-zero exit code indicates +failure. The following failure codes can be returned: + +1 + Error in command line syntax. +2 + One of the files passed on the command line did not exist. +3 + A required tool could not be found. +4 + The action failed. +5 + No permission to read one of the files passed on the command line. + +See Also + +xdg-desktop-icon(1), xdg-desktop-menu(1), xdg-mime(1) + +Examples + +To install an icon resource to depict a launcher for the application myfoobar, +the company ShinyThings Inc. can use: + +xdg-icon-resource install --size 64 shinythings-myfoobar.png + +To install an icon for a new application/x-foobar file type one can use: + +xdg-icon-resource install --context mimetypes --size 48 ./mime-foobar-48.png application-x-foobar +xdg-icon-resource install --context mimetypes --size 64 ./mime-foobar-64.png application-x-foobar + +This will install two icons with the name application-x-foobar but with +different sizes. + +_MANUALPAGE +} + +usage() +{ +cat << _USAGE +xdg-icon-resource - command line tool for (un)installing icon resources + +Synopsis + +xdg-icon-resource install [--noupdate] [--novendor] [--theme theme] [--context +context] [--mode mode] --size size icon-file [icon-name] + +xdg-icon-resource uninstall [--noupdate] [--theme theme] [--context context] +[--mode mode] --size size icon-name + +xdg-icon-resource forceupdate [--theme theme] [--mode mode] + +xdg-icon-resource { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + echo "Try 'xdg-icon-resource --help' for more information." >&2 + else + usage + echo "Use 'man xdg-icon-resource' or 'xdg-icon-resource --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-icon-resource: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-icon-resource: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-icon-resource --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-icon-resource' or 'xdg-icon-resource --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-icon-resource 1.0.1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`kde-config --version 2>/dev/null | grep KDE` + major=`echo $version | sed 's/KDE: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +# Set GTK_UPDATE_ICON_CACHE to gtk-update-icon-cache executable path or +# to "-" if not found. +GTK_UPDATE_ICON_CACHE= +find_gtk_update_icon_cache() +{ + [ -n "$GTK_UPDATE_ICON_CACHE" ] && return; + + GTK_UPDATE_ICON_CACHE="-" + for x in `echo "$PATH:/opt/gnome/bin" | sed 's/:/ /g'`; do + DEBUG 3 "Checking $x for gtk-update-icon-cache" + if [ -x "$x/gtk-update-icon-cache" ] ; then + DEBUG 1 "Found $x/gtk-update-icon-cache" + GTK_UPDATE_ICON_CACHE="$x/gtk-update-icon-cache" + return + fi + done +} + +# Start GNOME legacy workaround section +need_dot_icon_path() +{ + # GTK < 2.6 uses ~/.icons but not XDG_DATA_HOME/icons + # The availability of gtk-update-icon-cache is used as indication + # of whether the system is using GTK 2.6 or later + find_gtk_update_icon_cache + [ "$GTK_UPDATE_ICON_CACHE" != "-" ] && return 1; + return 0; +} + +update_icon_database() +{ + # Touch me, I'm dirty + touch "$1/.xdg-icon-resource-dummy" + rm -f "$1/.xdg-icon-resource-dummy" + + # Don't create a cache if there wan't one already + if [ -f "$1/icon-theme.cache" ] ; then + find_gtk_update_icon_cache + if [ "$GTK_UPDATE_ICON_CACHE" != "-" ] ; then + DEBUG 1 "Running $GTK_UPDATE_ICON_CACHE -f -t \"$1\"" + eval '$GTK_UPDATE_ICON_CACHE -f -t "$1"'$xdg_redirect_output + return + fi + fi +} + +[ x"$1" != x"" ] || exit_failure_syntax + +mode= +action= +update=yes +size= +theme=hicolor +context=apps +icon_file= +icon_name= + +case $1 in + install) + action=install + ;; + + uninstall) + action=uninstall + ;; + + forceupdate) + action=forceupdate + ;; + + *) + exit_failure_syntax "unknown command '$1'" + ;; +esac + +shift + +vendor=true +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case $parm in + --noupdate) + update=no + ;; + + --mode) + if [ -z "$1" ] ; then + exit_failure_syntax "mode argument missing for --mode" + fi + case "$1" in + user) + mode="user" + ;; + + system) + mode="system" + ;; + + *) + exit_failure_syntax "unknown mode '$1'" + ;; + esac + shift + ;; + + --theme) + if [ -z "$1" ] ; then + exit_failure_syntax "theme argument missing for --theme" + fi + theme="$1" + shift + ;; + + --size) + if [ -z "$1" ] ; then + exit_failure_syntax "size argument missing for --size" + fi + if echo "$1" | grep '[^0-9]' > /dev/null 2> /dev/null; then + exit_failure_syntax "size argument must be numeric" + fi + size="$1" + shift + ;; + + --context) + if [ -z "$1" ] ; then + exit_failure_syntax "context argument missing for --context" + fi + context="$1" + shift + ;; + + --novendor) + vendor=false + ;; + + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$icon_name" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + elif [ -n "$icon_file" ] ; then + icon_name="$parm" + else + if [ "$action" = "install" ] ; then + check_input_file "$parm" + fi + icon_file="$parm" + fi + ;; + esac +done + +# Shouldn't happen +if [ -z "$action" ] ; then + exit_failure_syntax "command argument missing" +fi + +# Shouldn't happen +if [ -z "$context" ] ; then + exit_failure_syntax "context argument missing" +fi + +if [ -n "$XDG_UTILS_INSTALL_MODE" ] ; then + if [ "$XDG_UTILS_INSTALL_MODE" = "system" ] ; then + mode="system" + elif [ "$XDG_UTILS_INSTALL_MODE" = "user" ] ; then + mode="user" + fi +fi + +if [ -z "$mode" ] ; then + if [ `whoami` = "root" ] ; then + mode="system" + else + mode="user" + fi +fi + +xdg_dir_name="icons/$theme" + +xdg_user_dir="$XDG_DATA_HOME" +[ -n "$xdg_user_dir" ] || xdg_user_dir="$HOME/.local/share" +xdg_user_prefix="$xdg_user_dir/icons" +xdg_user_dir="$xdg_user_dir/$xdg_dir_name" + +xdg_global_dir= +xdg_global_prefix= +xdg_system_dirs="$XDG_DATA_DIRS" +[ -n "$xdg_system_dirs" ] || xdg_system_dirs="/usr/local/share/:/usr/share/" +for x in `echo "$xdg_system_dirs" | sed 's/:/ /g'`; do + if [ -w $x/$xdg_dir_name ] ; then + xdg_global_prefix="$x/icons" + xdg_global_dir="$x/$xdg_dir_name" + break + fi +done +[ -w $xdg_global_dir ] || xdg_global_dir= + +dot_icon_dir= +dot_base_dir= +if [ x"$mode" = x"user" ] ; then + xdg_base_dir="$xdg_user_dir" + #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME + if need_dot_icon_path ; then + dot_icon_dir="$HOME/.icons" + dot_base_dir="$dot_icon_dir/$theme" + fi +else + xdg_base_dir="$xdg_global_dir" + if [ -z "$xdg_base_dir" ] ; then + exit_failure_operation_impossible "No writable system icon directory found." + fi +fi + +if [ x"$action" = x"forceupdate" ] ; then + if [ -n "$icon_file" ] ; then + exit_failure_syntax "unexpected argument '$icon_file'" + fi + update_icon_database $xdg_base_dir + if [ -n "$dot_icon_dir" ] ; then + if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then + update_icon_database $dot_base_dir + fi + fi + exit_success +fi + +if [ -z "$icon_file" ] ; then + if [ x"$action" = x"install" ] ; then + exit_failure_syntax "icon-file argument missing" + else + exit_failure_syntax "icon-name argument missing" + fi +fi + +xdg_size_name= +extension= + +if [ -z "$size" ] ; then + exit_failure_syntax "the icon size must be specified with --size" +fi +xdg_size_name="${size}x${size}" + +if [ x"$action" = x"install" ] ; then + case $icon_file in + *.xpm) + extension="xpm" + ;; + *.png) + extension="png" + ;; + *) + exit_failure_syntax "icon file to install must be a *.png or *.xpm file" + ;; + esac +fi + +if [ -n "$icon_name" ] ; then + case $icon_name in + *.png) + exit_failure_syntax "icon name should not include an extension" + ;; + *.xpm) + exit_failure_syntax "icon name should not include an extension" + ;; + esac +fi + +# Start KDE legacy workaround section +need_kde_icon_path() +{ + local path + path=`readlink -f "$1" 2> /dev/null` # Normalize path + DEBUG 2 "need_kde_icon_path $path" + if [ -z "$path" ] ; then + DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no xdg icon dir)" + return 1; # Not needed + fi + + # if kde-config not found... return 0 + kde_icon_dirs=`kde-config --path icon 2> /dev/null |sed 's/:/ /g'` + DEBUG 3 "kde_icon_dirs: $kde_icon_dirs" + if [ -z "$kde_icon_dirs" ] ; then + DEBUG 3 "no result from kde-config --path icon" + DEBUG 2 "need_kde_icon_path RETURN 1 (not needed, no kde icon path)" + return 1; # Not needed + fi + needed=0 # Needed + for y in $kde_icon_dirs ; do + x=`readlink -f "$y"` # Normalize path + DEBUG 3 "Normalize $y --> $x" + if [ -n "$x" ] ; then + if [ "$x" = "$path" ] ; then + needed=1 # Not needed + fi + if [ -w "$x" ] ; then + kde_global_prefix="$x" + # Take last writable dir + fi + fi + done + DEBUG 2 "kde_global_prefix: $kde_global_prefix" + [ $needed -eq "1" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (not needed)" + [ $needed -eq "0" ] && DEBUG 2 "need_kde_icon_path RETURN $needed (needed)" + return $needed +} + +kde_dir= +if [ x"$mode" = x"user" ] ; then + xdg_dir="$xdg_base_dir/$xdg_size_name/$context" + #KDE 3.x doesn't support XDG_DATA_HOME for icons + #Check if xdg_dir prefix is listed by kde-config --path icon + #If not, install additional symlink to kdedir + if need_kde_icon_path "$xdg_user_prefix" ; then + kde_user_dir="$HOME/.kde/share/icons/$theme" + kde_dir="$kde_user_dir/$xdg_size_name/$context" + fi + #Gnome 2.8 supports ~/.icons but not XDG_DATA_HOME + if [ -n "$dot_icon_dir" ] ; then + if [ -L "$dot_icon_dir" ] ; then + # Don't do anything + dot_icon_dir= + elif [ ! -d "$dot_icon_dir/" ] ; then + # Symlink if it doesn't exist + eval 'ln -s ".local/share/icons" "$dot_icon_dir"'$xdg_redirect_output + dot_icon_dir= + else + dot_icon_dir="$dot_icon_dir/$theme/$xdg_size_name/$context" + fi + fi + my_umask=077 +else + xdg_dir="$xdg_base_dir/$xdg_size_name/$context" + #KDE 3.x doesn't support XDG_DATA_DIRS for icons + #Check if xdg_dir prefix is listed by kde-config --path icon + #If not, install additional symlink to kdedir + if need_kde_icon_path "$xdg_global_prefix" ; then + kde_global_dir="$kde_global_prefix/$theme" + kde_dir="$kde_global_dir/$xdg_size_name/$context" + fi + my_umask=022 +fi +# End KDE legacy workaround section + +# Start GNOME legacy workaround section +need_gnome_mime= +[ $context = "mimetypes" ] && need_gnome_mime=true +# End GNOME legacy workaround section + +[ -n "$icon_name" ] || icon_name=`basename $icon_file | sed 's/\.[a-z][a-z][a-z]$//'` + +if [ "$vendor" = "true" -a "$action" = "install" -a "$context" = "apps" ] ; then + check_vendor_prefix "$icon_name" "icon name" +fi + +icon_icon_file=`echo "$icon_file" | sed 's/\.[a-z][a-z][a-z]$/.icon/'` +icon_icon_name="$icon_name.icon" + +DEBUG 1 "$action icon in $xdg_dir" +[ $action = "install" -a -f $icon_icon_file ] && DEBUG 1 "install $icon_icon_name meta file in $xdg_dir" +[ -n "$kde_dir" ] && DEBUG 1 "$action symlink in $kde_dir (KDE 3.x support)" +[ -n "$need_gnome_mime" ] && DEBUG 1 "$action gnome-mime-$icon_name symlink (GNOME 2.x support)" +[ $action = "install" -a -n "$dot_icon_dir" ] && DEBUG 1 "$action ~/.icons symlink (GNOME 2.8 support)" + +case $action in + install) + save_umask=`umask` + umask $my_umask + + for icon_dir in $xdg_dir $dot_icon_dir; do + mkdir -p $icon_dir + eval 'cp "$icon_file" "$icon_dir/$icon_name.$extension"'$xdg_redirect_output + if [ -f "$icon_icon_file" ] ; then + eval 'cp "$icon_icon_file" "$icon_dir/$icon_icon_name"'$xdg_redirect_output + fi + if [ -n "$need_gnome_mime" ] ; then + eval 'ln -s "$icon_name.$extension" "$icon_dir/gnome-mime-$icon_name.$extension"'$xdg_redirect_output + fi + done + if [ -n "$kde_dir" ] ; then + mkdir -p $kde_dir + eval 'ln -s "$xdg_dir/$icon_name.$extension" "$kde_dir/$icon_name.$extension"'$xdg_redirect_output + fi + + umask $save_umask + ;; + + uninstall) + for icon_dir in $xdg_dir $dot_icon_dir; do + rm -f "$icon_dir/$icon_name.xpm" "$icon_dir/$icon_name.png" + rm -f "$icon_dir/$icon_icon_name" + if [ -n "$need_gnome_mime" ] ; then + rm -f "$icon_dir/gnome-mime-$icon_name.xpm" + rm -f "$icon_dir/gnome-mime-$icon_name.png" + fi + done + if [ -n "$kde_dir" ] ; then + rm -f "$kde_dir/$icon_name.xpm" "$kde_dir/$icon_name.png" + fi + + ;; +esac + +if [ x"$update" = x"yes" ] ; then + update_icon_database "$xdg_base_dir" + if [ -n "$dot_icon_dir" ] ; then + if [ -d "$dot_icon_dir/" -a ! -L "$dot_icon_dir" ] ; then + update_icon_database $dot_base_dir + fi + fi +fi + +exit_success diff --git a/src/desktop/xdg-utils-1.0.1/scripts/xdg-open b/src/desktop/xdg-utils-1.0.1/scripts/xdg-open new file mode 100755 index 00000000..4cc18a84 --- /dev/null +++ b/src/desktop/xdg-utils-1.0.1/scripts/xdg-open @@ -0,0 +1,436 @@ +#!/bin/sh +#--------------------------------------------- +# xdg-open +# +# Utility script to open a URL in the registered default application. +# +# Refer to the usage() function below for usage. +# +# Copyright 2006, Kevin Krammer +# Copyright 2006, Jeremy White +# +# LICENSE: +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +#--------------------------------------------- + +manualpage() +{ +cat << _MANUALPAGE +Name + +xdg-open - opens a file or URL in the user's preferred application + +Synopsis + +xdg-open { file | URL } + +xdg-open { --help | --manual | --version } + +Description + +xdg-open opens a file or URL in the user's preferred application. If a URL is +provided the URL will be opened in the user's preferred web browser. If a file +is provided the file will be opened in the preferred application for files of +that type. xdg-open supports file, ftp, http and https URLs. + +xdg-open is for use inside a desktop session only. It is not recommended to use +xdg-open as root. + +Options + +--help + Show command synopsis. +--manual + Show this manualpage. +--version + Show the xdg-utils version information. + +Exit Codes + +An exit code of 0 indicates success while a non-zero exit code indicates +failure. The following failure codes can be returned: + +1 + Error in command line syntax. +2 + One of the files passed on the command line did not exist. +3 + A required tool could not be found. +4 + The action failed. + +Examples + +xdg-open 'http://www.freedesktop.org/' + +Opens the Freedesktop.org website in the user's default browser + +xdg-open /tmp/foobar.png + +Opens the PNG image file /tmp/foobar.png in the user's default image viewing +application. + +_MANUALPAGE +} + +usage() +{ +cat << _USAGE +xdg-open - opens a file or URL in the user's preferred application + +Synopsis + +xdg-open { file | URL } + +xdg-open { --help | --manual | --version } + +_USAGE +} + +#@xdg-utils-common@ + +#---------------------------------------------------------------------------- +# Common utility functions included in all XDG wrapper scripts +#---------------------------------------------------------------------------- + +DEBUG() +{ + [ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && return 0; + [ ${XDG_UTILS_DEBUG_LEVEL} -lt $1 ] && return 0; + shift + echo "$@" >&2 +} + +#------------------------------------------------------------- +# Exit script on successfully completing the desired operation + +exit_success() +{ + if [ $# -gt 0 ]; then + echo "$@" + echo + fi + + exit 0 +} + + +#----------------------------------------- +# Exit script on malformed arguments, not enough arguments +# or missing required option. +# prints usage information + +exit_failure_syntax() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + echo "Try 'xdg-open --help' for more information." >&2 + else + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + fi + + exit 1 +} + +#------------------------------------------------------------- +# Exit script on missing file specified on command line + +exit_failure_file_missing() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 2 +} + +#------------------------------------------------------------- +# Exit script on failure to locate necessary tool applications + +exit_failure_operation_impossible() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 3 +} + +#------------------------------------------------------------- +# Exit script on failure returned by a tool application + +exit_failure_operation_failed() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 4 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_read() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 5 +} + +#------------------------------------------------------------ +# Exit script on insufficient permission to read a specified file + +exit_failure_file_permission_write() +{ + if [ $# -gt 0 ]; then + echo "xdg-open: $@" >&2 + fi + + exit 6 +} + +check_input_file() +{ + if [ ! -e "$1" ]; then + exit_failure_file_missing "file '$1' does not exist" + fi + if [ ! -r "$1" ]; then + exit_failure_file_permission_read "no permission to read file '$1'" + fi +} + +check_vendor_prefix() +{ + file_label="$2" + [ -n "$file_label" ] || file_label="filename" + file=`basename "$1"` + case "$file" in + [a-zA-Z]*-*) + return + ;; + esac + + echo "xdg-open: $file_label '$file' does not have a proper vendor prefix" >&2 + echo 'A vendor prefix consists of alpha characters ([a-zA-Z]) and is terminated' >&2 + echo 'with a dash ("-"). An example '"$file_label"' is '"'example-$file'" >&2 + echo "Use --novendor to override or 'xdg-open --manual' for additional info." >&2 + exit 1 +} + +check_output_file() +{ + # if the file exists, check if it is writeable + # if it does not exists, check if we are allowed to write on the directory + if [ -e "$1" ]; then + if [ ! -w "$1" ]; then + exit_failure_file_permission_write "no permission to write to file '$1'" + fi + else + DIR=`dirname "$1"` + if [ ! -w "$DIR" -o ! -x "$DIR" ]; then + exit_failure_file_permission_write "no permission to create file '$1'" + fi + fi +} + +#---------------------------------------- +# Checks for shared commands, e.g. --help + +check_common_commands() +{ + while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + --help) + usage + echo "Use 'man xdg-open' or 'xdg-open --manual' for additional info." + exit_success + ;; + + --manual) + manualpage + exit_success + ;; + + --version) + echo "xdg-open 1.0.1" + exit_success + ;; + esac + done +} + +check_common_commands "$@" + +[ -z "${XDG_UTILS_DEBUG_LEVEL}" ] && unset XDG_UTILS_DEBUG_LEVEL; +if [ ${XDG_UTILS_DEBUG_LEVEL-0} -lt 1 ]; then + # Be silent + xdg_redirect_output=" > /dev/null 2> /dev/null" +else + # All output to stderr + xdg_redirect_output=" >&2" +fi + +#-------------------------------------- +# Checks for known desktop environments +# set variable DE to the desktop environments name, lowercase + +detectDE() +{ + if [ x"$KDE_FULL_SESSION" = x"true" ]; then DE=kde; + elif [ x"$GNOME_DESKTOP_SESSION_ID" != x"" ]; then DE=gnome; + elif xprop -root _DT_SAVE_MODE | grep ' = \"xfce4\"$' >/dev/null 2>&1; then DE=xfce; + fi +} + +#---------------------------------------------------------------------------- +# kfmclient exec/openURL can give bogus exit value in KDE <= 3.5.4 +# It also always returns 1 in KDE 3.4 and earlier +# Simply return 0 in such case + +kfmclient_fix_exit_code() +{ + version=`kde-config --version 2>/dev/null | grep KDE` + major=`echo $version | sed 's/KDE: \([0-9]\).*/\1/'` + minor=`echo $version | sed 's/KDE: [0-9]*\.\([0-9]\).*/\1/'` + release=`echo $version | sed 's/KDE: [0-9]*\.[0-9]*\.\([0-9]\).*/\1/'` + test "$major" -gt 3 && return $1 + test "$minor" -gt 5 && return $1 + test "$release" -gt 4 && return $1 + return 0 +} + +open_kde() +{ + kfmclient exec "$1" + kfmclient_fix_exit_code $? + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_gnome() +{ + gnome-open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_xfce() +{ + exo-open "$1" + + if [ $? -eq 0 ]; then + exit_success + else + exit_failure_operation_failed + fi +} + +open_generic() +{ + IFS=":" + for browser in $BROWSER; do + if [ x"$browser" != x"" ]; then + + browser_with_arg=`echo "$browser" | sed s#%s#"$1"#` + + if [ x"$browser_with_arg" = x"$browser" ]; then "$browser" "$1"; + else $browser_with_arg; + fi + + if [ $? -eq 0 ]; then exit_success; + fi + fi + done + + exit_failure_operation_impossible "no method available for opening '$1'" +} + +[ x"$1" != x"" ] || exit_failure_syntax + +url= +while [ $# -gt 0 ] ; do + parm="$1" + shift + + case "$parm" in + -*) + exit_failure_syntax "unexpected option '$parm'" + ;; + + *) + if [ -n "$url" ] ; then + exit_failure_syntax "unexpected argument '$parm'" + fi + url="$parm" + ;; + esac +done + +if [ -z "${url}" ] ; then + exit_failure_syntax "file or URL argument missing" +fi + +detectDE + +if [ x"$DE" = x"" ]; then + # if BROWSER variable is not set, check some well known browsers instead + if [ x"$BROWSER" = x"" ]; then + BROWSER=firefox:mozilla:netscape + fi + DE=generic +fi + +case "$DE" in + kde) + open_kde "$url" + ;; + + gnome) + open_gnome "$url" + ;; + + xfce) + open_xfce "$url" + ;; + + generic) + open_generic "$url" + ;; + + *) + exit_failure_operation_impossible "no method available for opening '$url'" + ;; +esac diff --git a/src/doc/man/recoll.1 b/src/doc/man/recoll.1 new file mode 100644 index 00000000..41b3bb54 --- /dev/null +++ b/src/doc/man/recoll.1 @@ -0,0 +1,103 @@ +.\" $Id: recoll.1,v 1.3 2007-11-13 18:42:18 dockes Exp $ (C) 2005 J.F.Dockes\$ +.TH RECOLL 1 "8 January 2006" +.SH NAME +recoll \- user interface for the Recoll full text search system +.SH SYNOPSIS +.B recoll +[ +.B \-c + +] +[ +.B \-o +| +.B \-l +| +.B \-f +| +.B \-a +] +[ +.B \-t +] +[ +.B \-q + +] + +.B recoll +[ +.B \-c + +] + +.SH DESCRIPTION +In the first form, the +.B recoll +command will start the graphical user interface for querying the +.B Recoll +database. +.PP +On the first run, +.B recoll +will create the user configuration which can be customized +before starting the first indexation. +.PP +The +.B \-c +option specifies the configuration directory name, overriding the +default or $RECOLL_CONFDIR. +.PP +The +.B \-q +option can be used to specify an initial query on the command line. This +query will be interpreted by default as a query language string. +If +.B \-a +is specified, the query string will be interpreted as an +.I all words +simple search query. If +.B \-o +is specified, the query string will be interpreted as an +.I any word +simple search query. If +.B \-f +is specified, the query string will be interpreted as a +.I file name +simple search query. If +.B \-l +is specified, the query string will be interpreted as a +.I query language +simple search query. +.PP +If +.B \-t +is specified, or if +.B recoll +is called as +.B recollq +(through a link), the Graphical User Interface will not be started, and results +will be printed to the standard output. Additional options understood by +the +.B recollq +command may be specified in this case. These can control the output format +and the maximum number of results to be printed. +.PP +Please refer to online help for a full description. +.PP +In the second form, the +.B recoll +command can be used to start a native viewer for a document indexed by +Recoll. It will understand a final URL fragment (separated by a '#' +character) to indicate an +.I ipath +, the specifier for the part of the Recoll document access path which is is +internal to a container such as a mbox folder or a zip archive, and will, +if needed, create a temporary file to let a normal system utility display +the document. +.PP +The second form is mostly used for opening embedded documents from the +Ubuntu Unity Recoll lens. +.SH SEE ALSO +.PP +recollindex(1) recollq(1) recoll.conf(5) diff --git a/src/doc/man/recoll.conf.5 b/src/doc/man/recoll.conf.5 new file mode 100644 index 00000000..9123005a --- /dev/null +++ b/src/doc/man/recoll.conf.5 @@ -0,0 +1,619 @@ +.TH RECOLL.CONF 5 "14 November 2012" +.SH NAME +recoll.conf \- main personal configuration file for Recoll +.SH DESCRIPTION +This file defines the index configuration for the Recoll full-text search +system. +.LP +The system-wide configuration file is normally located inside +/usr/[local]/share/recoll/examples. Any parameter set in the common file +may be overridden by setting it in the personal configuration file, by default: +.IR $HOME/.recoll/recoll.conf +.LP +Please note while we try to keep this manual page reasonably up to date, it +will frequently lag the current state of the software. The best source of +information about the configuration are the comments in the system-wide +configuration file. + +.LP +A short extract of the file might look as follows: +.IP +.nf + +# Space-separated list of directories to index. +topdirs = ~/docs /usr/share/doc + +[~/somedirectory-with-utf8-txt-files] +defaultcharset = utf-8 + +.fi +.LP +There are three kinds of lines: +.RS +.IP \(bu +Comment or empty +.IP \(bu +Parameter affectation +.IP \(bu +Section definition +.RE +.LP +Empty lines or lines beginning with # are ignored. +.LP +Affectation lines are in the form 'name = value'. +.LP +Section lines allow redefining a parameter for a directory subtree. Some of +the parameters used for indexing are looked up hierarchically from the +more to the less specific. Not all parameters can be meaningfully +redefined, this is specified for each in the next section. +.LP +The tilde character (~) is expanded in file names to the name of the user's +home directory. +.LP +Where values are lists, white space is used for separation, and elements with +embedded spaces can be quoted with double-quotes. +.SH OPTIONS +.TP +.BI "topdirs = "string +Space-separated list of files or +directories to recursively index. Default to ~ (indexes +$HOME). You can use symbolic links in the list, they will be followed, +independantly of the value of the followLinks variable. +.TP +.BI "skippedNames = "string +Files and directories which should be ignored. +White space separated list of wildcard patterns (simple ones, not paths, +must contain no / ), which will be tested against file and directory +names. The list in the default configuration does not exclude hidden +directories (names beginning with a dot), which means that it may index +quite a few things that you do not want. On the other hand, email user +agents like Thunderbird usually store messages in hidden directories, and +you probably want this indexed. One possible solution is to have '.*' in +'skippedNames', and add things like '~/.thunderbird' '~/.evolution' to +'topdirs'. Not even the file names are indexed for patterns in this +list, see the 'noContentSuffixes' variable for an alternative approach +which indexes the file names. Can be redefined for any +subtree. +.TP +.BI "noContentSuffixes = "string +List of name endings (not necessarily dot-separated suffixes) for +which we don't try MIME type identification, and don't uncompress or +index content. Only the names will be indexed. This +complements the now obsoleted recoll_noindex list from the mimemap file, +which will go away in a future release (the move from mimemap to +recoll.conf allows editing the list through the GUI). This is different +from skippedNames because these are name ending matches only (not +wildcard patterns), and the file name itself gets indexed normally. This +can be redefined for subdirectories. +.TP +.BI "skippedPaths = "string +Paths we should not go into. Space-separated list of +wildcard expressions for filesystem paths. Can contain files and +directories. The database and configuration directories will +automatically be added. The expressions are matched using 'fnmatch(3)' +with the FNM_PATHNAME flag set by default. This means that '/' characters +must be matched explicitely. You can set 'skippedPathsFnmPathname' to 0 +to disable the use of FNM_PATHNAME (meaning that '/*/dir3' will match +'/dir1/dir2/dir3'). The default value contains the usual mount point for +removable media to remind you that it is a bad idea to have Recoll work +on these (esp. with the monitor: media gets indexed on mount, all data +gets erased on unmount). Explicitely adding '/media/xxx' to the topdirs +will override this. +.TP +.BI "skippedPathsFnmPathname = "bool +Set to 0 to +override use of FNM_PATHNAME for matching skipped +paths. +.TP +.BI "daemSkippedPaths = "string +skippedPaths equivalent specific to +real time indexing. This enables having parts of the tree +which are initially indexed but not monitored. If daemSkippedPaths is +not set, the daemon uses skippedPaths. +.TP +.BI "zipSkippedNames = "string +Space-separated list of wildcard expressions for names that should +be ignored inside zip archives. This is used directly by +the zip handler, and has a function similar to skippedNames, but works +independantly. Can be redefined for subdirectories. Supported by recoll +1.20 and newer. See +https://bitbucket.org/medoc/recoll/wiki/Filtering%20out%20Zip%20archive%20members + +.TP +.BI "followLinks = "bool +Follow symbolic links during +indexing. The default is to ignore symbolic links to avoid +multiple indexing of linked files. No effort is made to avoid duplication +when this option is set to true. This option can be set individually for +each of the 'topdirs' members by using sections. It can not be changed +below the 'topdirs' level. Links in the 'topdirs' list itself are always +followed. +.TP +.BI "indexedmimetypes = "string +Restrictive list of +indexed mime types. Normally not set (in which case all +supported types are indexed). If it is set, +only the types from the list will have their contents indexed. The names +will be indexed anyway if indexallfilenames is set (default). MIME +type names should be taken from the mimemap file. Can be redefined for +subtrees. +.TP +.BI "excludedmimetypes = "string +List of excluded MIME +types. Lets you exclude some types from indexing. Can be +redefined for subtrees. +.TP +.BI "compressedfilemaxkbs = "int +Size limit for compressed +files. We need to decompress these in a +temporary directory for identification, which can be wasteful in some +cases. Limit the waste. Negative means no limit. 0 results in no +processing of any compressed file. Default 50 MB. +.TP +.BI "textfilemaxmbs = "int +Size limit for text +files. Mostly for skipping monster +logs. Default 20 MB. +.TP +.BI "indexallfilenames = "bool +Index the file names of +unprocessed files Index the names of files the contents of +which we don't index because of an excluded or unsupported MIME +type. +.TP +.BI "usesystemfilecommand = "bool +Use a system command +for file MIME type guessing as a final step in file type +identification This is generally useful, but will usually +cause the indexing of many bogus 'text' files. See 'systemfilecommand' +for the command used. +.TP +.BI "systemfilecommand = "string +Command used to guess +MIME types if the internal methods fails This should be a +"file -i" workalike. The file path will be added as a last parameter to +the command line. 'xdg-mime' works better than the traditional 'file' +command, and is now the configured default (with a hard-coded fallback to +'file') +.TP +.BI "processwebqueue = "bool +Decide if we process the +Web queue. The queue is a directory where the Recoll Web +browser plugins create the copies of visited pages. +.TP +.BI "textfilepagekbs = "int +Page size for text +files. If this is set, text/plain files will be divided +into documents of approximately this size. Will reduce memory usage at +index time and help with loading data in the preview window at query +time. Particularly useful with very big files, such as application or +system logs. Also see textfilemaxmbs and +compressedfilemaxkbs. +.TP +.BI "membermaxkbs = "int +Size limit for archive +members. This is passed to the filters in the environment +as RECOLL_FILTER_MAXMEMBERKB. +.TP +.BI "indexStripChars = "bool +Decide if we store +character case and diacritics in the index. If we do, +searches sensitive to case and diacritics can be performed, but the index +will be bigger, and some marginal weirdness may sometimes occur. The +default is a stripped index. When using multiple indexes for a search, +this parameter must be defined identically for all. Changing the value +implies an index reset. +.TP +.BI "nonumbers = "bool +Decides if terms will be +generated for numbers. For example "123", "1.5e6", +192.168.1.4, would not be indexed if nonumbers is set ("value123" would +still be). Numbers are often quite interesting to search for, and this +should probably not be set except for special situations, ie, scientific +documents with huge amounts of numbers in them, where setting nonumbers +will reduce the index size. This can only be set for a whole index, not +for a subtree. +.TP +.BI "dehyphenate = "bool +Determines if we index +'coworker' also when the input is 'co-worker'. This is new +in version 1.22, and on by default. Setting the variable to off allows +restoring the previous behaviour. +.TP +.BI "nocjk = "bool +Decides if specific East Asian +(Chinese Korean Japanese) characters/word splitting is turned +off. This will save a small amount of CPU if you have no CJK +documents. If your document base does include such text but you are not +interested in searching it, setting nocjk may be a +significant time and space saver. +.TP +.BI "cjkngramlen = "int +This lets you adjust the size of +n-grams used for indexing CJK text. The default value of 2 is +probably appropriate in most cases. A value of 3 would allow more precision +and efficiency on longer words, but the index will be approximately twice +as large. +.TP +.BI "indexstemminglanguages = "string +Languages for which to create stemming expansion +data. Stemmer names can be found by executing 'recollindex +-l', or this can also be set from a list in the GUI. +.TP +.BI "defaultcharset = "string +Default character +set. This is used for files which do not contain a +character set definition (e.g.: text/plain). Values found inside files, +e.g. a 'charset' tag in HTML documents, will override it. If this is not +set, the default character set is the one defined by the NLS environment +($LC_ALL, $LC_CTYPE, $LANG), or ultimately iso-8859-1 (cp-1252 in fact). +If for some reason you want a general default which does not match your +LANG and is not 8859-1, use this variable. This can be redefined for any +sub-directory. +.TP +.BI "unac_except_trans = "string +A list of characters, +encoded in UTF-8, which should be handled specially +when converting text to unaccented lowercase. For +example, in Swedish, the letter a with diaeresis has full alphabet +citizenship and should not be turned into an a. +Each element in the space-separated list has the special character as +first element and the translation following. The handling of both the +lowercase and upper-case versions of a character should be specified, as +appartenance to the list will turn-off both standard accent and case +processing. The value is global and affects both indexing and querying. +Examples: +Swedish: +unac_except_trans = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl åå Åå +. German: +unac_except_trans = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl +In French, you probably want to decompose oe and ae and nobody would type +a German ß +unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl +. The default for all until someone protests follows. These decompositions +are not performed by unac, but it is unlikely that someone would type the +composed forms in a search. +unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl +.TP +.BI "maildefcharset = "string +Overrides the default +character set for email messages which don't specify +one. This is mainly useful for readpst (libpst) dumps, +which are utf-8 but do not say so. +.TP +.BI "localfields = "string +Set fields on all files +(usually of a specific fs area). Syntax is the usual: +name = value ; attr1 = val1 ; [...] +value is empty so this needs an initial semi-colon. This is useful, e.g., +for setting the rclaptg field for application selection inside +mimeview. +.TP +.BI "testmodifusemtime = "bool +Use mtime instead of +ctime to test if a file has been modified. The time is used +in addition to the size, which is always used. +Setting this can reduce re-indexing on systems where extended attributes +are used (by some other application), but not indexed, because changing +extended attributes only affects ctime. +Notes: +- This may prevent detection of change in some marginal file rename cases +(the target would need to have the same size and mtime). +- You should probably also set noxattrfields to 1 in this case, except if +you still prefer to perform xattr indexing, for example if the local +file update pattern makes it of value (as in general, there is a risk +for pure extended attributes updates without file modification to go +undetected). Perform a full index reset after changing this. + +.TP +.BI "noxattrfields = "bool +Disable extended attributes +conversion to metadata fields. This probably needs to be +set if testmodifusemtime is set. +.TP +.BI "metadatacmds = "string +Define commands to +gather external metadata, e.g. tmsu tags. +There can be several entries, separated by semi-colons, each defining +which field name the data goes into and the command to use. Don't forget the +initial semi-colon. All the field names must be different. You can use +aliases in the "field" file if necessary. +As a not too pretty hack conceded to convenience, any field name +beginning with "rclmulti" will be taken as an indication that the command +returns multiple field values inside a text blob formatted as a recoll +configuration file ("fieldname = fieldvalue" lines). The rclmultixx name +will be ignored, and field names and values will be parsed from the data. +Example: metadatacmds = ; tags = tmsu tags %f; rclmulti1 = cmdOutputsConf %f + +.TP +.BI "cachedir = "dfn +Top directory for Recoll data. Recoll data +directories are normally located relative to the configuration directory +(e.g. ~/.recoll/xapiandb, ~/.recoll/mboxcache). If 'cachedir' is set, the +directories are stored under the specified value instead (e.g. if +cachedir is ~/.cache/recoll, the default dbdir would be +~/.cache/recoll/xapiandb). This affects dbdir, webcachedir, +mboxcachedir, aspellDicDir, which can still be individually specified to +override cachedir. Note that if you have multiple configurations, each +must have a different cachedir, there is no automatic computation of a +subpath under cachedir. +.TP +.BI "maxfsoccuppc = "int +Maximum file system occupation +over which we stop indexing. The value is a percentage, +corresponding to what the "Capacity" df output column shows. The default +value is 0, meaning no checking. +.TP +.BI "xapiandb = "dfn +Xapian database directory +location. This will be created on first indexing. If the +value is not an absolute path, it will be interpreted as relative to +cachedir if set, or the configuration directory (-c argument or +$RECOLL_CONFDIR). If nothing is specified, the default is then +~/.recoll/xapiandb/ +.TP +.BI "idxstatusfile = "fn +Name of the scratch file where the indexer process updates its +status. Default: idxstatus.txt inside the configuration +directory. +.TP +.BI "mboxcachedir = "dfn +Directory location for storing mbox message offsets cache +files. This is normally 'mboxcache' under cachedir if set, +or else under the configuration directory, but it may be useful to share +a directory between different configurations. +.TP +.BI "mboxcacheminmbs = "int +Minimum mbox file size over which we cache the offsets. There is really no sense in caching offsets for small files. The +default is 5 MB. +.TP +.BI "webcachedir = "dfn +Directory where we store the archived web pages. This is only used by the web history indexing code +Default: cachedir/webcache if cachedir is set, else +$RECOLL_CONFDIR/webcache +.TP +.BI "webcachemaxmbs = "int +Maximum size in MB of the Web archive. This is only used by the web history indexing code. +Default: 40 MB. +Reducing the size will not physically truncate the file. +.TP +.BI "webqueuedir = "fn +The path to the Web indexing queue. This is +hard-coded in the plugin as ~/.recollweb/ToIndex so there should be no +need or possibility to change it. +.TP +.BI "aspellDicDir = "dfn +Aspell dictionary storage directory location. The +aspell dictionary (aspdict.(lang).rws) is normally stored in the +directory specified by cachedir if set, or under the configuration +directory. +.TP +.BI "filtersdir = "dfn +Directory location for executable input handlers. If +RECOLL_FILTERSDIR is set in the environment, we use it instead. Defaults +to $prefix/share/recoll/filters. Can be redefined for +subdirectories. +.TP +.BI "iconsdir = "dfn +Directory location for icons. The only reason to +change this would be if you want to change the icons displayed in the +result list. Defaults to $prefix/share/recoll/images +.TP +.BI "idxflushmb = "int +Threshold (megabytes of new data) where we flush from memory to +disk index. Setting this allows some control over memory +usage by the indexer process. A value of 0 means no explicit flushing, +which lets Xapian perform its own thing, meaning flushing every +$XAPIAN_FLUSH_THRESHOLD documents created, modified or deleted: as memory +usage depends on average document size, not only document count, the +Xapian approach is is not very useful, and you should let Recoll manage +the flushes. The default value of idxflushmb is 10 MB, and may be a bit +low. If you are looking for maximum speed, you may want to experiment +with values between 20 and +80. In my experience, values beyond 100 are always counterproductive. If +you find otherwise, please drop me a note. +.TP +.BI "filtermaxseconds = "int +Maximum external filter execution time in +seconds. Default 1200 (20mn). Set to 0 for no limit. This +is mainly to avoid infinite loops in postscript files +(loop.ps) +.TP +.BI "filtermaxmbytes = "int +Maximum virtual memory space for filter processes +(setrlimit(RLIMIT_AS)), in megabytes. Note that this +includes any mapped libs (there is no reliable Linux way to limit the +data space only), so we need to be a bit generous here. Anything over +2000 will be ignored on 32 bits machines. +.TP +.BI "thrQSizes = "string +Stage input queues configuration. There are three +internal queues in the indexing pipeline stages (file data extraction, +terms generation, index update). This parameter defines the queue depths +for each stage (three integer values). If a value of -1 is given for a +given stage, no queue is used, and the thread will go on performing the +next stage. In practise, deep queues have not been shown to increase +performance. Default: a value of 0 for the first queue tells Recoll to +perform autoconfiguration based on the detected number of CPUs (no need +for the two other values in this case). Use thrQSizes = -1 -1 -1 to +disable multithreading entirely. +.TP +.BI "thrTCounts = "string +Number of threads used for each indexing stage. The +three stages are: file data extraction, terms generation, index +update). The use of the counts is also controlled by some special values +in thrQSizes: if the first queue depth is 0, all counts are ignored +(autoconfigured); if a value of -1 is used for a queue depth, the +corresponding thread count is ignored. It makes no sense to use a value +other than 1 for the last stage because updating the Xapian index is +necessarily single-threaded (and protected by a mutex). +.TP +.BI "loglevel = "int +Log file verbosity 1-6. A value of 2 will print +only errors and warnings. 3 will print information like document updates, +4 is quite verbose and 6 very verbose. +.TP +.BI "logfilename = "fn +Log file destination. Use 'stderr' (default) to write to the +console. +.TP +.BI "idxloglevel = "int +Override loglevel for the indexer. +.TP +.BI "idxlogfilename = "fn +Override logfilename for the indexer. +.TP +.BI "daemloglevel = "int +Override loglevel for the indexer in real time +mode. The default is to use the idx... values if set, else +the log... values. +.TP +.BI "daemlogfilename = "fn +Override logfilename for the indexer in real time +mode. The default is to use the idx... values if set, else +the log... values. +.TP +.BI "idxrundir = "dfn +Indexing process current directory. The input +handlers sometimes leave temporary files in the current directory, so it +makes sense to have recollindex chdir to some temporary directory. If the +value is empty, the current directory is not changed. If the +value is (literal) tmp, we use the temporary directory as set by the +environment (RECOLL_TMPDIR else TMPDIR else /tmp). If the value is an +absolute path to a directory, we go there. +.TP +.BI "checkneedretryindexscript = "fn +Script used to heuristically check if we need to retry indexing +files which previously failed. The default script checks +the modified dates on /usr/bin and /usr/local/bin. A relative path will +be looked up in the filters dirs, then in the path. Use an absolute path +to do otherwise. +.TP +.BI "recollhelperpath = "string +Additional places to search for helper executables. This is only used on Windows for now. +.TP +.BI "idxabsmlen = "int +Length of abstracts we store while indexing. Recoll stores an abstract for each indexed file. +The text can come from an actual 'abstract' section in the +document or will just be the beginning of the document. It is stored in +the index so that it can be displayed inside the result lists without +decoding the original file. The idxabsmlen parameter +defines the size of the stored abstract. The default value is 250 +bytes. The search interface gives you the choice to display this stored +text or a synthetic abstract built by extracting text around the search +terms. If you always prefer the synthetic abstract, you can reduce this +value and save a little space. +.TP +.BI "idxmetastoredlen = "int +Truncation length of stored metadata fields. This +does not affect indexing (the whole field is processed anyway), just the +amount of data stored in the index for the purpose of displaying fields +inside result lists or previews. The default value is 150 bytes which +may be too low if you have custom fields. +.TP +.BI "aspellLanguage = "string +Language definitions to use when creating the aspell +dictionary. The value must match a set of aspell language +definition files. You can type "aspell dicts" to see a list The default +if this is not set is to use the NLS environment to guess the +value. +.TP +.BI "aspellAddCreateParam = "string +Additional option and parameter to aspell dictionary creation +command. Some aspell packages may need an additional option +(e.g. on Debian Jessie: --local-data-dir=/usr/lib/aspell). See Debian bug +772415. +.TP +.BI "aspellKeepStderr = "bool +Set this to have a look at aspell dictionary creation +errors. There are always many, so this is mostly for +debugging. +.TP +.BI "noaspell = "bool +Disable aspell use. The aspell dictionary generation +takes time, and some combinations of aspell version, language, and local +terms, result in aspell crashing, so it sometimes makes sense to just +disable the thing. +.TP +.BI "monauxinterval = "int +Auxiliary database update interval. The real time +indexer only updates the auxiliary databases (stemdb, aspell) +periodically, because it would be too costly to do it for every document +change. The default period is one hour. +.TP +.BI "monixinterval = "int +Minimum interval (seconds) between processings of the indexing +queue. The real time indexer does not process each event +when it comes in, but lets the queue accumulate, to diminish overhead and +to aggregate multiple events affecting the same file. Default 30 +S. +.TP +.BI "mondelaypatterns = "string +Timing parameters for the real time indexing. Definitions for files which get a longer delay before reindexing +is allowed. This is for fast-changing files, that should only be +reindexed once in a while. A list of wildcardPattern:seconds pairs. The +patterns are matched with fnmatch(pattern, path, 0) You can quote entries +containing white space with double quotes (quote the whole entry, not the +pattern). The default is empty. +Example: mondelaypatterns = *.log:20 "*with spaces.*:30" +.TP +.BI "monioniceclass = "int +ionice class for the real time indexing process On platforms where this is supported. The default value is +3. +.TP +.BI "monioniceclassdata = "string +ionice class parameter for the real time indexing process. On platforms where this is supported. The default is +empty. +.TP +.BI "autodiacsens = "bool +auto-trigger diacritics sensitivity (raw index only). IF the index is not stripped, decide if we automatically trigger +diacritics sensitivity if the search term has accented characters (not in +unac_except_trans). Else you need to use the query language and the "D" +modifier to specify diacritics sensitivity. Default is no. +.TP +.BI "autocasesens = "bool +auto-trigger case sensitivity (raw index only). IF +the index is not stripped (see indexStripChars), decide if we +automatically trigger character case sensitivity if the search term has +upper-case characters in any but the first position. Else you need to use +the query language and the "C" modifier to specify character-case +sensitivity. Default is yes. +.TP +.BI "maxTermExpand = "int +Maximum query expansion count +for a single term (e.g.: when using wildcards). This only +affects queries, not indexing. We used to not limit this at all (except +for filenames where the limit was too low at 1000), but it is +unreasonable with a big index. Default 10000. +.TP +.BI "maxXapianClauses = "int +Maximum number of clauses +we add to a single Xapian query. This only affects queries, +not indexing. In some cases, the result of term expansion can be +multiplicative, and we want to avoid eating all the memory. Default +50000. +.TP +.BI "snippetMaxPosWalk = "int +Maximum number of positions we walk while populating a snippet for +the result list. The default of 1,000,000 may be +insufficient for very big documents, the consequence would be snippets +with possibly meaning-altering missing words. +.TP +.BI "pdfocr = "bool +Attempt OCR of PDF files with no text content if both tesseract and +pdftoppm are installed. The default is off because OCR is so +very slow. +.TP +.BI "pdfattach = "bool +Enable PDF attachment extraction by executing pdftk (if +available). This is +normally disabled, because it does slow down PDF indexing a bit even if +not one attachment is ever found. +.TP +.BI "mhmboxquirks = "string +Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for the directory where the email mbox files are +stored. + +.SH SEE ALSO +.PP +recollindex(1) recoll(1) diff --git a/src/doc/man/recollindex.1 b/src/doc/man/recollindex.1 new file mode 100644 index 00000000..2340fd83 --- /dev/null +++ b/src/doc/man/recollindex.1 @@ -0,0 +1,317 @@ +.\" $Id: recollindex.1,v 1.7 2008-09-05 10:25:54 dockes Exp $ (C) 2005 J.F.Dockes\$ +.TH RECOLLINDEX 1 "8 January 2006" +.SH NAME +recollindex \- indexing command for the Recoll full text search system +.SH SYNOPSIS +.B recollindex \-h +.br +.B recollindex +[ +.B \-c + +] +[ +.B \-z|\-Z +] +[ +.B \-k +] +.br +.B recollindex +[ +.B \-c + +] +.B \-m +[ +.B \-w + +] +[ +.B \-D +] +[ +.B \-x +] +[ +.B \-C +] +[ +.B \-n|-k +] +.br +.B recollindex +[ +.B \-c + +] +.B \-i +[ +.B \-Z +] +[ +.B \-k +] +[ +.B \-f +] +[] +.br +.B recollindex +[ +.B \-c + +] +.B \-r +[ +.B \-Z +] +[ +.B \-K +] +[ +.B \-e +] +[ +.B \-f +] +[ +.B \-p +pattern +] + +.br +.B recollindex +[ +.B \-c + +] +.B \-e +[] +.br +.B recollindex +[ +.B \-c + +] +.B \-l +.br +.B recollindex +[ +.B \-c + +] +.B \-s + +.br +.B recollindex +[ +.B \-c + +] +.B \-S +.br +.B recollindex +[ +.B \-c + +] +.B \-E + +.SH DESCRIPTION +The +.B recollindex +utility allows you to perform indexing operations for the Recoll text +search system. +.PP +As indexing can sometimes take a long time, the command can be interrupted +by sending an interrupt (Ctrl-C, SIGINT) or terminate (SIGTERM) +signal. Some time may elapse before the process exits, because it needs to +properly flush and close the index. This can also be done from the recoll +GUI (menu entry: File/Stop_Indexing). After such an interruption, the index +will be somewhat inconsistent because some operations which are normally +performed at the end of the indexing pass will have been skipped (for +example, the stemming and spelling databases will be inexistant or out of +date). You just need to restart indexing at a later time to restore +consistency. The indexing will restart at the interruption point (the full +file tree will be traversed, but files that were indexed up to the +interruption and for which the index is still up to date will not need to +be reindexed). +.PP +The +.B \-c +option specifies the configuration directory name, overriding the +default or $RECOLL_CONFDIR. +.PP +There are several modes of operation. +.PP +The normal mode will index the set of files described in the configuration +file +.B recoll.conf. +This will incrementally update the database with files that changed since +the last run. If option +.B \-z +is given, the database will be erased before starting. If option +.B \-Z +is given, the database will not be reset, but all files will be considered +as needing reindexing (in place reset). +.PP +As of version 1.21, +.B recollindex +usually does not process again files which previously failed to index (for +example because of a missing helper program). If option +.B \-k +is given, +.B recollindex +will try again to process all failed files. Please note that +.B recollindex +may also decide to retry failed files if the auxiliary checking script +defined by the "checkneedretryindexscript" configuration variable indicates +that this should happen. +.PP +If option +.B +\-m +is given, recollindex is started for real time monitoring, using the +file system monitoring package it was configured for (either fam, gamin, or +inotify). This mode must have been explicitly configured when building the +package, it is not available by default. The program will normally detach +from the controlling terminal and become a daemon. If option +.B +\-D +is given, it will stay in the foreground. Option +.B +\-w + can be used to specify that the program should sleep for the +specified time before indexing begins. The default value is 60. The daemon +normally monitors the X11 session and exits when it is reset. +Option +.B +\-x +disables this X11 session monitoring (daemon will stay alive even if it +cannot connect to the X11 server). You need to use this too if you use the +daemon without an X11 context. You can use option +.B +\-n +to skip the initial incrementing pass which is normally performed before +monitoring starts. Once monitoring is started, the daemon normally monitors +the configuration and restarts from scratch if a change is made. You can +disable this with option +.B +\-C +.PP +.B recollindex \-i +will index individual files into the database. The stem expansion and +aspell databases will not be updated. The skippedPaths and skippedNames +configuration variables will be used, so that some files may be +skipped. You can tell recollindex to ignore skippedPaths and skippedNames +by setting the +.B +\-f +option. This allows fully custom file selection for a given subtree, +for which you would add the top directory to skippedPaths, and use any +custom tool to generate the file list (ie: a tool from a source code +control system). +.PP +.PP +.B recollindex \-e +will erase data for individual files from the database. The stem expansion +databases will not be updated. +.PP +Options +.B +\-i +and +.B +\-e +can be combined. This will first perform the purge, then the indexing. +.PP +With options +.B \-i +or +.B \-e +, if no file names are given on the command line, they +will be read from stdin, so that you could for example run: +.PP +find /path/to/dir \-print | recollindex \-e \-i +.PP +to force the reindexing of a directory tree (which has to exist inside the +file system area defined by +.I topdirs +in recoll.conf). You could mostly accomplish the same thing with +.PP +find /path/to/dir \-print | recollindex \-Z \-i +.PP +The latter will perform a less thorough job of purging stale sub-documents +though. +.PP +.B recollindex \-r +mostly works like +.B \-i +, but the parameter is a single directory, which will +be recursively updated. This mostly does nothing more than +.B find topdir | recollindex \-i +but it may be more convenient to use when started from another +program. This retries failed files by default, use option +.B \-K +to change. One or multiple +.B \-p +options can be used to set shell-type selection patterns (e.g.: *.pdf). +.PP +.B recollindex \-l +will list the names of available language stemmers. +.PP +.B recollindex \-s +will build the stem expansion database for a given language, which may or +may not be part of the list in the configuration file. If the language is +not part of the configuration, the stem expansion database will be deleted +at the end of the next normal indexing run. You can get the list of stemmer +names from the +.B recollindex \-l +command. Note that this is mostly for experimental use, the normal way to +add a stemming language is to set it in the configuration, either by +editing "recoll.conf" or by using the GUI indexing configuration dialog. +.br +At the time of this writing, the following languages +are recognized (out of Xapian's stem.h): +.IP \(bu +danish +.IP \(bu +dutch +.IP \(bu +english Martin Porter's 2002 revision of his stemmer +.IP \(bu +english_lovins Lovin's stemmer +.IP \(bu +english_porter Porter's stemmer as described in his 1980 paper +.IP \(bu +finnish +.IP \(bu +french +.IP \(bu +german +.IP \(bu +italian +.IP \(bu +norwegian +.IP \(bu +portuguese +.IP \(bu +russian +.IP \(bu +spanish +.IP \(bu +swedish +.PP +.B recollindex \-S +will rebuild the phonetic/orthographic index. This feature uses the +.B aspell +package, which must be installed on the system. +.PP +.B recollindex \-E +will check the configuration file for topdirs and other relevant paths +existence (to help catch typos). + +.SH SEE ALSO +.PP +recoll(1) recoll.conf(5) diff --git a/src/doc/man/recollq.1 b/src/doc/man/recollq.1 new file mode 100644 index 00000000..c698284f --- /dev/null +++ b/src/doc/man/recollq.1 @@ -0,0 +1,148 @@ +.\" $Id: recollq.1,v 1.1 2007-11-13 10:07:35 dockes Exp $ (C) 2005 J.F.Dockes\$ +.TH RECOLLQ 1 "13 November 2007" +.SH NAME +recollq \- command line / standard output Recoll query command. +.SH SYNOPSIS +.B recollq +[ +.B \-c + +] +[ +.B \-o +| +.B \-f +| +.B \-a +] +[ +.B \-b +] +[ +.B \-d +] +[ +.B \-A +] +[ +.B \-e +] +[ +.B \-m +] +[ +.B \-n +<[first-]cnt> +] +[ +.B \-Q +] +[ +.B \-s + +] +[ +.B \-S + +] +[ +.B \-D +] +[ +.B \-i + +] +[ +.B \-F + +] + + +.B recollq \-P + +.SH DESCRIPTION +The +.B recollq +command will execute the Recoll query specified on the command line and +print the results to the standard output. It is primarily designed for +diagnostics, or piping the data to some other program. The basic format and +its variations can be useful for command line querying. The \-F option +should exclusively be used for using the output data in another program, as +it is the only one for which output is guaranteed to be fully parseable. +.PP +The +.B \-c +option specifies the configuration directory name, overriding the +default or $RECOLL_CONFDIR. +.PP +The query string is built by concatenating all arguments found at the end +of the command line (after the options). It will be interpreted by default +as a query language string. Quoting should be used as needed to escape +characters that might be interpreted by the shell (ie: wildcards). +.B \-a +is specified, the query string will be interpreted as an +.I all words +simple search query. If +.B \-o +is specified, the query string will be interpreted as an +.I any word +simple search query. If +.B \-f +is specified, the query string will be interpreted as a +.I file name +simple search query. +.PP +.B \-b +(basic) can be specified to only print the result urls in the output +stream. +.PP +If +.B \-d +is set, the text for the result files contents will be dumped to stdout. +.PP +If +.B \-m +is set, the whole metadata array will be dumped for each document. +.PP +If +.B \-A +is set, the document abstracts will be printed. +.PP +.B \-S + +sorts the results according to the specified field. Use +.B \-D +for descending order. +.PP +.B \-n + +can be used to set the maximum number of results that should be +printed. The default is 2000. Use a value of 0 for no limit. +.PP +.B \-s + +selects the word stemming language. The value should match an existing +stemming database (as set in the configuration or added with recollindex \-s). +.PP +.B \-i + +adds the specified Xapian index to the set used for the query. Can be +specified multiple times. +.PP +.B \-F + +should be used for piping the data to another program. After 2 initial +lines showing the actual query and the estimated result counts, it will +print one line for each result document. Each line will have +exactly the fields requested on the command line. Fields are encoded in +base64 and separated by one space character. Empty fields are indicated by +consecutive space characters. There is one additional space character at +the end of each line. +.PP +.B recollq \-P +(Period) will print the minimum and maximum modification years for +documents in the index. + +.SH SEE ALSO +.PP +recollindex(1) recollq(1) recoll.conf(5) diff --git a/src/doc/prog/Doxyfile b/src/doc/prog/Doxyfile new file mode 100644 index 00000000..d57dced8 --- /dev/null +++ b/src/doc/prog/Doxyfile @@ -0,0 +1,1212 @@ +# Doxyfile 1.4.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Recoll + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the progam writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../src top.txt filters.txt + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = .moc .ui + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = docprog_html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/src/doc/prog/Makefile b/src/doc/prog/Makefile new file mode 100644 index 00000000..926acf16 --- /dev/null +++ b/src/doc/prog/Makefile @@ -0,0 +1,5 @@ +documentation: + doxygen Doxyfile +clean: + rm -f docprog_html/* + diff --git a/src/doc/prog/filters.txt b/src/doc/prog/filters.txt new file mode 100644 index 00000000..67cff502 --- /dev/null +++ b/src/doc/prog/filters.txt @@ -0,0 +1,47 @@ +/*!@filters + +\page filters About filters + +\section filtintro Overview + +Before a document can be processed either for indexing or previewing, it +must be translated into an internal common format. + +The MimeHandler class defines the virtual interface for filters. There are +derived classes for text, html (MimeHandlerHtml), and mail folders +(MimeHandlerMail) + +There is also a derived class (MimeHandlerExec) that will execute an +external program to translate the document to simple html (to be further +processed by MimeHandlerHtml). + +To extend Recoll for a new document type, you may either subclass the +MimeHandler class (look at one of the existing subclasses), or write an +external filter, which will probably be the simpler solution in most cases. + +\section extfilts External filters + +Filters are programs (usually shell scripts) that will turn a document of +foreign type into something that Recoll can understand. HTML was chosen as +a pivot format for its ability to carry structured information. + +The meta-information tags that Recoll will use at the moment are the +following: + + - title + - charset + - keywords + - description + +For an example, you can take a look at the rclsoff filter which translates +openoffice documents. + +The filter is executed with the input file name as a parameter and should +output the result to stdout. + +\section extassoc Associating a filter to a mime type + +This is done in the mimeconf configuration file. Take a look at the file, +the format is self-explanatory. + +*/ diff --git a/src/doc/prog/top.txt b/src/doc/prog/top.txt new file mode 100644 index 00000000..becb8c3b --- /dev/null +++ b/src/doc/prog/top.txt @@ -0,0 +1,20 @@ +/*!@mainpage Recoll: A personal/desktop text-search program +\author email address: jfd@recoll.org + +\section intro Introduction + +Home page: http://www.recoll.org + +This is the documentation for Recoll, a personal text search tool. Recoll +is written in C++, has a QT-based gui and uses the
Xapian full text search engine. + +Recoll supports a number of document types, the decoding of which is either +performed with internal code or an externally executed, program. + +It should be relatively easy to write a new filter for some yet unsupported +file type, and the documentation for this is found here: Writing input filters + +*/ + diff --git a/src/doc/user/00README.txt b/src/doc/user/00README.txt new file mode 100644 index 00000000..892a3b85 --- /dev/null +++ b/src/doc/user/00README.txt @@ -0,0 +1,30 @@ += Building the Recoll user manual + +The Recoll user manual used to be written in DocBook SGML and used the +FreeBSD doc toolchain to produce the output formats. This had the advantage +of an easy way to produce all formats including a PDF manual, but presented +two problems: + + - Dependancy on the FreeBSD platform. + - No support for UTF-8 (last I looked), only latin1. + +The manual is now compatible with XML. There is a small script that +converts the SGML (but XML-compatible) manual into XML (changes the header, +mostly). The SGML version is still the primary one. + +Beyond fixing a few missing closing tags, the main change that had to be +made was to make the anchors explicitly upper-case because the SGML +toolchain converts them to upper-case and the XML one does not, so the only +way to have compatibility is to make them upper-case in the first place. + +We initially had a problem for producing the PDF manual, which motivated +keeping the SGML version for producing the PDF with the FreeBSD SGML +toolchain. This problem is now solved with dblatex, so that the SGML +version now has little reason to persist and it will go away at some point +in the future. + +Asciidoc would also be a candidate as the source format, because it can +easily produce docbook, so the future will probably be: + +asciidoc->docbook-xml-> html + -> pdf diff --git a/src/doc/user/Makefile b/src/doc/user/Makefile new file mode 100644 index 00000000..14b6c9c2 --- /dev/null +++ b/src/doc/user/Makefile @@ -0,0 +1,43 @@ +# Wherever docbook.xsl and chunk.xsl live +# Fbsd +#XSLDIR="/usr/local/share/xsl/docbook/" +# Mac +#XSLDIR="/opt/local/share/xsl/docbook-xsl/" +#Linux +XSLDIR="/usr/share/xml/docbook/stylesheet/docbook-xsl/" + + +# Options common to the single-file and chunked versions +commonoptions=--stringparam section.autolabel 1 \ + --stringparam section.autolabel.max.depth 3 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam autotoc.label.in.hyperlink 0 \ + --stringparam abstract.notitle.enabled 1 \ + --stringparam html.stylesheet docbook-xsl.css \ + --stringparam generate.toc "book toc,title,figure,table,example,equation" + + +# index.html chunk format target replaced by nicer webhelp (needs separate +# make) in webhelp/ subdir +all: usermanual.html webh usermanual.pdf + +webh: + make -C webhelp + +usermanual.html: usermanual.xml + xsltproc --xinclude ${commonoptions} \ + -o tmpfile.html "${XSLDIR}/html/docbook.xsl" $< + -tidy -indent tmpfile.html > usermanual.html + rm -f tmpfile.html + +index.html: usermanual.xml + xsltproc ${commonoptions} \ + --stringparam use.id.as.filename 1 \ + --stringparam root.filename index \ + "${XSLDIR}/html/chunk.xsl" $< + +usermanual.pdf: usermanual.xml + dblatex $< + +clean: + rm -f RCL.*.html usermanual.pdf usermanual.html index.html tmpfile.html diff --git a/src/doc/user/docbook-xsl.css b/src/doc/user/docbook-xsl.css new file mode 100644 index 00000000..8cc0a8b2 --- /dev/null +++ b/src/doc/user/docbook-xsl.css @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2001, 2003, 2010 The FreeBSD Documentation Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: doc/share/misc/docbook.css,v 1.15 2010/03/20 04:15:01 hrs Exp $ + */ + +body address { + line-height: 1.3; + margin: .6em 0; +} + +body blockquote { + margin-top: .75em; + line-height: 1.5; + margin-bottom: .75em; +} + +html body { + margin: 1em 8% 1em 10%; + line-height: 1.2; +} + +.legalnotice { + font-size: small; + font-variant: small-caps; +} + +body div { + margin: 0; +} + +dl { + margin: .8em 0; + line-height: 1.2; +} + +body form { + margin: .6em 0; +} + +h1, h2, h3, h4, h5, h6, +div.example p b, +.question, +div.table p b, +div.procedure p b { + color: #990000; +} + +body h1, body h2, body h3, body h4, body h5, body h6 { + line-height: 1.3; + margin-left: 0; +} + +body h1, body h2 { + margin: .8em 0 0 -4%; +} + +body h3, body h4 { + margin: .8em 0 0 -3%; +} + +body h5 { + margin: .8em 0 0 -2%; +} + +body h6 { + margin: .8em 0 0 -1%; +} + +body hr { + margin: .6em; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #cecece; +} + +body img.navheader { + margin: 0 0 0 -4%; +} + +ol { + margin: 0 0 0 5%; + line-height: 1.2; +} + +body pre { + margin: .75em 0; + line-height: 1.0; + font-family: monospace; +} + +body td, body th { + line-height: 1.2; +} + +ul, body dir, body menu { + margin: 0 0 0 5%; + line-height: 1.2; +} + +html { + margin: 0; + padding: 0; +} + +body p b.application { + color: #000000; +} +body p span.application { + font-weight: bold; + color: #000000; +} + +.filename { + color: #007a00; +} + +.guimenu, .guimenuitem, .guisubmenu, +.guilabel, .interface, +.shortcut, .shortcut .keycap { + font-weight: bold; +} + +.guibutton { + background-color: #cfcfcf; + padding: 2px; +} + +.accel { + background-color: #f0f0f0; + text-decoration: underline; +} + +.screen { + padding: 1ex; +} + +.programlisting { + padding: 1ex; + background-color: #eee; + border: 1px solid #ccc; +} + +@media screen { /* hide from ie3 */ + a[href]:hover { background: #ffa } +} + +blockquote.note { + color: #222; + background: #eee; + border: 1px solid #ccc; + padding: 0.4em 0.4em; + width: 85%; +} + +blockquote.tip { + color: #004f00; + background: #d8ecd6; + border: 1px solid green; + padding: 0.2em 2em; + width: 85%; +} + +blockquote.important { + font-style:italic; + border: 1px solid #a00; + border-left: 12px solid #c00; + padding: 0.1em 1em; +} + +blockquote.warning { + color: #9f1313; + background: #f8e8e8; + border: 1px solid #e59595; + padding: 0.2em 2em; + width: 85%; +} + +.example { + background: #fefde6; + border: 1px solid #f1bb16; + margin: 1em 0; + padding: 0.2em 2em; + width: 90%; +} + +.informaltable table.calstable tr td { + padding-left: 1em; + padding-right: 1em; +} diff --git a/src/doc/user/docbook.css b/src/doc/user/docbook.css new file mode 100644 index 00000000..3d40fa70 --- /dev/null +++ b/src/doc/user/docbook.css @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2001, 2003, 2010 The FreeBSD Documentation Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: doc/share/misc/docbook.css,v 1.15 2010/03/20 04:15:01 hrs Exp $ + */ + +BODY ADDRESS { + line-height: 1.3; + margin: .6em 0; +} + +BODY BLOCKQUOTE { + margin-top: .75em; + line-height: 1.5; + margin-bottom: .75em; +} + +HTML BODY { + margin: 1em 8% 1em 10%; + line-height: 1.2; +} + +.LEGALNOTICE { + font-size: small; + font-variant: small-caps; +} + +BODY DIV { + margin: 0; +} + +DL { + margin: .8em 0; + line-height: 1.2; +} + +BODY FORM { + margin: .6em 0; +} + +H1, H2, H3, H4, H5, H6, +DIV.EXAMPLE P B, +.QUESTION, +DIV.TABLE P B, +DIV.PROCEDURE P B { + color: #990000; +} + +BODY H1, BODY H2, BODY H3, BODY H4, BODY H5, BODY H6 { + line-height: 1.3; + margin-left: 0; +} + +BODY H1, BODY H2 { + margin: .8em 0 0 -4%; +} + +BODY H3, BODY H4 { + margin: .8em 0 0 -3%; +} + +BODY H5 { + margin: .8em 0 0 -2%; +} + +BODY H6 { + margin: .8em 0 0 -1%; +} + +BODY HR { + margin: .6em; + border-width: 0 0 1px 0; + border-style: solid; + border-color: #cecece; +} + +BODY IMG.NAVHEADER { + margin: 0 0 0 -4%; +} + +OL { + margin: 0 0 0 5%; + line-height: 1.2; +} + +BODY PRE { + margin: .75em 0; + line-height: 1.0; + font-family: monospace; +} + +BODY TD, BODY TH { + line-height: 1.2; +} + +UL, BODY DIR, BODY MENU { + margin: 0 0 0 5%; + line-height: 1.2; +} + +HTML { + margin: 0; + padding: 0; +} + +BODY P B.APPLICATION { + color: #000000; +} + +.FILENAME { + color: #007a00; +} + +.GUIMENU, .GUIMENUITEM, .GUISUBMENU, +.GUILABEL, .INTERFACE, +.SHORTCUT, .SHORTCUT .KEYCAP { + font-weight: bold; +} + +.GUIBUTTON { + background-color: #CFCFCF; + padding: 2px; +} + +.ACCEL { + background-color: #F0F0F0; + text-decoration: underline; +} + +.SCREEN { + padding: 1ex; +} + +.PROGRAMLISTING { + padding: 1ex; + background-color: #eee; + border: 1px solid #ccc; +} + +@media screen { /* hide from IE3 */ + a[href]:hover { background: #ffa } +} + +BLOCKQUOTE.NOTE { + color: #222; + background: #eee; + border: 1px solid #ccc; + padding: 0.4em 0.4em; + width: 85%; +} + +BLOCKQUOTE.TIP { + color: #004F00; + background: #d8ecd6; + border: 1px solid green; + padding: 0.2em 2em; + width: 85%; +} + +BLOCKQUOTE.IMPORTANT { + font-style:italic; + border: 1px solid #a00; + border-left: 12px solid #c00; + padding: 0.1em 1em; +} + +BLOCKQUOTE.WARNING { + color: #9F1313; + background: #f8e8e8; + border: 1px solid #e59595; + padding: 0.2em 2em; + width: 85%; +} + +.EXAMPLE { + background: #fefde6; + border: 1px solid #f1bb16; + margin: 1em 0; + padding: 0.2em 2em; + width: 90%; +} + +.INFORMALTABLE TABLE.CALSTABLE TR TD { + padding-left: 1em; + padding-right: 1em; +} diff --git a/src/doc/user/recoll.conf.xml b/src/doc/user/recoll.conf.xml new file mode 100644 index 00000000..81bd8b02 --- /dev/null +++ b/src/doc/user/recoll.conf.xml @@ -0,0 +1,589 @@ + + +Recoll main configuration file, recoll.conf + +Parameters affecting what documents we index + +topdirs +Space-separated list of files or +directories to recursively index. Default to ~ (indexes +$HOME). You can use symbolic links in the list, they will be followed, +independantly of the value of the followLinks variable. + +skippedNames +Files and directories which should be ignored. +White space separated list of wildcard patterns (simple ones, not paths, +must contain no / ), which will be tested against file and directory +names. The list in the default configuration does not exclude hidden +directories (names beginning with a dot), which means that it may index +quite a few things that you do not want. On the other hand, email user +agents like Thunderbird usually store messages in hidden directories, and +you probably want this indexed. One possible solution is to have ".*" in +"skippedNames", and add things like "~/.thunderbird" "~/.evolution" to +"topdirs". Not even the file names are indexed for patterns in this +list, see the "noContentSuffixes" variable for an alternative approach +which indexes the file names. Can be redefined for any +subtree. + +noContentSuffixes +List of name endings (not necessarily dot-separated suffixes) for +which we don't try MIME type identification, and don't uncompress or +index content. Only the names will be indexed. This +complements the now obsoleted recoll_noindex list from the mimemap file, +which will go away in a future release (the move from mimemap to +recoll.conf allows editing the list through the GUI). This is different +from skippedNames because these are name ending matches only (not +wildcard patterns), and the file name itself gets indexed normally. This +can be redefined for subdirectories. + +skippedPaths +Paths we should not go into. Space-separated list of +wildcard expressions for filesystem paths. Can contain files and +directories. The database and configuration directories will +automatically be added. The expressions are matched using 'fnmatch(3)' +with the FNM_PATHNAME flag set by default. This means that '/' characters +must be matched explicitely. You can set 'skippedPathsFnmPathname' to 0 +to disable the use of FNM_PATHNAME (meaning that '/*/dir3' will match +'/dir1/dir2/dir3'). The default value contains the usual mount point for +removable media to remind you that it is a bad idea to have Recoll work +on these (esp. with the monitor: media gets indexed on mount, all data +gets erased on unmount). Explicitely adding '/media/xxx' to the topdirs +will override this. + +skippedPathsFnmPathname +Set to 0 to +override use of FNM_PATHNAME for matching skipped +paths. + +daemSkippedPaths +skippedPaths equivalent specific to +real time indexing. This enables having parts of the tree +which are initially indexed but not monitored. If daemSkippedPaths is +not set, the daemon uses skippedPaths. + +zipSkippedNames +Space-separated list of wildcard expressions for names that should +be ignored inside zip archives. This is used directly by +the zip handler, and has a function similar to skippedNames, but works +independantly. Can be redefined for subdirectories. Supported by recoll +1.20 and newer. See +https://bitbucket.org/medoc/recoll/wiki/Filtering%20out%20Zip%20archive%20members + + +followLinks +Follow symbolic links during +indexing. The default is to ignore symbolic links to avoid +multiple indexing of linked files. No effort is made to avoid duplication +when this option is set to true. This option can be set individually for +each of the 'topdirs' members by using sections. It can not be changed +below the 'topdirs' level. Links in the 'topdirs' list itself are always +followed. + +indexedmimetypes +Restrictive list of +indexed mime types. Normally not set (in which case all +supported types are indexed). If it is set, +only the types from the list will have their contents indexed. The names +will be indexed anyway if indexallfilenames is set (default). MIME +type names should be taken from the mimemap file. Can be redefined for +subtrees. + +excludedmimetypes +List of excluded MIME +types. Lets you exclude some types from indexing. Can be +redefined for subtrees. + +compressedfilemaxkbs +Size limit for compressed +files. We need to decompress these in a +temporary directory for identification, which can be wasteful in some +cases. Limit the waste. Negative means no limit. 0 results in no +processing of any compressed file. Default 50 MB. + +textfilemaxmbs +Size limit for text +files. Mostly for skipping monster +logs. Default 20 MB. + +indexallfilenames +Index the file names of +unprocessed files Index the names of files the contents of +which we don't index because of an excluded or unsupported MIME +type. + +usesystemfilecommand +Use a system command +for file MIME type guessing as a final step in file type +identification This is generally useful, but will usually +cause the indexing of many bogus 'text' files. See 'systemfilecommand' +for the command used. + +systemfilecommand +Command used to guess +MIME types if the internal methods fails This should be a +"file -i" workalike. The file path will be added as a last parameter to +the command line. 'xdg-mime' works better than the traditional 'file' +command, and is now the configured default (with a hard-coded fallback to +'file') + +processwebqueue +Decide if we process the +Web queue. The queue is a directory where the Recoll Web +browser plugins create the copies of visited pages. + +textfilepagekbs +Page size for text +files. If this is set, text/plain files will be divided +into documents of approximately this size. Will reduce memory usage at +index time and help with loading data in the preview window at query +time. Particularly useful with very big files, such as application or +system logs. Also see textfilemaxmbs and +compressedfilemaxkbs. + +membermaxkbs +Size limit for archive +members. This is passed to the filters in the environment +as RECOLL_FILTER_MAXMEMBERKB. + + +Parameters affecting how we generate terms + +indexStripChars +Decide if we store +character case and diacritics in the index. If we do, +searches sensitive to case and diacritics can be performed, but the index +will be bigger, and some marginal weirdness may sometimes occur. The +default is a stripped index. When using multiple indexes for a search, +this parameter must be defined identically for all. Changing the value +implies an index reset. + +nonumbers +Decides if terms will be +generated for numbers. For example "123", "1.5e6", +192.168.1.4, would not be indexed if nonumbers is set ("value123" would +still be). Numbers are often quite interesting to search for, and this +should probably not be set except for special situations, ie, scientific +documents with huge amounts of numbers in them, where setting nonumbers +will reduce the index size. This can only be set for a whole index, not +for a subtree. + +dehyphenate +Determines if we index +'coworker' also when the input is 'co-worker'. This is new +in version 1.22, and on by default. Setting the variable to off allows +restoring the previous behaviour. + +nocjk +Decides if specific East Asian +(Chinese Korean Japanese) characters/word splitting is turned +off. This will save a small amount of CPU if you have no CJK +documents. If your document base does include such text but you are not +interested in searching it, setting nocjk may be a +significant time and space saver. + +cjkngramlen +This lets you adjust the size of +n-grams used for indexing CJK text. The default value of 2 is +probably appropriate in most cases. A value of 3 would allow more precision +and efficiency on longer words, but the index will be approximately twice +as large. + +indexstemminglanguages +Languages for which to create stemming expansion +data. Stemmer names can be found by executing 'recollindex +-l', or this can also be set from a list in the GUI. + +defaultcharset +Default character +set. This is used for files which do not contain a +character set definition (e.g.: text/plain). Values found inside files, +e.g. a 'charset' tag in HTML documents, will override it. If this is not +set, the default character set is the one defined by the NLS environment +($LC_ALL, $LC_CTYPE, $LANG), or ultimately iso-8859-1 (cp-1252 in fact). +If for some reason you want a general default which does not match your +LANG and is not 8859-1, use this variable. This can be redefined for any +sub-directory. + +unac_except_trans +A list of characters, +encoded in UTF-8, which should be handled specially +when converting text to unaccented lowercase. For +example, in Swedish, the letter a with diaeresis has full alphabet +citizenship and should not be turned into an a. +Each element in the space-separated list has the special character as +first element and the translation following. The handling of both the +lowercase and upper-case versions of a character should be specified, as +appartenance to the list will turn-off both standard accent and case +processing. The value is global and affects both indexing and querying. +Examples: +Swedish: +unac_except_trans = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl åå Åå +. German: +unac_except_trans = ää Ää öö Öö üü Üü ßss œoe Œoe æae Æae ffff fifi flfl +In French, you probably want to decompose oe and ae and nobody would type +a German ß +unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl +. The default for all until someone protests follows. These decompositions +are not performed by unac, but it is unlikely that someone would type the +composed forms in a search. +unac_except_trans = ßss œoe Œoe æae Æae ffff fifi flfl + +maildefcharset +Overrides the default +character set for email messages which don't specify +one. This is mainly useful for readpst (libpst) dumps, +which are utf-8 but do not say so. + +localfields +Set fields on all files +(usually of a specific fs area). Syntax is the usual: +name = value ; attr1 = val1 ; [...] +value is empty so this needs an initial semi-colon. This is useful, e.g., +for setting the rclaptg field for application selection inside +mimeview. + +testmodifusemtime +Use mtime instead of +ctime to test if a file has been modified. The time is used +in addition to the size, which is always used. +Setting this can reduce re-indexing on systems where extended attributes +are used (by some other application), but not indexed, because changing +extended attributes only affects ctime. +Notes: +- This may prevent detection of change in some marginal file rename cases +(the target would need to have the same size and mtime). +- You should probably also set noxattrfields to 1 in this case, except if +you still prefer to perform xattr indexing, for example if the local +file update pattern makes it of value (as in general, there is a risk +for pure extended attributes updates without file modification to go +undetected). Perform a full index reset after changing this. + + +noxattrfields +Disable extended attributes +conversion to metadata fields. This probably needs to be +set if testmodifusemtime is set. + +metadatacmds +Define commands to +gather external metadata, e.g. tmsu tags. +There can be several entries, separated by semi-colons, each defining +which field name the data goes into and the command to use. Don't forget the +initial semi-colon. All the field names must be different. You can use +aliases in the "field" file if necessary. +As a not too pretty hack conceded to convenience, any field name +beginning with "rclmulti" will be taken as an indication that the command +returns multiple field values inside a text blob formatted as a recoll +configuration file ("fieldname = fieldvalue" lines). The rclmultixx name +will be ignored, and field names and values will be parsed from the data. +Example: metadatacmds = ; tags = tmsu tags %f; rclmulti1 = cmdOutputsConf %f + + + +Parameters affecting where and how we store things + +cachedir +Top directory for Recoll data. Recoll data +directories are normally located relative to the configuration directory +(e.g. ~/.recoll/xapiandb, ~/.recoll/mboxcache). If 'cachedir' is set, the +directories are stored under the specified value instead (e.g. if +cachedir is ~/.cache/recoll, the default dbdir would be +~/.cache/recoll/xapiandb). This affects dbdir, webcachedir, +mboxcachedir, aspellDicDir, which can still be individually specified to +override cachedir. Note that if you have multiple configurations, each +must have a different cachedir, there is no automatic computation of a +subpath under cachedir. + +maxfsoccuppc +Maximum file system occupation +over which we stop indexing. The value is a percentage, +corresponding to what the "Capacity" df output column shows. The default +value is 0, meaning no checking. + +xapiandb +Xapian database directory +location. This will be created on first indexing. If the +value is not an absolute path, it will be interpreted as relative to +cachedir if set, or the configuration directory (-c argument or +$RECOLL_CONFDIR). If nothing is specified, the default is then +~/.recoll/xapiandb/ + +idxstatusfile +Name of the scratch file where the indexer process updates its +status. Default: idxstatus.txt inside the configuration +directory. + +mboxcachedir +Directory location for storing mbox message offsets cache +files. This is normally 'mboxcache' under cachedir if set, +or else under the configuration directory, but it may be useful to share +a directory between different configurations. + +mboxcacheminmbs +Minimum mbox file size over which we cache the offsets. There is really no sense in caching offsets for small files. The +default is 5 MB. + +webcachedir +Directory where we store the archived web pages. This is only used by the web history indexing code +Default: cachedir/webcache if cachedir is set, else +$RECOLL_CONFDIR/webcache + +webcachemaxmbs +Maximum size in MB of the Web archive. This is only used by the web history indexing code. +Default: 40 MB. +Reducing the size will not physically truncate the file. + +webqueuedir +The path to the Web indexing queue. This is +hard-coded in the plugin as ~/.recollweb/ToIndex so there should be no +need or possibility to change it. + +aspellDicDir +Aspell dictionary storage directory location. The +aspell dictionary (aspdict.(lang).rws) is normally stored in the +directory specified by cachedir if set, or under the configuration +directory. + +filtersdir +Directory location for executable input handlers. If +RECOLL_FILTERSDIR is set in the environment, we use it instead. Defaults +to $prefix/share/recoll/filters. Can be redefined for +subdirectories. + +iconsdir +Directory location for icons. The only reason to +change this would be if you want to change the icons displayed in the +result list. Defaults to $prefix/share/recoll/images + + +Parameters affecting indexing performance and resource usage + +idxflushmb +Threshold (megabytes of new data) where we flush from memory to +disk index. Setting this allows some control over memory +usage by the indexer process. A value of 0 means no explicit flushing, +which lets Xapian perform its own thing, meaning flushing every +$XAPIAN_FLUSH_THRESHOLD documents created, modified or deleted: as memory +usage depends on average document size, not only document count, the +Xapian approach is is not very useful, and you should let Recoll manage +the flushes. The program compiled value is 0. The configured default +value (from this file) is 10 MB, and will be too low in many cases (it is +chosen to conserve memory). If you are looking +for maximum speed, you may want to experiment with values between 20 and +200. In my experience, values beyond this are always counterproductive. If +you find otherwise, please drop me a note. + +filtermaxseconds +Maximum external filter execution time in +seconds. Default 1200 (20mn). Set to 0 for no limit. This +is mainly to avoid infinite loops in postscript files +(loop.ps) + +filtermaxmbytes +Maximum virtual memory space for filter processes +(setrlimit(RLIMIT_AS)), in megabytes. Note that this +includes any mapped libs (there is no reliable Linux way to limit the +data space only), so we need to be a bit generous here. Anything over +2000 will be ignored on 32 bits machines. + +thrQSizes +Stage input queues configuration. There are three +internal queues in the indexing pipeline stages (file data extraction, +terms generation, index update). This parameter defines the queue depths +for each stage (three integer values). If a value of -1 is given for a +given stage, no queue is used, and the thread will go on performing the +next stage. In practise, deep queues have not been shown to increase +performance. Default: a value of 0 for the first queue tells Recoll to +perform autoconfiguration based on the detected number of CPUs (no need +for the two other values in this case). Use thrQSizes = -1 -1 -1 to +disable multithreading entirely. + +thrTCounts +Number of threads used for each indexing stage. The +three stages are: file data extraction, terms generation, index +update). The use of the counts is also controlled by some special values +in thrQSizes: if the first queue depth is 0, all counts are ignored +(autoconfigured); if a value of -1 is used for a queue depth, the +corresponding thread count is ignored. It makes no sense to use a value +other than 1 for the last stage because updating the Xapian index is +necessarily single-threaded (and protected by a mutex). + + +Miscellaneous parameters + +loglevel +Log file verbosity 1-6. A value of 2 will print +only errors and warnings. 3 will print information like document updates, +4 is quite verbose and 6 very verbose. + +logfilename +Log file destination. Use 'stderr' (default) to write to the +console. + +idxloglevel +Override loglevel for the indexer. + +idxlogfilename +Override logfilename for the indexer. + +daemloglevel +Override loglevel for the indexer in real time +mode. The default is to use the idx... values if set, else +the log... values. + +daemlogfilename +Override logfilename for the indexer in real time +mode. The default is to use the idx... values if set, else +the log... values. + +idxrundir +Indexing process current directory. The input +handlers sometimes leave temporary files in the current directory, so it +makes sense to have recollindex chdir to some temporary directory. If the +value is empty, the current directory is not changed. If the +value is (literal) tmp, we use the temporary directory as set by the +environment (RECOLL_TMPDIR else TMPDIR else /tmp). If the value is an +absolute path to a directory, we go there. + +checkneedretryindexscript +Script used to heuristically check if we need to retry indexing +files which previously failed. The default script checks +the modified dates on /usr/bin and /usr/local/bin. A relative path will +be looked up in the filters dirs, then in the path. Use an absolute path +to do otherwise. + +recollhelperpath +Additional places to search for helper executables. This is only used on Windows for now. + +idxabsmlen +Length of abstracts we store while indexing. Recoll stores an abstract for each indexed file. +The text can come from an actual 'abstract' section in the +document or will just be the beginning of the document. It is stored in +the index so that it can be displayed inside the result lists without +decoding the original file. The idxabsmlen parameter +defines the size of the stored abstract. The default value is 250 +bytes. The search interface gives you the choice to display this stored +text or a synthetic abstract built by extracting text around the search +terms. If you always prefer the synthetic abstract, you can reduce this +value and save a little space. + +idxmetastoredlen +Truncation length of stored metadata fields. This +does not affect indexing (the whole field is processed anyway), just the +amount of data stored in the index for the purpose of displaying fields +inside result lists or previews. The default value is 150 bytes which +may be too low if you have custom fields. + +aspellLanguage +Language definitions to use when creating the aspell +dictionary. The value must match a set of aspell language +definition files. You can type "aspell dicts" to see a list The default +if this is not set is to use the NLS environment to guess the +value. + +aspellAddCreateParam +Additional option and parameter to aspell dictionary creation +command. Some aspell packages may need an additional option +(e.g. on Debian Jessie: --local-data-dir=/usr/lib/aspell). See Debian bug +772415. + +aspellKeepStderr +Set this to have a look at aspell dictionary creation +errors. There are always many, so this is mostly for +debugging. + +noaspell +Disable aspell use. The aspell dictionary generation +takes time, and some combinations of aspell version, language, and local +terms, result in aspell crashing, so it sometimes makes sense to just +disable the thing. + +monauxinterval +Auxiliary database update interval. The real time +indexer only updates the auxiliary databases (stemdb, aspell) +periodically, because it would be too costly to do it for every document +change. The default period is one hour. + +monixinterval +Minimum interval (seconds) between processings of the indexing +queue. The real time indexer does not process each event +when it comes in, but lets the queue accumulate, to diminish overhead and +to aggregate multiple events affecting the same file. Default 30 +S. + +mondelaypatterns +Timing parameters for the real time indexing. Definitions for files which get a longer delay before reindexing +is allowed. This is for fast-changing files, that should only be +reindexed once in a while. A list of wildcardPattern:seconds pairs. The +patterns are matched with fnmatch(pattern, path, 0) You can quote entries +containing white space with double quotes (quote the whole entry, not the +pattern). The default is empty. +Example: mondelaypatterns = *.log:20 "*with spaces.*:30" + +monioniceclass +ionice class for the real time indexing process On platforms where this is supported. The default value is +3. + +monioniceclassdata +ionice class parameter for the real time indexing process. On platforms where this is supported. The default is +empty. + + +Query-time parameters (no impact on the index) + +autodiacsens +auto-trigger diacritics sensitivity (raw index only). IF the index is not stripped, decide if we automatically trigger +diacritics sensitivity if the search term has accented characters (not in +unac_except_trans). Else you need to use the query language and the "D" +modifier to specify diacritics sensitivity. Default is no. + +autocasesens +auto-trigger case sensitivity (raw index only). IF +the index is not stripped (see indexStripChars), decide if we +automatically trigger character case sensitivity if the search term has +upper-case characters in any but the first position. Else you need to use +the query language and the "C" modifier to specify character-case +sensitivity. Default is yes. + +maxTermExpand +Maximum query expansion count +for a single term (e.g.: when using wildcards). This only +affects queries, not indexing. We used to not limit this at all (except +for filenames where the limit was too low at 1000), but it is +unreasonable with a big index. Default 10000. + +maxXapianClauses +Maximum number of clauses +we add to a single Xapian query. This only affects queries, +not indexing. In some cases, the result of term expansion can be +multiplicative, and we want to avoid eating all the memory. Default +50000. + +snippetMaxPosWalk +Maximum number of positions we walk while populating a snippet for +the result list. The default of 1,000,000 may be +insufficient for very big documents, the consequence would be snippets +with possibly meaning-altering missing words. + + +Parameters for the PDF input script + +pdfocr +Attempt OCR of PDF files with no text content if both tesseract and +pdftoppm are installed. The default is off because OCR is so +very slow. + +pdfattach +Enable PDF attachment extraction by executing pdftk (if +available). This is +normally disabled, because it does slow down PDF indexing a bit even if +not one attachment is ever found. + + +Parameters set for specific locations + +mhmboxquirks +Enable thunderbird/mozilla-seamonkey mbox format quirks Set this for the directory where the email mbox files are +stored. + + diff --git a/src/doc/user/usermanual-italian.html b/src/doc/user/usermanual-italian.html new file mode 100644 index 00000000..d9820c05 --- /dev/null +++ b/src/doc/user/usermanual-italian.html @@ -0,0 +1,3849 @@ + + + + + + + + + + + + + Recoll user manual + + + + + + + + + + + + + + + +
+
+

Recoll: +manuale utente

+ + +

Jean-Francois +Dockes

+ + +
+
+

+ + +
+ + +
+ + + + + +
+
+

Questo documento spiega le nozioni della ricerca testuale e descrive +l'installazione e l'uso di Recoll.

+ + +
+ + +
+ + +
+
+ + +
+
+ + +
Indice
+ + +
1. Introduzione
+ + +
+ +
+ + +
1.1. Per +gli impazienti
+ + +
1.2. Ricerca +a tutto testo
+ + +
1.3. Panoramica +d Recoll
+ + + +
+ + +
+ + +
2. Indicizzazione
+ + +
+ +
+ + +
2.1. Introduzione
+ + +
2.2. Salvare +l'indice
+ + +
+ +
+ + +
2.2.1. Sicurezza
+ + + +
+ + +
+ + +
2.3. Configurazione dell'indicizzazione
+ + +
2.4. Indicizzazione +periodica
+ + +
+ +
+ + +
2.4.1. Iniziare +l'indicizzazione
+ + +
2.4.2. Usare +cron per l'indicizzazione automatica
+ + + +
+ + +
+ + +
2.5. Indicizzazione in tempo +reale
+ + + +
+ + +
+ + +
3. Search
+ + +
+ +
+ + +
3.1. Ricerca +semplice
+ + +
3.2. La +lista dei risultati
+ + +
+ +
+ + +
3.2.1. Il +clic col tasto destro del mouse sulla lista dei risultati
+ + + +
+ + +
+ + +
3.3. La +finestra di preview
+ + +
3.4. Ricerca +complessa/avanzata
+ + +
3.5. Il +terminale di esplorazione
+ + +
3.6. Database +multipli
+ + +
3.7. Storia +dei documenti
+ + +
3.8. Ordinare +i risultati della ricerca
+ + +
3.9. Consigli +per la ricerca, scorciatoie
+ + +
3.10. Personalizzare +l'interfaccia di ricerca
+ + + +
+ + +
+ + +
4. Installazione
+ + +
+ +
+ + +
4.1. Installare +una copia pre-compilata
+ + +
+ +
+ + +
4.1.1. Installazione +con un programma di installazione
+ + +
4.1.2. Installare +un pacchetto Recoll +pre-compilato
+ + + +
+ + +
+ + +
4.2. Pacchetti +esterni utilizzabili
+ + +
4.3. Compilazione +da sorgente
+ + +
+ +
+ + +
4.3.1. Prerequisiti
+ + +
4.3.2. Compilazione
+ + +
4.3.3. Installazione
+ + + +
+ + +
+ + +
4.4. Panoramica +della configurazione
+ + +
+ +
+ + +
4.4.1. File +principale di configurazione
+ + +
4.4.2. Il +file mimemap
+ + +
4.4.3. Il +file mimeconf
+ + +
4.4.4. Il +file mimeview
+ + +
4.4.5. Esempio
+ + + +
+ + +
+ + + +
+ + +
+ + +
+ + +
+ + +
+
+

Capitolo +1. Introduzione

+ + +
+

1.1. Per gli impazienti

+ + +

Se non amate leggere manuali (chi lo ama?) e vorreste provare +subito Recoll, eseguite +allora l'installazione +e lanciate recoll, +che per default inizierà ad indicizzare la vostra home +cartella, permettendovi di fare subito una ricerca non appena il +processo di indicizzazione sarà terminato.

+ + +

Non fate così, però, se la vostra home +cartella +contiene un gran numero di documenti e non avete voglia di aspettare o +avete poco spazio sul disco. In questo caso potrebbe convenirvi di +editare per prima cosa il file di  configurazione per +estringere l'area da indicizzare.

+ + +

Fate inoltre attenzione che potreste dover installare le applicazioni di supporto esterne +per indicizzare quei documenti che le richiedono (ad esempio antiword per documenti +ms-word).

+ + +
+ + +
+
+

1.2. Ricerca a tutto testo

+ + +

Recoll +è un'applicazione per la +ricerca a tutto testo. Le applicazioni di ricerca a tutto testo vi +permettono di trovare ciò che cercate in base al contenuto +dei +files e non al loro nome o estensione. Più in dettaglio vi +lasciano specificare le parole (termini di ricerca) che dovrebbero (o +non dovrebbereo) essere nel testo che cercate e vi ritornano una lista +di documenti che soddisfano tale criterio, ordinati in maniera tale che +quelli più rilevanti appaiano +in cima alla lista.

+ + +

Non hai bisogno di ricordare in che file o e-mail hai scritto +una +certa informazione. Semplicemente chiedi di trovare i termini che ti +interessano e lo strumento ti ritornerà una lista di +documenti +che li conetngono, in modo simile a quello che fa un motore di ricerca +su internet.

+ + +

Recoll cerca di +determinare quali +documenti sono più rilevanti al fine della ricerca dei +termini +inseriti. Gli algritmi che determinano la rilevanza possono essere +molto complessi e in generale sono inferiori alla potenza e +rapidità della mente umana. La qualità nella +determinazione della rilevanza è probabilmente il fattore +più importante di uno strumento di ricerca.

+ + +

In molti casi cercate tutte le forme di una parola, non una +forma +specifica. Queste differenti forme possono includere plurali, diverse +coniugazioni di verbi, o parole derivate da una radice comune +o stem +(ad esempio: floopianor, piani, pianoforte, ripiano...). Recoll per default espande la +ricerca a tutte queste variazioni +parole che hanno in comune la stessa radice o stem). Questa espansione +può essere disabilitata in qualsiasi momento.

+ + +

Lo stemming, per se stesso, non risolve errori di ortografia, +nè può fare ricerche fonetiche. Recoll supporta queste +caratteristiche attraverso uno strumento specifico (il terminale di esplorazione) +che vi lascia esplorare i +termini contenuti nell'indice in differenti maniere.

+ + +
+ + +
+
+

1.3. Panoramica di Recoll

+ + +

Recoll usa la +libreria di ricerca informazioni Xapian + come suo motore di ricerca e indicizzazione. Xapian è un +programma molto maturo che usa un +modello di rilevanza probabilistica molto sofisticato. Recoll provvede l'interfaccia +per indicizzare del sistema ed estrarli in base alla ricerca.

+ + +

In pratica, Xapian +lavora ricordandosi i +termini (parole) contenuti nei vari documenti. Conoscenza acquisita +tramite il procedimento chiamato indicizzazione.

+ + +

L'indice risultante può essere molto grande (a +spanna la +grandezza dei files indicizzati), ma non è un archivio di +documenti. Recoll +può mostrare solo +i documenti che si trovano ancora là dove sono stati +indicizzati. (In effetti esiste un modo per ricostruire un documento +dalle informazioni racchiuse nell'indice, ma il risultato non +è +bello dal momento che il testo è tutto minuscolo e sono +perdute +le informazioni di formattazione).

+ + +

Recoll +immagazzina tutte le informazioni sando il formato Unicode UTF-8 +e può indicizzare files con  un differente set di +caratteri, diverse codifiche e lingue sullo stesso indice. Posside +filtri di ingresso per molteplici tipi di files.

+ + +

Lo stemming dipende dalla lingua del documento. Recoll +immagazzina i termini senza stem e usa database ausiliari per espandere +(stemming) le parole. Può farlo scegliendo tra lingue +diverse o +aggiungendo nuove lingue senza dover rifare l'indice. Immagazzinare +documenti in diverse lingue nello stesso indice è possibile, +e +nella pratica utile, ma può introdurre +possibilità di +confusione. Recoll +attualmente non fa alcun tentativo per riconoscere automaticamente la +lingua.

+ + +

Recoll ha molti +parametri per definire +esattamente ciò che deve indicizzare e come classificare e +decodificare il sorgente dei documenti. Questi parametri sono contenuti +in un file di +configurazione. La configurazione standard è messa +in una cartella standard (normalmente qualcosa come /usr/[local/]share/recoll/examples) +durante l'installazione. I parametri di default possono essere cambiati +con valori da voi scelti e messi nel vostro file di configurazione +personale che deve trovarsi nella cartella .recoll +nella vostra home cartella. Il file di configurazione fornito di +default dovrebbe essere sufficente per indicizzare la vostra home +cartella e permettervi così di provare Recoll, salvo naturalmente +personalizzarlo in seguito.

+ + +

L'indicizzazione +comincia +automaticamente la prima volta che lanciate l'interfaccia grafica di +ricerca di recoll oppure eseguendo il comando recollindex.

+ + +

La ricerca viene +fatta col programma recoll che ha numerose opzioni per farvi trovare +quello che effettivamente state cercando.

+ + +
+ + +
+ + +
+
+

Capitolo +2. Indicizzazione

+ + +
+

2.1. +Introduzione

+ + +

L'indicizzazione è il processo che analizza i +documenti e mette i dati nel database. Il processo di indicizzazione di +Recoll +è normalmente incrementale, vale a dire che i documenti +vengono +analizzati e indicizzati solo se hanno subito modifiche. Alla prima +esecuzione, naturalmente, tutti i documenti vengono analizzati e +indicizzati..Il processo (indicizzazione completa) può +essere +eseguito in seguito specificando un'opzione al comando di +indicizzazione (recollindex +-z).

+ + +

L'indicizzazione con Recoll può essere +fatta con due metodi diversi:

+ + +
    + + +
  • + +
    + +

    Indicizzazione periodica: +l'indicizzazione avviene in tempi prestabiliti, eseguendo il comando recollindex. L'uso tipico +è quello di fare una indicizzazione durante la notte programmando +l'evento con cron.

    + + +
    + + +
  • + + +
  • + +
    + +

    Indicizzazione in tempo reale: +l'indicizzazione avviene non appena un file viene creato o cambiato. In +questo caso recollindex +gira come un  demone e usa il monitoraggio del file-system +fornito da Fam, Gamin o inotify per scoprire gli +eventuali cambiamenti. Monitorare un grosso albero di cartelle +può consumare molte risorse.

    + + +
    + + +
  • + + +
+ + +

La scelta tra i due metodi è principalmente +questione di +preferenze e può essere combinata costruendo indici +diversi (ad esempio: indicizzazione periodica per una grossa +cartella di documenti e indicizzazione in tempo reale per una piccola +home cartella). Monitorare grandi sezioni del disco + può +richiedere risorse significative del sistema senza portare vantaggi +considerevoli.

+ + +

+

+ + +

Recoll riconosce +alcuni differenti tipi di documenti. +I parametri per il riconoscimento dei documenti sono nei files di configurazione. +La maggior parte dei tipi, come l'HTML o i files di un wordprocessor, +sono un unico documento. Altri tipi, come le mail cartelle, possono +contenere molti singoli documenti indicizzati.

+ + +

Recoll processa +files di testo, HTML, +openoffice ed +e-mail internamente. Altri tipi (ad esempio: files postscript, pdf, +ms-word, rtf) richiedono applicazioni esterne per poter essere +processati. La lista di queste applicazioni è nella sezione installazione.

+ + +

Senza ulteriori configurazioni, Recoll +indicizzerà tutti i files della vostra home cartella, usando +i parametri della configurazione di default.

+ + +

In qualche caso potreste essere interessati ad indicizzare +aree +differenti del vostro file system in database separati. Potete farlo +utilizzando la configurazione multipla di cartelle, indicizzando +ciascuna area del file system in uno specifico database. Vedi la sezione su come usare database +multipli per avere maggiori informazione sulla configurazione +e indicizzazione multipla.
+ + +

+ + +
+ + +
+
+

2.2. Salvare l'indice

+ + +

Normalmente la cartella dove viene salvato l'indice +è la sotto cartella xapiandb nella cartella di +configurazione di Recoll, +tipicamente +$HOME/.recoll/xapiandb/. +Questo però può essere cambiato in due modi +differenti (con due differenti scopi):

+ + +
    + + +
  • + +

    Puoi specificare una differente cartella di configurazione +tramite la variabile di ambiente RECOLL_CONFDIR, +oppure usando l'opzione -c +nei comandi di  Recoll. +Questo metodo è usato tipicamente per indicizzare differenti +aree del file system in differenti indici. Per esempio, coi seguenti +comandi:

    + + + +
    export RECOLL_CONFDIR=~/.indexes-email
    recoll

    + + + Recoll +userò il file di configurazione che trova in ~/.indexes-email/ e, (se non +specificato altrimenti in recoll.conf) +cercherà l'indice in in ~/.indexes-email/xapiandb/. +
    + + +
    + + + +

    Usare diverse cartella di configurazionee +diverse  opzioni +di configurazione permette di adattare le configurazioni e +gli indici ai dati presenti nelle varie aree dove volete effettuare le +ricerche.

    + + +
  • + + +
  • + +

    Potete specificare un indirizzo diverso per salvare +l'indice editando il parametro the dbdir +che si trova nel file di configurazione (vedi la  sezione di +configurazione). +Questometodo va usato se vuoi mantenere la cartella di configurazione +nel suo indirizzo di default, ma vuoi mettere l'indice da qualche altra +parte, generalmente per ragioni di spazio.

    + + +
  • + + +
+ + +

La grandezza dell'indice è determinata dal volume +dei +documenti da indicizzare, ma il rapporto può variare molto. +Per +un insieme di documenti normalmente misto il volume dell'indice +è molto vicino a quello dei documenti indicizzati In casi +specifici (ad esempio un insieme di mbox compresse), il volume +dell'indice può essere molto più grande di quello +dei +documenti stessi. Può anche essere molto più +piccolo se +l'insieme di documenti contiene molte immagini e altri dati non +indicizzati (un esempio estremo è dato dai files mp3 dove +solo i +tags vengono indicizzati).

+ + +

Naturalmente immagini, suoni e video non incrementano il +volume +dell'indice, il che ha come conseguenza che, oggi (2006), il volume +dell'indice sarà comunque trascurabile rispetto +all'ammontare +dei dati contenuti nel vostro computer.

+ + +

La cartella contenente l'indice (xapiandb) +contiene solo dati che possono essere ricostruiti in qualsiasi momento +re-indicizzando il tutto, e quindi può essere cancellata +senza +problemi.

+ + +
+
+

2.2.1. Sicurezza

+ + +

L'indice di Recoll +non contiene le copie +dei documenti indicizzati. Ma conyiene abbastanza dati da permettere +una ricostruzione piuttosto completa e comprensibile. +Nel caso vengano indicizzati documenti confidenziali +lìaccesso +alla cartella del database dovrebbe essere limitato.

+ + +

Dalla versione 1.4, Recoll +crea la cartella di configurazione con i permessi 0700 (accessibile +solo per +il proprietario). Visto che bormalmente la cartella del database +è una sub cartella di questa, la protezione dovrebbe essere +sufficenta.

+ + +

Se usi un'altra configurazione dovresti pensare al tipo di +protezione che l'indice dovrebbe avere e settare la cartella +corrispondente e i files con i permessi del caso.

+ + +
+ + +
+ + +
+
+

2.3. Configurazione +dell'indicizzazione

+ + +

Puoi controllare le aree del file system da indicizzare e come +processare i files tramite le variabili nei files +di configurazione di Recoll.

+ + +

Puoi anche usare indici +multipli +definiti da configurazioni separate, normalmente  per separare +indici personali e indici in comune, oppure per avvantaggiarsi +dell'organizzazione dei tuoi dati e aumentare la precisione.

+ + +

La prima volta che lanci recoll, +verrai richiesto se vuoi che recoll costruisca l'indice oppure no. Se +vuoi sistemare la configurazione prima che venga creato l'indice, +clicca ora su Cancel. +Facendo così avrai creato la cartella ~/.recoll contenente +files di configurazione vuoti.

+ + +

La configurazione è documentata all'interno +del  capitolo +installazione +di questo documento, o nella pagina man di recoll.conf(5) man +page. La variabile di maggiore  e immediato interesse +è +probabilmente topdirs, +che determina quali cartelle indicizzare.

+ + +

Le applicazioni esterne necessarie per indicizzare tipi di +files diversi da txt, HTML o email (ad esempio: pdf, +postscript, ms-word...) sono indicate nella sezione pacchetti esterni.

+ + +
+ + +
+
+

2.4. Indicizzazione periodica

+ + +
+

2.4.1.Iniziare +l'indicizzazione

+ + +

L'indicizzazione viene eseguita o tramite il programma recollindex, +o lanciando il thread di indicizzazione dal programma recoll (usa il menu File). Entrambi i modi fanno +uso della variabile RECOLL_CONFDIR +o accettano l'opzione -c confdir +per specificare la cartella di configurazione da usare.

+ + +

Se il programma recoll +non trova alcun indice quando è lanciato, inizia +automaticamente +l'indicizzazione (a meno che non clicchi sul tasto Cancel).

+ + +

E' meglio non interrompere il processo di indicizzazione +perchè facendo così, il più delle +volte, l'indice +viene corrotto. Questo non è un problema serio visto che +tutto +quello che devi fare è cancellare l'indice e riavviare +l'indicizzazione. I files dell'indice sono normalmente nella cartella $HOME/.recoll/xapiandb, che puoi +tranquillamente cancellare se necessario. In alternativa puoi avviare recollindex con +l'opzione -z, opzione che +cancella il database prima di fare l'indicewhich will reset the +database before indexing.

+ + +
+ + +
+
+

2.4.2. Usare cron per +l'indicizzazione automatica

+ + +

Il modo più semplice per avere un'indicizzazione +automatica è usare cron per fare l'indicizzazione ogni +notte. +Ad esempio la seguente linea aggiunta a crontab +esegue l'indicizzazione ogni giorno alle 3:30AM (supponendo +che recollindex sia nel +vostro PATH):

+ + +
30 3 * * * recollindex > /tmp/recolltrace 2>&1
+ + +

Il comando usuale per editare crontabcrontab -e +(che normalmente lancia l'editor vi +per editare crontab). Potreste ovviamente avere strumenti +più sofisticati  nel vostro sistema atti allo scopo.

+ + +
+ + +
+ + +
+
+

2.5. Indicizzazione in tempo +reale

+ + +

L'indicizzazione in tempo reale si ottiene con il comando recollindex -m. Con questa +opzione, recollindex viene +lanciato dal terminele e diventa un demone, +monitorando in continuazione i cambiamenti e tenendo così +aggiornato l'indice.

+ + +

L'indicizzazione in tempo reale viene impostata alla configurazione +del pacchetto (prima della compilazione) con l'opzione --with[out]-fam or --with[out]-inotify. Per default +viene scelto inotify per i sistemi che lo supportano.

+ + +

Lo script rclmon.sh +può essere usato per lanciare e fermare il demone. Si trova +nella cartella examples +di recoll +(normalmente /usr/local/[share/]recoll/examples).

+ + +

Il lancio del demone è normalmente eseguito come +parte della +sessione dell'utente. Ad esempio la mia sessione fuori +moda xdm ha +lo script .xsession +con le seguenti linne alla fine:

+ + +
recollconf=$HOME/.recoll-home
recolldata=/usr/local/share/recoll
RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start

fvwm

+ + +

Viene lanciato prima il demone e poil il window-manager, per +il quale la sessione aspetta.

+ + +

Per default il demone di indicizzazione monitorizza lo stato +della +sessione X11 ed esce quando questa finisce (non è necessario +chiuderlo esplicitamente). Il monitoraggio della sessione X11 +può essere disabilitato con l'opzione -x di recollindex.

+ + +

Con KDE, puoi mettere un piccolo script per +lanciare recollindex +-m nella $HOME/.kde/Autostart. +Verrà eseguito ogni volta che inizia la sessione KDE.

+ + +

Esiste un meccanismo simile anche per Gnome (trova lo +strumento per +il controllo della gestione nel menu e usa la linguetta "Startup +programs").

+ + +

Per default, il demone di indicizzazione scrive i suoi +messaggiin un +file dentro la cartella di configurazione (ciò è +controllato dai parametri daemlogfilename e daemloglevel +di configurazione). Puoi naturalmente cambiarli. Il file di log fviene +troncato all'avvio del demone. Se il demone è sempre in +funzione, il file di log può diventare molto grosso a +seconda +del livello di log scelto.

+ + +

Sebbene l'indicizzazione real time sia apprezzabile, +può +causare un alto carico del sistema, ad esempio se cambiano dati come le +e-mail. Probabilmente ti conviene non abilitarla se il tuo sistema +è a corto di risorse. L'indicizzazione periodica +è +sufficente nella maggior parte dei casi.

+ + +
+ + +
+ + +
+
+

Capitolo +3. Ricerca

+ + +

Il programma recoll provvede l'interfaccia +paer la ricerca. Utilizza le librerie QT.

+ + +
+
+

3.1. Ricerca semplice

+ + +
+
    + + +
  1. + +

    Lancia il programma recoll.

    + + +
  2. + + +
  3. + +

    Scegli il modo di reicerca: Qualsiasi +o Tutti o Nome File.

    + + +
  4. + + +
  5. + +

    Entra la/e parola/e da cercare nel campo testo nella parte +superiore della finestra.

    + + +
  6. + + +
  7. + +

    Clicca sul bottone Cerca +o clicca il tasto Enter per +iniziare la ricerca.

    + + +
  8. + + +
+ + +
+ + +

Il modo di default iniziale di ricerca è Qualsiasi. +Questo cercherà quei documenti che contengano qualsiasi +delle +parole cercate (ill documento che ne contiene di più +avrà +maggiore rilevanza). Tutte +mostrerà solo quei documenti che contengono tutte le parole +cercate. Nome File cerca +solo tra i nomi dei files e permette l'uso dei Caratteri Jolly (*, ? +, []).

+ + +

Puoi anche cercare frasi (parole adiacenti in un dato ordine) +racchiudendo tra virgolette le parole di ricerca. Ad esempio: "realtà virtuale".

+ + +

Maiuscole e minuscole non hanno alcuna influenza sulla +ricerca, con +l'unica eccezione che puoi disabilitare lo stemming (ricerca delle +parole che contengono quella data) scrivendo il primo carattere +maiuscolo. Ad esempio: la ricerca di  casa +cercherà anche  caso, case, casi, casato, +casale, ecc., ma la ricerca di Casa cercherà solo casa, con +caratteri maiuscoli o minuscoli (lo stemming può essere +disbilitato globalmente nelle preferenze).

+ + +

Recoll si +ricorda gli ultimi termini di +ricerca. +Per richiamarli puoi usare il combobox della casella di +ricerca. +Tieni però a mente che vengono ricordate solo le parole, ma +non +il modo (Qualsiasi, Tutte, Nome file).

+ + +

I tasti Esc +Space +mentre si sta scrivendo una parola nella ricerca semplice aprono una +finestra con i possibili completamenti della parole. Questi ultimi sono +tratti dalle parole esistenti nel database.

+ + +

Un doppio clic su una parola della lista dei risultati o nella +finestra di visualizzazione inserisce la parola stessa nel campo di +ricerca semplice.

+ + +

Puoi usare la voce di menu Strumenti/Ricerca avanzata +per aprire la finestra di dialogo per ricerche più complesse.

+ + +
+ + +
+
+

3.2. La lista dei risultati

+ + +

Lanciata la ricerca verrà immediatamente mostrata +nella finestra principale la lista dei risultati.

+ + +

Per default, i documenti sono presentati in ordine di +rilevanza (nel +limite in cui il sistema riesce a stimare la rilevanza). Puoi ordinarli +in maniera diversa usando la voce di menu Strumenti / Ordina: scegli +parametri.

+ + +

Se clicchi sul link Preview +di uno dei +risultati si pare una finestra di Visualizzaxione interna col testo del +documento. Un ulteriore clic sul link Preview di un altro risultato, +aprirà una seconda linguetta. Puoi usare  Shift+Click +per forzare l'apertura di una seconda finestra di visualizzazione che +può essere utile per vedere ad esempio due pagine dello +stesso +documento.

+ + +

Cliccando sul link Edit +verrà +aperto un visualizzatore esterno (generalmente il programma che ha +creato il file). Il programma che deve essere aperto viene configurato +attraverso il dialogo di preferenze, oppure editando il file di +configurazione mimeview.

+ + +

I link Preview +e Edit possono non essere +presenti per tutti i risultati. Ciò significa che Recoll +non ha la configurazione necessaria per la visualizzazione di un +determinato tipo di file (che quindi sarà stato indicizzato +solo +per nome), o non sa con quale programma esterno aprirlo. Spesso +ciò può essere sistemato con apposite aggiunte ai +files +di configurazione mimemap e mimeview +(l'ultimo può essere modificato con la finestra di dialogo +delle preferenza).

+ + +

Cliccando sul link Dettagli ricerca nella parte superiore +della +finestra di ricerca verrò mostrata la stringa di ricerca +utilizzata, dopo l'eventuale applicazione dello stemming e/o di altri +processi.

+ + +

Un doppio clic su qualsiasi parola della finestra di +visualizzazione +inserice  tale parola nel campo di ricerca semplice. Un doppio +clic su qualsiasi parola della lista dei risultati avrà lo +stesso risultato.

+ + +

La lsista dei risultati è divisa in pagine (il +numero di +risultati per pagina può essere impostato nelle preferenze). +Passi da una pagina all'altra con i tasti frecce della tastiera oppure +col link a fondo pagina  della lista dei risultati.

+ + +
+
+

3.2.1. Il clic col tasto +destro del mouse sulla lista dei risultati

+ + +

Oltre ai links preview ed edit, puoi ottenere un +menu pop-up menu cliccando col tasto destro su di una linea +della +lista dei risultati. Il menu ha le seguenti voci:

+ + +
    + + +
  • + +

    Preview

    + + +
  • + + +
  • + +

    Edita

    + + +
  • + + +
  • + +

    Copia il nome del file

    + + +
  • + + +
  • + +

    Copia l'Url

    + + +
  • + + +
  • + +

    Trova documenti simili

    + + +
  • + + +
  • + +

    Apri cartella del +documento

    + + +
  • + + +
+ + +

Le voci Preview +e Edita hanno la +stessa funzione dei links corrispondenti. 

+ + +

Le due voci seguenti copiano rispettivamente l'indirizzo e il +nome + o l'url del file nella clipboard per poterli incollare in +un'altra applicazione.

+ + +

La voce Trova documenti simili seleziona +un certo numero di parole rilevanti del documento e le scrive nella +casella di ricerca semplice ed effettua la ricerca per trovare +documenti correlati con quello di partenza.

+ + +La voce Apri cartella del documento apre la cartella ove si trova il +documento (il programma per l'apertura della cartella si imposta nei +files di configurazione. Di default è Rox). +
+ + +
+ + +
+
+

3.3. La finestra di visualizzazione

+ + +

La finestra di visualizzazione si apre cliccando sul +link Preview nella +lista dei risultati.

+ + +

Una successiva richiesta di visualizzazione apre una nuova +linguetta nella finestra di visualizzazione stessa.

+ + +

Eseguendo una nuova ricerca e attivando la finestra di +visualizzazione, se ne aprirà una seconda mentre la prima +resta +aperta fintanto che non venga chiusa.

+ + +

Puoi chiudere una linguetta della finestra di visualizzazione +coi tasti ^W (Ctrl + W) +sulla finestra. Chiudendo l'ultima linguetta chiudi anche la finestra.

+ + +

Naturalmente puoi chiudere la linguetta (e la finestra) col +bottone Chiudi Tab nella parte superiore della finestra stessa.

+ + +

Puoi vedere documenti successivi o precedenti della lista dei +risultati nella finestra di visualizzazione con i tasti Shift+Down +or Shift+Up +(dove Down e Up sono i tasti freccia).

+ + +

La finestra di visualizzazione ha una ricerca interna. Puoi +iniziare +la ricerca scrivendo una slash (/) all'interno del testo o tramite la +casella per la ricerca , immettendo il testo da cercare e premendo il +tasto cerca. Puoi +usare i tasti Seguente +e Precedente per trovare ricorrenze successive o precedenti. Puoi anche +usare il tasto F3, all'interno dell'area di testo, per trovare la +prossima ricorrenza.

+ + +

Se hai immesso dei termini di ricerca e usi i +tasti ^Up/^Down +per passare da un documento all'altro, la ricerca inizia con ogni nuovo +documento. Se il termine di ricerca è trovato, il cursore si +posiziona sulla prima ricorrenza.

+ + +
+ + +
+
Nessuna parola +
    + + +
  • + +

    Tutte le parole.

    + + +
  • + + +
  • + +

    Qualsiasi parola.

    + + +
  • + + +
  • + +

    None of the terms.

    + + +
  • + + +
  • + +

    Questa frase (le parole esatte nell'ordine preciso in +campi numerata).

    + + +
  • + + +
  • + +

    Parole simili (parole in qualsiasi ordine in campi +numerati).condizione

    + + +
  • + + +
  • + +

    Nome del file con Caratteri Jolly.

    + + +
  • + + +
+ + +
+ + +
+ + +

Altri campi possono essere creati cliccando sul bottone +Aggiungi condizione.

+ + +

Tutti i campi saranno tra loro combinati con le clausole AND o +OR. +Tutti i tipi di condizioni, ad eccezione di "Questa frase" e "Parole +simili" accettano un insieme di parole singole e frasi (racchiuse tra +virgolette). L'espansione (Stemming) viene fatta per tutte le parole +che non iniziano con una maiuscola, ma non per le frasi.

+ + +

La ricerca avanzata permette di cercare tra documenti di un +tipo specifico (ad esmpio: solo testo semplice, o testo rtf, o testo/HTML o application/pdf +ecc...). La selzione del tipo di file (mime) può essere +salvata +come default. (il filtro non sarà attivato al lancio di +recoll, +ma la lista sarà presente come era stata salvata).

+ + +

Si può anche restringere la ricerca ad un sotto +insieme delle +cartelle indicizzate. Se questa è un'opzione che usi spesso, +puoi anche pensare a fare diversi indici così da migliorare +la +performance.

+ + +

Per iniziare la ricerca clicca sul bottone Cerca o premi Enter in qualsiasi +campo di ricerca. Il +bottone nella finestra principale esegue sempre e solo una ricerca +semplice.

+ + +

Clicca sul link 'mostra stringa' in alto nella finestra +principale per vedere la stringa di ricerca applicata.

+ + +
+ + +
+
+

3.5. Il terminale di +esplorazione

+ + +

Recoll utilizza +automaticamente +l'espansione dei termini di ricerca ai loro derivati (ad esempio: +plurali/singolare, coniugazioni dei verbi). Ma ci sono altri casi in +cui l'estto termine di ricerca non è conosciuto. Ad esempio +potresti ricordarti la pronincia ma non come il termine viene scritto, +oppure conoscere solamente l'inizio della parola da cercare.

+ + +

Il terminale di esplorazione (lanciato tramite la sua piccola +icona nella finestra principale o dal menu 'Strumenti') +può essere usato per le ricerche nell'indice del + database. Ha tre modi operativi:

+ + +
+
+ + +
Caratteri Jolly
+ + +
+ +

In questo modo operativo si possono usare stringhe con +caratteri jolly (*, +?). ad esempio: xapi* +.

+ + +
+ + +
Espressioni regolari
+ + +
+ +

In questa modalità sono accettate le +espressioni regolari. Esempio: word[0-9]+ +.

+ + +
+ + +
Espansione grammaticale
+ + +
+ +

Questa modalità esegue la normale espansione +(stemming). +In questo senso è utile per mostrare il suo funzionamento.

+ + +
+ + +
Ortografia/Fonetica
+ + +
+ +

In questa modalità si inserisce il termine come +si pensa sia scritto e Recoll +farà del suo meglio per trovare termini inseriti nel suo +indice che suonino simili. Questa modalità usa Aspell, +che quindi deve essere installata sul vostro sistema +affinchè le +cose funzionino per il verso giusto. La lingua usata nella costruzione +del dizionario (cosa che avviene alla fine dell'indicizzazione) +è quella di sistema. Cose strane possono accadere se +più +lingue sono mischiate.

+ + +
+ + +
+ + +
+ + +

Nota che nel caso Recoll +non conosca l'inizio della parola da cercare(ad esempio un carattere +jolly come *asa), +l'espansione può richiedere un certo tempo perchè +la +ricercaviene fatta sull'indice completo. L'espansione al momento +è limitata ai primi 200 risultati nel caso di caratteri +jolly o +espressioni regolari.

+ + +

Un doppio clic su di un termine nella lista dei risultati lo +inserisce nella casella della ricerca semplice nella finestra +principale. Si può naturalmente nche copiare e incollare tra +la +lista dei risultati e la casella di ricerca.

+ + +
+ + +
+
+

3.6. Database multipli

+ + +

Database e indici multipli di Recoll +dpossono essere creati usando differenti cartelle di configurazione che +conterranno di norma differenti indici per differenti aree del file +system. Un indice specifico può essere selezionato per +aggiornarlo o per effettuare una ricerca usando la variabile di +sistema RECOLL_CONFDIR +oppure lìopzione -c +di recoll e recollindex.

+ + +

Una istanza di recollindex +può aggiornare o indicizzare solo un indice specifico.

+ + +

Una istanza di recoll +è anche associata ad un indice specifico, che è +quello +che viene aggiornato, ma si possono usare più indici +di Recoll per la +ricerca. Gli indici esterni possono essere selezionati tramite la +linguetta Indici esterni nel dialogo delle preferenze.

+ + +

La selezione dell'indice viene fatta in due fasi Un set di +indici +utilizzabili deve essere prima definito, e dopo si può +indicare +un sotto insieme di indici da usare per la ricerca. Naturalmente questi +parametri sono conservati da una esecuzione del programma ad un'altra +(sono registrati separatamente per ogni configurazione di Recoll). Il set di tutti gli +indici è generalmente fisso, mentre l'indice attivo viene +probabilmente cambiato frequentemente.

+ + +

L'indice principale (definito da RECOLL_CONFDIR) +è sempre attivo. +Se ciò non è desiderabile, puoi far sì +che la tua +configurazione punti all'indicizzazione di una cartella vuota.

+ + +

Poichè costruire tutti gli indici può +essere noioso se +fatto dall'interfaccia grafica si può usare la variabile di +sistema RECOLL_EXTRA_DBS +per costruire il set +iniziale. Questo lo fa normalmente l'amministratore del sistema +così che non debba farlo ogni utente. La variabile dovrebbe +definire una lista separata da due punti delle cartelle da indicizzare. +Ad esempio:

+ + +
export RECOLL_EXTRA_DBS=/qualche/cartella/xapiandb:/qualche/altra/db
+ + +

Un tipico scenario d'uso per gli indici multipli per un +amministratore potrebbe essere la creazione di un indice di dati comuni +su cui tu potresti fare una ricerca e un indice per i tuoi dati +personali. Naturalmente ci sono altre possibilità. +Ci sono molti casi in cui conosci il sotto insieme di cartelle che devi +esaminare per trovare il risultato e quindi , restringendo il campo di +ricerca, è possibile aumentare l'efficenza e la precisione +della +ricerca stessa. Ciò può essere fatto anche con +l'opzione +che limita le cartelle su cui si effettua la ricerca nella finestra +della ricerca avanzata, ma l'indicizzazione multipla può +aumentare la performance e valere la pena di essere provata.

+ + +
+ + +
+
+

3.7. Storia dei documenti

+ + +

I documenti che hai visto col visualizzatore o con un +programma +esterno sono annotati nello storico dei documenti e quindi ricordati. +Puoi vedere la lista dello storico con la voce di menu Strumenti/Storia documenti.

+ + +
+ + +
+
+

3.8. Ordinare il risultato della +ricerca

+ + +

I documenti nella lista dei risultati sono normalmente +ordinati in +base della loro rilevanza. E' possibile specificare un diverso criterio +usano la finestra di dialogo Ordina risultati +(localizzata nel menu Strumenti).

+ + +

Lo strumento ordina un numero di documenti ordinati per +rilevanza in base a determinati criteri. I criteri attualmente sono la data e il tipo mime.

+ + +

La scelta per l'ordinamento resta invariata sino a quando non +viene +cambiata o il programma non viene chiuso. Il tipo di ordinamento +è indicato all'inizio della lista dei risultati.

+ + +
+ + +
+
+

3.9. Consigli per la ricerca, +scorciatoie

+ + +
+

Completamento della parola. I +tasti Esc Spaceifinchè +si sta scrivendo una parola nella casella di ricerca semplice +completano la stessa se essa è unica nel database, +altrimenti +aprono una finestra da cui si pppuò scegliere fra le parole +suggerite.

+ + +
+ + +
+

Prendere nuove parole dalla lista dei risultati o +dalla finestra di visualizzazione. +Un doppio clic su una parola nella lista dei risultati o nel testo +della finestra di visualizzazionie copia la stessa nella casella di +ricerca semplice.

+ + +
+ + +
+

Disabilitare l'espansione (stemming). +Scrivendo una parola nella casella di ricerca con la prima lettera +maiuscola disabilita l'espansione (nessuna ricerca per casino +se hai inserito Casa). +Questo è l'unico caso in cui le maiuscole o minuscole hanno +importanza nella ricerca. E' anche possibile eliminare l'espansione +(stemming) o cambiare la lingua nelle preferenze.

+ + +
+ + +
+

Frasi. Per cercare una frase basta +racchiuderla tra virgolette. Esempio: +"user manual" +cercherà per tutte le ricorrenze di 'user' seguito +immediatamente da 'manual'. Puoi anche usare il campo 'Questa frase' +nel dialogo avanzato di ricerca con lo stesso effetto. +Frasi possono essere immesse insieme a parole sia nella casella di +ricerca semplice che nelle caselle della ricerca avanzata, con +escluione della casell 'Questa frase'.

+ + +
+ + +
+

Scorrere la lista dei risultati nella finestra di +visualizzazione (1.5). I tasti  Shift-Down +o Shift-Up (Shift ++una freccia) nella finestra di visualizzazione mostra il documento +successivo o precedente della lista dei risultati. Ogni ricerca +secondaria attualmente attiva verrà eseguita nel nuovo +documento.

+ + +
+ + +
+

Forzare l'apertura di una nuova finestra di +visualizzazione (1.6). Con Shift+Click +sul link Preview +di un risultato della lista dei risultati si apre una nuova finestra di +visualizzazione invece di una nuova linguetta su quella già +visualizzata.

+ + +
+ + +
+

Aggiungi automaticamente frase (1.5). +Questa opzione +può essere impostata nella finestra di configurazione. +Quando +è settata sarà costruita automaticamente una +frase con le +parole della ricerca e aggiunta alla ricerca se è impostata +a +'Qualsiasi parola'I. Ciò non cambia radicalmente il +risultato +della ricerca, ma aumenta la rilevanza per quei documenti dove le +parole cercate costituiscono una frase. ad esempio: cercando le +parole virtual reality +saranno comunque +trovati tutti i documenti contenenti le parole 'virtual', 'reality' o +entrambe, ma in cima alla lista appariranno i documenti, se ci sono, +che contengono la frase 'virtual reality.

+ + +
+ + +
+

Trovare documenti simili. Se nel menu che +appare cliccando +col taso destro nella lista dei risultati si sceglie la voce 'Documenti +simili', un numero di parole 'interessanti' contenute nel documento +selezionato viene messo nella casella di ricerca semplice e viene +avviata una nuova ricerca. In questo modo, eventualmente editando +ulteriormente la casella di ricerca semplice, puoi trovare documenti in +qualche maniera simili o correlati al primo.

+ + +
+ + +
+

Nome file. Durante l'indicizzazione sono +aggiunti anche i nomi dei files. Puoi quindi inserirli come un normale +termine di ricerca (Recoll +indicizzava tutte le cartelle come termini. Questo però +è +stato abbandonato non sembrando molto utilel). In alternativa puoi +usare l'opzione 'Nome file' e la ricerca avverrà +esclusivamente +tra i nomi dei files (in tal caso è possibile usare i +caratteri jolly).

+ + +
+ + +
+

Stringa di ricerca. Puoi vedere la stringa +con cui è +stata effettuata la ricerca, incluse le espansioni e gli operatori +Booleani, cliccando sul link 'mostra stringa' all'inizio della lista +dei risultati.

+ + +
+ + +
+

Chiudere la finestra di visualizzazione. Il +tasto ^W in una linguetta, la +chiude +(e, se questa è l'ultima linguetta, chiude anche la +finestra). Il tasto Esc +chiude tutte le linguette e la finestra di visualizzazione.

+ + +
+ + +
+

Chiudere il programma. Il tast ^Q quasi dappertutto chiude il +programma.

+ + +
+ + +
+ + +
+
+

3.10. Personalizzare l'interfaccia +di ricerca

+ + +

E' possibile personalizzare alcuni aspetti dell'interfaccia di +ricerca usando la voce 'configurazione ricerca' del menu 'Preferenze'.

+ + +

Ci sono due linguette nella finestra di dialogo che riguardano +l'interfaccia stessa e i criteri adottati per la ricerca e la +presentazione dei risultati.

+ + +
+

Interfaccia utente:

+ + +
    + + +
  • + +

    Numero di risultati +per pagina

    + + +
  • + + +
  • + +

    Fonts per la lista dei +risultati: +Ci sono molte informazioni visualizzate nella lista dei risultati e +potresti voler personalizzare i caratteri e la loro dimensioneT. I +caratteri usati da Recoll +sono quelli della tua configurazione di  QT(prova il +comando qtconfig).

    + + +
  • + + +
  • + +

    Stringa di +formattazione dei risultati: +ti permette di cambiare la presentazione di ciascun risultato nella +lista. Usa string del tipo qt-html dove le seguenti sostituzioni, in +modo simile al comando +printf %, vengono fatte:

    + + + +
      + + +
    • + +
      + +

      %A. Riassunto

      + + +
      + + +
    • + + +
    • + +
      + +

      %D. Data

      + + +
      + + +
    • + + +
    • + +
      + +

      %K. Parole chiave (se ci sono)

      + + +
      + + +
    • + + +
    • + +
      + +

      %L. links Preview e Edit

      + + +
      + + +
    • + + +
    • + +
      + +

      %M. Tipo Mime

      + + +
      + + +
    • + + +
    • + +
      + +

      %N. Numero del risultato

      + + +
      + + +
    • + + +
    • + +
      + +

      %R. Rilevanza in %

      + + +
      + + +
    • + + +
    • + +
      + +

      %S. Grandezza

      + + +
      + + +
    • + + +
    • + +
      + +

      %T. Titolo

      + + +
      + + +
    • + + +
    • + +
      + +

      %U. Url

      + + +
      + + +
    • + + + +
    + + +I valori di default value per la stringa sono: + +
    %R %S %L &nbsp;&nbsp;<b>%T</b><br>
    %M&nbsp;%D&nbsp;&nbsp;&nbsp;<i>%U</i><br>
    %A %K

    + + +Puoi provare, ad esempio, la seguente stringa per una lista +più simile all'esperienza del Web: + +
    <u><b><a href="P%N">%T</a></b></u>&nbsp;%R&nbsp;%D<br>
    %A<font color=#B22C1D>%U - %M - %S</font> - %L

    + + +Il formato dei links Preview e Edit è <a +href="Pdocnum"> +and <a href="Edocnum"> +where docnum +è quello che %N dovrebbe stampare. Questo rende il titolo +nel +formato dell'esempio un link per la finestra di visualizzazione.
    + + +
    + + +
  • + + +
  • + +

    Browser HTML: +qui puoi scegliere il browser preferito, che verrà avviato +col menu 'Aiuto' per leggere il manuale utente. Puoi inserire +semplicemente il nome, se il browser è nel tuo path, oppure +l'indirizzo completo.

    + + +
  • + + +
  • + +

    Mostra le icone nella +lista dei risultati: +le icone nella lista dei risultati possono essere disabilitate. Portano +via molta memoria e tutto sommato non contengono informazioni +essenziali.

    + + +
  • + + +
  • + +

    Inizia la ricerca +quando digiti uno spazio: +se lo contrassegni, la ricerca inizia non appena digiti uno spazio +nella casella di ricerca. Questo ti permette di vedere i risultati +prima di immettere una seconda parola. E' disabilitato per default, che +ti piaccia o no...

    + + +
  • + + +
+ + +
+ + +
+ + +
+ + +
+

Parametri di ricerca:

+ + +
    + + +
  • + +

    Lingua +per l'espansione +grammaticale: l'espansione (stemming) dipende evidentemente dalla +lingua. Qui puoi scegliere tra le lingue con cui sono stati costruiti i +database di espansione durante l'indicizzazione (questo viene stabilito +nel  file +principale di configurazione), o pià tardi +aggiunto col comando recollindex +-s +(Vedi il manuale per recollindex). Le lingue di espansione aggiunte +dinamicamente saranno cancellate alla successiva indicizzazione, a meno +che non siano aggiunte al file di configurazione principale.

    + + +
  • + + +
  • + +

    Costruisci +dinamicamente il riassunto: questo decide se Recoll +cerca di costruire un riassunto del documento quando lo mostra nella +lista dei risultati. I riassunti vengono costruiti prendendo +informazioni dal contesto del documento attorno alle parole trovate. +Questo può rallentare la visualizzazione della lista dei +risultati per grossi documenti e, se vuoi, puoi disabilitarlo.

    + + +
  • + + +
  • + +

    Rimpiazza i riassunti +esistenti nel documento: questo decide se costruire un +riassunto al posto un riassunto già esistente nel documento.

    + + +
  • + + +
  • + +

    Numero caratteri per +il riassunto: scegli quello che preferisci...

    + + +
  • + + +
  • + +

    numero di parole +del riassunto per +ogni termine nel documento: quante parole devono essere mostrate +intorno ad ogni ricorrenza trovata nel documento.

    + + +
  • + + +
+ + +
+ + +
+ + +
+ + +
+

Indici +esterni: +Questa linguetta ti permette di navigare eventuali altri indici su cui +vorresti effettuare la ricerca. Gli indici esterni sono assegnati dalla +cartella del loro database (ad esempio: /home/someothergui/.recoll/xapiandb, +/usr/local/recollglobal/xapiandb).

+ + +
+ + +

Una volta scelto, l'indice apparirà nella lista +'Tutti gli +indici', e puoi scegliere quale usare spstandolo alla/dalla lista +'Indici attivi'.

+ + +

Il tuo database (quello della configueazione attuale) +è +sempre implicitamente attivo. Se ciò non è +desiderabile, +puoi sempre fare una configurazione che indicizzi, ad esempio, una +cartella vuota.

+ + +
+ + +
+ + +
+
+

Capitolo +4. Installazione

+ + +
+

4.1. Installare un pacchetto +pre-compilato

+ + +

L'installazione binaria di Recoll è sempre lincata +staticamente alla libreria di xapian , e non ha altre +dipendenze. Devi solo eventualmente installare i  pacchetti esterni per +i tipi di files che vuoi indicizzare diversi da testo, HTML ed e-mail.

+ + +
+
+

4.1.1. Installazione con +un programma di installazione

+ + +

Se usi un sistem del tipo BSD o sistemi che usano pacchetti +pre-compilati (RPM o altri), segui semplicemente le procedure usuali, e +magari dai un'occhiata alla  sezione +di configurazione (anche se non è necessario per +provare il programma con i parametri di default).

+ + +
+ + +
+
+

4.1.2. Installare Recoll +pre-compilato

+ + +

I pacchetti binari sono semplicemente un insieme di cartelle +compresse dove solo le parti utili sono conservate (gli esguibili e la +configurazione di esempio).

+ + +

I binari eseguibili sono compilati con un link statico alla +libreria libxapian e libiconv, tper rendere l'installazione +più semplice(nessuna dipendenza). Questo comunque significa +che +non potete cambiare le versioni che sono state usate.

+ + +

Dopo l'estrazione del file tar, procedi con l'installazione +come se avessi compilato il tutto da sorgente (ciò significa +dare il comando make install). L'albero delle +cartelle va in /usr/local.

+ + +

Puoi inoltre desiderare di installare le applicazioni esterne +necessarie per processare determinati tipi di files (ad esempio: +acrobat, postscript ...). Vedi la prossima sessione.

+ + +

Alla fine, se vuoi, dòà un'occhiata +alla  sezione di +configurazione.

+ + +
+ + +
+ + +
+
+

4.2. Pacchetti esterni +utilizzabili

+ + +

Recollusa +applicazioni esterne per +indicizzare alcuni tipi di files. +Devi quindi installare quelle necessarie ai tipi di files che vuoi +indicizzare (queste sono dipendenze di run-time. Nessuna di queste +applicazioni è necessaria per compilare Recoll):

+ + +
    + + +
  • + +

    Openoffice: è supportato nativamente, ma +necessita del programma unzip, +che quindi deve essere installato.

    + + +
  • + + +
  • + +

    PDF: pdftotext è parte del pacchetto Xpdf.

    + + +
  • + + +
  • + +

    Postscript: pstotext.

    + + +
  • + + +
  • + +

    MS Word: antiword.

    + + +
  • + + +
  • + +

    MS Excel and PowerPoint: catdoc.

    + + +
  • + + +
  • + +

    RTF: unrtf

    + + +
  • + + +
  • + +

    dvi: dvips

    + + +
  • + + +
  • + +

    djvu: DjVuLibre

    + + +
  • + + +
  • + +

    MP3: Recoll +usa il comado id3info del +pacchetto id3lib per estrarre i tag. Senza +questo pacchetto, solo i nomi saranno indicizzati.

    + + +
  • + + +
+ + +

Text, HTML, cartelle e-mail e files Openoffice sono processati +internamente.

+ + +
+ + +
+
+

4.3. Compilare da sorgente

+ + +
+

4.3.1. Prerequisiti

+ + +

Come minimo è necessario scaricare e installare il +pacchetto xapian core (Recoll attualmente usa la +versione 0.attualmente usa le versionidevelopment currently +uses +version 3.3.5, ma qualsiasi versione 3.3 probabilmente è OK).

+ + +

Quasi certamente sarete in grado di trovare un pacchetto +binario per qt +per il vostro sistema, ma probabilmente dovrete compilare Xapian, ma questo non +è difficile (se stai usando FreeBSD, c'è un +port).

+ + +

Ti serve anche libiconv. +Recoll attualmente usa la +versione 1.9 +(questo non dovrebbe essere critico). Sui sistemi Linux, l'interfaccia iconv fa +parte di libc e quindi non dovrebbe essere necessario fare niente di +speciale.

+ + +
+ + +
+
+

4.3.2. Compilazione

+ + +

Recoll +è stato compilato su Linux (redhat7.3, mandriva 2005/6, +Fedora Core 3/4/5, Ubuntu Edgy 64bit), FreeBSD e Solaris 8. Se lo +compili su un altro sistema, Idesidererei +vivamente ricevere eventuali patches.

+ + +

A seconad della configurazione di qt +nel vostro sistema, potreste dover settare le variabili di +sistema QTDIR e QMAKESPECS:

+ + +
    + + +
  • + +

    QTDIR dovrebbe +puntare alla cartell superiore a quella che contiene i files 'include' +di qt (ad esempio: se qt.h +è in /usr/local/qt/include/qt.h, +QTDIR dovrebbe essere /usr/local/qt).

    + + +
  • + + +
  • + +

    QMAKESPECS +dovrebbe puntare ad una delle sotto-cartelle mkspecs di qt (ad esempio: linux-g++).

    + + +
  • + + +
+ + +

Su molti sistemi Linux, QTDIR +è settata dallo script di login, e +QMAKESPECS inon +è becessaria perchè c'è un link +simbolico in mkspecs/.

+ + +
+

Opzioni per configure: --without-aspell +disabilita il codice per la ricerca fonetica. --with-fam +o --with-inotify +abilita il codice per l'indicizzazione in tempo reale real time +indexing. Il supporto inotify è abilitato di default nei +sistemi +Linux recenti.

+ + +
+ + +

Procedura normale:

+ + +
 cd recoll-xxx
configure
make +
+ + +

Piccola auto-configurazione. Lo script di configurazione +essenzialmente linca uno dei files specifici del sistema nella cartella +mk alla cartella mk/sysconf. Se il vostro sistema non è +attualmente conosciuto ve lo dirà e, se volete, potete +copiare e +modificare manualmente uno dei files esistenti (il nome del file +dovrebbe essere il risultato del comando uname -s).

+ + +
+ + +
+
+

4.3.3. Installazione

+ + +

Dai il comado make +install oppure esegui recollinstall +prefix, +nella cartella root. Questo copierà gli eseguibili nella +cartella prefix/bin +e gli esempi di configurazione, +scripts e altri dati nella cartella prefix/share/recoll.

+ + +

Se il prefisso di installazione dato al comando recollinstall +è differente da quello usato eseguendo il comando configure, +dovete settare la variabile di sistema RECOLL_DATADIR +per indicare dove sono i dati comuni.

+ + +

Potete poi procedere alla  configurazione.

+ + +
+ + +
+ + +
+
+

4.4. Panoramica della +configurazione

+ + +

La maggior +parte dei parametri specifici della GUI di Recoll sono +determinati attraverso il menu 'Preferenze'e salvate nlla cartella +standard delle applicazion QT ($HOME/.qt/recollrc). +probabilmnete non hai alcuna necessità di editare tale file.

+ + +

Per altre opzioni, Recoll +usa files di +configurazione testuali. Al momento devi editarli a mano +(c'è +ancora qualche speranza per uno strimento di configurazione grafico in +futuro). La più accurata documentazione per i parametri di +configurazione si trova nei commenti negli stessi files di default e +qui quindi troverai una semplice panoramica.

+ + +

Ci sono due insiemi di files di configurazione. Quelli per la +configurazione generale del sistema si trovano nella cartella /usr/[local/]share/recoll/examples, +e definiscono i valori di default per tutto il sistema. Un insieme +parallelo di files di configurazione esiste nella cartella +.recoll nella tua cartella +home. Questa cartella può essere cambiata con la variabile +di sistema RECOLL_CONFDIR +o con l'opzione -c per recoll +e recollindex.

+ + +

Se la cartella .recoll +non esiste, essa viene creata lanciando la prima volta recoll o recollindex, +e viene riempita con un insieme vuoto di files di configurazione. recoll vi dà la scelta +se editare i files di configurazione prima di iniziare la creazione +dell'indice, recollindex +invece procederà immediatamente.

+ + +

Tutti ifiles di configurazione hanno lo stesso formato. Ad +esempio, +un piccolo estratto del file di configurazione principale +può +essere simile al seguente::

+ + +
 # Space-separated list of directories to index.
topdirs = ~/docs /usr/share/doc

[~/somedirectory-with-utf8-txt-files]
defaultcharset = utf-8

+ + +

Ci sono tre specie di linne:

+ + +
    + + +
  • + +

    Commenti (iniziano con #) o sono vuoti.

    + + +
  • + + +
  • + +

    Settaggio dei parametri (nome = +valore).

    + + +
  • + + +
  • + +

    Definizione delle sezioni ([nome di qualche cartella]).

    + + +
  • + + +
+ + +

La definizione delle sezioni permette di ridefinire alcuni +parametri  per le sotto-cartelle. Restano effettivi +sinchè +viene trovata un'altra definizione di sezione, o si arriva alla fine +del file. Alcuni dei parametri usati per l'indicizzazione sono +considerati partendo dalla cartella attuale e salendo. Non tutti i +parametri possono essere ridefiniti in maniera comprensibile, ma questo +sarà spiegato di seguito nella prossima sezione.

+ + +

La tilde (~) indica l'indirizzo completo della +cartella dell'utente.

+ + +

Spazi vuoti sono usati come separatori nelle liste. Elementi +che +contengono spazi devono pertanto essere racchiusi tra virgolette.

+ + +
+
+

4.4.1. File di +configurazione principale

+ + +

recoll.conf +è il file di configurazione principale Definisce cosa +indicizzareIt  (cartella radice e cose da ignorare), e il set +di caratteri di default da usare per i documenti che non lo definiscono +specificamente al loro interno.

+ + +

La configurazione di default indicizzerò la vostra +cartella home intera. Se questo non va bene lanciate  recoll +per creare un set di configurazione vuoto, cliccate su Cancel, ed editate i files di +configurazione prima di lanciare nuovamente recoll (o recollindex). +Verrà così iniziata l'indicizzazione, cosa che +può richiedere un certo tempo.

+ + +

Parametri:

+ + +
+
+ + +
topdirs
+ + +
+ +

Specifica la lista di cartelle e/o files da indicizzare +(recursivamente per le cartelle). L0indicizzazione non segue eventuali +liks simbolici all'interno dell'albero delle cartelle. Se la cartella +radice è un link simbolico, l'indicizzazione non inizia e +viene mostrato un avviso di errore.

+ + +
+ + +
dbdir
+ + +
+ +

E' il nome della cartella Xapian dei dati. La +cartella, se necessario, verrà creata all'inizio +dell'indicizzazione. Se non è un indirizzo assoluto, +verrà interpretato come relativo alla cartella di +configurazioneI.

+ + +
+ + +
skippedNames
+ + +
+ +

Una lista di cartelle e nomi di files, separati da uno +spazio vuoto, di ciò che deve essere completamente ignorato +dal processo di indicizzazione. The list defined in La lista di default +è:e default file is:

+ + + +
*~ #* bin CVS Cache caughtspam tmp
+ + + +

Alla lista possono essere aggiunte sotto-cartelle, che +però devono essere nell'albero delle cartelle definite in topdirs.

+ + + +

Le cartelle presenti in topdirs +non risentono di eventuali omonimi in skippedNames +(vale a dire che una cartella scritta in topdirs +viene indicizzata comunque, anche se il suo nome compare nella lista di + skippedNames).

+ + + +

La lista della configurazione di default non esclude le +cartelle nascoste (nomi preceduti da un punto), il che significa che +verranno indicizzte anche alcune cose che non vorreste. D'altra parte i +programmi di posta, come thunderbird, +normalmente salvano i messaggi in cartelle nascoste e probabilmente +volete indicizzarli. Una possibile soluzione è avere .* in skippedNames, +e aggiungere qualcosa come  ~/.thunderbird +o ~/.evolution in topdirs.

+ + +
+ + +
loglevel,daemloglevel
+ + +
+ +

Livello di verbosità per recoll e recollindex. +Un valore di 4 produce molti messaggi di +debug/informationi. 2 solo una lista di errori. Daemversion +è specifico al demone che monitorizza l'indicizzazione.

+ + +
+ + +
logfilename, +daemlogfilename
+ + +
+ +

Dove vanno i messaggi. 'stderr' può essere +usato come valore speciale, ed è quello di default.

+ + +
+ + +
filtersdir
+ + +
+ +

La cartella ove cercare gli sripts esterni necessari ad +indicizzare alcuni tipi di files. Non dovrebbe esserci motivo per +cambiarlo, a meno che non vogliate modificare gli script originali +mettendoli altrove. Il valore può essere ridefinito per ogni +sott-cartella.

+ + +
+ + +
indexstemminglanguages
+ + +
+ +

Una lista di lingue per le quali verrà +costruito il database per l'espansione grammaticale. Guardate +recollindex(1) per possibili valori (man recollindex). Puoi aggiungere +un database per qualsiasi lingua usando il comando recollindex +-s, ma tale database verrà cancellato alla +successiva re-indicizzazione Soltanto i database delle ingue listate +nella configurazione sono permanenti.

+ + +
+ + +
defaultcharset
+ + +
+ +

Nome del set di caratteri usati per files che non hanno +una definizione dei caratteri (ad esempio: files plain text). +Può essere definito per ogni sub-cartella, se non +è dato alcun set di caratteriviene utilizzato quello di +sistema (LC_ALL, +LC_CTYPE, LANG), or iso8859-1.

+ + +
+ + +
guesscharset
+ + +
+ +

Decide se cercare di indovinare il set di caratteri del +documanto qualora questo non sia specificato nel documento stesso +(ad esempio: files plain text). Ciò non funziona bene in +molti casi, e probabilmente non dovrebbe essere usato.

+ + +
+ + +
usesystemfilecommand
+ + +
+ +

Decide se usare il comando di sistema file -i per determinare il tipo +mime del file (la procedura normale usa l'associazione dei suffissi +come definiti nel file  mimemap). +Ciò può essere utile per files senza suffisso, ma +causa anche l'indicizzazione di molti strani files di "testo".

+ + +
+ + +
indexallfilenames
+ + +
+ +

Recoll +indicizza i nomi dei files in una speciale sezione del database per +permettere le ricerche dei nomi dei files anche con i caratteri jolly +Questo parametro decide se indicizzare solo i nomi di files che hanno +un suffisso che ne permette l'indicizzazione completa, o se +indicizzarli tutti indipendentemente dal suffisso.

+ + +
+ + +
idxabsmlen
+ + +
+ +

Recoll salva +un riassunto per ogni file indicizzato nel database. Questo +è quello che viene mostrato nella lista dei risultati senza +dover leggere il file originale. Questo parametro definisce la +dimensione del riassunto salvato (che può provenire +dall'attuale sezione o dall'inizio del testo). Il valore di default +è +250 caratteri.

+ + +
+ + +
iconsdir
+ + +
+ +

Il nome della cartella dove si trovano le icone che +vengono mostrate nella lista dei risultati. La puoi cambiare se vuoi +immagini differenti.

+ + +
+ + +
+ + +
+ + +
+ + +
+
+

4.4.2. Il file mimemap

+ + +

mimemap specifica +l'estensione mime del file per la sua mappatura nei tipi mime.

+ + +

Per i files senza un'estensione o con un'estensione non +riconosciuta viene eseguito il comando di sistema file +-i per determinarne  il tipo mime (ciò +può essere disbilitato nel file di configurazione).

+ + +

La mappatura può essere specificata su una base di +sotto-cartelle, cosa che può essere utile in certe +occasioni. Esempio: i logs di gaim hanno un'estensione .txt ma dovrebbero essere +trattai diversamente, cosa che è possibile perchè +essi generalmente sono posti in ina specifica cartella.

+ + +

mimemap ha anche +una variabile recoll_noindex +che è una lista di suffissi. I files con tali suffissi +vengono ignorati (il che evita decompressioni o esecuzioni non +necessarie ). Questo è una duplicazione parziale +della variabile skippedNames +inel file di configurazione principale, però con due +differenza: non riguarda le cartelle, e non può dipendere +dalla locazione nel file system (è un parametro di +configurazione generale). Potete quindi fare con skippedNames tutto quello che fa recoll_noindex. L'ultimo +parametro è usato normalmente per cose che si sa non sono +indicizzabili con una determinata versione di Recoll. Mettendole in questo +file si evita di toccare la variabile skippedNames +più orientata all'utente e alla localizzazione.

+ + +
+ + +
+
+

4.4.3. Il file mimeconf

+ + +

mimeconf +specifica come vengono trattati i vari tipi mime per l'indicizzazione, +e quali icone devono essere mostrate nella lista dei risultati di recoll.

+ + +

Cambiare i parametri nella sezione [index] non +è probabilmente una buona idea a meno che non siate +sviluppatori di Recoll.

+ + +

La sezione [icons] permette di cambiare le icone che +vengono mostrate nella lista dei risultati (i nomi sono quelli +delle immagini png, senza suffisso, che si trovano nella cartella iconsdir (specificata in recoll.conf).

+ + +
+ + +
+
+

4.4.4. Il file mimeview

+ + +

mimeview +specifica il programma che deve essere lanciato quando clicchi su Edit +nella lista dei risultati. ad esempio: HTML viene normalmente aperto +con firefox, ma potresti +preferire Konqueror, il +programma openoffice.org +potrebbe essere chiamato oofice +invece di openoffice etc.

+ + +

Cambiamenti a questo file possono essere fatti direttamente o +attraverso il dialogo 'Preferenze' del programma recoll.

+ + +

Come tutti gli altri files di configurazione, l'uso normale +è avere un mimeview +nella vostra cartella personale, con solo le voci non di default, che +si sovrapporrà a quello centrale per tutto il sistema.

+ + +

Per favore prendi nota che queste 'entrate' devono essere +fatte in una sezione nominata [view] +section.

+ + +
+ + +
+
+

4.4.5. Esempio

+ + +

Esempio:

+ + +

pensiamo di aggiungere la possibilità di +indicizzare i files +con estensione .lyx (file fatti col programma Lyx) in modo da poter +avere una visualizzazione corretta degli stessi e di poterli aprire con +il programma Lyx quando clicchiamo sul link edit. Dovremo, so +già non l'abbiamo, procurarci dal sito di recoll lo script +rcllyx necessario per l'indicizzazione dei files .lyx.
+ + +Tale script è un file di testo e va messo nella cartella +/usr/share/recoll/filters e reso eseguibile.

+ + +

Vogliamo inoltre poter aprire i file con estensione .kwd e +.kwt +(flies fatti con Kword) con il polor programma: Kword. (Questi files +non potranno essere indicizzate, se non con il loro nome (quindi niente +visualizzazione, ma possibilità di apertura degli stessi).

+ + +Per prima cosa dobbiamo trovare il tipo mime dato dal sistema +ai  +files di Lyx e di Kword. Troveremo che il tipo per ifiles di Lyx +è application/x-lyx +mentre per i files di Kword application/x-kword
+ + +(La procedura è molto semplice. Ad esempi con KDE si +apre konqueror, il menu impostazioni/associazione caratteri, +si +mette l'estensione del file nell'apposita casella e si prende nota +dell'associazione corrispondente.)
+ + +
+ + +A questo punto possiamo procedere. Di seguito i tre files modificati, +dove le linee in neretto + si riferiscono ai files Lyx, mentre quello rosse +ai files di Kword.
+ + +
+ + +MIMEMAP
+ + +# @(#$Id: usermanual-italian.html,v 1.1 2007-02-02 10:05:22 dockes Exp $  (C) +2004 J.F.Dockes
+ + +# Recoll: associations of file name extensions to mime types
+ + +
+ + +.txt = text/plain
+ + +.text = text/plain
+ + +.d    = text/plain
+ + +.lyx = application/x-lyx
+ + +.kwt += application/x-kword
+ + +.kwd += application/x-kword
+ + +
+ + +# Source files. Defining them as text/x-c will enable ext viewer. If
+ + +# text/plain they will be somewhat indexed
+ + +.cpp = text/x-c
+ + +.h   = text/x-c
+ + +.c   = text/x-c
+ + +.cc  = text/x-c
+ + +
+ + +.rtf  = text/rtf
+ + +
+ + +.html = text/html
+ + +.htm = text/html
+ + +.shtml = text/html
+ + +.php = text/html
+ + +
+ + +.pdf = application/pdf
+ + +
+ + +.ps = application/postscript
+ + +.eps = application/postscript
+ + +.ai = application/postscript
+ + +
+ + +.dvi = application/x-dvi
+ + +
+ + +.djvu = image/vnd.djvu
+ + +
+ + +.gz = application/x-gzip
+ + +.Z = application/x-gzip
+ + +.bz2 = application/x-bzip2
+ + +#.Z  = application/x-compress
+ + +
+ + +.doc = application/msword
+ + +.ppt = application/vnd.ms-powerpoint
+ + +.xls = application/vnd.ms-excel
+ + +
+ + +# OpenOffice / opendocument. We handle opendocument as old openoffice +files
+ + +# for now
+ + +.sxc = application/vnd.sun.xml.calc
+ + +.ods = application/vnd.sun.xml.calc
+ + +.stc = application/vnd.sun.xml.calc.template
+ + +.sxd = application/vnd.sun.xml.draw
+ + +.std = application/vnd.sun.xml.draw.template
+ + +.sxi = application/vnd.sun.xml.impress
+ + +.odp = application/vnd.sun.xml.impress
+ + +.sti = application/vnd.sun.xml.impress.template
+ + +.sxm = application/vnd.sun.xml.math
+ + +.sxw = application/vnd.sun.xml.writer
+ + +.odt = application/vnd.sun.xml.writer
+ + +.sxg = application/vnd.sun.xml.writer.global
+ + +.stw = application/vnd.sun.xml.writer.template
+ + +
+ + +
+ + +.wpd = application/vnd.wordperfect
+ + +.rtf = text/rtf
+ + +
+ + +.mp3 = audio/mpeg
+ + +.png = image/png
+ + +.jpg = image/jpeg
+ + +
+ + +# A list of stuff that we don't want to touch at all (for now). Having +the
+ + +# suffixes listed in there speeds up things quite a lot by avoiding
+ + +# unneeded decompression or 'file' calls. File names still get indexed +if
+ + +# indexallfilenames is set
+ + +recoll_noindex = .tar.gz .tgz .tar.bz2 .tbz .log.gz .md5 .map \
+ + +       .m4 .tcl +.js .sh .pl .awk \
+ + +       .o .lib +.dll .a \
+ + +       .dat .bak +.rdf .log .db .ini .msf .pid \
+ + +       .gnm +.gnumeric .tex \
+ + +       .gif .bmp +.xpm \
+ + +       ,v ~ #
+ + +
+ + +# Special handling of .txt files inside ~/.gaim directory
+ + +[~/.gaim]
+ + +.txt = text/x-gaim-log
+ + +
+ + +MIMECONF
+ + +# @(#$Id: usermanual-italian.html,v 1.1 2007-02-02 10:05:22 dockes Exp $  +(C) 2004 J.F.Dockes
+ + +
+ + +# Recoll : associations of mime types to processing filters.
+ + +# There are different sections for decompression, 'interning' for +indexing
+ + +# and preview, and external viewers
+ + +
+ + +## #######################################
+ + +# Decompression: these types need a first pass to create a temp file to
+ + +# work with. We use a script because uncompress utilities usually work +in
+ + +# place, which is not suitable.
+ + +#
+ + +# The %t parameter will be substituted to the name of a temporary +directory
+ + +# by recoll. This directory is guaranteed empty when calling the filter
+ + +#
+ + +# The %f parameter will be substituted with the input file.
+ + +#
+ + +# The script (ie: rcluncomp) must output the uncompressed file name on
+ + +# stdout.
+ + +application/x-gzip  =  uncompress rcluncomp gunzip %f +%t
+ + +application/x-compress = uncompress rcluncomp gunzip %f %t
+ + +application/x-bzip2 =  uncompress rcluncomp bunzip2 %f %t
+ + +
+ + +## ###################################
+ + +# Filters for indexing and internal preview.
+ + +# The external (exec) filters  output the document in simple +html format,
+ + +# have a look at the scripts.
+ + +[index]
+ + +application/msword = exec rcldoc
+ + +application/pdf = exec rclpdf
+ + +application/postscript = exec rclps
+ + +application/vnd.ms-powerpoint = exec rclppt
+ + +application/vnd.ms-excel = exec rclxls
+ + +application/vnd.sun.xml.calc = exec rclsoff
+ + +application/vnd.sun.xml.calc.template = exec rclsoff
+ + +application/vnd.sun.xml.draw = exec rclsoff
+ + +application/vnd.sun.xml.draw.template = exec rclsoff
+ + +application/vnd.sun.xml.impress = exec rclsoff
+ + +application/vnd.sun.xml.impress.template = exec rclsoff
+ + +application/vnd.sun.xml.math = exec rclsoff
+ + +application/vnd.sun.xml.writer = exec rclsoff
+ + +application/vnd.sun.xml.writer.global = exec rclsoff
+ + +application/vnd.sun.xml.writer.template = exec rclsoff
+ + +application/x-dvi = exec rcldvi
+ + +audio/mpeg = exec rclmedia
+ + +image/vnd.djvu = exec rcldjvu
+ + +message/rfc822 = internal
+ + +text/html  = internal
+ + +text/plain = internal
+ + +text/rtf = exec rclrtf
+ + +text/x-gaim-log = exec rclgaim
+ + +text/x-mail = internal
+ + +application/x-lyx = +exec rcllyx
+ + +
+ + +## #############################################
+ + +# Icons to be used in the result list if required by gui config
+ + +[icons]
+ + +application/msword = wordprocessing
+ + +application/pdf = pdf
+ + +application/postscript = postscript
+ + +application/vnd.ms-excel = spreadsheet
+ + +application/vnd.ms-powerpoint = presentation
+ + +application/vnd.sun.xml.calc = spreadsheet
+ + +application/vnd.sun.xml.calc.template = spreadsheet
+ + +application/vnd.sun.xml.draw = drawing
+ + +application/vnd.sun.xml.draw.template = drawing
+ + +application/vnd.sun.xml.impress = presentation
+ + +application/vnd.sun.xml.impress.template = presentation
+ + +application/vnd.sun.xml.writer = wordprocessing
+ + +application/vnd.sun.xml.writer.global = wordprocessing
+ + +application/vnd.sun.xml.writer.template = wordprocessing
+ + +application/x-fsdirectory = folder
+ + +application/x-dvi = document
+ + +audio/mpeg = sownd
+ + +image/jpeg = image
+ + +image/png = image
+ + +image/vnd.djvu = document
+ + +message/rfc822 = message
+ + +text/html = html
+ + +text/plain = txt
+ + +text/x-mail = message
+ + +text/x-c = source
+ + +application/x-lyx = +wordprocessing
+ + +application/x-kword = +wordprocessing
+ + +

+ + +[categories]
+ + +
+ + +texts = application/msword \
+ + +      application/pdf \
+ + +      +application/postscript \
+ + +      +application/vnd.sun.xml.writer \
+ + +      +application/vnd.sun.xml.writer.global \
+ + +      +application/vnd.sun.xml.writer.template \
+ + +      application/x-dvi \
+ + +      image/vnd.djvu \
+ + +      text/html \
+ + +      text/plain \
+ + +      application/x-lyx +\
+ + +     application/x-kword +\
+ + +
      text/rtf
+ + +
+ + +spreadsheets = application/vnd.ms-excel \
+ + +         +application/vnd.sun.xml.calc \
+ + +         +application/vnd.sun.xml.calc.template
+ + +
+ + +presentations = application/vnd.ms-powerpoint \
+ + +    +      +application/vnd.sun.xml.impress \
+ + +    +      +application/vnd.sun.xml.impress.template
+ + +
+ + +media = audio/mpeg \
+ + +      image/jpeg \
+ + +      image/png \
+ + +
+ + +messages = message/rfc822 \
+ + +     text/x-gaim-log \
+ + +     text/x-mail \
+ + +
+ + +other = application/vnd.sun.xml.draw \
+ + +      +application/vnd.sun.xml.draw.template \
+ + +      +application/vnd.sun.xml.math \
+ + +      +application/x-fsdirectory
+ + +
+ + +MIMEVIEW
+ + +
+ + +# @(#$Id: mimeview,v +1.2 2006/12/19 08:40:50 dockes Exp $  (C) 2004 J.F.Dockes
+ + +
+ + +## +##########################################
+ + +# External viewers, +launched by the recoll GUI when you click on a result
+ + +# 'edit' link
+ + +
+ + +[view]
+ + +application/msword = +openoffice %f
+ + +application/pdf  += kpdf %f
+ + +application/postscript += gv %f
+ + +application/vnd.ms-excel += openoffice %f
+ + +application/vnd.ms-powerpoint += openoffice %f
+ + +application/vnd.sun.xml.calc += openoffice %f
+ + +application/vnd.sun.xml.calc.template += openoffice %f
+ + +application/vnd.sun.xml.draw += openoffice %f
+ + +application/vnd.sun.xml.draw.template += openoffice %f
+ + +application/vnd.sun.xml.impress += openoffice %f
+ + +application/vnd.sun.xml.impress.template += openoffice %f
+ + +application/vnd.sun.xml.math += openoffice %f
+ + +application/vnd.sun.xml.writer += openoffice %f
+ + +application/vnd.sun.xml.writer.global += openoffice %f
+ + +application/vnd.sun.xml.writer.template += openoffice %f
+ + +application/x-fsdirectory += rox %f
+ + +application/x-dvi = +xdvi %f
+ + +audio/mpeg = xmms %f
+ + +image/jpeg = gimp %f
+ + +image/png = gimp %f
+ + +image/vnd.djvu = djview +%f
+ + +# Or firefox -remote +"openFile(%u)"
+ + +text/html = konqueror %u
+ + +application/x-lyx = +lyx %f
+ + +
application/x-kword += kword %f
+ + +
+ + +
+ + +
+ + +
+ + +
+
+ + + + diff --git a/src/doc/user/usermanual.html b/src/doc/user/usermanual.html new file mode 100644 index 00000000..c0c11462 --- /dev/null +++ b/src/doc/user/usermanual.html @@ -0,0 +1,10355 @@ + + + + + + + + Recoll user manual + + + + + + +
+
+
+
+

Recoll user manual

+
+ +
+
+

Jean-Francois Dockes

+ +
+ +
+
+
+ +
+ +
+ +
+
+

Permission is granted to copy, + distribute and/or modify this document under the terms + of the GNU Free Documentation License, Version 1.3 or + any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover + Texts, and no Back-Cover Texts. A copy of the license + can be found at the following location: GNU web site.

+ +

This document introduces full text search notions + and describes the installation and use of the + Recoll application. + This version describes Recoll 1.22.

+
+
+
+
+
+ +
+

Table of Contents

+ +
+
1. Introduction
+ +
+
+
1.1. Giving it a + try
+ +
1.2. Full text + search
+ +
1.3. Recoll + overview
+
+
+ +
2. Indexing
+ +
+
+
2.1. Introduction
+ +
+
+
2.1.1. Indexing + modes
+ +
2.1.2. Configurations, + multiple indexes
+ +
2.1.3. Document types
+ +
2.1.4. Indexing failures
+ +
2.1.5. Recovery
+
+
+ +
2.2. Index storage
+ +
+
+
2.2.1. Xapian index + formats
+ +
2.2.2. Security + aspects
+
+
+ +
2.3. Index + configuration
+ +
+
+
2.3.1. Multiple + indexes
+ +
2.3.2. Index case and + diacritics sensitivity
+ +
2.3.3. Indexing threads + configuration
+ +
2.3.4. The index configuration + GUI
+
+
+ +
2.4. Indexing WEB pages you + wisit
+ +
2.5. Extended attributes + data
+ +
2.6. Importing external + tags
+ +
2.7. Periodic + indexing
+ +
+
+
2.7.1. Running + indexing
+ +
2.7.2. Using cron to automate + indexing
+
+
+ +
2.8. Real time + indexing
+ +
+
+
2.8.1. Slowing down the + reindexing rate for fast changing + files
+
+
+
+
+ +
3. Searching
+ +
+
+
3.1. Searching with the Qt graphical user + interface
+ +
+
+
3.1.1. Simple + search
+ +
3.1.2. The default result + list
+ +
3.1.3. The result + table
+ +
3.1.4. Running arbitrary + commands on result files (1.20 and + later)
+ +
3.1.5. Displaying + thumbnails
+ +
3.1.6. The preview + window
+ +
3.1.7. The Query Fragments + window
+ +
3.1.8. Complex/advanced + search
+ +
3.1.9. The term explorer + tool
+ +
3.1.10. Multiple + indexes
+ +
3.1.11. Document + history
+ +
3.1.12. Sorting search results and + collapsing duplicates
+ +
3.1.13. Search tips, + shortcuts
+ +
3.1.14. Saving and restoring queries + (1.21 and later)
+ +
3.1.15. Customizing the search + interface
+
+
+ +
3.2. Searching with the KDE KIO + slave
+ +
+
+
3.2.1. What's this
+ +
3.2.2. Searchable + documents
+
+
+ +
3.3. Searching on the command + line
+ +
3.4. Using Synonyms + (1.22)
+ +
3.5. Path translations
+ +
3.6. The query language
+ +
+
+
3.6.1. Modifiers
+
+
+ +
3.7. Search case and diacritics + sensitivity
+ +
3.8. Anchored searches and + wildcards
+ +
+
+
3.8.1. More about + wildcards
+ +
3.8.2. Anchored + searches
+
+
+ +
3.9. Desktop + integration
+ +
+
+
3.9.1. Hotkeying + recoll
+ +
3.9.2. The KDE Kicker Recoll + applet
+
+
+
+
+ +
4. Programming interface
+ +
+
+
4.1. Writing a document input + handler
+ +
+
+
4.1.1. Simple input + handlers
+ +
4.1.2. "Multiple" + handlers
+ +
4.1.3. Telling + Recoll about the + handler
+ +
4.1.4. Input handler HTML + output
+ +
4.1.5. Page + numbers
+
+
+ +
4.2. Field data + processing
+ +
4.3. Python API
+ +
+
+
4.3.1. Introduction
+ +
4.3.2. Interface + elements
+ +
4.3.3. Python search + interface
+ +
4.3.4. Creating Python + external indexers
+ +
4.3.5. Package + compatibility with the previous + version
+
+
+
+
+ +
5. Installation and + configuration
+ +
+
+
5.1. Installing a binary + copy
+ +
5.2. Supporting + packages
+ +
5.3. Building from + source
+ +
+
+
5.3.1. Prerequisites
+ +
5.3.2. Building
+ +
5.3.3. Installation
+
+
+ +
5.4. Configuration + overview
+ +
+
+
5.4.1. Environment + variables
+ +
5.4.2. Recoll main + configuration file, recoll.conf
+ +
5.4.3. The fields + file
+ +
5.4.4. The mimemap + file
+ +
5.4.5. The mimeconf + file
+ +
5.4.6. The mimeview + file
+ +
5.4.7. The ptrans file
+ +
5.4.8. Examples of + configuration adjustments
+
+
+
+
+
+
+ +
+
+
+
+

Chapter 1. Introduction

+
+
+
+ +

This document introduces full text search notions and + describes the installation and use of the Recoll application. This version + describes Recoll 1.22.

+ +

Recoll was for a long + time dedicated to Unix-like systems. It was only lately + (2015) ported to MS-Windows. + Many references in this manual, especially file locations, + are specific to Unix, and not valid on Windows. Some described features are + also not available on Windows. The manual will be + progressively updated. Until this happens, most references to + shared files can be translated by looking under the Recoll + installation directory (esp. the Share subdirectory). The user configuration + is stored by default under AppData/Local/Recoll inside the user + directory, along with the index itself.

+ +
+
+
+
+

1.1. Giving it a + try

+
+
+
+ +

If you do not like reading manuals (who does?) but wish + to give Recoll a try, just + install the + application and start the recoll graphical user + interface (GUI), which will ask permission to index your + home directory by default, allowing you to search + immediately after indexing completes.

+ +

Do not do this if your home directory contains a huge + number of documents and you do not want to wait or are very + short on disk space. In this case, you may first want to + customize the configuration to + restrict the indexed area (for the very impatient with a + completed package install, from the recoll GUI: PreferencesIndexing configuration, then adjust + the Top directories + section).

+ +

Also be aware that, on Unix/Linux, you may need to + install the appropriate supporting applications + for document types that need them (for example antiword for Microsoft Word files).

+ +

The Recoll installation + for Windows is + self-contained and includes most useful auxiliary programs. + You will just need to install Python 2.7.

+
+ +
+
+
+
+

1.2. Full text + search

+
+
+
+ +

Recoll is a full text + search application, which means that it finds your data by + content rather than by external attributes (like the file + name). You specify words (terms) which should or should not + appear in the text you are looking for, and receive in + return a list of matching documents, ordered so that the + most relevant + documents will appear first.

+ +

You do not need to remember in what file or email + message you stored a given piece of information. You just + ask for related terms, and the tool will return a list of + documents where these terms are prominent, in a similar way + to Internet search engines.

+ +

Full text search applications try to determine which + documents are most relevant to the search terms you + provide. Computer algorithms for determining relevance can + be very complex, and in general are inferior to the power + of the human mind to rapidly determine relevance. The + quality of relevance guessing is probably the most + important aspect when evaluating a search application.

+ +

In many cases, you are looking for all the forms of a + word, including plurals, different tenses for a verb, or + terms derived from the same root or stem (example: floor, floors, floored, + flooring...). Queries are usually automatically + expanded to all such related terms (words that reduce to + the same stem). This can be prevented for searching for a + specific form.

+ +

Stemming, by itself, does not accommodate for + misspellings or phonetic searches. A full text search + application may also support this form of approximation. + For example, a search for aliterattion returning no + result may propose, depending on index contents, alliteration alteration alterations + altercation as possible replacement terms.

+
+ +
+
+
+
+

1.3. Recoll + overview

+
+
+
+ +

Recoll uses the + Xapian + information retrieval library as its storage and retrieval + engine. Xapian is a very + mature package using a + sophisticated probabilistic ranking model.

+ +

The Xapian library + manages an index database which describes where terms + appear in your document files. It efficiently processes the + complex queries which are produced by the Recoll query expansion mechanism, and + is in charge of the all-important relevance computation + task.

+ +

Recoll provides the + mechanisms and interface to get data into and out of the + index. This includes translating the many possible document + formats into pure text, handling term variations (using + Xapian stemmers), and + spelling approximations (using the aspell speller), interpreting user + queries and presenting results.

+ +

In a shorter way, Recoll does the dirty footwork, + Xapian deals with the + intelligent parts of the process.

+ +

The Xapian index can be + big (roughly the size of the original document set), but it + is not a document archive. Recoll can only display documents that + still exist at the place from which they were indexed. + (Actually, there is a way to reconstruct a document from + the information in the index, but the result is not nice, + as all formatting, punctuation and capitalization are + lost).

+ +

Recoll stores all + internal data in Unicode + UTF-8 format, and it can index files of many types + with different character sets, encodings, and languages + into the same index. It can process documents embedded + inside other documents (for example a pdf document stored + inside a Zip archive sent as an email attachment...), down + to an arbitrary depth.

+ +

Stemming is the process by which Recoll reduces words to their radicals + so that searching does not depend, for example, on a word + being singular or plural (floor, floors), or on a verb + tense (flooring, floored). Because the mechanisms used for + stemming depend on the specific grammatical rules for each + language, there is a separate Xapian stemmer module for most common + languages where stemming makes sense.

+ +

Recoll stores the + unstemmed versions of terms in the main index and uses + auxiliary databases for term expansion (one for each + stemming language), which means that you can switch + stemming languages between searches, or add a language + without needing a full reindex.

+ +

Storing documents written in different languages in the + same index is possible, and commonly done. In this + situation, you can specify several stemming languages for + the index.

+ +

Recoll currently makes + no attempt at automatic language recognition, which means + that the stemmer will sometimes be applied to terms from + other languages with potentially strange results. In + practise, even if this introduces possibilities of + confusion, this approach has been proven quite useful, and + it is much less cumbersome than separating your documents + according to what language they are written in.

+ +

By default, Recoll + strips most accents and diacritics from terms, and converts + them to lower case before either storing them in the index + or searching for them. As a consequence, it is impossible + to search for a particular capitalization of a term + (US / us), or to discriminate two terms based on + diacritics (sake / + saké, mate / maté).

+ +

Recoll versions 1.18 + and newer can optionally store the raw terms, without + accent stripping or case conversion. In this configuration, + default searches will behave as before, but it is possible + to perform searches sensitive to case and diacritics. This + is described in more detail in the section + about index case and diacritics sensitivity.

+ +

Recoll has many + parameters which define exactly what to index, and how to + classify and decode the source documents. These are kept in + configuration files. A + default configuration is copied into a standard location + (usually something like /usr/share/recoll/examples) during + installation. The default values set by the configuration + files in this directory may be overridden by values set + inside your personal configuration, found by default in the + .recoll sub-directory of your + home directory. The default configuration will index your + home directory with default parameters and should be + sufficient for giving Recoll a try, but you may want to + adjust it later, which can be done either by editing the + text files or by using configuration menus in the + recoll GUI. + Some other parameters affecting only the recoll GUI are stored in + the standard location defined by Qt.

+ +

The indexing process + is started automatically the first time you execute the + recoll GUI. + Indexing can also be performed by executing the + recollindex + command. Recoll indexing + is multithreaded by default when appropriate hardware + resources are available, and can perform in parallel + multiple tasks among text extraction, segmentation and + index updates.

+ +

Searches are usually + performed inside the recoll GUI, which has + many options to help you find what you are looking for. + However, there are other ways to perform Recoll searches: mostly a command line + interface, a Python programming interface, a + KDE KIO slave module, and Ubuntu + Unity Lens (for older versions) or Scope (for current versions) modules.

+
+
+ +
+
+
+
+

Chapter 2. Indexing

+
+
+
+ +
+
+
+
+

2.1. Introduction

+
+
+
+ +

Indexing is the process by which the set of documents is + analyzed and the data entered into the database. + Recoll indexing is + normally incremental: documents will only be processed if + they have been modified since the last run. On the first + execution, all documents will need processing. A full index + build can be forced later by specifying an option to the + indexing command (recollindex -z or -Z).

+ +

recollindex skips files + which caused an error during a previous pass. This is a + performance optimization, and a new behaviour in version + 1.21 (failed files were always retried by previous + versions). The command line option -k can be set to retry failed files, for + example after updating a filter.

+ +

The following sections give an overview of different + aspects of the indexing processes and configuration, with + links to detailed sections.

+ +

Depending on your data, temporary files may be needed + during indexing, some of them possibly quite big. You can + use the RECOLL_TMPDIR or + TMPDIR environment variables to + determine where they are created (the default is to use + /tmp). Using TMPDIR has the nice property that it may + also be taken into account by auxiliary commands executed + by recollindex.

+ +
+
+
+
+

2.1.1. Indexing + modes

+
+
+
+ +

Recoll indexing can + be performed along two different modes:

+ +
+
    +
  • +

    Periodic (or + batch) indexing: indexing takes place + at discrete times, by executing the recollindex + command. The typical usage is to have a nightly + indexing run programmed + into your cron file.

    +
  • + +
  • +

    Real time + indexing: indexing takes place as soon + as a file is created or changed. recollindex runs + as a daemon and uses a file system alteration + monitor such as inotify, Fam or Gamin to detect file + changes.

    +
  • +
+
+ +

The choice between the two methods is mostly a matter + of preference, and they can be combined by setting up + multiple indexes (ie: use periodic indexing on a big + documentation directory, and real time indexing on a + small home directory). Monitoring a big file system tree + can consume significant system resources.

+ +

The choice of method and the parameters used can be + configured from the recoll GUI: + Preferences → + Indexing schedule

+ +

The File menu also has + entries to start or stop the current indexing operation. + Stopping indexing is performed by killing the + recollindex + process, which will checkpoint its state and exit. A + later restart of indexing will mostly resume from where + things stopped (the file tree walk has to be restarted + from the beginning).

+ +

When the real time indexer is running, only a stop + operation is available from the menu. When no indexing is + running, you have a choice of updating the index or + rebuilding it (the first choice only processes changed + files, the second one zeroes the index before starting so + that all files are processed).

+
+ +
+
+
+
+

2.1.2. Configurations, + multiple indexes

+
+
+
+ +

The parameters describing what is to be indexed and + local preferences are defined in text files contained in + a configuration + directory.

+ +

All parameters have defaults, defined in system-wide + files.

+ +

Without further configuration, Recoll will index all appropriate + files from your home directory, with a reasonable set of + defaults.

+ +

A default personal configuration directory + ($HOME/.recoll/) is created + when a Recoll program is + first executed. It is possible to create other + configuration directories, and use them by setting the + RECOLL_CONFDIR environment + variable, or giving the -c + option to any of the Recoll commands.

+ +

In some cases, it may be interesting to index + different areas of the file system to separate databases. + You can do this by using multiple configuration + directories, each indexing a file system area to a + specific database. Typically, this would be done to + separate personal and shared indexes, or to take + advantage of the organization of your data to improve + search precision.

+ +

The generated indexes can be queried concurrently in a + transparent manner.

+ +

For index generation, multiple configurations are + totally independant from each other. When multiple + indexes need to be used for a single search, some parameters should be + consistent among the configurations.

+
+ +
+
+
+
+

2.1.3. Document types

+
+
+
+ +

Recoll knows about + quite a few different document types. The parameters for + document types recognition and processing are set in + configuration + files.

+ +

Most file types, like HTML or word processing files, + only hold one document. Some file types, like email + folders or zip archives, can hold many individually + indexed documents, which may themselves be compound ones. + Such hierarchies can go quite deep, and Recoll can process, for example, a + LibreOffice document + stored as an attachment to an email message inside an + email folder archived in a zip file...

+ +

Recoll indexing + processes plain text, HTML, OpenDocument + (Open/LibreOffice), email formats, and a few others + internally.

+ +

Other file types (ie: postscript, pdf, ms-word, rtf + ...) need external applications for preprocessing. The + list is in the installation section. + After every indexing operation, Recoll updates a list of commands + that would be needed for indexing existing files types. + This list can be displayed by selecting the menu option + FileShow Missing Helpers in the + recoll GUI. + It is stored in the missing + text file inside the configuration directory.

+ +

By default, Recoll + will try to index any file type that it has a way to + read. This is sometimes not desirable, and there are ways + to either exclude some types, or on the contrary to + define a positive list of types to be indexed. In the + latter case, any type not in the list will be + ignored.

+ +

Excluding types can be done by adding wildcard name + patterns to the skippedNames + list, which can be done from the GUI Index configuration + menu. For versions 1.20 and later, you can alternatively + set the excludedmimetypes + list in the configuration file. This can be redefined for + subdirectories.

+ +

You can also define an exclusive list of MIME types to + be indexed (no others will be indexed), by settting the + indexedmimetypes + configuration variable. Example:

+
+indexedmimetypes = text/html application/pdf
+          
+
+ +

It is possible to redefine this parameter for + subdirectories. Example:

+
+[/path/to/my/dir]
+indexedmimetypes = application/pdf
+          
+
+ +

(When using sections like this, don't forget that they + remain in effect until the end of the file or another + section indicator).

+ +

excludedmimetypes or + indexedmimetypes, can be set + either by editing the + main configuration file (recoll.conf), or from the GUI index + configuration tool.

+ +
+

Note

+ +

When editing the indexedmimetypes or excludedmimetypes lists, you should + use the MIME values listed in the mimemap file or in Recoll result + lists in preference to file + -i output: there are a number of + differences.

+
+
+ +
+
+
+
+

2.1.4. Indexing + failures

+
+
+
+ +

Indexing may fail for some documents, for a number of + reasons: a helper program may be missing, the document + may be corrupt, we may fail to uncompress a file because + no file system space is available, etc.

+ +

Recoll versions prior + to 1.21 always retried to index files which had + previously caused an error. This guaranteed that anything + that may have become indexable (for example because a + helper had been installed) would be indexed. However this + was bad for performance because some indexing failures + may be quite costly (for example failing to uncompress a + big file because of insufficient disk space).

+ +

The indexer in Recoll + versions 1.21 and later does not retry failed file by + default. Retrying will only occur if an explicit option + (-k) is set on the + recollindex + command line, or if a script executed when recollindex starts up + says so. The script is defined by a configuration + variable (checkneedretryindexscript), and makes a + rather lame attempt at deciding if a helper command may + have been installed, by checking if any of the common + bin directories have + changed.

+
+ +
+
+
+
+

2.1.5. Recovery

+
+
+
+ +

In the rare case where the index becomes corrupted + (which can signal itself by weird search results or + crashes), the index files need to be erased before + restarting a clean indexing pass. Just delete the + xapiandb directory (see + next section), or, + alternatively, start the next recollindex with the + -z option, which will reset + the database before indexing.

+
+
+ +
+
+
+
+

2.2. Index + storage

+
+
+
+ +

The default location for the index data is the + xapiandb subdirectory of the + Recoll configuration + directory, typically $HOME/.recoll/xapiandb/. This can be + changed via two different methods (with different + purposes):

+ +
+
    +
  • +

    You can specify a different configuration + directory by setting the RECOLL_CONFDIR environment variable, + or using the -c option to + the Recoll commands. + This method would typically be used to index + different areas of the file system to different + indexes. For example, if you were to issue the + following command:

    +
    +recoll -c ~/.indexes-email
    +
    + +

    Then Recoll would + use configuration files stored in ~/.indexes-email/ and, (unless + specified otherwise in recoll.conf) would look for the + index in ~/.indexes-email/xapiandb/.

    + +

    Using multiple configuration directories and + + configuration options allows you to tailor + multiple configurations and indexes to handle + whatever subset of the available data you wish to + make searchable.

    +
  • + +
  • +

    For a given configuration directory, you can + specify a non-default storage location for the index + by setting the dbdir + parameter in the configuration file (see the + + configuration section). This method would mainly + be of use if you wanted to keep the configuration + directory in its default location, but desired + another location for the index, typically out of disk + occupation concerns.

    +
  • +
+
+ +

The size of the index is determined by the size of the + set of documents, but the ratio can vary a lot. For a + typical mixed set of documents, the index size will often + be close to the data set size. In specific cases (a set of + compressed mbox files for example), the index can become + much bigger than the documents. It may also be much smaller + if the documents contain a lot of images or other + non-indexed data (an extreme example being a set of mp3 + files where only the tags would be indexed).

+ +

Of course, images, sound and video do not increase the + index size, which means that nowadays (2012), typically, + even a big index will be negligible against the total + amount of data on the computer.

+ +

The index data directory (xapiandb) only contains data that can be + completely rebuilt by an index run (as long as the original + documents exist), and it can always be destroyed + safely.

+ +
+
+
+
+

2.2.1. Xapian + index formats

+
+
+
+ +

Xapian versions + usually support several formats for index storage. A + given major Xapian + version will have a current format, used to create new + indexes, and will also support the format from the + previous major version.

+ +

Xapian will not + convert automatically an existing index from the older + format to the newer one. If you want to upgrade to the + new format, or if a very old index needs to be converted + because its format is not supported any more, you will + have to explicitly delete the old index, then run a + normal indexing process.

+ +

Using the -z option to + recollindex + is not sufficient to change the format, you will have to + delete all files inside the index directory (typically + ~/.recoll/xapiandb) before + starting the indexing.

+
+ +
+
+
+
+

2.2.2. Security + aspects

+
+
+
+ +

The Recoll index does + not hold copies of the indexed documents. But it does + hold enough data to allow for an almost complete + reconstruction. If confidential data is indexed, access + to the database directory should be restricted.

+ +

Recoll will create + the configuration directory with a mode of 0700 (access + by owner only). As the index data directory is by default + a sub-directory of the configuration directory, this + should result in appropriate protection.

+ +

If you use another setup, you should think of the kind + of protection you need for your index, set the directory + and files access modes appropriately, and also maybe + adjust the umask used during + index updates.

+
+
+ +
+
+
+
+

2.3. Index + configuration

+
+
+
+ +

Variables set inside the Recoll configuration files control + which areas of the file system are indexed, and how files + are processed. These variables can be set either by editing + the text files or by using the dialogs in the + recoll + GUI.

+ +

The first time you start recoll, you will be asked + whether or not you would like it to build the index. If you + want to adjust the configuration before indexing, just + click Cancel at this point, + which will get you into the configuration interface. If you + exit at this point, recoll + will have created a ~/.recoll + directory containing empty configuration files, which you + can edit by hand.

+ +

The configuration is documented inside the installation chapter + of this document, or in the recoll.conf(5) man page, but + the most current information will most likely be the + comments inside the sample file. The most immediately + useful variable you may interested in is probably topdirs, which determines what + subtrees get indexed.

+ +

The applications needed to index file types other than + text, HTML or email (ie: pdf, postscript, ms-word...) are + described in the external packages + section.

+ +

As of Recoll 1.18 there are two incompatible types of + Recoll indexes, depending on the treatment of character + case and diacritics. The next section describes the two + types in more detail.

+ +
+
+
+
+

2.3.1. Multiple + indexes

+
+
+
+ +

Multiple Recoll + indexes can be created by using several configuration + directories which are usually set to index different + areas of the file system. A specific index can be + selected for updating or searching, using the + RECOLL_CONFDIR environment + variable or the -c option to + recoll and + recollindex.

+ +

When working with the recoll index + configuration GUI, the configuration directory for which + parameters are modified is the one which was selected by + RECOLL_CONFDIR or the + -c parameter, and there is no + way to switch configurations within the GUI.

+ +

Additional configuration directory (beyond + ~/.recoll) must be created + by hand (mkdir or such), the GUI + will not do it. This is to avoid mistakenly creating + additional directories when an argument is mistyped.

+ +

A typical usage scenario for the multiple index + feature would be for a system administrator to set up a + central index for shared data, that you choose to search + or not in addition to your personal data. Of course, + there are other possibilities. There are many cases where + you know the subset of files that should be searched, and + where narrowing the search can improve the results. You + can achieve approximately the same effect with the + directory filter in advanced search, but multiple indexes + will have much better performance and may be worth the + trouble.

+ +

A recollindex program + instance can only update one specific index.

+ +

The main index (defined by RECOLL_CONFDIR or -c) is always active. If this is + undesirable, you can set up your base configuration to + index an empty directory.

+ +

The different search interfaces (GUI, command line, + ...) have different methods to define the set of indexes + to be used, see the appropriate section.

+ +

If a set of multiple indexes are to be used together + for searches, some configuration parameters must be + consistent among the set. These are parameters which need + to be the same when indexing and searching. As the + parameters come from the main configuration when + searching, they need to be compatible with what was set + when creating the other indexes (which came from their + respective configuration directories).

+ +

Most importantly, all indexes to be queried + concurrently must have the same option concerning + character case and diacritics stripping, but there are + other constraints. Most of the relevant parameters are + described in the + linked section.

+
+ +
+
+
+
+

2.3.2. Index + case and diacritics sensitivity

+
+
+
+ +

As of Recoll version + 1.18 you have a choice of building an index with terms + stripped of character case and diacritics, or one with + raw terms. For a source term of Résumé, the former will + store resume, the latter + Résumé.

+ +

Each type of index allows performing searches + insensitive to case and diacritics: with a raw index, the + user entry will be expanded to match all case and + diacritics variations present in the index. With a + stripped index, the search term will be stripped before + searching.

+ +

A raw index allows for another possibility which a + stripped index cannot offer: using case and diacritics to + discriminate between terms, returning different results + when searching for US and + us or resume and résumé. Read the section + about search case and diacritics sensitivity for more + details.

+ +

The type of index to be created is controlled by the + indexStripChars + configuration variable which can only be changed by + editing the configuration file. Any change implies an + index reset (not automated by Recoll), and all indexes in a search + must be set in the same way (again, not checked by + Recoll).

+ +

If the indexStripChars is + not set, Recoll 1.18 + creates a stripped index by default, for compatibility + with previous versions.

+ +

As a cost for added capability, a raw index will be + slightly bigger than a stripped one (around 10%). Also, + searches will be more complex, so probably slightly + slower, and the feature is still young, so that a certain + amount of weirdness cannot be excluded.

+ +

One of the most adverse consequence of using a raw + index is that some phrase and proximity searches may + become impossible: because each term needs to be + expanded, and all combinations searched for, the + multiplicative expansion may become unmanageable.

+
+ +
+
+
+
+

2.3.3. Indexing + threads configuration

+
+
+
+ +

The Recoll indexing + process recollindex can use + multiple threads to speed up indexing on multiprocessor + systems. The work done to index files is divided in + several stages and some of the stages can be executed by + multiple threads. The stages are:

+ +
+
    +
  1. File system walking: this is + always performed by the main thread.
  2. + +
  3. File conversion and data + extraction.
  4. + +
  5. Text processing (splitting, + stemming, etc.)
  6. + +
  7. Xapian index update.
  8. +
+
+ +

You can also read a longer document about the + transformation of Recoll + indexing to multithreading.

+ +

The threads configuration is controlled by two + configuration file parameters.

+ +
+
+
thrQSizes
+ +
+

This variable defines the job input queues + configuration. There are three possible queues for + stages 2, 3 and 4, and this parameter should give + the queue depth for each stage (three integer + values). If a value of -1 is used for a given + stage, no queue is used, and the thread will go on + performing the next stage. In practise, deep queues + have not been shown to increase performance. A + value of 0 for the first queue tells Recoll to perform + autoconfiguration (no need for anything else in + this case, thrTCounts is not used) - this is the + default configuration.

+
+ +
thrTCounts
+ +
+

This defines the number of threads used for each + stage. If a value of -1 is used for one of the + queue depths, the corresponding thread count is + ignored. It makes no sense to use a value other + than 1 for the last stage because updating the + Xapian index is + necessarily single-threaded (and protected by a + mutex).

+
+
+
+ +
+

Note

+ +

If the first value in thrQSizes is 0, thrTCounts is ignored.

+
+ +

The following example would use three queues (of depth + 2), and 4 threads for converting source documents, 2 for + processing their text, and one to update the index. This + was tested to be the best configuration on the test + system (quadri-processor with multiple disks).

+
+thrQSizes = 2 2 2
+thrTCounts =  4 2 1
+
+ +

The following example would use a single queue, and + the complete processing for each document would be + performed by a single thread (several documents will + still be processed in parallel in most cases). The + threads will use mutual exclusion when entering the index + update stage. In practise the performance would be close + to the precedent case in general, but worse in certain + cases (e.g. a Zip archive would be performed purely + sequentially), so the previous approach is preferred. + YMMV... The 2 last values for thrTCounts are ignored.

+
+thrQSizes = 2 -1 -1
+thrTCounts =  6 1 1
+
+ +

The following example would disable multithreading. + Indexing will be performed by a single thread.

+
+thrQSizes = -1 -1 -1
+
+
+ +
+
+
+
+

2.3.4. The + index configuration GUI

+
+
+
+ +

Most parameters for a given index configuration can be + set from a recoll GUI running on + this configuration (either as default, or by setting + RECOLL_CONFDIR or the + -c option.)

+ +

The interface is started from the PreferencesIndex Configuration menu entry. It + is divided in four tabs, Global + parameters, Local + parameters, Web + history (which is explained in the next section) + and Search parameters.

+ +

The Global parameters + tab allows setting global variables, like the lists of + top directories, skipped paths, or stemming + languages.

+ +

The Local parameters tab + allows setting variables that can be redefined for + subdirectories. This second tab has an initially empty + list of customisation directories, to which you can add. + The variables are then set for the currently selected + directory (or at the top level if the empty line is + selected).

+ +

The Search parameters + section defines parameters which are used at query time, + but are global to an index and affect all search tools, + not only the GUI.

+ +

The meaning for most entries in the interface is + self-evident and documented by a ToolTip popup on the text label. For + more detail, you will need to refer to the configuration + section of this guide.

+ +

The configuration tool normally respects the comments + and most of the formatting inside the configuration file, + so that it is quite possible to use it on hand-edited + files, which you might nevertheless want to backup + first...

+
+
+ +
+
+
+
+

2.4. Indexing WEB + pages you wisit

+
+
+
+ +

With the help of a Firefox extension, Recoll can index the Internet pages + that you visit. The extension was initially designed for + the Beagle indexer, but it + has recently be renamed and better adapted to Recoll.

+ +

The extension works by copying visited WEB pages to an + indexing queue directory, which Recoll then processes, indexing the + data, storing it into a local cache, then removing the file + from the queue.

+ +

This feature can be enabled in the GUI Index configuration panel, or by editing + the configuration file (set processwebqueue to 1).

+ +

A current pointer to the extension can be found, along + with up-to-date instructions, on the Recoll wiki.

+ +

A copy of the indexed WEB pages is retained by Recoll in + a local cache (from which previews can be fetched). The + cache size can be adjusted from the Index configuration / Web history panel. Once the maximum size + is reached, old pages are purged - both from the cache and + the index - to make room for new ones, so you need to + explicitly archive in some other place the pages that you + want to keep indefinitely.

+
+ +
+
+
+
+

2.5. Extended + attributes data

+
+
+
+ +

User extended attributes are named pieces of information + that most modern file systems can attach to any file.

+ +

Recoll versions 1.19 + and later process extended attributes as document fields by + default. For older versions, this has to be activated at + build time.

+ +

A freedesktop standard defines a few + special attributes, which are handled as such by + Recoll:

+ +
+
+
mime_type
+ +
+

If set, this overrides any other determination of + the file MIME type.

+
+ +
charset
+ +
If set, this defines the file character set (mostly + useful for plain text files).
+
+
+ +

By default, other attributes are handled as Recoll fields. On Linux, the + user prefix is removed from + the name. This can be configured more precisely inside the + fields configuration file.

+
+ +
+
+
+
+

2.6. Importing + external tags

+
+
+
+ +

During indexing, it is possible to import metadata for + each file by executing commands. For example, this could + extract user tag data for the file and store it in a field + for indexing.

+ +

See the section about + the metadatacmds field in + the main configuration chapter for a description of the + configuration syntax.

+ +

As an example, if you would want Recoll to use tags managed by + tmsu, you would add the + following to the configuration file:

+
+[/some/area/of/the/fs]
+metadatacmds = ; tags = tmsu tags %f
+      
+
+ +
+

Note

+ +

Depending on the tmsu + version, you may need/want to add options like + --database=/some/db.

+
+ +

You may want to restrict this processing to a subset of + the directory tree, because it may slow down indexing a bit + ([some/area/of/the/fs]).

+ +

Note the initial semi-colon after the equal sign.

+ +

In the example above, the output of tmsu is used to set a + field named tags. The field + name is arbitrary and could be tmsu or myfield just the same, but tags is an alias for the standard + Recoll keywords field, and the tmsu output will just + augment its contents. This will avoid the need to extend + the field + configuration.

+ +

Once re-indexing is performed (you'll need to force the + file reindexing, Recoll + will not detect the need by itself), you will be able to + search from the query language, through any of its aliases: + tags:some/alternate/values or + tags:all,these,values (the + compact field search syntax is supported for recoll 1.20 + and later. For older versions, you would need to repeat the + tags: specifier for each term, + e.g. tags:some OR + tags:alternate).

+ +

You should be aware that tags changes will not be + detected by the indexer if the file itself did not change. + One possible workaround would be to update the file + ctime when you modify the + tags, which would be consistent with how extended + attributes function. A pair of chmod commands could + accomplish this, or a touch -a + . Alternatively, just couple the tag update with a + recollindex -e -i + filename.

+
+ +
+
+
+
+

2.7. Periodic + indexing

+
+
+
+ +
+
+
+
+

2.7.1. Running + indexing

+
+
+
+ +

Indexing is always performed by the recollindex program, + which can be started either from the command line or from + the File menu in the + recoll GUI + program. When started from the GUI, the indexing will run + on the same configuration recoll was started on. + When started from the command line, recollindex will use + the RECOLL_CONFDIR variable or + accept a -c confdir option to specify + a non-default configuration directory.

+ +

If the recoll program finds no + index when it starts, it will automatically start + indexing (except if canceled).

+ +

The recollindex indexing + process can be interrupted by sending an interrupt + (Ctrl-C, SIGINT) or terminate + (SIGTERM) signal. Some time may elapse before the process + exits, because it needs to properly flush and close the + index. This can also be done from the recoll GUI FileStop Indexing menu entry.

+ +

After such an interruption, the index will be somewhat + inconsistent because some operations which are normally + performed at the end of the indexing pass will have been + skipped (for example, the stemming and spelling databases + will be inexistant or out of date). You just need to + restart indexing at a later time to restore consistency. + The indexing will restart at the interruption point (the + full file tree will be traversed, but files that were + indexed up to the interruption and for which the index is + still up to date will not need to be reindexed).

+ +

recollindex has a + number of other options which are described in its man + page. Only a few will be described here.

+ +

Option -z will reset the + index when starting. This is almost the same as + destroying the index files (the nuance is that the + Xapian format version + will not be changed).

+ +

Option -Z will force the + update of all documents without resetting the index + first. This will not have the "clean start" aspect of + -z, but the advantage is that + the index will remain available for querying while it is + rebuilt, which can be a significant advantage if it is + very big (some installations need days for a full index + rebuild).

+ +

Option -k will force + retrying files which previously failed to be indexed, for + example because of a missing helper program.

+ +

Of special interest also, maybe, are the -i and -f + options. -i allows indexing + an explicit list of files (given as command line + parameters or read on stdin). -f + tells recollindex to ignore + file selection parameters from the configuration. + Together, these options allow building a custom file + selection process for some area of the file system, by + adding the top directory to the skippedPaths list and using an + appropriate file selection method to build the file list + to be fed to recollindex + -if. Trivial example:

+
+            find . -name indexable.txt -print | recollindex -if
+          
+
+ +

recollindex + -i will not descend into + subdirectories specified as parameters, but just add them + as index entries. It is up to the external file selection + method to build the complete file list.

+
+ +
+
+
+
+

2.7.2. Using + cron + to automate indexing

+
+
+
+ +

The most common way to set up indexing is to have a + cron task execute it every night. For example the + following crontab entry + would do it every day at 3:30AM (supposing recollindex is in your + PATH):

+
+30 3 * * * recollindex > /some/tmp/dir/recolltrace 2>&1
+
+ +

Or, using anacron:

+
+1  15  su mylogin -c "recollindex recollindex > /tmp/rcltraceme 2>&1"
+
+ +

As of version 1.17 the Recoll GUI has dialogs to manage + crontab entries for + recollindex. You can + reach them from the PreferencesIndexing Schedule menu. They only + work with the good old cron, and do not give + access to all features of cron scheduling.

+ +

The usual command to edit your crontab is crontab -e (which will usually start the + vi editor + to edit the file). You may have more sophisticated tools + available on your system.

+ +

Please be aware that there may be differences between + your usual interactive command line environment and the + one seen by crontab commands. Especially the PATH + variable may be of concern. Please check the crontab + manual pages about possible issues.

+
+
+ +
+
+
+
+

2.8. Real time + indexing

+
+
+
+ +

Real time monitoring/indexing is performed by starting + the recollindex -m command. With this option, recollindex will detach + from the terminal and become a daemon, permanently + monitoring file changes and updating the index.

+ +

Under KDE, Gnome and some other desktop + environments, the daemon can automatically started when you + log in, by creating a desktop file inside the ~/.config/autostart directory. This can + be done for you by the Recoll GUI. Use the Preferences->Indexing Schedule + menu.

+ +

With older X11 setups, + starting the daemon is normally performed as part of the + user session script.

+ +

The rclmon.sh script can + be used to easily start and stop the daemon. It can be + found in the examples + directory (typically /usr/local/[share/]recoll/examples).

+ +

For example, my out of fashion xdm-based session has a .xsession script with the following lines + at the end:

+
+recollconf=$HOME/.recoll-home
+recolldata=/usr/local/share/recoll
+RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start
+
+fvwm 
+
+
+ +

The indexing daemon gets started, then the window + manager, for which the session waits.

+ +

By default the indexing daemon will monitor the state of + the X11 session, and exit when it finishes, it is not + necessary to kill it explicitly. (The X11 server monitoring can be disabled + with option -x to recollindex).

+ +

If you use the daemon completely out of an X11 session, you need to add option + -x to disable X11 session monitoring (else the + daemon will not start).

+ +

By default, the messages from the indexing daemon will + be setn to the same file as those from the interactive + commands (logfilename). You + may want to change this by setting the daemlogfilename and daemloglevel configuration parameters. + Also the log file will only be truncated when the daemon + starts. If the daemon runs permanently, the log file may + grow quite big, depending on the log level.

+ +

When building Recoll, + the real time indexing support can be customised during + package configuration with the + --with[out]-fam or --with[out]-inotify options. The default is + currently to include inotify monitoring on systems that + support it, and, as of Recoll 1.17, gamin support on FreeBSD.

+ +

While it is convenient that data is indexed in real + time, repeated indexing can generate a significant load on + the system when files such as email folders change. Also, + monitoring large file trees by itself significantly taxes + system resources. You probably do not want to enable it if + your system is short on resources. Periodic indexing is + adequate in most cases.

+ +
+

Increasing resources for inotify

+ +

On Linux systems, monitoring a big tree may need + increasing the resources available to inotify, which are + normally defined in /etc/sysctl.conf.

+
+### inotify
+#
+# cat  /proc/sys/fs/inotify/max_queued_events   - 16384
+# cat  /proc/sys/fs/inotify/max_user_instances  - 128
+# cat  /proc/sys/fs/inotify/max_user_watches    - 16384
+#
+# -- Change to:
+#
+fs.inotify.max_queued_events=32768
+fs.inotify.max_user_instances=256
+fs.inotify.max_user_watches=32768
+          
+
+ +

Especially, you will need to trim your tree or adjust + the max_user_watches value + if indexing exits with a message about errno ENOSPC (28) from inotify_add_watch.

+
+ +
+
+
+
+

2.8.1. Slowing + down the reindexing rate for fast changing + files

+
+
+
+ +

When using the real time monitor, it may happen that + some files need to be indexed, but change so often that + they impose an excessive load for the system.

+ +

Recoll provides a + configuration option to specify the minimum time before + which a file, specified by a wildcard pattern, cannot be + reindexed. See the mondelaypatterns parameter in the + configuration + section.

+
+
+
+ +
+
+
+
+

Chapter 3. Searching

+
+
+
+ +
+
+
+
+

3.1. Searching with the Qt + graphical user interface

+
+
+
+ +

The recoll + program provides the main user interface for searching. It + is based on the Qt + library.

+ +

recoll has + two search modes:

+ +
+
    +
  • +

    Simple search (the default, on the main screen) + has a single entry field where you can enter multiple + words.

    +
  • + +
  • +

    Advanced search (a panel accessed through the + Tools menu or the + toolbox bar icon) has multiple entry fields, which + you may use to build a logical condition, with + additional filtering on file type, location in the + file system, modification date, and size.

    +
  • +
+
+ +

In most cases, you can enter the terms as you think + them, even if they contain embedded punctuation or other + non-textual characters. For example, Recoll can handle things like email + addresses, or arbitrary cut and paste from another text + window, punctation and all.

+ +

The main case where you should enter text differently + from how it is printed is for east-asian languages + (Chinese, Japanese, Korean). Words composed of single or + multiple characters should be entered separated by white + space in this case (they would typically be printed without + white space).

+ +

Some searches can be quite complex, and you may want to + re-use them later, perhaps with some tweaking. Recoll versions 1.21 and later can + save and restore searches, using XML files. See + Saving and restoring queries.

+ +
+
+
+
+

3.1.1. Simple + search

+
+
+
+ +
+
    +
  1. +

    Start the recoll + program.

    +
  2. + +
  3. +

    Possibly choose a search mode: Any term, All terms, File name or Query language.

    +
  4. + +
  5. +

    Enter search term(s) in the text field at the + top of the window.

    +
  6. + +
  7. +

    Click the Search + button or hit the Enter key to start + the search.

    +
  8. +
+
+ +

The initial default search mode is Query language. Without special + directives, this will look for documents containing all + of the search terms (the ones with more terms will get + better scores), just like the All + terms mode which will ignore such directives. + Any term will search for + documents where at least one of the terms appear.

+ +

The Query Language + features are described in a + separate section.

+ +

All search modes allow wildcards inside terms + (*, ?, []). You + may want to have a look at the section about + wildcards for more information about this.

+ +

File name will + specifically look for file names. The point of having a + separate file name search is that wild card expansion can + be performed more efficiently on a small subset of the + index (allowing wild cards on the left of terms without + excessive penality). Things to know:

+ +
+
    +
  • +

    White space in the entry should match white + space in the file name, and is not treated + specially.

    +
  • + +
  • +

    The search is insensitive to character case and + accents, independantly of the type of index.

    +
  • + +
  • +

    An entry without any wild card character and not + capitalized will be prepended and appended with '*' + (ie: etc + -> *etc*, but + Etc -> + etc).

    +
  • + +
  • +

    If you have a big index (many files), + excessively generic fragments may result in + inefficient searches.

    +
  • +
+
+ +

You can search for exact phrases (adjacent words in a + given order) by enclosing the input inside double quotes. + Ex: "virtual reality".

+ +

When using a stripped index, character case has no + influence on search, except that you can disable stem + expansion for any term by capitalizing it. Ie: a search + for floor will also normally + look for flooring, + floored, etc., but a search + for Floor will only look for + floor, in any character + case. Stemming can also be disabled globally in the + preferences. When using a raw index, the + rules are a bit more complicated.

+ +

Recoll remembers the + last few searches that you performed. You can use the + simple search text entry widget (a combobox) to recall + them (click on the thing at the right of the text field). + Please note, however, that only the search texts are + remembered, not the mode (all/any/file name).

+ +

Typing Esc Space while entering a + word in the simple search entry will open a window with + possible completions for the word. The completions are + extracted from the database.

+ +

Double-clicking on a word in the result list or a + preview window will insert it into the simple search + entry field.

+ +

You can cut and paste any text into an All terms or Any + term search field, punctuation, newlines and all - + except for wildcard characters (single ? characters are ok). Recoll will process it and produce a + meaningful search. This is what most differentiates this + mode from the Query + Language mode, where you have to care about the + syntax.

+ +

You can use the ToolsAdvanced search dialog for more + complex searches.

+
+ +
+
+
+
+

3.1.2. The + default result list

+
+
+
+ +

After starting a search, a list of results will + instantly be displayed in the main list window.

+ +

By default, the document list is presented in order of + relevance (how well the system estimates that the + document matches the query). You can sort the result by + ascending or descending date by using the vertical arrows + in the toolbar.

+ +

Clicking on the Preview + link for an entry will open an internal preview window + for the document. Further Preview clicks for the same search will + open tabs in the existing preview window. You can use + Shift+Click + to force the creation of another preview window, which + may be useful to view the documents side by side. (You + can also browse successive results in a single preview + window by typing Shift+ArrowUp/Down in the + window).

+ +

Clicking the Open link + will start an external viewer for the document. By + default, Recoll lets the + desktop choose the appropriate application for most + document types (there is a short list of exceptions, see + further). If you prefer to completely customize the + choice of applications, you can uncheck the Use desktop preferences option in the + GUI preferences dialog, and click the Choose editor applications button to + adjust the predefined Recoll choices. The tool accepts + multiple selections of MIME types (e.g. to set up the + editor for the dozens of office file types).

+ +

Even when Use desktop + preferences is checked, there is a small list of + exceptions, for MIME types where the Recoll choice should override the + desktop one. These are applications which are well + integrated with Recoll, + especially evince for + viewing PDF and Postscript files because of its support + for opening the document at a specific page and passing a + search string as an argument. Of course, you can edit the + list (in the GUI preferences) if you would prefer to lose + the functionality and use the standard desktop tool.

+ +

You may also change the choice of applications by + editing the mimeview configuration file if you + find this more convenient.

+ +

Each result entry also has a right-click menu with an + Open With entry. This lets + you choose an application from the list of those which + registered with the desktop for the document MIME + type.

+ +

The Preview and + Open edit links may not be + present for all entries, meaning that Recoll has no configured way to + preview a given file type (which was indexed by name + only), or no configured external editor for the file + type. This can sometimes be adjusted simply by tweaking + the mimemap and mimeview configuration files (the + latter can be modified with the user preferences + dialog).

+ +

The format of the result list entries is entirely + configurable by using the preference dialog to edit an HTML + fragment.

+ +

You can click on the Query + details link at the top of the results page to see + the query actually performed, after stem expansion and + other processing.

+ +

Double-clicking on any word inside the result list or + a preview window will insert it into the simple search + text.

+ +

The result list is divided into pages (the size of + which you can change in the preferences). Use the arrow + buttons in the toolbar or the links at the bottom of the + page to browse the results.

+ +
+
+
+
+

3.1.2.1. No + results: the spelling suggestions

+
+
+
+ +

When a search yields no result, and if the + aspell dictionary is + configured, Recoll + will try to check for misspellings among the query + terms, and will propose lists of replacements. Clicking + on one of the suggestions will replace the word and + restart the search. You can hold any of the modifier + keys (Ctrl, Shift, etc.) while clicking if you would + rather stay on the suggestion screen because several + terms need replacement.

+
+ +
+
+
+
+

3.1.2.2. The + result list right-click menu

+
+
+
+ +

Apart from the preview and edit links, you can + display a pop-up menu by right-clicking over a + paragraph in the result list. This menu has the + following entries:

+ +
+
    +
  • +

    Preview

    +
  • + +
  • +

    Open

    +
  • + +
  • +

    Open With

    +
  • + +
  • +

    Run Script

    +
  • + +
  • +

    Copy File + Name

    +
  • + +
  • +

    Copy Url

    +
  • + +
  • +

    Save to File

    +
  • + +
  • +

    Find similar

    +
  • + +
  • +

    Preview Parent + document

    +
  • + +
  • +

    Open Parent + document

    +
  • + +
  • +

    Open Snippets + Window

    +
  • +
+
+ +

The Preview and + Open entries do the same + thing as the corresponding links.

+ +

Open With lets you + open the document with one of the applications claiming + to be able to handle its MIME type (the information + comes from the .desktop + files in /usr/share/applications).

+ +

Run Script allows + starting an arbitrary command on the result file. It + will only appear for results which are top-level files. + See + further for a more detailed description.

+ +

The Copy File Name and + Copy Url copy the + relevant data to the clipboard, for later pasting.

+ +

Save to File allows + saving the contents of a result document to a chosen + file. This entry will only appear if the document does + not correspond to an existing file, but is a + subdocument inside such a file (ie: an email + attachment). It is especially useful to extract + attachments with no associated editor.

+ +

The Open/Preview Parent + document entries allow working with the higher + level document (e.g. the email message an attachment + comes from). Recoll is + sometimes not totally accurate as to what it can or + can't do in this area. For example the Parent entry will also appear for an + email which is part of an mbox folder file, but you + can't actually visualize the mbox (there will be an + error dialog if you try).

+ +

If the document is a top-level file, Open Parent will start the default + file manager on the enclosing filesystem directory.

+ +

The Find similar entry + will select a number of relevant term from the current + document and enter them into the simple search field. + You can then start a simple search, with a good chance + of finding documents related to the current result. I + can't remember a single instance where this function + was actually useful to me...

+ +

The + Open Snippets Window + entry will only appear for documents which support page + breaks (typically PDF, Postscript, DVI). The snippets + window lists extracts from the document, taken around + search terms occurrences, along with the corresponding + page number, as links which can be used to start the + native viewer on the appropriate page. If the viewer + supports it, its search function will also be primed + with one of the search terms.

+
+
+ +
+
+
+
+

3.1.3. The + result table

+
+
+
+ +

In Recoll 1.15 and + newer, the results can be displayed in spreadsheet-like + fashion. You can switch to this presentation by clicking + the table-like icon in the toolbar (this is a toggle, + click again to restore the list).

+ +

Clicking on the column headers will allow sorting by + the values in the column. You can click again to invert + the order, and use the header right-click menu to reset + sorting to the default relevance order (you can also use + the sort-by-date arrows to do this).

+ +

Both the list and the table display the same + underlying results. The sort order set from the table is + still active if you switch back to the list mode. You can + click twice on a date sort arrow to reset it from + there.

+ +

The header right-click menu allows adding or deleting + columns. The columns can be resized, and their order can + be changed (by dragging). All the changes are recorded + when you quit recoll

+ +

Hovering over a table row will update the detail area + at the bottom of the window with the corresponding + values. You can click the row to freeze the display. The + bottom area is equivalent to a result list paragraph, + with links for starting a preview or a native + application, and an equivalent right-click menu. Typing + Esc (the + Escape key) will unfreeze the display.

+
+ +
+
+
+
+

3.1.4. Running + arbitrary commands on result files (1.20 and + later)

+
+
+
+ +

Apart from the Open and + Open With operations, which + allow starting an application on a result document (or a + temporary copy), based on its MIME type, it is also + possible to run arbitrary commands on results which are + top-level files, using the Run + Script entry in the results pop-up menu.

+ +

The commands which will appear in the Run Script submenu must be defined by + .desktop files inside the + scripts subdirectory of the + current configuration directory.

+ +

Here follows an example of a .desktop file, which could be named for + example, ~/.recoll/scripts/myscript.desktop (the + exact file name inside the directory is irrelevant):

+
+[Desktop Entry]
+Type=Application
+Name=MyFirstScript
+Exec=/home/me/bin/tryscript %F
+MimeType=*/*
+      
+
+ +

The Name attribute + defines the label which will appear inside the + Run Script menu. The + Exec attribute defines the + program to be run, which does not need to actually be a + script, of course. The MimeType attribute is not used, but + needs to exist.

+ +

The commands defined this way can also be used from + links inside the result paragraph.

+ +

As an example, it might make sense to write a script + which would move the document to the trash and purge it + from the Recoll + index.

+
+ +
+
+
+
+

3.1.5. Displaying + thumbnails

+
+
+
+ +

The default format for the result list entries and the + detail area of the result table display an icon for each + result document. The icon is either a generic one + determined from the MIME type, or a thumbnail of the + document appearance. Thumbnails are only displayed if + found in the standard freedesktop location, where they + would typically have been created by a file manager.

+ +

Recoll has no capability to create thumbnails. A + relatively simple trick is to use the Open parent document/folder entry in + the result list popup menu. This should open a file + manager window on the containing directory, which should + in turn create the thumbnails (depending on your + settings). Restarting the search should then display the + thumbnails.

+ +

There are also some pointers about thumbnail + generation on the Recoll wiki.

+
+ +
+
+
+
+

3.1.6. The + preview window

+
+
+
+ +

The preview window opens when you first click a + Preview link inside the + result list.

+ +

Subsequent preview requests for a given search open + new tabs in the existing window (except if you hold the + Shift key + while clicking which will open a new window for side by + side viewing).

+ +

Starting another search and requesting a preview will + create a new preview window. The old one stays open until + you close it.

+ +

You can close a preview tab by typing Ctrl-W (Ctrl + W) in the window. + Closing the last tab for a window will also close the + window.

+ +

Of course you can also close a preview window by using + the window manager button in the top of the frame.

+ +

You can display successive or previous documents from + the result list inside a preview tab by typing + Shift+Down or Shift+Up (Down and Up are the arrow + keys).

+ +

A right-click menu in the text area allows switching + between displaying the main text or the contents of + fields associated to the document (ie: author, abtract, + etc.). This is especially useful in cases where the term + match did not occur in the main text but in one of the + fields. In the case of images, you can switch between + three displays: the image itself, the image metadata as + extracted by exiftool and the + fields, which is the metadata stored in the index.

+ +

You can print the current preview window contents by + typing Ctrl-P (Ctrl + P) in the window + text.

+ +
+
+
+
+

3.1.6.1. Searching + inside the preview

+
+
+
+ +

The preview window has an internal search + capability, mostly controlled by the panel at the + bottom of the window, which works in two modes: as a + classical editor incremental search, where we look for + the text entered in the entry zone, or as a way to walk + the matches between the document and the Recoll query that found it.

+ +
+
+
Incremental text + search
+ +
+

The preview tabs have an internal incremental + search function. You initiate the search either + by typing a / (slash) or + CTL-F inside the + text area or by clicking into the Search for: text field and + entering the search string. You can then use the + Next and + Previous buttons to + find the next/previous occurrence. You can also + type F3 inside the + text area to get to the next occurrence.

+ +

If you have a search string entered and you + use Ctrl-Up/Ctrl-Down to browse the results, the + search is initiated for each successive document. + If the string is found, the cursor will be + positioned at the first occurrence of the search + string.

+
+ +
Walking the match + lists
+ +
+

If the entry area is empty when you click the + Next or + Previous buttons, + the editor will be scrolled to show the next + match to any search term (the next highlighted + zone). If you select a search group from the + dropdown list and click Next or Previous, the match list for + this group will be walked. This is not the same + as a text search, because the occurences will + include non-exact matches (as caused by stemming + or wildcards). The search will revert to the text + mode as soon as you edit the entry area.

+
+
+
+
+
+ +
+
+
+
+

3.1.7. The + Query Fragments window

+
+
+
+ +

Selecting the Tools + → Query Fragments + menu entry will open a window with radio- and + check-buttons which can be used to activate query + language fragments for filtering the current query. This + can be useful if you have frequent reusable selectors, + for example, filtering on alternate directories, or + searching just one category of files, not covered by the + standard category selectors.

+ +

The contents of the window are entirely customizable, + and defined by the contents of the fragbuts.xml file inside the + configuration directory. The sample file distributed with + Recoll (which you should + be able to find under /usr/share/recoll/examples/fragbuts.xml), + contains an example which filters the results from the + WEB history.

+ +

Here follows an example:

+
+<?xml version="1.0" encoding="UTF-8"?>
+
+<fragbuts version="1.0">
+
+  <radiobuttons>
+
+    <fragbut>
+      <label>Include Web Results</label>
+      <frag></frag>
+    </fragbut>
+
+    <fragbut>
+      <label>Exclude Web Results</label>
+      <frag>-rclbes:BGL</frag>
+    </fragbut>
+
+    <fragbut>
+      <label>Only Web Results</label>
+      <frag>rclbes:BGL</frag>
+    </fragbut>
+
+  </radiobuttons>
+
+  <buttons>
+
+    <fragbut>
+      <label>Year 2010</label>
+      <frag>date:2010-01-01/2010-12-31</frag>
+    </fragbut>
+
+    <fragbut>
+      <label>My Great Directory Only</label>
+      <frag>dir:/my/great/directory</frag>
+    </fragbut>
+
+  </buttons>
+</fragbuts>
+
+ +

Each radiobuttons or + buttons section defines a + line of checkbuttons or radiobuttons inside the window. + Any number of buttons can be selected, but the + radiobuttons in a line are exclusive.

+ +

Each fragbut section + defines the label for a button, and the Query Language + fragment which will be added (as an AND filter) before + performing the query if the button is active.

+ +

This feature is new in Recoll 1.20, and will probably be + refined depending on user feedback.

+
+ +
+
+
+
+

3.1.8. Complex/advanced + search

+
+
+
+ +

The advanced search dialog helps you build more + complex queries without memorizing the search language + constructs. It can be opened through the Tools menu or through the main + toolbar.

+ +

Recoll keeps a + history of searches. See Advanced search + history.

+ +

The dialog has two tabs:

+ +
+
    +
  1. +

    The first tab lets you specify terms to search + for, and permits specifying multiple clauses which + are combined to build the search.

    +
  2. + +
  3. +

    The second tab lets filter the results according + to file size, date of modification, MIME type, or + location.

    +
  4. +
+
+ +

Click on the Start + Search button in the advanced search dialog, or + type Enter + in any text field to start the search. The button in the + main window always performs a simple search.

+ +

Click on the Show query + details link at the top of the result page to see + the query expansion.

+ +
+
+
+
+

3.1.8.1. Avanced + search: the "find" tab

+
+
+
+ +

This part of the dialog lets you constructc a query + by combining multiple clauses of different types. Each + entry field is configurable for the following + modes:

+ +
+
    +
  • +

    All terms.

    +
  • + +
  • +

    Any term.

    +
  • + +
  • +

    None of the terms.

    +
  • + +
  • +

    Phrase (exact terms in order within an + adjustable window).

    +
  • + +
  • +

    Proximity (terms in any order within an + adjustable window).

    +
  • + +
  • +

    Filename search.

    +
  • +
+
+ +

Additional entry fields can be created by clicking + the Add clause + button.

+ +

When searching, the non-empty clauses will be + combined either with an AND or an OR conjunction, + depending on the choice made on the left (All clauses or Any clause).

+ +

Entries of all types except "Phrase" and "Near" + accept a mix of single words and phrases enclosed in + double quotes. Stemming and wildcard expansion will be + performed as for simple search.

+ +

Phrases and Proximity searches. These + two clauses work in similar ways, with the difference + that proximity searches do not impose an order on the + words. In both cases, an adjustable number (slack) of + non-matched words may be accepted between the searched + ones (use the counter on the left to adjust this + count). For phrases, the default count is zero (exact + match). For proximity it is ten (meaning that two + search terms, would be matched if found within a window + of twelve words). Examples: a phrase search for + quick fox with a slack of + 0 will match quick fox but + not quick brown fox. With + a slack of 1 it will match the latter, but not + fox quick. A proximity + search for quick fox with + the default slack will match the latter, and also + a fox is a cunning and quick + animal.

+
+ +
+
+
+
+

3.1.8.2. Avanced + search: the "filter" tab

+
+
+
+ +

This part of the dialog has several sections which + allow filtering the results of a search according to a + number of criteria

+ +
+
    +
  • +

    The first section allows filtering by dates of + last modification. You can specify both a minimum + and a maximum date. The initial values are set + according to the oldest and newest documents + found in the index.

    +
  • + +
  • +

    The next section allows filtering the results + by file size. There are two entries for minimum + and maximum size. Enter decimal numbers. You can + use suffix multipliers: k/K, m/M, g/G, t/T for 1E3, 1E6, 1E9, 1E12 + respectively.

    +
  • + +
  • +

    The next section allows filtering the results + by their MIME types, or MIME categories (ie: + media/text/message/etc.).

    + +

    You can transfer the types between two boxes, + to define which will be included or excluded by + the search.

    + +

    The state of the file type selection can be + saved as the default (the file type filter will + not be activated at program start-up, but the + lists will be in the restored state).

    +
  • + +
  • +

    The bottom section allows restricting the + search results to a sub-tree of the indexed area. + You can use the Invert checkbox to search for + files not in the sub-tree instead. If you use + directory filtering often and on big subsets of + the file system, you may think of setting up + multiple indexes instead, as the performance may + be better.

    + +

    You can use relative/partial paths for + filtering. Ie, entering dirA/dirB would match either + /dir1/dirA/dirB/myfile1 or + /dir2/dirA/dirB/someother/myfile2.

    +
  • +
+
+
+ +
+
+
+
+

3.1.8.3. Avanced + search history

+
+
+
+ +

The advanced search tool memorizes the last 100 + searches performed. You can walk the saved searches by + using the up and down arrow keys while the keyboard + focus belongs to the advanced search dialog.

+ +

The complex search history can be erased, along with + the one for simple search, by selecting the + FileErase Search History menu + entry.

+
+
+ +
+
+
+
+

3.1.9. The + term explorer tool

+
+
+
+ +

Recoll automatically + manages the expansion of search terms to their + derivatives (ie: plural/singular, verb inflections). But + there are other cases where the exact search term is not + known. For example, you may not remember the exact + spelling, or only know the beginning of the name.

+ +

The search will only propose replacement terms with + spelling variations when no matching document were found. + In some cases, both proper spellings and mispellings are + present in the index, and it may be interesting to look + for them explicitely.

+ +

The term explorer tool (started from the toolbar icon + or from the Term explorer + entry of the Tools menu) + can be used to search the full index terms list. It has + three modes of operations:

+ +
+
+
Wildcard
+ +
+

In this mode of operation, you can enter a + search string with shell-like wildcards (*, ?, []). + ie: xapi* + would display all index terms beginning with + xapi. + (More about wildcards here).

+
+ +
Regular expression
+ +
+

This mode will accept a regular expression as + input. Example: word[0-9]+. The + expression is implicitely anchored at the + beginning. Ie: press will match + pression + but not expression. You can + use .*press to match + the latter, but be aware that this will cause a + full index term list scan, which can be quite + long.

+
+ +
Stem expansion
+ +
+

This mode will perform the usual stem expansion + normally done as part user input processing. As + such it is probably mostly useful to demonstrate + the process.

+
+ +
Spelling/Phonetic
+ +
+

In this mode, you enter the term as you think it + is spelled, and Recoll will do its best to + find index terms that sound like your entry. This + mode uses the Aspell spelling application, + which must be installed on your system for things + to work (if your documents contain non-ascii + characters, Recoll + needs an aspell version newer than 0.60 for UTF-8 + support). The language which is used to build the + dictionary out of the index terms (which is done at + the end of an indexing pass) is the one defined by + your NLS environment. Weird things will probably + happen if languages are mixed up.

+
+
+
+ +

Note that in cases where Recoll does not know the beginning + of the string to search for (ie a wildcard expression + like *coll), + the expansion can take quite a long time because the full + index term list will have to be processed. The expansion + is currently limited at 10000 results for wildcards and + regular expressions. It is possible to change the limit + in the configuration file.

+ +

Double-clicking on a term in the result list will + insert it into the simple search entry field. You can + also cut/paste between the result list and any entry + field (the end of lines will be taken care of).

+
+ +
+
+
+
+

3.1.10. Multiple + indexes

+
+
+
+ +

See the section describing the use + of multiple indexes for generalities. Only the + aspects concerning the recoll GUI are + described here.

+ +

A recoll + program instance is always associated with a specific + index, which is the one to be updated when requested from + the File menu, but it can + use any number of Recoll + indexes for searching. The external indexes can be + selected through the external + indexes tab in the preferences dialog.

+ +

Index selection is performed in two phases. A set of + all usable indexes must first be defined, and then the + subset of indexes to be used for searching. These + parameters are retained across program executions (there + are kept separately for each Recoll configuration). The set of + all indexes is usually quite stable, while the active + ones might typically be adjusted quite frequently.

+ +

The main index (defined by RECOLL_CONFDIR) is always active. If this + is undesirable, you can set up your base configuration to + index an empty directory.

+ +

When adding a new index to the set, you can select + either a Recoll + configuration directory, or directly a Xapian index directory. In the first + case, the Xapian index + directory will be obtained from the selected + configuration.

+ +

As building the set of all indexes can be a little + tedious when done through the user interface, you can use + the RECOLL_EXTRA_DBS + environment variable to provide an initial set. This + might typically be set up by a system administrator so + that every user does not have to do it. The variable + should define a colon-separated list of index + directories, ie:

+
+export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db
+
+ +

Another environment variable, RECOLL_ACTIVE_EXTRA_DBS allows adding to + the active list of indexes. This variable was suggested + and implemented by a Recoll user. It is mostly useful if + you use scripts to mount external volumes with + Recoll indexes. By using + RECOLL_EXTRA_DBS and + RECOLL_ACTIVE_EXTRA_DBS, you + can add and activate the index for the mounted volume + when starting recoll.

+ +

RECOLL_ACTIVE_EXTRA_DBS is + available for Recoll + versions 1.17.2 and later. A change was made in the same + update so that recoll will + automatically deactivate unreachable indexes when + starting up.

+
+ +
+
+
+
+

3.1.11. Document + history

+
+
+
+ +

Documents that you actually view (with the internal + preview or an external tool) are entered into the + document history, which is remembered.

+ +

You can display the history list by using the + Tools/Doc History menu entry.

+ +

You can erase the document history by using the + Erase document history + entry in the File menu.

+
+ +
+
+
+
+

3.1.12. Sorting + search results and collapsing duplicates

+
+
+
+ +

The documents in a result list are normally sorted in + order of relevance. It is possible to specify a different + sort order, either by using the vertical arrows in the + GUI toolbox to sort by date, or switching to the result + table display and clicking on any header. The sort order + chosen inside the result table remains active if you + switch back to the result list, until you click one of + the vertical arrows, until both are unchecked (you are + back to sort by relevance).

+ +

Sort parameters are remembered between program + invocations, but result sorting is normally always + inactive when the program starts. It is possible to keep + the sorting activation state between program invocations + by checking the Remember sort + activation state option in the preferences.

+ +

It is also possible to hide duplicate entries inside + the result list (documents with the exact same contents + as the displayed one). The test of identity is based on + an MD5 hash of the document container, not only of the + text contents (so that ie, a text document with an image + added will not be a duplicate of the text only). + Duplicates hiding is controlled by an entry in the + GUI configuration dialog, + and is off by default.

+ +

As of release 1.19, when a result document does have + undisplayed duplicates, a Dups link will be shown with the result + list entry. Clicking the link will display the paths + (URLs + ipaths) for the duplicate entries.

+
+ +
+
+
+
+

3.1.13. Search tips, + shortcuts

+
+
+
+ +
+
+
+
+

3.1.13.1. Terms + and search expansion

+
+
+
+ +

Term completion. Typing Esc Space in the simple + search entry field while entering a word will either + complete the current word if its beginning matches a + unique term in the index, or open a window to propose a + list of completions.

+ +

Picking up new terms from result or preview + text. Double-clicking on a word in the result + list or in a preview window will copy it to the simple + search entry field.

+ +

Wildcards. Wildcards can be used inside + search terms in all forms of searches. More about + wildcards.

+ +

Automatic suffixes. Words like + odt or ods can be automatically turned into + query language ext:xxx + clauses. This can be enabled in the Search preferences panel in the + GUI.

+ +

Disabling stem expansion. Entering a + capitalized word in any search field will prevent stem + expansion (no search for gardening if you enter Garden instead of garden). This is the only case where + character case should make a difference for a + Recoll search. You can + also disable stem expansion or change the stemming + language in the preferences.

+ +

Finding related documents. Selecting the + Find similar documents + entry in the result list paragraph right-click menu + will select a set of "interesting" terms from the + current result, and insert them into the simple search + entry field. You can then possibly edit the list and + start a search to find documents which may be + apparented to the current result.

+ +

File names. File names are added as + terms during indexing, and you can specify them as + ordinary terms in normal search fields (Recoll used to index all + directories in the file path as terms. This has been + abandoned as it did not seem really useful). + Alternatively, you can use the specific file name + search which will only look for file names, + and may be faster than the generic search especially + when using wildcards.

+
+ +
+
+
+
+

3.1.13.2. Working + with phrases and proximity

+
+
+
+ +

Phrases and Proximity searches. A phrase + can be looked for by enclosing it in double quotes. + Example: "user manual" + will look only for occurrences of user immediately followed by + manual. You can use the + This phrase field of the + advanced search dialog to the same effect. Phrases can + be entered along simple terms in all simple or advanced + search entry fields (except This + exact phrase).

+ +

AutoPhrases. This option can be set in + the preferences dialog. If it is set, a phrase will be + automatically built and added to simple searches when + looking for Any terms. + This will not change radically the results, but will + give a relevance boost to the results where the search + terms appear as a phrase. Ie: searching for + virtual reality will still + find all documents where either virtual or reality or both appear, but those + which contain virtual + reality should appear sooner in the list.

+ +

Phrase searches can strongly slow down a query if + most of the terms in the phrase are common. This is why + the autophrase option is + off by default for Recoll versions before 1.17. As of + version 1.17, autophrase + is on by default, but very common terms will be removed + from the constructed phrase. The removal threshold can + be adjusted from the search preferences.

+ +

Phrases and abbreviations. As of + Recoll version 1.17, + dotted abbreviations like I.B.M. are also automatically indexed + as a word without the dots: IBM. Searching for the word inside a + phrase (ie: "the IBM + company") will only match the dotted + abrreviation if you increase the phrase slack (using + the advanced search panel control, or the o query language modifier). Literal + occurences of the word will be matched normally.

+
+ +
+
+
+
+

3.1.13.3. Others

+
+
+
+ +

Using fields. You can use the query language and + field specifications to only search certain parts of + documents. This can be especially helpful with email, + for example only searching emails from a specific + originator: search tips + from:helpfulgui

+ +

Ajusting the result table columns. When + displaying results in table mode, you can use a right + click on the table headers to activate a pop-up menu + which will let you adjust what columns are displayed. + You can drag the column headers to adjust their order. + You can click them to sort by the field displayed in + the column. You can also save the result list in CSV + format.

+ +

Changing the GUI geometry. It is + possible to configure the GUI in wide form factor by + dragging the toolbars to one of the sides (their + location is remembered between sessions), and moving + the category filters to a menu (can be set in the + Preferences → + GUI configuration + → User interface + panel).

+ +

Query explanation. You can get an exact + description of what the query looked for, including + stem expansion, and Boolean operators used, by clicking + on the result list header.

+ +

Advanced search history. As of + Recoll 1.18, you can + display any of the last 100 complex searches performed + by using the up and down arrow keys while the advanced + search panel is active.

+ +

Browsing the result list inside a preview + window. Entering Shift-Down or + Shift-Up + (Shift + + an arrow key) in a preview window will display the next + or the previous document from the result list. Any + secondary search currently active will be executed on + the new document.

+ +

Scrolling the result list from the + keyboard. You can use PageUp and + PageDown + to scroll the result list, Shift+Home to go back + to the first page. These work even while the focus is + in the search entry.

+ +

Result table: moving the focus to the + table. You can use Ctrl-r to move the + focus from the search entry to the table, and then use + the arrow keys to change the current row. Ctrl-Shift-s returns + to the search.

+ +

Result table: open / preview. With the + focus in the result table, you can use Ctrl-o to open the + document from the current row, Ctrl-Shift-o to open + the document and close recoll, Ctrl-d to preview the + document.

+ +

Editing a new search while the focus is not in + the search entry. You can use the Ctrl-Shift-S shortcut + to return the cursor to the search entry (and select + the current search text), while the focus is anywhere + in the main window.

+ +

Forced opening of a preview window. You + can use Shift+Click on a + result list Preview link + to force the creation of a preview window instead of a + new tab in the existing one.

+ +

Closing previews. Entering Ctrl-W in a tab will + close it (and, for the last tab, close the preview + window). Entering Esc will close the + preview window and all its tabs.

+ +

Printing previews. Entering Ctrl-P in a preview + window will print the currently displayed text.

+ +

Quitting. Entering Ctrl-Q almost anywhere + will close the application.

+
+
+ +
+
+
+
+

3.1.14. Saving and + restoring queries (1.21 and later)

+
+
+
+ +

Both simple and advanced query dialogs save recent + history, but the amount is limited: old queries will + eventually be forgotten. Also, important queries may be + difficult to find among others. This is why both types of + queries can also be explicitely saved to files, from the + GUI menus: File → + Save last query / Load last + query

+ +

The default location for saved queries is a + subdirectory of the current configuration directory, but + saved queries are ordinary files and can be written or + moved anywhere.

+ +

Some of the saved query parameters are part of the + preferences (e.g. autophrase + or the active external indexes), and may differ when the + query is loaded from the time it was saved. In this case, + Recoll will warn of the + differences, but will not change the user + preferences.

+
+ +
+
+
+
+

3.1.15. Customizing + the search interface

+
+
+
+ +

You can customize some aspects of the search interface + by using the GUI + configuration entry in the Preferences menu.

+ +

There are several tabs in the dialog, dealing with the + interface itself, the parameters used for searching and + returning results, and what indexes are searched.

+ +

User interface + parameters: 

+ +
+
    +
  • +

    Highlight color for query + terms: Terms from the user query are + highlighted in the result list samples and the + preview window. The color can be chosen here. Any + Qt color string should work (ie red, #ff0000). The default is + blue.

    +
  • + +
  • +

    Style sheet: The + name of a Qt style + sheet text file which is applied to the whole + Recoll application on startup. The default value is + empty, but there is a skeleton style sheet + (recoll.qss) inside + the /usr/share/recoll/examples + directory. Using a style sheet, you can change most + recoll graphical + parameters: colors, fonts, etc. See the sample file + for a few simple examples.

    + +

    You should be aware that parameters (e.g.: the + background color) set inside the Recoll GUI style sheet will + override global system preferences, with possible + strange side effects: for example if you set the + foreground to a light color and the background to a + dark one in the desktop preferences, but only the + background is set inside the Recoll style sheet, and it is + light too, then text will appear light-on-light + inside the Recoll + GUI.

    +
  • + +
  • +

    Maximum text size + highlighted for preview Inserting highlights + on search term inside the text before inserting it + in the preview window involves quite a lot of + processing, and can be disabled over the given text + size to speed up loading.

    +
  • + +
  • +

    Prefer HTML to plain text + for preview if set, Recoll will display HTML + as such inside the preview window. If this causes + problems with the Qt HTML display, you can uncheck + it to display the plain text version instead.

    +
  • + +
  • +

    Plain text to HTML line + style: when displaying plain text inside the + preview window, Recoll tries to preserve some + of the original text line breaks and indentation. + It can either use PRE HTML tags, which will well + preserve the indentation but will force horizontal + scrolling for long lines, or use BR tags to break + at the original line breaks, which will let the + editor introduce other line breaks according to the + window width, but will lose some of the original + indentation. The third option has been available in + recent releases and is probably now the best one: + use PRE tags with line wrapping.

    +
  • + +
  • +

    Choose editor + applicationsr: this opens a dialog which + allows you to select the application to be used to + open each MIME type. The default is nornally to use + the xdg-open utility, + but you can override it.

    +
  • + +
  • +

    Exceptions: even + wen xdg-open is used + by default for opening documents, you can set + exceptions for MIME types that will still be opened + according to Recoll preferences. This is + useful for passing parameters like page numbers or + search strings to applications that support them + (e.g. evince). + This cannot be done with xdg-open which + only supports passing one parameter.

    +
  • + +
  • +

    Document filter choice + style: this will let you choose if the + document categories are displayed as a list or a + set of buttons, or a menu.

    +
  • + +
  • +

    Start with simple search + mode: this lets you choose the value of the + simple search type on program startup. Either a + fixed value (e.g. Query + Language, or the value in use when the + program last exited.

    +
  • + +
  • +

    Auto-start simple search + on white space entry: if this is checked, a + search will be executed each time you enter a space + in the simple search input field. This lets you + look at the result list as you enter new terms. + This is off by default, you may like it or + not...

    +
  • + +
  • +

    Start with advanced + search dialog open : If you use this dialog + frequently, checking the entries will get it to + open when recoll starts.

    +
  • + +
  • +

    Remember sort activation + state if set, Recoll will remember the sort + tool stat between invocations. It normally starts + with sorting disabled.

    +
  • +
+
+ +

Result list + parameters: 

+ +
+
    +
  • +

    Number of results in a + result page

    +
  • + +
  • +

    Result list font: + There is quite a lot of information shown in the + result list, and you may want to customize the font + and/or font size. The rest of the fonts used by + Recoll are + determined by your generic Qt config (try the + qtconfig + command).

    +
  • + +
  • +

    Edit result list paragraph format + string: allows you to change the + presentation of each result list entry. See the + result list + customisation section.

    +
  • + +
  • +

    Edit result page HTML header + insert: allows you to define text inserted + at the end of the result page HTML header. More + detail in the result list + customisation section.

    +
  • + +
  • +

    Date format: + allows specifying the format used for displaying + dates inside the result list. This should be + specified as an strftime() string (man + strftime).

    +
  • + +
  • +

    Abstract snippet separator: for + synthetic abstracts built from index data, which + are usually made of several snippets from different + parts of the document, this defines the snippet + separator, an ellipsis by default.

    +
  • +
+
+ +

Search + parameters: 

+ +
+
    +
  • +

    Hide duplicate + results: decides if result list entries are + shown for identical documents found in different + places.

    +
  • + +
  • +

    Stemming language: + stemming obviously depends on the document's + language. This listbox will let you chose among the + stemming databases which were built during indexing + (this is set in the + main configuration file), or later added with + recollindex + -s (See the recollindex manual). + Stemming languages which are dynamically added will + be deleted at the next indexing pass unless they + are also added in the configuration file.

    +
  • + +
  • +

    Automatically add phrase + to simple searches: a phrase will be + automatically built and added to simple searches + when looking for Any + terms. This will give a relevance boost to + the results where the search terms appear as a + phrase (consecutive and in order).

    +
  • + +
  • +

    Autophrase term frequency + threshold percentage: very frequent terms + should not be included in automatic phrase searches + for performance reasons. The parameter defines the + cutoff percentage (percentage of the documents + where the term appears).

    +
  • + +
  • +

    Replace abstracts from + documents: this decides if we should + synthesize and display an abstract in place of an + explicit abstract found within the document + itself.

    +
  • + +
  • +

    Dynamically build + abstracts: this decides if Recoll tries to build document + abstracts (lists of snippets) when + displaying the result list. Abstracts are + constructed by taking context from the document + information, around the search terms.

    +
  • + +
  • +

    Synthetic abstract + size: adjust to taste...

    +
  • + +
  • +

    Synthetic abstract + context words: how many words should be + displayed around each term occurrence.

    +
  • + +
  • +

    Query language magic file + name suffixes: a list of words which + automatically get turned into ext:xxx file name suffix clauses + when starting a query language query (ie: + doc xls xlsx...). This + will save some typing for people who use file types + a lot when querying.

    +
  • +
+
+ +

External + indexes: This panel will let you browse for + additional indexes that you may want to search. External + indexes are designated by their database directory (ie: + /home/someothergui/.recoll/xapiandb, + /usr/local/recollglobal/xapiandb).

+ +

Once entered, the indexes will appear in the + External indexes list, and + you can chose which ones you want to use at any moment by + checking or unchecking their entries.

+ +

Your main database (the one the current configuration + indexes to), is always implicitly active. If this is not + desirable, you can set up your configuration so that it + indexes, for example, an empty directory. An alternative + indexer may also need to implement a way of purging the + index from stale data,

+ +
+
+
+
+

3.1.15.1. The + result list format

+
+
+
+ +

Newer versions of Recoll (from 1.17) normally use + WebKit HTML widgets for the result list and the + snippets + window (this may be disabled at build time). Total + customisation is possible with full support for CSS and + Javascript. Conversely, there are limits to what you + can do with the older Qt QTextBrowser, but still, it is + possible to decide what data each result will contain, + and how it will be displayed.

+ +

The result list presentation can be exhaustively + customized by adjusting two elements:

+ +
+
    +
  • +

    The paragraph format

    +
  • + +
  • +

    HTML code inside the header section. For + versions 1.21 and later, this is also used for + the snippets + window

    +
  • +
+
+ +

The paragraph format and the header fragment can be + edited from the Result + list tab of the GUI + configuration.

+ +

The header fragment is used both for the result list + and the snippets window. The snippets list is a table + and has a snippets class + attribute. Each paragraph in the result list is a + table, with class respar, + but this can be changed by editing the paragraph + format.

+ +

There are a few examples on the page about customising the result list on + the Recoll web + site.

+ +
+
+
+
+
The + paragraph format
+
+
+
+ +

This is an arbitrary HTML string where the + following printf-like % + substitutions will be performed:

+ +
+
    +
  • +

    %A. Abstract

    +
  • + +
  • +

    %D. Date

    +
  • + +
  • +

    %I. Icon image name. This is + normally determined from the MIME type. The + associations are defined inside the mimeconf configuration + file. If a thumbnail for the file is found + at the standard Freedesktop location, this will + be displayed instead.

    +
  • + +
  • +

    %K. Keywords (if any)

    +
  • + +
  • +

    %L. Precooked Preview, Edit, and + possibly Snippets links

    +
  • + +
  • +

    %M. MIME type

    +
  • + +
  • +

    %N. result Number inside the + result page

    +
  • + +
  • +

    %P. Parent folder Url. In the + case of an embedded document, this is the + parent folder for the top level container + file.

    +
  • + +
  • +

    %R. Relevance percentage

    +
  • + +
  • +

    %S. Size information

    +
  • + +
  • +

    %T. Title or Filename if not + set.

    +
  • + +
  • +

    %t. Title or Filename if not + set.

    +
  • + +
  • +

    %U. Url

    +
  • +
+
+ +

The format of the Preview, Edit, and Snippets + links is <a + href="P%N">, <a + href="E%N"> and <a + href="A%N"> where docnum (%N) expands + to the document number inside the result page).

+ +

A link target defined as "F%N" will open the document + corresponding to the %P + parent folder expansion, usually creating a file + manager window on the folder where the container file + resides. E.g.:

+
+<a href="F%N">%P</a>
+
+ +

A link target defined as R%N|scriptname + will run the corresponding script on the result file + (if the document is embedded, the script will be + started on the top-level parent). See the + section about defining scripts.

+ +

In addition to the predefined values above, all + strings like %(fieldname) will be replaced by the + value of the field named fieldname for this document. Only + stored fields can be accessed in this way, the value + of indexed but not stored fields is not known at this + point in the search process (see field + configuration). There are currently very few + fields stored by default, apart from the values above + (only author and + filename), so this + feature will need some custom local configuration to + be useful. An example candidate would be the + recipient field which is + generated by the message input handlers.

+ +

The default value for the paragraph format string + is:

+
+    "<table class=\"respar\">\n"
+    "<tr>\n"
+    "<td><a href='%U'><img src='%I' width='64'></a></td>\n"
+    "<td>%L &nbsp;<i>%S</i> &nbsp;&nbsp;<b>%T</b><br>\n"
+    "<span style='white-space:nowrap'><i>%M</i>&nbsp;%D</span>&nbsp;&nbsp;&nbsp; <i>%U</i>&nbsp;%i<br>\n"
+    "%A %K</td>\n"
+    "</tr></table>\n"
+
+ +

You may, for example, try the following for a more + web-like experience:

+
+<u><b><a href="P%N">%T</a></b></u><br>
+%A<font color=#008000>%U - %S</font> - %L
+
+ +

Note that the P%N link in the above paragraph + makes the title a preview link. Or the clean + looking:

+
+<img src="%I" align="left">%L <font color="#900000">%R</font>
+&nbsp;&nbsp;<b>%T&</b><br>%S&nbsp;
+<font color="#808080"><i>%U</i></font>
+<table bgcolor="#e0e0e0">
+<tr><td><div>%A</div></td></tr>
+</table>%K
+
+ +

These samples, and some others are on the web site, with pictures to show + how they look.

+ +

It is also possible to define the value of + the snippet separator inside the abstract + section.

+
+
+
+
+ +
+
+
+
+

3.2. Searching with the KDE + KIO slave

+
+
+
+ +
+
+
+
+

3.2.1. What's + this

+
+
+
+ +

The Recoll KIO slave + allows performing a Recoll search by entering an + appropriate URL in a KDE open dialog, or with an + HTML-based interface displayed in Konqueror.

+ +

The HTML-based interface is similar to the Qt-based + interface, but slightly less powerful for now. Its + advantage is that you can perform your search while + staying fully within the KDE framework: drag and drop + from the result list works normally and you have your + normal choice of applications for opening files.

+ +

The alternative interface uses a directory view of + search results. Due to limitations in the current KIO + slave interface, it is currently not obviously useful (to + me).

+ +

The interface is described in more detail inside a + help file which you can access by entering recoll:/ inside the konqueror URL line + (this works only if the recoll KIO slave has been + previously installed).

+ +

The instructions for building this module are located + in the source tree. See: kde/kio/recoll/00README.txt. Some Linux + distributions do package the kio-recoll module, so check + before diving into the build process, maybe it's already + out there ready for one-click installation.

+
+ +
+
+
+
+

3.2.2. Searchable + documents

+
+
+
+ +

As a sample application, the Recoll KIO slave could allow + preparing a set of HTML documents (for example a manual) + so that they become their own search interface inside + konqueror.

+ +

This can be done by either explicitly inserting + <a + href="recoll://..."> links around some document + areas, or automatically by adding a very small + javascript program to + the documents, like the following example, which would + initiate a search by double-clicking any term:

+
+<script language="JavaScript">
+    function recollsearch() {
+        var t = document.getSelection();
+        window.location.href = 'recoll://search/query?qtp=a&p=0&q=' +
+            encodeURIComponent(t);
+    }
+</script>
+ ....
+<body ondblclick="recollsearch()">
+
+
+
+
+ +
+
+
+
+

3.3. Searching on + the command line

+
+
+
+ +

There are several ways to obtain search results as a + text stream, without a graphical interface:

+ +
+
    +
  • +

    By passing option -t + to the recoll program, or + by calling it as recollq (through a + link).

    +
  • + +
  • +

    By using the recollq + program.

    +
  • + +
  • +

    By writing a custom Python program, using the + Recoll Python API.

    +
  • +
+
+ +

The first two methods work in the same way and + accept/need the same arguments (except for the additional + -t to recoll). The query to be + executed is specified as command line arguments.

+ +

recollq is + not built by default. You can use the Makefile in the query directory to build it. This is a + very simple program, and if you can program a little c++, + you may find it useful to taylor its output format to your + needs. Not that recollq is only really useful on systems + where the Qt libraries (or even the X11 ones) are not + available. Otherwise, just use recoll + -t, which takes the exact same parameters and + options which are described for recollq

+ +

recollq + has a man page (not installed by default, look in the + doc/man directory). The Usage + string is as follows:

+
+recollq: usage:
+ -P: Show the date span for all the documents present in the index
+ [-o|-a|-f] [-q] <query string>
+ Runs a recoll query and displays result lines. 
+  Default: will interpret the argument(s) as a xesam query string
+    query may be like: 
+    implicit AND, Exclusion, field spec:    t1 -t2 title:t3
+    OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4)
+    Phrase: "t1 t2" (needs additional quoting on cmd line)
+  -o Emulate the GUI simple search in ANY TERM mode
+  -a Emulate the GUI simple search in ALL TERMS mode
+  -f Emulate the GUI simple search in filename mode
+  -q is just ignored (compatibility with the recoll GUI command line)
+Common options:
+    -c <configdir> : specify config directory, overriding $RECOLL_CONFDIR
+    -d also dump file contents
+    -n [first-]<cnt> define the result slice. The default value for [first]
+       is 0. Without the option, the default max count is 2000.
+       Use n=0 for no limit
+    -b : basic. Just output urls, no mime types or titles
+    -Q : no result lines, just the processed query and result count
+    -m : dump the whole document meta[] array for each result
+    -A : output the document abstracts
+    -S fld : sort by field <fld>
+    -s stemlang : set stemming language to use (must exist in index...)
+       Use -s "" to turn off stem expansion
+    -D : sort descending
+    -i <dbdir> : additional index, several can be given
+    -e use url encoding (%xx) for urls
+    -F <field name list> : output exactly these fields for each result.
+       The field values are encoded in base64, output in one line and 
+       separated by one space character. This is the recommended format 
+       for use by other programs. Use a normal query with option -m to 
+       see the field names.
+
+ +

Sample execution:

+
+recollq 'ilur -nautique mime:text/html'
+Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11)
+  OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html))
+4 results
+text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html]      [comptes.html]  18593   bytes   
+text/html       [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio...
+text/html       [file:///Users/uncrypted-dockes/projets/pagepers/index.html]    [psxtcl/writemime/recoll]...
+text/html       [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree....
+
+
+ +
+
+
+
+

3.4. Using Synonyms + (1.22)

+
+
+
+ +

Term synonyms: there are a number of ways to + use term synonyms for searching text:

+ +
+
    +
  • +

    At index creation time, they can be used to alter + the indexed terms, either increasing or decreasing + their number, by expanding the original terms to all + synonyms, or by reducing all synonym terms to a + canonical one.

    +
  • + +
  • +

    At query time, they can be used to match texts + containing terms which are synonyms of the ones + specified by the user, either by expanding the query + for all synonyms, or by reducing the user entry to + canonical terms (the latter only works if the + corresponding processing has been performed while + creating the index).

    +
  • +
+
+ +

Recoll only uses + synonyms at query time. A user query term which part of a + synonym group will be optionally expanded into an + OR query for all terms in the + group.

+ +

Synonym groups are defined inside ordinary text files. + Each line in the file defines a group.

+ +

Example:

+
+hi hello "good morning"
+
+# not sure about "au revoir" though. Is this english ?
+bye goodbye "see you" \
+  "au revoir" 
+    
+
+ +

As usual, lines beginning with a # are comments, empty lines are ignored, + and lines can be continued by ending them with a + backslash.

+ +

Multi-word synonyms are supported, but be aware that + these will generate phrase queries, which may degrade + performance and will disable stemming expansion for the + phrase terms.

+ +

The synonyms file can be specified in the Search parameters tab of the GUI configuration Preferences menu entry, or as an option + for command-line searches.

+ +

Once the file is defined, the use of synonyms can be + enabled or disabled directly from the Preferences menu.

+ +

The synonyms are searched for matches with user terms + after the latter are stem-expanded, but the contents of the + synonyms file itself is not subjected to stem expansion. + This means that a match will not be found if the form + present in the synonyms file is not present anywhere in the + document set.

+ +

The synonyms function is probably not going to help you + find your letters to Mr. Smith. It is best used for + domain-specific searches. For example, it was initially + suggested by a user performing searches among historical + documents: the synonyms file would contains nicknames and + aliases for each of the persons of interest.

+
+ +
+
+
+
+

3.5. Path + translations

+
+
+
+ +

In some cases, the document paths stored inside the + index do not match the actual ones, so that document + previews and accesses will fail. This can occur in a number + of circumstances:

+ +
+
    +
  • +

    When using multiple indexes it is a relatively + common occurrence that some will actually reside on a + remote volume, for exemple mounted via NFS. In this + case, the paths used to access the documents on the + local machine are not necessarily the same than the + ones used while indexing on the remote machine. For + example, /home/me may + have been used as a topdirs elements while indexing, but + the directory might be mounted as /net/server/home/me on the local + machine.

    +
  • + +
  • +

    The case may also occur with removable disks. It + is perfectly possible to configure an index to live + with the documents on the removable disk, but it may + happen that the disk is not mounted at the same place + so that the documents paths from the index are + invalid.

    +
  • + +
  • +

    As a last exemple, one could imagine that a big + directory has been moved, but that it is currently + inconvenient to run the indexer.

    +
  • +
+
+ +

Recoll has a facility + for rewriting access paths when extracting the data from + the index. The translations can be defined for the main + index and for any additional query index.

+ +

The path translation facility will be useful whenever + the documents paths seen by the indexer are not the same as + the ones which should be used at query time.

+ +

In the above NFS example, Recoll could be instructed to rewrite + any file:///home/me URL from + the index to file:///net/server/home/me, allowing + accesses from the client.

+ +

The translations are defined in the ptrans configuration file, which can + be edited by hand or from the GUI external indexes + configuration dialog: PreferencesExternal index dialog, then click the + Paths translations button on + the right below the index list.

+ +
+

Note

+ +

Due to a current bug, the GUI must be restarted after + changing the ptrans values + (even when they were changed from the GUI).

+
+
+ +
+
+
+
+

3.6. The query + language

+
+
+
+ +

The query language processor is activated in the GUI + simple search entry when the search mode selector is set to + Query Language. It can also + be used with the KIO slave or the command line search. It + broadly has the same capabilities as the complex search + interface in the GUI.

+ +

The language was based on the now defunct Xesam user search language + specification.

+ +

If the results of a query language search puzzle you and + you doubt what has been actually searched for, you can use + the GUI Show Query link at the + top of the result list to check the exact query which was + finally executed by Xapian.

+ +

Here follows a sample request that we are going to + explain:

+
+          author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes
+      
+
+ +

This would search for all documents with John Doe appearing as a + phrase in the author field (exactly what this is would + depend on the document type, ie: the From: header, for an email message), and + containing either beatles or lennon and either + live or + unplugged but not + potatoes (in any + part of the document).

+ +

An element is composed of an optional field + specification, and a value, separated by a colon (the field + separator is the last colon in the element). Examples: + Eugenie, + author:balzac, + dc:title:grandet + dc:title:"eugenie + grandet"

+ +

The colon, if present, means "contains". Xesam defines + other relations, which are mostly unsupported for now + (except in special cases, described further down).

+ +

All elements in the search entry are normally combined + with an implicit AND. It is possible to specify that + elements be OR'ed instead, as in Beatles OR Lennon. The OR must be entered literally (capitals), + and it has priority over the AND associations: word1 word2 OR word3 means word1 AND (word2 OR word3) not (word1 AND word2) OR word3.

+ +

Recoll versions 1.21 + and later, allow using parentheses to group elements, which + will sometimes make things clearer, and may allow + expressing combinations which would have been difficult + otherwise.

+ +

An element preceded by a - + specifies a term that should not appear.

+ +

As usual, words inside quotes define a phrase (the order + of words is significant), so that title:"prejudice pride" is + not the same as title:prejudice + title:pride, and is unlikely to find a + result.

+ +

Words inside phrases and capitalized words are not + stem-expanded. Wildcards may be used anywhere inside a + term. Specifying a wild-card on the left of a term can + produce a very slow search (or even an incorrect one if the + expansion is truncated because of excessive size). Also see + More about + wildcards.

+ +

To save you some typing, recent Recoll versions (1.20 and later) + interpret a comma-separated list of terms as an AND list + inside the field. Use slash characters ('/') for an OR + list. No white space is allowed. So

+
+author:john,lennon
+
+ +

will search for documents with john and lennon inside the author field (in any order), and

+
+author:john/ringo
+
+ +

would search for john or + ringo.

+ +

Modifiers can be set on a double-quote value, for + example to specify a proximity search (unordered). See + the modifier section. No space + must separate the final double-quote and the modifiers + value, e.g. "two + one"po10

+ +

Recoll currently + manages the following default fields:

+ +
+
    +
  • +

    title, subject or caption are synonyms which specify + data to be searched for in the document title or + subject.

    +
  • + +
  • +

    author or + from for searching the + documents originators.

    +
  • + +
  • +

    recipient or + to for searching the + documents recipients.

    +
  • + +
  • +

    keyword for searching + the document-specified keywords (few documents + actually have any).

    +
  • + +
  • +

    filename for the + document's file name. This is not necessarily set for + all documents: internal documents contained inside a + compound one (for example an EPUB section) do not + inherit the container file name any more, this was + replaced by an explicit field (see next). + Sub-documents can still have a specific filename, if it is implied by the + document format, for example the attachment file name + for an email attachment.

    +
  • + +
  • +

    containerfilename. + This is set for all documents, both top-level and + contained sub-documents, and is always the name of + the filesystem directory entry which contains the + data. The terms from this field can only be matched + by an explicit field specification (as opposed to + terms from filename + which are also indexed as general document content). + This avoids getting matches for all the sub-documents + when searching for the container file name.

    +
  • + +
  • +

    ext specifies the + file name extension (Ex: ext:html)

    +
  • +
+
+ +

Recoll 1.20 and later + have a way to specify aliases for the field names, which + will save typing, for example by aliasing filename to fn or containerfilename to cfn. See the section about the + fields file

+ +

The document input handlers used while indexing have the + possibility to create other fields with arbitrary names, + and aliases may be defined in the configuration, so that + the exact field search possibilities may be different for + you if someone took care of the customisation.

+ +

The field syntax also supports a few field-like, but + special, criteria:

+ +
+
    +
  • +

    dir for filtering the + results on file location (Ex: dir:/home/me/somedir). -dir also works to find results not + in the specified directory (release >= 1.15.8). + Tilde expansion will be performed as usual (except + for a bug in versions 1.19 to 1.19.11p1). Wildcards + will be expanded, but please have a + look at an important limitation of wildcards in + path filters.

    + +

    Relative paths also make sense, for example, + dir:share/doc would + match either /usr/share/doc or /usr/local/share/doc

    + +

    Several dir clauses + can be specified, both positive and negative. For + example the following makes sense:

    +
    +dir:recoll dir:src -dir:utils -dir:common
    +            
    +
    + +

    This would select results which have both + recoll and src in the path (in any order), and + which have not either utils or common.

    + +

    You can also use OR + conjunctions with dir: + clauses.

    + +

    A special aspect of dir clauses is that the values in + the index are not transcoded to UTF-8, and never + lower-cased or unaccented, but stored as binary. This + means that you need to enter the values in the exact + lower or upper case, and that searches for names with + diacritics may sometimes be impossible because of + character set conversion issues. Non-ASCII UNIX file + paths are an unending source of trouble and are best + avoided.

    + +

    You need to use double-quotes around the path + value if it contains space characters.

    +
  • + +
  • +

    size for filtering + the results on file size. Example: size<10000. You can use + <, > or = as operators. You can specify a + range like the following: size>100 size<1000. The usual + k/K, m/M, g/G, t/T can + be used as (decimal) multipliers. Ex: size>1k to search for files + bigger than 1000 bytes.

    +
  • + +
  • +

    date for searching or + filtering on dates. The syntax for the argument is + based on the ISO8601 standard for dates and time + intervals. Only dates are supported, no times. The + general syntax is 2 elements separated by a + / character. Each + element can be a date or a period of time. Periods + are specified as PnYnMnD. The n numbers are the + respective numbers of years, months or days, any of + which may be missing. Dates are specified as + YYYY-MM-DD. The days and + months parts may be missing. If the / is present but an element is + missing, the missing element is interpreted as the + lowest or highest date in the index. Examples:

    + +
    +
      +
    • +

      2001-03-01/2002-05-01 the + basic syntax for an interval of dates.

      +
    • + +
    • +

      2001-03-01/P1Y2M the same + specified with a period.

      +
    • + +
    • +

      2001/ from the + beginning of 2001 to the latest date in the + index.

      +
    • + +
    • +

      2001 the whole + year of 2001

      +
    • + +
    • +

      P2D/ means 2 + days ago up to now if there are no documents + with dates in the future.

      +
    • + +
    • +

      /2003 all + documents from 2003 or older.

      +
    • +
    +
    + +

    Periods can also be specified with small letters + (ie: p2y).

    +
  • + +
  • +

    mime or format for specifying the MIME type. + These clauses are processed besides the normal + Boolean logic of the search. Multiple values will be + OR'ed (instead of the normal AND). You can specify + types to be excluded, with the usual -, and use wildcards. Example: + mime:text/* + -mime:text/plain Specifying an explicit + boolean operator before a mime specification is not supported + and will produce strange results.

    +
  • + +
  • +

    type or rclcat for specifying the category + (as in text/media/presentation/etc.). The + classification of MIME types in categories is defined + in the Recoll + configuration (mimeconf), and can be modified or + extended. The default category names are those which + permit filtering results in the main GUI screen. + Categories are OR'ed like MIME types above, and can + be negated with -.

    +
  • +
+
+ +
+

Note

+ +

mime, rclcat, size and date criteria always affect the whole + query (they are applied as a final filter), even if set + with other terms inside a parenthese.

+
+ +
+

Note

+ +

mime (or the equivalent + rclcat) is the only field with an + OR default. You do need to + use OR with ext terms for example.

+
+ +
+
+
+
+

3.6.1. Modifiers

+
+
+
+ +

Some characters are recognized as search modifiers + when found immediately after the closing double quote of + a phrase, as in "some + term"modifierchars. The actual "phrase" can be a + single term of course. Supported modifiers:

+ +
+
    +
  • +

    l can be used to + turn off stemming (mostly makes sense with + p because stemming is + off by default for phrases).

    +
  • + +
  • +

    s can be used to + turn off synonym expansion, if a synonyms file is + in place (only for Recoll 1.22 and later).

    +
  • + +
  • +

    o can be used to + specify a "slack" for phrase and proximity + searches: the number of additional terms that may + be found between the specified ones. If + o is followed by an + integer number, this is the slack, else the default + is 10.

    +
  • + +
  • +

    p can be used to + turn the default phrase search into a proximity one + (unordered). Example: "order + any in"p

    +
  • + +
  • +

    C will turn on case + sensitivity (if the index supports it).

    +
  • + +
  • +

    D will turn on + diacritics sensitivity (if the index supports + it).

    +
  • + +
  • +

    A weight can be specified for a query element by + specifying a decimal value at the start of the + modifiers. Example: "Important"2.5.

    +
  • +
+
+
+
+ +
+
+
+
+

3.7. Search case and + diacritics sensitivity

+
+
+
+ +

For Recoll versions + 1.18 and later, and when working + with a raw index (not the default), searches + can be sensitive to character case and diacritics. How this + happens is controlled by configuration variables and what + search data is entered.

+ +

The general default is that searches entered without + upper-case or accented characters are insensitive to case + and diacritics. An entry of resume will match any of Resume, RESUME, résumé, Résumé etc.

+ +

Two configuration variables can automate switching on + sensitivity (they were documented but actually did nothing + until Recoll 1.22):

+ +
+
+
autodiacsens
+ +
+

If this is set, search sensitivity to diacritics + will be turned on as soon as an accented character + exists in a search term. When the variable is set to + true, resume will start + a diacritics-unsensitive search, but résumé will be matched + exactly. The default value is false.

+
+ +
autocasesens
+ +
+

If this is set, search sensitivity to character + case will be turned on as soon as an upper-case + character exists in a search term except for the first one. + When the variable is set to true, us or Us will start a + diacritics-unsensitive search, but US will be matched exactly. The + default value is true (contrary to + autodiacsens).

+
+
+
+ +

As in the past, capitalizing the first letter of a word + will turn off its stem expansion and have no effect on + case-sensitivity.

+ +

You can also explicitely activate case and diacritics + sensitivity by using modifiers with the query language. + C will make the term + case-sensitive, and D will + make it diacritics-sensitive. Examples:

+
+        "us"C
+   
+
+ +

will search for the term us + exactly (Us will not be a + match).

+
+        "resume"D
+      
+
+ +

will search for the term resume exactly (résumé will not be a + match).

+ +

When either case or diacritics sensitivity is activated, + stem expansion is turned off. Having both does not make + much sense.

+
+ +
+
+
+
+

3.8. Anchored + searches and wildcards

+
+
+
+ +

Some special characters are interpreted by Recoll in search strings to expand or + specialize the search. Wildcards expand a root term in + controlled ways. Anchor characters can restrict a search to + succeed only if the match is found at or near the beginning + of the document or one of its fields.

+ +
+
+
+
+

3.8.1. More + about wildcards

+
+
+
+ +

All words entered in Recoll search fields will be + processed for wildcard expansion before the request is + finally executed.

+ +

The wildcard characters are:

+ +
+
    +
  • +

    * which matches 0 + or more characters.

    +
  • + +
  • +

    ? which matches a + single character.

    +
  • + +
  • +

    [] which allow + defining sets of characters to be matched (ex: + [abc] matches a single character which + may be 'a' or 'b' or 'c', [0-9] matches any number.

    +
  • +
+
+ +

You should be aware of a few things when using + wildcards.

+ +
+
    +
  • +

    Using a wildcard character at the beginning of a + word can make for a slow search because + Recoll will have + to scan the whole index term list to find the + matches. However, this is much less a problem for + field searches, and queries like author:*@domain.com + can sometimes be very useful.

    +
  • + +
  • +

    For Recoll + version 18 only, when working with a raw index + (preserving character case and diacritics), the + literal part of a wildcard expression will be + matched exactly for case and diacritics. This is + not true any more for versions 19 and later.

    +
  • + +
  • +

    Using a * at the + end of a word can produce more matches than you + would think, and strange search results. You can + use the term + explorer tool to check what completions exist + for a given term. You can also see exactly what + search was performed by clicking on the link at the + top of the result list. In general, for natural + language terms, stem expansion will produce better + results than an ending * (stem expansion is turned off + when any wildcard character appears in the + term).

    +
  • +
+
+ +
+
+
+
+

3.8.1.1. Wildcards + and path filtering

+
+
+
+ +

Due to the way that Recoll processes wildcards inside + dir path filtering + clauses, they will have a multiplicative effect on the + query size. A clause containg wildcards in several + paths elements, like, for example, dir:/home/me/*/*/docdir, + will almost certainly fail if your indexed tree is of + any realistic size.

+ +

Depending on the case, you may be able to work + around the issue by specifying the paths elements more + narrowly, with a constant prefix, or by using 2 + separate dir: clauses + instead of multiple wildcards, as in dir:/home/me dir:docdir. The latter + query is not equivalent to the initial one because it + does not specify a number of directory levels, but + that's the best we can do (and it may be actually more + useful in some cases).

+
+
+ +
+
+
+
+

3.8.2. Anchored + searches

+
+
+
+ +

Two characters are used to specify that a search hit + should occur at the beginning or at the end of the text. + ^ at the beginning of a term + or phrase constrains the search to happen at the start, + $ at the end force it to + happen at the end.

+ +

As this function is implemented as a phrase search it + is possible to specify a maximum distance at which the + hit should occur, either through the controls of the + advanced search panel, or using the query language, for + example, as in:

+
+"^someterm"o10
+
+ +

which would force someterm to be found within 10 terms of + the start of the text. This can be combined with a field + search as in somefield:"^someterm"o10 or somefield:someterm$.

+ +

This feature can also be used with an actual phrase + search, but in this case, the distance applies to the + whole phrase and anchor, so that, for example, + bla bla my unexpected term + at the beginning of the text would be a match for + "^my term"o5.

+ +

Anchored searches can be very useful for searches + inside somewhat structured documents like scientific + articles, in case explicit metadata has not been supplied + (a most frequent case), for example for looking for + matches inside the abstract or the list of authors (which + occur at the top of the document).

+
+
+ +
+
+
+
+

3.9. Desktop + integration

+
+
+
+ +

Being independant of the desktop type has its drawbacks: + Recoll desktop integration + is minimal. However there are a few tools available:

+ +
+ +
+ +

Here follow a few other things that may help.

+ +
+
+
+
+

3.9.1. Hotkeying + recoll

+
+
+
+ +

It is surprisingly convenient to be able to show or + hide the Recoll GUI with + a single keystroke. Recoll comes with a small Python + script, based on the libwnck window manager interface + library, which will allow you to do just this. The + detailed instructions are on this wiki page.

+
+ +
+
+
+
+

3.9.2. The KDE Kicker + Recoll applet

+
+
+
+ +

This is probably obsolete now. Anyway:

+ +

The Recoll source + tree contains the source code to the recoll_applet, a small application + derived from the find_applet. This can be used to add + a small Recoll launcher + to the KDE panel.

+ +

The applet is not automatically built with the main + Recoll programs, nor is + it included with the main source distribution (because + the KDE build boilerplate makes it relatively big). You + can download its source from the recoll.org download + page. Use the omnipotent configure;make;make + install incantation to build and + install.

+ +

You can then add the applet to the panel by + right-clicking the panel and choosing the Add applet entry.

+ +

The recoll_applet has + a small text window where you can type a Recoll query (in query language + form), and an icon which can be used to restrict the + search to certain types of files. It is quite primitive, + and launches a new recoll GUI instance every time (even + if it is already running). You may find it useful + anyway.

+
+
+
+ +
+
+
+
+

Chapter 4. Programming + interface

+
+
+
+ +

Recoll has an Application + Programming Interface, usable both for indexing and + searching, currently accessible from the Python language.

+ +

Another less radical way to extend the application is to + write input handlers for new types of documents.

+ +

The processing of metadata attributes for documents + (fields) is highly + configurable.

+ +
+
+
+
+

4.1. Writing a + document input handler

+
+
+
+ +
+

Terminology

+ +

The small programs or pieces of code which handle the + processing of the different document types for + Recoll used to be called + filters, which is still + reflected in the name of the directory which holds them + and many configuration variables. They were named this + way because one of their primary functions is to filter + out the formatting directives and keep the text content. + However these modules may have other behaviours, and the + term input handler is now + progressively substituted in the documentation. + filter is still used in many + places though.

+
+ +

Recoll input handlers + cooperate to translate from the multitude of input document + formats, simple ones as opendocument, acrobat), or compound ones such as + Zip or Email, into the final Recoll indexing input format, which is + plain text. Most input handlers are executable programs or + scripts. A few handlers are coded in C++ and live inside + recollindex. + This latter kind will not be described here.

+ +

There are currently (since version 1.13) two kinds of + external executable input handlers:

+ +
+
    +
  • +

    Simple exec handlers + run once and exit. They can be bare programs like + antiword, or + scripts using other programs. They are very simple to + write, because they just need to print the converted + document to the standard output. Their output can be + plain text or HTML. HTML is usually preferred because + it can store metadata fields and it allows preserving + some of the formatting for the GUI preview.

    +
  • + +
  • +

    Multiple execm + handlers can process multiple files (sparing the + process startup time which can be very significant), + or multiple documents per file (e.g.: for + zip or chm files). They communicate + with the indexer through a simple protocol, but are + nevertheless a bit more complicated than the older + kind. Most of new handlers are written in + Python, using a + common module to handle the protocol. There is an + exception, rclimg which is + written in Perl. The subdocuments output by these + handlers can be directly indexable (text or HTML), or + they can be other simple or compound documents that + will need to be processed by another handler.

    +
  • +
+
+ +

In both cases, handlers deal with regular file system + files, and can process either a single document, or a + linear list of documents in each file. Recoll is responsible for performing + up to date checks, deal with more complex embedding and + other upper level issues.

+ +

A simple handler returning a document in text/plain format, can transfer no + metadata to the indexer. Generic metadata, like document + size or modification date, will be gathered and stored by + the indexer.

+ +

Handlers that produce text/html format can return an arbitrary + amount of metadata inside HTML meta tags. These will be processed + according to the directives found in the fields configuration file.

+ +

The handlers that can handle multiple documents per file + return a single piece of data to identify each document + inside the file. This piece of data, called an ipath element will be sent back by + Recoll to extract the + document at query time, for previewing, or for creating a + temporary file to be opened by a viewer.

+ +

The following section describes the simple handlers, and + the next one gives a few explanations about the + execm ones. You could + conceivably write a simple handler with only the elements + in the manual. This will not be the case for the other + ones, for which you will have to look at the code.

+ +
+
+
+
+

4.1.1. Simple + input handlers

+
+
+
+ +

Recoll simple + handlers are usually shell-scripts, but this is in no way + necessary. Extracting the text from the native format is + the difficult part. Outputting the format expected by + Recoll is trivial. + Happily enough, most document formats have translators or + text extractors which can be called from the handler. In + some cases the output of the translating program is + completely appropriate, and no intermediate shell-script + is needed.

+ +

Input handlers are called with a single argument which + is the source file name. They should output the result to + stdout.

+ +

When writing a handler, you should decide if it will + output plain text or HTML. Plain text is simpler, but you + will not be able to add metadata or vary the output + character encoding (this will be defined in a + configuration file). Additionally, some formatting may be + easier to preserve when previewing HTML. Actually the + deciding factor is metadata: Recoll has a way to extract metadata + from the HTML header and use it for field + searches..

+ +

The RECOLL_FILTER_FORPREVIEW environment + variable (values yes, + no) tells the handler if the + operation is for indexing or previewing. Some handlers + use this to output a slightly different format, for + example stripping uninteresting repeated keywords (ie: + Subject: for email) when + indexing. This is not essential.

+ +

You should look at one of the simple handlers, for + example rclps for a starting + point.

+ +

Don't forget to make your handler executable before + testing !

+
+ +
+
+
+
+

4.1.2. "Multiple" + handlers

+
+
+
+ +

If you can program and want to write an execm handler, it should not be too + difficult to make sense of one of the existing modules. + There is a sample one with many comments, not actually + used by Recoll, which + would index a text file as one document per line. Look + for rcltxtlines.py in the + src/filters directory in + the Recoll BitBucket repository (the sample not in + the distributed release at the moment).

+ +

You can also have a look at the slightly more complex + rclzip + which uses Zip file paths as identifiers (ipath).

+ +

execm handlers sometimes + need to make a choice for the nature of the ipath elements that they use in + communication with the indexer. Here are a few + guidelines:

+ +
+
    +
  • +

    Use ASCII or UTF-8 (if the identifier is an + integer print it, for example, like printf %d would + do).

    +
  • + +
  • +

    If at all possible, the data should make some + kind of sense when printed to a log file to help + with debugging.

    +
  • + +
  • +

    Recoll uses a + colon (:) as a + separator to store a complex path internally (for + deeper embedding). Colons inside the ipath elements output by a handler + will be escaped, but would be a bad choice as a + handler-specific separator (mostly, again, for + debugging issues).

    +
  • +
+
+ +

In any case, the main goal is that it should be easy + for the handler to extract the target document, given the + file name and the ipath + element.

+ +

execm handlers will also + produce a document with a null ipath element. Depending on the type of + document, this may have some associated data (e.g. the + body of an email message), or none (typical for an + archive file). If it is empty, this document will be + useful anyway for some operations, as the parent of the + actual data documents.

+
+ +
+
+
+
+

4.1.3. Telling + Recoll about the + handler

+
+
+
+ +

There are two elements that link a file to the handler + which should process it: the association of file to MIME + type and the association of a MIME type with a + handler.

+ +

The association of files to MIME types is mostly based + on name suffixes. The types are defined inside the + mimemap file. Example:

+
+
+.doc = application/msword
+
+ +

If no suffix association is found for the file name, + Recoll will try to + execute a system command (typically file -i or xdg-mime) to determine + a MIME type.

+ +

The second element is the association of MIME types to + handlers in the mimeconf file. A sample will + probably be better than a long explanation:

+
+
+[index]
+application/msword = exec antiword -t -i 1 -m UTF-8;\
+     mimetype = text/plain ; charset=utf-8
+
+application/ogg = exec rclogg
+
+text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html
+
+application/x-chm = execm rclchm
+
+ +

The fragment specifies that:

+ +
+
    +
  • +

    application/msword + files are processed by executing the antiword program, + which outputs text/plain encoded in utf-8.

    +
  • + +
  • +

    application/ogg + files are processed by the rclogg script, + with default output type (text/html, with encoding specified + in the header, or utf-8 by default).

    +
  • + +
  • +

    text/rtf is + processed by unrtf, which + outputs text/html. The + iso-8859-1 encoding is + specified because it is not the utf-8 default, and not output by + unrtf + in the HTML header section.

    +
  • + +
  • +

    application/x-chm + is processed by a persistant handler. This is + determined by the execm keyword.

    +
  • +
+
+
+ +
+
+
+
+

4.1.4. Input + handler HTML output

+
+
+
+ +

The output HTML could be very minimal like the + following example:

+
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+  </head>
+  <body>
+   Some text content
+  </body>
+</html>
+          
+
+ +

You should take care to escape some characters inside + the text by transforming them into appropriate entities. + At the very minimum, "&" + should be transformed into "&amp;", "<" should be transformed into + "&lt;". This is not + always properly done by translating programs which output + HTML, and of course never by those which output plain + text.

+ +

When encapsulating plain text in an HTML body, the + display of a preview may be improved by enclosing the + text inside <pre> + tags.

+ +

The character set needs to be specified in the header. + It does not need to be UTF-8 (Recoll will take care of translating + it), but it must be accurate for good results.

+ +

Recoll will process + meta tags inside the header + as possible document fields candidates. Documents fields + can be processed by the indexer in different ways, for + searching or displaying inside query results. This is + described in a following + section.

+ +

By default, the indexer will process the standard + header fields if they are present: title, meta/description, and meta/keywords are both indexed and + stored for query-time display.

+ +

A predefined non-standard meta tag will also be processed by + Recoll without further + configuration: if a date tag + is present and has the right format, it will be used as + the document date (for display and sorting), in + preference to the file modification date. The date format + should be as follows:

+
+<meta name="date" content="YYYY-mm-dd HH:MM:SS">
+or
+<meta name="date" content="YYYY-mm-ddTHH:MM:SS">
+          
+
+ +

Example:

+
+<meta name="date" content="2013-02-24 17:50:00">
+          
+
+ +

Input handlers also have the possibility to "invent" + field names. This should also be output as meta tags:

+
+<meta name="somefield" content="Some textual data" />
+
+ +

You can embed HTML markup inside the content of custom + fields, for improving the display inside result lists. In + this case, add a (wildly non-standard) markup attribute to tell Recoll that the value is HTML and + should not be escaped for display.

+
+<meta name="somefield" markup="html" content="Some <i>textual</i> data" />
+
+ +

As written above, the processing of fields is + described in a further + section.

+
+ +
+
+
+
+

4.1.5. Page + numbers

+
+
+
+ +

The indexer will interpret ^L characters in the handler output as + indicating page breaks, and will record them. At query + time, this allows starting a viewer on the right page for + a hit or a snippet. Currently, only the PDF, Postscript + and DVI handlers generate page breaks.

+
+
+ +
+
+
+
+

4.2. Field data + processing

+
+
+
+ +

Fields are named pieces of + information in or about documents, like title, author, abstract.

+ +

The field values for documents can appear in several + ways during indexing: either output by input handlers as + meta fields in the HTML header + section, or extracted from file extended attributes, or + added as attributes of the Doc + object when using the API, or again synthetized internally + by Recoll.

+ +

The Recoll query + language allows searching for text in a specific field.

+ +

Recoll defines a number + of default fields. Additional ones can be output by + handlers, and described in the fields configuration file.

+ +

Fields can be:

+ +
+
    +
  • +

    indexed, meaning that + their terms are separately stored in inverted lists + (with a specific prefix), and that a field-specific + search is possible.

    +
  • + +
  • +

    stored, meaning that + their value is recorded in the index data record for + the document, and can be returned and displayed with + search results.

    +
  • +
+
+ +

A field can be either or both indexed and stored. This + and other aspects of fields handling is defined inside the + fields configuration + file.

+ +

The sequence of events for field processing is as + follows:

+ +
+
    +
  • +

    During indexing, recollindex scans + all meta fields in HTML + documents (most document types are transformed into + HTML at some point). It compares the name for each + element to the configuration defining what should be + done with fields (the fields file)

    +
  • + +
  • +

    If the name for the meta element matches one for a field + that should be indexed, the contents are processed + and the terms are entered into the index with the + prefix defined in the fields file.

    +
  • + +
  • +

    If the name for the meta element matches one for a field + that should be stored, the content of the element is + stored with the document data record, from which it + can be extracted and displayed at query time.

    +
  • + +
  • +

    At query time, if a field search is performed, the + index prefix is computed and the match is only + performed against appropriately prefixed terms in the + index.

    +
  • + +
  • +

    At query time, the field can be displayed inside + the result list by using the appropriate directive in + the definition of the result list + paragraph format. All fields are displayed on the + fields screen of the preview window (which you can + reach through the right-click menu). This is + independant of the fact that the search which + produced the results used the field or not.

    +
  • +
+
+ +

You can find more information in the section about the + fields file, or in + comments inside the file.

+ +

You can also have a look at the example on the Wiki, detailing how one + could add a page + count field to pdf documents for displaying + inside result lists.

+
+ +
+
+
+
+

4.3. Python API

+
+
+
+ +
+
+
+
+

4.3.1. Introduction

+
+
+
+ +

Recoll versions after + 1.11 define a Python programming interface, both for + searching and creating/updating an index.

+ +

The search interface is used in the Recoll Ubuntu Unity Lens and the + Recoll Web UI. It can + run queries on any Recoll configuration.

+ +

The index update section of the API may be used to + create and update Recoll + indexes on specific configurations (separate from the + ones created by recollindex). The + resulting databases can be queried alone, or in + conjunction with regular ones, through the GUI or any of + the query interfaces.

+ +

The search API is modeled along the Python database + API specification. There were two major changes along + Recoll versions:

+ +
+
    +
  • +

    The basis for the Recoll API changed from Python + database API version 1.0 (Recoll versions up to 1.18.1), + to version 2.0 (Recoll 1.18.2 and later).

    +
  • + +
  • +

    The recoll module + became a package (with an internal recoll module) as of Recoll version 1.19, in order + to add more functions. For existing code, this only + changes the way the interface must be imported.

    +
  • +
+
+ +

We will describe the new API and package structure + here. A paragraph at the end of this section will explain + a few differences and ways to write code compatible with + both versions.

+ +

The Python interface can be found in the source + package, under python/recoll.

+ +

The python/recoll/ + directory contains the usual setup.py. After configuring the main + Recoll code, you can use + the script to build and install the Python module:

+
+            cd recoll-xxx/python/recoll
+            python setup.py build
+            python setup.py install
+          
+
+ +

As of Recoll 1.19, + the module can be compiled for Python3.

+ +

The normal Recoll + installer installs the Python2 API along with the main + code. The Python3 version must be explicitely built and + installed.

+ +

When installing from a repository, and depending on + the distribution, the Python API can sometimes be found + in a separate package.

+ +

As an introduction, the following small sample will + run a query and list the title and url for each of the + results. It would work with Recoll 1.19 and later. The + python/samples source + directory contains several examples of Python programming + with Recoll, exercising + the extension more completely, and especially its data + extraction features.

+
+#!/usr/bin/env python
+
+from recoll import recoll
+
+db = recoll.connect()
+query = db.query()
+nres = query.execute("some query")
+results = query.fetchmany(20)
+for doc in results:
+    print(doc.url, doc.title)
+
+
+ +
+
+
+
+

4.3.2. Interface + elements

+
+
+
+ +

A few elements in the interface are specific and and + need an explanation.

+ +
+
+
ipath
+ +
+

This data value (set as a field in the Doc + object) is stored, along with the URL, but not + indexed by Recoll. + Its contents are not interpreted by the index + layer, and its use is up to the application. For + example, the Recoll file system indexer + uses the ipath to + store the part of the document access path internal + to (possibly imbricated) container documents. + ipath in this case is + a vector of access elements (e.g, the first part + could be a path inside a zip file to an archive + member which happens to be an mbox file, the second + element would be the message sequential number + inside the mbox etc.). url and ipath are returned in every search + result and define the access to the original + document. ipath is + empty for top-level document/files (e.g. a PDF + document which is a filesystem file). The + Recoll GUI knows + about the structure of the ipath values used by the + filesystem indexer, and uses it for such functions + as opening the parent of a given document.

+
+ +
udi
+ +
+

An udi (unique + document identifier) identifies a document. Because + of limitations inside the index engine, it is + restricted in length (to 200 bytes), which is why a + regular URI cannot be used. The structure and + contents of the udi is + defined by the application and opaque to the index + engine. For example, the internal file system + indexer uses the complete document path (file path + + internal path), truncated to length, the + suppressed part being replaced by a hash value. The + udi is not explicit in + the query interface (it is used "under the hood" by + the rclextract + module), but it is an explicit element of the + update interface.

+
+ +
parent_udi
+ +
+

If this attribute is set on a document when + entering it in the index, it designates its + physical container document. In a multilevel + hierarchy, this may not be the immediate parent. + parent_udi is + optional, but its use by an indexer may simplify + index maintenance, as Recoll will automatically + delete all children defined by parent_udi == udi when the + document designated by udi is destroyed. e.g. if a + Zip archive contains + entries which are themselves containers, like + mbox files, all the + subdocuments inside the Zip file (mbox, messages, message + attachments, etc.) would have the same parent_udi, matching the + udi for the + Zip file, and all + would be destroyed when the Zip file (identified by its + udi) is removed from + the index. The standard filesystem indexer uses + parent_udi.

+
+ +
Stored and indexed + fields
+ +
+

The fields file + inside the Recoll + configuration defines which document fields are + either "indexed" (searchable), "stored" + (retrievable with search results), or both.

+
+
+
+
+ +
+
+
+
+

4.3.3. Python + search interface

+
+
+
+ +
+
+
+
+

4.3.3.1. Recoll + package

+
+
+
+ +

The recoll package + contains two modules:

+ +
+
    +
  • +

    The recoll module + contains functions and classes used to query (or + update) the index. This section will only + describe the query part, see further for the + update part.

    +
  • + +
  • +

    The rclextract + module contains functions and classes used to + access document data.

    +
  • +
+
+
+ +
+
+
+
+

4.3.3.2. The + recoll module

+
+
+
+ +
+
+
+
+
Functions
+
+
+
+ +
+
+
connect(confdir=None, + extra_dbs=None, writable = False)
+ +
+

The connect() + function connects to one or several + Recoll + index(es) and returns a Db object.

+ +
+
    +
  • +

    confdir + may specify a configuration directory. + The usual defaults apply.

    +
  • + +
  • +

    extra_dbs + is a list of additional indexes (Xapian + directories).

    +
  • + +
  • +

    writable + decides if we can index new data through + this connection.

    +
  • +
+
+ +

This call initializes the recoll module, and + it should always be performed before any other + call or object creation.

+
+
+
+
+ +
+
+
+
+
Classes
+
+
+
+ +
+
+
+
+
The + Db class
+
+
+
+ +

A Db object is created by a connect() call and holds a + connection to a Recoll index.

+ +
+
+
Db.close()
+ +
+

Closes the connection. You can't do + anything with the Db object after this.

+
+ +
Db.query(), + Db.cursor()
+ +
+

These aliases return a blank Query object for this + index.

+
+ +
Db.setAbstractParams(maxchars, + contextwords)
+ +
+

Set the parameters used to build snippets + (sets of keywords in context text fragments). + maxchars defines + the maximum total size of the abstract. + contextwords + defines how many terms are shown around the + keyword.

+
+ +
Db.termMatch(match_type, + expr, field='', maxlen=-1, casesens=False, + diacsens=False, lang='english')
+ +
+

Expand an expression against the index + term list. Performs the basic function from + the GUI term explorer tool. match_type can be either of + wildcard, + regexp or + stem. Returns a + list of terms expanded from the input + expression.

+
+
+
+
+ +
+
+
+
+
The + Query class
+
+
+
+ +

A Query object + (equivalent to a cursor in the Python DB API) is + created by a Db.query() call. It is used to + execute index searches.

+ +
+
+
Query.sortby(fieldname, + ascending=True)
+ +
+

Sort results by fieldname, in + ascending or descending order. Must be called + before executing the search.

+
+ +
Query.execute(query_string, stemming=1, + stemlang="english")
+ +
+

Starts a search for query_string, + a Recoll + search language string.

+
+ +
Query.executesd(SearchData)
+ +
+

Starts a search for the query defined by + the SearchData object.

+
+ +
Query.fetchmany(size=query.arraysize)
+ +
+

Fetches the next Doc objects in the current + search results, and returns them as an array + of the required size, which is by default the + value of the arraysize data member.

+
+ +
Query.fetchone()
+ +
+

Fetches the next Doc object from the current + search results.

+
+ +
Query.close()
+ +
+

Closes the query. The object is unusable + after the call.

+
+ +
Query.scroll(value, + mode='relative')
+ +
+

Adjusts the position in the current result + set. mode can be + relative or + absolute.

+
+ +
Query.getgroups()
+ +
+

Retrieves the expanded query terms as a + list of pairs. Meaningful only after + executexx In each pair, the first entry is a + list of user terms (of size one for simple + terms, or more for group and phrase clauses), + the second a list of query terms as derived + from the user terms and used in the Xapian + Query.

+
+ +
Query.getxquery()
+ +
+

Return the Xapian query description as a + Unicode string. Meaningful only after + executexx.

+
+ +
Query.highlight(text, + ishtml = 0, methods = object)
+ +
+

Will insert <span "class=rclmatch">, + </span> tags around the match areas in + the input text and return the modified text. + ishtml can be + set to indicate that the input text is HTML + and that HTML special characters should not + be escaped. methods if set should be an + object with methods startMatch(i) and + endMatch() which will be called for each + match and should return a begin and end + tag

+
+ +
Query.makedocabstract(doc, methods = + object))
+ +
+

Create a snippets abstract for + doc (a + Doc object) by + selecting text around the match terms. If + methods is set, will also perform + highlighting. See the highlight method.

+
+ +
Query.__iter__() and + Query.next()
+ +
+

So that things like for doc in query: will + work.

+
+
+
+ +
+
+
Query.arraysize
+ +
+

Default number of records processed by + fetchmany (r/w).

+
+ +
Query.rowcount
+ +
+

Number of records returned by the last + execute.

+
+ +
Query.rownumber
+ +
+

Next index to be fetched from results. + Normally increments after each fetchone() + call, but can be set/reset before the call to + effect seeking (equivalent to using + scroll()). + Starts at 0.

+
+
+
+
+ +
+
+
+
+
+ The Doc class
+
+
+
+ +

A Doc object + contains index data for a given document. The data + is extracted from the index when searching, or set + by the indexer program when updating. The Doc + object has many attributes to be read or set by its + user. It matches exactly the Rcl::Doc C++ object. + Some of the attributes are predefined, but, + especially when indexing, others can be set, the + name of which will be processed as field names by + the indexing configuration. Inputs can be specified + as Unicode or strings. Outputs are Unicode objects. + All dates are specified as Unix timestamps, printed + as strings. Please refer to the rcldb/rcldoc.h C++ file for a + description of the predefined attributes.

+ +

At query time, only the fields that are defined + as stored either by + default or in the fields configuration file will be + meaningful in the Doc + object. Especially this will not be the case for + the document text. See the rclextract module for accessing + document contents.

+ +
+
+
get(key), [] + operator
+ +
+

Retrieve the named doc attribute. You can + also use getattr(doc, + key) or doc.key.

+
+ +
doc.key = + value
+ +
+

Set the the named doc attribute. You can + also use setattr(doc, + key, value).

+
+ +
getbinurl()
+ +
+

Retrieve the URL in byte array format (no + transcoding), for use as parameter to a + system call.

+
+ +
setbinurl(url)
+ +
+

Set the URL in byte array format (no + transcoding).

+
+ +
items()
+ +
+

Return a dictionary of doc object + keys/values

+
+ +
keys()
+ +
+

list of doc object keys (attribute + names).

+
+
+
+
+ +
+
+
+
+
+ The SearchData class
+
+
+
+ +

A SearchData object + allows building a query by combining clauses, for + execution by Query.executesd(). It can be used + in replacement of the query language approach. The + interface is going to change a little, so no + detailed doc for now...

+ +
+
+
addclause(type='and'|'or'|'excl'|'phrase'|'near'|'sub', + qstring=string, slack=0, field='', stemming=1, + subSearch=SearchData)
+
+
+
+
+
+ +
+
+
+
+

4.3.3.3. The + rclextract module

+
+
+
+ +

Index queries do not provide document content (only + a partial and unprecise reconstruction is performed to + show the snippets text). In order to access the actual + document data, the data extraction part of the indexing + process must be performed (subdocument access and + format translation). This is not trivial in general. + The rclextract module + currently provides a single class which can be used to + access the data content for result documents.

+ +
+
+
+
+
Classes
+
+
+
+ +
+
+
+
+
+ The Extractor class
+
+
+
+ +
+
+
Extractor(doc)
+ +
+

An Extractor + object is built from a Doc object, output from a + query.

+
+ +
Extractor.textextract(ipath)
+ +
+

Extract document defined by ipath and + return a Doc + object. The doc.text field has the document + text converted to either text/plain or + text/html according to doc.mimetype. The + typical use would be as follows:

+
+qdoc = query.fetchone()
+extractor = recoll.Extractor(qdoc)
+doc = extractor.textextract(qdoc.ipath)
+# use doc.text, e.g. for previewing
+
+
+ +
Extractor.idoctofile(ipath, targetmtype, + outfile='')
+ +
+

Extracts document into an output file, + which can be given explicitly or will be + created as a temporary file to be deleted by + the caller. Typical use:

+
+qdoc = query.fetchone()
+extractor = recoll.Extractor(qdoc)
+filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype)
+
+
+
+
+
+
+
+ +
+
+
+
+

4.3.3.4. Search + API usage example

+
+
+
+ +

The following sample would query the index with a + user language string. See the python/samples directory inside the + Recoll source for + other examples. The recollgui subdirectory has a very + embryonic GUI which demonstrates the highlighting and + data extraction functions.

+
+#!/usr/bin/env python
+
+from recoll import recoll
+
+db = recoll.connect()
+db.setAbstractParams(maxchars=80, contextwords=4)
+
+query = db.query()
+nres = query.execute("some user question")
+print "Result count: ", nres
+if nres > 5:
+    nres = 5
+for i in range(nres):
+    doc = query.fetchone()
+    print "Result #%d" % (query.rownumber,)
+    for k in ("title", "size"):
+        print k, ":", getattr(doc, k).encode('utf-8')
+    abs = db.makeDocAbstract(doc, query).encode('utf-8')
+    print abs
+    print
+
+
+
+
+
+ +
+
+
+
+

4.3.4. Creating + Python external indexers

+
+
+
+ +

The update API can be used to create an index from + data which is not accessible to the regular Recoll indexer, or structured to + present difficulties to the Recoll input handlers.

+ +

An indexer created using this API will be have + equivalent work to do as the the Recoll file system + indexer: look for modified documents, extract their text, + call the API for indexing it, take care of purging the + index out of data from documents which do not exist in + the document store any more.

+ +

The data for such an external indexer should be stored + in an index separate from any used by the Recoll internal file system indexer. + The reason is that the main document indexer purge pass + (removal of deleted documents) would also remove all the + documents belonging to the external indexer, as they were + not seen during the filesystem walk. The main indexer + documents would also probably be a problem for the + external indexer own purge operation.

+ +

While there would be ways to enable multiple foreign + indexers to cooperate on a single index, it is just + simpler to use separate ones, and use the multiple index + access capabilities of the query interface, if + needed.

+ +

There are two parts in the update interface:

+ +
+
    +
  • +

    Methods inside the recoll module allow inserting + data into the index, to make it accessible by the + normal query interface.

    +
  • + +
  • +

    An interface based on scripts execution is + defined to allow either the GUI or the rclextract module to access + original document data for previewing or + editing.

    +
  • +
+
+ +
+
+
+
+

4.3.4.1. Python + update interface

+
+
+
+ +

The update methods are part of the recoll module described above. The + connect() method is used with a writable=true parameter to obtain a + writable Db object. The + following Db object + methods are then available.

+ +
+
+
addOrUpdate(udi, doc, + parent_udi=None)
+ +
+

Add or update index data for a given document + The udi + string must define a unique id for the document. + It is an opaque interface element and not + interpreted inside Recoll. doc is a Doc object, + created from the data to be indexed (the main + text should be in doc.text). If parent_udi + is set, this is a unique identifier for the + top-level container (e.g. for the filesystem + indexer, this would be the one which is an actual + file).

+
+ +
delete(udi)
+ +
+

Purge index from all data for udi, and all documents (if any) + which have a matrching parent_udi.

+
+ +
needUpdate(udi, + sig)
+ +
+

Test if the index needs to be updated for the + document identified by udi. If this call is to be used, + the doc.sig field + should contain a signature value when calling + addOrUpdate(). The + needUpdate() call + then compares its parameter value with the stored + sig for udi. sig is an opaque value, compared + as a string.

+ +

The filesystem indexer uses a concatenation of + the decimal string values for file size and + update time, but a hash of the contents could + also be used.

+ +

As a side effect, if the return value is false + (the index is up to date), the call will set the + existence flag for the document (and any + subdocument defined by its parent_udi), so that a later + purge() call will + preserve them).

+ +

The use of needUpdate() and purge() is optional, and the + indexer may use another method for checking the + need to reindex or to delete stale entries.

+
+ +
purge()
+ +
+

Delete all documents that were not touched + during the just finished indexing pass (since + open-for-write). These are the documents for the + needUpdate() call was not performed, indicating + that they no longer exist in the primary storage + system.

+
+
+
+
+ +
+
+
+
+

4.3.4.2. Query + data access for external indexers (1.23)

+
+
+
+ +

Recoll has internal + methods to access document data for its internal + (filesystem) indexer. An external indexer needs to + provide data access methods if it needs integration + with the GUI (e.g. preview function), or support for + the rclextract + module.

+ +

The index data and the access method are linked by + the rclbes (recoll backend + storage) Doc field. You + should set this to a short string value identifying + your indexer (e.g. the filesystem indexer uses either + "FS" or an empty value, the Web history indexer uses + "BGL").

+ +

The link is actually performed inside a backends configuration file (stored + in the configuration directory). This defines commands + to execute to access data from the specified indexer. + Example, for the mbox indexing sample found in the + Recoll source (which sets rclbes="MBOX"):

+
+[MBOX]
+fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch
+makesig = path/to/recoll/src/python/samples/rclmbox.py makesig
+        
+
+ +

fetch and makesig define two commands to execute + to respectively retrieve the document text and compute + the document signature (the example implementation uses + the same script with different first parameters to + perform both operations).

+ +

The scripts are called with three additional + arguments: udi, + url, ipath, stored with the document when + it was indexed, and may use any or all to perform the + requested operation. The caller expects the result data + on stdout.

+
+ +
+
+
+
+

4.3.4.3. External + indexer samples

+
+
+
+ +

The Recoll source tree has two samples of external + indexers in the src/python/samples directory. The + more interesting one is rclmbox.py which indexes a directory + containing mbox folder + files. It exercises most features in the update + interface, and has a data access interface.

+ +

See the comments inside the file for more + information.

+
+
+ +
+
+
+
+

4.3.5. Package + compatibility with the previous version

+
+
+
+ +

The following code fragments can be used to ensure + that code can run with both the old and the new API (as + long as it does not use the new abilities of the new API + of course).

+ +

Adapting to the new package structure:

+
+
+try:
+    from recoll import recoll
+    from recoll import rclextract
+    hasextract = True
+except:
+    import recoll
+    hasextract = False
+
+      
+
+ +

Adapting to the change of nature of the next Query + member. The same test can be used to choose to use the + scroll() method (new) or set + the next value (old).

+
+
+       rownum = query.next if type(query.next) == int else \
+                 query.rownumber
+
+      
+
+
+
+
+ +
+
+
+
+

Chapter 5. Installation and + configuration

+
+
+
+ +
+
+
+
+

5.1. Installing a + binary copy

+
+
+
+ +

Recoll binary copies + are always distributed as regular packages for your system. + They can be obtained either through the system's normal + software distribution framework (e.g. Debian/Ubuntu apt, FreeBSD ports, etc.), or from some + type of "backports" repository providing versions newer + than the standard ones, or found on the Recoll WEB site in some cases. The + most up-to-date information about Recoll packages can + usually be found on the Recoll WEB site + downloads page

+ +

There used to exist another form of binary install, as + pre-compiled source trees, but these are just less + convenient than the packages and don't exist any more.

+ +

The package management tools will usually automatically + deal with hard dependancies for packages obtained from a + proper package repository. You will have to deal with them + by hand for downloaded packages (for example, when + dpkg + complains about missing dependancies).

+ +

In all cases, you will have to check or install + supporting applications + for the file types that you want to index beyond those that + are natively processed by Recoll (text, HTML, email files, and a + few others).

+ +

You should also maybe have a look at the configuration + section (but this may not be necessary for a quick test + with default parameters). Most parameters can be more + conveniently set from the GUI interface.

+
+ +
+
+
+
+

5.2. Supporting + packages

+
+
+
+ +
+

Note

+ +

The Windows + installation of Recoll + is self-contained, and only needs Python 2.7 to be + externally installed. Windows users can skip this + section.

+
+ +

Recoll uses external + applications to index some file types. You need to install + them for the file types that you wish to have indexed + (these are run-time optional dependencies. None is needed + for building or running Recoll except for indexing their + specific file type).

+ +

After an indexing pass, the commands that were found + missing can be displayed from the recoll File menu. The list is stored in the + missing text file inside the + configuration directory.

+ +

A list of common file types which need external commands + follows. Many of the handlers need the iconv command, which is + not always listed as a dependancy.

+ +

Please note that, due to the relatively dynamic nature + of this information, the most up to date version is now + kept on http://www.recoll.org/features.html along with + links to the home pages or best source/patches pages, and + misc tips. The list below is not updated often and may be + quite stale.

+ +

For many Linux distributions, most of the commands + listed can be installed from the package repositories. + However, the packages are sometimes outdated, or not the + best version for Recoll, + so you should take a look at http://www.recoll.org/features.html if a file + type is important to you.

+ +

As of Recoll release + 1.14, a number of XML-based formats that were handled by ad + hoc handler code now use the xsltproc command, which + usually comes with libxslt. These are: abiword, fb2 + (ebooks), kword, openoffice, svg.

+ +

Now for the list:

+ +
+
    +
  • +

    Openoffice files need unzip and + xsltproc.

    +
  • + +
  • +

    PDF files need pdftotext which is + part of Poppler + (usually comes with the poppler-utils package). Avoid the + original one from Xpdf.

    +
  • + +
  • +

    Postscript files need pstotext. The + original version has an issue with shell character in + file names, which is corrected in recent packages. + See http://www.recoll.org/features.html + for more detail.

    +
  • + +
  • +

    MS Word needs antiword. It is + also useful to have wvWare installed as + it may be be used as a fallback for some files which + antiword does not + handle.

    +
  • + +
  • +

    MS Excel and PowerPoint are processed by internal + Python + handlers.

    +
  • + +
  • +

    MS Open XML (docx) needs xsltproc.

    +
  • + +
  • +

    Wordperfect files need wpd2html from the + libwpd (or + libwpd-tools on + Ubuntu) package.

    +
  • + +
  • +

    RTF files need unrtf, which, in + its older versions, has much trouble with non-western + character sets. Many Linux distributions carry + outdated unrtf versions. + Check http://www.recoll.org/features.html + for details.

    +
  • + +
  • +

    TeX files need untex or + detex. + Check http://www.recoll.org/features.html + for sources if it's not packaged for your + distribution.

    +
  • + +
  • +

    dvi files need dvips.

    +
  • + +
  • +

    djvu files need djvutxt and + djvused + from the DjVuLibre + package.

    +
  • + +
  • +

    Audio files: Recoll releases 1.14 and later + use a single Python + handler based on mutagen for all audio file + types.

    +
  • + +
  • +

    Pictures: Recoll + uses the Exiftool + Perl package to + extract tag information. Most image file formats are + supported. Note that there may not be much interest + in indexing the technical tags (image size, aperture, + etc.). This is only of interest if you store personal + tags or textual descriptions inside the image + files.

    +
  • + +
  • +

    chm: files in Microsoft help format need Python + and the pychm module + (which needs chmlib).

    +
  • + +
  • +

    ICS: up to Recoll + 1.13, iCalendar files need Python and the icalendar module. icalendar is not needed for + newer versions, which use internal code.

    +
  • + +
  • +

    Zip archives need Python (and the standard zipfile + module).

    +
  • + +
  • +

    Rar archives need Python, the rarfile Python module and the + unrar + utility.

    +
  • + +
  • +

    Midi karaoke files need Python and the Midi + module

    +
  • + +
  • +

    Konqueror webarchive format with Python (uses the + Tarfile module).

    +
  • + +
  • +

    Mimehtml web archive format (support based on the + email handler, which introduces some mild weirdness, + but still usable).

    +
  • +
+
+ +

Text, HTML, email folders, and Scribus files are + processed internally. Lyx + is used to index Lyx files. Many handlers need iconv and the standard + sed and + awk.

+
+ +
+
+
+
+

5.3. Building from + source

+
+
+
+ +
+
+
+
+

5.3.1. Prerequisites

+
+
+
+ +

If you can install any or all of the following through + the package manager for your system, all the better. + Especially Qt is a very + big piece of software, but you will most probably be able + to find a binary package.

+ +

You may have to compile Xapian but this is easy.

+ +

The shopping list:

+ +
+
    +
  • +

    The autoconf, + automake and + libtool triad. Only + autoconf is needed up + to Recoll + 1.21.

    +
  • + +
  • +

    C++ compiler. Up to Recoll version 1.13.04, its + absence can manifest itself by strange messages + about a missing iconv_open.

    +
  • + +
  • +

    bison command + (for Recoll 1.21 + and later).

    +
  • + +
  • +

    xsltproc command. + For building the documentation (for Recoll 1.21 and later). This + sometimes comes with the libxslt package. And also the + Docbook XML and style sheet files.

    +
  • + +
  • +

    Development files for Xapian core.

    + +
    +

    Important

    + +

    If you are building Xapian for an older CPU + (before Pentium 4 or Athlon 64), you need to add + the --disable-sse + flag to the configure command. Else all Xapian + application will crash with an illegal instruction error.

    +
    +
  • + +
  • +

    Development files for Qt 4 . + Recoll has not + been tested with Qt + 5 yet. Recoll 1.15.9 was the last + version to support Qt + 3. If you do not want to install or build + the Qt Webkit + module, Recoll has + a configuration option to disable its use (see + further).

    +
  • + +
  • +

    Development files for X11 and zlib.

    +
  • + +
  • +

    Development files for Python (or use --disable-python-module).

    +
  • + +
  • +

    You may also need libiconv. On Linux systems, the iconv + interface is part of libc and you should not need + to do anything special.

    +
  • +
+
+ +

Check the Recoll download + page for up to date version information.

+
+ +
+
+
+
+

5.3.2. Building

+
+
+
+ +

Recoll has been built + on Linux, FreeBSD, Mac OS X, and Solaris, most versions + after 2005 should be ok, maybe some older ones too + (Solaris 8 is ok). If you build on another system, and + need to modify things, I would very much + welcome patches.

+ +

Configure options: 

+ +
+
    +
  • +

    --without-aspell + will disable the code for phonetic matching of + search terms.

    +
  • + +
  • +

    --with-fam or + --with-inotify will + enable the code for real time indexing. Inotify + support is enabled by default on recent Linux + systems.

    +
  • + +
  • +

    --with-qzeitgeist + will enable sending Zeitgeist events about the + visited search results, and needs the qzeitgeist package.

    +
  • + +
  • +

    --disable-webkit is + available from version 1.17 to implement the result + list with a Qt + QTextBrowser instead of a WebKit widget if you do + not or can't depend on the latter.

    +
  • + +
  • +

    --disable-idxthreads + is available from version 1.19 to suppress + multithreading inside the indexing process. You can + also use the run-time configuration to restrict + recollindex to + using a single thread, but the compile-time option + may disable a few more unused locks. This only + applies to the use of multithreading for the core + index processing (data input). The Recoll monitor mode always + uses at least two threads of execution.

    +
  • + +
  • +

    --disable-python-module will avoid + building the Python module.

    +
  • + +
  • +

    --disable-xattr will + prevent fetching data from file extended + attributes. Beyond a few standard attributes, + fetching extended attributes data can only be + useful is some application stores data in there, + and also needs some simple configuration (see + comments in the fields configuration file).

    +
  • + +
  • +

    --enable-camelcase + will enable splitting camelCase words. + This is not enabled by default as it has the + unfortunate side-effect of making some phrase + searches quite confusing: ie, "MySQL manual" would be matched by + "MySQL manual" and + "my sql manual" but + not "mysql manual" + (only inside phrase searches).

    +
  • + +
  • +

    --with-file-command + Specify the version of the 'file' command to use + (ie: --with-file-command=/usr/local/bin/file). Can + be useful to enable the gnu version on systems + where the native one is bad.

    +
  • + +
  • +

    --disable-qtgui + Disable the Qt interface. Will allow building the + indexer and the command line search program in + absence of a Qt environment.

    +
  • + +
  • +

    --disable-x11mon + Disable X11 + connection monitoring inside recollindex. Together + with --disable-qtgui, this allows building recoll + without Qt and + X11.

    +
  • + +
  • +

    --disable-userdoc + will avoid building the user manual. This avoids + having to install the Docbook XML/XSL files and the + TeX toolchain used for translating the manual to + PDF.

    +
  • + +
  • +

    --disable-pic + (Recoll versions + up to 1.21 only) will compile Recoll with position-dependant + code. This is incompatible with building the KIO or + the Python or + PHP extensions, + but might yield very marginally faster code.

    +
  • + +
  • +

    Of course the usual autoconf configure + options, like --prefix + apply.

    +
  • +
+
+ +

Normal procedure (for source extracted from a tar + distribution):

+
+        cd recoll-xxx
+        ./configure
+        make
+        (practices usual hardship-repelling invocations)
+      
+
+ +

When building from source cloned from the BitBucket + repository, you also need to install autoconf, automake, and libtool and you must execute + sh autogen.sh in the top + source directory before running configure.

+ +
+
+
+
+

5.3.2.1. Building + on Solaris

+
+
+
+ +

We did not test building the GUI on Solaris for + recent versions. You will need at least Qt 4.4. There + are some hints on an old web site page, they may still be + valid.

+ +

Someone did test the 1.19 indexer and Python module + build, they do work, with a few minor glitches. Be sure + to use GNU make and install.

+
+
+ +
+
+
+
+

5.3.3. Installation

+
+
+
+ +

Either type make + install or execute recollinstall prefix, + in the root of the source tree. This will copy the + commands to prefix/bin and the + sample configuration files, scripts and other shared data + to prefix/share/recoll.

+ +

If the installation prefix given to recollinstall is + different from either the system default or the value + which was specified when executing configure (as in + configure --prefix + /some/path), you will have to set the + RECOLL_DATADIR environment + variable to indicate where the shared data is to be found + (ie for (ba)sh: export + RECOLL_DATADIR=/some/path/share/recoll).

+ +

You can then proceed to configuration.

+
+
+ +
+
+
+
+

5.4. Configuration + overview

+
+
+
+ +

Most of the parameters specific to the recoll GUI are set + through the Preferences menu + and stored in the standard Qt place ($HOME/.config/Recoll.org/recoll.conf). + You probably do not want to edit this by hand.

+ +

Recoll indexing options + are set inside text configuration files located in a + configuration directory. There can be several such + directories, each of which defines the parameters for one + index.

+ +

The configuration files can be edited by hand or through + the Index configuration + dialog (Preferences menu). + The GUI tool will try to respect your formatting and + comments as much as possible, so it is quite possible to + use both approaches on the same configuration.

+ +

The most accurate documentation for the configuration + parameters is given by comments inside the default files, + and we will just give a general overview here.

+ +

For each index, there are at least two sets of + configuration files. System-wide configuration files are + kept in a directory named like /usr/share/recoll/examples, and define + default values, shared by all indexes. For each index, a + parallel set of files defines the customized + parameters.

+ +

The default location of the customized configuration is + the .recoll directory in your + home. Most people will only use this directory.

+ +

This location can be changed, or others can be added + with the RECOLL_CONFDIR + environment variable or the -c + option parameter to recoll and recollindex.

+ +

In addition (as of Recoll version 1.19.7), it is possible + to specify two additional configuration directories which + will be stacked before and after the user configuration + directory. These are defined by the RECOLL_CONFTOP and RECOLL_CONFMID environment variables. Values + from configuration files inside the top directory will + override user ones, values from configuration files inside + the middle directory will override system ones and be + overriden by user ones. These two variables may be of use + to applications which augment Recoll functionality, and need to add + configuration data without disturbing the user's files. + Please note that the two, currently single, values will + probably be interpreted as colon-separated lists in the + future: do not use colon characters inside the directory + paths.

+ +

If the .recoll directory + does not exist when recoll or recollindex are started, + it will be created with a set of empty configuration files. + recoll will + give you a chance to edit the configuration file before + starting indexing. recollindex will proceed + immediately. To avoid mistakes, the automatic directory + creation will only occur for the default location, not if + -c or RECOLL_CONFDIR were used (in the latter + cases, you will have to create the directory).

+ +

All configuration files share the same format. For + example, a short extract of the main configuration file + might look as follows:

+
+        # Space-separated list of directories to index.
+        topdirs =  ~/docs /usr/share/doc
+
+        [~/somedirectory-with-utf8-txt-files]
+        defaultcharset = utf-8
+        
+
+ +

There are three kinds of lines:

+ +
+
    +
  • +

    Comment (starts with #) or empty.

    +
  • + +
  • +

    Parameter affectation (name = value).

    +
  • + +
  • +

    Section definition ([somedirname]).

    +
  • +
+
+ +

Long lines can be broken by ending each incomplete part + with a backslash (\).

+ +

Depending on the type of configuration file, section + definitions either separate groups of parameters or allow + redefining some parameters for a directory sub-tree. They + stay in effect until another section definition, or the end + of file, is encountered. Some of the parameters used for + indexing are looked up hierarchically from the current + directory location upwards. Not all parameters can be + meaningfully redefined, this is specified for each in the + next section.

+ +

When found at the beginning of a file path, the tilde + character (~) is expanded to the name of the user's home + directory, as a shell would do.

+ +

Some parameters are lists of strings. White space is + used for separation. List elements with embedded spaces can + be quoted using double-quotes. Double quotes inside these + elements can be escaped with a backslash.

+ +

No value inside a configuration file can contain a + newline character. Long lines can be continued by escaping + the physical newline with backslash, even inside quoted + strings.

+
+astringlist =  "some string \
+with spaces"
+thesame = "some string with spaces"        
+        
+
+ +

Parameters which are not part of string lists can't be + quoted, and leading and trailing space characters are + stripped before the value is used.

+ +

Encoding issues. Most of the configuration + parameters are plain ASCII. Two particular sets of values + may cause encoding issues:

+ +
+
    +
  • +

    File path parameters may contain non-ascii + characters and should use the exact same byte values + as found in the file system directory. Usually, this + means that the configuration file should use the + system default locale encoding.

    +
  • + +
  • +

    The unac_except_trans + parameter should be encoded in UTF-8. If your system + locale is not UTF-8, and you need to also specify + non-ascii file paths, this poses a difficulty because + common text editors cannot handle multiple encodings + in a single file. In this relatively unlikely case, + you can edit the configuration file as two separate + text files with appropriate encodings, and + concatenate them to create the complete + configuration.

    +
  • +
+
+ +
+
+
+
+

5.4.1. Environment + variables

+
+
+
+ +
+
+
RECOLL_CONFDIR
+ +
+

Defines the main configuration directory.

+
+ +
RECOLL_TMPDIR, TMPDIR
+ +
+

Locations for temporary files, in this order of + priority. The default if none of these is set is to + use /tmp. Big + temporary files may be created during indexing, + mostly for decompressing, and also for processing, + e.g. email attachments.

+
+ +
RECOLL_CONFTOP, + RECOLL_CONFMID
+ +
+

Allow adding configuration directories with + priorities below and above the user directory (see + above the Configuration overview section for + details).

+
+ +
RECOLL_EXTRA_DBS, + RECOLL_ACTIVE_EXTRA_DBS
+ +
+

Help for setting up external indexes. See + this + paragraph for explanations.

+
+ +
RECOLL_DATADIR
+ +
+

Defines replacement for the default location of + Recoll data files, normally found in, e.g., + /usr/share/recoll).

+
+ +
RECOLL_FILTERSDIR
+ +
+

Defines replacement for the default location of + Recoll filters, normally found in, e.g., + /usr/share/recoll/filters).

+
+ +
ASPELL_PROG
+ +
+

aspell program to + use for creating the spelling dictionary. The + result has to be compatible with the libaspell which Recoll is using.

+
+ +
VARNAME
+ +
+

Blabla

+
+
+
+
+ +
+
+
+
+

5.4.2. Recoll + main configuration file, recoll.conf

+
+
+
+ +
+
+
+
+

5.4.2.1. Parameters + affecting what documents we index

+
+
+
+ +
+
topdirs
+ +
+

Space-separated list of files or directories to + recursively index. Default to ~ (indexes $HOME). + You can use symbolic links in the list, they will + be followed, independantly of the value of the + followLinks variable.

+
+ +
skippedNames
+ +
+

Files and directories which should be ignored. + White space separated list of wildcard patterns + (simple ones, not paths, must contain no / ), which + will be tested against file and directory names. + The list in the default configuration does not + exclude hidden directories (names beginning with a + dot), which means that it may index quite a few + things that you do not want. On the other hand, + email user agents like Thunderbird usually store + messages in hidden directories, and you probably + want this indexed. One possible solution is to have + ".*" in "skippedNames", and add things like + "~/.thunderbird" "~/.evolution" to "topdirs". Not + even the file names are indexed for patterns in + this list, see the "noContentSuffixes" variable for + an alternative approach which indexes the file + names. Can be redefined for any subtree.

+
+ +
noContentSuffixes
+ +
+

List of name endings (not necessarily + dot-separated suffixes) for which we don't try MIME + type identification, and don't uncompress or index + content. Only the names will be indexed. This + complements the now obsoleted recoll_noindex list + from the mimemap file, which will go away in a + future release (the move from mimemap to + recoll.conf allows editing the list through the + GUI). This is different from skippedNames because + these are name ending matches only (not wildcard + patterns), and the file name itself gets indexed + normally. This can be redefined for + subdirectories.

+
+ +
skippedPaths
+ +
+

Paths we should not go into. Space-separated + list of wildcard expressions for filesystem paths. + Can contain files and directories. The database and + configuration directories will automatically be + added. The expressions are matched using + 'fnmatch(3)' with the FNM_PATHNAME flag set by + default. This means that '/' characters must be + matched explicitely. You can set + 'skippedPathsFnmPathname' to 0 to disable the use + of FNM_PATHNAME (meaning that '/*/dir3' will match + '/dir1/dir2/dir3'). The default value contains the + usual mount point for removable media to remind you + that it is a bad idea to have Recoll work on these + (esp. with the monitor: media gets indexed on + mount, all data gets erased on unmount). + Explicitely adding '/media/xxx' to the topdirs will + override this.

+
+ +
+ skippedPathsFnmPathname
+ +
+

Set to 0 to override use of FNM_PATHNAME for + matching skipped paths.

+
+ +
daemSkippedPaths
+ +
+

skippedPaths equivalent specific to real time + indexing. This enables having parts of the tree + which are initially indexed but not monitored. If + daemSkippedPaths is not set, the daemon uses + skippedPaths.

+
+ +
zipSkippedNames
+ +
+

Space-separated list of wildcard expressions for + names that should be ignored inside zip archives. + This is used directly by the zip handler, and has a + function similar to skippedNames, but works + independantly. Can be redefined for subdirectories. + Supported by recoll 1.20 and newer. See + https://bitbucket.org/medoc/recoll/wiki/Filtering%20out%20Zip%20archive%20members

+
+ +
followLinks
+ +
+

Follow symbolic links during indexing. The + default is to ignore symbolic links to avoid + multiple indexing of linked files. No effort is + made to avoid duplication when this option is set + to true. This option can be set individually for + each of the 'topdirs' members by using sections. It + can not be changed below the 'topdirs' level. Links + in the 'topdirs' list itself are always + followed.

+
+ +
indexedmimetypes
+ +
+

Restrictive list of indexed mime types. Normally + not set (in which case all supported types are + indexed). If it is set, only the types from the + list will have their contents indexed. The names + will be indexed anyway if indexallfilenames is set + (default). MIME type names should be taken from the + mimemap file. Can be redefined for subtrees.

+
+ +
excludedmimetypes
+ +
+

List of excluded MIME types. Lets you exclude + some types from indexing. Can be redefined for + subtrees.

+
+ +
compressedfilemaxkbs
+ +
+

Size limit for compressed files. We need to + decompress these in a temporary directory for + identification, which can be wasteful in some + cases. Limit the waste. Negative means no limit. 0 + results in no processing of any compressed file. + Default 50 MB.

+
+ +
textfilemaxmbs
+ +
+

Size limit for text files. Mostly for skipping + monster logs. Default 20 MB.

+
+ +
indexallfilenames
+ +
+

Index the file names of unprocessed files Index + the names of files the contents of which we don't + index because of an excluded or unsupported MIME + type.

+
+ +
usesystemfilecommand
+ +
+

Use a system command for file MIME type guessing + as a final step in file type identification This is + generally useful, but will usually cause the + indexing of many bogus 'text' files. See + 'systemfilecommand' for the command used.

+
+ +
systemfilecommand
+ +
+

Command used to guess MIME types if the internal + methods fails This should be a "file -i" workalike. + The file path will be added as a last parameter to + the command line. 'xdg-mime' works better than the + traditional 'file' command, and is now the + configured default (with a hard-coded fallback to + 'file')

+
+ +
processwebqueue
+ +
+

Decide if we process the Web queue. The queue is + a directory where the Recoll Web browser plugins + create the copies of visited pages.

+
+ +
textfilepagekbs
+ +
+

Page size for text files. If this is set, + text/plain files will be divided into documents of + approximately this size. Will reduce memory usage + at index time and help with loading data in the + preview window at query time. Particularly useful + with very big files, such as application or system + logs. Also see textfilemaxmbs and + compressedfilemaxkbs.

+
+ +
membermaxkbs
+ +
+

Size limit for archive members. This is passed + to the filters in the environment as + RECOLL_FILTER_MAXMEMBERKB.

+
+
+
+ +
+
+
+
+

5.4.2.2. Parameters + affecting how we generate terms

+
+
+
+ +
+
indexStripChars
+ +
+

Decide if we store character case and diacritics + in the index. If we do, searches sensitive to case + and diacritics can be performed, but the index will + be bigger, and some marginal weirdness may + sometimes occur. The default is a stripped index. + When using multiple indexes for a search, this + parameter must be defined identically for all. + Changing the value implies an index reset.

+
+ +
nonumbers
+ +
+

Decides if terms will be generated for numbers. + For example "123", "1.5e6", 192.168.1.4, would not + be indexed if nonumbers is set ("value123" would + still be). Numbers are often quite interesting to + search for, and this should probably not be set + except for special situations, ie, scientific + documents with huge amounts of numbers in them, + where setting nonumbers will reduce the index size. + This can only be set for a whole index, not for a + subtree.

+
+ +
dehyphenate
+ +
+

Determines if we index 'coworker' also when the + input is 'co-worker'. This is new in version 1.22, + and on by default. Setting the variable to off + allows restoring the previous behaviour.

+
+ +
nocjk
+ +
+

Decides if specific East Asian (Chinese Korean + Japanese) characters/word splitting is turned off. + This will save a small amount of CPU if you have no + CJK documents. If your document base does include + such text but you are not interested in searching + it, setting nocjk may be a significant time and + space saver.

+
+ +
cjkngramlen
+ +
+

This lets you adjust the size of n-grams used + for indexing CJK text. The default value of 2 is + probably appropriate in most cases. A value of 3 + would allow more precision and efficiency on longer + words, but the index will be approximately twice as + large.

+
+ +
+ indexstemminglanguages
+ +
+

Languages for which to create stemming expansion + data. Stemmer names can be found by executing + 'recollindex -l', or this can also be set from a + list in the GUI.

+
+ +
defaultcharset
+ +
+

Default character set. This is used for files + which do not contain a character set definition + (e.g.: text/plain). Values found inside files, e.g. + a 'charset' tag in HTML documents, will override + it. If this is not set, the default character set + is the one defined by the NLS environment ($LC_ALL, + $LC_CTYPE, $LANG), or ultimately iso-8859-1 + (cp-1252 in fact). If for some reason you want a + general default which does not match your LANG and + is not 8859-1, use this variable. This can be + redefined for any sub-directory.

+
+ +
unac_except_trans
+ +
+

A list of characters, encoded in UTF-8, which + should be handled specially when converting text to + unaccented lowercase. For example, in Swedish, the + letter a with diaeresis has full alphabet + citizenship and should not be turned into an a. + Each element in the space-separated list has the + special character as first element and the + translation following. The handling of both the + lowercase and upper-case versions of a character + should be specified, as appartenance to the list + will turn-off both standard accent and case + processing. The value is global and affects both + indexing and querying. Examples: Swedish: + unac_except_trans = ää Ää + öö Öö üü Üü + ßss œoe Œoe æae Æae + ffff fifi flfl åå + Åå . German: unac_except_trans = + ää Ää öö Öö + üü Üü ßss œoe + Œoe æae Æae ffff fifi + flfl In French, you probably want to + decompose oe and ae and nobody would type a German + ß unac_except_trans = ßss œoe + Œoe æae Æae ffff fifi + flfl . The default for all until someone + protests follows. These decompositions are not + performed by unac, but it is unlikely that someone + would type the composed forms in a search. + unac_except_trans = ßss œoe Œoe + æae Æae ffff fifi + flfl

+
+ +
maildefcharset
+ +
+

Overrides the default character set for email + messages which don't specify one. This is mainly + useful for readpst (libpst) dumps, which are utf-8 + but do not say so.

+
+ +
localfields
+ +
+

Set fields on all files (usually of a specific + fs area). Syntax is the usual: name = value ; attr1 + = val1 ; [...] value is empty so this needs an + initial semi-colon. This is useful, e.g., for + setting the rclaptg field for application selection + inside mimeview.

+
+ +
testmodifusemtime
+ +
+

Use mtime instead of ctime to test if a file has + been modified. The time is used in addition to the + size, which is always used. Setting this can reduce + re-indexing on systems where extended attributes + are used (by some other application), but not + indexed, because changing extended attributes only + affects ctime. Notes: - This may prevent detection + of change in some marginal file rename cases (the + target would need to have the same size and mtime). + - You should probably also set noxattrfields to 1 + in this case, except if you still prefer to perform + xattr indexing, for example if the local file + update pattern makes it of value (as in general, + there is a risk for pure extended attributes + updates without file modification to go + undetected). Perform a full index reset after + changing this.

+
+ +
noxattrfields
+ +
+

Disable extended attributes conversion to + metadata fields. This probably needs to be set if + testmodifusemtime is set.

+
+ +
metadatacmds
+ +
+

Define commands to gather external metadata, + e.g. tmsu tags. There can be several entries, + separated by semi-colons, each defining which field + name the data goes into and the command to use. + Don't forget the initial semi-colon. All the field + names must be different. You can use aliases in the + "field" file if necessary. As a not too pretty hack + conceded to convenience, any field name beginning + with "rclmulti" will be taken as an indication that + the command returns multiple field values inside a + text blob formatted as a recoll configuration file + ("fieldname = fieldvalue" lines). The rclmultixx + name will be ignored, and field names and values + will be parsed from the data. Example: metadatacmds + = ; tags = tmsu tags %f; rclmulti1 = cmdOutputsConf + %f

+
+
+
+ +
+
+
+
+

5.4.2.3. Parameters + affecting where and how we store things

+
+
+
+ +
+
cachedir
+ +
+

Top directory for Recoll data. Recoll data + directories are normally located relative to the + configuration directory (e.g. ~/.recoll/xapiandb, + ~/.recoll/mboxcache). If 'cachedir' is set, the + directories are stored under the specified value + instead (e.g. if cachedir is ~/.cache/recoll, the + default dbdir would be ~/.cache/recoll/xapiandb). + This affects dbdir, webcachedir, mboxcachedir, + aspellDicDir, which can still be individually + specified to override cachedir. Note that if you + have multiple configurations, each must have a + different cachedir, there is no automatic + computation of a subpath under cachedir.

+
+ +
maxfsoccuppc
+ +
+

Maximum file system occupation over which we + stop indexing. The value is a percentage, + corresponding to what the "Capacity" df output + column shows. The default value is 0, meaning no + checking.

+
+ +
xapiandb
+ +
+

Xapian database directory location. This will be + created on first indexing. If the value is not an + absolute path, it will be interpreted as relative + to cachedir if set, or the configuration directory + (-c argument or $RECOLL_CONFDIR). If nothing is + specified, the default is then + ~/.recoll/xapiandb/

+
+ +
idxstatusfile
+ +
+

Name of the scratch file where the indexer + process updates its status. Default: idxstatus.txt + inside the configuration directory.

+
+ +
mboxcachedir
+ +
+

Directory location for storing mbox message + offsets cache files. This is normally 'mboxcache' + under cachedir if set, or else under the + configuration directory, but it may be useful to + share a directory between different + configurations.

+
+ +
mboxcacheminmbs
+ +
+

Minimum mbox file size over which we cache the + offsets. There is really no sense in caching + offsets for small files. The default is 5 MB.

+
+ +
webcachedir
+ +
+

Directory where we store the archived web pages. + This is only used by the web history indexing code + Default: cachedir/webcache if cachedir is set, else + $RECOLL_CONFDIR/webcache

+
+ +
webcachemaxmbs
+ +
+

Maximum size in MB of the Web archive. This is + only used by the web history indexing code. + Default: 40 MB. Reducing the size will not + physically truncate the file.

+
+ +
webqueuedir
+ +
+

The path to the Web indexing queue. This is + hard-coded in the plugin as ~/.recollweb/ToIndex so + there should be no need or possibility to change + it.

+
+ +
aspellDicDir
+ +
+

Aspell dictionary storage directory location. + The aspell dictionary (aspdict.(lang).rws) is + normally stored in the directory specified by + cachedir if set, or under the configuration + directory.

+
+ +
filtersdir
+ +
+

Directory location for executable input + handlers. If RECOLL_FILTERSDIR is set in the + environment, we use it instead. Defaults to + $prefix/share/recoll/filters. Can be redefined for + subdirectories.

+
+ +
iconsdir
+ +
+

Directory location for icons. The only reason to + change this would be if you want to change the + icons displayed in the result list. Defaults to + $prefix/share/recoll/images

+
+
+
+ +
+
+
+
+

5.4.2.4. Parameters + affecting indexing performance and resource + usage

+
+
+
+ +
+
idxflushmb
+ +
+

Threshold (megabytes of new data) where we flush + from memory to disk index. Setting this allows some + control over memory usage by the indexer process. A + value of 0 means no explicit flushing, which lets + Xapian perform its own thing, meaning flushing + every $XAPIAN_FLUSH_THRESHOLD documents created, + modified or deleted: as memory usage depends on + average document size, not only document count, the + Xapian approach is is not very useful, and you + should let Recoll manage the flushes. The program + compiled value is 0. The configured default value + (from this file) is 10 MB, and will be too low in + many cases (it is chosen to conserve memory). If + you are looking for maximum speed, you may want to + experiment with values between 20 and 200. In my + experience, values beyond this are always + counterproductive. If you find otherwise, please + drop me a note.

+
+ +
filtermaxseconds
+ +
+

Maximum external filter execution time in + seconds. Default 1200 (20mn). Set to 0 for no + limit. This is mainly to avoid infinite loops in + postscript files (loop.ps)

+
+ +
filtermaxmbytes
+ +
+

Maximum virtual memory space for filter + processes (setrlimit(RLIMIT_AS)), in megabytes. + Note that this includes any mapped libs (there is + no reliable Linux way to limit the data space + only), so we need to be a bit generous here. + Anything over 2000 will be ignored on 32 bits + machines.

+
+ +
thrQSizes
+ +
+

Stage input queues configuration. There are + three internal queues in the indexing pipeline + stages (file data extraction, terms generation, + index update). This parameter defines the queue + depths for each stage (three integer values). If a + value of -1 is given for a given stage, no queue is + used, and the thread will go on performing the next + stage. In practise, deep queues have not been shown + to increase performance. Default: a value of 0 for + the first queue tells Recoll to perform + autoconfiguration based on the detected number of + CPUs (no need for the two other values in this + case). Use thrQSizes = -1 -1 -1 to disable + multithreading entirely.

+
+ +
thrTCounts
+ +
+

Number of threads used for each indexing stage. + The three stages are: file data extraction, terms + generation, index update). The use of the counts is + also controlled by some special values in + thrQSizes: if the first queue depth is 0, all + counts are ignored (autoconfigured); if a value of + -1 is used for a queue depth, the corresponding + thread count is ignored. It makes no sense to use a + value other than 1 for the last stage because + updating the Xapian index is necessarily + single-threaded (and protected by a mutex).

+
+
+
+ +
+
+
+
+

5.4.2.5. Miscellaneous + parameters

+
+
+
+ +
+
loglevel
+ +
+

Log file verbosity 1-6. A value of 2 will print + only errors and warnings. 3 will print information + like document updates, 4 is quite verbose and 6 + very verbose.

+
+ +
logfilename
+ +
+

Log file destination. Use 'stderr' (default) to + write to the console.

+
+ +
idxloglevel
+ +
+

Override loglevel for the indexer.

+
+ +
idxlogfilename
+ +
+

Override logfilename for the indexer.

+
+ +
daemloglevel
+ +
+

Override loglevel for the indexer in real time + mode. The default is to use the idx... values if + set, else the log... values.

+
+ +
daemlogfilename
+ +
+

Override logfilename for the indexer in real + time mode. The default is to use the idx... values + if set, else the log... values.

+
+ +
idxrundir
+ +
+

Indexing process current directory. The input + handlers sometimes leave temporary files in the + current directory, so it makes sense to have + recollindex chdir to some temporary directory. If + the value is empty, the current directory is not + changed. If the value is (literal) tmp, we use the + temporary directory as set by the environment + (RECOLL_TMPDIR else TMPDIR else /tmp). If the value + is an absolute path to a directory, we go + there.

+
+ +
+ checkneedretryindexscript
+ +
+

Script used to heuristically check if we need to + retry indexing files which previously failed. The + default script checks the modified dates on + /usr/bin and /usr/local/bin. A relative path will + be looked up in the filters dirs, then in the path. + Use an absolute path to do otherwise.

+
+ +
recollhelperpath
+ +
+

Additional places to search for helper + executables. This is only used on Windows for + now.

+
+ +
idxabsmlen
+ +
+

Length of abstracts we store while indexing. + Recoll stores an abstract for each indexed file. + The text can come from an actual 'abstract' section + in the document or will just be the beginning of + the document. It is stored in the index so that it + can be displayed inside the result lists without + decoding the original file. The idxabsmlen + parameter defines the size of the stored abstract. + The default value is 250 bytes. The search + interface gives you the choice to display this + stored text or a synthetic abstract built by + extracting text around the search terms. If you + always prefer the synthetic abstract, you can + reduce this value and save a little space.

+
+ +
idxmetastoredlen
+ +
+

Truncation length of stored metadata fields. + This does not affect indexing (the whole field is + processed anyway), just the amount of data stored + in the index for the purpose of displaying fields + inside result lists or previews. The default value + is 150 bytes which may be too low if you have + custom fields.

+
+ +
aspellLanguage
+ +
+

Language definitions to use when creating the + aspell dictionary. The value must match a set of + aspell language definition files. You can type + "aspell dicts" to see a list The default if this is + not set is to use the NLS environment to guess the + value.

+
+ +
aspellAddCreateParam
+ +
+

Additional option and parameter to aspell + dictionary creation command. Some aspell packages + may need an additional option (e.g. on Debian + Jessie: --local-data-dir=/usr/lib/aspell). See + Debian bug 772415.

+
+ +
aspellKeepStderr
+ +
+

Set this to have a look at aspell dictionary + creation errors. There are always many, so this is + mostly for debugging.

+
+ +
noaspell
+ +
+

Disable aspell use. The aspell dictionary + generation takes time, and some combinations of + aspell version, language, and local terms, result + in aspell crashing, so it sometimes makes sense to + just disable the thing.

+
+ +
monauxinterval
+ +
+

Auxiliary database update interval. The real + time indexer only updates the auxiliary databases + (stemdb, aspell) periodically, because it would be + too costly to do it for every document change. The + default period is one hour.

+
+ +
monixinterval
+ +
+

Minimum interval (seconds) between processings + of the indexing queue. The real time indexer does + not process each event when it comes in, but lets + the queue accumulate, to diminish overhead and to + aggregate multiple events affecting the same file. + Default 30 S.

+
+ +
mondelaypatterns
+ +
+

Timing parameters for the real time indexing. + Definitions for files which get a longer delay + before reindexing is allowed. This is for + fast-changing files, that should only be reindexed + once in a while. A list of wildcardPattern:seconds + pairs. The patterns are matched with + fnmatch(pattern, path, 0) You can quote entries + containing white space with double quotes (quote + the whole entry, not the pattern). The default is + empty. Example: mondelaypatterns = *.log:20 "*with + spaces.*:30"

+
+ +
monioniceclass
+ +
+

ionice class for the real time indexing process + On platforms where this is supported. The default + value is 3.

+
+ +
+ monioniceclassdata
+ +
+

ionice class parameter for the real time + indexing process. On platforms where this is + supported. The default is empty.

+
+
+
+ +
+
+
+
+

5.4.2.6. Query-time + parameters (no impact on the index)

+
+
+
+ +
+
autodiacsens
+ +
+

auto-trigger diacritics sensitivity (raw index + only). IF the index is not stripped, decide if we + automatically trigger diacritics sensitivity if the + search term has accented characters (not in + unac_except_trans). Else you need to use the query + language and the "D" modifier to specify diacritics + sensitivity. Default is no.

+
+ +
autocasesens
+ +
+

auto-trigger case sensitivity (raw index only). + IF the index is not stripped (see indexStripChars), + decide if we automatically trigger character case + sensitivity if the search term has upper-case + characters in any but the first position. Else you + need to use the query language and the "C" modifier + to specify character-case sensitivity. Default is + yes.

+
+ +
maxTermExpand
+ +
+

Maximum query expansion count for a single term + (e.g.: when using wildcards). This only affects + queries, not indexing. We used to not limit this at + all (except for filenames where the limit was too + low at 1000), but it is unreasonable with a big + index. Default 10000.

+
+ +
maxXapianClauses
+ +
+

Maximum number of clauses we add to a single + Xapian query. This only affects queries, not + indexing. In some cases, the result of term + expansion can be multiplicative, and we want to + avoid eating all the memory. Default 50000.

+
+ +
snippetMaxPosWalk
+ +
+

Maximum number of positions we walk while + populating a snippet for the result list. The + default of 1,000,000 may be insufficient for very + big documents, the consequence would be snippets + with possibly meaning-altering missing words.

+
+
+
+ +
+
+
+
+

5.4.2.7. Parameters + for the PDF input script

+
+
+
+ +
+
pdfocr
+ +
+

Attempt OCR of PDF files with no text content if + both tesseract and pdftoppm are installed. The + default is off because OCR is so very slow.

+
+ +
pdfattach
+ +
+

Enable PDF attachment extraction by executing + pdftk (if available). This is normally disabled, + because it does slow down PDF indexing a bit even + if not one attachment is ever found.

+
+
+
+ +
+
+
+
+

5.4.2.8. Parameters + set for specific locations

+
+
+
+ +
+
mhmboxquirks
+ +
+

Enable thunderbird/mozilla-seamonkey mbox format + quirks Set this for the directory where the email + mbox files are stored.

+
+
+
+
+ +
+
+
+
+

5.4.3. The + fields file

+
+
+
+ +

This file contains information about dynamic fields + handling in Recoll. Some + very basic fields have hard-wired behaviour, and, mostly, + you should not change the original data inside the + fields file. But you can + create custom fields fitting your data and handle them + just like they were native ones.

+ +

The fields file has + several sections, which each define an aspect of fields + processing. Quite often, you'll have to modify several + sections to obtain the desired behaviour.

+ +

We will only give a short description here, you should + refer to the comments inside the default file for more + detailed information.

+ +

Field names should be lowercase alphabetic ASCII.

+ +
+
+
[prefixes]
+ +
+

A field becomes indexed (searchable) by having a + prefix defined in this section.

+
+ +
[stored]
+ +
+

A field becomes stored (displayable inside + results) by having its name listed in this section + (typically with an empty value).

+
+ +
[aliases]
+ +
+

This section defines lists of synonyms for the + canonical names used inside the [prefixes] and [stored] sections

+
+ +
[queryaliases]
+ +
+

This section also defines aliases for the + canonic field names, with the difference that the + substitution will only be used at query time, + avoiding any possibility that the value would + pick-up random metadata from documents.

+
+ +
handler-specific + sections
+ +
+

Some input handlers may need specific + configuration for handling fields. Only the email + message handler currently has such a section (named + [mail]). It allows + indexing arbitrary email headers in addition to the + ones indexed by default. Other such sections may + appear in the future.

+
+
+
+ +

Here follows a small example of a personal + fields file. This would + extract a specific email header and use it as a + searchable field, with data displayable inside result + lists. (Side note: as the email handler does no decoding + on the values, only plain ascii headers can be indexed, + and only the first occurrence will be used for headers + that occur several times).

+
+[prefixes]
+# Index mailmytag contents (with the given prefix)
+mailmytag = XMTAG
+
+[stored]
+# Store mailmytag inside the document data record (so that it can be
+# displayed - as %(mailmytag) - in result lists).
+mailmytag = 
+
+[queryaliases]
+filename = fn
+containerfilename = cfn
+
+[mail]
+# Extract the X-My-Tag mail header, and use it internally with the
+# mailmytag field name
+x-my-tag = mailmytag
+
+ +
+
+
+
+

5.4.3.1. Extended + attributes in the fields file

+
+
+
+ +

Recoll versions + 1.19 and later process user extended file attributes as + documents fields by default.

+ +

Attributes are processed as fields of the same name, + after removing the user + prefix on Linux.

+ +

The [xattrtofields] + section of the fields + file allows specifying translations from extended + attributes names to Recoll field names. An empty + translation disables use of the corresponding attribute + data.

+
+
+ +
+
+
+
+

5.4.4. The + mimemap file

+
+
+
+ +

mimemap specifies the + file name extension to MIME type mappings.

+ +

For file names without an extension, or with an + unknown one, a system command (file -i, or xdg-mime) will be + executed to determine the MIME type (this can be switched + off, or the command changed inside the main configuration + file).

+ +

The mappings can be specified on a per-subtree basis, + which may be useful in some cases. Example: okular notes have a .xml extension but should be handled + specially, which is possible because they are usually all + located in one place. Example:

+
+[~/.kde/share/apps/okular/docdata]
+.xml = application/x-okular-notes
+
+ +

The recoll_noindex + mimemap variable has been + moved to recoll.conf and + renamed to noContentSuffixes, while keeping the + same function, as of Recoll version 1.21. For older + Recoll versions, see the + documentation for noContentSuffixes but use recoll_noindex in mimemap.

+
+ +
+
+
+
+

5.4.5. The + mimeconf file

+
+
+
+ +

mimeconf specifies how + the different MIME types are handled for indexing, and + which icons are displayed in the recoll result + lists.

+ +

Changing the parameters in the [index] section is + probably not a good idea except if you are a Recoll developer.

+ +

The [icons] section allows you to change the icons + which are displayed by recoll in the result + lists (the values are the basenames of the png images + inside the iconsdir + directory (specified in recoll.conf).

+
+ +
+
+
+
+

5.4.6. The + mimeview file

+
+
+
+ +

mimeview specifies which + programs are started when you click on an Open link in a result list. Ie: HTML is + normally displayed using firefox, but you may prefer + Konqueror, your + openoffice.org program + might be named oofice instead of + openoffice + etc.

+ +

Changes to this file can be done by direct editing, or + through the recoll GUI preferences + dialog.

+ +

If Use desktop preferences to + choose document editor is checked in the + Recoll GUI preferences, + all mimeview entries will + be ignored except the one labelled application/x-all (which is set to use + xdg-open by + default).

+ +

In this case, the xallexcepts top level variable defines a + list of MIME type exceptions which will be processed + according to the local entries instead of being passed to + the desktop. This is so that specific Recoll options such as a page number + or a search string can be passed to applications that + support them, such as the evince viewer.

+ +

As for the other configuration files, the normal usage + is to have a mimeview + inside your own configuration directory, with just the + non-default entries, which will override those from the + central configuration file.

+ +

All viewer definition entries must be placed under a + [view] section.

+ +

The keys in the file are normally MIME types. You can + add an application tag to specialize the choice for an + area of the filesystem (using a localfields specification in + mimeconf). The syntax for + the key is mimetype|tag

+ +

The nouncompforviewmts + entry, (placed at the top level, outside of the + [view] section), holds a + list of MIME types that should not be uncompressed before + starting the viewer (if they are found compressed, ie: + mydoc.doc.gz).

+ +

The right side of each assignment holds a command to + be executed for opening the file. The following + substitutions are performed:

+ +
+
    +
  • +

    %D. Document date

    +
  • + +
  • +

    %f. File name. This may be the name + of a temporary file if it was necessary to create + one (ie: to extract a subdocument from a + container).

    +
  • + +
  • +

    %i. Internal path, for subdocuments + of containers. The format depends on the container + type. If this appears in the command line, + Recoll will not + create a temporary file to extract the subdocument, + expecting the called application (possibly a + script) to be able to handle it.

    +
  • + +
  • +

    %M. MIME type

    +
  • + +
  • +

    %p. Page index. Only significant for + a subset of document types, currently only PDF, + Postscript and DVI files. Can be used to start the + editor at the right page for a match or + snippet.

    +
  • + +
  • +

    %s. Search term. The value will only + be set for documents with indexed page numbers (ie: + PDF). The value will be one of the matched search + terms. It would allow pre-setting the value in the + "Find" entry inside Evince for example, for easy + highlighting of the term.

    +
  • + +
  • +

    %u. Url.

    +
  • +
+
+ +

In addition to the predefined values above, all + strings like %(fieldname) + will be replaced by the value of the field named + fieldname for the document. + This could be used in combination with field + customisation to help with opening the document.

+
+ +
+
+
+
+

5.4.7. The + ptrans file

+
+
+
+ +

ptrans specifies + query-time path translations. These can be useful in + multiple cases.

+ +

The file has a section for any index which needs + translations, either the main one or additional query + indexes. The sections are named with the Xapian index directory names. No + slash character should exist at the end of the paths (all + comparisons are textual). An exemple should make things + sufficiently clear

+
+          [/home/me/.recoll/xapiandb]
+          /this/directory/moved = /to/this/place
+
+          [/path/to/additional/xapiandb]
+          /server/volume1/docdir = /net/server/volume1/docdir
+          /server/volume2/docdir = /net/server/volume2/docdir
+        
+
+
+ +
+
+
+
+

5.4.8. Examples + of configuration adjustments

+
+
+
+ +
+
+
+
+

5.4.8.1. Adding + an external viewer for an non-indexed type

+
+
+
+ +

Imagine that you have some kind of file which does + not have indexable content, but for which you would + like to have a functional Open link in the result list (when + found by file name). The file names end in .blob and can be + displayed by application blobviewer.

+ +

You need two entries in the configuration files for + this to work:

+ +
+
    +
  • +

    In $RECOLL_CONFDIR/mimemap + (typically ~/.recoll/mimemap), add the + following line:

    +
    +.blob = application/x-blobapp
    +
    + +

    Note that the MIME type is made up here, and + you could call it diesel/oil just + the same.

    +
  • + +
  • +

    In $RECOLL_CONFDIR/mimeview under + the [view] section, + add:

    +
    +application/x-blobapp = blobviewer %f
    +
    + +

    We are supposing that blobviewer wants + a file name parameter here, you would use + %u if it liked URLs + better.

    +
  • +
+
+ +

If you just wanted to change the application used by + Recoll to display a + MIME type which it already knows, you would just need + to edit mimeview. The + entries you add in your personal file override those in + the central configuration, which you do not need to + alter. mimeview can also + be modified from the Gui.

+
+ +
+
+
+
+

5.4.8.2. Adding + indexing support for a new file type

+
+
+
+ +

Let us now imagine that the above .blob files actually + contain indexable text and that you know how to extract + it with a command line program. Getting Recoll to index the files is easy. + You need to perform the above alteration, and also to + add data to the mimeconf + file (typically in ~/.recoll/mimeconf):

+ +
+
    +
  • +

    Under the [index] + section, add the following line (more about the + rclblob + indexing script later):

    +
    +application/x-blobapp = exec rclblob
    +
    +
  • + +
  • +

    Under the [icons] + section, you should choose an icon to be + displayed for the files inside the result lists. + Icons are normally 64x64 pixels PNG files which + live in /usr/share/recoll/images.

    +
  • + +
  • +

    Under the [categories] section, you should + add the MIME type where it makes sense (you can + also create a category). Categories may be used + for filtering in advanced search.

    +
  • +
+
+ +

The rclblob handler should + be an executable program or script which exists inside + /usr/share/recoll/filters. It will be + given a file name as argument and should output the + text or html contents on the standard output.

+ +

The filter + programming section describes in more detail how to + write an input handler.

+
+
+
+
+
+ + diff --git a/src/doc/user/usermanual.xml b/src/doc/user/usermanual.xml new file mode 100644 index 00000000..8fa9472c --- /dev/null +++ b/src/doc/user/usermanual.xml @@ -0,0 +1,6300 @@ +Recoll"> +http://www.recoll.org/features.html"> + +Xapian"> +Windows"> + +]> + + + + + Recoll user manual + + + Jean-Francois + Dockes + +
jfd@recoll.org
+
+
+ + + 2005-2015 + Jean-Francois Dockes + + + + Permission is granted to copy, distribute and/or + modify this document under the terms of the GNU Free Documentation + License, Version 1.3 or any later version published by the Free + Software Foundation; with no Invariant Sections, no Front-Cover + Texts, and no Back-Cover Texts. A copy of the license can be + found at the following + location: GNU + web site. + + This document introduces full text search notions + and describes the installation and use of the &RCL; + application. This version describes &RCL; &RCLVERSION;. + + + +
+ + + Introduction + + This document introduces full text search notions + and describes the installation and use of the &RCL; + application. This version describes &RCL; &RCLVERSION;. + + &RCL; was for a long time dedicated to Unix-like systems. It + was only lately (2015) ported to + MS-Windows. Many references in this + manual, especially file locations, are specific to Unix, and not + valid on &WIN;. Some described features are also not available on + &WIN;. The manual will be progressively updated. Until this happens, + most references to shared files can be translated by looking under + the Recoll installation directory (esp. the + Share subdirectory). The user configuration is + stored by default under AppData/Local/Recoll + inside the user directory, along with the index itself. + + + Giving it a try + + If you do not like reading manuals (who does?) but + wish to give &RCL; a try, just install the application + and start the recoll graphical user + interface (GUI), which will ask permission to index your home + directory by default, allowing you to search immediately after + indexing completes. + + Do not do this if your home directory contains a huge + number of documents and you do not want to wait or are very + short on disk space. In this case, you may first want to customize + the configuration + to restrict the indexed area (for the very impatient with a completed package install, from the recoll GUI: + Preferences + Indexing configuration + , then adjust the Top + directories section). + + Also be aware that, on Unix/Linux, you may need to install the + appropriate supporting + applications for document types that need them (for + example antiword for + Microsoft Word files). + + The &RCL; installation for &WIN; is self-contained and includes + most useful auxiliary programs. You will just need to install Python + 2.7. + + + + + Full text search + + &RCL; is a full text search application, which means that it + finds your data by content rather than by external attributes + (like the file name). You specify words + (terms) which should or should not appear in the text you are + looking for, and receive in return a list of matching + documents, ordered so that the most + relevant documents will appear + first. + + You do not need to remember in what file or email message you + stored a given piece of information. You just ask for related + terms, and the tool will return a list of documents where + these terms are prominent, in a similar way to Internet search + engines. + + Full text search applications try to determine which + documents are most relevant to the search terms you + provide. Computer algorithms for determining relevance can be + very complex, and in general are inferior to the power of the + human mind to rapidly determine relevance. The quality of + relevance guessing is probably the most important aspect when + evaluating a search application. + + In many cases, you are looking for all the forms of a + word, including plurals, different tenses for a verb, or terms + derived from the same root or stem + (example: floor, floors, floored, + flooring...). Queries are usually automatically + expanded to all such related terms (words that reduce to the + same stem). This can be prevented for searching for a specific + form. + + Stemming, by itself, does not accommodate for misspellings + or phonetic searches. A full text search application may also + support this form of approximation. For example, a search for + aliterattion returning no result may + propose, depending on index contents, alliteration + alteration alterations altercation as possible + replacement terms. + + + + + Recoll overview + + &RCL; uses the + &XAP; information retrieval + library as its storage and retrieval engine. &XAP; is a very + mature package using a sophisticated + probabilistic ranking model. + + The &XAP; library manages an index database which + describes where terms appear in your document files. It + efficiently processes the complex queries which are produced by + the &RCL; query expansion mechanism, and is in charge of the + all-important relevance computation task. + + &RCL; provides the mechanisms and interface to get data + into and out of the index. This includes translating the many + possible document formats into pure text, handling term + variations (using &XAP; stemmers), and spelling approximations + (using the aspell speller), + interpreting user queries and presenting results. + + In a shorter way, &RCL; does the dirty footwork, &XAP; + deals with the intelligent parts of the process. + + The &XAP; index can be big (roughly the size of the + original document set), but it is not a document + archive. &RCL; can only display documents that still exist at + the place from which they were indexed. (Actually, there is a + way to reconstruct a document from the information in the + index, but the result is not nice, as all formatting, + punctuation and capitalization are lost). + + &RCL; stores all internal data in Unicode + UTF-8 format, and it can index files of many types + with different character sets, encodings, and languages into the + same index. It can process documents embedded inside other + documents (for example a pdf document stored inside a Zip + archive sent as an email attachment...), down to an arbitrary + depth. + + Stemming is the process by which &RCL; reduces words to + their radicals so that searching does not depend, for example, on a + word being singular or plural (floor, floors), or on a verb tense + (flooring, floored). Because the mechanisms used for stemming + depend on the specific grammatical rules for each language, there + is a separate &XAP; stemmer module for most common languages where + stemming makes sense. + + &RCL; stores the unstemmed versions of terms in the main index + and uses auxiliary databases for term expansion (one for each + stemming language), which means that you can switch stemming + languages between searches, or add a language without needing a + full reindex. + + Storing documents written in different languages in the same + index is possible, and commonly done. In this situation, you can + specify several stemming languages for the index. + + &RCL; currently makes no attempt at automatic language + recognition, which means that the stemmer will sometimes be applied + to terms from other languages with potentially strange results. In + practise, even if this introduces possibilities of confusion, this + approach has been proven quite useful, and it is much less + cumbersome than separating your documents according to what + language they are written in. + + By default, &RCL; strips most accents and + diacritics from terms, and converts them to lower case before + either storing them in the index or searching for them. As a + consequence, it is impossible to search for a particular + capitalization of a term (US / + us), or to discriminate two terms based on + diacritics (sake / saké, + mate / maté). + + &RCL; versions 1.18 and newer can optionally store the raw + terms, without accent stripping or case conversion. In this + configuration, default searches will behave as before, but it is + possible to perform searches sensitive to case and + diacritics. This is described in more detail + in the section about index + case and diacritics sensitivity. + + &RCL; has many parameters which define exactly what to + index, and how to classify and decode the source + documents. These are kept in configuration files. A + default configuration is copied into a standard location + (usually something like + /usr/share/recoll/examples) + during installation. The default values set by the + configuration files in this directory may be overridden by + values set inside your personal configuration, found + by default in the .recoll sub-directory + of your home directory. The default configuration will index + your home directory with default parameters and should be + sufficient for giving &RCL; a try, but you may want to adjust + it later, which can be done either by editing the text files + or by using configuration menus in the + recoll GUI. Some other parameters affecting only + the recoll GUI are stored in the standard + location defined by Qt. + + The indexing + process is started automatically the first time you + execute the recoll GUI. Indexing can also + be performed by executing the recollindex + command. &RCL; indexing is multithreaded by default when + appropriate hardware resources are available, and can perform + in parallel multiple tasks among text extraction, segmentation + and index updates. + + Searches are usually + performed inside the recoll GUI, which has many + options to help you find what you are looking for. However, there + are other ways to perform &RCL; searches: mostly a + command line interface, a + + Python + programming interface, a + KDE KIO slave module, and + Ubuntu Unity + Lens (for older versions) or + + Scope (for current versions) modules. + + + + + + + + Indexing + + + Introduction + + Indexing is the process by which the set of documents is + analyzed and the data entered into the database. &RCL; + indexing is normally incremental: documents will only be + processed if they have been modified since the last run. On + the first execution, all documents will need processing. A + full index build can be forced later by specifying an option + to the indexing command (recollindex + or ). + + recollindex skips files which caused an + error during a previous pass. This is a performance + optimization, and a new behaviour in version 1.21 (failed files + were always retried by previous versions). The command line + option can be set to retry failed files, for + example after updating a filter. + + The following sections give an overview of different + aspects of the indexing processes and configuration, with links + to detailed sections. + + Depending on your data, temporary files may be needed during + indexing, some of them possibly quite big. You can use the + RECOLL_TMPDIR or TMPDIR environment + variables to determine where they are created (the default is to + use /tmp). Using TMPDIR has + the nice property that it may also be taken into account by + auxiliary commands executed by recollindex. + + + Indexing modes + + &RCL; indexing can be performed along two different modes: + + + + <link linkend="RCL.INDEXING.PERIODIC"> + Periodic (or batch) indexing:</link> + indexing takes place at discrete + times, by executing the recollindex + command. The typical usage is to have a nightly indexing run + + programmed into + your cron file. + + + + <link linkend="RCL.INDEXING.MONITOR">Real + time indexing:</link> + indexing takes place as soon as a file is created or + changed. recollindex runs as a daemon + and uses a file system alteration monitor such as + inotify, + Fam or + Gamin + to detect file changes. + + + + + The choice between the two methods is mostly a matter of + preference, and they can be combined by setting up multiple + indexes (ie: use periodic indexing on a big documentation + directory, and real time indexing on a small home + directory). Monitoring a big file system tree can consume + significant system resources. + + The choice of method and the parameters used can be + configured from the recoll GUI: + + Preferences + Indexing schedule + + + + The File + menu also has entries to start or stop + the current indexing operation. Stopping indexing is performed by + killing the recollindex process, which will + checkpoint its state and exit. A later restart of indexing will + mostly resume from where things stopped (the file tree walk has to + be restarted from the beginning). + + When the real time indexer is running, only a stop operation + is available from the menu. When no indexing is running, you have + a choice of updating the index or rebuilding it (the first choice + only processes changed files, the second one zeroes the index + before starting so that all files are processed). + + + + + Configurations, multiple indexes + + The parameters describing what is to be indexed and + local preferences are defined in text files contained in a + configuration + directory. + + All parameters have defaults, defined in system-wide + files. + + Without further configuration, &RCL; will index all + appropriate files from your home directory, with a reasonable + set of defaults. + + A default personal configuration directory + ($HOME/.recoll/) is created + when a &RCL; program is first executed. It is possible to + create other configuration directories, and use them by + setting the RECOLL_CONFDIR environment + variable, or giving the option to any of + the &RCL; commands. + + In some cases, it may be interesting to index different + areas of the file system to separate databases. You can do this + by using multiple configuration directories, each indexing a + file system area to a specific database. Typically, this + would be done to separate personal and shared + indexes, or to take advantage of the organization of your data + to improve search precision. + + The generated indexes can + be queried concurrently in a transparent manner. + + For index generation, multiple configurations are + totally independant from each other. When multiple indexes need + to be used for a single search, + some parameters + should be consistent among the configurations. + + + + + Document types + &RCL; knows about quite a few different document + types. The parameters for document types recognition and + processing are set in + configuration files. + + Most file types, like HTML or word processing files, only hold + one document. Some file types, like email folders or zip + archives, can hold many individually indexed documents, which may + themselves be compound ones. Such hierarchies can go quite + deep, and &RCL; can process, for example, a + LibreOffice + document stored as an attachment to an email message inside an + email folder archived in a zip file... + + &RCL; indexing processes plain text, HTML, OpenDocument + (Open/LibreOffice), email formats, and a few others internally. + + Other file types (ie: postscript, pdf, ms-word, rtf ...) + need external applications for preprocessing. The list is in the + installation + section. After every indexing operation, &RCL; updates a list of + commands that would be needed for indexing existing files + types. This list can be displayed by selecting the menu option + + File + Show Missing Helpers + + in the recoll GUI. It is stored in the + missing text file inside the configuration + directory. + + By default, &RCL; will try to index any file type that + it has a way to read. This is sometimes not desirable, and + there are ways to either exclude some types, or on the + contrary to define a positive list of types to be + indexed. In the latter case, any type not in the list will + be ignored. + + Excluding types can be done by adding wildcard name + patterns to the skippedNames list, which + can be done from the GUI Index configuration menu. For + versions 1.20 and later, you can alternatively set the + excludedmimetypes list in the + configuration file. This can be redefined for + subdirectories. + + You can also define an exclusive list of MIME types to be indexed (no others will be indexed), by settting + the indexedmimetypes configuration + variable. Example: +indexedmimetypes = text/html application/pdf + + It is possible to redefine this parameter for + subdirectories. Example: +[/path/to/my/dir] +indexedmimetypes = application/pdf + + (When using sections like this, don't forget that they remain + in effect until the end of the file or another section + indicator). + + + excludedmimetypes or + indexedmimetypes, can be set either by + editing the + main configuration file + (recoll.conf), or from the GUI + index configuration tool. + + When editing the indexedmimetypes + or excludedmimetypes lists, you should use the + MIME values listed in the mimemap file + or in Recoll result lists in preference to file -i + output: there are a number of differences. + + + + + Indexing failures + + Indexing may fail for some documents, for a number of + reasons: a helper program may be missing, the document may be + corrupt, we may fail to uncompress a file because no file + system space is available, etc. + + &RCL; versions prior to 1.21 always retried to index + files which had previously caused an error. This guaranteed + that anything that may have become indexable (for example + because a helper had been installed) would be indexed. However + this was bad for performance because some indexing failures + may be quite costly (for example failing to uncompress a big + file because of insufficient disk space). + + The indexer in &RCL; versions 1.21 and later does not + retry failed file by default. Retrying will only occur if an + explicit option () is set on the + recollindex command line, or if a script + executed when recollindex starts up says + so. The script is defined by a configuration variable + (checkneedretryindexscript), and makes a + rather lame attempt at deciding if a helper command may have + been installed, by checking if any of the common + bin directories have changed. + + + + + Recovery + In the rare case where the index becomes corrupted (which can + signal itself by weird search results or crashes), the index files + need to be erased before restarting a clean indexing pass. Just delete + the xapiandb directory (see + next section), or, + alternatively, start the next recollindex with the + option, which will reset the database before + indexing. + + + + + + Index storage + + The default location for the index data is the + xapiandb subdirectory of the &RCL; + configuration directory, typically + $HOME/.recoll/xapiandb/. This can be + changed via two different methods (with different purposes): + + You can specify a different configuration + directory by setting the RECOLL_CONFDIR + environment variable, or using the + option to the &RCL; commands. This method would typically be + used to index different areas of the file system to + different indexes. For example, if you were to issue the + following command: + recoll -c ~/.indexes-email Then + &RCL; would use configuration files + stored in ~/.indexes-email/ and, + (unless specified otherwise in + recoll.conf) would look for + the index in + ~/.indexes-email/xapiandb/. + + Using multiple configuration directories and configuration + options allows you to tailor multiple configurations and + indexes to handle whatever subset of the available data you wish + to make searchable. + + + + For a given configuration directory, you can + specify a non-default storage location for the index by setting + the dbdir parameter in the configuration file + (see the configuration + section). This method would mainly be of use if you wanted + to keep the configuration directory in its default location, but + desired another location for the index, typically out of disk + occupation concerns. + + + + + + The size of the index is determined by the size of the set + of documents, but the ratio can vary a lot. For a typical + mixed set of documents, the index size will often be close to + the data set size. In specific cases (a set of compressed mbox + files for example), the index can become much bigger than the + documents. It may also be much smaller if the documents + contain a lot of images or other non-indexed data (an extreme + example being a set of mp3 files where only the tags would be + indexed). + + Of course, images, sound and video do not increase the + index size, which means that nowadays (2012), typically, even a big + index will be negligible against the total amount of data on the + computer. + + The index data directory (xapiandb) + only contains data that can be completely rebuilt by an index run + (as long as the original documents exist), and it can always be + destroyed safely. + + + &XAP; index formats + + &XAP; versions usually support several formats for index + storage. A given major &XAP; version will have a current format, + used to create new indexes, and will also support the format from + the previous major version. + + &XAP; will not convert automatically an existing index + from the older format to the newer one. If you want to upgrade to + the new format, or if a very old index needs to be converted + because its format is not supported any more, you will have to + explicitly delete the old index, then run a normal indexing + process. + + Using the option to + recollindex is not sufficient to change the + format, you will have to delete all files inside the index + directory (typically ~/.recoll/xapiandb) + before starting the indexing. + + + + + Security aspects + + The &RCL; index does not hold copies of the indexed + documents. But it does hold enough data to allow for an almost + complete reconstruction. If confidential data is indexed, + access to the database directory should be restricted. + + &RCL; will create the configuration directory with a mode of + 0700 (access by owner only). As the index data directory is by + default a sub-directory of the configuration directory, this should + result in appropriate protection. + + If you use another setup, you should think of the kind + of protection you need for your index, set the directory + and files access modes appropriately, and also maybe adjust + the umask used during index updates. + + + + + + + + Index configuration + + Variables set inside the + &RCL; configuration files + control which areas of the file system are indexed, and how + files are processed. These variables can be set either by + editing the text files or by using the + dialogs in the + recoll GUI. + + The first time you start recoll, you + will be asked whether or not you would like it to build the + index. If you want to adjust the configuration before + indexing, just click Cancel at this + point, which will get you into the configuration interface. If + you exit at this point, recoll will have + created a ~/.recoll directory containing + empty configuration files, which you can edit by hand. + + The configuration is documented inside the + installation chapter + of this document, or in the + + recoll.conf + 5 + + man page, but the most + current information will most likely be the comments inside the + sample file. The most immediately useful variable you may + interested in is probably + + topdirs, + which determines what subtrees get indexed. + + The applications needed to index file types other than + text, HTML or email (ie: pdf, postscript, ms-word...) are + described in the external + packages section. + + As of Recoll 1.18 there are two incompatible types of Recoll + indexes, depending on the treatment of character case and + diacritics. The next section describes the two types in more + detail. + + + Multiple indexes + + Multiple &RCL; indexes can be created by + using several configuration directories which are usually set to + index different areas of the file system. A specific index can + be selected for updating or searching, using the + RECOLL_CONFDIR environment variable or the + option to recoll and + recollindex. + + When working with the recoll index + configuration GUI, the configuration directory for which parameters + are modified is the one which was selected by + RECOLL_CONFDIR or the parameter, + and there is no way to switch configurations within the GUI. + + Additional configuration directory (beyond + ~/.recoll) must be created by hand + (mkdir or such), the GUI will not do it. This is + to avoid mistakenly creating additional directories when an + argument is mistyped. + + A typical usage scenario for the multiple index feature + would be for a system administrator to set up a central index + for shared data, that you choose to search or not in addition to + your personal data. Of course, there are other + possibilities. There are many cases where you know the subset of + files that should be searched, and where narrowing the search + can improve the results. You can achieve approximately the same + effect with the directory filter in advanced search, but + multiple indexes will have much better performance and may be + worth the trouble. + + A recollindex program instance can only + update one specific index. + + The main index (defined by + RECOLL_CONFDIR or ) is + always active. If this is undesirable, you can set up your + base configuration to index an empty directory. + + The different search interfaces (GUI, command line, ...) + have different methods to define the set of indexes to be + used, see the appropriate section. + + If a set of multiple indexes are to be used together for + searches, some configuration parameters must be consistent + among the set. These are parameters which need to be the same + when indexing and searching. As the parameters come from the + main configuration when searching, they need to be compatible + with what was set when creating the other indexes (which came + from their respective configuration directories). + + Most importantly, all indexes to be queried concurrently must + have the same option concerning character case and diacritics + stripping, but there are other constraints. Most of the + relevant parameters are described in the + linked + section. + + + + + + Index case and diacritics sensitivity + + As of &RCL; version 1.18 you have a choice of building an + index with terms stripped of character case and diacritics, or + one with raw terms. For a source term of + Résumé, the former will store + resume, the latter + Résumé. + + Each type of index allows performing searches insensitive to + case and diacritics: with a raw index, the user entry will be + expanded to match all case and diacritics variations present in + the index. With a stripped index, the search term will be stripped + before searching. + + A raw index allows for another possibility which a stripped + index cannot offer: using case and diacritics to discriminate + between terms, returning different results when searching for + US and us or + resume and résumé. + Read the section about search + case and diacritics sensitivity for more details. + + The type of index to be created is controlled by the + indexStripChars configuration + variable which can only be changed by editing the + configuration file. Any change implies an index reset (not + automated by &RCL;), and all indexes in a search must be set + in the same way (again, not checked by &RCL;). + + If the indexStripChars is not set, &RCL; + 1.18 creates a stripped index by default, for + compatibility with previous versions. + + As a cost for added capability, a raw index will be slightly + bigger than a stripped one (around 10%). Also, searches will be + more complex, so probably slightly slower, and the feature is + still young, so that a certain amount of weirdness cannot be + excluded. + + One of the most adverse consequence of using a raw index + is that some phrase and proximity searches may become + impossible: because each term needs to be expanded, and all + combinations searched for, the multiplicative expansion may + become unmanageable. + + + + + + + + + Indexing threads configuration + + The &RCL; indexing process + recollindex can use multiple threads to + speed up indexing on multiprocessor systems. The work done + to index files is divided in several stages and some of the + stages can be executed by multiple threads. The stages are: + + File system walking: this is always performed by + the main thread. + File conversion and data extraction. + Text processing (splitting, stemming, + etc.) + &XAP; index update. + + + You can also read a + + longer document about the transformation of + &RCL; indexing to multithreading. + + The threads configuration is controlled by two + configuration file parameters. + + + + thrQSizes + This variable defines the job input queues + configuration. There are three possible queues for stages + 2, 3 and 4, and this parameter should give the queue depth + for each stage (three integer values). If a value of -1 is + used for a given stage, no queue is used, and the thread + will go on performing the next stage. In practise, deep + queues have not been shown to increase performance. A value + of 0 for the first queue tells &RCL; to perform + autoconfiguration (no need for anything else in this case, + thrTCounts is not used) - this is the default + configuration. + + + + thrTCounts + This defines the number of threads used + for each stage. If a value of -1 is used for one of + the queue depths, the corresponding thread count is + ignored. It makes no sense to use a value other than 1 + for the last stage because updating the &XAP; index is + necessarily single-threaded (and protected by a + mutex). + + + + + + If the first value in thrQSizes is + 0, thrTCounts is ignored. + + The following example would use three queues (of depth 2), + and 4 threads for converting source documents, 2 for + processing their text, and one to update the index. This was + tested to be the best configuration on the test system + (quadri-processor with multiple disks). + +thrQSizes = 2 2 2 +thrTCounts = 4 2 1 + + + + The following example would use a single queue, and the + complete processing for each document would be performed by + a single thread (several documents will still be processed + in parallel in most cases). The threads will use mutual + exclusion when entering the index update stage. In practise + the performance would be close to the precedent case in + general, but worse in certain cases (e.g. a Zip archive + would be performed purely sequentially), so the previous + approach is preferred. YMMV... The 2 last values for + thrTCounts are ignored. + +thrQSizes = 2 -1 -1 +thrTCounts = 6 1 1 + + + + The following example would disable + multithreading. Indexing will be performed by a single + thread. + +thrQSizes = -1 -1 -1 + + + + + + + + + The index configuration GUI + + Most parameters for a given index configuration can + be set from a recoll GUI running on this + configuration (either as default, or by setting + RECOLL_CONFDIR or the + option.) + + The interface is started from the + + Preferences + Index Configuration + + menu entry. It is divided in four tabs, + Global parameters, Local + parameters, Web history + (which is explained in the next section) and Search + parameters. + + The Global parameters tab allows setting + global variables, like the lists of top directories, skipped paths, + or stemming languages. + + The Local parameters tab allows setting + variables that can be redefined for subdirectories. This second tab + has an initially empty list of customisation directories, to which + you can add. The variables are then set for the currently selected + directory (or at the top level if the empty line is + selected). + + The Search parameters section defines + parameters which are used at query time, but are global to an + index and affect all search tools, not only the GUI. + + The meaning for most entries in the interface is + self-evident and documented by a ToolTip + popup on the text label. For more detail, you will need to + refer to the configuration + section of this guide. + + The configuration tool normally respects the comments + and most of the formatting inside the configuration file, so + that it is quite possible to use it on hand-edited files, + which you might nevertheless want to backup first... + + + + + + + Indexing WEB pages you wisit + + With the help of a Firefox + extension, &RCL; can index the Internet pages that you visit. The + extension was initially designed for the + Beagle indexer, but it has recently be + renamed and better adapted to &RCL;. + + The extension works by copying visited WEB pages to an indexing + queue directory, which &RCL; then processes, indexing the data, + storing it into a local cache, then removing the file from the + queue. + + This feature can be enabled in the GUI + Index configuration + panel, or by editing the configuration file (set + processwebqueue to 1). + + A current pointer to the extension can be found, along with + up-to-date instructions, on the + Recoll wiki. + + A copy of the indexed WEB pages is retained by Recoll in a + local cache (from which previews can be fetched). The cache size can + be adjusted from the Index configuration / + Web history panel. Once the maximum size + is reached, old pages are purged - both from the cache and the index + - to make room for new ones, so you need to explicitly archive in + some other place the pages that you want to keep + indefinitely. + + + + + Extended attributes data + + User extended attributes are named pieces of information + that most modern file systems can attach to any file. + + &RCL; versions 1.19 and later process extended attributes + as document fields by default. For older versions, this has to + be activated at build time. + + A + + freedesktop standard defines a few special + attributes, which are handled as such by &RCL;: + + + mime_type + If set, this overrides any other + determination of the file MIME type. + + + charset + If set, this defines the file character set + (mostly useful for plain text files). + + + + + By default, other attributes are handled as &RCL; fields. + On Linux, the user prefix is removed from + the name. This can be configured more precisely inside + the + fields configuration file. + + + + + + Importing external tags + + During indexing, it is possible to import metadata for + each file by executing commands. For example, this could + extract user tag data for the file and store it in a field for + indexing. + + See the + section + about the metadatacmds field in + the main configuration chapter for a description of the + configuration syntax. + + As an example, if you would want &RCL; to use tags managed by + tmsu, you would add the following to the + configuration file: + + [/some/area/of/the/fs] +metadatacmds = ; tags = tmsu tags %f + + + Depending on the tmsu version, + you may need/want to add options like + --database=/some/db. + + You may want to restrict this processing to a subset of + the directory tree, because it may slow down indexing a bit + ([some/area/of/the/fs]). + Note the initial semi-colon after the equal sign. + + In the example above, the output of tmsu is + used to set a field named tags. The field name is + arbitrary and could be tmsu or + myfield just the same, but tags + is an alias for the standard &RCL; keywords field, + and the tmsu output will just augment its + contents. This will avoid the need to extend the field configuration. + + Once re-indexing is performed (you'll need to force the file + reindexing, &RCL; will not detect the need by itself), you will + be able to search from the query language, through any of its + aliases: tags:some/alternate/values or + tags:all,these,values (the compact field search + syntax is supported for recoll 1.20 and later. For + older versions, you would need to repeat the tags: + specifier for each term, e.g. tags:some OR + tags:alternate). + + You should be aware that tags changes will not be detected by + the indexer if the file itself did not change. One possible + workaround would be to update the file ctime when + you modify the tags, which + would be consistent with how extended attributes function. A pair of + chmod commands could accomplish this, or a + touch -a . Alternatively, just + couple the tag update with a recollindex -e -i + filename. + + + + + + Periodic indexing + + + Running indexing + + Indexing is always performed by the + recollindex program, which can be started + either from the command line or from the File + menu in the recoll GUI program. When started + from the GUI, the indexing will run on the same configuration + recoll was started on. When started from the + command line, recollindex will use the + RECOLL_CONFDIR variable or accept a + confdir option + to specify a non-default configuration directory. + + If the recoll program finds no index + when it starts, it will automatically start indexing (except + if canceled). + + The recollindex indexing process can be + interrupted by sending an interrupt (Ctrl-C, + SIGINT) or terminate + (SIGTERM) signal. Some time may elapse before the process exits, + because it needs to properly flush and close the index. This can + also be done from the recoll GUI + + File + Stop Indexing + + menu entry. + + After such an interruption, the index will be somewhat + inconsistent because some operations which are normally + performed at the end of the indexing pass will have been + skipped (for example, the stemming and spelling databases + will be inexistant or out of date). You just need to restart + indexing at a later time to restore consistency. The + indexing will restart at the interruption point (the full + file tree will be traversed, but files that were indexed up + to the interruption and for which the index is still up to + date will not need to be reindexed). + + recollindex has a number of other options + which are described in its man page. Only a few will be + described here. + Option will reset the index when + starting. This is almost the same as destroying the index + files (the nuance is that the &XAP; format version will not + be changed). + Option will force the update of all + documents without resetting the index first. This will not + have the "clean start" aspect of , but + the advantage is that the index will remain available for + querying while it is rebuilt, which can be a significant + advantage if it is very big (some installations need days + for a full index rebuild). + + Option will force retrying files + which previously failed to be indexed, for example because + of a missing helper program. + + Of special interest also, maybe, are + the and + options. allows indexing an explicit + list of files (given as command line parameters or read on + stdin). tells + recollindex to ignore file selection + parameters from the configuration. Together, these options + allow building a custom file selection process for some area + of the file system, by adding the top directory to the + skippedPaths list and using an + appropriate file selection method to build the file list to + be fed to recollindex + . Trivial example: + + + find . -name indexable.txt -print | recollindex -if + + + recollindex will + not descend into subdirectories specified as parameters, + but just add them as index entries. It is + up to the external file selection method to build the complete + file list. + + + + Using <command>cron</command> to automate + indexing + + The most common way to set up indexing is to have a cron + task execute it every night. For example the following + crontab entry would do it every day at + 3:30AM (supposing recollindex is in your + PATH): + + /some/tmp/dir/recolltrace 2>&1 +]]> + + Or, using anacron: + /tmp/rcltraceme 2>&1" +]]> + + + As of version 1.17 the &RCL; GUI has dialogs to manage + crontab entries for + recollindex. You can reach them from the + + Preferences + Indexing Schedule + + menu. They only + work with the good old cron, and do not give + access to all features of cron scheduling. + + The usual command to edit your + crontab is crontab + (which will usually start the + vi editor to edit the file). You may have + more sophisticated tools available on your system. + + Please be aware that there may be differences between your + usual interactive command line environment and the one seen by + crontab commands. Especially the PATH variable may be of + concern. Please check the crontab manual pages about possible + issues. + + + + + + + Real time indexing + + Real time monitoring/indexing is performed by starting the + recollindex command. + With this option, recollindex will detach + from the terminal and become a daemon, permanently monitoring + file changes and updating the index. + + Under KDE, + Gnome and some other desktop + environments, the daemon can automatically started when you log + in, by creating a desktop file inside the + ~/.config/autostart directory. This can be + done for you by the &RCL; GUI. Use the + Preferences->Indexing Schedule menu. + + With older X11 setups, starting + the daemon is normally performed as part of the user session + script. + + The rclmon.sh script can be used to + easily start and stop the daemon. It can be found in the + examples directory (typically + /usr/local/[share/]recoll/examples). + + For example, my out of fashion + xdm-based session has a + .xsession script with the following lines + at the end: + + recollconf=$HOME/.recoll-home +recolldata=/usr/local/share/recoll +RECOLL_CONFDIR=$recollconf $recolldata/examples/rclmon.sh start + +fvwm + + + + The indexing daemon gets started, then the window manager, + for which the session waits. By default the + indexing daemon will monitor the state of the X11 session, and + exit when it finishes, it is not necessary to kill it + explicitly. (The X11 server + monitoring can be disabled with option to + recollindex). + + If you use the daemon completely out of an + X11 session, you need to add option + to disable X11 + session monitoring (else the daemon will not start). + + By default, the messages from the indexing daemon will be + setn to the same file as those from the interactive commands + (logfilename). You may want to change this + by setting the daemlogfilename and + daemloglevel configuration parameters. Also + the log file will only be truncated when the daemon starts. If + the daemon runs permanently, the log file may grow quite big, + depending on the log level. + + When building &RCL;, the real time indexing support can be + customised during package configuration with + the or + options. The default is + currently to include inotify + monitoring on systems that support it, and, as of &RCL; 1.17, + gamin support on + FreeBSD. + + While it is convenient that data is indexed in real time, + repeated indexing can generate a significant load on the + system when files such as email folders change. Also, + monitoring large file trees by itself significantly taxes + system resources. You probably do not want to enable it if + your system is short on resources. Periodic indexing is + adequate in most cases. + + Increasing resources for inotify + On Linux systems, monitoring a big tree may need + increasing the resources available to inotify, which are + normally defined in /etc/sysctl.conf. + +### inotify +# +# cat /proc/sys/fs/inotify/max_queued_events - 16384 +# cat /proc/sys/fs/inotify/max_user_instances - 128 +# cat /proc/sys/fs/inotify/max_user_watches - 16384 +# +# -- Change to: +# +fs.inotify.max_queued_events=32768 +fs.inotify.max_user_instances=256 +fs.inotify.max_user_watches=32768 + + + + Especially, you will need to trim your tree or adjust + the max_user_watches value if indexing exits with + a message about errno ENOSPC (28) from + inotify_add_watch. + + + + Slowing down the reindexing rate for fast changing + files + + When using the real time monitor, it may happen that some + files need to be indexed, but change so often that they impose an + excessive load for the system. + + &RCL; provides a configuration option to specify the minimum + time before which a file, specified by a wildcard pattern, cannot be + reindexed. See the mondelaypatterns parameter in + the + configuration section. + + + + + + + + Searching + + + Searching with the Qt graphical user interface + + The recoll program provides the main user + interface for searching. It is based on the + Qt library. + + recoll has two search modes: + + Simple search (the default, on the main screen) has + a single entry field where you can enter multiple words. + + Advanced search (a panel accessed through the + Tools menu or the toolbox bar icon) has + multiple entry fields, which you may use to build a logical + condition, with additional filtering on file type, location + in the file system, modification date, and size. + + + + In most cases, you can enter the terms as you + think them, even if they contain embedded punctuation or other + non-textual characters. For + example, &RCL; can handle things like email addresses, or + arbitrary cut and paste from another text window, punctation + and all. + + The main case where you should enter text differently from + how it is printed is for east-asian languages (Chinese, + Japanese, Korean). Words composed of single or multiple + characters should be entered separated by white space in this + case (they would typically be printed without white + space). + + Some searches can be quite complex, and you may want to + re-use them later, perhaps with some tweaking. &RCL; versions + 1.21 and later can save and restore searches, using XML files. See + Saving and restoring + queries. + + + Simple search + + + Start the recoll program. + + Possibly choose a search mode: Any + term, All terms, + File name or + Query language. + + Enter search term(s) in the text field at the top of the + window. + + Click the Search button or + hit the Enter key to start the search. + + + + The initial default search mode is Query + language. Without special directives, this will look for + documents containing all of the search terms (the ones with more + terms will get better scores), just like the All + terms mode which will ignore such + directives. Any term will search for documents + where at least one of the terms appear. + + The Query Language features are + described in a separate + section. + + All search modes allow wildcards inside terms + (*, ?, + []). You may want to have a look at the + section about wildcards + for more information about this. + + File name will specifically look for file + names. The point of having a separate file name + search is that wild card expansion can be performed more + efficiently on a small subset of the index (allowing + wild cards on the left of terms without excessive penality). + Things to know: + + White space in the entry should match white + space in the file name, and is not treated specially. + + The search is insensitive to character case and + accents, independantly of the type of index. + + An entry without any wild card + character and not capitalized will be prepended and appended + with '*' (ie: etc -> + *etc*, but + Etc -> + etc). + + If you have a big index (many files), + excessively generic fragments may result in inefficient + searches. + + + + + You can search for exact phrases (adjacent words in a + given order) by enclosing the input inside double quotes. Ex: + "virtual reality". + + When using a stripped index, character case has no influence on + search, except that you can disable stem expansion for any term by + capitalizing it. Ie: a search for floor will also + normally look for flooring, + floored, etc., but a search for + Floor will only look for floor, + in any character case. Stemming can also be disabled globally in the + preferences. When using a raw index, the rules are a bit more + complicated. + + &RCL; remembers the last few searches that you + performed. You can use the simple search text entry widget (a + combobox) to recall them (click on the thing at the right of the + text field). Please note, however, that only the search texts + are remembered, not the mode (all/any/file name). + + Typing Esc Space while + entering a word in the simple search entry will open a window + with possible completions for the word. The completions are + extracted from the database. + + Double-clicking on a word in the result list or a preview + window will insert it into the simple search entry field. + + You can cut and paste any text into an All + terms or Any term search field, + punctuation, newlines and all - except for wildcard characters + (single ? characters are ok). &RCL; will process + it and produce a meaningful search. This is what most differentiates + this mode from the Query Language mode, where + you have to care about the syntax. + + You can use the + + Tools + Advanced search + + dialog for more complex searches. + + + + + The default result list + + After starting a search, a list of results will instantly + be displayed in the main list window. + + By default, the document list is presented in order of + relevance (how well the system estimates that the document + matches the query). You can sort the result by ascending or + descending date by using the vertical arrows in the toolbar. + + Clicking on the + Preview link for an entry will open an + internal preview window for the document. Further + Preview clicks for the same search will open + tabs in the existing preview window. You can use + Shift+Click to force the creation of another + preview window, which may be useful to view the documents side + by side. (You can also browse successive results in a single + preview window by typing + Shift+ArrowUp/Down in the + window). + + Clicking the Open link will + start an external viewer for the document. By default, &RCL; lets + the desktop choose the appropriate application for most document + types (there is a short list of exceptions, see further). If you + prefer to completely customize the choice of applications, you can + uncheck the Use desktop preferences option in + the GUI preferences dialog, and click the Choose editor + applications button to adjust the predefined &RCL; + choices. The tool accepts multiple selections of MIME types (e.g. to + set up the editor for the dozens of office file types). + + Even when Use desktop preferences is + checked, there is a small list of exceptions, for MIME types where + the &RCL; choice should override the desktop one. These are + applications which are well integrated with &RCL;, especially + evince for viewing PDF and Postscript + files because of its support for opening the document at a specific + page and passing a search string as an argument. Of course, you can + edit the list (in the GUI preferences) if you would prefer to lose + the functionality and use the standard desktop tool. + + You may also change the choice of applications by editing the + + mimeview configuration file if you find + this more convenient. + + Each result entry also has a right-click menu with an + Open With entry. This lets you choose an + application from the list of those which registered with the desktop + for the document MIME type. + + The Preview and Open + edit links may not be present for all entries, meaning that + &RCL; has no configured way to preview a given file type (which + was indexed by name only), or no configured external editor for + the file type. This can sometimes be adjusted simply by tweaking + the + mimemap and + + mimeview configuration files (the latter + can be modified with the user preferences dialog). + + The format of the result list entries is entirely + configurable by using the preference dialog to + edit an HTML + fragment. + + You can click on the Query details link + at the top of the results page to see the query actually + performed, after stem expansion and other processing. + + Double-clicking on any word inside the result list or a + preview window will insert it into the simple search text. + + The result list is divided into pages (the size of which + you can change in the preferences). Use the arrow buttons in the + toolbar or the links at the bottom of the page to browse the + results. + + + No results: the spelling suggestions + + When a search yields no result, and if the + aspell dictionary is configured, &RCL; + will try to check for misspellings among the query terms, and + will propose lists of replacements. Clicking on one of the + suggestions will replace the word and restart the search. You can + hold any of the modifier keys (Ctrl, Shift, etc.) while clicking + if you would rather stay on the suggestion screen because several + terms need replacement. + + + + + + The result list right-click menu + + Apart from the preview and edit links, you can display a + pop-up menu by right-clicking over a paragraph in the result + list. This menu has the following entries: + + + Preview + Open + Open With + Run Script + Copy File Name + Copy Url + Save to File + Find similar + Preview Parent + document + Open Parent + document + Open Snippets + Window + + + The Preview and + Open entries do the same thing as the + corresponding links. + + Open With lets you open the document + with one of the applications claiming to be able to handle its MIME + type (the information comes from the .desktop + files in + /usr/share/applications). + + Run Script allows starting an arbitrary + command on the result file. It will only appear for results which + are top-level files. See further for a more + detailed description. + + The Copy File Name and + Copy Url copy the relevant data to the + clipboard, for later pasting. + + Save to File allows saving the + contents of a result document to a chosen file. This entry + will only appear if the document does not correspond to an + existing file, but is a subdocument inside such a file (ie: an + email attachment). It is especially useful to extract attachments + with no associated editor. + + The Open/Preview Parent document entries + allow working with the higher level document (e.g. the email + message an attachment comes from). &RCL; is sometimes not totally + accurate as to what it can or can't do in this area. For example + the Parent entry will also appear for an + email which is part of an mbox folder file, but you can't actually + visualize the mbox (there will be an error dialog if you + try). + + If the document is a top-level file, Open + Parent will start the default file manager on the + enclosing filesystem directory. + + The Find similar entry will select + a number of relevant term from the current document and enter + them into the simple search field. You can then start a simple + search, with a good chance of finding documents related to the + current result. I can't remember a single instance where this + function was actually useful to me... + + The Open Snippets Window entry will only + appear for documents which support page breaks (typically + PDF, Postscript, DVI). The snippets window lists extracts from + the document, taken around search terms occurrences, along with the + corresponding page number, as links which can be used to start + the native viewer on the appropriate page. If the viewer supports + it, its search function will also be primed with one of the + search terms. + + + + + + + The result table + + In &RCL; 1.15 and newer, the results can be displayed in + spreadsheet-like fashion. You can switch to this presentation by + clicking the table-like icon in the toolbar (this is a toggle, + click again to restore the list). + + Clicking on the column headers will allow sorting by the + values in the column. You can click again to invert the order, and + use the header right-click menu to reset sorting to the default + relevance order (you can also use the sort-by-date arrows to do + this). + + Both the list and the table display the same underlying + results. The sort order set from the table is still active if you + switch back to the list mode. You can click twice on a date sort + arrow to reset it from there. + + The header right-click menu allows adding or deleting + columns. The columns can be resized, and their order can be changed + (by dragging). All the changes are recorded when you quit + recoll + + Hovering over a table row will update the detail area at the + bottom of the window with the corresponding values. You can click + the row to freeze the display. The bottom area is equivalent to a + result list paragraph, with links for starting a preview or a + native application, and an equivalent right-click menu. Typing + Esc (the Escape key) will unfreeze the + display. + + + + + Running arbitrary commands on result files (1.20 and later) + + Apart from the Open and Open + With operations, which allow starting an application on a + result document (or a temporary copy), based on its MIME type, it is + also possible to run arbitrary commands on results which are + top-level files, using the Run Script entry in + the results pop-up menu. + + The commands which will appear in the Run + Script submenu must be defined by + .desktop files inside the + scripts subdirectory of the current + configuration directory. + + Here follows an example of a .desktop file, + which could be named for example, + ~/.recoll/scripts/myscript.desktop (the exact + file name inside the directory is irrelevant): + +[Desktop Entry] +Type=Application +Name=MyFirstScript +Exec=/home/me/bin/tryscript %F +MimeType=*/* + + The Name attribute defines the label which will + appear inside the Run Script menu. The + Exec attribute defines the program to be run, + which does not need to actually be a script, of course. The + MimeType attribute is not used, but needs to exist. + + + The commands defined this way can also be used from links + inside the + result paragraph. + + As an example, it might make sense to write a script which + would move the document to the trash and purge it from the &RCL; + index. + + + + + Displaying thumbnails + + The default format for the result list entries and the + detail area of the result table display an icon for each result + document. The icon is either a generic one determined from the + MIME type, or a thumbnail of the document appearance. Thumbnails + are only displayed if found in the standard + freedesktop location, where they would + typically have been created by a file manager. + + Recoll has no capability to create thumbnails. A relatively + simple trick is to use the Open parent + document/folder entry in the result list popup + menu. This should open a file manager window on the containing + directory, which should in turn create the thumbnails (depending on + your settings). Restarting the search should then display the + thumbnails. + + There are also some + pointers about thumbnail generation on the &RCL; wiki. + + + + + + The preview window + + The preview window opens when you first click a + Preview link inside the result list. + + Subsequent preview requests for a given search open new + tabs in the existing window (except if you hold the + Shift key while clicking which will open a new + window for side by side viewing). + + Starting another search and requesting a preview will + create a new preview window. The old one stays open until you + close it. + + You can close a preview tab by typing Ctrl-W + (Ctrl + W) in the + window. Closing the last tab for a window will also close the + window. + + Of course you can also close a preview window by using the + window manager button in the top of the frame. + + You can display successive or previous documents from the + result list inside a preview tab by typing + Shift+Down or + Shift+Up (Down + and Up are the arrow keys). + + A right-click menu in the text area allows switching + between displaying the main text or the contents of fields + associated to the document (ie: author, abtract, etc.). This is + especially useful in cases where the term match did not occur in + the main text but in one of the fields. In the case of + images, you can switch between three displays: the image + itself, the image metadata as extracted + by exiftool and the fields, which is the + metadata stored in the index. + + + You can print the current preview window contents by typing + Ctrl-P (Ctrl + + P) in the window text. + + + + Searching inside the preview + + The preview window has an internal search capability, + mostly controlled by the panel at the bottom of the window, + which works in two modes: as a classical editor incremental + search, where we look for the text entered in the entry + zone, or as a way to walk the matches between the document + and the &RCL; query that found it. + + + + Incremental text search + The preview tabs have an internal incremental search + function. You initiate the search either by typing a + / (slash) or CTL-F + inside the text area or by clicking into + the Search for: text field and + entering the search string. You can then use the + Next + and Previous buttons + to find the next/previous occurrence. You can also type + F3 inside the text area to get to the next + occurrence. + If you have a search string entered and you use + Ctrl-Up/Ctrl-Down to browse the results, the search is + initiated for each successive document. If the string is + found, the cursor will be positioned at the first + occurrence of the search string. + + + + + Walking the match lists + If the entry area is empty when you click + the Next + or Previous buttons, the editor will + be scrolled to show the next match to any search term + (the next highlighted zone). If you select a search group + from the dropdown list and click Next + or Previous, the match list for this + group will be walked. This is not the same as a text + search, because the occurences will include non-exact + matches (as caused by stemming or wildcards). The search + will revert to the text mode as soon as you edit the + entry area. + + + + + + + + + + The Query Fragments window + + Selecting the Tools + Query Fragments menu + entry will open a window with radio- and check-buttons which + can be used to activate query language fragments for + filtering the current query. This can be useful if you have + frequent reusable selectors, for example, filtering on + alternate directories, or searching just one category of + files, not covered by the standard category + selectors. + + The contents of the window are entirely customizable, and + defined by the contents of the fragbuts.xml + file inside the configuration directory. The sample file + distributed with &RCL; (which you should be able to find under + /usr/share/recoll/examples/fragbuts.xml), + contains an example which filters the results from the WEB + history. + + Here follows an example: + +<?xml version="1.0" encoding="UTF-8"?> + +<fragbuts version="1.0"> + + <radiobuttons> + + <fragbut> + <label>Include Web Results</label> + <frag></frag> + </fragbut> + + <fragbut> + <label>Exclude Web Results</label> + <frag>-rclbes:BGL</frag> + </fragbut> + + <fragbut> + <label>Only Web Results</label> + <frag>rclbes:BGL</frag> + </fragbut> + + </radiobuttons> + + <buttons> + + <fragbut> + <label>Year 2010</label> + <frag>date:2010-01-01/2010-12-31</frag> + </fragbut> + + <fragbut> + <label>My Great Directory Only</label> + <frag>dir:/my/great/directory</frag> + </fragbut> + + </buttons> +</fragbuts> + + + + Each radiobuttons or + buttons section defines a line of + checkbuttons or radiobuttons inside the window. Any number of + buttons can be selected, but the radiobuttons in a line are + exclusive. + + Each fragbut section defines the label + for a button, and the Query Language fragment which will be + added (as an AND filter) before performing the query if the + button is active. + + This feature is new in &RCL; 1.20, and will probably be + refined depending on user feedback. + + + + + + Complex/advanced search + + The advanced search dialog helps you build more complex queries + without memorizing the search language constructs. It can be opened + through the Tools menu or through the main + toolbar. + + &RCL; keeps a history of searches. See + + Advanced search history. + + The dialog has two tabs: + + + + The first tab lets you specify terms to search + for, and permits specifying multiple clauses which are combined + to build the search. + + + The second tab lets filter the results according + to file size, date of modification, MIME type, or + location. + + + + + Click on the Start Search button in + the advanced search dialog, or type Enter in + any text field to start the search. The button in + the main window always performs a simple search. + + Click on the Show query details link at + the top of the result page to see the query expansion. + + + Avanced search: the "find" tab + + This part of the dialog lets you constructc a query by + combining multiple clauses of different types. Each entry + field is configurable for the following modes: + + + All terms. + + Any term. + + None of the terms. + + Phrase (exact terms in order within an + adjustable window). + + Proximity (terms in any order within an + adjustable window). + + Filename search. + + + + Additional entry fields can be created by clicking the + Add clause button. + + When searching, the non-empty clauses will be + combined either with an AND or an OR conjunction, depending on + the choice made on the left (All clauses or + Any clause). + + Entries of all types except "Phrase" and "Near" accept + a mix of single words and phrases enclosed in double quotes. + Stemming and wildcard expansion will be performed as for simple + search. + + Phrases and Proximity searches + These two clauses work in similar ways, with the + difference that proximity searches do not impose an order on the + words. In both cases, an adjustable number (slack) of non-matched words + may be accepted between the searched ones (use the counter on + the left to adjust this count). For phrases, the default count + is zero (exact match). For proximity it is ten (meaning that two search + terms, would be matched if found within a window of twelve + words). Examples: a phrase search for quick + fox with a slack of 0 will match quick + fox but not quick brown fox. With + a slack of 1 it will match the latter, but not fox + quick. A proximity search for quick + fox with the default slack will match the + latter, and also a fox is a cunning and quick + animal. + + + + + + Avanced search: the "filter" tab + + This part of the dialog has several sections which allow + filtering the results of a search according to a number of + criteria + + + + + The first section allows filtering by dates of last + modification. You can specify both a minimum and a maximum date. The + initial values are set according to the oldest and newest documents + found in the index. + + + + The next section allows filtering the results by + file size. There are two entries for minimum and maximum + size. Enter decimal numbers. You can use suffix multipliers: + k/K, m/M, + g/G, t/T for 1E3, 1E6, + 1E9, 1E12 respectively. + + + + The next section allows filtering the results by their MIME + types, or MIME categories (ie: media/text/message/etc.). + You can transfer the types between two boxes, to define + which will be included or excluded by the search. + The state of the file type selection can be saved as + the default (the file type filter will not be activated at + program start-up, but the lists will be in the restored + state). + + + + The bottom section allows restricting the search results to a + sub-tree of the indexed area. You can use the + Invert checkbox to search for files not in + the sub-tree instead. If you use directory filtering often and on + big subsets of the file system, you may think of setting up + multiple indexes instead, as the performance may be + better. + You can use relative/partial paths for filtering. Ie, + entering dirA/dirB would match either + /dir1/dirA/dirB/myfile1 or + /dir2/dirA/dirB/someother/myfile2. + + + + + + + + Avanced search history + + The advanced search tool memorizes the last 100 searches + performed. You can walk the saved searches by using the up and + down arrow keys while the keyboard focus belongs to the advanced + search dialog. + + The complex search history can be erased, along with the + one for simple search, by selecting the + File + Erase Search History + menu entry. + + + + + + + The term explorer tool + + &RCL; automatically manages the expansion of search terms + to their derivatives (ie: plural/singular, verb + inflections). But there are other cases where the exact search + term is not known. For example, you may not remember the exact + spelling, or only know the beginning of the name. + + The search will only propose replacement terms with + spelling variations when no matching document were found. In some + cases, both proper spellings and mispellings are present in the + index, and it may be interesting to look for them explicitely. + + The term explorer tool (started from the toolbar icon or + from the Term explorer entry of the + Tools menu) can be used to search the full index + terms list. It has three modes of operations: + + + + Wildcard + In this mode of operation, you can enter a + search string with shell-like wildcards (*, ?, []). ie: + xapi* would display all index terms + beginning with xapi. (More + about wildcards here). + + + + Regular expression + This mode will accept a regular expression + as input. Example: + word[0-9]+. The expression is + implicitely anchored at the beginning. Ie: + press will match + pression but not + expression. You can use + .*press to match the latter, + but be aware that this will cause a full index term list + scan, which can be quite long. + + + + + Stem expansion + This mode will perform the usual stem expansion + normally done as part user input processing. As such it is + probably mostly useful to demonstrate the process. + + + + + Spelling/Phonetic In this + mode, you enter the term as you think it is spelled, and + &RCL; will do its best to find index terms that sound like + your entry. This mode uses the + Aspell spelling application, + which must be installed on your system for things to work + (if your documents contain non-ascii characters, &RCL; + needs an aspell version newer than 0.60 for UTF-8 + support). The language which is used to build the + dictionary out of the index terms (which is done at the + end of an indexing pass) is the one defined by your NLS + environment. Weird things will probably happen if + languages are mixed up. + + + + Note that in cases where &RCL; does not know the beginning + of the string to search for (ie a wildcard expression like + *coll), the expansion can take quite + a long time because the full index term list will have to be + processed. The expansion is currently limited at 10000 results for + wildcards and regular expressions. It is possible to change the + limit in the configuration file. + + Double-clicking on a term in the result list will insert + it into the simple search entry field. You can also cut/paste + between the result list and any entry field (the end of lines + will be taken care of). + + + + + Multiple indexes + + See the section + describing the use of multiple indexes for + generalities. Only the aspects concerning + the recoll GUI are described here. + + A recoll program instance is always + associated with a specific index, which is the one to be updated + when requested from the File menu, but it can + use any number of &RCL; indexes for searching. The external + indexes can be selected through the external + indexes tab in the preferences dialog. + + Index selection is performed in two phases. A set of all + usable indexes must first be defined, and then the subset of + indexes to be used for searching. These parameters + are retained across program executions (there are kept + separately for each &RCL; configuration). The set of all indexes + is usually quite stable, while the active ones might typically + be adjusted quite frequently. + + The main index (defined by + RECOLL_CONFDIR) is always active. If this is + undesirable, you can set up your base configuration to index + an empty directory. + + When adding a new index to the set, you can select either + a &RCL; configuration directory, or directly a &XAP; index + directory. In the first case, the &XAP; index directory will + be obtained from the selected configuration. + + As building the set of all indexes can be a little tedious + when done through the user interface, you can use the + RECOLL_EXTRA_DBS environment + variable to provide an initial set. This might typically be + set up by a system administrator so that every user does not + have to do it. The variable should define a colon-separated list + of index directories, ie: + + export RECOLL_EXTRA_DBS=/some/place/xapiandb:/some/other/db + + Another environment variable, + RECOLL_ACTIVE_EXTRA_DBS allows adding to the active + list of indexes. This variable was suggested and implemented by a + &RCL; user. It is mostly useful if you use scripts to mount + external volumes with &RCL; indexes. By using + RECOLL_EXTRA_DBS and + RECOLL_ACTIVE_EXTRA_DBS, you can add and activate + the index for the mounted volume when starting + recoll. + + + RECOLL_ACTIVE_EXTRA_DBS is available for + &RCL; versions 1.17.2 and later. A change was made in the same + update so that recoll will + automatically deactivate unreachable indexes when starting + up. + + + + + Document history + + Documents that you actually view (with the internal preview + or an external tool) are entered into the document history, + which is remembered. + You can display the history list by using + the Tools/Doc History menu + entry. + You can erase the document history by using the + Erase document history entry in the + File menu. + + + + + Sorting search results and collapsing duplicates + + The documents in a result list are normally sorted in + order of relevance. It is possible to specify a different sort + order, either by using the vertical arrows in the GUI toolbox to + sort by date, or switching to the result table display and clicking + on any header. The sort order chosen inside the result table + remains active if you switch back to the result list, until you + click one of the vertical arrows, until both are unchecked (you are + back to sort by relevance). + + Sort parameters are remembered between program + invocations, but result sorting is normally always inactive + when the program starts. It is possible to keep the sorting + activation state between program invocations by checking the + Remember sort activation state option in + the preferences. + + It is also possible to hide duplicate entries inside + the result list (documents with the exact same contents as the + displayed one). The test of identity is based on an MD5 hash + of the document container, not only of the text contents (so + that ie, a text document with an image added will not be a + duplicate of the text only). Duplicates hiding is controlled + by an entry in the GUI configuration + dialog, and is off by default. + + As of release 1.19, when a result document does have + undisplayed duplicates, a Dups + link will be shown with the result list entry. Clicking the + link will display the paths (URLs + ipaths) for the duplicate + entries. + + + + + Search tips, shortcuts + + + Terms and search expansion + + Term completion + Typing Esc Space in + the simple search entry field while entering a word will + either complete the current word if its beginning matches a + unique term in the index, or open a window to propose a list + of completions. + + + Picking up new terms from result or preview + text + Double-clicking on a word in the result list or in a + preview window will copy it to the simple search entry field. + + + Wildcards + Wildcards can be used inside search terms in all forms + of searches. + More about wildcards. + + + + Automatic suffixes + Words like odt or ods + can be automatically turned into query language + ext:xxx clauses. This can be enabled in the + Search preferences panel in the GUI. + + + + Disabling stem expansion + Entering a capitalized word in any search field will prevent + stem expansion (no search for + gardening if you enter + Garden instead of + garden). This is the only case where + character case should make a difference for a &RCL; + search. You can also disable stem expansion or change the + stemming language in the preferences. + + + Finding related documents + Selecting the Find similar documents entry + in the result list paragraph right-click menu will select a + set of "interesting" terms from the current result, and insert + them into the simple search entry field. You can then possibly + edit the list and start a search to find documents which may + be apparented to the current result. + + + File names + File names are added as terms during indexing, and you can + specify them as ordinary terms in normal search fields (&RCL; used + to index all directories in the file path as terms. This has been + abandoned as it did not seem really useful). Alternatively, you + can use the specific file name search which will + only look for file names, and may be + faster than the generic search especially when using wildcards. + + + + + + + Working with phrases and proximity + + Phrases and Proximity searches + A phrase can be looked for by enclosing it in double + quotes. Example: "user manual" will look + only for occurrences of user immediately + followed by manual. You can use the + This phrase field of the advanced + search dialog to the same effect. Phrases can be entered along + simple terms in all simple or advanced search entry fields + (except This exact phrase). + + + AutoPhrases + This option can be set in the preferences dialog. If it is + set, a phrase will be automatically built and added to simple + searches when looking for Any terms. This + will not change radically the results, but will give a relevance + boost to the results where the search terms appear as a + phrase. Ie: searching for virtual reality + will still find all documents where either + virtual or reality or + both appear, but those which contain virtual + reality should appear sooner in the list. + + + Phrase searches can strongly slow down a query if most of the + terms in the phrase are common. This is why the + autophrase option is off by default for &RCL; + versions before 1.17. As of version 1.17, + autophrase is on by default, but very common + terms will be removed from the constructed phrase. The removal + threshold can be adjusted from the search preferences. + + Phrases and abbreviations As of + &RCL; version 1.17, dotted abbreviations like + I.B.M. are also automatically indexed as a word + without the dots: IBM. Searching for the word + inside a phrase (ie: "the IBM company") will only + match the dotted abrreviation if you increase the phrase slack (using the + advanced search panel control, or the o query + language modifier). Literal occurences of the word will be matched + normally. + + + + + + Others + + Using fields + You can use the query + language and field specifications + to only search certain parts of documents. This can be + especially helpful with email, for example only searching + emails from a specific originator: + search tips from:helpfulgui + + + + Ajusting the result table columns + When displaying results in table mode, you can use a + right click on the table headers to activate a pop-up menu + which will let you adjust what columns are displayed. You can + drag the column headers to adjust their order. You can click + them to sort by the field displayed in the column. You can + also save the result list in CSV format. + + + + Changing the GUI geometry + It is possible to configure the GUI in wide form + factor by dragging the toolbars to one of the sides (their + location is remembered between sessions), and moving the + category filters to a menu (can be set in the + + Preferences + GUI configuration + User interface + panel). + + + Query explanation + You can get an exact description of what the query + looked for, including stem expansion, and Boolean operators + used, by clicking on the result list header. + + + Advanced search history + As of &RCL; 1.18, you can display any of the last 100 complex + searches performed by using the up and down arrow keys while the + advanced search panel is active. + + + Browsing the result list inside a preview + window + Entering Shift-Down or Shift-Up + (Shift + an arrow key) in a preview window will + display the next or the previous document from the result + list. Any secondary search currently active will be executed on + the new document. + + + Scrolling the result list from the keyboard + You can use PageUp and PageDown + to scroll the result list, Shift+Home to go back + to the first page. These work even while the focus is in the + search entry. + + + Result table: moving the focus to the table + You can use Ctrl-r to move the focus + from the search entry to the table, and then use the arrow keys + to change the current row. Ctrl-Shift-s returns to + the search. + + + Result table: open / preview + With the focus in the result table, you can use + Ctrl-o to open the document from the current + row, Ctrl-Shift-o to open the document and close + recoll, Ctrl-d to preview + the document. + + + Editing a new search while the focus is not + in the search entry + You can use the Ctrl-Shift-S shortcut to + return the cursor to the search entry (and select the current + search text), while the focus is anywhere in the main + window. + + + Forced opening of a preview window + You can use Shift+Click on a result list + Preview link to force the creation of a + preview window instead of a new tab in the existing one. + + + Closing previews + Entering Ctrl-W in a tab will + close it (and, for the last tab, close the preview + window). Entering Esc will close the preview + window and all its tabs. + + + Printing previews + Entering Ctrl-P in a preview window will print + the currently displayed text. + + + Quitting + Entering Ctrl-Q almost anywhere will + close the application. + + + + + + Saving and restoring queries (1.21 and later) + + Both simple and advanced query dialogs save recent + history, but the amount is limited: old queries will eventually + be forgotten. Also, important queries may be difficult to find + among others. This is why both types of queries can also be + explicitely saved to files, from the GUI menus: + + File + Save last query / Load last query + + + + The default location for saved queries is a subdirectory + of the current configuration directory, but saved queries are + ordinary files and can be written or moved anywhere. + + Some of the saved query parameters are part of the + preferences (e.g. autophrase or the active + external indexes), and may differ when the query is + loaded from the time it was saved. In this case, &RCL; will warn + of the differences, but will not change the user + preferences. + + + + + Customizing the search interface + + You can customize some aspects of the search interface by using + the GUI configuration entry in the + Preferences menu. + + There are several tabs in the dialog, dealing with the + interface itself, the parameters used for searching and + returning results, and what indexes are searched. + + + + User interface parameters: + + + + Highlight color for query + terms: Terms from the user query are highlighted in + the result list samples and the preview window. The color can + be chosen here. Any Qt color string should work (ie + red, #ff0000). The + default is blue. + + + Style sheet: + The name of a Qt style sheet + text file which is applied to the whole Recoll application + on startup. The default value is empty, but there is a + skeleton style sheet (recoll.qss) + inside the /usr/share/recoll/examples + directory. Using a style sheet, you can change most + recoll graphical parameters: + colors, fonts, etc. See the sample file for a few + simple examples. + You should be aware that parameters (e.g.: the + background color) set inside the &RCL; GUI style sheet + will override global system preferences, with possible + strange side effects: for example if you set the + foreground to a light color and the background to a + dark one in the desktop preferences, but only the + background is set inside the &RCL; style sheet, and it + is light too, then text will appear light-on-light + inside the &RCL; GUI. + + + Maximum text size highlighted for + preview Inserting highlights on search term inside + the text before inserting it in the preview window involves + quite a lot of processing, and can be disabled over the given + text size to speed up loading. + + + Prefer HTML to plain text for + preview if set, Recoll will display HTML as such + inside the preview window. If this causes problems with the Qt + HTML display, you can uncheck it to display the plain text + version instead. + + + Plain text to HTML line style: + when displaying plain text inside the preview window, &RCL; + tries to preserve some of the original text line breaks and + indentation. It can either use PRE HTML tags, which will + well preserve the indentation but will force horizontal + scrolling for long lines, or use BR tags to break at the + original line breaks, which will let the editor introduce + other line breaks according to the window width, but will + lose some of the original indentation. The third option has + been available in recent releases and is probably now the best + one: use PRE tags with line wrapping. + + + Choose editor + applicationsr: this opens a dialog which allows you + to select the application to be used to open each MIME + type. The default is nornally to use the + xdg-open utility, but you can override it. + + + Exceptions: even wen + xdg-open is used by default for opening + documents, you can set exceptions for MIME types that will + still be opened according to &RCL; preferences. This is useful + for passing parameters like page numbers or search strings to + applications that support them + (e.g. evince). This cannot be done + with xdg-open which only supports passing + one parameter. + + + Document filter choice + style: this will let you choose if the document + categories are displayed as a list or a set of buttons, or a + menu. + + + Start with simple search + mode: this lets you choose the value of the simple + search type on program startup. Either a fixed value + (e.g. Query Language, or the value in use + when the program last exited. + + Auto-start simple search on white + space entry: if this is checked, a search will be + executed each time you enter a space in the simple search input + field. This lets you look at the result list as you enter new + terms. This is off by default, you may like it or not... + + + Start with advanced search dialog open + : If you use this dialog frequently, checking + the entries will get it to open when recoll starts. + + + Remember sort activation + state if set, Recoll will remember the sort tool + stat between invocations. It normally starts with sorting + disabled. + + + + + + + + + Result list parameters: + + + + Number of results in a result + page + + + Result list font: There is + quite a lot of information shown in the result list, and you + may want to customize the font and/or font size. The rest of + the fonts used by &RCL; are determined by your generic Qt + config (try the qtconfig command). + + + + Edit result list paragraph format string: + allows you to change the presentation of each result list + entry. See the + result list customisation section. + + + + Edit result page HTML header insert: + allows you to define text inserted at the end of the result + page HTML header. + More detail in the + result list customisation section. + + + + Date format: allows specifying the + format used for displaying dates inside the result list. This + should be specified as an strftime() string (man strftime). + + + + Abstract snippet separator: + for synthetic abstracts built from index data, which are + usually made of several snippets from different parts of the + document, this defines the snippet separator, an ellipsis by + default. + + + + + + + Search parameters: + + + + Hide duplicate results: + decides if result list entries are shown for identical + documents found in different places. + + + Stemming language: + stemming obviously depends on the document's language. This + listbox will let you chose among the stemming databases which + were built during indexing (this is set in the main configuration + file), or later added with recollindex + -s (See the recollindex manual). Stemming languages + which are dynamically added will be deleted at the next + indexing pass unless they are also added in the configuration + file. + + + Automatically add phrase to simple + searches: a phrase will be automatically built and + added to simple searches when looking for Any + terms. This will give a relevance boost to the + results where the search terms appear as a phrase (consecutive + and in order). + + + Autophrase term frequency threshold + percentage: very frequent terms should not be included + in automatic phrase searches for performance reasons. The + parameter defines the cutoff percentage (percentage of the + documents where the term appears). + + + Replace abstracts from + documents: this decides if we should synthesize and + display an abstract in place of an explicit abstract found + within the document itself. + + + Dynamically build + abstracts: this decides if &RCL; tries to build + document abstracts (lists of snippets) + when displaying the result list. Abstracts are constructed by + taking context from the document information, around the search + terms. + + + Synthetic abstract size: + adjust to taste... + + + Synthetic abstract context + words: how many words should be displayed around + each term occurrence. + + + Query language magic file name + suffixes: a list of words which automatically get + turned into ext:xxx file name suffix clauses + when starting a query language query (ie: doc xls + xlsx...). This will save some typing for people who + use file types a lot when querying. + + + + + + + External indexes: + This panel will let you browse for additional indexes + that you may want to search. External indexes are designated by + their database directory (ie: + /home/someothergui/.recoll/xapiandb, + /usr/local/recollglobal/xapiandb). + + + Once entered, the indexes will appear in the + External indexes list, and you can + chose which ones you want to use at any moment by checking or + unchecking their entries. + + Your main database (the one the current configuration + indexes to), is always implicitly active. If this is not + desirable, you can set up your configuration so that it indexes, + for example, an empty directory. An alternative indexer may also + need to implement a way of purging the index from stale data, + + + + The result list format + + Newer versions of Recoll (from 1.17) normally use WebKit HTML + widgets for the result list and the + + snippets window (this may be disabled at build time). + Total customisation is possible with full support for CSS and + Javascript. Conversely, there are limits to what you can do with + the older Qt QTextBrowser, but still, it is possible to decide + what data each result will contain, and how it will be + displayed. + + The result list presentation can be exhaustively customized + by adjusting two elements: + + + The paragraph format + HTML code inside the header section. For + versions 1.21 and later, this is also used for the + + snippets window + + The paragraph format and the header fragment can be edited + from the Result list tab of the + GUI configuration. + + + The header fragment is used both for the result list and + the snippets window. The snippets list is a table and has a + snippets class attribute. Each paragraph in + the result list is a table, with class + respar, but this can be changed by editing + the paragraph format. + + There are a few examples on the + page about + customising the result list on the &RCL; web site. + + + The paragraph format + + This is an arbitrary HTML string where the following printf-like + % substitutions will be performed: + + + + %AAbstract + + %DDate + + %IIcon image + name. This is normally determined from the MIME type. The + associations are defined inside the + + mimeconf configuration file. + If a thumbnail for the file is found at + the standard Freedesktop location, this will be displayed + instead. + + %KKeywords (if + any) + + %LPrecooked Preview, + Edit, and possibly Snippets links + + %MMIME + type + + %Nresult Number inside + the result page + + %PParent folder + Url. In the case of an embedded document, this is the parent folder + for the top level container file. + + %RRelevance + percentage + + %SSize + information + + %TTitle or Filename if + not set. + + %tTitle or Filename if + not set. + + %UUrl + + + + The format of the Preview, Edit, and Snippets links is + <a href="P%N">, + <a href="E%N"> + and + <a href="A%N"> + where docnum (%N) expands to the document + number inside the result page). + + A link target defined as "F%N" will open + the document corresponding to the %P parent + folder expansion, usually creating a file manager window on the + folder where the container file resides. E.g.: + <a href="F%N">%P</a> + + + A link target defined as + R%N|scriptname will + run the corresponding script on the result file (if the document is + embedded, the script will be started on the top-level parent). + See the section about + defining scripts. + + In addition to the predefined values above, all strings + like %(fieldname) will be replaced by the + value of the field named fieldname for this + document. Only stored fields can be accessed in this way, the + value of indexed but not stored fields is not known at this + point in the search process + (see field + configuration). There are currently very few fields + stored by default, apart from the values above + (only author + and filename), so this feature will need + some custom local configuration to be useful. An example + candidate would be the recipient field + which is generated by the message input handlers. + + The default value for the paragraph format string is: + \n" + "\n" + "\n" + "%L  %S   %T
\n" + "%M %D    %U %i
\n" + "%A %K\n" + "\n" +]]>
+ + You may, for example, try the following for a more web-like + experience: + + %T
+%A%U - %S - %L +]]>
+ + Note that the P%N link in the above paragraph makes the title a + preview link. Or the clean looking: + + %L %R +  %T&
%S  +%U + + +
%A
%K +]]>
+
+ + These samples, and some others are + on the web + site, with pictures to show how they look. + + It is also possible to + + define the value of the snippet separator inside the abstract + section. +
+
+
+ +
+ + + Searching with the KDE KIO slave + + + What's this + + The &RCL; KIO slave allows performing a &RCL; search + by entering an appropriate URL in a KDE open dialog, or with an + HTML-based interface displayed in + Konqueror. + + The HTML-based interface is similar to the Qt-based + interface, but slightly less powerful for now. Its advantage is + that you can perform your search while staying fully within the + KDE framework: drag and drop from the result list works normally + and you have your normal choice of applications for opening + files. + + The alternative interface uses a directory view of search + results. Due to limitations in the current KIO slave interface, + it is currently not obviously useful (to me). + + The interface is described in more detail inside a help + file which you can access by entering + recoll:/ inside the + konqueror URL line (this works only if the + recoll KIO slave has been previously installed). + + + The instructions for building this module are located in the + source tree. See: + kde/kio/recoll/00README.txt. Some Linux + distributions do package the kio-recoll module, so check before + diving into the build process, maybe it's already out there ready for + one-click installation. + + + + + Searchable documents + + As a sample application, the &RCL; KIO slave could allow + preparing a set of HTML documents (for example a manual) so that + they become their own search interface inside + konqueror. + + This can be done by either explicitly inserting + ]]> links + around some document areas, or automatically by adding a + very small javascript program to the + documents, like the following example, which would initiate a search by + double-clicking any term: + + <script language="JavaScript"> + function recollsearch() { + var t = document.getSelection(); + window.location.href = 'recoll://search/query?qtp=a&p=0&q=' + + encodeURIComponent(t); + } +</script> + .... +<body ondblclick="recollsearch()"> + + + + + + + + Searching on the command line + + There are several ways to obtain search results as a text + stream, without a graphical interface: + + By passing option to the + recoll program, or by calling it as + recollq (through a link). + + By using the recollq program. + + By writing a custom + Python program, using the + Recoll Python API. + + + + The first two methods work in the same way and accept/need the same + arguments (except for the additional to + recoll). The query to be executed is specified + as command line arguments. + + recollq is not built by default. You can + use the Makefile in the + query directory to build it. This is a very + simple program, and if you can program a little c++, you may find it + useful to taylor its output format to your needs. Not that recollq is + only really useful on systems where the Qt libraries (or even the X11 + ones) are not available. Otherwise, just use recoll + -t, which takes the exact same parameters and options which + are described for recollq + + recollq has a man page (not installed by + default, look in the doc/man directory). The + Usage string is as follows: + +recollq: usage: + -P: Show the date span for all the documents present in the index + [-o|-a|-f] [-q] <query string> + Runs a recoll query and displays result lines. + Default: will interpret the argument(s) as a xesam query string + query may be like: + implicit AND, Exclusion, field spec: t1 -t2 title:t3 + OR has priority: t1 OR t2 t3 OR t4 means (t1 OR t2) AND (t3 OR t4) + Phrase: "t1 t2" (needs additional quoting on cmd line) + -o Emulate the GUI simple search in ANY TERM mode + -a Emulate the GUI simple search in ALL TERMS mode + -f Emulate the GUI simple search in filename mode + -q is just ignored (compatibility with the recoll GUI command line) +Common options: + -c <configdir> : specify config directory, overriding $RECOLL_CONFDIR + -d also dump file contents + -n [first-]<cnt> define the result slice. The default value for [first] + is 0. Without the option, the default max count is 2000. + Use n=0 for no limit + -b : basic. Just output urls, no mime types or titles + -Q : no result lines, just the processed query and result count + -m : dump the whole document meta[] array for each result + -A : output the document abstracts + -S fld : sort by field <fld> + -s stemlang : set stemming language to use (must exist in index...) + Use -s "" to turn off stem expansion + -D : sort descending + -i <dbdir> : additional index, several can be given + -e use url encoding (%xx) for urls + -F <field name list> : output exactly these fields for each result. + The field values are encoded in base64, output in one line and + separated by one space character. This is the recommended format + for use by other programs. Use a normal query with option -m to + see the field names. + + + Sample execution: +recollq 'ilur -nautique mime:text/html' +Recoll query: ((((ilur:(wqf=11) OR ilurs) AND_NOT (nautique:(wqf=11) + OR nautiques OR nautiqu OR nautiquement)) FILTER Ttext/html)) +4 results +text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/comptes.html] [comptes.html] 18593 bytes +text/html [file:///Users/uncrypted-dockes/projets/nautique/webnautique/articles/ilur1/index.html] [Constructio... +text/html [file:///Users/uncrypted-dockes/projets/pagepers/index.html] [psxtcl/writemime/recoll]... +text/html [file:///Users/uncrypted-dockes/projets/bateaux/ilur/factEtCie/recu-chasse-maree.... + + + + + Using Synonyms (1.22) + + Term synonyms: + there are a number of ways to use term synonyms for searching text: + + At index creation time, they can be used to alter the + indexed terms, either increasing or decreasing their number, by + expanding the original terms to all synonyms, or by + reducing all synonym terms to a canonical one. + At query time, they can be used to match texts + containing terms which are synonyms of the ones specified by the user, + either by expanding the query for all synonyms, or by reducing the user + entry to canonical terms (the latter only works if the corresponding + processing has been performed while creating the index). + + + + + &RCL; only uses synonyms at query time. A user query term which + part of a synonym group will be optionally expanded into an + OR query for all terms in the group. + + Synonym groups are defined inside ordinary text files. Each line + in the file defines a group. + + Example: + +hi hello "good morning" + +# not sure about "au revoir" though. Is this english ? +bye goodbye "see you" \ + "au revoir" + + + + As usual, lines beginning with a # are comments, + empty lines are ignored, and lines can be continued by ending them with + a backslash. + + + Multi-word synonyms are supported, but be aware that these will + generate phrase queries, which may degrade performance and will disable + stemming expansion for the phrase terms. + + The synonyms file can be specified in the Search + parameters tab of the GUI configuration + Preferences menu entry, or as an option for + command-line searches. + + Once the file is defined, the use of synonyms can be enabled or + disabled directly from the Preferences + menu. + + The synonyms are searched for matches with user terms after the + latter are stem-expanded, but the contents of the synonyms file itself + is not subjected to stem expansion. This means that a match will not be + found if the form present in the synonyms file is not present anywhere + in the document set. + + The synonyms function is probably not going to help you find your + letters to Mr. Smith. It is best used for domain-specific searches. For + example, it was initially suggested by a user performing searches among + historical documents: the synonyms file would contains nicknames and + aliases for each of the persons of interest. + + + + + + Path translations + + In some cases, the document paths stored inside the index do + not match the actual ones, so that document + previews and accesses will fail. This can occur in a number of + circumstances: + + When using multiple indexes it is a relatively common + occurrence that some will actually reside on a remote volume, for + exemple mounted via NFS. In this case, the paths used to access + the documents on the local machine are not necessarily the same + than the ones used while indexing on the remote machine. For + example, /home/me may have been used as + a topdirs elements while indexing, but the + directory might be mounted + as /net/server/home/me on the local + machine. + + The case may also occur with removable + disks. It is perfectly possible to configure an index to + live with the documents on the removable disk, but it may + happen that the disk is not mounted at the same place so + that the documents paths from the index are + invalid. + + As a last exemple, one could imagine that a big + directory has been moved, but that it is currently + inconvenient to run the indexer. + + + &RCL; has a facility for rewriting access paths when + extracting the data from the index. The translations can be + defined for the main index and for any additional query + index. + + The path translation facility will be useful + whenever the documents paths seen by the indexer are not the same + as the ones which should be used at query time. + + In the above NFS example, &RCL; could be instructed to + rewrite any file:///home/me URL from the + index to file:///net/server/home/me, + allowing accesses from the client. + + The translations are defined in the + + ptrans configuration file, which + can be edited by hand or from the GUI external indexes + configuration dialog: + Preferences + External index dialog + , then click the Paths + translations button on the right below the index + list. + + Due to a current bug, the GUI must be restarted + after changing the ptrans values (even when they + were changed from the GUI). + + + + + + The query language + + The query language processor is activated in the GUI + simple search entry when the search mode selector is set to + Query Language. It can also be used with the KIO + slave or the command line search. It broadly has the same + capabilities as the complex search interface in the + GUI. + + The language was based on the now defunct + + Xesam user search language specification. + + If the results of a query language search puzzle you and you + doubt what has been actually searched for, you can use the GUI + Show Query link at the top of the result list to + check the exact query which was finally executed by Xapian. + + Here follows a sample request that we are going to + explain: + + + author:"john doe" Beatles OR Lennon Live OR Unplugged -potatoes + + + This would search for all documents with + John Doe + appearing as a phrase in the author field (exactly what this is + would depend on the document type, ie: the + From: header, for an email message), + and containing either beatles or + lennon and either + live or + unplugged but not + potatoes (in any part of the document). + + An element is composed of an optional field specification, + and a value, separated by a colon (the field separator is the last + colon in the element). Examples: + Eugenie, + author:balzac, + dc:title:grandet + dc:title:"eugenie grandet" + + + The colon, if present, means "contains". Xesam defines other + relations, which are mostly unsupported for now (except in special + cases, described further down). + + All elements in the search entry are normally combined + with an implicit AND. It is possible to specify that elements be + OR'ed instead, as in Beatles + OR Lennon. The + OR must be entered literally (capitals), and + it has priority over the AND associations: + word1 + word2 OR + word3 + means + word1 AND + (word2 OR + word3) + not + (word1 AND + word2) OR + word3. + + &RCL; versions 1.21 and later, allow using parentheses to + group elements, which will sometimes make things clearer, and may + allow expressing combinations which would have been difficult + otherwise. + + An element preceded by a - specifies a + term that should not appear. + + As usual, words inside quotes define a phrase + (the order of words is significant), so that + title:"prejudice pride" is not the same as + title:prejudice title:pride, and is + unlikely to find a result. + + Words inside phrases and capitalized words are not + stem-expanded. Wildcards may be used anywhere inside a term. + Specifying a wild-card on the left of a term can produce a very + slow search (or even an incorrect one if the expansion is + truncated because of excessive size). Also see + + More about wildcards. + + To save you some typing, recent &RCL; versions (1.20 and later) + interpret a comma-separated list of terms as an AND list inside the + field. Use slash characters ('/') for an OR list. No white space + is allowed. So + author:john,lennon will search for + documents with john and lennon + inside the author field (in any order), and + author:john/ringo would search for + john or ringo. + + Modifiers can be set on a double-quote value, for example to specify + a proximity search (unordered). See + the modifier + section. No space must separate the final + double-quote and the modifiers value, e.g. "two + one"po10 + + &RCL; currently manages the following default fields: + + + + title, + subject or caption are + synonyms which specify data to be searched for in the + document title or subject. + + + author or + from for searching the documents + originators. + + + recipient or + to for searching the documents + recipients. + + + keyword for searching the + document-specified keywords (few documents actually have + any). + + + filename for the document's + file name. This is not necessarily set for all documents: + internal documents contained inside a compound one (for example + an EPUB section) do not inherit the container file name any more, + this was replaced by an explicit field (see next). Sub-documents + can still have a specific filename, if it is + implied by the document format, for example the attachment file + name for an email attachment. + + containerfilename. This is + set for all documents, both top-level and contained + sub-documents, and is always the name of the filesystem directory + entry which contains the data. The terms from this field can + only be matched by an explicit field specification (as opposed + to terms from filename which are also indexed + as general document content). This avoids getting matches for + all the sub-documents when searching for the container file + name. + + ext specifies the file + name extension (Ex: ext:html) + + + + + &RCL; 1.20 and later have a way to specify aliases for the + field names, which will save typing, for example by aliasing + filename to fn or + containerfilename to + cfn. See the section about the + fields file + + The document input handlers used while indexing have the + possibility to create other fields with arbitrary names, and + aliases may be defined in the configuration, so that the exact + field search possibilities may be different for you if someone + took care of the customisation. + + The field syntax also supports a few field-like, but + special, criteria: + + + + dir for filtering the + results on file location + (Ex: dir:/home/me/somedir). + -dir + also works to find results not in the specified directory + (release >= 1.15.8). Tilde expansion will be performed as + usual (except for a bug in versions 1.19 to + 1.19.11p1). Wildcards will be expanded, but + please have a + look at an important limitation of wildcards in + path filters. + + Relative paths also make sense, for example, + dir:share/doc would match either + /usr/share/doc or + /usr/local/share/doc + + Several dir clauses can be specified, + both positive and negative. For example the following makes sense: + +dir:recoll dir:src -dir:utils -dir:common + This would select results which have both + recoll and src in the + path (in any order), and which have not either + utils or + common. + + You can also use OR conjunctions + with dir: clauses. + + A special aspect of dir clauses is + that the values in the index are not transcoded to UTF-8, and + never lower-cased or unaccented, but stored as binary. This means + that you need to enter the values in the exact lower or upper + case, and that searches for names with diacritics may sometimes + be impossible because of character set conversion + issues. Non-ASCII UNIX file paths are an unending source of + trouble and are best avoided. + + You need to use double-quotes around the path value if it + contains space characters. + + + + size for filtering the + results on file size. Example: + size<10000. You can use + <, > or + = as operators. You can specify a range like the + following: size>100 size<1000. The usual + k/K, m/M, g/G, t/T can be used as (decimal) + multipliers. Ex: size>1k to search for files + bigger than 1000 bytes. + + + date for searching or filtering + on dates. The syntax for the argument is based on the ISO8601 + standard for dates and time intervals. Only dates are supported, no + times. The general syntax is 2 elements separated by a + / character. Each element can be a date or a + period of time. Periods are specified as + PnYnMnD. + The n numbers are the respective numbers + of years, months or days, any of which may be missing. Dates are + specified as + YYYY-MM-DD. + The days and months parts may be missing. If the + / is present but an element is missing, the + missing element is interpreted as the lowest or highest date in the + index. Examples: + + + 2001-03-01/2002-05-01 the + basic syntax for an interval of dates. + + 2001-03-01/P1Y2M the + same specified with a period. + + 2001/ from the beginning of + 2001 to the latest date in the index. + + 2001 the whole year of + 2001 + P2D/ means 2 days ago up to + now if there are no documents with dates in the future. + + /2003 all documents from + 2003 or older. + + + Periods can also be specified with small letters (ie: + p2y). + + + mime or + format for specifying the + MIME type. These clauses are processed besides the normal + Boolean logic of the search. Multiple values will be OR'ed + (instead of the normal AND). You can specify types to be + excluded, with the usual -, and use + wildcards. Example: mime:text/* + -mime:text/plain + Specifying an explicit boolean + operator before a mime specification is not + supported and will produce strange results. + + + type or + rclcat for specifying the category (as in + text/media/presentation/etc.). The classification of MIME + types in categories is defined in the &RCL; configuration + (mimeconf), and can be modified or + extended. The default category names are those which permit + filtering results in the main GUI screen. Categories are OR'ed + like MIME types above, and can be negated with + -. + + + + + + mime, rclcat, + size and date criteria + always affect the whole query (they are applied as a final + filter), even if set with other terms inside a parenthese. + + + + mime (or the equivalent + rclcat) is the only + field with an OR default. You do need to use + OR with ext terms for + example. + + + Modifiers + + Some characters are recognized as search modifiers when found + immediately after the closing double quote of a phrase, as in + "some term"modifierchars. The actual "phrase" + can be a single term of course. Supported modifiers: + + + l can be used to turn off + stemming (mostly makes sense with p because + stemming is off by default for phrases). + + + s can be used to turn off + synonym expansion, if a synonyms file is in place (only for + &RCL; 1.22 and later). + + + o can be used to specify a + "slack" for phrase and proximity searches: the number of + additional terms that may be found between the specified + ones. If o is followed by an integer number, + this is the slack, else the default is 10. + + + p can be used to turn the + default phrase search into a proximity one + (unordered). Example: "order any in"p + + + C will turn on case + sensitivity (if the index supports it). + + D will turn on diacritics + sensitivity (if the index supports it). + + A weight can be specified for a query element + by specifying a decimal value at the start of the + modifiers. Example: "Important"2.5. + + + + + + + + + + + + Search case and diacritics sensitivity + + For &RCL; versions 1.18 and later, and when working + with a raw index (not the default), searches can be + sensitive to character case and diacritics. How this happens + is controlled by configuration variables and what search data is + entered. + + The general default is that searches entered without upper-case + or accented characters are insensitive to case and diacritics. An + entry of resume will match any of + Resume, RESUME, + résumé, Résumé etc. + + Two configuration variables can automate switching on + sensitivity (they were documented but actually did nothing until + &RCL; 1.22): + + + + + autodiacsensIf this is set, search + sensitivity to diacritics will be turned on as soon as an + accented character exists in a search term. When the variable + is set to true, resume will start a + diacritics-unsensitive search, but résumé + will be matched exactly. The default value is + false. + + + + autocasesensIf this is set, search + sensitivity to character case will be turned on as soon as an + upper-case character exists in a search term except + for the first one. When the variable is set to + true, us or Us will + start a diacritics-unsensitive search, but + US will be matched exactly. The default + value is true (contrary to + autodiacsens). + + + + + As in the past, capitalizing the first letter of a word will + turn off its stem expansion and have no effect on + case-sensitivity. + + You can also explicitely activate case and diacritics + sensitivity by using modifiers with the query + language. C will make the term case-sensitive, and + D will make it + diacritics-sensitive. Examples: + + "us"C + + + will search for the term us exactly + (Us will not be a match). + + + "resume"D + + will search for the term resume exactly + (résumé will not be a match). + + + When either case or diacritics sensitivity is activated, stem + expansion is turned off. Having both does not make much sense. + + + + + Anchored searches and wildcards + + Some special characters are interpreted by &RCL; in search + strings to expand or specialize the search. Wildcards expand a root + term in controlled ways. Anchor characters can restrict a search to + succeed only if the match is found at or near the beginning of the + document or one of its fields. + + + More about wildcards + + All words entered in &RCL; search fields will be processed + for wildcard expansion before the request is finally + executed. + + The wildcard characters are: + + + * which matches 0 or more + characters. + + ? which matches + a single character. + + [] which allow + defining sets of characters to be matched (ex: + [abc] + matches a single character which may be 'a' or 'b' or 'c', + [0-9] + matches any number. + + + + You should be aware of a few things when using + wildcards. + + + Using a wildcard character at the beginning of + a word can make for a slow search because &RCL; will have to + scan the whole index term list to find the + matches. However, this is much less a problem for field + searches, and queries + like author:*@domain.com can + sometimes be very useful. + + For &RCL; version 18 only, when working with a + raw index (preserving character case and diacritics), the + literal part of a wildcard expression will be matched + exactly for case and diacritics. This is not true any + more for versions 19 and later. + + Using a * at the end of a + word can produce more matches than you would think, and + strange search results. You can use the + term + explorer tool to check what completions exist for + a given term. You can also see exactly what search was + performed by clicking on the link at the top of the result + list. In general, for natural language terms, stem + expansion will produce better results than an + ending * (stem expansion is turned off + when any wildcard character appears in the + term). + + + + Wildcards and path filtering + + Due to the way that &RCL; processes wildcards + inside dir path filtering clauses, they + will have a multiplicative effect on the query size. A clause + containg wildcards in several paths elements, like, for + example, + dir:/home/me/*/*/docdir, + will almost certainly fail if your indexed tree is of any realistic + size. + + Depending on the case, you may be able to work around + the issue by specifying the paths elements more narrowly, with + a constant prefix, or by using 2 + separate dir: clauses instead of multiple + wildcards, as + in dir:/home/me dir:docdir. The + latter query is not equivalent to the initial one because it + does not specify a number of directory levels, but that's + the best we can do (and it may be actually more useful in + some cases). + + + + + + + Anchored searches + + Two characters are used to specify that a search hit should + occur at the beginning or at the end of the + text. ^ at the beginning of a term or phrase + constrains the search to happen at the start, $ + at the end force it to happen at the end. + + As this function is implemented as a phrase search it is + possible to specify a maximum distance at which the hit should + occur, either through the controls of the advanced search panel, or + using the query language, for example, as in: + "^someterm"o10 which would force + someterm to be found within 10 terms of the + start of the text. This can be combined with a field search as in + somefield:"^someterm"o10 or + somefield:someterm$. + + This feature can also be used with an actual phrase search, + but in this case, the distance applies to the whole phrase and + anchor, so that, for example, bla bla my unexpected + term at the beginning of the text would be a match for + "^my term"o5. + + Anchored searches can be very useful for searches inside + somewhat structured documents like scientific articles, in case + explicit metadata has not been supplied (a most frequent case), for + example for looking for matches inside the abstract or the list of + authors (which occur at the top of the document). + + + + + + + + Desktop integration + + Being independant of the desktop type has its drawbacks: &RCL; + desktop integration is minimal. However there are a few tools + available: + + + The KDE KIO Slave was + described in a previous + section. + + + If you use a recent version of Ubuntu Linux, you may + find the Ubuntu Unity + Lens module useful. + + + There is also an independantly developed + + Krunner plugin. + + + + + Here follow a few other things that may help. + + + Hotkeying recoll + + It is surprisingly convenient to be able to show or hide the + &RCL; GUI with a single keystroke. Recoll comes with a small + Python script, based on the libwnck window + manager interface library, which will allow you to do just + this. The detailed instructions are on + this wiki page. + + + + + The KDE Kicker Recoll applet + + This is probably obsolete now. Anyway: + The &RCL; source tree contains the source code to the + recoll_applet, a small application derived + from the find_applet. This can be used to + add a small &RCL; launcher to the KDE panel. + + The applet is not automatically built with the main &RCL; + programs, nor is it included with the main source distribution + (because the KDE build boilerplate makes it relatively big). You can + download its source from the recoll.org download page. Use the + omnipotent configure;make;make install + incantation to build and install. + + You can then add the applet to the panel by right-clicking the + panel and choosing the Add applet entry. + + The recoll_applet has a small text + window where you can type a &RCL; query (in query language form), + and an icon which can be used to restrict the search to certain + types of files. It is quite primitive, and launches a new recoll + GUI instance every time (even if it is already running). You may + find it useful anyway. + + + + + +
+ + + + Programming interface + + &RCL; has an Application Programming Interface, usable both + for indexing and searching, currently accessible from the + Python language. + + Another less radical way to extend the application is to + write input handlers for new types of documents. + + The processing of metadata attributes for documents + (fields) is highly configurable. + + + + + Writing a document input handler + + TerminologyThe small programs or pieces + of code which handle the processing of the different document + types for &RCL; used to be called filters, + which is still reflected in the name of the directory which + holds them and many configuration variables. They were named + this way because one of their primary functions is to filter + out the formatting directives and keep the text + content. However these modules may have other behaviours, and + the term input handler is now progressively + substituted in the documentation. filter is + still used in many places though. + + &RCL; input handlers cooperate to translate from the multitude + of input document formats, simple ones + as opendocument, + acrobat), or compound ones such + as Zip + or Email, into the final &RCL; + indexing input format, which is plain text. + Most input handlers are executable + programs or scripts. A few handlers are coded in C++ and live + inside recollindex. This latter kind will not + be described here. + + There are currently (since version 1.13) two kinds of + external executable input handlers: + + Simple exec handlers + run once and exit. They can be bare programs like + antiword, or scripts using other + programs. They are very simple to write, because they just + need to print the converted document to the standard + output. Their output can be plain text or HTML. HTML is + usually preferred because it can store metadata fields and + it allows preserving some of the formatting for the GUI + preview. + + Multiple execm handlers + can process multiple files (sparing the process startup + time which can be very significant), or multiple documents + per file (e.g.: for zip or + chm files). They communicate + with the indexer through a simple protocol, but are + nevertheless a bit more complicated than the older + kind. Most of new handlers are written in + Python, using a common module + to handle the protocol. There is an exception, + rclimg which is written in Perl. The + subdocuments output by these handlers can be directly + indexable (text or HTML), or they can be other simple or + compound documents that will need to be processed by + another handler. + + + + + In both cases, handlers deal with regular file system + files, and can process either a single document, or a + linear list of documents in each file. &RCL; is responsible + for performing up to date checks, deal with more complex + embedding and other upper level issues. + + A simple handler returning a + document in text/plain format, can transfer + no metadata to the indexer. Generic metadata, like document + size or modification date, will be gathered and stored by + the indexer. + + Handlers that produce text/html + format can return an arbitrary amount of metadata inside HTML + meta tags. These will be processed + according to the directives found in + the + fields configuration + file. + + The handlers that can handle multiple documents per file + return a single piece of data to identify each document inside + the file. This piece of data, called + an ipath element will be sent back by + &RCL; to extract the document at query time, for previewing, + or for creating a temporary file to be opened by a + viewer. + + The following section describes the simple + handlers, and the next one gives a few explanations about + the execm ones. You could conceivably + write a simple handler with only the elements in the + manual. This will not be the case for the other ones, for + which you will have to look at the code. + + + Simple input handlers + + &RCL; simple handlers are usually shell-scripts, but this is in + no way necessary. Extracting the text from the native format is the + difficult part. Outputting the format expected by &RCL; is + trivial. Happily enough, most document formats have translators or + text extractors which can be called from the handler. In some cases + the output of the translating program is completely appropriate, + and no intermediate shell-script is needed. + + Input handlers are called with a single argument which is the + source file name. They should output the result to stdout. + + When writing a handler, you should decide if it will output + plain text or HTML. Plain text is simpler, but you will not be able + to add metadata or vary the output character encoding (this will be + defined in a configuration file). Additionally, some formatting may + be easier to preserve when previewing HTML. Actually the deciding factor + is metadata: &RCL; has a way to + extract metadata from the HTML header and use it for field + searches.. + + The RECOLL_FILTER_FORPREVIEW environment + variable (values yes, no) + tells the handler if the operation is for indexing or + previewing. Some handlers use this to output a slightly different + format, for example stripping uninteresting repeated keywords (ie: + Subject: for email) when indexing. This is not + essential. + + You should look at one of the simple handlers, for example + rclps for a starting point. + + Don't forget to make your handler executable before + testing ! + + + + + "Multiple" handlers + + If you can program and want to write + an execm handler, it should not be too + difficult to make sense of one of the existing modules. There is + a sample one with many comments, not actually used by &RCL;, + which would index a text file as one document per line. Look for + rcltxtlines.py in the + src/filters directory in the &RCL; BitBucket + repository (the sample + not in the distributed release at the moment). + + You can also have a look at the slightly more complex + rclzip which uses Zip + file paths as identifiers (ipath). + + execm handlers sometimes need to make + a choice for the nature of the ipath + elements that they use in communication with the + indexer. Here are a few guidelines: + + Use ASCII or UTF-8 (if the identifier is an + integer print it, for example, like printf %d would + do). + If at all possible, the data should make some + kind of sense when printed to a log file to help with + debugging. + &RCL; uses a colon (:) as a + separator to store a complex path internally (for + deeper embedding). Colons inside + the ipath elements output by a + handler will be escaped, but would be a bad choice as a + handler-specific separator (mostly, again, for + debugging issues). + + In any case, the main goal is that it should + be easy for the handler to extract the target document, given + the file name and the ipath + element. + + execm handlers will also produce + a document with a null ipath + element. Depending on the type of document, this may have + some associated data (e.g. the body of an email message), or + none (typical for an archive file). If it is empty, this + document will be useful anyway for some operations, as the + parent of the actual data documents. + + + + Telling &RCL; about the handler + + There are two elements that link a file to the handler which + should process it: the association of file to MIME type and the + association of a MIME type with a handler. + + The association of files to MIME types is mostly based on + name suffixes. The types are defined inside the + + mimemap file. Example: + + +.doc = application/msword + + If no suffix association is found for the file name, &RCL; will try + to execute a system command (typically file -i or + xdg-mime) to determine a MIME type. + + The second element is the association of MIME types to handlers + in the + mimeconf file. A sample will probably be + better than a long explanation: + + +[index] +application/msword = exec antiword -t -i 1 -m UTF-8;\ + mimetype = text/plain ; charset=utf-8 + +application/ogg = exec rclogg + +text/rtf = exec unrtf --nopict --html; charset=iso-8859-1; mimetype=text/html + +application/x-chm = execm rclchm + + + The fragment specifies that: + + + application/msword files + are processed by executing the antiword + program, which outputs + text/plain encoded in + utf-8. + + + application/ogg files are + processed by the rclogg script, with + default output type (text/html, with + encoding specified in the header, or utf-8 + by default). + + + text/rtf is processed by + unrtf, which outputs + text/html. The + iso-8859-1 encoding is specified because it + is not the utf-8 default, and not output by + unrtf in the HTML header section. + + application/x-chm is processed + by a persistant handler. This is determined by the + execm keyword. + + + + + + + + Input handler HTML output + + The output HTML could be very minimal like the following + example: + +<html> + <head> + <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> + </head> + <body> + Some text content + </body> +</html> + + + + You should take care to escape some + characters inside the text by transforming them into + appropriate entities. At the very minimum, + "&" should be transformed into + "&amp;", "<" + should be transformed into + "&lt;". This is not always properly + done by translating programs which output HTML, and of + course never by those which output plain text. + + When encapsulating plain text in an HTML body, + the display of a preview may be improved by enclosing the + text inside <pre> tags. + + The character set needs to be specified in the + header. It does not need to be UTF-8 (&RCL; will take care + of translating it), but it must be accurate for good + results. + + &RCL; will process meta tags inside + the header as possible document fields candidates. Documents + fields can be processed by the indexer in different ways, + for searching or displaying inside query results. This is + described in a following + section. + + + By default, the indexer will process the standard header + fields if they are present: title, + meta/description, + and meta/keywords are both indexed and stored + for query-time display. + + A predefined non-standard meta tag + will also be processed by &RCL; without further + configuration: if a date tag is present + and has the right format, it will be used as the document + date (for display and sorting), in preference to the file + modification date. The date format should be as follows: + +<meta name="date" content="YYYY-mm-dd HH:MM:SS"> +or +<meta name="date" content="YYYY-mm-ddTHH:MM:SS"> + + Example: + +<meta name="date" content="2013-02-24 17:50:00"> + + + + Input handlers also have the possibility to "invent" field + names. This should also be output as meta tags: + + +<meta name="somefield" content="Some textual data" /> + + + You can embed HTML markup inside the content of custom + fields, for improving the display inside result lists. In this + case, add a (wildly non-standard) markup + attribute to tell &RCL; that the value is HTML and should not + be escaped for display. + + +<meta name="somefield" markup="html" content="Some <i>textual</i> data" /> + + + As written above, the processing of fields is described + in a further + section. + + + + + Page numbers + + The indexer will interpret ^L characters + in the handler output as indicating page breaks, and will record + them. At query time, this allows starting a viewer on the right + page for a hit or a snippet. Currently, only the PDF, Postscript + and DVI handlers generate page breaks. + + + + + + + Field data processing + + Fields are named pieces of information + in or about documents, like title, + author, abstract. + + The field values for documents can appear in several ways + during indexing: either output by input handlers + as meta fields in the HTML header section, or + extracted from file extended attributes, or added as attributes + of the Doc object when using the API, or + again synthetized internally by &RCL;. + + The &RCL; query language allows searching for text in a + specific field. + + &RCL; defines a number of default fields. Additional + ones can be output by handlers, and described in the + fields configuration file. + + Fields can be: + + + indexed, meaning that their + terms are separately stored in inverted lists (with a specific + prefix), and that a field-specific search is possible. + + + stored, meaning that their + value is recorded in the index data record for the document, + and can be returned and displayed with search results. + + + + + A field can be either or both indexed and stored. This and + other aspects of fields handling is defined inside the + fields configuration file. + + The sequence of events for field processing is as follows: + + During indexing, + recollindex scans all meta + fields in HTML documents (most document types are transformed + into HTML at some point). It compares the name for each element + to the configuration defining what should be done with fields + (the fields file) + + If the name for the meta + element matches one for a field that should be indexed, the + contents are processed and the terms are entered into the index + with the prefix defined in the fields + file. + + If the name for the meta element + matches one for a field that should be stored, the content of the + element is stored with the document data record, from which it + can be extracted and displayed at query time. + + At query time, if a field search is performed, the + index prefix is computed and the match is only performed against + appropriately prefixed terms in the index. + + At query time, the field can be displayed inside + the result list by using the appropriate directive in the + definition of the result list paragraph + format. All fields are displayed on the fields screen of + the preview window (which you can reach through the right-click + menu). This is independant of the fact that the search which + produced the results used the field or not. + + + + + You can find more information in the + section about the + fields file, or in comments inside the + file. + + You can also have a look at the + example on the Wiki, + detailing how one could add a page count field + to pdf documents for displaying inside result lists. + + + + + + Python API + + + Introduction + + &RCL; versions after 1.11 define a Python programming + interface, both for searching and creating/updating an + index. + + The search interface is used in the &RCL; Ubuntu Unity Lens + and the &RCL; Web UI. It can run queries on any &RCL; + configuration. + + The index update section of the API may be used to create and + update &RCL; indexes on specific configurations (separate from the + ones created by recollindex). The resulting + databases can be queried alone, or in conjunction with regular + ones, through the GUI or any of the query interfaces. + + The search API is modeled along the Python database API + specification. There were two major changes along &RCL; versions: + + The basis for the &RCL; API changed from Python + database API version 1.0 (&RCL; versions up to 1.18.1), + to version 2.0 (&RCL; 1.18.2 and later). + The recoll module became a + package (with an internal recoll + module) as of &RCL; version 1.19, in order to add more + functions. For existing code, this only changes the way + the interface must be imported. + + + + We will describe the new API and package structure here. A + paragraph at the end of this section will explain a few differences + and ways to write code compatible with both versions. + + The Python interface can be found in the source package, + under python/recoll. + + The python/recoll/ directory + contains the usual setup.py. After + configuring the main &RCL; code, you can use the script to + build and install the Python module: + + cd recoll-xxx/python/recoll + python setup.py build + python setup.py install + + + + As of &RCL; 1.19, the module can be compiled for + Python3. + + The normal &RCL; installer installs the Python2 + API along with the main code. The Python3 version must be + explicitely built and installed. + + When installing from a repository, and depending on the + distribution, the Python API can sometimes be found in a + separate package. + + As an introduction, the following small sample will run a + query and list the title and url for each of the results. It would + work with &RCL; 1.19 and later. The + python/samples source directory contains + several examples of Python programming with &RCL;, exercising the + extension more completely, and especially its data extraction + features. + + + + + + + Interface elements + + A few elements in the interface are specific and and need + an explanation. + + + + > + ipath + + This data value (set as a field in the Doc + object) is stored, along with the URL, but not indexed by + &RCL;. Its contents are not interpreted by the index layer, and + its use is up to the application. For example, the &RCL; file + system indexer uses the ipath to store the + part of the document access path internal to (possibly + imbricated) container documents. ipath in + this case is a vector of access elements (e.g, the first part + could be a path inside a zip file to an archive member which + happens to be an mbox file, the second element would be the + message sequential number inside the mbox + etc.). url and ipath are + returned in every search result and define the access to the + original document. ipath is empty for + top-level document/files (e.g. a PDF document which is a + filesystem file). The &RCL; GUI knows about the structure of the + ipath values used by the filesystem indexer, + and uses it for such functions as opening the parent of a given + document. + + + + + udi + + An udi (unique document + identifier) identifies a document. Because of limitations inside + the index engine, it is restricted in length (to 200 bytes), + which is why a regular URI cannot be used. The structure and + contents of the udi is defined by the + application and opaque to the index engine. For example, the + internal file system indexer uses the complete document path + (file path + internal path), truncated to length, the suppressed + part being replaced by a hash value. The udi + is not explicit in the query interface (it is used "under the + hood" by the rclextract module), but it is + an explicit element of the update interface. + + + + parent_udi + + If this attribute is set on a document when + entering it in the index, it designates its physical container + document. In a multilevel hierarchy, this may not be the + immediate parent. parent_udi is optional, but + its use by an indexer may simplify index maintenance, as &RCL; + will automatically delete all children defined by + parent_udi == udi when the document designated + by udi is destroyed. e.g. if a + Zip archive contains entries which are + themselves containers, like mbox files, all + the subdocuments inside the Zip file (mbox, + messages, message attachments, etc.) would have the same + parent_udi, matching the + udi for the Zip file, and + all would be destroyed when the Zip file + (identified by its udi) is removed from the + index. The standard filesystem indexer uses + parent_udi. + + + + Stored and indexed fields + + The fields file inside + the &RCL; configuration defines which document fields are + either "indexed" (searchable), "stored" (retrievable with + search results), or both. + + + + + + + + + Python search interface + + + Recoll package + + The recoll package contains two + modules: + + The recoll module contains + functions and classes used to query (or update) the + index. This section will only describe the query part, see + further for the update part. + The rclextract module contains + functions and classes used to access document + data. + + + + + + The recoll module + + + Functions + + + + connect(confdir=None, extra_dbs=None, + writable = False) + + The connect() function connects to + one or several &RCL; index(es) and returns + a Db object. + + confdir may specify + a configuration directory. The usual defaults + apply. + extra_dbs is a list of + additional indexes (Xapian directories). + writable decides if + we can index new data through this + connection. + + This call initializes the recoll module, and it should + always be performed before any other call or object + creation. + + + + + + + + Classes + + + The Db class + + A Db object is created by + a connect() call and holds a + connection to a Recoll index. + + + Db.close() + Closes the connection. You can't do anything + with the Db object after + this. + + + Db.query(), Db.cursor() These + aliases return a blank Query object + for this index. + + + + Db.setAbstractParams(maxchars, + contextwords) Set the parameters used + to build snippets (sets of keywords in context text + fragments). maxchars defines the + maximum total size of the abstract. + contextwords defines how many + terms are shown around the keyword. + + + + Db.termMatch(match_type, expr, field='', + maxlen=-1, casesens=False, diacsens=False, lang='english') + + Expand an expression against the + index term list. Performs the basic function from the + GUI term explorer tool. match_type + can be either + of wildcard, regexp + or stem. Returns a list of terms + expanded from the input expression. + + + + + + + + + + The Query class + + A Query object (equivalent to a + cursor in the Python DB API) is created by + a Db.query() call. It is used to + execute index searches. + + + + + Query.sortby(fieldname, ascending=True) + Sort results + by fieldname, in ascending + or descending order. Must be called before executing + the search. + + + + Query.execute(query_string, stemming=1, + stemlang="english") + Starts a search + for query_string, a &RCL; + search language string. + + + + Query.executesd(SearchData) + Starts a search for the query defined by the + SearchData object. + + + + Query.fetchmany(size=query.arraysize) + + Fetches + the next Doc objects in the current + search results, and returns them as an array of the + required size, which is by default the value of + the arraysize data member. + + + + Query.fetchone() + Fetches the next Doc object + from the current search results. + + + + Query.close() + Closes the query. The object is unusable + after the call. + + + + Query.scroll(value, mode='relative') + Adjusts the position in the current result + set. mode can + be relative + or absolute. + + + + Query.getgroups() + Retrieves the expanded query terms as a list + of pairs. Meaningful only after executexx In each + pair, the first entry is a list of user terms (of size + one for simple terms, or more for group and phrase + clauses), the second a list of query terms as derived + from the user terms and used in the Xapian + Query. + + + + Query.getxquery() + Return the Xapian query description as a + Unicode string. + Meaningful only after executexx. + + + + Query.highlight(text, ishtml = 0, methods = object) + Will insert <span "class=rclmatch">, + </span> tags around the match areas in the input text + and return the modified text. ishtml + can be set to indicate that the input text is HTML and + that HTML special characters should not be escaped. + methods if set should be an object + with methods startMatch(i) and endMatch() which will be + called for each match and should return a begin and end + tag + + + + Query.makedocabstract(doc, methods = object)) + Create a snippets abstract + for doc (a Doc + object) by selecting text around the match terms. + If methods is set, will also perform highlighting. See + the highlight method. + + + + + Query.__iter__() and Query.next() + So that things like for doc in + query: will work. + + + + + + Query.arraysize + Default number of records processed by fetchmany + (r/w). + + Query.rowcountNumber + of records returned by the last + execute. + Query.rownumberNext index + to be fetched from results. Normally increments after + each fetchone() call, but can be set/reset before the + call to effect seeking (equivalent to + using scroll()). Starts at + 0. + + + + + + + + + The Doc class + + A Doc object contains index data + for a given document. The data is extracted from the + index when searching, or set by the indexer program when + updating. The Doc object has many attributes to be read or + set by its user. It matches exactly the Rcl::Doc C++ + object. Some of the attributes are predefined, but, + especially when indexing, others can be set, the name of + which will be processed as field names by the indexing + configuration. Inputs can be specified as Unicode or + strings. Outputs are Unicode objects. All dates are + specified as Unix timestamps, printed as strings. Please + refer to the rcldb/rcldoc.h C++ file + for a description of the predefined attributes. + + At query time, only the fields that are defined + as stored either by default or in + the fields configuration file will be + meaningful in the Doc + object. Especially this will not be the case for the + document text. See the rclextract + module for accessing document contents. + + + + + get(key), [] operator + + Retrieve the named doc + attribute. You can also use + getattr(doc, key) or + doc.key. + + + + doc.key = value + + Set the the named doc + attribute. You can also use + setattr(doc, key, value). + + + + getbinurl() + + Retrieve the URL in byte array format (no + transcoding), for use as parameter to a system + call. + + + + setbinurl(url) + + Set the URL in byte array format (no + transcoding). + + + + items() + Return a dictionary of doc object + keys/values + + + + keys() + list of doc object keys (attribute + names). + + + + + + + The SearchData class + + A SearchData object allows building + a query by combining clauses, for execution + by Query.executesd(). It can be used + in replacement of the query language approach. The + interface is going to change a little, so no detailed doc + for now... + + + + + addclause(type='and'|'or'|'excl'|'phrase'|'near'|'sub', + qstring=string, slack=0, field='', stemming=1, + subSearch=SearchData) + + + + + + + + + + + The rclextract module + + Index queries do not provide document content (only a + partial and unprecise reconstruction is performed to show the + snippets text). In order to access the actual document data, + the data extraction part of the indexing process + must be performed (subdocument access and format + translation). This is not trivial in + general. The rclextract module currently + provides a single class which can be used to access the data + content for result documents. + + + Classes + + + The Extractor class + + + + + Extractor(doc) + An Extractor object is + built from a Doc object, output + from a query. + + + Extractor.textextract(ipath) + Extract document defined + by ipath and return + a Doc object. The doc.text field + has the document text converted to either text/plain or + text/html according to doc.mimetype. The typical use + would be as follows: + +qdoc = query.fetchone() +extractor = recoll.Extractor(qdoc) +doc = extractor.textextract(qdoc.ipath) +# use doc.text, e.g. for previewing + + + + + Extractor.idoctofile(ipath, targetmtype, outfile='') + Extracts document into an output file, + which can be given explicitly or will be created as a + temporary file to be deleted by the caller. Typical use: + +qdoc = query.fetchone() +extractor = recoll.Extractor(qdoc) +filename = extractor.idoctofile(qdoc.ipath, qdoc.mimetype) + + + + + + + + + + + + Search API usage example + + The following sample would query the index with a user + language string. See the python/samples + directory inside the &RCL; source for other + examples. The recollgui subdirectory + has a very embryonic GUI which demonstrates the + highlighting and data extraction functions. + + +#!/usr/bin/env python + 5: + nres = 5 +for i in range(nres): + doc = query.fetchone() + print "Result #%d" % (query.rownumber,) + for k in ("title", "size"): + print k, ":", getattr(doc, k).encode('utf-8') + abs = db.makeDocAbstract(doc, query).encode('utf-8') + print abs + print + +]]> + + + + + + + + Creating Python external indexers + + The update API can be used to create an index from data which + is not accessible to the regular &RCL; indexer, or structured to + present difficulties to the &RCL; input handlers. + + An indexer created using this API will be have equivalent work + to do as the the Recoll file system indexer: look for modified + documents, extract their text, call the API for indexing it, take + care of purging the index out of data from documents which do not + exist in the document store any more. + + The data for such an external indexer should be stored in an + index separate from any used by the &RCL; internal file system + indexer. The reason is that the main document indexer purge pass + (removal of deleted documents) would also remove all the documents + belonging to the external indexer, as they were not seen during the + filesystem walk. The main indexer documents would also probably be a + problem for the external indexer own purge operation. + + While there would be ways to enable multiple foreign indexers + to cooperate on a single index, it is just simpler to use separate + ones, and use the multiple index access capabilities of the query + interface, if needed. + + There are two parts in the update interface: + + + Methods inside the recoll + module allow inserting data into the index, to make it accessible by + the normal query interface. + An interface based on scripts execution is defined + to allow either the GUI or the rclextract + module to access original document data for previewing or + editing. + + + + Python update interface + + The update methods are part of the + recoll module described above. The connect() + method is used with a writable=true parameter to + obtain a writable Db object. The following + Db object methods are then available. + + + + + addOrUpdate(udi, doc, parent_udi=None) + Add or update index data for a given document + The + + udi string must define a unique id for + the document. It is an opaque interface element and not + interpreted inside Recoll. doc is a + + + Doc object, created from the data to be + indexed (the main text should be in + doc.text). If + + parent_udi is set, this is a unique + identifier for the top-level container (e.g. for the + filesystem indexer, this would be the one which is an actual + file). + + + + + delete(udi) + Purge index from all data for + udi, and all documents (if any) which have a + matrching parent_udi. + + + + needUpdate(udi, sig) + Test if the index needs to be updated for the + document identified by udi. If this call is + to be used, the doc.sig field should contain + a signature value when calling + addOrUpdate(). The + needUpdate() call then compares its + parameter value with the stored sig for + udi. sig is an opaque + value, compared as a string. + The filesystem indexer uses a + concatenation of the decimal string values for file size and + update time, but a hash of the contents could also be + used. + As a side effect, if the return value is false (the index + is up to date), the call will set the existence flag for the + document (and any subdocument defined by its + parent_udi), so that a later + purge() call will preserve them). + The use of needUpdate() and + purge() is optional, and the indexer may use + another method for checking the need to reindex or to delete + stale entries. + + + + purge() + Delete all documents that were not touched + during the just finished indexing pass (since + open-for-write). These are the documents for the needUpdate() + call was not performed, indicating that they no longer exist in + the primary storage system. + + + + + + + + Query data access for external indexers (1.23) + + &RCL; has internal methods to access document data for its + internal (filesystem) indexer. An external indexer needs to provide + data access methods if it needs integration with the GUI + (e.g. preview function), or support for the + rclextract module. + + The index data and the access method are linked by the + rclbes (recoll backend storage) + Doc field. You should set this to a short string + value identifying your indexer (e.g. the filesystem indexer uses either + "FS" or an empty value, the Web history indexer uses "BGL"). + + The link is actually performed inside a + backends configuration file (stored in the + configuration directory). This defines commands to execute to + access data from the specified indexer. Example, for the mbox + indexing sample found in the Recoll source (which sets + rclbes="MBOX"): + [MBOX] +fetch = /path/to/recoll/src/python/samples/rclmbox.py fetch +makesig = path/to/recoll/src/python/samples/rclmbox.py makesig + + fetch and makesig + define two commands to execute to respectively retrieve the + document text and compute the document signature (the example + implementation uses the same script with different first parameters + to perform both operations). + + The scripts are called with three additional arguments: + udi, url, + ipath, stored with the document when it was + indexed, and may use any or all to perform the requested + operation. The caller expects the result data on + stdout. + + + + + External indexer samples + + The Recoll source tree has two samples of external indexers + in the src/python/samples directory. The more + interesting one is rclmbox.py which indexes a + directory containing mbox folder files. It + exercises most features in the update interface, and has a data + access interface. + + See the comments inside the file for more information. + + + + + Package compatibility with the previous version + + The following code fragments can be used to ensure that + code can run with both the old and the new API (as long as it + does not use the new abilities of the new API of + course). + + Adapting to the new package structure: + + + + + Adapting to the change of nature of + the next Query + member. The same test can be used to choose to use + the scroll() method (new) or set + the next value (old). + + + + + + + + + + + + + + Installation and configuration + + + Installing a binary copy + + + &RCL; binary copies are always distributed as regular + packages for your system. They can be obtained either through + the system's normal software distribution framework (e.g. + Debian/Ubuntu apt, + FreeBSD ports, etc.), or from some type + of "backports" repository providing versions newer than the standard + ones, or found on the &RCL; WEB site in some + cases. The most up-to-date information about Recoll packages can + usually be found on the + + Recoll WEB site downloads + page + + There used to exist another form of binary install, as + pre-compiled source trees, but these are just less convenient than + the packages and don't exist any more. + + The package management tools will usually automatically + deal with hard dependancies for packages obtained from a proper + package repository. You will have to deal with them by hand for + downloaded packages (for example, when dpkg + complains about missing dependancies). + + In all cases, you will have to check or install supporting applications + for the file types that you want to index beyond those that are + natively processed by &RCL; (text, HTML, email files, and a few + others). + + You should also maybe have a look at the + configuration section + (but this may not be necessary for a quick test with default + parameters). Most parameters can be more conveniently set from the + GUI interface. + + + + + Supporting packages + + The &WIN; installation of &RCL; is self-contained, and + only needs Python 2.7 to be externally installed. &WIN; users can + skip this section. + + &RCL; uses external applications to index some file + types. You need to install them for the file types that you wish to + have indexed (these are run-time optional dependencies. None is + needed for building or running &RCL; except for indexing their + specific file type). + + After an indexing pass, the commands that were found + missing can be displayed from the recoll + File menu. The list is stored in the + missing text file inside the configuration + directory. + + A list of common file types which need external + commands follows. Many of the handlers need the + iconv command, which is not always listed as a + dependancy. + + Please note that, due to the relatively dynamic nature of this + information, the most up to date version is now kept on &RCLAPPS; + along with links to the home pages or best source/patches pages, + and misc tips. The list below is not updated often and may be quite + stale. + + For many Linux distributions, most of the commands listed can + be installed from the package repositories. However, the packages + are sometimes outdated, or not the best version for &RCL;, so you + should take a look at &RCLAPPS; if a file + type is important to you. + + As of &RCL; release 1.14, a number of XML-based formats that + were handled by ad hoc handler code now use the + xsltproc command, which usually comes with + libxslt. These are: abiword, fb2 + (ebooks), kword, openoffice, svg. + + Now for the list: + + + Openoffice files need unzip and + xsltproc. + + PDF files need pdftotext + which is part of Poppler (usually + comes with the poppler-utils + package). Avoid the original one from + Xpdf. + + Postscript files need pstotext. + The original version has an issue with shell + character in file names, which is corrected in recent + packages. See &RCLAPPS; for more detail. + + + MS Word needs + antiword. It is also useful to have + wvWare installed as it may be + be used as a fallback for some files which + antiword does not handle. + + MS Excel and PowerPoint are processed by + internal Python handlers. + + MS Open XML (docx) needs + xsltproc. + + Wordperfect files need wpd2html + from the libwpd (or + libwpd-tools on Ubuntu) + package. + + RTF files need unrtf, + which, in its older versions, has much trouble with + non-western character sets. Many Linux distributions carry + outdated unrtf versions. Check + &RCLAPPS; for details. + + TeX files need untex or + detex. Check &RCLAPPS; for sources if it's not + packaged for your distribution. + + dvi files need dvips. + + + djvu files need djvutxt and + djvused from the + DjVuLibre package. + + Audio files: &RCL; releases 1.14 and later use + a single Python handler based + on mutagen for all audio file + types. + + + Pictures: &RCL; uses the + Exiftool + Perl package to extract tag + information. Most image file formats are supported. Note that + there may not be much interest in indexing the technical tags + (image size, aperture, etc.). This is only of interest if you + store personal tags or textual descriptions inside the image + files. + + chm: files in Microsoft help format need Python and + the pychm module (which needs + chmlib). + + ICS: up to &RCL; 1.13, iCalendar files need + Python + and the icalendar + module. icalendar is not needed for newer + versions, which use internal code. + + Zip archives need Python + (and the standard zipfile module). + + Rar archives need + Python, the + rarfile Python module and the + unrar utility. + + Midi karaoke files need + Python and the + + Midi module + + + Konqueror webarchive format with Python (uses the + Tarfile module). + + Mimehtml web archive format (support based on + the email handler, which introduces some mild weirdness, but + still usable). + + + + Text, HTML, email folders, and Scribus files are + processed internally. Lyx is used to + index Lyx files. Many handlers need iconv and the + standard sed and awk. + + + + + + + Building from source + + + Prerequisites + + If you can install any or all of the following through + the package manager for your system, all the + better. Especially Qt is a very + big piece of software, but you will most probably be able to + find a binary package. + + You may have to compile &XAP; but this is easy. + + The shopping list: + + + The autoconf, + automake and libtool + triad. Only autoconf is needed up to &RCL; + 1.21. + + C++ compiler. Up to &RCL; version 1.13.04, + its absence can manifest itself by strange messages + about a missing iconv_open. + + + bison command (for &RCL; 1.21 + and later). + + + xsltproc command. For building + the documentation (for &RCL; 1.21 + and later). This sometimes comes with the + libxslt package. And also the Docbook XML and + style sheet files. + + + + Development files + for Xapian + core. + + If you are + building Xapian for an older CPU (before Pentium 4 or Athlon + 64), you need to add the flag + to the configure command. Else all Xapian application will + crash with an illegal instruction + error. + + + + + Development files for + + Qt 4 . &RCL; has not been + tested with Qt 5 yet. &RCL; 1.15.9 + was the last version to support Qt 3. + If you do not want to install or build + the Qt Webkit module, &RCL; + has a configuration option to disable its use (see further). + + + + + Development files for X11 and + zlib. + + + + Development files for Python + (or use --disable-python-module). + + + + You may also need + + libiconv. On Linux + systems, the iconv interface is part of libc and you should not + need to do anything special. + + + + + Check the + &RCL; download page for up to date version + information. + + + + + Building + + &RCL; has been built on Linux, FreeBSD, Mac OS X, and Solaris, + most versions after 2005 should be ok, maybe some older ones too + (Solaris 8 is ok). If you build on another system, and + need to modify things, + I would + very much welcome patches. + + + Configure options: + + + + + will disable the code for phonetic matching of search + terms. + + or + will enable the code for + real time indexing. Inotify support is enabled by default on + recent Linux systems. + + will + enable sending Zeitgeist + events about the visited search results, and needs + the qzeitgeist + package. + + is available + from version 1.17 to implement the result list with a + Qt QTextBrowser instead of a + WebKit widget if you do not or can't depend on the + latter. + + is available + from version 1.19 to suppress multithreading inside the + indexing process. You can also use the run-time + configuration to restrict recollindex + to using a single thread, but the compile-time option + may disable a few more unused locks. This only applies + to the use of multithreading for the core index + processing (data input). The &RCL; monitor mode always + uses at least two threads of execution. + + will + avoid building the Python + module. + + will prevent + fetching data from file extended attributes. Beyond a + few standard attributes, fetching extended attributes + data can only be useful is some application stores data + in there, and also needs some simple configuration (see + comments in the fields configuration + file). + + will enable + splitting camelCase words. This + is not enabled by default as it has the unfortunate + side-effect of making some phrase searches quite + confusing: ie, "MySQL manual" would be + matched by "MySQL manual" and + "my sql manual" but not "mysql + manual" (only inside phrase searches). + + + Specify + the version of the 'file' command to use (ie: + --with-file-command=/usr/local/bin/file). Can be useful to + enable the gnu version on systems where the native one is + bad. + + Disable the Qt + interface. Will allow building the indexer and the command line + search program in absence of a Qt environment. + + + Disable + X11 connection monitoring + inside recollindex. Together with --disable-qtgui, this + allows building recoll without + Qt and + X11. + + + will avoid building the user manual. This avoids having to + install the Docbook XML/XSL files and the TeX toolchain used for + translating the manual to PDF. + + (&RCL; versions up + to 1.21 only) will compile + &RCL; with position-dependant code. This is incompatible with + building the KIO or the Python + or PHP extensions, but might + yield very marginally faster code. + + Of course the usual + autoconf configure + options, like apply. + + + + + + Normal procedure (for source extracted from a tar + distribution): + + cd recoll-xxx + ./configure + make + (practices usual hardship-repelling invocations) + + + When building from source cloned from the BitBucket repository, + you also need to install autoconf, + automake, and + libtool and you must execute sh + autogen.sh in the top source directory before running + configure. + + + Building on Solaris + + We did not test building the GUI on Solaris for recent + versions. You will need at least Qt 4.4. There are some hints + on an old + web site page, they may still be valid. + + Someone did test the 1.19 indexer and Python module build, + they do work, with a few minor glitches. Be sure to use + GNU make and install. + + + + + + Installation + + Either type make install or execute + recollinstall + prefix, in the root + of the source tree. This will copy the commands to + prefix/bin + and the sample configuration files, scripts and other shared + data to + prefix/share/recoll. + If the installation prefix given to + recollinstall is different from either the + system default or the value which was + specified when executing configure (as in + configure --prefix /some/path), you + will have to set the RECOLL_DATADIR + environment variable to indicate where the shared data is to + be found (ie for (ba)sh: + export RECOLL_DATADIR=/some/path/share/recoll). + + + You can then proceed to configuration. + + + + + + Configuration overview + + Most of the parameters specific to the + recoll GUI are set through the + Preferences menu and stored in the standard Qt + place ($HOME/.config/Recoll.org/recoll.conf). + You probably do not want to edit this by hand. + + &RCL; indexing options are set inside text configuration + files located in a configuration directory. There can be + several such directories, each of which defines the parameters + for one index. + + The configuration files can be edited by hand or through + the Index configuration dialog + (Preferences menu). The GUI tool will try + to respect your formatting and comments as much as possible, + so it is quite possible to use both approaches on the same + configuration. + + The most accurate documentation for the + configuration parameters is given by comments inside the default + files, and we will just give a general overview here. + + For each index, there are at least two sets of + configuration files. System-wide configuration files are kept + in a directory named + like /usr/share/recoll/examples, + and define default values, shared by all indexes. For each + index, a parallel set of files defines the customized + parameters. + + The default location of the customized configuration is the + .recoll + directory in your home. Most people will only use this + directory. + + This location can be changed, or others can be added with the + RECOLL_CONFDIR environment variable or the + option parameter to recoll and + recollindex. + + In addition (as of &RCL; version 1.19.7), it is possible + to specify two additional configuration directories which will + be stacked before and after the user configuration + directory. These are defined by + the RECOLL_CONFTOP + and RECOLL_CONFMID environment + variables. Values from configuration files inside the top + directory will override user ones, values from configuration + files inside the middle directory will override system ones + and be overriden by user ones. These two variables may be of + use to applications which augment &RCL; functionality, and + need to add configuration data without disturbing the user's + files. Please note that the two, currently single, values will + probably be interpreted as colon-separated lists in the + future: do not use colon characters inside the directory + paths. + + If the .recoll directory does not + exist when recoll or + recollindex are started, it will be created + with a set of empty configuration files. + recoll will give you a chance to edit the + configuration file before starting + indexing. recollindex will proceed + immediately. To avoid mistakes, the automatic directory + creation will only occur for the + default location, not if or + RECOLL_CONFDIR were used (in the latter + cases, you will have to create the directory). + + All configuration files share the same format. For + example, a short extract of the main configuration file might + look as follows: + + # Space-separated list of directories to index. + topdirs = ~/docs /usr/share/doc + + [~/somedirectory-with-utf8-txt-files] + defaultcharset = utf-8 + + + There are three kinds of lines: + + Comment (starts with + #) or empty. + + Parameter affectation (name = + value). + + Section definition + ([somedirname]). + + + + Long lines can be broken by ending each incomplete part with + a backslash (\). + + Depending on the type of configuration file, section + definitions either separate groups of parameters or allow + redefining some parameters for a directory sub-tree. They stay + in effect until another section definition, or the end of + file, is encountered. Some of the parameters used for indexing + are looked up hierarchically from the current directory + location upwards. Not all parameters can be meaningfully + redefined, this is specified for each in the next + section. + + When found at the beginning of a file path, the tilde + character (~) is expanded to the name of the user's home + directory, as a shell would do. + + Some parameters are lists of strings. White space is used for + separation. List elements with embedded spaces can be quoted using + double-quotes. Double quotes inside these elements can be escaped + with a backslash. + + No value inside a configuration file can contain a newline + character. Long lines can be continued by escaping the + physical newline with backslash, even inside quoted strings. + +astringlist = "some string \ +with spaces" +thesame = "some string with spaces" + + + Parameters which are not part of string lists can't be + quoted, and leading and trailing space characters are + stripped before the value is used. + + + Encoding issues + Most of the configuration parameters are plain ASCII. Two + particular sets of values may cause encoding issues: + + + + + + File path parameters may contain non-ascii + characters and should use the exact same byte values as found in + the file system directory. Usually, this means that the + configuration file should use the system default locale + encoding. + + The unac_except_trans parameter + should be encoded in UTF-8. If your system locale is not UTF-8, and + you need to also specify non-ascii file paths, this poses a + difficulty because common text editors cannot handle multiple + encodings in a single file. In this relatively unlikely case, you + can edit the configuration file as two separate text files with + appropriate encodings, and concatenate them to create the complete + configuration. + + + + + + Environment variables + + + + RECOLL_CONFDIR + Defines the main configuration + directory. + + + + RECOLL_TMPDIR, TMPDIR + Locations for temporary files, in this order + of priority. The default if none of these is set is to use + /tmp. Big temporary files may be created + during indexing, mostly for decompressing, and also for + processing, e.g. email attachments. + + + + RECOLL_CONFTOP, RECOLL_CONFMID + Allow adding configuration directories with + priorities below and above the user directory (see above the + Configuration overview section for details). + + + + RECOLL_EXTRA_DBS, + RECOLL_ACTIVE_EXTRA_DBS + + Help for setting up external indexes. See this paragraph for + explanations. + + + + + RECOLL_DATADIR + Defines replacement for the default location + of Recoll data files, normally found in, e.g., + /usr/share/recoll). + + + + RECOLL_FILTERSDIR + Defines replacement for the default location + of Recoll filters, normally found in, e.g., + /usr/share/recoll/filters). + + + + ASPELL_PROG + aspell program to use for + creating the spelling dictionary. The result has to be + compatible with the libaspell which &RCL; + is using. + + + + VARNAME + Blabla + + + + + + + + + + + + The fields file + + This file contains information about dynamic fields handling + in &RCL;. Some very basic fields have hard-wired behaviour, + and, mostly, you should not change the original data inside the + fields file. But you can create custom fields + fitting your data and handle them just like they were native + ones. + + The fields file has several sections, + which each define an aspect of fields processing. Quite often, + you'll have to modify several sections to obtain the desired + behaviour. + + We will only give a short description here, you should refer + to the comments inside the default file for more detailed + information. + + Field names should be lowercase alphabetic ASCII. + + + + + [prefixes] + A field becomes indexed (searchable) by having + a prefix defined in this section. + + + + [stored] + A field becomes stored (displayable inside + results) by having its name listed in this section (typically + with an empty value). + + + + [aliases] + This section defines lists of synonyms for the + canonical names used inside the [prefixes] + and [stored] sections + + + + [queryaliases] + This section also defines aliases for the + canonic field names, with the difference that the substitution + will only be used at query time, avoiding any possibility that + the value would pick-up random metadata from documents. + + + + handler-specific sections + Some input handlers may need specific + configuration for handling fields. Only the email message handler + currently has such a section (named + [mail]). It allows indexing arbitrary email + headers in addition to the ones indexed by default. Other such + sections may appear in the future. + + + + + + Here follows a small example of a personal + fields + file. This would extract a specific email header and + use it as a searchable field, with data displayable inside result + lists. (Side note: as the email handler does no decoding on the values, + only plain ascii headers can be indexed, and only the + first occurrence will be used for headers that occur several times). + +[prefixes] +# Index mailmytag contents (with the given prefix) +mailmytag = XMTAG + +[stored] +# Store mailmytag inside the document data record (so that it can be +# displayed - as %(mailmytag) - in result lists). +mailmytag = + +[queryaliases] +filename = fn +containerfilename = cfn + +[mail] +# Extract the X-My-Tag mail header, and use it internally with the +# mailmytag field name +x-my-tag = mailmytag + + + + + + Extended attributes in the fields file + + &RCL; versions 1.19 and later process user extended + file attributes as documents fields by default. + + Attributes are processed as fields of the same name, + after removing the user prefix on + Linux. + + The [xattrtofields] + section of the fields file allows + specifying translations from extended attributes names to + &RCL; field names. An empty translation disables use of the + corresponding attribute data. + + + + + + + The mimemap file + + mimemap specifies the + file name extension to MIME type mappings. + + For file names without an extension, or with an unknown one, + a system command (file , or + xdg-mime) will be executed to determine the MIME + type (this can be switched off, or the command changed inside the + main configuration file). + + The mappings can be specified on a per-subtree basis, + which may be useful in some cases. Example: + okular notes have a + .xml extension but + should be handled specially, which is possible because they + are usually all located in one place. Example: + [~/.kde/share/apps/okular/docdata] +.xml = application/x-okular-notes + + The recoll_noindex + mimemap variable has been moved to + recoll.conf and renamed to + noContentSuffixes, while keeping the same + function, as of &RCL; version 1.21. For older &RCL; versions, + see the documentation for noContentSuffixes + but use recoll_noindex in + mimemap. + + + + + The mimeconf file + + mimeconf specifies how the + different MIME types are handled for indexing, and which icons + are displayed in the recoll result lists. + + Changing the parameters in the [index] section is + probably not a good idea except if you are a &RCL; + developer. + + The [icons] section allows you to change the icons which + are displayed by recoll in the result + lists (the values are the basenames of the png images inside + the iconsdir directory (specified in + recoll.conf). + + + + + The mimeview file + + mimeview specifies which programs + are started when you click on an Open link + in a result list. Ie: HTML is normally displayed using + firefox, but you may prefer + Konqueror, your + openoffice.org + program might be named oofice instead of + openoffice etc. + + Changes to this file can be done by direct editing, or + through the recoll GUI preferences dialog. + + If Use desktop preferences to choose document + editor is checked in the &RCL; GUI preferences, all + mimeview entries will be ignored except the + one labelled application/x-all (which is set to + use xdg-open by default). + + In this case, the xallexcepts top level + variable defines a list of MIME type exceptions which + will be processed according to the local entries instead of being + passed to the desktop. This is so that specific &RCL; options + such as a page number or a search string can be passed to + applications that support them, such as the + evince viewer. + + As for the other configuration files, the normal usage + is to have a mimeview inside your own + configuration directory, with just the non-default entries, + which will override those from the central configuration + file. + + All viewer definition entries must be placed under a + [view] section. + + The keys in the file are normally MIME types. You can add an + application tag to specialize the choice for an area of the + filesystem (using a localfields specification + in mimeconf). The syntax for the key is +mimetype|tag + + The nouncompforviewmts entry, (placed at + the top level, outside of the [view] section), + holds a list of MIME types that should not be uncompressed before + starting the viewer (if they are found compressed, ie: + mydoc.doc.gz). + + The right side of each assignment holds a command to be + executed for opening the file. The following substitutions are + performed: + + + + %D + Document date + + + %f + File name. This may be the name of a temporary file if + it was necessary to create one (ie: to extract a subdocument + from a container). + + + %i + Internal path, for subdocuments of containers. The + format depends on the container type. If this appears in the + command line, &RCL; will not create a temporary file to + extract the subdocument, expecting the called application + (possibly a script) to be able to handle it. + + + %M + MIME type + + + %p + Page index. Only significant for a subset of document + types, currently only PDF, Postscript and DVI files. Can be + used to start the editor at the right page for a match or + snippet. + + + %s + Search term. The value will only be set for documents + with indexed page numbers (ie: PDF). The value will be one of + the matched search terms. It would allow pre-setting the + value in the "Find" entry inside Evince for example, for easy + highlighting of the term. + + + %u + Url. + + + + In addition to the predefined values above, all strings like + %(fieldname) will be replaced by the value of + the field named fieldname for the + document. This could be used in combination with field + customisation to help with opening the document. + + + + + The <filename>ptrans</filename> file + + ptrans specifies query-time path + translations. These can be useful + in multiple + cases. + The file has a section for any index which needs + translations, either the main one or additional query + indexes. The sections are named with the &XAP; index + directory names. No slash character should exist at the end + of the paths (all comparisons are textual). An exemple + should make things sufficiently clear + + + [/home/me/.recoll/xapiandb] + /this/directory/moved = /to/this/place + + [/path/to/additional/xapiandb] + /server/volume1/docdir = /net/server/volume1/docdir + /server/volume2/docdir = /net/server/volume2/docdir + + + + + + + Examples of configuration adjustments + + + Adding an external viewer for an non-indexed type + + Imagine that you have some kind of file which does not + have indexable content, but for which you would like to have a + functional Open link in the result list + (when found by file name). The file names end in + .blob and can be displayed by + application blobviewer. + + You need two entries in the configuration files for this + to work: + + + In $RECOLL_CONFDIR/mimemap + (typically ~/.recoll/mimemap), add the + following line: +.blob = application/x-blobapp + + Note that the MIME type is made up here, and you could + call it diesel/oil just the + same. + + In $RECOLL_CONFDIR/mimeview + under the [view] section, add: + +application/x-blobapp = blobviewer %f + + We are supposing + that blobviewer wants a file + name parameter here, you would use %u if + it liked URLs better. + + + + If you just wanted to change the application used by + &RCL; to display a MIME type which it already knows, you + would just need to edit mimeview. The + entries you add in your personal file override those in the + central configuration, which you do not need to + alter. mimeview can also be modified + from the Gui. + + + + + Adding indexing support for a new file type + + Let us now imagine that the above + .blob files actually contain + indexable text and that you know how to extract it with a + command line program. Getting &RCL; to index the files is + easy. You need to perform the above alteration, and also to + add data to the mimeconf file + (typically in ~/.recoll/mimeconf): + + Under the [index] + section, add the following line (more about the + rclblob indexing script + later): +application/x-blobapp = exec rclblob + + + Under the [icons] + section, you should choose an icon to be displayed for the + files inside the result lists. Icons are normally 64x64 + pixels PNG files which live in + /usr/share/recoll/images. + + Under the [categories] + section, you should add the MIME type where it makes sense + (you can also create a category). Categories may be used + for filtering in advanced search. + + + + The rclblob handler should + be an executable program or script which exists inside + /usr/share/recoll/filters. It + will be given a file name as argument and should output the + text or html contents on the standard output. + + The filter + programming section describes in more detail how + to write an input handler. + + + + + + + + + +
+ diff --git a/src/doc/user/webhelp/00README.txt b/src/doc/user/webhelp/00README.txt new file mode 100644 index 00000000..50f6609c --- /dev/null +++ b/src/doc/user/webhelp/00README.txt @@ -0,0 +1,13 @@ + +01-2016: +Webhelp is not packaged on Debian. To setup the build: + + - Get a docbook-xsl tar distribution (e.g. docbook-xsl-1.79.1.tar.bz2) + - Copy webhelp/xsl to the docbook dist: + /usr/share/xml/docbook/stylesheet/docbook-xsl/webhelp/xsl + - Possibly adjust + DOCBOOK_DIST := /usr/share/xml/docbook/stylesheet/docbook-xsl/ + in Makefile (if other system with docbook installed elsewhere). + +Did not try to get the search to work (needs lucene etc.) + diff --git a/src/doc/user/webhelp/Makefile b/src/doc/user/webhelp/Makefile new file mode 100644 index 00000000..50b210ef --- /dev/null +++ b/src/doc/user/webhelp/Makefile @@ -0,0 +1,114 @@ +# Configuration +# The name of the source DocBook xml file +INPUT_XML = ../usermanual.xml + +# The makefile assumes that you have a +# directory named images that contains +# your images. It copies this to the +# output directory +USER_IMAGES_PARENT_DIR=docsrc + +# Name of the desired output directory +# This will be created if it doesn't exist +OUTPUT_DIR = docs + +# A list of files to exclude from indexing +INDEXER_EXCLUDED_FILES = ix01.html + +# Profiling params. For more information on +# profiling (conditional text) and DocBook documents, see +# http://www.sagehill.net/docbookxsl/Profiling.html +PROFILE.ARCH = "" +PROFILE.AUDIENCE = "" +PROFILE.CONDITION = "" +PROFILE.CONFORMANCE = "" +PROFILE.LANG = "" +PROFILE.OS = "" +PROFILE.REVISION = "" +PROFILE.REVISIONFLAG = "" +PROFILE.ROLE = "" +PROFILE.SECURITY = "" +PROFILE.STATUS = "" +PROFILE.USERLEVEL = "" +PROFILE.VENDOR = "" +PROFILE.WORDSIZE = "" +PROFILE.ATTRIBUTE = "" +PROFILE.VALUE = "" + +# Use this variable to pass in other stringparams +# to the xsltproc pass that generates DocBook output. +# For example: +# OTHER_XSLTPROC_ARGS = --stringparam example.param "" +OTHER_XSLTPROC_ARGS = + +# Path to the DocBook Distribution that +# contains the xslts etc. +DOCBOOK_DIST := /usr/share/xml/docbook/stylesheet/docbook-xsl/ + +# ================================================= +# You probably don't need to change anything below +# unless you choose to add a validation step. +# ================================================ +DOCBOOK_EXTENSIONS_DIR = $(DOCBOOK_DIST)/extensions +INDEXER_JAR := $(DOCBOOK_EXTENSIONS_DIR)/webhelpindexer.jar +TAGSOUP_JAR := $(DOCBOOK_EXTENSIONS_DIR)/tagsoup-1.2.1.jar +LUCENE_ANALYZER_JAR := $(DOCBOOK_EXTENSIONS_DIR)/lucene-analyzers-3.0.0.jar +LUCENE_CORE_JAR := $(DOCBOOK_EXTENSIONS_DIR)/lucene-core-3.0.0.jar + +classpath := $(INDEXER_JAR):$(TAGSOUP_JAR):$(LUCENE_ANALYZER_JAR):$(LUCENE_CORE_JAR) + +all: copyfiles docs/index.html # index + +${OUTPUT_DIR}/favicon.ico: template/favicon.ico + cp -p template/favicon.ico ${OUTPUT_DIR}/favicon.ico +${OUTPUT_DIR}/common/main.js: template/common/main.js + cp -rp template/common ${OUTPUT_DIR} + +copyfiles: ${OUTPUT_DIR}/favicon.ico ${OUTPUT_DIR}/common/main.js + +# test ! -d $(USER_IMAGES_PARENT_DIR)/images/ || \ +# cp -rp $(USER_IMAGES_PARENT_DIR)/images ${OUTPUT_DIR}/images + +docs/index.html: ${INPUT_XML} + xsltproc --xinclude --output xincluded-profiled.xml \ + --stringparam profile.arch ${PROFILE.ARCH} \ + --stringparam profile.audience ${PROFILE.AUDIENCE} \ + --stringparam profile.condition ${PROFILE.CONDITION} \ + --stringparam profile.conformance ${PROFILE.CONFORMANCE} \ + --stringparam profile.lang ${PROFILE.LANG} \ + --stringparam profile.os ${PROFILE.OS} \ + --stringparam profile.revision ${PROFILE.REVISION} \ + --stringparam profile.revisionflag ${PROFILE.REVISIONFLAG} \ + --stringparam profile.role ${PROFILE.ROLE} \ + --stringparam profile.security ${PROFILE.SECURITY} \ + --stringparam profile.status ${PROFILE.STATUS} \ + --stringparam profile.userlevel ${PROFILE.USERLEVEL} \ + --stringparam profile.vendor ${PROFILE.VENDOR} \ + --stringparam profile.wordsize ${PROFILE.WORDSIZE} \ + --stringparam profile.attribute ${PROFILE.ATTRIBUTE} \ + --stringparam profile.value ${PROFILE.VALUE} \ + ${DOCBOOK_DIST}/profiling/profile.xsl \ + ${INPUT_XML} + xsltproc ${OTHER_XSLTPROC_ARGS} \ + ${DOCBOOK_DIST}/webhelp/xsl/webhelp.xsl \ + xincluded-profiled.xml + rm xincluded-profiled.xml + +index: + java \ + -DhtmlDir=$(OUTPUT_DIR) \ + -DindexerLanguage=en \ + -DhtmlExtension=html \ + -DdoStem=true \ + -DindexerExcludedFiles=$(INDEXER_EXCLUDED_FILES) \ + -Dorg.xml.sax.driver=org.ccil.cowan.tagsoup.Parser \ + -Djavax.xml.parsers.SAXParserFactory=org.ccil.cowan.tagsoup.jaxp.SAXFactoryImpl \ + -classpath $(classpath) \ + com.nexwave.nquindexer.IndexerMain + + cp -r template/search/* ${OUTPUT_DIR}/search + +clean: + $(RM) -r ${OUTPUT_DIR} + mkdir -p $(OUTPUT_DIR) + diff --git a/src/doc/user/webhelp/docs/favicon.ico b/src/doc/user/webhelp/docs/favicon.ico new file mode 100755 index 00000000..281a0368 Binary files /dev/null and b/src/doc/user/webhelp/docs/favicon.ico differ diff --git a/src/doc/user/webhelp/template/common/browserDetect.js b/src/doc/user/webhelp/template/common/browserDetect.js new file mode 100644 index 00000000..c6a2c73a --- /dev/null +++ b/src/doc/user/webhelp/template/common/browserDetect.js @@ -0,0 +1,116 @@ +var BrowserDetect = { + init: function () { + this.browser = this.searchString(this.dataBrowser) || "An unknown browser"; + this.version = this.searchVersion(navigator.userAgent) + || this.searchVersion(navigator.appVersion) + || "an unknown version"; + this.OS = this.searchString(this.dataOS) || "an unknown OS"; + }, + searchString: function (data) { + for (var i=0;ip{ font-weight: bold; } + +p.breadcrumbs { + display: inline; + margin-bottom: 0px; + margin-top: 33px; +} + +p.breadcrumbs a { + padding-right: 12px; + margin-right: 5px; + text-decoration: none; + color: #575757; + text-transform: uppercase; + font-size: 10px; +} + +p.breadcrumbs a:first-child {background: url(../images/breadcrumb-arrow-white.png) no-repeat right center;} + +p.breadcrumbs a:hover {text-decoration: underline;} + +#star ul.star { + LIST-STYLE: none; + MARGIN: 0; + PADDING: 0; + WIDTH: 85px; + /* was 100 */ + HEIGHT: 20px; + LEFT: 1px; + TOP: -5px; + POSITION: relative; + FLOAT: right; + BACKGROUND: url('../images/starsSmall.png') repeat-x 0 -25px; +} +#star li { + PADDING: 0; + MARGIN: 0; + FLOAT: right; + DISPLAY: block; + WIDTH: 85px; + /* was 100 */ + HEIGHT: 20px; + TEXT-DECORATION: none; + text-indent: -9000px; + Z-INDEX: 20; + POSITION: absolute; + PADDING: 0; +} +#star li.curr { + BACKGROUND: url('../images/starsSmall.png') left 25px; + FONT-SIZE: 1px; +} + +table.navLinks {margin-right: 20px;} + +table.navLinks td a { + text-decoration: none; + text-transform: uppercase; + color: black; + font-size: 11px; +} + +a.navLinkPrevious { + padding-left: 12px; + background: url(../images/previous-arrow.png) no-repeat left center; +} + +a.navLinkNext { + padding-right: 12px; + background: url(../images/next-arrow.png) no-repeat right center; +} + +a#showHideButton { + padding-left: 20px; + background: url(../images/sidebar.png) no-repeat left center; +} + + +.filetree li span a { color: #777; } + +#treediv { -webkit-box-shadow: #CCC 0px 1px 2px 0px inset; } + +.legal, .legal *{ + color: #555; + text-align: center; + padding-bottom: 10px; +} + +.internal { color : #0000CC;} + +.writeronly {color : red;} + +.remark, .remark .added, .remark .changed, .remark .deleted{ background: yellow;} + +tr th, tr th .internal, tr th .added, tr th .changed { + background: #00589E; + color: white; + font-weight: bold; + text-align: left; +} + +.statustext{ + position:fixed; + top:105px; + width: 0%; + height: 0%; + opacity: .3; + -webkit-transform: rotate(90deg); + -moz-transform: rotate(90deg); + -o-transform: rotate(90deg); + white-space: nowrap; + color: red; + font-weight: bold; + font-size: 2em; + margin-top: 30px; +} + +#toolbar { + width: 100%; + height: 33px; + position: fixed; + top: 93px; + z-index: 99; + left: 280px; + color: #333; + line-height: 28px; + padding-left: 10px; +} + +#toolbar-left { + position: relative; + left: 0px; +} + +body p.breadcrumbs { + margin: 0px; + padding: 0px; + line-height: 28px; +} + +/*body #content { + position: static; + margin-top: 126px; + top: 0px; +}*/ + +body.sidebar #toolbar{left: 0px;} + +body.sidebar #toolbar-left{left: 0px;} + +div#toolbar-left img {vertical-align: text-top;} + +div.note *, div.caution *, div.important *, div.tip *, div.warning * { + background: inherit !important; + color: inherit !important; + border: inherit !important; +} + +#content table thead, #content table th{ + background: gray; + color: white; + font-weight: bold; +} + +#content table caption{font-weight: bold;} + +#content table td, #content table {border: 1px solid black;} + +#content table td, #content table th { padding: 5px;} + +#content table {margin-bottom: 20px;} + +*[align = 'center']{ text-align: center;} + +#content .qandaset>table, #content .qandaset>table td, #content .calloutlist table, #content .calloutlist table td, #content .navfooter table, #content .navfooter table td { + border: 0px solid; +} + +#sidebar { display: none } + +@media print { + + body * { + visibility: hidden; + } + + #content, #content * { + visibility: visible; + } + + #sidebar, .navfooter { + display: none; + } + + #content { + margin: 0 0 0 0; + } + +} + diff --git a/src/doc/user/webhelp/template/common/images/admon/caution.png b/src/doc/user/webhelp/template/common/images/admon/caution.png new file mode 100644 index 00000000..5b7809ca Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/admon/caution.png differ diff --git a/src/doc/user/webhelp/template/common/images/admon/important.png b/src/doc/user/webhelp/template/common/images/admon/important.png new file mode 100644 index 00000000..12c90f60 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/admon/important.png differ diff --git a/src/doc/user/webhelp/template/common/images/admon/note.png b/src/doc/user/webhelp/template/common/images/admon/note.png new file mode 100644 index 00000000..d0c3c645 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/admon/note.png differ diff --git a/src/doc/user/webhelp/template/common/images/admon/tip.png b/src/doc/user/webhelp/template/common/images/admon/tip.png new file mode 100644 index 00000000..5c4aab3b Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/admon/tip.png differ diff --git a/src/doc/user/webhelp/template/common/images/admon/warning.png b/src/doc/user/webhelp/template/common/images/admon/warning.png new file mode 100644 index 00000000..1c33db8f Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/admon/warning.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/1.png b/src/doc/user/webhelp/template/common/images/callouts/1.png new file mode 100755 index 00000000..de682c62 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/1.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/10.png b/src/doc/user/webhelp/template/common/images/callouts/10.png new file mode 100755 index 00000000..96c6ce45 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/10.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/11.png b/src/doc/user/webhelp/template/common/images/callouts/11.png new file mode 100755 index 00000000..4550cb09 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/11.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/12.png b/src/doc/user/webhelp/template/common/images/callouts/12.png new file mode 100755 index 00000000..ef0f6350 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/12.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/13.png b/src/doc/user/webhelp/template/common/images/callouts/13.png new file mode 100755 index 00000000..b4878f1a Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/13.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/14.png b/src/doc/user/webhelp/template/common/images/callouts/14.png new file mode 100755 index 00000000..a222d7bf Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/14.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/15.png b/src/doc/user/webhelp/template/common/images/callouts/15.png new file mode 100755 index 00000000..f6a76d51 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/15.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/16.png b/src/doc/user/webhelp/template/common/images/callouts/16.png new file mode 100755 index 00000000..c5ef6359 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/16.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/17.png b/src/doc/user/webhelp/template/common/images/callouts/17.png new file mode 100755 index 00000000..85a2101e Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/17.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/18.png b/src/doc/user/webhelp/template/common/images/callouts/18.png new file mode 100755 index 00000000..7744d257 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/18.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/19.png b/src/doc/user/webhelp/template/common/images/callouts/19.png new file mode 100755 index 00000000..44bacf8a Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/19.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/2.png b/src/doc/user/webhelp/template/common/images/callouts/2.png new file mode 100755 index 00000000..24ec0f65 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/2.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/20.png b/src/doc/user/webhelp/template/common/images/callouts/20.png new file mode 100755 index 00000000..5e100fe5 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/20.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/21.png b/src/doc/user/webhelp/template/common/images/callouts/21.png new file mode 100755 index 00000000..c87e80a9 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/21.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/22.png b/src/doc/user/webhelp/template/common/images/callouts/22.png new file mode 100755 index 00000000..20593a4e Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/22.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/23.png b/src/doc/user/webhelp/template/common/images/callouts/23.png new file mode 100755 index 00000000..3909b9cd Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/23.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/24.png b/src/doc/user/webhelp/template/common/images/callouts/24.png new file mode 100755 index 00000000..963a9e77 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/24.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/25.png b/src/doc/user/webhelp/template/common/images/callouts/25.png new file mode 100755 index 00000000..458a9199 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/25.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/26.png b/src/doc/user/webhelp/template/common/images/callouts/26.png new file mode 100755 index 00000000..74b25073 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/26.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/27.png b/src/doc/user/webhelp/template/common/images/callouts/27.png new file mode 100755 index 00000000..611b8ce8 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/27.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/28.png b/src/doc/user/webhelp/template/common/images/callouts/28.png new file mode 100755 index 00000000..6aa21af6 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/28.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/29.png b/src/doc/user/webhelp/template/common/images/callouts/29.png new file mode 100755 index 00000000..6009b520 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/29.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/3.png b/src/doc/user/webhelp/template/common/images/callouts/3.png new file mode 100755 index 00000000..01cdff1d Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/3.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/30.png b/src/doc/user/webhelp/template/common/images/callouts/30.png new file mode 100755 index 00000000..c4dc404b Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/30.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/4.png b/src/doc/user/webhelp/template/common/images/callouts/4.png new file mode 100755 index 00000000..1e42fb37 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/4.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/5.png b/src/doc/user/webhelp/template/common/images/callouts/5.png new file mode 100755 index 00000000..635e7f81 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/5.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/6.png b/src/doc/user/webhelp/template/common/images/callouts/6.png new file mode 100755 index 00000000..521aedde Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/6.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/7.png b/src/doc/user/webhelp/template/common/images/callouts/7.png new file mode 100755 index 00000000..0d4b876a Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/7.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/8.png b/src/doc/user/webhelp/template/common/images/callouts/8.png new file mode 100755 index 00000000..50fa94d1 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/8.png differ diff --git a/src/doc/user/webhelp/template/common/images/callouts/9.png b/src/doc/user/webhelp/template/common/images/callouts/9.png new file mode 100755 index 00000000..7190d5a9 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/callouts/9.png differ diff --git a/src/doc/user/webhelp/template/common/images/header-bg.gif b/src/doc/user/webhelp/template/common/images/header-bg.gif new file mode 100644 index 00000000..f9efa280 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/header-bg.gif differ diff --git a/src/doc/user/webhelp/template/common/images/header-bg.png b/src/doc/user/webhelp/template/common/images/header-bg.png new file mode 100755 index 00000000..75202f9b Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/header-bg.png differ diff --git a/src/doc/user/webhelp/template/common/images/highlight-blue.gif b/src/doc/user/webhelp/template/common/images/highlight-blue.gif new file mode 100644 index 00000000..4fdabde6 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/highlight-blue.gif differ diff --git a/src/doc/user/webhelp/template/common/images/highlight-yellow.gif b/src/doc/user/webhelp/template/common/images/highlight-yellow.gif new file mode 100644 index 00000000..3e847e7e Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/highlight-yellow.gif differ diff --git a/src/doc/user/webhelp/template/common/images/loading.gif b/src/doc/user/webhelp/template/common/images/loading.gif new file mode 100644 index 00000000..085ccaec Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/loading.gif differ diff --git a/src/doc/user/webhelp/template/common/images/logo.png b/src/doc/user/webhelp/template/common/images/logo.png new file mode 100644 index 00000000..42e78483 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/logo.png differ diff --git a/src/doc/user/webhelp/template/common/images/next-arrow.png b/src/doc/user/webhelp/template/common/images/next-arrow.png new file mode 100644 index 00000000..db595f46 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/next-arrow.png differ diff --git a/src/doc/user/webhelp/template/common/images/previous-arrow.png b/src/doc/user/webhelp/template/common/images/previous-arrow.png new file mode 100644 index 00000000..347bc534 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/previous-arrow.png differ diff --git a/src/doc/user/webhelp/template/common/images/search-icon.png b/src/doc/user/webhelp/template/common/images/search-icon.png new file mode 100644 index 00000000..715f62d0 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/search-icon.png differ diff --git a/src/doc/user/webhelp/template/common/images/showHideTreeIcons.png b/src/doc/user/webhelp/template/common/images/showHideTreeIcons.png new file mode 100644 index 00000000..c1ec1f96 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/showHideTreeIcons.png differ diff --git a/src/doc/user/webhelp/template/common/images/sidebar.png b/src/doc/user/webhelp/template/common/images/sidebar.png new file mode 100644 index 00000000..54926718 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/sidebar.png differ diff --git a/src/doc/user/webhelp/template/common/images/starsSmall.png b/src/doc/user/webhelp/template/common/images/starsSmall.png new file mode 100644 index 00000000..490a27b9 Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/starsSmall.png differ diff --git a/src/doc/user/webhelp/template/common/images/toc-icon.png b/src/doc/user/webhelp/template/common/images/toc-icon.png new file mode 100644 index 00000000..40b34bce Binary files /dev/null and b/src/doc/user/webhelp/template/common/images/toc-icon.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/jquery-1.7.2.min.js b/src/doc/user/webhelp/template/common/jquery/jquery-1.7.2.min.js new file mode 100644 index 00000000..93adea19 --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/jquery-1.7.2.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.2 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
"+""+"
",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
t
",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( +a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f +.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/src/doc/user/webhelp/template/common/jquery/jquery-ui-1.8.2.custom.min.js b/src/doc/user/webhelp/template/common/jquery/jquery-ui-1.8.2.custom.min.js new file mode 100644 index 00000000..fec53e8e --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/jquery-ui-1.8.2.custom.min.js @@ -0,0 +1,321 @@ +/*! + * jQuery UI 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI + */ +(function(c){c.ui=c.ui||{};if(!c.ui.version){c.extend(c.ui,{version:"1.8.2",plugin:{add:function(a,b,d){a=c.ui[a].prototype;for(var e in d){a.plugins[e]=a.plugins[e]||[];a.plugins[e].push([b,d[e]])}},call:function(a,b,d){if((b=a.plugins[b])&&a.element[0].parentNode)for(var e=0;e0)return true;a[b]=1;d=a[b]>0;a[b]=0;return d},isOverAxis:function(a,b,d){return a>b&&a=0)&&c(a).is(":focusable")}})}})(jQuery); +;/*! + * jQuery UI Widget 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Widget + */ +(function(b){var j=b.fn.remove;b.fn.remove=function(a,c){return this.each(function(){if(!c)if(!a||b.filter(a,[this]).length)b("*",this).add(this).each(function(){b(this).triggerHandler("remove")});return j.call(b(this),a,c)})};b.widget=function(a,c,d){var e=a.split(".")[0],f;a=a.split(".")[1];f=e+"-"+a;if(!d){d=c;c=b.Widget}b.expr[":"][f]=function(h){return!!b.data(h,a)};b[e]=b[e]||{};b[e][a]=function(h,g){arguments.length&&this._createWidget(h,g)};c=new c;c.options=b.extend({},c.options);b[e][a].prototype= +b.extend(true,c,{namespace:e,widgetName:a,widgetEventPrefix:b[e][a].prototype.widgetEventPrefix||a,widgetBaseClass:f},d);b.widget.bridge(a,b[e][a])};b.widget.bridge=function(a,c){b.fn[a]=function(d){var e=typeof d==="string",f=Array.prototype.slice.call(arguments,1),h=this;d=!e&&f.length?b.extend.apply(null,[true,d].concat(f)):d;if(e&&d.substring(0,1)==="_")return h;e?this.each(function(){var g=b.data(this,a),i=g&&b.isFunction(g[d])?g[d].apply(g,f):g;if(i!==g&&i!==undefined){h=i;return false}}):this.each(function(){var g= +b.data(this,a);if(g){d&&g.option(d);g._init()}else b.data(this,a,new c(d,this))});return h}};b.Widget=function(a,c){arguments.length&&this._createWidget(a,c)};b.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:false},_createWidget:function(a,c){this.element=b(c).data(this.widgetName,this);this.options=b.extend(true,{},this.options,b.metadata&&b.metadata.get(c)[this.widgetName],a);var d=this;this.element.bind("remove."+this.widgetName,function(){d.destroy()});this._create(); +this._init()},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName);this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled ui-state-disabled")},widget:function(){return this.element},option:function(a,c){var d=a,e=this;if(arguments.length===0)return b.extend({},e.options);if(typeof a==="string"){if(c===undefined)return this.options[a];d={};d[a]=c}b.each(d,function(f, +h){e._setOption(f,h)});return e},_setOption:function(a,c){this.options[a]=c;if(a==="disabled")this.widget()[c?"addClass":"removeClass"](this.widgetBaseClass+"-disabled ui-state-disabled").attr("aria-disabled",c);return this},enable:function(){return this._setOption("disabled",false)},disable:function(){return this._setOption("disabled",true)},_trigger:function(a,c,d){var e=this.options[a];c=b.Event(c);c.type=(a===this.widgetEventPrefix?a:this.widgetEventPrefix+a).toLowerCase();d=d||{};if(c.originalEvent){a= +b.event.props.length;for(var f;a;){f=b.event.props[--a];c[f]=c.originalEvent[f]}}this.element.trigger(c,d);return!(b.isFunction(e)&&e.call(this.element[0],c,d)===false||c.isDefaultPrevented())}}})(jQuery); +;/*! + * jQuery UI Mouse 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Mouse + * + * Depends: + * jquery.ui.widget.js + */ +(function(c){c.widget("ui.mouse",{options:{cancel:":input,option",distance:1,delay:0},_mouseInit:function(){var a=this;this.element.bind("mousedown."+this.widgetName,function(b){return a._mouseDown(b)}).bind("click."+this.widgetName,function(b){if(a._preventClickEvent){a._preventClickEvent=false;b.stopImmediatePropagation();return false}});this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName)},_mouseDown:function(a){a.originalEvent=a.originalEvent||{};if(!a.originalEvent.mouseHandled){this._mouseStarted&& +this._mouseUp(a);this._mouseDownEvent=a;var b=this,e=a.which==1,f=typeof this.options.cancel=="string"?c(a.target).parents().add(a.target).filter(this.options.cancel).length:false;if(!e||f||!this._mouseCapture(a))return true;this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet)this._mouseDelayTimer=setTimeout(function(){b.mouseDelayMet=true},this.options.delay);if(this._mouseDistanceMet(a)&&this._mouseDelayMet(a)){this._mouseStarted=this._mouseStart(a)!==false;if(!this._mouseStarted){a.preventDefault(); +return true}}this._mouseMoveDelegate=function(d){return b._mouseMove(d)};this._mouseUpDelegate=function(d){return b._mouseUp(d)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);c.browser.safari||a.preventDefault();return a.originalEvent.mouseHandled=true}},_mouseMove:function(a){if(c.browser.msie&&!a.button)return this._mouseUp(a);if(this._mouseStarted){this._mouseDrag(a);return a.preventDefault()}if(this._mouseDistanceMet(a)&& +this._mouseDelayMet(a))(this._mouseStarted=this._mouseStart(this._mouseDownEvent,a)!==false)?this._mouseDrag(a):this._mouseUp(a);return!this._mouseStarted},_mouseUp:function(a){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=a.target==this._mouseDownEvent.target;this._mouseStop(a)}return false},_mouseDistanceMet:function(a){return Math.max(Math.abs(this._mouseDownEvent.pageX- +a.pageX),Math.abs(this._mouseDownEvent.pageY-a.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return true}})})(jQuery); +;/* + * jQuery UI Position 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Position + */ +(function(c){c.ui=c.ui||{};var m=/left|center|right/,n=/top|center|bottom/,p=c.fn.position,q=c.fn.offset;c.fn.position=function(a){if(!a||!a.of)return p.apply(this,arguments);a=c.extend({},a);var b=c(a.of),d=(a.collision||"flip").split(" "),e=a.offset?a.offset.split(" "):[0,0],g,h,i;if(a.of.nodeType===9){g=b.width();h=b.height();i={top:0,left:0}}else if(a.of.scrollTo&&a.of.document){g=b.width();h=b.height();i={top:b.scrollTop(),left:b.scrollLeft()}}else if(a.of.preventDefault){a.at="left top";g=h= +0;i={top:a.of.pageY,left:a.of.pageX}}else{g=b.outerWidth();h=b.outerHeight();i=b.offset()}c.each(["my","at"],function(){var f=(a[this]||"").split(" ");if(f.length===1)f=m.test(f[0])?f.concat(["center"]):n.test(f[0])?["center"].concat(f):["center","center"];f[0]=m.test(f[0])?f[0]:"center";f[1]=n.test(f[1])?f[1]:"center";a[this]=f});if(d.length===1)d[1]=d[0];e[0]=parseInt(e[0],10)||0;if(e.length===1)e[1]=e[0];e[1]=parseInt(e[1],10)||0;if(a.at[0]==="right")i.left+=g;else if(a.at[0]==="center")i.left+= +g/2;if(a.at[1]==="bottom")i.top+=h;else if(a.at[1]==="center")i.top+=h/2;i.left+=e[0];i.top+=e[1];return this.each(function(){var f=c(this),k=f.outerWidth(),l=f.outerHeight(),j=c.extend({},i);if(a.my[0]==="right")j.left-=k;else if(a.my[0]==="center")j.left-=k/2;if(a.my[1]==="bottom")j.top-=l;else if(a.my[1]==="center")j.top-=l/2;j.left=parseInt(j.left);j.top=parseInt(j.top);c.each(["left","top"],function(o,r){c.ui.position[d[o]]&&c.ui.position[d[o]][r](j,{targetWidth:g,targetHeight:h,elemWidth:k, +elemHeight:l,offset:e,my:a.my,at:a.at})});c.fn.bgiframe&&f.bgiframe();f.offset(c.extend(j,{using:a.using}))})};c.ui.position={fit:{left:function(a,b){var d=c(window);b=a.left+b.elemWidth-d.width()-d.scrollLeft();a.left=b>0?a.left-b:Math.max(0,a.left)},top:function(a,b){var d=c(window);b=a.top+b.elemHeight-d.height()-d.scrollTop();a.top=b>0?a.top-b:Math.max(0,a.top)}},flip:{left:function(a,b){if(b.at[0]!=="center"){var d=c(window);d=a.left+b.elemWidth-d.width()-d.scrollLeft();var e=b.my[0]==="left"? +-b.elemWidth:b.my[0]==="right"?b.elemWidth:0,g=-2*b.offset[0];a.left+=a.left<0?e+b.targetWidth+g:d>0?e-b.targetWidth+g:0}},top:function(a,b){if(b.at[1]!=="center"){var d=c(window);d=a.top+b.elemHeight-d.height()-d.scrollTop();var e=b.my[1]==="top"?-b.elemHeight:b.my[1]==="bottom"?b.elemHeight:0,g=b.at[1]==="top"?b.targetHeight:-b.targetHeight,h=-2*b.offset[1];a.top+=a.top<0?e+b.targetHeight+h:d>0?e+g+h:0}}}};if(!c.offset.setOffset){c.offset.setOffset=function(a,b){if(/static/.test(c.curCSS(a,"position")))a.style.position= +"relative";var d=c(a),e=d.offset(),g=parseInt(c.curCSS(a,"top",true),10)||0,h=parseInt(c.curCSS(a,"left",true),10)||0;e={top:b.top-e.top+g,left:b.left-e.left+h};"using"in b?b.using.call(a,e):d.css(e)};c.fn.offset=function(a){var b=this[0];if(!b||!b.ownerDocument)return null;if(a)return this.each(function(){c.offset.setOffset(this,a)});return q.call(this)}}})(jQuery); +;/* + * jQuery UI Resizable 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Resizables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(d){d.widget("ui.resizable",d.ui.mouse,{widgetEventPrefix:"resize",options:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,containment:false,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1E3},_create:function(){var b=this,a=this.options;this.element.addClass("ui-resizable");d.extend(this,{_aspectRatio:!!a.aspectRatio,aspectRatio:a.aspectRatio,originalElement:this.element, +_proportionallyResizeElements:[],_helper:a.helper||a.ghost||a.animate?a.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){/relative/.test(this.element.css("position"))&&d.browser.opera&&this.element.css({position:"relative",top:"auto",left:"auto"});this.element.wrap(d('
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(), +top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle= +this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=a.handles||(!d(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne", +nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all")this.handles="n,e,s,w,se,sw,ne,nw";var c=this.handles.split(",");this.handles={};for(var e=0;e
');/sw|se|ne|nw/.test(g)&&f.css({zIndex:++a.zIndex});"se"==g&&f.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[g]=".ui-resizable-"+g;this.element.append(f)}}this._renderAxis=function(h){h=h||this.element;for(var i in this.handles){if(this.handles[i].constructor== +String)this.handles[i]=d(this.handles[i],this.element).show();if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var j=d(this.handles[i],this.element),l=0;l=/sw|ne|nw|se|n|s/.test(i)?j.outerHeight():j.outerWidth();j=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join("");h.css(j,l);this._proportionallyResize()}d(this.handles[i])}};this._renderAxis(this.element);this._handles=d(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!b.resizing){if(this.className)var h=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);b.axis=h&&h[1]?h[1]:"se"}});if(a.autoHide){this._handles.hide();d(this.element).addClass("ui-resizable-autohide").hover(function(){d(this).removeClass("ui-resizable-autohide");b._handles.show()},function(){if(!b.resizing){d(this).addClass("ui-resizable-autohide");b._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var b=function(c){d(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()}; +if(this.elementIsWrapper){b(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);b(this.originalElement);return this},_mouseCapture:function(b){var a=false;for(var c in this.handles)if(d(this.handles[c])[0]==b.target)a=true;return!this.options.disabled&&a},_mouseStart:function(b){var a=this.options,c=this.element.position(), +e=this.element;this.resizing=true;this.documentScroll={top:d(document).scrollTop(),left:d(document).scrollLeft()};if(e.is(".ui-draggable")||/absolute/.test(e.css("position")))e.css({position:"absolute",top:c.top,left:c.left});d.browser.opera&&/relative/.test(e.css("position"))&&e.css({position:"relative",top:"auto",left:"auto"});this._renderProxy();c=m(this.helper.css("left"));var g=m(this.helper.css("top"));if(a.containment){c+=d(a.containment).scrollLeft()||0;g+=d(a.containment).scrollTop()||0}this.offset= +this.helper.offset();this.position={left:c,top:g};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:c,top:g};this.sizeDiff={width:e.outerWidth()-e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:b.pageX,top:b.pageY};this.aspectRatio=typeof a.aspectRatio=="number"?a.aspectRatio: +this.originalSize.width/this.originalSize.height||1;a=d(".ui-resizable-"+this.axis).css("cursor");d("body").css("cursor",a=="auto"?this.axis+"-resize":a);e.addClass("ui-resizable-resizing");this._propagate("start",b);return true},_mouseDrag:function(b){var a=this.helper,c=this.originalMousePosition,e=this._change[this.axis];if(!e)return false;c=e.apply(this,[b,b.pageX-c.left||0,b.pageY-c.top||0]);if(this._aspectRatio||b.shiftKey)c=this._updateRatio(c,b);c=this._respectSize(c,b);this._propagate("resize", +b);a.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(c);this._trigger("resize",b,this.ui());return false},_mouseStop:function(b){this.resizing=false;var a=this.options,c=this;if(this._helper){var e=this._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName);e=g&&d.ui.hasScroll(e[0],"left")?0:c.sizeDiff.height; +g={width:c.size.width-(g?0:c.sizeDiff.width),height:c.size.height-e};e=parseInt(c.element.css("left"),10)+(c.position.left-c.originalPosition.left)||null;var f=parseInt(c.element.css("top"),10)+(c.position.top-c.originalPosition.top)||null;a.animate||this.element.css(d.extend(g,{top:f,left:e}));c.helper.height(c.size.height);c.helper.width(c.size.width);this._helper&&!a.animate&&this._proportionallyResize()}d("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop", +b);this._helper&&this.helper.remove();return false},_updateCache:function(b){this.offset=this.helper.offset();if(k(b.left))this.position.left=b.left;if(k(b.top))this.position.top=b.top;if(k(b.height))this.size.height=b.height;if(k(b.width))this.size.width=b.width},_updateRatio:function(b){var a=this.position,c=this.size,e=this.axis;if(b.height)b.width=c.height*this.aspectRatio;else if(b.width)b.height=c.width/this.aspectRatio;if(e=="sw"){b.left=a.left+(c.width-b.width);b.top=null}if(e=="nw"){b.top= +a.top+(c.height-b.height);b.left=a.left+(c.width-b.width)}return b},_respectSize:function(b){var a=this.options,c=this.axis,e=k(b.width)&&a.maxWidth&&a.maxWidthb.width,h=k(b.height)&&a.minHeight&&a.minHeight>b.height;if(f)b.width=a.minWidth;if(h)b.height=a.minHeight;if(e)b.width=a.maxWidth;if(g)b.height=a.maxHeight;var i=this.originalPosition.left+this.originalSize.width,j=this.position.top+this.size.height, +l=/sw|nw|w/.test(c);c=/nw|ne|n/.test(c);if(f&&l)b.left=i-a.minWidth;if(e&&l)b.left=i-a.maxWidth;if(h&&c)b.top=j-a.minHeight;if(g&&c)b.top=j-a.maxHeight;if((a=!b.width&&!b.height)&&!b.left&&b.top)b.top=null;else if(a&&!b.top&&b.left)b.left=null;return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var b=this.helper||this.element,a=0;a');var a=d.browser.msie&&d.browser.version<7,c=a?1:0;a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-c+"px",top:this.elementOffset.top-c+"px",zIndex:++b.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,a){return{width:this.originalSize.width+ +a}},w:function(b,a){return{left:this.originalPosition.left+a,width:this.originalSize.width-a}},n:function(b,a,c){return{top:this.originalPosition.top+c,height:this.originalSize.height-c}},s:function(b,a,c){return{height:this.originalSize.height+c}},se:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[b,a,c]))},sw:function(b,a,c){return d.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[b,a,c]))},ne:function(b,a,c){return d.extend(this._change.n.apply(this, +arguments),this._change.e.apply(this,[b,a,c]))},nw:function(b,a,c){return d.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[b,a,c]))}},_propagate:function(b,a){d.ui.plugin.call(this,b,[a,this.ui()]);b!="resize"&&this._trigger(b,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});d.extend(d.ui.resizable, +{version:"1.8.2"});d.ui.plugin.add("resizable","alsoResize",{start:function(){var b=d(this).data("resizable").options,a=function(c){d(c).each(function(){d(this).data("resizable-alsoresize",{width:parseInt(d(this).width(),10),height:parseInt(d(this).height(),10),left:parseInt(d(this).css("left"),10),top:parseInt(d(this).css("top"),10)})})};if(typeof b.alsoResize=="object"&&!b.alsoResize.parentNode)if(b.alsoResize.length){b.alsoResize=b.alsoResize[0];a(b.alsoResize)}else d.each(b.alsoResize,function(c){a(c)}); +else a(b.alsoResize)},resize:function(){var b=d(this).data("resizable"),a=b.options,c=b.originalSize,e=b.originalPosition,g={height:b.size.height-c.height||0,width:b.size.width-c.width||0,top:b.position.top-e.top||0,left:b.position.left-e.left||0},f=function(h,i){d(h).each(function(){var j=d(this),l=d(this).data("resizable-alsoresize"),p={};d.each((i&&i.length?i:["width","height","top","left"])||["width","height","top","left"],function(n,o){if((n=(l[o]||0)+(g[o]||0))&&n>=0)p[o]=n||null});if(/relative/.test(j.css("position"))&& +d.browser.opera){b._revertToRelativePosition=true;j.css({position:"absolute",top:"auto",left:"auto"})}j.css(p)})};typeof a.alsoResize=="object"&&!a.alsoResize.nodeType?d.each(a.alsoResize,function(h,i){f(h,i)}):f(a.alsoResize)},stop:function(){var b=d(this).data("resizable");if(b._revertToRelativePosition&&d.browser.opera){b._revertToRelativePosition=false;el.css({position:"relative"})}d(this).removeData("resizable-alsoresize-start")}});d.ui.plugin.add("resizable","animate",{stop:function(b){var a= +d(this).data("resizable"),c=a.options,e=a._proportionallyResizeElements,g=e.length&&/textarea/i.test(e[0].nodeName),f=g&&d.ui.hasScroll(e[0],"left")?0:a.sizeDiff.height;g={width:a.size.width-(g?0:a.sizeDiff.width),height:a.size.height-f};f=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null;var h=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(d.extend(g,h&&f?{top:h,left:f}:{}),{duration:c.animateDuration,easing:c.animateEasing, +step:function(){var i={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10),top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};e&&e.length&&d(e[0]).css({width:i.width,height:i.height});a._updateCache(i);a._propagate("resize",b)}})}});d.ui.plugin.add("resizable","containment",{start:function(){var b=d(this).data("resizable"),a=b.element,c=b.options.containment;if(a=c instanceof d?c.get(0):/parent/.test(c)?a.parent().get(0):c){b.containerElement= +d(a);if(/document/.test(c)||c==document){b.containerOffset={left:0,top:0};b.containerPosition={left:0,top:0};b.parentData={element:d(document),left:0,top:0,width:d(document).width(),height:d(document).height()||document.body.parentNode.scrollHeight}}else{var e=d(a),g=[];d(["Top","Right","Left","Bottom"]).each(function(i,j){g[i]=m(e.css("padding"+j))});b.containerOffset=e.offset();b.containerPosition=e.position();b.containerSize={height:e.innerHeight()-g[3],width:e.innerWidth()-g[1]};c=b.containerOffset; +var f=b.containerSize.height,h=b.containerSize.width;h=d.ui.hasScroll(a,"left")?a.scrollWidth:h;f=d.ui.hasScroll(a)?a.scrollHeight:f;b.parentData={element:a,left:c.left,top:c.top,width:h,height:f}}}},resize:function(b){var a=d(this).data("resizable"),c=a.options,e=a.containerOffset,g=a.position;b=a._aspectRatio||b.shiftKey;var f={top:0,left:0},h=a.containerElement;if(h[0]!=document&&/static/.test(h.css("position")))f=e;if(g.left<(a._helper?e.left:0)){a.size.width+=a._helper?a.position.left-e.left: +a.position.left-f.left;if(b)a.size.height=a.size.width/c.aspectRatio;a.position.left=c.helper?e.left:0}if(g.top<(a._helper?e.top:0)){a.size.height+=a._helper?a.position.top-e.top:a.position.top;if(b)a.size.width=a.size.height*c.aspectRatio;a.position.top=a._helper?e.top:0}a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;c=Math.abs((a._helper?a.offset.left-f.left:a.offset.left-f.left)+a.sizeDiff.width);e=Math.abs((a._helper?a.offset.top-f.top:a.offset.top- +e.top)+a.sizeDiff.height);g=a.containerElement.get(0)==a.element.parent().get(0);f=/relative|absolute/.test(a.containerElement.css("position"));if(g&&f)c-=a.parentData.left;if(c+a.size.width>=a.parentData.width){a.size.width=a.parentData.width-c;if(b)a.size.height=a.size.width/a.aspectRatio}if(e+a.size.height>=a.parentData.height){a.size.height=a.parentData.height-e;if(b)a.size.width=a.size.height*a.aspectRatio}},stop:function(){var b=d(this).data("resizable"),a=b.options,c=b.containerOffset,e=b.containerPosition, +g=b.containerElement,f=d(b.helper),h=f.offset(),i=f.outerWidth()-b.sizeDiff.width;f=f.outerHeight()-b.sizeDiff.height;b._helper&&!a.animate&&/relative/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f});b._helper&&!a.animate&&/static/.test(g.css("position"))&&d(this).css({left:h.left-e.left-c.left,width:i,height:f})}});d.ui.plugin.add("resizable","ghost",{start:function(){var b=d(this).data("resizable"),a=b.options,c=b.size;b.ghost=b.originalElement.clone();b.ghost.css({opacity:0.25, +display:"block",position:"relative",height:c.height,width:c.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof a.ghost=="string"?a.ghost:"");b.ghost.appendTo(b.helper)},resize:function(){var b=d(this).data("resizable");b.ghost&&b.ghost.css({position:"relative",height:b.size.height,width:b.size.width})},stop:function(){var b=d(this).data("resizable");b.ghost&&b.helper&&b.helper.get(0).removeChild(b.ghost.get(0))}});d.ui.plugin.add("resizable","grid",{resize:function(){var b= +d(this).data("resizable"),a=b.options,c=b.size,e=b.originalSize,g=b.originalPosition,f=b.axis;a.grid=typeof a.grid=="number"?[a.grid,a.grid]:a.grid;var h=Math.round((c.width-e.width)/(a.grid[0]||1))*(a.grid[0]||1);a=Math.round((c.height-e.height)/(a.grid[1]||1))*(a.grid[1]||1);if(/^(se|s|e)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a}else if(/^(ne)$/.test(f)){b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}else{if(/^(sw)$/.test(f)){b.size.width=e.width+h;b.size.height= +e.height+a}else{b.size.width=e.width+h;b.size.height=e.height+a;b.position.top=g.top-a}b.position.left=g.left-h}}});var m=function(b){return parseInt(b,10)||0},k=function(b){return!isNaN(parseInt(b,10))}})(jQuery); +; +/* + * jQuery UI Selectable 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Selectables + * + * Depends: + * jquery.ui.core.js + * jquery.ui.mouse.js + * jquery.ui.widget.js + */ +(function(e){e.widget("ui.selectable",e.ui.mouse,{options:{appendTo:"body",autoRefresh:true,distance:0,filter:"*",tolerance:"touch"},_create:function(){var c=this;this.element.addClass("ui-selectable");this.dragged=false;var f;this.refresh=function(){f=e(c.options.filter,c.element[0]);f.each(function(){var d=e(this),b=d.offset();e.data(this,"selectable-item",{element:this,$element:d,left:b.left,top:b.top,right:b.left+d.outerWidth(),bottom:b.top+d.outerHeight(),startselected:false,selected:d.hasClass("ui-selected"), +selecting:d.hasClass("ui-selecting"),unselecting:d.hasClass("ui-unselecting")})})};this.refresh();this.selectees=f.addClass("ui-selectee");this._mouseInit();this.helper=e("
")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting"); +b.unselecting=true;f._trigger("unselecting",c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f= +this;this.dragged=true;if(!this.options.disabled){var d=this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(c){var f=this;this.opos=[c.pageX, +c.pageY];if(!this.options.disabled){var d=this.options;this.selectees=e(d.filter,this.element[0]);this._trigger("start",c);e(d.appendTo).append(this.helper);this.helper.css({"z-index":100,position:"absolute",left:c.clientX,top:c.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var b=e.data(this,"selectable-item");b.startselected=true;if(!c.metaKey){b.$element.removeClass("ui-selected");b.selected=false;b.$element.addClass("ui-unselecting"); +b.unselecting=true;f._trigger("unselecting",c,{unselecting:b.element})}});e(c.target).parents().andSelf().each(function(){var b=e.data(this,"selectable-item");if(b){var g=!c.metaKey||!b.$element.hasClass("ui-selected");b.$element.removeClass(g?"ui-unselecting":"ui-selected").addClass(g?"ui-selecting":"ui-unselecting");b.unselecting=!g;b.selecting=g;(b.selected=g)?f._trigger("selecting",c,{selecting:b.element}):f._trigger("unselecting",c,{unselecting:b.element});return false}})}},_mouseDrag:function(c){var f= +this;this.dragged=true;if(!this.options.disabled){var d=this.options,b=this.opos[0],g=this.opos[1],h=c.pageX,i=c.pageY;if(b>h){var j=h;h=b;b=j}if(g>i){j=i;i=g;g=j}this.helper.css({left:b,top:g,width:h-b,height:i-g});this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!(!a||a.element==f.element[0])){var k=false;if(d.tolerance=="touch")k=!(a.left>h||a.righti||a.bottomb&&a.rightg&&a.bottom").addClass("ui-autocomplete").appendTo("body",c).mousedown(function(){setTimeout(function(){clearTimeout(a.closing)},13)}).menu({focus:function(d,b){b=b.item.data("item.autocomplete"); +false!==a._trigger("focus",null,{item:b})&&/^key/.test(d.originalEvent.type)&&a.element.val(b.value)},selected:function(d,b){b=b.item.data("item.autocomplete");false!==a._trigger("select",d,{item:b})&&a.element.val(b.value);a.close(d);d=a.previous;if(a.element[0]!==c.activeElement){a.element.focus();a.previous=d}a.selectedItem=b},blur:function(){a.menu.element.is(":visible")&&a.element.val(a.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");e.fn.bgiframe&&this.menu.element.bgiframe()}, +destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup");this.menu.element.remove();e.Widget.prototype.destroy.call(this)},_setOption:function(a){e.Widget.prototype._setOption.apply(this,arguments);a==="source"&&this._initSource()},_initSource:function(){var a,c;if(e.isArray(this.options.source)){a=this.options.source;this.source=function(d,b){b(e.ui.autocomplete.filter(a,d.term))}}else if(typeof this.options.source=== +"string"){c=this.options.source;this.source=function(d,b){e.getJSON(c,d,b)}}else this.source=this.options.source},search:function(a,c){a=a!=null?a:this.element.val();if(a.length").data("item.autocomplete", +c).append(""+c.label+"").appendTo(a)},_move:function(a,c){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(a)||this.menu.last()&&/^next/.test(a)){this.element.val(this.term);this.menu.deactivate()}else this.menu[a](c);else this.search(null,c)},widget:function(){return this.menu.element}});e.extend(e.ui.autocomplete,{escapeRegex:function(a){return a.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")},filter:function(a,c){var d=new RegExp(e.ui.autocomplete.escapeRegex(c), +"i");return e.grep(a,function(b){return d.test(b.label||b.value||b)})}})})(jQuery); +(function(e){e.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){if(e(c.target).closest(".ui-menu-item a").length){c.preventDefault();a.select(c)}});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(c){a.activate(c,e(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(a,c){this.deactivate();if(this.hasScroll()){var d=c.offset().top-this.element.offset().top,b=this.element.attr("scrollTop"),f=this.element.height();if(d<0)this.element.attr("scrollTop",b+d);else d>f&&this.element.attr("scrollTop",b+d-f+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",a,{item:c})},deactivate:function(){if(this.active){this.active.children("a").removeClass("ui-state-hover").removeAttr("id"); +this._trigger("blur");this.active=null}},next:function(a){this.move("next",".ui-menu-item:first",a)},previous:function(a){this.move("prev",".ui-menu-item:last",a)},first:function(){return this.active&&!this.active.prev().length},last:function(){return this.active&&!this.active.next().length},move:function(a,c,d){if(this.active){a=this.active[a+"All"](".ui-menu-item").eq(0);a.length?this.activate(d,a):this.activate(d,this.element.children(c))}else this.activate(d,this.element.children(c))},nextPage:function(a){if(this.hasScroll())if(!this.active|| +this.last())this.activate(a,this.element.children(":first"));else{var c=this.active.offset().top,d=this.element.height(),b=this.element.children("li").filter(function(){var f=e(this).offset().top-c-d+e(this).height();return f<10&&f>-10});b.length||(b=this.element.children(":last"));this.activate(a,b)}else this.activate(a,this.element.children(!this.active||this.last()?":first":":last"))},previousPage:function(a){if(this.hasScroll())if(!this.active||this.first())this.activate(a,this.element.children(":last")); +else{var c=this.active.offset().top,d=this.element.height();result=this.element.children("li").filter(function(){var b=e(this).offset().top-c+d-e(this).height();return b<10&&b>-10});result.length||(result=this.element.children(":first"));this.activate(a,result)}else this.activate(a,this.element.children(!this.active||this.first()?":last":":first"))},hasScroll:function(){return this.element.height()").addClass("ui-button-text").html(this.options.label).appendTo(b.empty()).text(),d=this.options.icons,e=d.primary&&d.secondary;if(d.primary||d.secondary){b.addClass("ui-button-text-icon"+(e?"s":""));d.primary&&b.prepend("");d.secondary&&b.append("");if(!this.options.text){b.addClass(e?"ui-button-icons-only":"ui-button-icon-only").removeClass("ui-button-text-icons ui-button-text-icon"); +this.hasTitle||b.attr("title",c)}}else b.addClass("ui-button-text-only")}}});a.widget("ui.buttonset",{_create:function(){this.element.addClass("ui-buttonset");this._init()},_init:function(){this.refresh()},_setOption:function(b,c){b==="disabled"&&this.buttons.button("option",b,c);a.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){this.buttons=this.element.find(":button, :submit, :reset, :checkbox, :radio, a, :data(button)").filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass("ui-corner-left").end().filter(":last").addClass("ui-corner-right").end().end()}, +destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return a(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy");a.Widget.prototype.destroy.call(this)}})})(jQuery); +;/* + * jQuery UI Dialog 1.8.2 + * + * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Dialog + * + * Depends: + * jquery.ui.core.js + * jquery.ui.widget.js + * jquery.ui.button.js + * jquery.ui.draggable.js + * jquery.ui.mouse.js + * jquery.ui.position.js + * jquery.ui.resizable.js + */ +(function(c){c.widget("ui.dialog",{options:{autoOpen:true,buttons:{},closeOnEscape:true,closeText:"close",dialogClass:"",draggable:true,hide:null,height:"auto",maxHeight:false,maxWidth:false,minHeight:150,minWidth:150,modal:false,position:"center",resizable:true,show:null,stack:true,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");var a=this,b=a.options,d=b.title||a.originalTitle||" ",e=c.ui.dialog.getTitleId(a.element),g=(a.uiDialog=c("
")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +b.dialogClass).css({zIndex:b.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(i){if(b.closeOnEscape&&i.keyCode&&i.keyCode===c.ui.keyCode.ESCAPE){a.close(i);i.preventDefault()}}).attr({role:"dialog","aria-labelledby":e}).mousedown(function(i){a.moveToTop(false,i)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(g);var f=(a.uiDialogTitlebar=c("
")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(g), +h=c('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){h.addClass("ui-state-hover")},function(){h.removeClass("ui-state-hover")}).focus(function(){h.addClass("ui-state-focus")}).blur(function(){h.removeClass("ui-state-focus")}).click(function(i){a.close(i);return false}).appendTo(f);(a.uiDialogTitlebarCloseText=c("")).addClass("ui-icon ui-icon-closethick").text(b.closeText).appendTo(h);c("").addClass("ui-dialog-title").attr("id", +e).html(d).prependTo(f);if(c.isFunction(b.beforeclose)&&!c.isFunction(b.beforeClose))b.beforeClose=b.beforeclose;f.find("*").add(f).disableSelection();b.draggable&&c.fn.draggable&&a._makeDraggable();b.resizable&&c.fn.resizable&&a._makeResizable();a._createButtons(b.buttons);a._isOpen=false;c.fn.bgiframe&&g.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){var a=this;a.overlay&&a.overlay.destroy();a.uiDialog.hide();a.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +a.uiDialog.remove();a.originalTitle&&a.element.attr("title",a.originalTitle);return a},widget:function(){return this.uiDialog},close:function(a){var b=this,d;if(false!==b._trigger("beforeClose",a)){b.overlay&&b.overlay.destroy();b.uiDialog.unbind("keypress.ui-dialog");b._isOpen=false;if(b.options.hide)b.uiDialog.hide(b.options.hide,function(){b._trigger("close",a)});else{b.uiDialog.hide();b._trigger("close",a)}c.ui.dialog.overlay.resize();if(b.options.modal){d=0;c(".ui-dialog").each(function(){if(this!== +b.uiDialog[0])d=Math.max(d,c(this).css("z-index"))});c.ui.dialog.maxZ=d}return b}},isOpen:function(){return this._isOpen},moveToTop:function(a,b){var d=this,e=d.options;if(e.modal&&!a||!e.stack&&!e.modal)return d._trigger("focus",b);if(e.zIndex>c.ui.dialog.maxZ)c.ui.dialog.maxZ=e.zIndex;if(d.overlay){c.ui.dialog.maxZ+=1;d.overlay.$el.css("z-index",c.ui.dialog.overlay.maxZ=c.ui.dialog.maxZ)}a={scrollTop:d.element.attr("scrollTop"),scrollLeft:d.element.attr("scrollLeft")};c.ui.dialog.maxZ+=1;d.uiDialog.css("z-index", +c.ui.dialog.maxZ);d.element.attr(a);d._trigger("focus",b);return d},open:function(){if(!this._isOpen){var a=this,b=a.options,d=a.uiDialog;a.overlay=b.modal?new c.ui.dialog.overlay(a):null;d.next().length&&d.appendTo("body");a._size();a._position(b.position);d.show(b.show);a.moveToTop(true);b.modal&&d.bind("keypress.ui-dialog",function(e){if(e.keyCode===c.ui.keyCode.TAB){var g=c(":tabbable",this),f=g.filter(":first");g=g.filter(":last");if(e.target===g[0]&&!e.shiftKey){f.focus(1);return false}else if(e.target=== +f[0]&&e.shiftKey){g.focus(1);return false}}});c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();a._trigger("open");a._isOpen=true;return a}},_createButtons:function(a){var b=this,d=false,e=c("
").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");b.uiDialog.find(".ui-dialog-buttonpane").remove();typeof a==="object"&&a!==null&&c.each(a,function(){return!(d=true)});if(d){c.each(a, +function(g,f){g=c('').text(g).click(function(){f.apply(b.element[0],arguments)}).appendTo(e);c.fn.button&&g.button()});e.appendTo(b.uiDialog)}},_makeDraggable:function(){function a(f){return{position:f.position,offset:f.offset}}var b=this,d=b.options,e=c(document),g;b.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(f,h){g=d.height==="auto"?"auto":c(this).height();c(this).height(c(this).height()).addClass("ui-dialog-dragging"); +b._trigger("dragStart",f,a(h))},drag:function(f,h){b._trigger("drag",f,a(h))},stop:function(f,h){d.position=[h.position.left-e.scrollLeft(),h.position.top-e.scrollTop()];c(this).removeClass("ui-dialog-dragging").height(g);b._trigger("dragStop",f,a(h));c.ui.dialog.overlay.resize()}})},_makeResizable:function(a){function b(f){return{originalPosition:f.originalPosition,originalSize:f.originalSize,position:f.position,size:f.size}}a=a===undefined?this.options.resizable:a;var d=this,e=d.options,g=d.uiDialog.css("position"); +a=typeof a==="string"?a:"n,e,s,w,se,sw,ne,nw";d.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:d.element,maxWidth:e.maxWidth,maxHeight:e.maxHeight,minWidth:e.minWidth,minHeight:d._minHeight(),handles:a,start:function(f,h){c(this).addClass("ui-dialog-resizing");d._trigger("resizeStart",f,b(h))},resize:function(f,h){d._trigger("resize",f,b(h))},stop:function(f,h){c(this).removeClass("ui-dialog-resizing");e.height=c(this).height();e.width=c(this).width();d._trigger("resizeStop", +f,b(h));c.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var a=this.options;return a.height==="auto"?a.minHeight:Math.min(a.minHeight,a.height)},_position:function(a){var b=[],d=[0,0];a=a||c.ui.dialog.prototype.options.position;if(typeof a==="string"||typeof a==="object"&&"0"in a){b=a.split?a.split(" "):[a[0],a[1]];if(b.length===1)b[1]=b[0];c.each(["left","top"],function(e,g){if(+b[e]===b[e]){d[e]=b[e];b[e]= +g}})}else if(typeof a==="object"){if("left"in a){b[0]="left";d[0]=a.left}else if("right"in a){b[0]="right";d[0]=-a.right}if("top"in a){b[1]="top";d[1]=a.top}else if("bottom"in a){b[1]="bottom";d[1]=-a.bottom}}(a=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position({my:b.join(" "),at:b.join(" "),offset:d.join(" "),of:window,collision:"fit",using:function(e){var g=c(this).css(e).offset().top;g<0&&c(this).css("top",e.top-g)}});a||this.uiDialog.hide()},_setOption:function(a, +b){var d=this,e=d.uiDialog,g=e.is(":data(resizable)"),f=false;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":d._createButtons(b);break;case "closeText":d.uiDialogTitlebarCloseText.text(""+b);break;case "dialogClass":e.removeClass(d.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+b);break;case "disabled":b?e.addClass("ui-dialog-disabled"):e.removeClass("ui-dialog-disabled");break;case "draggable":b?d._makeDraggable():e.draggable("destroy");break; +case "height":f=true;break;case "maxHeight":g&&e.resizable("option","maxHeight",b);f=true;break;case "maxWidth":g&&e.resizable("option","maxWidth",b);f=true;break;case "minHeight":g&&e.resizable("option","minHeight",b);f=true;break;case "minWidth":g&&e.resizable("option","minWidth",b);f=true;break;case "position":d._position(b);break;case "resizable":g&&!b&&e.resizable("destroy");g&&typeof b==="string"&&e.resizable("option","handles",b);!g&&b!==false&&d._makeResizable(b);break;case "title":c(".ui-dialog-title", +d.uiDialogTitlebar).html(""+(b||" "));break;case "width":f=true;break}c.Widget.prototype._setOption.apply(d,arguments);f&&d._size()},_size:function(){var a=this.options,b;this.element.css({width:"auto",minHeight:0,height:0});b=this.uiDialog.css({height:"auto",width:a.width}).height();this.element.css(a.height==="auto"?{minHeight:Math.max(a.minHeight-b,0),height:"auto"}:{minHeight:0,height:Math.max(a.height-b,0)}).show();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight", +this._minHeight())}});c.extend(c.ui.dialog,{version:"1.8.2",uuid:0,maxZ:0,getTitleId:function(a){a=a.attr("id");if(!a){this.uuid+=1;a=this.uuid}return"ui-dialog-title-"+a},overlay:function(a){this.$el=c.ui.dialog.overlay.create(a)}});c.extend(c.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:c.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(a){return a+".dialog-overlay"}).join(" "),create:function(a){if(this.instances.length===0){setTimeout(function(){c.ui.dialog.overlay.instances.length&& +c(document).bind(c.ui.dialog.overlay.events,function(d){return c(d.target).zIndex()>=c.ui.dialog.overlay.maxZ})},1);c(document).bind("keydown.dialog-overlay",function(d){if(a.options.closeOnEscape&&d.keyCode&&d.keyCode===c.ui.keyCode.ESCAPE){a.close(d);d.preventDefault()}});c(window).bind("resize.dialog-overlay",c.ui.dialog.overlay.resize)}var b=(this.oldInstances.pop()||c("
").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(),height:this.height()});c.fn.bgiframe&& +b.bgiframe();this.instances.push(b);return b},destroy:function(a){this.oldInstances.push(this.instances.splice(c.inArray(a,this.instances),1)[0]);this.instances.length===0&&c([document,window]).unbind(".dialog-overlay");a.remove();var b=0;c.each(this.instances,function(){b=Math.max(b,this.css("z-index"))});this.maxZ=b},height:function(){var a,b;if(c.browser.msie&&c.browser.version<7){a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight);b=Math.max(document.documentElement.offsetHeight, +document.body.offsetHeight);return a",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:'
  • #{label}
  • '},_create:function(){this._tabify(true)},_setOption:function(c,e){if(c=="selected")this.options.collapsible&& +e==this.options.selected||this.select(e);else{this.options[c]=e;this._tabify()}},_tabId:function(c){return c.title&&c.title.replace(/\s/g,"_").replace(/[^A-Za-z0-9\-_:\.]/g,"")||this.options.idPrefix+s()},_sanitizeSelector:function(c){return c.replace(/:/g,"\\:")},_cookie:function(){var c=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+v());return d.cookie.apply(null,[c].concat(d.makeArray(arguments)))},_ui:function(c,e){return{tab:c,panel:e,index:this.anchors.index(c)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var c= +d(this);c.html(c.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function e(g,f){g.css({display:""});!d.support.opacity&&f.opacity&&g[0].style.removeAttribute("filter")}this.list=this.element.find("ol,ul").eq(0);this.lis=d("li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return d("a",this)[0]});this.panels=d([]);var a=this,b=this.options,h=/^#.+/;this.anchors.each(function(g,f){var j=d(f).attr("href"),l=j.split("#")[0],p;if(l&&(l===location.toString().split("#")[0]|| +(p=d("base")[0])&&l===p.href)){j=f.hash;f.href=j}if(h.test(j))a.panels=a.panels.add(a._sanitizeSelector(j));else if(j!="#"){d.data(f,"href.tabs",j);d.data(f,"load.tabs",j.replace(/#.*$/,""));j=a._tabId(f);f.href="#"+j;f=d("#"+j);if(!f.length){f=d(b.panelTemplate).attr("id",j).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(a.panels[g-1]||a.list);f.data("destroy.tabs",true)}a.panels=a.panels.add(f)}else b.disabled.push(g)});if(c){this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"); +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.lis.addClass("ui-state-default ui-corner-top");this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom");if(b.selected===undefined){location.hash&&this.anchors.each(function(g,f){if(f.hash==location.hash){b.selected=g;return false}});if(typeof b.selected!="number"&&b.cookie)b.selected=parseInt(a._cookie(),10);if(typeof b.selected!="number"&&this.lis.filter(".ui-tabs-selected").length)b.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"));b.selected=b.selected||(this.lis.length?0:-1)}else if(b.selected===null)b.selected=-1;b.selected=b.selected>=0&&this.anchors[b.selected]||b.selected<0?b.selected:0;b.disabled=d.unique(b.disabled.concat(d.map(this.lis.filter(".ui-state-disabled"),function(g){return a.lis.index(g)}))).sort();d.inArray(b.selected,b.disabled)!=-1&&b.disabled.splice(d.inArray(b.selected,b.disabled),1);this.panels.addClass("ui-tabs-hide");this.lis.removeClass("ui-tabs-selected ui-state-active"); +if(b.selected>=0&&this.anchors.length){this.panels.eq(b.selected).removeClass("ui-tabs-hide");this.lis.eq(b.selected).addClass("ui-tabs-selected ui-state-active");a.element.queue("tabs",function(){a._trigger("show",null,a._ui(a.anchors[b.selected],a.panels[b.selected]))});this.load(b.selected)}d(window).bind("unload",function(){a.lis.add(a.anchors).unbind(".tabs");a.lis=a.anchors=a.panels=null})}else b.selected=this.lis.index(this.lis.filter(".ui-tabs-selected"));this.element[b.collapsible?"addClass": +"removeClass"]("ui-tabs-collapsible");b.cookie&&this._cookie(b.selected,b.cookie);c=0;for(var i;i=this.lis[c];c++)d(i)[d.inArray(c,b.disabled)!=-1&&!d(i).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");b.cache===false&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if(b.event!="mouseover"){var k=function(g,f){f.is(":not(.ui-state-disabled)")&&f.addClass("ui-state-"+g)},n=function(g,f){f.removeClass("ui-state-"+g)};this.lis.bind("mouseover.tabs", +function(){k("hover",d(this))});this.lis.bind("mouseout.tabs",function(){n("hover",d(this))});this.anchors.bind("focus.tabs",function(){k("focus",d(this).closest("li"))});this.anchors.bind("blur.tabs",function(){n("focus",d(this).closest("li"))})}var m,o;if(b.fx)if(d.isArray(b.fx)){m=b.fx[0];o=b.fx[1]}else m=o=b.fx;var q=o?function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.hide().removeClass("ui-tabs-hide").animate(o,o.duration||"normal",function(){e(f,o);a._trigger("show", +null,a._ui(g,f[0]))})}:function(g,f){d(g).closest("li").addClass("ui-tabs-selected ui-state-active");f.removeClass("ui-tabs-hide");a._trigger("show",null,a._ui(g,f[0]))},r=m?function(g,f){f.animate(m,m.duration||"normal",function(){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");e(f,m);a.element.dequeue("tabs")})}:function(g,f){a.lis.removeClass("ui-tabs-selected ui-state-active");f.addClass("ui-tabs-hide");a.element.dequeue("tabs")};this.anchors.bind(b.event+".tabs", +function(){var g=this,f=d(this).closest("li"),j=a.panels.filter(":not(.ui-tabs-hide)"),l=d(a._sanitizeSelector(this.hash));if(f.hasClass("ui-tabs-selected")&&!b.collapsible||f.hasClass("ui-state-disabled")||f.hasClass("ui-state-processing")||a._trigger("select",null,a._ui(this,l[0]))===false){this.blur();return false}b.selected=a.anchors.index(this);a.abort();if(b.collapsible)if(f.hasClass("ui-tabs-selected")){b.selected=-1;b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){r(g, +j)}).dequeue("tabs");this.blur();return false}else if(!j.length){b.cookie&&a._cookie(b.selected,b.cookie);a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this));this.blur();return false}b.cookie&&a._cookie(b.selected,b.cookie);if(l.length){j.length&&a.element.queue("tabs",function(){r(g,j)});a.element.queue("tabs",function(){q(g,l)});a.load(a.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier.";d.browser.msie&&this.blur()});this.anchors.bind("click.tabs", +function(){return false})},destroy:function(){var c=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var e=d.data(this,"href.tabs");if(e)this.href=e;var a=d(this).unbind(".tabs");d.each(["href","load","cache"],function(b,h){a.removeData(h+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){d.data(this, +"destroy.tabs")?d(this).remove():d(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});c.cookie&&this._cookie(null,c.cookie);return this},add:function(c,e,a){if(a===undefined)a=this.anchors.length;var b=this,h=this.options;e=d(h.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,e));c=!c.indexOf("#")?c.replace("#",""):this._tabId(d("a",e)[0]);e.addClass("ui-state-default ui-corner-top").data("destroy.tabs", +true);var i=d("#"+c);i.length||(i=d(h.panelTemplate).attr("id",c).data("destroy.tabs",true));i.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");if(a>=this.lis.length){e.appendTo(this.list);i.appendTo(this.list[0].parentNode)}else{e.insertBefore(this.lis[a]);i.insertBefore(this.panels[a])}h.disabled=d.map(h.disabled,function(k){return k>=a?++k:k});this._tabify();if(this.anchors.length==1){h.selected=0;e.addClass("ui-tabs-selected ui-state-active");i.removeClass("ui-tabs-hide"); +this.element.queue("tabs",function(){b._trigger("show",null,b._ui(b.anchors[0],b.panels[0]))});this.load(0)}this._trigger("add",null,this._ui(this.anchors[a],this.panels[a]));return this},remove:function(c){var e=this.options,a=this.lis.eq(c).remove(),b=this.panels.eq(c).remove();if(a.hasClass("ui-tabs-selected")&&this.anchors.length>1)this.select(c+(c+1=c?--h:h});this._tabify();this._trigger("remove", +null,this._ui(a.find("a")[0],b[0]));return this},enable:function(c){var e=this.options;if(d.inArray(c,e.disabled)!=-1){this.lis.eq(c).removeClass("ui-state-disabled");e.disabled=d.grep(e.disabled,function(a){return a!=c});this._trigger("enable",null,this._ui(this.anchors[c],this.panels[c]));return this}},disable:function(c){var e=this.options;if(c!=e.selected){this.lis.eq(c).addClass("ui-state-disabled");e.disabled.push(c);e.disabled.sort();this._trigger("disable",null,this._ui(this.anchors[c],this.panels[c]))}return this}, +select:function(c){if(typeof c=="string")c=this.anchors.index(this.anchors.filter("[href$="+c+"]"));else if(c===null)c=-1;if(c==-1&&this.options.collapsible)c=this.options.selected;this.anchors.eq(c).trigger(this.options.event+".tabs");return this},load:function(c){var e=this,a=this.options,b=this.anchors.eq(c)[0],h=d.data(b,"load.tabs");this.abort();if(!h||this.element.queue("tabs").length!==0&&d.data(b,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(c).addClass("ui-state-processing"); +if(a.spinner){var i=d("span",b);i.data("label.tabs",i.html()).html(a.spinner)}this.xhr=d.ajax(d.extend({},a.ajaxOptions,{url:h,success:function(k,n){d(e._sanitizeSelector(b.hash)).html(k);e._cleanup();a.cache&&d.data(b,"cache.tabs",true);e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.success(k,n)}catch(m){}},error:function(k,n){e._cleanup();e._trigger("load",null,e._ui(e.anchors[c],e.panels[c]));try{a.ajaxOptions.error(k,n,c,b)}catch(m){}}}));e.element.dequeue("tabs");return this}}, +abort:function(){this.element.queue([]);this.panels.stop(false,true);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));if(this.xhr){this.xhr.abort();delete this.xhr}this._cleanup();return this},url:function(c,e){this.anchors.eq(c).removeData("cache.tabs").data("load.tabs",e);return this},length:function(){return this.anchors.length}});d.extend(d.ui.tabs,{version:"1.8.2"});d.extend(d.ui.tabs.prototype,{rotation:null,rotate:function(c,e){var a=this,b=this.options,h=a._rotate||(a._rotate= +function(i){clearTimeout(a.rotation);a.rotation=setTimeout(function(){var k=b.selected;a.select(++k").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});c.wrap(b);b=c.parent();if(c.css("position")=="static"){b.css({position:"relative"});c.css({position:"relative"})}else{f.extend(a,{position:c.css("position"),zIndex:c.css("z-index")});f.each(["top","left","bottom","right"],function(d,e){a[e]=c.css(e);if(isNaN(parseInt(a[e],10)))a[e]="auto"}); +c.css({position:"relative",top:0,left:0})}return b.css(a).show()},removeWrapper:function(c){if(c.parent().is(".ui-effects-wrapper"))return c.parent().replaceWith(c);return c},setTransition:function(c,a,b,d){d=d||{};f.each(a,function(e,g){unit=c.cssUnit(g);if(unit[0]>0)d[g]=unit[0]*b+unit[1]});return d}});f.fn.extend({effect:function(c){var a=j.apply(this,arguments);a={options:a[1],duration:a[2],callback:a[3]};var b=f.effects[c];return b&&!f.fx.off?b.call(this,a):this},_show:f.fn.show,show:function(c){if(!c|| +typeof c=="number"||f.fx.speeds[c])return this._show.apply(this,arguments);else{var a=j.apply(this,arguments);a[1].mode="show";return this.effect.apply(this,a)}},_hide:f.fn.hide,hide:function(c){if(!c||typeof c=="number"||f.fx.speeds[c])return this._hide.apply(this,arguments);else{var a=j.apply(this,arguments);a[1].mode="hide";return this.effect.apply(this,a)}},__toggle:f.fn.toggle,toggle:function(c){if(!c||typeof c=="number"||f.fx.speeds[c]||typeof c=="boolean"||f.isFunction(c))return this.__toggle.apply(this, +arguments);else{var a=j.apply(this,arguments);a[1].mode="toggle";return this.effect.apply(this,a)}},cssUnit:function(c){var a=this.css(c),b=[];f.each(["em","px","%","pt"],function(d,e){if(a.indexOf(e)>0)b=[parseFloat(a),e]});return b}});f.easing.jswing=f.easing.swing;f.extend(f.easing,{def:"easeOutQuad",swing:function(c,a,b,d,e){return f.easing[f.easing.def](c,a,b,d,e)},easeInQuad:function(c,a,b,d,e){return d*(a/=e)*a+b},easeOutQuad:function(c,a,b,d,e){return-d*(a/=e)*(a-2)+b},easeInOutQuad:function(c, +a,b,d,e){if((a/=e/2)<1)return d/2*a*a+b;return-d/2*(--a*(a-2)-1)+b},easeInCubic:function(c,a,b,d,e){return d*(a/=e)*a*a+b},easeOutCubic:function(c,a,b,d,e){return d*((a=a/e-1)*a*a+1)+b},easeInOutCubic:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a+b;return d/2*((a-=2)*a*a+2)+b},easeInQuart:function(c,a,b,d,e){return d*(a/=e)*a*a*a+b},easeOutQuart:function(c,a,b,d,e){return-d*((a=a/e-1)*a*a*a-1)+b},easeInOutQuart:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a+b;return-d/2*((a-=2)*a*a*a-2)+ +b},easeInQuint:function(c,a,b,d,e){return d*(a/=e)*a*a*a*a+b},easeOutQuint:function(c,a,b,d,e){return d*((a=a/e-1)*a*a*a*a+1)+b},easeInOutQuint:function(c,a,b,d,e){if((a/=e/2)<1)return d/2*a*a*a*a*a+b;return d/2*((a-=2)*a*a*a*a+2)+b},easeInSine:function(c,a,b,d,e){return-d*Math.cos(a/e*(Math.PI/2))+d+b},easeOutSine:function(c,a,b,d,e){return d*Math.sin(a/e*(Math.PI/2))+b},easeInOutSine:function(c,a,b,d,e){return-d/2*(Math.cos(Math.PI*a/e)-1)+b},easeInExpo:function(c,a,b,d,e){return a==0?b:d*Math.pow(2, +10*(a/e-1))+b},easeOutExpo:function(c,a,b,d,e){return a==e?b+d:d*(-Math.pow(2,-10*a/e)+1)+b},easeInOutExpo:function(c,a,b,d,e){if(a==0)return b;if(a==e)return b+d;if((a/=e/2)<1)return d/2*Math.pow(2,10*(a-1))+b;return d/2*(-Math.pow(2,-10*--a)+2)+b},easeInCirc:function(c,a,b,d,e){return-d*(Math.sqrt(1-(a/=e)*a)-1)+b},easeOutCirc:function(c,a,b,d,e){return d*Math.sqrt(1-(a=a/e-1)*a)+b},easeInOutCirc:function(c,a,b,d,e){if((a/=e/2)<1)return-d/2*(Math.sqrt(1-a*a)-1)+b;return d/2*(Math.sqrt(1-(a-=2)* +a)+1)+b},easeInElastic:function(c,a,b,d,e){c=1.70158;var g=0,h=d;if(a==0)return b;if((a/=e)==1)return b+d;g||(g=e*0.3);if(h').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1E3}).css(b(this).offset()).appendTo("body")});return!0},_mouseStart:function(a){var c=this.options;this.helper=this._createHelper(a);this._cacheHelperProportions();b.ui.ddmanager&&(b.ui.ddmanager.current=this); +this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.positionAbs=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};b.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this.position=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY= +a.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);c.containment&&this._setContainment();if(!1===this._trigger("start",a))return this._clear(),!1;this._cacheHelperProportions();b.ui.ddmanager&&!c.dropBehaviour&&b.ui.ddmanager.prepareOffsets(this,a);this.helper.addClass("ui-draggable-dragging");this._mouseDrag(a,!0);b.ui.ddmanager&&b.ui.ddmanager.dragStart(this,a);return!0},_mouseDrag:function(a,c){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute"); +if(!c){var d=this._uiHash();if(!1===this._trigger("drag",a,d))return this._mouseUp({}),!1;this.position=d.position}if(!this.options.axis||"y"!=this.options.axis)this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||"x"!=this.options.axis)this.helper[0].style.top=this.position.top+"px";b.ui.ddmanager&&b.ui.ddmanager.drag(this,a);return!1},_mouseStop:function(a){var c=!1;b.ui.ddmanager&&!this.options.dropBehaviour&&(c=b.ui.ddmanager.drop(this,a));this.dropped&&(c=this.dropped,this.dropped= +!1);if((!this.element[0]||!this.element[0].parentNode)&&"original"==this.options.helper)return!1;if("invalid"==this.options.revert&&!c||"valid"==this.options.revert&&c||!0===this.options.revert||b.isFunction(this.options.revert)&&this.options.revert.call(this.element,c)){var d=this;b(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){d._trigger("stop",a)!==false&&d._clear()})}else!1!==this._trigger("stop",a)&&this._clear();return!1},_mouseUp:function(a){!0=== +this.options.iframeFix&&b("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)});b.ui.ddmanager&&b.ui.ddmanager.dragStop(this,a);return b.ui.mouse.prototype._mouseUp.call(this,a)},cancel:function(){this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear();return this},_getHandle:function(a){var c=!this.options.handle||!b(this.options.handle,this.element).length?!0:!1;b(this.options.handle,this.element).find("*").andSelf().each(function(){this==a.target&&(c= +!0)});return c},_createHelper:function(a){var c=this.options,a=b.isFunction(c.helper)?b(c.helper.apply(this.element[0],[a])):"clone"==c.helper?this.element.clone().removeAttr("id"):this.element;a.parents("body").length||a.appendTo("parent"==c.appendTo?this.element[0].parentNode:c.appendTo);a[0]!=this.element[0]&&!/(fixed|absolute)/.test(a.css("position"))&&a.css("position","absolute");return a},_adjustOffsetFromHelper:function(a){"string"==typeof a&&(a=a.split(" "));b.isArray(a)&&(a={left:+a[0],top:+a[1]|| +0});"left"in a&&(this.offset.click.left=a.left+this.margins.left);"right"in a&&(this.offset.click.left=this.helperProportions.width-a.right+this.margins.left);"top"in a&&(this.offset.click.top=a.top+this.margins.top);"bottom"in a&&(this.offset.click.top=this.helperProportions.height-a.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var a=this.offsetParent.offset();"absolute"==this.cssPosition&&(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0], +this.offsetParent[0]))&&(a.left+=this.scrollParent.scrollLeft(),a.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&"html"==this.offsetParent[0].tagName.toLowerCase()&&b.browser.msie)a={top:0,left:0};return{top:a.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:a.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if("relative"==this.cssPosition){var b=this.element.position();return{top:b.top- +(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(), +height:this.helper.outerHeight()}},_setContainment:function(){var a=this.options;"parent"==a.containment&&(a.containment=this.helper[0].parentNode);if("document"==a.containment||"window"==a.containment)this.containment=["document"==a.containment?0:b(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,"document"==a.containment?0:b(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,("document"==a.containment?0:b(window).scrollLeft())+b("document"==a.containment?document: +window).width()-this.helperProportions.width-this.margins.left,("document"==a.containment?0:b(window).scrollTop())+(b("document"==a.containment?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(a.containment)&&a.containment.constructor!=Array){var a=b(a.containment),c=a[0];if(c){a.offset();var d="hidden"!=b(c).css("overflow");this.containment=[(parseInt(b(c).css("borderLeftWidth"),10)||0)+(parseInt(b(c).css("paddingLeft"), +10)||0),(parseInt(b(c).css("borderTopWidth"),10)||0)+(parseInt(b(c).css("paddingTop"),10)||0),(d?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(b(c).css("borderLeftWidth"),10)||0)-(parseInt(b(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(d?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(b(c).css("borderTopWidth"),10)||0)-(parseInt(b(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom]; +this.relative_container=a}}else a.containment.constructor==Array&&(this.containment=a.containment)},_convertPositionTo:function(a,c){c||(c=this.position);var d="absolute"==a?1:-1,g="absolute"==this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,h=/(html|body)/i.test(g[0].tagName);return{top:c.top+this.offset.relative.top*d+this.offset.parent.top*d-(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition? +0:("fixed"==this.cssPosition?-this.scrollParent.scrollTop():h?0:g.scrollTop())*d),left:c.left+this.offset.relative.left*d+this.offset.parent.left*d-(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:("fixed"==this.cssPosition?-this.scrollParent.scrollLeft():h?0:g.scrollLeft())*d)}},_generatePosition:function(a){var c=this.options,d="absolute"==this.cssPosition&&!(this.scrollParent[0]!=document&&b.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent, +g=/(html|body)/i.test(d[0].tagName),h=a.pageX,e=a.pageY;if(this.originalPosition){var f;this.containment&&(this.relative_container?(f=this.relative_container.offset(),f=[this.containment[0]+f.left,this.containment[1]+f.top,this.containment[2]+f.left,this.containment[3]+f.top]):f=this.containment,a.pageX-this.offset.click.leftf[2]&&(h=f[2]+this.offset.click.left), +a.pageY-this.offset.click.top>f[3]&&(e=f[3]+this.offset.click.top));c.grid&&(e=c.grid[1]?this.originalPageY+Math.round((e-this.originalPageY)/c.grid[1])*c.grid[1]:this.originalPageY,e=f?!(e-this.offset.click.topf[3])?e:!(e-this.offset.click.topf[2])?h:!(h-this.offset.click.left< +f[0])?h-c.grid[0]:h+c.grid[0]:h)}return{top:e-this.offset.click.top-this.offset.relative.top-this.offset.parent.top+(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollTop():g?0:d.scrollTop()),left:h-this.offset.click.left-this.offset.relative.left-this.offset.parent.left+(b.browser.safari&&526>b.browser.version&&"fixed"==this.cssPosition?0:"fixed"==this.cssPosition?-this.scrollParent.scrollLeft():g?0:d.scrollLeft())}},_clear:function(){this.helper.removeClass("ui-draggable-dragging"); +this.helper[0]!=this.element[0]&&!this.cancelHelperRemoval&&this.helper.remove();this.helper=null;this.cancelHelperRemoval=!1},_trigger:function(a,c,d){d=d||this._uiHash();b.ui.plugin.call(this,a,[c,d]);"drag"==a&&(this.positionAbs=this._convertPositionTo("absolute"));return b.Widget.prototype._trigger.call(this,a,c,d)},plugins:{},_uiHash:function(){return{helper:this.helper,position:this.position,originalPosition:this.originalPosition,offset:this.positionAbs}}});b.extend(b.ui.draggable,{version:"1.8.14"}); +b.ui.plugin.add("draggable","connectToSortable",{start:function(a,c){var d=b(this).data("draggable"),g=d.options,h=b.extend({},c,{item:d.element});d.sortables=[];b(g.connectToSortable).each(function(){var c=b.data(this,"sortable");c&&!c.options.disabled&&(d.sortables.push({instance:c,shouldRevert:c.options.revert}),c.refreshPositions(),c._trigger("activate",a,h))})},stop:function(a,c){var d=b(this).data("draggable"),g=b.extend({},c,{item:d.element});b.each(d.sortables,function(){this.instance.isOver? +(this.instance.isOver=0,d.cancelHelperRemoval=!0,this.instance.cancelHelperRemoval=!1,this.shouldRevert&&(this.instance.options.revert=!0),this.instance._mouseStop(a),this.instance.options.helper=this.instance.options._helper,"original"==d.options.helper&&this.instance.currentItem.css({top:"auto",left:"auto"})):(this.instance.cancelHelperRemoval=!1,this.instance._trigger("deactivate",a,g))})},drag:function(a,c){var d=b(this).data("draggable"),g=this;b.each(d.sortables,function(){this.instance.positionAbs= +d.positionAbs;this.instance.helperProportions=d.helperProportions;this.instance.offset.click=d.offset.click;this.instance._intersectsWith(this.instance.containerCache)?(this.instance.isOver||(this.instance.isOver=1,this.instance.currentItem=b(g).clone().removeAttr("id").appendTo(this.instance.element).data("sortable-item",!0),this.instance.options._helper=this.instance.options.helper,this.instance.options.helper=function(){return c.helper[0]},a.target=this.instance.currentItem[0],this.instance._mouseCapture(a, +!0),this.instance._mouseStart(a,!0,!0),this.instance.offset.click.top=d.offset.click.top,this.instance.offset.click.left=d.offset.click.left,this.instance.offset.parent.left-=d.offset.parent.left-this.instance.offset.parent.left,this.instance.offset.parent.top-=d.offset.parent.top-this.instance.offset.parent.top,d._trigger("toSortable",a),d.dropped=this.instance.element,d.currentItem=d.element,this.instance.fromOutside=d),this.instance.currentItem&&this.instance._mouseDrag(a)):this.instance.isOver&& +(this.instance.isOver=0,this.instance.cancelHelperRemoval=!0,this.instance.options.revert=!1,this.instance._trigger("out",a,this.instance._uiHash(this.instance)),this.instance._mouseStop(a,!0),this.instance.options.helper=this.instance.options._helper,this.instance.currentItem.remove(),this.instance.placeholder&&this.instance.placeholder.remove(),d._trigger("fromSortable",a),d.dropped=!1)})}});b.ui.plugin.add("draggable","cursor",{start:function(){var a=b("body"),c=b(this).data("draggable").options; +a.css("cursor")&&(c._cursor=a.css("cursor"));a.css("cursor",c.cursor)},stop:function(){var a=b(this).data("draggable").options;a._cursor&&b("body").css("cursor",a._cursor)}});b.ui.plugin.add("draggable","opacity",{start:function(a,c){var d=b(c.helper),g=b(this).data("draggable").options;d.css("opacity")&&(g._opacity=d.css("opacity"));d.css("opacity",g.opacity)},stop:function(a,c){var d=b(this).data("draggable").options;d._opacity&&b(c.helper).css("opacity",d._opacity)}});b.ui.plugin.add("draggable", +"scroll",{start:function(){var a=b(this).data("draggable");a.scrollParent[0]!=document&&"HTML"!=a.scrollParent[0].tagName&&(a.overflowOffset=a.scrollParent.offset())},drag:function(a){var c=b(this).data("draggable"),d=c.options,g=!1;if(c.scrollParent[0]!=document&&"HTML"!=c.scrollParent[0].tagName){if(!d.axis||"x"!=d.axis)c.overflowOffset.top+c.scrollParent[0].offsetHeight-a.pageY=k&&e<=l||f>=k&&f<=l||el)&&(g>=i&&g<=j||h>=i&&h<=j||gj);default:return!1}}; +b.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(a,c){var d=b.ui.ddmanager.droppables[a.options.scope]||[],g=c?c.type:null,h=(a.currentItem||a.element).find(":data(droppable)").andSelf(),e=0;a:for(;e').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})), +this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize", +"none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize());this.handles=a.handles||(!b(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){"all"== +this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw");var h=this.handles.split(",");this.handles={};for(var e=0;e');/sw|se|ne|nw/.test(f)&&i.css({zIndex:++a.zIndex});"se"==f&&i.addClass("ui-icon ui-icon-gripsmall-diagonal-se");this.handles[f]=".ui-resizable-"+f;this.element.append(i)}}this._renderAxis=function(f){var f=f||this.element,c;for(c in this.handles){this.handles[c].constructor==String&&(this.handles[c]= +b(this.handles[c],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var a=b(this.handles[c],this.element),d=0,d=/sw|ne|nw|se|n|s/.test(c)?a.outerHeight():a.outerWidth(),a=["padding",/ne|nw|n/.test(c)?"Top":/se|sw|s/.test(c)?"Bottom":/^e$/.test(c)?"Right":"Left"].join("");f.css(a,d);this._proportionallyResize()}b(this.handles[c])}};this._renderAxis(this.element);this._handles=b(".ui-resizable-handle",this.element).disableSelection(); +this._handles.mouseover(function(){if(!c.resizing){if(this.className)var b=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);c.axis=b&&b[1]?b[1]:"se"}});a.autoHide&&(this._handles.hide(),b(this.element).addClass("ui-resizable-autohide").hover(function(){if(!a.disabled){b(this).removeClass("ui-resizable-autohide");c._handles.show()}},function(){if(!a.disabled&&!c.resizing){b(this).addClass("ui-resizable-autohide");c._handles.hide()}}));this._mouseInit()},destroy:function(){this._mouseDestroy(); +var c=function(c){b(c).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){c(this.element);var a=this.element;a.after(this.originalElement.css({position:a.css("position"),width:a.outerWidth(),height:a.outerHeight(),top:a.css("top"),left:a.css("left")})).remove()}this.originalElement.css("resize",this.originalResizeStyle);c(this.originalElement);return this},_mouseCapture:function(c){var a= +!1,h;for(h in this.handles)b(this.handles[h])[0]==c.target&&(a=!0);return!this.options.disabled&&a},_mouseStart:function(c){var g=this.options,h=this.element.position(),e=this.element;this.resizing=!0;this.documentScroll={top:b(document).scrollTop(),left:b(document).scrollLeft()};(e.is(".ui-draggable")||/absolute/.test(e.css("position")))&&e.css({position:"absolute",top:h.top,left:h.left});b.browser.opera&&/relative/.test(e.css("position"))&&e.css({position:"relative",top:"auto",left:"auto"});this._renderProxy(); +var h=a(this.helper.css("left")),f=a(this.helper.css("top"));g.containment&&(h+=b(g.containment).scrollLeft()||0,f+=b(g.containment).scrollTop()||0);this.offset=this.helper.offset();this.position={left:h,top:f};this.size=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalSize=this._helper?{width:e.outerWidth(),height:e.outerHeight()}:{width:e.width(),height:e.height()};this.originalPosition={left:h,top:f};this.sizeDiff={width:e.outerWidth()- +e.width(),height:e.outerHeight()-e.height()};this.originalMousePosition={left:c.pageX,top:c.pageY};this.aspectRatio="number"==typeof g.aspectRatio?g.aspectRatio:this.originalSize.width/this.originalSize.height||1;g=b(".ui-resizable-"+this.axis).css("cursor");b("body").css("cursor","auto"==g?this.axis+"-resize":g);e.addClass("ui-resizable-resizing");this._propagate("start",c);return!0},_mouseDrag:function(b){var c=this.helper,a=this.originalMousePosition,e=this._change[this.axis];if(!e)return!1;a= +e.apply(this,[b,b.pageX-a.left||0,b.pageY-a.top||0]);this._updateVirtualBoundaries(b.shiftKey);if(this._aspectRatio||b.shiftKey)a=this._updateRatio(a,b);a=this._respectSize(a,b);this._propagate("resize",b);c.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize();this._updateCache(a);this._trigger("resize",b,this.ui());return!1},_mouseStop:function(c){this.resizing= +!1;var a=this.options;if(this._helper){var h=this._proportionallyResizeElements,e=h.length&&/textarea/i.test(h[0].nodeName),h=e&&b.ui.hasScroll(h[0],"left")?0:this.sizeDiff.height,e=e?0:this.sizeDiff.width,e={width:this.helper.width()-e,height:this.helper.height()-h},h=parseInt(this.element.css("left"),10)+(this.position.left-this.originalPosition.left)||null,f=parseInt(this.element.css("top"),10)+(this.position.top-this.originalPosition.top)||null;a.animate||this.element.css(b.extend(e,{top:f,left:h})); +this.helper.height(this.size.height);this.helper.width(this.size.width);this._helper&&!a.animate&&this._proportionallyResize()}b("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",c);this._helper&&this.helper.remove();return!1},_updateVirtualBoundaries:function(b){var a=this.options,h,e,f,a={minWidth:c(a.minWidth)?a.minWidth:0,maxWidth:c(a.maxWidth)?a.maxWidth:Infinity,minHeight:c(a.minHeight)?a.minHeight:0,maxHeight:c(a.maxHeight)?a.maxHeight:Infinity}; +if(this._aspectRatio||b)if(b=a.minHeight*this.aspectRatio,e=a.minWidth/this.aspectRatio,h=a.maxHeight*this.aspectRatio,f=a.maxWidth/this.aspectRatio,b>a.minWidth&&(a.minWidth=b),e>a.minHeight&&(a.minHeight=e),hb.width,j=c(b.height)&&a.minHeight&&a.minHeight> +b.height;i&&(b.width=a.minWidth);j&&(b.height=a.minHeight);e&&(b.width=a.maxWidth);f&&(b.height=a.maxHeight);var k=this.originalPosition.left+this.originalSize.width,l=this.position.top+this.size.height,m=/sw|nw|w/.test(h),h=/nw|ne|n/.test(h);i&&m&&(b.left=k-a.minWidth);e&&m&&(b.left=k-a.maxWidth);j&&h&&(b.top=l-a.minHeight);f&&h&&(b.top=l-a.maxHeight);(a=!b.width&&!b.height)&&!b.left&&b.top?b.top=null:a&&(!b.top&&b.left)&&(b.left=null);return b},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var c= +this.helper||this.element,a=0;a');var a=b.browser.msie&&7>b.browser.version,h=a?1:0,a=a?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+a,height:this.element.outerHeight()+a,position:"absolute",left:this.elementOffset.left-h+"px",top:this.elementOffset.top- +h+"px",zIndex:++c.zIndex});this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(b,c){return{width:this.originalSize.width+c}},w:function(b,c){return{left:this.originalPosition.left+c,width:this.originalSize.width-c}},n:function(b,c,a){return{top:this.originalPosition.top+a,height:this.originalSize.height-a}},s:function(b,c,a){return{height:this.originalSize.height+a}},se:function(c,a,h){return b.extend(this._change.s.apply(this,arguments),this._change.e.apply(this, +[c,a,h]))},sw:function(c,a,h){return b.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[c,a,h]))},ne:function(c,a,h){return b.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[c,a,h]))},nw:function(c,a,h){return b.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[c,a,h]))}},_propagate:function(c,a){b.ui.plugin.call(this,c,[a,this.ui()]);"resize"!=c&&this._trigger(c,a,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement, +element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}});b.extend(b.ui.resizable,{version:"1.8.14"});b.ui.plugin.add("resizable","alsoResize",{start:function(){var c=b(this).data("resizable").options,a=function(c){b(c).each(function(){var c=b(this);c.data("resizable-alsoresize",{width:parseInt(c.width(),10),height:parseInt(c.height(),10),left:parseInt(c.css("left"),10),top:parseInt(c.css("top"),10),position:c.css("position")})})}; +"object"==typeof c.alsoResize&&!c.alsoResize.parentNode?c.alsoResize.length?(c.alsoResize=c.alsoResize[0],a(c.alsoResize)):b.each(c.alsoResize,function(b){a(b)}):a(c.alsoResize)},resize:function(c,a){var h=b(this).data("resizable"),e=h.options,f=h.originalSize,i=h.originalPosition,j={height:h.size.height-f.height||0,width:h.size.width-f.width||0,top:h.position.top-i.top||0,left:h.position.left-i.left||0},k=function(c,f){b(c).each(function(){var c=b(this),d=b(this).data("resizable-alsoresize"),i={}, +e=f&&f.length?f:c.parents(a.originalElement[0]).length?["width","height"]:["width","height","top","left"];b.each(e,function(b,c){var a=(d[c]||0)+(j[c]||0);a&&0<=a&&(i[c]=a||null)});b.browser.opera&&/relative/.test(c.css("position"))&&(h._revertToRelativePosition=!0,c.css({position:"absolute",top:"auto",left:"auto"}));c.css(i)})};"object"==typeof e.alsoResize&&!e.alsoResize.nodeType?b.each(e.alsoResize,function(b,c){k(b,c)}):k(e.alsoResize)},stop:function(){var c=b(this).data("resizable"),a=c.options, +h=function(c){b(c).each(function(){var c=b(this);c.css({position:c.data("resizable-alsoresize").position})})};c._revertToRelativePosition&&(c._revertToRelativePosition=!1,"object"==typeof a.alsoResize&&!a.alsoResize.nodeType?b.each(a.alsoResize,function(b){h(b)}):h(a.alsoResize));b(this).removeData("resizable-alsoresize")}});b.ui.plugin.add("resizable","animate",{stop:function(c){var a=b(this).data("resizable"),h=a.options,e=a._proportionallyResizeElements,f=e.length&&/textarea/i.test(e[0].nodeName), +i=f&&b.ui.hasScroll(e[0],"left")?0:a.sizeDiff.height,f={width:a.size.width-(f?0:a.sizeDiff.width),height:a.size.height-i},i=parseInt(a.element.css("left"),10)+(a.position.left-a.originalPosition.left)||null,j=parseInt(a.element.css("top"),10)+(a.position.top-a.originalPosition.top)||null;a.element.animate(b.extend(f,j&&i?{top:j,left:i}:{}),{duration:h.animateDuration,easing:h.animateEasing,step:function(){var f={width:parseInt(a.element.css("width"),10),height:parseInt(a.element.css("height"),10), +top:parseInt(a.element.css("top"),10),left:parseInt(a.element.css("left"),10)};e&&e.length&&b(e[0]).css({width:f.width,height:f.height});a._updateCache(f);a._propagate("resize",c)}})}});b.ui.plugin.add("resizable","containment",{start:function(){var c=b(this).data("resizable"),g=c.element,h=c.options.containment;if(g=h instanceof b?h.get(0):/parent/.test(h)?g.parent().get(0):h)if(c.containerElement=b(g),/document/.test(h)||h==document)c.containerOffset={left:0,top:0},c.containerPosition={left:0,top:0}, +c.parentData={element:b(document),left:0,top:0,width:b(document).width(),height:b(document).height()||document.body.parentNode.scrollHeight};else{var e=b(g),f=[];b(["Top","Right","Left","Bottom"]).each(function(b,c){f[b]=a(e.css("padding"+c))});c.containerOffset=e.offset();c.containerPosition=e.position();c.containerSize={height:e.innerHeight()-f[3],width:e.innerWidth()-f[1]};var h=c.containerOffset,i=c.containerSize.height,j=c.containerSize.width,j=b.ui.hasScroll(g,"left")?g.scrollWidth:j,i=b.ui.hasScroll(g)? +g.scrollHeight:i;c.parentData={element:g,left:h.left,top:h.top,width:j,height:i}}},resize:function(c){var a=b(this).data("resizable"),h=a.options,e=a.containerOffset,f=a.position,c=a._aspectRatio||c.shiftKey,i={top:0,left:0},j=a.containerElement;j[0]!=document&&/static/.test(j.css("position"))&&(i=e);if(f.left<(a._helper?e.left:0))a.size.width+=a._helper?a.position.left-e.left:a.position.left-i.left,c&&(a.size.height=a.size.width/h.aspectRatio),a.position.left=h.helper?e.left:0;if(f.top<(a._helper? +e.top:0))a.size.height+=a._helper?a.position.top-e.top:a.position.top,c&&(a.size.width=a.size.height*h.aspectRatio),a.position.top=a._helper?e.top:0;a.offset.left=a.parentData.left+a.position.left;a.offset.top=a.parentData.top+a.position.top;h=Math.abs(a.offset.left-i.left+a.sizeDiff.width);e=Math.abs((a._helper?a.offset.top-i.top:a.offset.top-e.top)+a.sizeDiff.height);f=a.containerElement.get(0)==a.element.parent().get(0);i=/relative|absolute/.test(a.containerElement.css("position"));f&&i&&(h-=a.parentData.left); +h+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-h,c&&(a.size.height=a.size.width/a.aspectRatio));e+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-e,c&&(a.size.width=a.size.height*a.aspectRatio))},stop:function(){var a=b(this).data("resizable"),c=a.options,h=a.containerOffset,e=a.containerPosition,f=a.containerElement,i=b(a.helper),j=i.offset(),k=i.outerWidth()-a.sizeDiff.width,i=i.outerHeight()-a.sizeDiff.height;a._helper&&(!c.animate&&/relative/.test(f.css("position")))&& +b(this).css({left:j.left-e.left-h.left,width:k,height:i});a._helper&&(!c.animate&&/static/.test(f.css("position")))&&b(this).css({left:j.left-e.left-h.left,width:k,height:i})}});b.ui.plugin.add("resizable","ghost",{start:function(){var a=b(this).data("resizable"),c=a.options,h=a.size;a.ghost=a.originalElement.clone();a.ghost.css({opacity:0.25,display:"block",position:"relative",height:h.height,width:h.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass("string"==typeof c.ghost?c.ghost: +"");a.ghost.appendTo(a.helper)},resize:function(){var a=b(this).data("resizable");a.ghost&&a.ghost.css({position:"relative",height:a.size.height,width:a.size.width})},stop:function(){var a=b(this).data("resizable");a.ghost&&a.helper&&a.helper.get(0).removeChild(a.ghost.get(0))}});b.ui.plugin.add("resizable","grid",{resize:function(){var a=b(this).data("resizable"),c=a.options,h=a.size,e=a.originalSize,f=a.originalPosition,i=a.axis;c.grid="number"==typeof c.grid?[c.grid,c.grid]:c.grid;var j=Math.round((h.width- +e.width)/(c.grid[0]||1))*(c.grid[0]||1),c=Math.round((h.height-e.height)/(c.grid[1]||1))*(c.grid[1]||1);/^(se|s|e)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c):/^(ne)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c,a.position.top=f.top-c):(/^(sw)$/.test(i)?(a.size.width=e.width+j,a.size.height=e.height+c):(a.size.width=e.width+j,a.size.height=e.height+c,a.position.top=f.top-c),a.position.left=f.left-j)}});var a=function(b){return parseInt(b,10)||0},c=function(b){return!isNaN(parseInt(b, +10))}})(jQuery); +(function(b){b.widget("ui.selectable",b.ui.mouse,{options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var a=this;this.element.addClass("ui-selectable");this.dragged=!1;var c;this.refresh=function(){c=b(a.options.filter,a.element[0]);c.each(function(){var a=b(this),c=a.offset();b.data(this,"selectable-item",{element:this,$element:a,left:c.left,top:c.top,right:c.left+a.outerWidth(),bottom:c.top+a.outerHeight(),startselected:!1,selected:a.hasClass("ui-selected"),selecting:a.hasClass("ui-selecting"), +unselecting:a.hasClass("ui-unselecting")})})};this.refresh();this.selectees=c.addClass("ui-selectee");this._mouseInit();this.helper=b("
    ")},destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item");this.element.removeClass("ui-selectable ui-selectable-disabled").removeData("selectable").unbind(".selectable");this._mouseDestroy();return this},_mouseStart:function(a){var c=this;this.opos=[a.pageX,a.pageY];if(!this.options.disabled){var d= +this.options;this.selectees=b(d.filter,this.element[0]);this._trigger("start",a);b(d.appendTo).append(this.helper);this.helper.css({left:a.clientX,top:a.clientY,width:0,height:0});d.autoRefresh&&this.refresh();this.selectees.filter(".ui-selected").each(function(){var d=b.data(this,"selectable-item");d.startselected=!0;a.metaKey||(d.$element.removeClass("ui-selected"),d.selected=!1,d.$element.addClass("ui-unselecting"),d.unselecting=!0,c._trigger("unselecting",a,{unselecting:d.element}))});b(a.target).parents().andSelf().each(function(){var d= +b.data(this,"selectable-item");if(d){var h=!a.metaKey||!d.$element.hasClass("ui-selected");d.$element.removeClass(h?"ui-unselecting":"ui-selected").addClass(h?"ui-selecting":"ui-unselecting");d.unselecting=!h;d.selecting=h;(d.selected=h)?c._trigger("selecting",a,{selecting:d.element}):c._trigger("unselecting",a,{unselecting:d.element});return!1}})}},_mouseDrag:function(a){var c=this;this.dragged=!0;if(!this.options.disabled){var d=this.options,g=this.opos[0],h=this.opos[1],e=a.pageX,f=a.pageY;if(g> +e)var i=e,e=g,g=i;h>f&&(i=f,f=h,h=i);this.helper.css({left:g,top:h,width:e-g,height:f-h});this.selectees.each(function(){var i=b.data(this,"selectable-item");if(i&&i.element!=c.element[0]){var k=false;d.tolerance=="touch"?k=!(i.left>e||i.rightf||i.bottomg&&i.righth&&i.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1E3},_create:function(){var b=this.options;this.containerCache={};this.element.addClass("ui-sortable");this.refresh(); +this.floating=this.items.length?"x"===b.axis||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1;this.offset=this.element.offset();this._mouseInit()},destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled").removeData("sortable").unbind(".sortable");this._mouseDestroy();for(var b=this.items.length-1;0<=b;b--)this.items[b].item.removeData("sortable-item");return this},_setOption:function(a,c){"disabled"===a?(this.options[a]= +c,this.widget()[c?"addClass":"removeClass"]("ui-sortable-disabled")):b.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(a,c){if(this.reverting||this.options.disabled||"static"==this.options.type)return!1;this._refreshItems(a);var d=null,g=this;b(a.target).parents().each(function(){if(b.data(this,"sortable-item")==g)return d=b(this),!1});b.data(a.target,"sortable-item")==g&&(d=b(a.target));if(!d)return!1;if(this.options.handle&&!c){var h=!1;b(this.options.handle,d).find("*").andSelf().each(function(){this== +a.target&&(h=!0)});if(!h)return!1}this.currentItem=d;this._removeCurrentsFromItems();return!0},_mouseStart:function(a,c,d){c=this.options;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(a);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition= +this.helper.css("position");b.extend(this.offset,{click:{left:a.pageX-this.offset.left,top:a.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(a);this.originalPageX=a.pageX;this.originalPageY=a.pageY;c.cursorAt&&this._adjustOffsetFromHelper(c.cursorAt);this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};this.helper[0]!=this.currentItem[0]&&this.currentItem.hide();this._createPlaceholder(); +c.containment&&this._setContainment();c.cursor&&(b("body").css("cursor")&&(this._storedCursor=b("body").css("cursor")),b("body").css("cursor",c.cursor));c.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",c.opacity));c.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",c.zIndex));this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName&&(this.overflowOffset=this.scrollParent.offset()); +this._trigger("start",a,this._uiHash());this._preserveHelperProportions||this._cacheHelperProportions();if(!d)for(d=this.containers.length-1;0<=d;d--)this.containers[d]._trigger("activate",a,this._uiHash(this));b.ui.ddmanager&&(b.ui.ddmanager.current=this);b.ui.ddmanager&&!c.dropBehaviour&&b.ui.ddmanager.prepareOffsets(this,a);this.dragging=!0;this.helper.addClass("ui-sortable-helper");this._mouseDrag(a);return!0},_mouseDrag:function(a){this.position=this._generatePosition(a);this.positionAbs=this._convertPositionTo("absolute"); +this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var c=this.options,d=!1;this.scrollParent[0]!=document&&"HTML"!=this.scrollParent[0].tagName?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-a.pageYb[this.floating?"width":"height"]?g+k>i&&g+ke&&c+lthis.containment[2]&&(h=this.containment[2]+this.offset.click.left),a.pageY-this.offset.click.top>this.containment[3]&&(e=this.containment[3]+this.offset.click.top)),c.grid))e=this.originalPageY+Math.round((e-this.originalPageY)/c.grid[1])*c.grid[1],e=this.containment?!(e-this.offset.click.topthis.containment[3])?e:!(e-this.offset.click.top< +this.containment[1])?e-c.grid[1]:e+c.grid[1]:e,h=this.originalPageX+Math.round((h-this.originalPageX)/c.grid[0])*c.grid[0],h=this.containment?!(h-this.offset.click.leftthis.containment[2])?h:!(h-this.offset.click.left li > :first-child,> :not(li):even",icons:{header:"ui-icon-triangle-1-e",headerSelected:"ui-icon-triangle-1-s"},navigation:!1,navigationFilter:function(){return this.href.toLowerCase()===location.href.toLowerCase()}},_create:function(){var a=this,c=a.options;a.running=0;a.element.addClass("ui-accordion ui-widget ui-helper-reset").children("li").addClass("ui-accordion-li-fix");a.headers= +a.element.find(c.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all").bind("mouseenter.accordion",function(){c.disabled||b(this).addClass("ui-state-hover")}).bind("mouseleave.accordion",function(){c.disabled||b(this).removeClass("ui-state-hover")}).bind("focus.accordion",function(){c.disabled||b(this).addClass("ui-state-focus")}).bind("blur.accordion",function(){c.disabled||b(this).removeClass("ui-state-focus")});a.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom"); +if(c.navigation){var d=a.element.find("a").filter(c.navigationFilter).eq(0);if(d.length){var g=d.closest(".ui-accordion-header");a.active=g.length?g:d.closest(".ui-accordion-content").prev()}}a.active=a._findActive(a.active||c.active).addClass("ui-state-default ui-state-active").toggleClass("ui-corner-all").toggleClass("ui-corner-top");a.active.next().addClass("ui-accordion-content-active");a._createIcons();a.resize();a.element.attr("role","tablist");a.headers.attr("role","tab").bind("keydown.accordion", +function(b){return a._keydown(b)}).next().attr("role","tabpanel");a.headers.not(a.active||"").attr({"aria-expanded":"false","aria-selected":"false",tabIndex:-1}).next().hide();a.active.length?a.active.attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}):a.headers.eq(0).attr("tabIndex",0);b.browser.safari||a.headers.find("a").attr("tabIndex",-1);c.event&&a.headers.bind(c.event.split(" ").join(".accordion ")+".accordion",function(b){a._clickHandler.call(a,b,this);b.preventDefault()})},_createIcons:function(){var a= +this.options;a.icons&&(b("").addClass("ui-icon "+a.icons.header).prependTo(this.headers),this.active.children(".ui-icon").toggleClass(a.icons.header).toggleClass(a.icons.headerSelected),this.element.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.children(".ui-icon").remove();this.element.removeClass("ui-accordion-icons")},destroy:function(){var a=this.options;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role");this.headers.unbind(".accordion").removeClass("ui-accordion-header ui-accordion-disabled ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-selected").removeAttr("tabIndex"); +this.headers.find("a").removeAttr("tabIndex");this._destroyIcons();var c=this.headers.next().css("display","").removeAttr("role").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-accordion-disabled ui-state-disabled");(a.autoHeight||a.fillHeight)&&c.css("height","");return b.Widget.prototype.destroy.call(this)},_setOption:function(a,c){b.Widget.prototype._setOption.apply(this,arguments);"active"==a&&this.activate(c);"icons"==a&&(this._destroyIcons(), +c&&this._createIcons());if("disabled"==a)this.headers.add(this.headers.next())[c?"addClass":"removeClass"]("ui-accordion-disabled ui-state-disabled")},_keydown:function(a){if(!this.options.disabled&&!a.altKey&&!a.ctrlKey){var c=b.ui.keyCode,d=this.headers.length,g=this.headers.index(a.target),h=!1;switch(a.keyCode){case c.RIGHT:case c.DOWN:h=this.headers[(g+1)%d];break;case c.LEFT:case c.UP:h=this.headers[(g-1+d)%d];break;case c.SPACE:case c.ENTER:this._clickHandler({target:a.target},a.target),a.preventDefault()}return h? +(b(a.target).attr("tabIndex",-1),b(h).attr("tabIndex",0),h.focus(),!1):!0}},resize:function(){var a=this.options,c;if(a.fillSpace){if(b.browser.msie){var d=this.element.parent().css("overflow");this.element.parent().css("overflow","hidden")}c=this.element.parent().height();b.browser.msie&&this.element.parent().css("overflow",d);this.headers.each(function(){c-=b(this).outerHeight(!0)});this.headers.next().each(function(){b(this).height(Math.max(0,c-b(this).innerHeight()+b(this).height()))}).css("overflow", +"auto")}else a.autoHeight&&(c=0,this.headers.next().each(function(){c=Math.max(c,b(this).height("").height())}).height(c));return this},activate:function(b){this.options.active=b;b=this._findActive(b)[0];this._clickHandler({target:b},b);return this},_findActive:function(a){return a?"number"===typeof a?this.headers.filter(":eq("+a+")"):this.headers.not(this.headers.not(a)):!1===a?b([]):this.headers.filter(":eq(0)")},_clickHandler:function(a,c){var d=this.options;if(!d.disabled)if(a.target){var g=b(a.currentTarget|| +c),h=g[0]===this.active[0];d.active=d.collapsible&&h?!1:this.headers.index(g);if(!(this.running||!d.collapsible&&h)){var e=this.active,f=g.next(),i=this.active.next(),j={options:d,newHeader:h&&d.collapsible?b([]):g,oldHeader:this.active,newContent:h&&d.collapsible?b([]):f,oldContent:i},k=this.headers.index(this.active[0])>this.headers.index(g[0]);this.active=h?b([]):g;this._toggle(f,i,j,h,k);e.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header); +h||(g.removeClass("ui-state-default ui-corner-all").addClass("ui-state-active ui-corner-top").children(".ui-icon").removeClass(d.icons.header).addClass(d.icons.headerSelected),g.next().addClass("ui-accordion-content-active"))}}else if(d.collapsible){this.active.removeClass("ui-state-active ui-corner-top").addClass("ui-state-default ui-corner-all").children(".ui-icon").removeClass(d.icons.headerSelected).addClass(d.icons.header);this.active.next().addClass("ui-accordion-content-active");var i=this.active.next(), +j={options:d,newHeader:b([]),oldHeader:d.active,newContent:b([]),oldContent:i},f=this.active=b([]);this._toggle(f,i,j)}},_toggle:function(a,c,d,g,h){var e=this,f=e.options;e.toShow=a;e.toHide=c;e.data=d;var i=function(){if(e)return e._completed.apply(e,arguments)};e._trigger("changestart",null,e.data);e.running=0===c.size()?a.size():c.size();if(f.animated){d={};d=f.collapsible&&g?{toShow:b([]),toHide:c,complete:i,down:h,autoHeight:f.autoHeight||f.fillSpace}:{toShow:a,toHide:c,complete:i,down:h,autoHeight:f.autoHeight|| +f.fillSpace};f.proxied||(f.proxied=f.animated);f.proxiedDuration||(f.proxiedDuration=f.duration);f.animated=b.isFunction(f.proxied)?f.proxied(d):f.proxied;f.duration=b.isFunction(f.proxiedDuration)?f.proxiedDuration(d):f.proxiedDuration;var g=b.ui.accordion.animations,j=f.duration,k=f.animated;k&&(!g[k]&&!b.easing[k])&&(k="slide");g[k]||(g[k]=function(b){this.slide(b,{easing:k,duration:j||700})});g[k](d)}else f.collapsible&&g?a.toggle():(c.hide(),a.show()),i(!0);c.prev().attr({"aria-expanded":"false", +"aria-selected":"false",tabIndex:-1}).blur();a.prev().attr({"aria-expanded":"true","aria-selected":"true",tabIndex:0}).focus()},_completed:function(b){this.running=b?0:--this.running;this.running||(this.options.clearStyle&&this.toShow.add(this.toHide).css({height:"",overflow:""}),this.toHide.removeClass("ui-accordion-content-active"),this.toHide.length&&(this.toHide.parent()[0].className=this.toHide.parent()[0].className),this._trigger("change",null,this.data))}});b.extend(b.ui.accordion,{version:"1.8.14", +animations:{slide:function(a,c){a=b.extend({easing:"swing",duration:300},a,c);if(a.toHide.size())if(a.toShow.size()){var d=a.toShow.css("overflow"),g=0,h={},e={},f,i=a.toShow;f=i[0].style.width;i.width(parseInt(i.parent().width(),10)-parseInt(i.css("paddingLeft"),10)-parseInt(i.css("paddingRight"),10)-(parseInt(i.css("borderLeftWidth"),10)||0)-(parseInt(i.css("borderRightWidth"),10)||0));b.each(["height","paddingTop","paddingBottom"],function(c,f){e[f]="hide";var i=(""+b.css(a.toShow[0],f)).match(/^([\d+-.]+)(.*)$/); +h[f]={value:i[1],unit:i[2]||"px"}});a.toShow.css({height:0,overflow:"hidden"}).show();a.toHide.filter(":hidden").each(a.complete).end().filter(":visible").animate(e,{step:function(b,c){"height"==c.prop&&(g=0===c.end-c.start?0:(c.now-c.start)/(c.end-c.start));a.toShow[0].style[c.prop]=g*h[c.prop].value+h[c.prop].unit},duration:a.duration,easing:a.easing,complete:function(){a.autoHeight||a.toShow.css("height","");a.toShow.css({width:f,overflow:d});a.complete()}})}else a.toHide.animate({height:"hide", +paddingTop:"hide",paddingBottom:"hide"},a);else a.toShow.animate({height:"show",paddingTop:"show",paddingBottom:"show"},a)},bounceslide:function(b){this.slide(b,{easing:b.down?"easeOutBounce":"swing",duration:b.down?1E3:200})}}})})(jQuery); +(function(b){var a=0;b.widget("ui.autocomplete",{options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null},pending:0,_create:function(){var c=this,a=this.element[0].ownerDocument,g;this.element.addClass("ui-autocomplete-input").attr("autocomplete","off").attr({role:"textbox","aria-autocomplete":"list","aria-haspopup":"true"}).bind("keydown.autocomplete",function(a){if(!c.options.disabled&&!c.element.attr("readonly")){g=!1;var d= +b.ui.keyCode;switch(a.keyCode){case d.PAGE_UP:c._move("previousPage",a);break;case d.PAGE_DOWN:c._move("nextPage",a);break;case d.UP:c._move("previous",a);a.preventDefault();break;case d.DOWN:c._move("next",a);a.preventDefault();break;case d.ENTER:case d.NUMPAD_ENTER:c.menu.active&&(g=!0,a.preventDefault());case d.TAB:if(!c.menu.active)break;c.menu.select(a);break;case d.ESCAPE:c.element.val(c.term);c.close(a);break;default:clearTimeout(c.searching),c.searching=setTimeout(function(){c.term!=c.element.val()&& +(c.selectedItem=null,c.search(null,a))},c.options.delay)}}}).bind("keypress.autocomplete",function(b){g&&(g=!1,b.preventDefault())}).bind("focus.autocomplete",function(){c.options.disabled||(c.selectedItem=null,c.previous=c.element.val())}).bind("blur.autocomplete",function(b){c.options.disabled||(clearTimeout(c.searching),c.closing=setTimeout(function(){c.close(b);c._change(b)},150))});this._initSource();this.response=function(){return c._response.apply(c,arguments)};this.menu=b("
      ").addClass("ui-autocomplete").appendTo(b(this.options.appendTo|| +"body",a)[0]).mousedown(function(a){var d=c.menu.element[0];b(a.target).closest(".ui-menu-item").length||setTimeout(function(){b(document).one("mousedown",function(a){a.target!==c.element[0]&&(a.target!==d&&!b.ui.contains(d,a.target))&&c.close()})},1);setTimeout(function(){clearTimeout(c.closing)},13)}).menu({focus:function(b,a){var f=a.item.data("item.autocomplete");!1!==c._trigger("focus",b,{item:f})&&/^key/.test(b.originalEvent.type)&&c.element.val(f.value)},selected:function(b,e){var f=e.item.data("item.autocomplete"), +i=c.previous;c.element[0]!==a.activeElement&&(c.element.focus(),c.previous=i,setTimeout(function(){c.previous=i;c.selectedItem=f},1));!1!==c._trigger("select",b,{item:f})&&c.element.val(f.value);c.term=c.element.val();c.close(b);c.selectedItem=f},blur:function(){c.menu.element.is(":visible")&&c.element.val()!==c.term&&c.element.val(c.term)}}).zIndex(this.element.zIndex()+1).css({top:0,left:0}).hide().data("menu");b.fn.bgiframe&&this.menu.element.bgiframe()},destroy:function(){this.element.removeClass("ui-autocomplete-input").removeAttr("autocomplete").removeAttr("role").removeAttr("aria-autocomplete").removeAttr("aria-haspopup"); +this.menu.element.remove();b.Widget.prototype.destroy.call(this)},_setOption:function(a,d){b.Widget.prototype._setOption.apply(this,arguments);"source"===a&&this._initSource();"appendTo"===a&&this.menu.element.appendTo(b(d||"body",this.element[0].ownerDocument)[0]);"disabled"===a&&(d&&this.xhr)&&this.xhr.abort()},_initSource:function(){var c=this,d,g;b.isArray(this.options.source)?(d=this.options.source,this.source=function(a,c){c(b.ui.autocomplete.filter(d,a.term))}):"string"===typeof this.options.source? +(g=this.options.source,this.source=function(d,e){c.xhr&&c.xhr.abort();c.xhr=b.ajax({url:g,data:d,dataType:"json",autocompleteRequest:++a,success:function(b){this.autocompleteRequest===a&&e(b)},error:function(){this.autocompleteRequest===a&&e([])}})}):this.source=this.options.source},search:function(b,a){b=null!=b?b:this.element.val();this.term=this.element.val();if(b.length").data("item.autocomplete",d).append(b("").text(d.label)).appendTo(a)},_move:function(b,a){if(this.menu.element.is(":visible"))if(this.menu.first()&&/^previous/.test(b)||this.menu.last()&& +/^next/.test(b))this.element.val(this.term),this.menu.deactivate();else this.menu[b](a);else this.search(null,a)},widget:function(){return this.menu.element}});b.extend(b.ui.autocomplete,{escapeRegex:function(b){return b.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},filter:function(a,d){var g=RegExp(b.ui.autocomplete.escapeRegex(d),"i");return b.grep(a,function(b){return g.test(b.label||b.value||b)})}})})(jQuery); +(function(b){b.widget("ui.menu",{_create:function(){var a=this;this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr({role:"listbox","aria-activedescendant":"ui-active-menuitem"}).click(function(c){b(c.target).closest(".ui-menu-item a").length&&(c.preventDefault(),a.select(c))});this.refresh()},refresh:function(){var a=this;this.element.children("li:not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","menuitem").children("a").addClass("ui-corner-all").attr("tabindex", +-1).mouseenter(function(c){a.activate(c,b(this).parent())}).mouseleave(function(){a.deactivate()})},activate:function(b,c){this.deactivate();if(this.hasScroll()){var d=c.offset().top-this.element.offset().top,g=this.element.scrollTop(),h=this.element.height();0>d?this.element.scrollTop(g+d):d>=h&&this.element.scrollTop(g+d-h+c.height())}this.active=c.eq(0).children("a").addClass("ui-state-hover").attr("id","ui-active-menuitem").end();this._trigger("focus",b,{item:c})},deactivate:function(){this.active&& +(this.active.children("a").removeClass("ui-state-hover").removeAttr("id"),this._trigger("blur"),this.active=null)},next:function(b){this.move("next",".ui-menu-item:first",b)},previous:function(b){this.move("prev",".ui-menu-item:last",b)},first:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},last:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},move:function(b,c,d){this.active?(b=this.active[b+"All"](".ui-menu-item").eq(0),b.length?this.activate(d, +b):this.activate(d,this.element.children(c))):this.activate(d,this.element.children(c))},nextPage:function(a){if(this.hasScroll())if(!this.active||this.last())this.activate(a,this.element.children(".ui-menu-item:first"));else{var c=this.active.offset().top,d=this.element.height(),g=this.element.children(".ui-menu-item").filter(function(){var a=b(this).offset().top-c-d+b(this).height();return 10>a&&-10a&&-10").addClass("ui-button-text").html(this.options.label).appendTo(a.empty()).text(),d=this.options.icons,h=d.primary&&d.secondary,e=[];d.primary||d.secondary?(this.options.text&&e.push("ui-button-text-icon"+(h?"s":d.primary?"-primary":"-secondary")),d.primary&&a.prepend(""),d.secondary&&a.append(""),this.options.text||(e.push(h?"ui-button-icons-only": +"ui-button-icon-only"),this.hasTitle||a.attr("title",c))):e.push("ui-button-text-only");a.addClass(e.join(" "))}}});b.widget("ui.buttonset",{options:{items:":button, :submit, :reset, :checkbox, :radio, a, :data(button)"},_create:function(){this.element.addClass("ui-buttonset")},_init:function(){this.refresh()},_setOption:function(a,c){"disabled"===a&&this.buttons.button("option",a,c);b.Widget.prototype._setOption.apply(this,arguments)},refresh:function(){var a="ltr"===this.element.css("direction"); +this.buttons=this.element.find(this.options.items).filter(":ui-button").button("refresh").end().not(":ui-button").button().end().map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-all ui-corner-left ui-corner-right").filter(":first").addClass(a?"ui-corner-left":"ui-corner-right").end().filter(":last").addClass(a?"ui-corner-right":"ui-corner-left").end().end()},destroy:function(){this.element.removeClass("ui-buttonset");this.buttons.map(function(){return b(this).button("widget")[0]}).removeClass("ui-corner-left ui-corner-right").end().button("destroy"); +b.Widget.prototype.destroy.call(this)}})})(jQuery); +(function(b,a){var c={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},d={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0},g=b.attrFn||{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0,click:!0};b.widget("ui.dialog",{options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",collision:"fit",using:function(a){var c= +b(this).css(a).offset().top;0>c&&b(this).css("top",a.top-c)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1E3},_create:function(){this.originalTitle=this.element.attr("title");"string"!==typeof this.originalTitle&&(this.originalTitle="");this.options.title=this.options.title||this.originalTitle;var a=this,c=a.options,f=c.title||" ",i=b.ui.dialog.getTitleId(a.element),d=(a.uiDialog=b("
      ")).appendTo(document.body).hide().addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+ +c.dialogClass).css({zIndex:c.zIndex}).attr("tabIndex",-1).css("outline",0).keydown(function(f){if(c.closeOnEscape&&f.keyCode&&f.keyCode===b.ui.keyCode.ESCAPE){a.close(f);f.preventDefault()}}).attr({role:"dialog","aria-labelledby":i}).mousedown(function(b){a.moveToTop(false,b)});a.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(d);var g=(a.uiDialogTitlebar=b("
      ")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").prependTo(d), +l=b('').addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").hover(function(){l.addClass("ui-state-hover")},function(){l.removeClass("ui-state-hover")}).focus(function(){l.addClass("ui-state-focus")}).blur(function(){l.removeClass("ui-state-focus")}).click(function(b){a.close(b);return false}).appendTo(g);(a.uiDialogTitlebarCloseText=b("")).addClass("ui-icon ui-icon-closethick").text(c.closeText).appendTo(l);b("").addClass("ui-dialog-title").attr("id", +i).html(f).prependTo(g);b.isFunction(c.beforeclose)&&!b.isFunction(c.beforeClose)&&(c.beforeClose=c.beforeclose);g.find("*").add(g).disableSelection();c.draggable&&b.fn.draggable&&a._makeDraggable();c.resizable&&b.fn.resizable&&a._makeResizable();a._createButtons(c.buttons);a._isOpen=!1;b.fn.bgiframe&&d.bgiframe()},_init:function(){this.options.autoOpen&&this.open()},destroy:function(){this.overlay&&this.overlay.destroy();this.uiDialog.hide();this.element.unbind(".dialog").removeData("dialog").removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"); +this.uiDialog.remove();this.originalTitle&&this.element.attr("title",this.originalTitle);return this},widget:function(){return this.uiDialog},close:function(a){var c=this,f,d;if(!1!==c._trigger("beforeClose",a))return c.overlay&&c.overlay.destroy(),c.uiDialog.unbind("keypress.ui-dialog"),c._isOpen=!1,c.options.hide?c.uiDialog.hide(c.options.hide,function(){c._trigger("close",a)}):(c.uiDialog.hide(),c._trigger("close",a)),b.ui.dialog.overlay.resize(),c.options.modal&&(f=0,b(".ui-dialog").each(function(){if(this!== +c.uiDialog[0]){d=b(this).css("z-index");isNaN(d)||(f=Math.max(f,d))}}),b.ui.dialog.maxZ=f),c},isOpen:function(){return this._isOpen},moveToTop:function(a,c){var f=this.options;if(f.modal&&!a||!f.stack&&!f.modal)return this._trigger("focus",c);f.zIndex>b.ui.dialog.maxZ&&(b.ui.dialog.maxZ=f.zIndex);this.overlay&&(b.ui.dialog.maxZ+=1,this.overlay.$el.css("z-index",b.ui.dialog.overlay.maxZ=b.ui.dialog.maxZ));f={scrollTop:this.element.attr("scrollTop"),scrollLeft:this.element.attr("scrollLeft")};b.ui.dialog.maxZ+= +1;this.uiDialog.css("z-index",b.ui.dialog.maxZ);this.element.attr(f);this._trigger("focus",c);return this},open:function(){if(!this._isOpen){var a=this.options,c=this.uiDialog;this.overlay=a.modal?new b.ui.dialog.overlay(this):null;this._size();this._position(a.position);c.show(a.show);this.moveToTop(!0);a.modal&&c.bind("keypress.ui-dialog",function(a){if(a.keyCode===b.ui.keyCode.TAB){var c=b(":tabbable",this),d=c.filter(":first"),c=c.filter(":last");if(a.target===c[0]&&!a.shiftKey)return d.focus(1), +!1;if(a.target===d[0]&&a.shiftKey)return c.focus(1),!1}});b(this.element.find(":tabbable").get().concat(c.find(".ui-dialog-buttonpane :tabbable").get().concat(c.get()))).eq(0).focus();this._isOpen=!0;this._trigger("open");return this}},_createButtons:function(a){var c=this,f=!1,d=b("
      ").addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),j=b("
      ").addClass("ui-dialog-buttonset").appendTo(d);c.uiDialog.find(".ui-dialog-buttonpane").remove();"object"===typeof a&& +null!==a&&b.each(a,function(){return!(f=!0)});f&&(b.each(a,function(a,f){var f=b.isFunction(f)?{click:f,text:a}:f,d=b('').click(function(){f.click.apply(c.element[0],arguments)}).appendTo(j);b.each(f,function(b,a){if("click"!==b)if(b in g)d[b](a);else d.attr(b,a)});b.fn.button&&d.button()}),d.appendTo(c.uiDialog))},_makeDraggable:function(){function a(b){return{position:b.position,offset:b.offset}}var c=this,f=c.options,d=b(document),g;c.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close", +handle:".ui-dialog-titlebar",containment:"document",start:function(d,i){g="auto"===f.height?"auto":b(this).height();b(this).height(b(this).height()).addClass("ui-dialog-dragging");c._trigger("dragStart",d,a(i))},drag:function(b,f){c._trigger("drag",b,a(f))},stop:function(k,l){f.position=[l.position.left-d.scrollLeft(),l.position.top-d.scrollTop()];b(this).removeClass("ui-dialog-dragging").height(g);c._trigger("dragStop",k,a(l));b.ui.dialog.overlay.resize()}})},_makeResizable:function(c){function d(b){return{originalPosition:b.originalPosition, +originalSize:b.originalSize,position:b.position,size:b.size}}var c=c===a?this.options.resizable:c,f=this,i=f.options,g=f.uiDialog.css("position"),c="string"===typeof c?c:"n,e,s,w,se,sw,ne,nw";f.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:f.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:f._minHeight(),handles:c,start:function(a,c){b(this).addClass("ui-dialog-resizing");f._trigger("resizeStart",a,d(c))},resize:function(b,a){f._trigger("resize", +b,d(a))},stop:function(a,c){b(this).removeClass("ui-dialog-resizing");i.height=b(this).height();i.width=b(this).width();f._trigger("resizeStop",a,d(c));b.ui.dialog.overlay.resize()}}).css("position",g).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var b=this.options;return"auto"===b.height?b.minHeight:Math.min(b.minHeight,b.height)},_position:function(a){var c=[],f=[0,0],d;if(a){if("string"===typeof a||"object"===typeof a&&"0"in a)c=a.split?a.split(" "): +[a[0],a[1]],1===c.length&&(c[1]=c[0]),b.each(["left","top"],function(b,a){+c[b]===c[b]&&(f[b]=c[b],c[b]=a)}),a={my:c.join(" "),at:c.join(" "),offset:f.join(" ")};a=b.extend({},b.ui.dialog.prototype.options.position,a)}else a=b.ui.dialog.prototype.options.position;(d=this.uiDialog.is(":visible"))||this.uiDialog.show();this.uiDialog.css({top:0,left:0}).position(b.extend({of:window},a));d||this.uiDialog.hide()},_setOptions:function(a){var g=this,f={},i=!1;b.each(a,function(b,a){g._setOption(b,a);b in +c&&(i=!0);b in d&&(f[b]=a)});i&&this._size();this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",f)},_setOption:function(a,c){var f=this.uiDialog;switch(a){case "beforeclose":a="beforeClose";break;case "buttons":this._createButtons(c);break;case "closeText":this.uiDialogTitlebarCloseText.text(""+c);break;case "dialogClass":f.removeClass(this.options.dialogClass).addClass("ui-dialog ui-widget ui-widget-content ui-corner-all "+c);break;case "disabled":c?f.addClass("ui-dialog-disabled"): +f.removeClass("ui-dialog-disabled");break;case "draggable":var d=f.is(":data(draggable)");d&&!c&&f.draggable("destroy");!d&&c&&this._makeDraggable();break;case "position":this._position(c);break;case "resizable":(d=f.is(":data(resizable)"))&&!c&&f.resizable("destroy");d&&"string"===typeof c&&f.resizable("option","handles",c);!d&&!1!==c&&this._makeResizable(c);break;case "title":b(".ui-dialog-title",this.uiDialogTitlebar).html(""+(c||" "))}b.Widget.prototype._setOption.apply(this,arguments)}, +_size:function(){var a=this.options,c,f,d=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0});a.minWidth>a.width&&(a.width=a.minWidth);c=this.uiDialog.css({height:"auto",width:a.width}).height();f=Math.max(0,a.minHeight-c);"auto"===a.height?b.support.minHeight?this.element.css({minHeight:f,height:"auto"}):(this.uiDialog.show(),a=this.element.css("height","auto").height(),d||this.uiDialog.hide(),this.element.height(Math.max(a,f))):this.element.height(Math.max(a.height- +c,0));this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}});b.extend(b.ui.dialog,{version:"1.8.14",uuid:0,maxZ:0,getTitleId:function(b){b=b.attr("id");b||(b=this.uuid+=1);return"ui-dialog-title-"+b},overlay:function(a){this.$el=b.ui.dialog.overlay.create(a)}});b.extend(b.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:b.map("focus mousedown mouseup keydown keypress click".split(" "),function(b){return b+".dialog-overlay"}).join(" "), +create:function(a){0===this.instances.length&&(setTimeout(function(){b.ui.dialog.overlay.instances.length&&b(document).bind(b.ui.dialog.overlay.events,function(a){if(b(a.target).zIndex()").addClass("ui-widget-overlay")).appendTo(document.body).css({width:this.width(), +height:this.height()});b.fn.bgiframe&&c.bgiframe();this.instances.push(c);return c},destroy:function(a){var c=b.inArray(a,this.instances);-1!=c&&this.oldInstances.push(this.instances.splice(c,1)[0]);0===this.instances.length&&b([document,window]).unbind(".dialog-overlay");a.remove();var f=0;b.each(this.instances,function(){f=Math.max(f,this.css("z-index"))});this.maxZ=f},height:function(){var a,c;return b.browser.msie&&7>b.browser.version?(a=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight), +c=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),a").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+("min"===c.range||"max"===c.range?" ui-slider-range-"+c.range:""))}for(var e=d.length;e"); +this.handles=d.add(b(h.join("")).appendTo(a.element));this.handle=this.handles.eq(0);this.handles.add(this.range).filter("a").click(function(b){b.preventDefault()}).hover(function(){c.disabled||b(this).addClass("ui-state-hover")},function(){b(this).removeClass("ui-state-hover")}).focus(function(){c.disabled?b(this).blur():(b(".ui-slider .ui-state-focus").removeClass("ui-state-focus"),b(this).addClass("ui-state-focus"))}).blur(function(){b(this).removeClass("ui-state-focus")});this.handles.each(function(a){b(this).data("index.ui-slider-handle", +a)});this.handles.keydown(function(c){var d=!0,g=b(this).data("index.ui-slider-handle"),e,h,m;if(!a.options.disabled){switch(c.keyCode){case b.ui.keyCode.HOME:case b.ui.keyCode.END:case b.ui.keyCode.PAGE_UP:case b.ui.keyCode.PAGE_DOWN:case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:if(d=!1,!a._keySliding&&(a._keySliding=!0,b(this).addClass("ui-state-active"),e=a._start(c,g),!1===e))return}m=a.options.step;e=a.options.values&&a.options.values.length?h=a.values(g): +h=a.value();switch(c.keyCode){case b.ui.keyCode.HOME:h=a._valueMin();break;case b.ui.keyCode.END:h=a._valueMax();break;case b.ui.keyCode.PAGE_UP:h=a._trimAlignValue(e+(a._valueMax()-a._valueMin())/5);break;case b.ui.keyCode.PAGE_DOWN:h=a._trimAlignValue(e-(a._valueMax()-a._valueMin())/5);break;case b.ui.keyCode.UP:case b.ui.keyCode.RIGHT:if(e===a._valueMax())return;h=a._trimAlignValue(e+m);break;case b.ui.keyCode.DOWN:case b.ui.keyCode.LEFT:if(e===a._valueMin())return;h=a._trimAlignValue(e-m)}a._slide(c, +g,h);return d}}).keyup(function(c){var d=b(this).data("index.ui-slider-handle");a._keySliding&&(a._keySliding=!1,a._stop(c,d),a._change(c,d),b(this).removeClass("ui-state-active"))});this._refreshValue();this._animateOff=!1},destroy:function(){this.handles.remove();this.range.remove();this.element.removeClass("ui-slider ui-slider-horizontal ui-slider-vertical ui-slider-disabled ui-widget ui-widget-content ui-corner-all").removeData("slider").unbind(".slider");this._mouseDestroy();return this},_mouseCapture:function(a){var c= +this.options,d,g,h,e,f;if(c.disabled)return!1;this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()};this.elementOffset=this.element.offset();d=this._normValueFromMouse({x:a.pageX,y:a.pageY});g=this._valueMax()-this._valueMin()+1;e=this;this.handles.each(function(a){var c=Math.abs(d-e.values(a));g>c&&(g=c,h=b(this),f=a)});!0===c.range&&this.values(1)===c.min&&(f+=1,h=b(this.handles[f]));if(!1===this._start(a,f))return!1;this._mouseSliding=!0;e._handleIndex=f;h.addClass("ui-state-active").focus(); +c=h.offset();this._clickOffset=!b(a.target).parents().andSelf().is(".ui-slider-handle")?{left:0,top:0}:{left:a.pageX-c.left-h.width()/2,top:a.pageY-c.top-h.height()/2-(parseInt(h.css("borderTopWidth"),10)||0)-(parseInt(h.css("borderBottomWidth"),10)||0)+(parseInt(h.css("marginTop"),10)||0)};this.handles.hasClass("ui-state-hover")||this._slide(a,f,d);return this._animateOff=!0},_mouseStart:function(){return!0},_mouseDrag:function(b){var c=this._normValueFromMouse({x:b.pageX,y:b.pageY});this._slide(b, +this._handleIndex,c);return!1},_mouseStop:function(b){this.handles.removeClass("ui-state-active");this._mouseSliding=!1;this._stop(b,this._handleIndex);this._change(b,this._handleIndex);this._clickOffset=this._handleIndex=null;return this._animateOff=!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(b){var c;"horizontal"===this.orientation?(c=this.elementSize.width,b=b.x-this.elementOffset.left-(this._clickOffset? +this._clickOffset.left:0)):(c=this.elementSize.height,b=b.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0));c=b/c;1c&&(c=0);"vertical"===this.orientation&&(c=1-c);b=this._valueMax()-this._valueMin();return this._trimAlignValue(this._valueMin()+c*b)},_start:function(b,c){var d={handle:this.handles[c],value:this.value()};this.options.values&&this.options.values.length&&(d.value=this.values(c),d.values=this.values());return this._trigger("start",b,d)},_slide:function(b, +c,d){var g;if(this.options.values&&this.options.values.length){g=this.values(c?0:1);if(2===this.options.values.length&&!0===this.options.range&&(0===c&&d>g||1===c&&d=this._valueMax())return this._valueMax();var c=0=c&&(alignValue+=0",remove:null,select:null,show:null,spinner:"Loading…",tabTemplate:"
    • #{label}
    • "},_create:function(){this._tabify(!0)},_setOption:function(b,a){"selected"==b?this.options.collapsible&&a==this.options.selected||this.select(a): +(this.options[b]=a,this._tabify())},_tabId:function(b){return b.title&&b.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF-]/g,"")||this.options.idPrefix+ ++c},_sanitizeSelector:function(b){return b.replace(/:/g,"\\:")},_cookie:function(){var a=this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++d);return b.cookie.apply(null,[a].concat(b.makeArray(arguments)))},_ui:function(b,a){return{tab:b,panel:a,index:this.anchors.index(b)}},_cleanup:function(){this.lis.filter(".ui-state-processing").removeClass("ui-state-processing").find("span:data(label.tabs)").each(function(){var a= +b(this);a.html(a.data("label.tabs")).removeData("label.tabs")})},_tabify:function(c){function d(a,c){a.css("display","");!b.support.opacity&&c.opacity&&a[0].style.removeAttribute("filter")}var e=this,f=this.options,i=/^#.+/;this.list=this.element.find("ol,ul").eq(0);this.lis=b(" > li:has(a[href])",this.list);this.anchors=this.lis.map(function(){return b("a",this)[0]});this.panels=b([]);this.anchors.each(function(a,c){var d=b(c).attr("href"),g=d.split("#")[0],h;if(g&&(g===location.toString().split("#")[0]|| +(h=b("base")[0])&&g===h.href))d=c.hash,c.href=d;i.test(d)?e.panels=e.panels.add(e.element.find(e._sanitizeSelector(d))):d&&"#"!==d?(b.data(c,"href.tabs",d),b.data(c,"load.tabs",d.replace(/#.*$/,"")),d=e._tabId(c),c.href="#"+d,g=e.element.find("#"+d),g.length||(g=b(f.panelTemplate).attr("id",d).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").insertAfter(e.panels[a-1]||e.list),g.data("destroy.tabs",!0)),e.panels=e.panels.add(g)):f.disabled.push(a)});c?(this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all"), +this.list.addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all"),this.lis.addClass("ui-state-default ui-corner-top"),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom"),f.selected===a?(location.hash&&this.anchors.each(function(b,a){if(a.hash==location.hash)return f.selected=b,!1}),"number"!==typeof f.selected&&f.cookie&&(f.selected=parseInt(e._cookie(),10)),"number"!==typeof f.selected&&this.lis.filter(".ui-tabs-selected").length&&(f.selected= +this.lis.index(this.lis.filter(".ui-tabs-selected"))),f.selected=f.selected||(this.lis.length?0:-1)):null===f.selected&&(f.selected=-1),f.selected=0<=f.selected&&this.anchors[f.selected]||0>f.selected?f.selected:0,f.disabled=b.unique(f.disabled.concat(b.map(this.lis.filter(".ui-state-disabled"),function(b){return e.lis.index(b)}))).sort(),-1!=b.inArray(f.selected,f.disabled)&&f.disabled.splice(b.inArray(f.selected,f.disabled),1),this.panels.addClass("ui-tabs-hide"),this.lis.removeClass("ui-tabs-selected ui-state-active"), +0<=f.selected&&this.anchors.length&&(e.element.find(e._sanitizeSelector(e.anchors[f.selected].hash)).removeClass("ui-tabs-hide"),this.lis.eq(f.selected).addClass("ui-tabs-selected ui-state-active"),e.element.queue("tabs",function(){e._trigger("show",null,e._ui(e.anchors[f.selected],e.element.find(e._sanitizeSelector(e.anchors[f.selected].hash))[0]))}),this.load(f.selected)),b(window).bind("unload",function(){e.lis.add(e.anchors).unbind(".tabs");e.lis=e.anchors=e.panels=null})):f.selected=this.lis.index(this.lis.filter(".ui-tabs-selected")); +this.element[f.collapsible?"addClass":"removeClass"]("ui-tabs-collapsible");f.cookie&&this._cookie(f.selected,f.cookie);for(var c=0,j;j=this.lis[c];c++)b(j)[-1!=b.inArray(c,f.disabled)&&!b(j).hasClass("ui-tabs-selected")?"addClass":"removeClass"]("ui-state-disabled");!1===f.cache&&this.anchors.removeData("cache.tabs");this.lis.add(this.anchors).unbind(".tabs");if("mouseover"!==f.event){var k=function(b,a){a.is(":not(.ui-state-disabled)")&&a.addClass("ui-state-"+b)};this.lis.bind("mouseover.tabs", +function(){k("hover",b(this))});this.lis.bind("mouseout.tabs",function(){b(this).removeClass("ui-state-hover")});this.anchors.bind("focus.tabs",function(){k("focus",b(this).closest("li"))});this.anchors.bind("blur.tabs",function(){b(this).closest("li").removeClass("ui-state-focus")})}var l,m;f.fx&&(b.isArray(f.fx)?(l=f.fx[0],m=f.fx[1]):l=m=f.fx);var p=m?function(a,c){b(a).closest("li").addClass("ui-tabs-selected ui-state-active");c.hide().removeClass("ui-tabs-hide").animate(m,m.duration||"normal", +function(){d(c,m);e._trigger("show",null,e._ui(a,c[0]))})}:function(a,c){b(a).closest("li").addClass("ui-tabs-selected ui-state-active");c.removeClass("ui-tabs-hide");e._trigger("show",null,e._ui(a,c[0]))},n=l?function(b,a){a.animate(l,l.duration||"normal",function(){e.lis.removeClass("ui-tabs-selected ui-state-active");a.addClass("ui-tabs-hide");d(a,l);e.element.dequeue("tabs")})}:function(b,a){e.lis.removeClass("ui-tabs-selected ui-state-active");a.addClass("ui-tabs-hide");e.element.dequeue("tabs")}; +this.anchors.bind(f.event+".tabs",function(){var a=this,c=b(a).closest("li"),d=e.panels.filter(":not(.ui-tabs-hide)"),i=e.element.find(e._sanitizeSelector(a.hash));if(c.hasClass("ui-tabs-selected")&&!f.collapsible||c.hasClass("ui-state-disabled")||c.hasClass("ui-state-processing")||e.panels.filter(":animated").length||e._trigger("select",null,e._ui(this,i[0]))===false){this.blur();return false}f.selected=e.anchors.index(this);e.abort();if(f.collapsible){if(c.hasClass("ui-tabs-selected")){f.selected= +-1;f.cookie&&e._cookie(f.selected,f.cookie);e.element.queue("tabs",function(){n(a,d)}).dequeue("tabs");this.blur();return false}if(!d.length){f.cookie&&e._cookie(f.selected,f.cookie);e.element.queue("tabs",function(){p(a,i)});e.load(e.anchors.index(this));this.blur();return false}}f.cookie&&e._cookie(f.selected,f.cookie);if(i.length){d.length&&e.element.queue("tabs",function(){n(a,d)});e.element.queue("tabs",function(){p(a,i)});e.load(e.anchors.index(this))}else throw"jQuery UI Tabs: Mismatching fragment identifier."; +b.browser.msie&&this.blur()});this.anchors.bind("click.tabs",function(){return false})},_getIndex:function(b){"string"==typeof b&&(b=this.anchors.index(this.anchors.filter("[href$="+b+"]")));return b},destroy:function(){var a=this.options;this.abort();this.element.unbind(".tabs").removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible").removeData("tabs");this.list.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all");this.anchors.each(function(){var a= +b.data(this,"href.tabs");a&&(this.href=a);var c=b(this).unbind(".tabs");b.each(["href","load","cache"],function(b,a){c.removeData(a+".tabs")})});this.lis.unbind(".tabs").add(this.panels).each(function(){b.data(this,"destroy.tabs")?b(this).remove():b(this).removeClass("ui-state-default ui-corner-top ui-tabs-selected ui-state-active ui-state-hover ui-state-focus ui-state-disabled ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide")});a.cookie&&this._cookie(null,a.cookie);return this},add:function(c, +d,e){e===a&&(e=this.anchors.length);var f=this,i=this.options,d=b(i.tabTemplate.replace(/#\{href\}/g,c).replace(/#\{label\}/g,d)),c=!c.indexOf("#")?c.replace("#",""):this._tabId(b("a",d)[0]);d.addClass("ui-state-default ui-corner-top").data("destroy.tabs",!0);var j=f.element.find("#"+c);j.length||(j=b(i.panelTemplate).attr("id",c).data("destroy.tabs",!0));j.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide");e>=this.lis.length?(d.appendTo(this.list),j.appendTo(this.list[0].parentNode)): +(d.insertBefore(this.lis[e]),j.insertBefore(this.panels[e]));i.disabled=b.map(i.disabled,function(b){return b>=e?++b:b});this._tabify();1==this.anchors.length&&(i.selected=0,d.addClass("ui-tabs-selected ui-state-active"),j.removeClass("ui-tabs-hide"),this.element.queue("tabs",function(){f._trigger("show",null,f._ui(f.anchors[0],f.panels[0]))}),this.load(0));this._trigger("add",null,this._ui(this.anchors[e],this.panels[e]));return this},remove:function(a){var a=this._getIndex(a),c=this.options,d=this.lis.eq(a).remove(), +f=this.panels.eq(a).remove();d.hasClass("ui-tabs-selected")&&1=a?--b:b});this._tabify();this._trigger("remove",null,this._ui(d.find("a")[0],f[0]));return this},enable:function(a){var a=this._getIndex(a),c=this.options;if(-1!=b.inArray(a,c.disabled))return this.lis.eq(a).removeClass("ui-state-disabled"),c.disabled=b.grep(c.disabled,function(b){return b!= +a}),this._trigger("enable",null,this._ui(this.anchors[a],this.panels[a])),this},disable:function(b){var b=this._getIndex(b),a=this.options;b!=a.selected&&(this.lis.eq(b).addClass("ui-state-disabled"),a.disabled.push(b),a.disabled.sort(),this._trigger("disable",null,this._ui(this.anchors[b],this.panels[b])));return this},select:function(b){b=this._getIndex(b);if(-1==b)if(this.options.collapsible&&-1!=this.options.selected)b=this.options.selected;else return this;this.anchors.eq(b).trigger(this.options.event+ +".tabs");return this},load:function(a){var a=this._getIndex(a),c=this,d=this.options,f=this.anchors.eq(a)[0],i=b.data(f,"load.tabs");this.abort();if(!i||0!==this.element.queue("tabs").length&&b.data(f,"cache.tabs"))this.element.dequeue("tabs");else{this.lis.eq(a).addClass("ui-state-processing");if(d.spinner){var j=b("span",f);j.data("label.tabs",j.html()).html(d.spinner)}this.xhr=b.ajax(b.extend({},d.ajaxOptions,{url:i,success:function(i,j){c.element.find(c._sanitizeSelector(f.hash)).html(i);c._cleanup(); +d.cache&&b.data(f,"cache.tabs",!0);c._trigger("load",null,c._ui(c.anchors[a],c.panels[a]));try{d.ajaxOptions.success(i,j)}catch(m){}},error:function(b,i){c._cleanup();c._trigger("load",null,c._ui(c.anchors[a],c.panels[a]));try{d.ajaxOptions.error(b,i,a,f)}catch(m){}}}));c.element.dequeue("tabs");return this}},abort:function(){this.element.queue([]);this.panels.stop(!1,!0);this.element.queue("tabs",this.element.queue("tabs").splice(-2,2));this.xhr&&(this.xhr.abort(),delete this.xhr);this._cleanup(); +return this},url:function(b,a){this.anchors.eq(b).removeData("cache.tabs").data("load.tabs",a);return this},length:function(){return this.anchors.length}});b.extend(b.ui.tabs,{version:"1.8.14"});b.extend(b.ui.tabs.prototype,{rotation:null,rotate:function(b,a){var c=this,f=this.options,d=c._rotate||(c._rotate=function(a){clearTimeout(c.rotation);c.rotation=setTimeout(function(){var b=f.selected;c.select(++b'))}function d(a){return a.bind("mouseout",function(a){a=b(a.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"); +a.length&&a.removeClass("ui-state-hover ui-datepicker-prev-hover ui-datepicker-next-hover")}).bind("mouseover",function(c){c=b(c.target).closest("button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a");if(!b.datepicker._isDisabledDatepicker(e.inline?a.parent()[0]:e.input[0])&&c.length)c.parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"),c.addClass("ui-state-hover"),c.hasClass("ui-datepicker-prev")&&c.addClass("ui-datepicker-prev-hover"),c.hasClass("ui-datepicker-next")&& +c.addClass("ui-datepicker-next-hover")})}function g(c,d){b.extend(c,d);for(var e in d)if(null==d[e]||d[e]==a)c[e]=d[e];return c}b.extend(b.ui,{datepicker:{version:"1.8.14"}});var h=(new Date).getTime(),e;b.extend(c.prototype,{markerClassName:"hasDatepicker",maxRows:4,log:function(){this.debug&&console.log.apply("",arguments)},_widgetDatepicker:function(){return this.dpDiv},setDefaults:function(b){g(this._defaults,b||{});return this},_attachDatepicker:function(a,c){var d=null,e;for(e in this._defaults){var g= +a.getAttribute("date:"+e);if(g){d=d||{};try{d[e]=eval(g)}catch(m){d[e]=g}}}e=a.nodeName.toLowerCase();g="div"==e||"span"==e;a.id||(this.uuid+=1,a.id="dp"+this.uuid);var h=this._newInst(b(a),g);h.settings=b.extend({},c||{},d||{});"input"==e?this._connectDatepicker(a,h):g&&this._inlineDatepicker(a,h)},_newInst:function(a,c){return{id:a[0].id.replace(/([^A-Za-z0-9_-])/g,"\\\\$1"),input:a,selectedDay:0,selectedMonth:0,selectedYear:0,drawMonth:0,drawYear:0,inline:c,dpDiv:!c?this.dpDiv:d(b('
      '))}},_connectDatepicker:function(a,c){var d=b(a);c.append=b([]);c.trigger=b([]);d.hasClass(this.markerClassName)||(this._attachments(d,c),d.addClass(this.markerClassName).keydown(this._doKeyDown).keypress(this._doKeyPress).keyup(this._doKeyUp).bind("setData.datepicker",function(b,a,f){c.settings[a]=f}).bind("getData.datepicker",function(b,a){return this._get(c,a)}),this._autoSize(c),b.data(a,"datepicker", +c))},_attachments:function(a,c){var d=this._get(c,"appendText"),e=this._get(c,"isRTL");c.append&&c.append.remove();d&&(c.append=b(''+d+""),a[e?"before":"after"](c.append));a.unbind("focus",this._showDatepicker);c.trigger&&c.trigger.remove();d=this._get(c,"showOn");("focus"==d||"both"==d)&&a.focus(this._showDatepicker);if("button"==d||"both"==d){var d=this._get(c,"buttonText"),g=this._get(c,"buttonImage");c.trigger=b(this._get(c,"buttonImageOnly")?b("").addClass(this._triggerClass).attr({src:g, +alt:d,title:d}):b('').addClass(this._triggerClass).html(""==g?d:b("").attr({src:g,alt:d,title:d})));a[e?"before":"after"](c.trigger);c.trigger.click(function(){b.datepicker._datepickerShowing&&b.datepicker._lastInput==a[0]?b.datepicker._hideDatepicker():b.datepicker._showDatepicker(a[0]);return false})}},_autoSize:function(b){if(this._get(b,"autoSize")&&!b.inline){var a=new Date(2009,11,20),c=this._get(b,"dateFormat");if(c.match(/[DM]/)){var d=function(b){for(var a= +0,c=0,f=0;fa&&(a=b[f].length,c=f);return c};a.setMonth(d(this._get(b,c.match(/MM/)?"monthNames":"monthNamesShort")));a.setDate(d(this._get(b,c.match(/DD/)?"dayNames":"dayNamesShort"))+20-a.getDay())}b.input.attr("size",this._formatDate(b,a).length)}},_inlineDatepicker:function(a,c){var d=b(a);d.hasClass(this.markerClassName)||(d.addClass(this.markerClassName).append(c.dpDiv).bind("setData.datepicker",function(b,a,f){c.settings[a]=f}).bind("getData.datepicker",function(b, +a){return this._get(c,a)}),b.data(a,"datepicker",c),this._setDate(c,this._getDefaultDate(c),!0),this._updateDatepicker(c),this._updateAlternate(c),c.dpDiv.show())},_dialogDatepicker:function(a,c,d,e,h){a=this._dialogInst;a||(this.uuid+=1,this._dialogInput=b(''),this._dialogInput.keydown(this._doKeyDown),b("body").append(this._dialogInput),a=this._dialogInst=this._newInst(this._dialogInput,!1), +a.settings={},b.data(this._dialogInput[0],"datepicker",a));g(a.settings,e||{});c=c&&c.constructor==Date?this._formatDate(a,c):c;this._dialogInput.val(c);this._pos=h?h.length?h:[h.pageX,h.pageY]:null;this._pos||(this._pos=[document.documentElement.clientWidth/2-100+(document.documentElement.scrollLeft||document.body.scrollLeft),document.documentElement.clientHeight/2-150+(document.documentElement.scrollTop||document.body.scrollTop)]);this._dialogInput.css("left",this._pos[0]+20+"px").css("top",this._pos[1]+ +"px");a.settings.onSelect=d;this._inDialog=!0;this.dpDiv.addClass(this._dialogClass);this._showDatepicker(this._dialogInput[0]);b.blockUI&&b.blockUI(this.dpDiv);b.data(this._dialogInput[0],"datepicker",a);return this},_destroyDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();b.removeData(a,"datepicker");"input"==e?(d.append.remove(),d.trigger.remove(),c.removeClass(this.markerClassName).unbind("focus",this._showDatepicker).unbind("keydown", +this._doKeyDown).unbind("keypress",this._doKeyPress).unbind("keyup",this._doKeyUp)):("div"==e||"span"==e)&&c.removeClass(this.markerClassName).empty()}},_enableDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if("input"==e)a.disabled=!1,d.trigger.filter("button").each(function(){this.disabled=!1}).end().filter("img").css({opacity:"1.0",cursor:""});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass),c.children().removeClass("ui-state-disabled"), +c.find("select.ui-datepicker-month, select.ui-datepicker-year").removeAttr("disabled");this._disabledInputs=b.map(this._disabledInputs,function(b){return b==a?null:b})}},_disableDatepicker:function(a){var c=b(a),d=b.data(a,"datepicker");if(c.hasClass(this.markerClassName)){var e=a.nodeName.toLowerCase();if("input"==e)a.disabled=!0,d.trigger.filter("button").each(function(){this.disabled=!0}).end().filter("img").css({opacity:"0.5",cursor:"default"});else if("div"==e||"span"==e)c=c.children("."+this._inlineClass), +c.children().addClass("ui-state-disabled"),c.find("select.ui-datepicker-month, select.ui-datepicker-year").attr("disabled","disabled");this._disabledInputs=b.map(this._disabledInputs,function(b){return b==a?null:b});this._disabledInputs[this._disabledInputs.length]=a}},_isDisabledDatepicker:function(b){if(!b)return!1;for(var a=0;ae||!d||-1n&&n>e?Math.abs(c.left+e-n):0);c.top-=Math.min(c.top,c.top+g>q&&q>g?Math.abs(g+p):0);return c},_findPos:function(a){for(var c= +this._get(this._getInst(a),"isRTL");a&&("hidden"==a.type||1!=a.nodeType||b.expr.filters.hidden(a));)a=a[c?"previousSibling":"nextSibling"];a=b(a).offset();return[a.left,a.top]},_triggerOnClose:function(a){var b=this._get(a,"onClose");b&&b.apply(a.input?a.input[0]:null,[a.input?a.input.val():"",a])},_hideDatepicker:function(a){var c=this._curInst;if(c&&!(a&&c!=b.data(a,"datepicker"))&&this._datepickerShowing){var a=this._get(c,"showAnim"),d=this._get(c,"duration"),e=function(){b.datepicker._tidyDialog(c); +this._curInst=null};if(b.effects&&b.effects[a])c.dpDiv.hide(a,b.datepicker._get(c,"showOptions"),d,e);else c.dpDiv["slideDown"==a?"slideUp":"fadeIn"==a?"fadeOut":"hide"](a?d:null,e);a||e();b.datepicker._triggerOnClose(c);this._datepickerShowing=!1;this._lastInput=null;this._inDialog&&(this._dialogInput.css({position:"absolute",left:"0",top:"-100px"}),b.blockUI&&(b.unblockUI(),b("body").append(this.dpDiv)));this._inDialog=!1}},_tidyDialog:function(a){a.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar")}, +_checkExternalClick:function(a){b.datepicker._curInst&&(a=b(a.target),a[0].id!=b.datepicker._mainDivId&&(0==a.parents("#"+b.datepicker._mainDivId).length&&!a.hasClass(b.datepicker.markerClassName)&&!a.hasClass(b.datepicker._triggerClass)&&b.datepicker._datepickerShowing&&(!b.datepicker._inDialog||!b.blockUI))&&b.datepicker._hideDatepicker())},_adjustDate:function(a,c,d){var a=b(a),e=this._getInst(a[0]);this._isDisabledDatepicker(a[0])||(this._adjustInstDate(e,c+("M"==d?this._get(e,"showCurrentAtPos"): +0),d),this._updateDatepicker(e))},_gotoToday:function(a){var a=b(a),c=this._getInst(a[0]);if(this._get(c,"gotoCurrent")&&c.currentDay)c.selectedDay=c.currentDay,c.drawMonth=c.selectedMonth=c.currentMonth,c.drawYear=c.selectedYear=c.currentYear;else{var d=new Date;c.selectedDay=d.getDate();c.drawMonth=c.selectedMonth=d.getMonth();c.drawYear=c.selectedYear=d.getFullYear()}this._notifyChange(c);this._adjustDate(a)},_selectMonthYear:function(a,c,d){var a=b(a),e=this._getInst(a[0]);e._selectingMonthYear= +!1;e["selected"+("M"==d?"Month":"Year")]=e["draw"+("M"==d?"Month":"Year")]=parseInt(c.options[c.selectedIndex].value,10);this._notifyChange(e);this._adjustDate(a)},_clickMonthYear:function(a){var c=this._getInst(b(a)[0]);c.input&&c._selectingMonthYear&&setTimeout(function(){c.input.focus()},0);c._selectingMonthYear=!c._selectingMonthYear},_selectDay:function(a,c,d,e){var g=b(a);!b(e).hasClass(this._unselectableClass)&&!this._isDisabledDatepicker(g[0])&&(g=this._getInst(g[0]),g.selectedDay=g.currentDay= +b("a",e).html(),g.selectedMonth=g.currentMonth=c,g.selectedYear=g.currentYear=d,this._selectDate(a,this._formatDate(g,g.currentDay,g.currentMonth,g.currentYear)))},_clearDate:function(a){a=b(a);this._getInst(a[0]);this._selectDate(a,"")},_selectDate:function(a,c){var d=this._getInst(b(a)[0]),c=null!=c?c:this._formatDate(d);d.input&&d.input.val(c);this._updateAlternate(d);var e=this._get(d,"onSelect");e?e.apply(d.input?d.input[0]:null,[c,d]):d.input&&d.input.trigger("change");d.inline?this._updateDatepicker(d): +(this._hideDatepicker(),this._lastInput=d.input[0],"object"!=typeof d.input[0]&&d.input.focus(),this._lastInput=null)},_updateAlternate:function(a){var c=this._get(a,"altField");if(c){var d=this._get(a,"altFormat")||this._get(a,"dateFormat"),e=this._getDate(a),g=this.formatDate(d,e,this._getFormatConfig(a));b(c).each(function(){b(this).val(g)})}},noWeekends:function(a){a=a.getDay();return[0a,""]},iso8601Week:function(a){a=new Date(a.getTime());a.setDate(a.getDate()+4-(a.getDay()||7));var b= +a.getTime();a.setMonth(0);a.setDate(1);return Math.floor(Math.round((b-a)/864E5)/7)+1},parseDate:function(a,c,d){if(null==a||null==c)throw"Invalid arguments";c="object"==typeof c?c.toString():c+"";if(""==c)return null;for(var e=(d?d.shortYearCutoff:null)||this._defaults.shortYearCutoff,e="string"!=typeof e?e:(new Date).getFullYear()%100+parseInt(e,10),g=(d?d.dayNamesShort:null)||this._defaults.dayNamesShort,h=(d?d.dayNames:null)||this._defaults.dayNames,p=(d?d.monthNamesShort:null)||this._defaults.monthNamesShort, +n=(d?d.monthNames:null)||this._defaults.monthNames,q=d=-1,o=-1,w=-1,r=!1,u=function(b){(b=E+1d&&(d+=(new Date).getFullYear()-(new Date).getFullYear()%100+(d<=e?0:-100));if(-1b.getYear()%100?"0":"")+b.getYear()%100;break;case "@":o+=b.getTime();break;case "!":o+=1E4*b.getTime()+this._ticksTo1970;break;case "'":h("'")?o+="'":w=!0;break;default:o+=a.charAt(r)}return o},_possibleChars:function(a){for(var b= +"",c=!1,d=function(b){(b=e+1n&&(n+=12,s--);if(u)for(var v=this._daylightSavingAdjust(new Date(u.getFullYear(),u.getMonth()-p[0]*p[1]+1,u.getDate())),v=r&&vv;)n--,0>n&&(n=11,s--);a.drawMonth=n;a.drawYear=s;var v=this._get(a,"prevText"),v=!m?v:this.formatDate(v,this._daylightSavingAdjust(new Date(s,n-q,1)),this._getFormatConfig(a)), +v=this._canAdjustMonth(a,-1,s,n)?''+v+"":g?"":''+v+"",z=this._get(a,"nextText"),z=!m?z:this.formatDate(z,this._daylightSavingAdjust(new Date(s, +n+q,1)),this._getFormatConfig(a)),g=this._canAdjustMonth(a,1,s,n)?''+z+"":g?"":''+z+"",q=this._get(a,"currentText"),z=this._get(a,"gotoCurrent")&& +a.currentDay?w:c,q=!m?q:this.formatDate(q,z,this._getFormatConfig(a)),m=!a.inline?'":"",e=e?'
      '+(d?m:"")+(this._isInRange(a,z)?'":"")+(d?"":m)+"
      ":"",m=parseInt(this._get(a,"firstDay"),10),m=isNaN(m)?0:m,q=this._get(a,"showWeek"),z=this._get(a,"dayNames");this._get(a,"dayNamesShort");var B=this._get(a,"dayNamesMin"),E=this._get(a,"monthNames"),C=this._get(a,"monthNamesShort"),O=this._get(a,"beforeShowDay"),K=this._get(a,"showOtherMonths"),S=this._get(a,"selectOtherMonths");this._get(a,"calculateWeek");for(var P=this._getDefaultDate(a),G="",H=0;H'+(/all|left/.test(A)&& +0==H?d?g:v:"")+(/all|right/.test(A)&&0==H?d?v:g:"")+this._generateMonthYearHeader(a,n,s,r,u,0
      '),D=q?'":"",A=0;7>A;A++)var x=(A+m)%7,D=D+("'+B[x]+"");y+=D+"";D=this._getDaysInMonth(s,n);s==a.selectedYear&&n==a.selectedMonth&&(a.selectedDay=Math.min(a.selectedDay, +D));A=(this._getFirstDayOfMonth(s,n)-m+7)%7;D=Math.ceil((A+D)/7);this.maxRows=D=o?this.maxRows>D?this.maxRows:D:D;for(var x=this._daylightSavingAdjust(new Date(s,n,1-A)),R=0;R",M=!q?"":'",A=0;7>A;A++){var J=O?O.apply(a.input?a.input[0]:null,[x]):[!0,""],F=x.getMonth()!=n,N=F&&!S||!J[0]||r&&xu,M=M+('");x.setDate(x.getDate()+1);x=this._daylightSavingAdjust(x)}y+=M+""}n++;11
      '+this._get(a,"weekHeader")+"
      '+this._get(a,"calculateWeek")(x)+""+(F&&!K? +" ":N?''+x.getDate()+"":''+x.getDate()+"")+"
      "+(o?""+(0':""):"");L+=y}G+=L}G+=e+(b.browser.msie&& +7>parseInt(b.browser.version,10)&&!a.inline?'':"");a._keyEvent=!1;return G},_generateMonthYearHeader:function(a,b,c,d,e,g,p,n){var q=this._get(a,"changeMonth"),o=this._get(a,"changeYear"),w=this._get(a,"showMonthAfterYear"),r='
      ',u="";if(g||!q)u+=''+p[b]+"";else{for(var p=d&&d.getFullYear()==c,s=e&&e.getFullYear()==c,u=u+('"}w||(r+=u+(g||!q||!o?" ":""));if(!a.yearshtml)if(a.yearshtml="",g||!o)r+=''+c+"";else{var n=this._get(a,"yearRange").split(":"),z=(new Date).getFullYear(),p=function(a){a= +a.match(/c[+-].*/)?c+parseInt(a.substring(1),10):a.match(/[+-].*/)?z+parseInt(a,10):parseInt(a,10);return isNaN(a)?z:a},b=p(n[0]),n=Math.max(b,p(n[1]||"")),b=d?Math.max(b,d.getFullYear()):b,n=e?Math.min(n,e.getFullYear()):n;for(a.yearshtml+='";r+=a.yearshtml;a.yearshtml=null}r+=this._get(a,"yearSuffix");w&&(r+=(g||!q||!o?" ":"")+u);return r+"
      "},_adjustInstDate:function(a,b,c){var d=a.drawYear+("Y"==c?b:0),e=a.drawMonth+("M"==c?b:0),b=Math.min(a.selectedDay,this._getDaysInMonth(d,e))+("D"==c?b:0),d=this._restrictMinMax(a,this._daylightSavingAdjust(new Date(d,e,b)));a.selectedDay=d.getDate();a.drawMonth=a.selectedMonth=d.getMonth();a.drawYear=a.selectedYear=d.getFullYear();("M"==c|| +"Y"==c)&&this._notifyChange(a)},_restrictMinMax:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max"),c=c&&bd?d:c},_notifyChange:function(a){var b=this._get(a,"onChangeMonthYear");b&&b.apply(a.input?a.input[0]:null,[a.selectedYear,a.selectedMonth+1,a])},_getNumberOfMonths:function(a){a=this._get(a,"numberOfMonths");return null==a?[1,1]:"number"==typeof a?[1,a]:a},_getMinMaxDate:function(a,b){return this._determineDate(a,this._get(a,b+"Date"),null)},_getDaysInMonth:function(a, +b){return 32-this._daylightSavingAdjust(new Date(a,b,32)).getDate()},_getFirstDayOfMonth:function(a,b){return(new Date(a,b,1)).getDay()},_canAdjustMonth:function(a,b,c,d){var e=this._getNumberOfMonths(a),c=this._daylightSavingAdjust(new Date(c,d+(0>b?b:e[0]*e[1]),1));0>b&&c.setDate(this._getDaysInMonth(c.getFullYear(),c.getMonth()));return this._isInRange(a,c)},_isInRange:function(a,b){var c=this._getMinMaxDate(a,"min"),d=this._getMinMaxDate(a,"max");return(!c||b.getTime()>=c.getTime())&&(!d||b.getTime()<= +d.getTime())},_getFormatConfig:function(a){var b=this._get(a,"shortYearCutoff"),b="string"!=typeof b?b:(new Date).getFullYear()%100+parseInt(b,10);return{shortYearCutoff:b,dayNamesShort:this._get(a,"dayNamesShort"),dayNames:this._get(a,"dayNames"),monthNamesShort:this._get(a,"monthNamesShort"),monthNames:this._get(a,"monthNames")}},_formatDate:function(a,b,c,d){b||(a.currentDay=a.selectedDay,a.currentMonth=a.selectedMonth,a.currentYear=a.selectedYear);b=b?"object"==typeof b?b:this._daylightSavingAdjust(new Date(d, +c,b)):this._daylightSavingAdjust(new Date(a.currentYear,a.currentMonth,a.currentDay));return this.formatDate(this._get(a,"dateFormat"),b,this._getFormatConfig(a))}});b.fn.datepicker=function(a){if(!this.length)return this;b.datepicker.initialized||(b(document).mousedown(b.datepicker._checkExternalClick).find("body").append(b.datepicker.dpDiv),b.datepicker.initialized=!0);var c=Array.prototype.slice.call(arguments,1);return"string"==typeof a&&("isDisabled"==a||"getDate"==a||"widget"==a)||"option"== +a&&2==arguments.length&&"string"==typeof arguments[1]?b.datepicker["_"+a+"Datepicker"].apply(b.datepicker,[this[0]].concat(c)):this.each(function(){typeof a=="string"?b.datepicker["_"+a+"Datepicker"].apply(b.datepicker,[this].concat(c)):b.datepicker._attachDatepicker(this,a)})};b.datepicker=new c;b.datepicker.initialized=!1;b.datepicker.uuid=(new Date).getTime();b.datepicker.version="1.8.14";window["DP_jQuery_"+h]=b})(jQuery); +(function(b,a){b.widget("ui.progressbar",{options:{value:0,max:100},min:0,_create:function(){this.element.addClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").attr({role:"progressbar","aria-valuemin":this.min,"aria-valuemax":this.options.max,"aria-valuenow":this._value()});this.valueDiv=b("
      ").appendTo(this.element);this.oldValue=this._value();this._refreshValue()},destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"); +this.valueDiv.remove();b.Widget.prototype.destroy.apply(this,arguments)},value:function(b){if(b===a)return this._value();this._setOption("value",b);return this},_setOption:function(a,d){"value"===a&&(this.options.value=d,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete"));b.Widget.prototype._setOption.apply(this,arguments)},_value:function(){var a=this.options.value;"number"!==typeof a&&(a=0);return Math.min(this.options.max,Math.max(this.min,a))},_percentage:function(){return 100* +this._value()/this.options.max},_refreshValue:function(){var a=this.value(),b=this._percentage();this.oldValue!==a&&(this.oldValue=a,this._trigger("change"));this.valueDiv.toggle(a>this.min).toggleClass("ui-corner-right",a===this.options.max).width(b.toFixed(0)+"%");this.element.attr("aria-valuenow",a)}});b.extend(b.ui.progressbar,{version:"1.8.14"})})(jQuery); +jQuery.effects||function(b,a){function c(a){var c;return a&&a.constructor==Array&&3==a.length?a:(c=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(a))?[parseInt(c[1],10),parseInt(c[2],10),parseInt(c[3],10)]:(c=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(a))?[2.55*parseFloat(c[1]),2.55*parseFloat(c[2]),2.55*parseFloat(c[3])]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))?[parseInt(c[1],16),parseInt(c[2], +16),parseInt(c[3],16)]:(c=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(a))?[parseInt(c[1]+c[1],16),parseInt(c[2]+c[2],16),parseInt(c[3]+c[3],16)]:/rgba\(0, 0, 0, 0\)/.exec(a)?i.transparent:i[b.trim(a).toLowerCase()]}function d(){var a=document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle,b={},c,d;if(a&&a.length&&a[0]&&a[a[0]])for(var e=a.length;e--;)c=a[e],"string"==typeof a[c]&&(d=c.replace(/\-(\w)/g,function(a,b){return b.toUpperCase()}),b[d]=a[c]);else for(c in a)"string"=== +typeof a[c]&&(b[c]=a[c]);return b}function g(a){var c,d;for(c in a)d=a[c],(null==d||b.isFunction(d)||c in k||/scrollbar/.test(c)||!/color/i.test(c)&&isNaN(parseFloat(d)))&&delete a[c];return a}function h(a,b){var c={_:0},d;for(d in b)a[d]!=b[d]&&(c[d]=b[d]);return c}function e(a,c,d,e){"object"==typeof a&&(e=c,d=null,c=a,a=c.effect);b.isFunction(c)&&(e=c,d=null,c={});if("number"==typeof c||b.fx.speeds[c])e=d,d=c,c={};b.isFunction(d)&&(e=d,d=null);c=c||{};d=d||c.duration;d=b.fx.off?0:"number"==typeof d? +d:d in b.fx.speeds?b.fx.speeds[d]:b.fx.speeds._default;e=e||c.complete;return[a,c,d,e]}function f(a){return!a||("number"===typeof a||b.fx.speeds[a])||"string"===typeof a&&!b.effects[a]?!0:!1}b.effects={};b.each("backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor borderColor color outlineColor".split(" "),function(a,d){b.fx.step[d]=function(a){if(!a.colorInit){var e;e=a.elem;var f=d,g;do{g=b.curCSS(e,f);if(g!=""&&g!="transparent"||b.nodeName(e,"body"))break;f="backgroundColor"}while(e= +e.parentNode);e=c(g);a.start=e;a.end=c(a.end);a.colorInit=true}a.elem.style[d]="rgb("+Math.max(Math.min(parseInt(a.pos*(a.end[0]-a.start[0])+a.start[0],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[1]-a.start[1])+a.start[1],10),255),0)+","+Math.max(Math.min(parseInt(a.pos*(a.end[2]-a.start[2])+a.start[2],10),255),0)+")"}});var i={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139], +darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255], +maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]},j=["add","remove","toggle"],k={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};b.effects.animateClass=function(a,c,e,f){b.isFunction(e)&&(f=e,e=null);return this.queue(function(){var i=b(this),o=i.attr("style")|| +" ",k=g(d.call(this)),r,u=i.attr("class");b.each(j,function(b,c){if(a[c])i[c+"Class"](a[c])});r=g(d.call(this));i.attr("class",u);i.animate(h(k,r),{queue:false,duration:c,easing:e,complete:function(){b.each(j,function(b,c){if(a[c])i[c+"Class"](a[c])});if(typeof i.attr("style")=="object"){i.attr("style").cssText="";i.attr("style").cssText=o}else i.attr("style",o);f&&f.apply(this,arguments);b.dequeue(this)}})})};b.fn.extend({_addClass:b.fn.addClass,addClass:function(a,c,d,e){return c?b.effects.animateClass.apply(this, +[{add:a},c,d,e]):this._addClass(a)},_removeClass:b.fn.removeClass,removeClass:function(a,c,d,e){return c?b.effects.animateClass.apply(this,[{remove:a},c,d,e]):this._removeClass(a)},_toggleClass:b.fn.toggleClass,toggleClass:function(c,d,e,f,g){return"boolean"==typeof d||d===a?e?b.effects.animateClass.apply(this,[d?{add:c}:{remove:c},e,f,g]):this._toggleClass(c,d):b.effects.animateClass.apply(this,[{toggle:c},d,e,f])},switchClass:function(a,c,d,e,f){return b.effects.animateClass.apply(this,[{add:c, +remove:a},d,e,f])}});b.extend(b.effects,{version:"1.8.14",save:function(a,b){for(var c=0;c").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0});a.wrap(d);d=a.parent();"static"==a.css("position")?(d.css({position:"relative"}),a.css({position:"relative"})): +(b.extend(c,{position:a.css("position"),zIndex:a.css("z-index")}),b.each(["top","left","bottom","right"],function(b,d){c[d]=a.css(d);isNaN(parseInt(c[d],10))&&(c[d]="auto")}),a.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"}));return d.css(c).show()},removeWrapper:function(a){return a.parent().is(".ui-effects-wrapper")?a.parent().replaceWith(a):a},setTransition:function(a,c,d,e){e=e||{};b.each(c,function(b,c){unit=a.cssUnit(c);0(b/=e/2)?d/2*b*b+c:-d/2*(--b*(b-2)-1)+c},easeInCubic:function(a,b,c,d,e){return d*(b/=e)*b*b+c},easeOutCubic:function(a,b,c,d,e){return d*((b=b/e-1)*b*b+1)+c},easeInOutCubic:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b+c:d/2*((b-=2)*b*b+2)+c},easeInQuart:function(a,b,c,d,e){return d*(b/=e)*b*b*b+c}, +easeOutQuart:function(a,b,c,d,e){return-d*((b=b/e-1)*b*b*b-1)+c},easeInOutQuart:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b*b+c:-d/2*((b-=2)*b*b*b-2)+c},easeInQuint:function(a,b,c,d,e){return d*(b/=e)*b*b*b*b+c},easeOutQuint:function(a,b,c,d,e){return d*((b=b/e-1)*b*b*b*b+1)+c},easeInOutQuint:function(a,b,c,d,e){return 1>(b/=e/2)?d/2*b*b*b*b*b+c:d/2*((b-=2)*b*b*b*b+2)+c},easeInSine:function(a,b,c,d,e){return-d*Math.cos(b/e*(Math.PI/2))+d+c},easeOutSine:function(a,b,c,d,e){return d*Math.sin(b/ +e*(Math.PI/2))+c},easeInOutSine:function(a,b,c,d,e){return-d/2*(Math.cos(Math.PI*b/e)-1)+c},easeInExpo:function(a,b,c,d,e){return 0==b?c:d*Math.pow(2,10*(b/e-1))+c},easeOutExpo:function(a,b,c,d,e){return b==e?c+d:d*(-Math.pow(2,-10*b/e)+1)+c},easeInOutExpo:function(a,b,c,d,e){return 0==b?c:b==e?c+d:1>(b/=e/2)?d/2*Math.pow(2,10*(b-1))+c:d/2*(-Math.pow(2,-10*--b)+2)+c},easeInCirc:function(a,b,c,d,e){return-d*(Math.sqrt(1-(b/=e)*b)-1)+c},easeOutCirc:function(a,b,c,d,e){return d*Math.sqrt(1-(b=b/e-1)* +b)+c},easeInOutCirc:function(a,b,c,d,e){return 1>(b/=e/2)?-d/2*(Math.sqrt(1-b*b)-1)+c:d/2*(Math.sqrt(1-(b-=2)*b)+1)+c},easeInElastic:function(a,b,c,d,e){var a=1.70158,f=0,g=d;if(0==b)return c;if(1==(b/=e))return c+d;f||(f=0.3*e);gb?-0.5*g*Math.pow(2,10*(b-=1))*Math.sin((b*e-a)*2*Math.PI/f)+c:0.5*g*Math.pow(2,-10*(b-=1))*Math.sin((b*e-a)*2*Math.PI/f)+d+c},easeInBack:function(b,c,d,e,f,g){g==a&&(g=1.70158);return e*(c/=f)*c*((g+1)*c-g)+d},easeOutBack:function(b,c,d,e, +f,g){g==a&&(g=1.70158);return e*((c=c/f-1)*c*((g+1)*c+g)+1)+d},easeInOutBack:function(b,c,d,e,f,g){g==a&&(g=1.70158);return 1>(c/=f/2)?e/2*c*c*(((g*=1.525)+1)*c-g)+d:e/2*((c-=2)*c*(((g*=1.525)+1)*c+g)+2)+d},easeInBounce:function(a,c,d,e,f){return e-b.easing.easeOutBounce(a,f-c,0,e,f)+d},easeOutBounce:function(a,b,c,d,e){return(b/=e)<1/2.75?d*7.5625*b*b+c:b<2/2.75?d*(7.5625*(b-=1.5/2.75)*b+0.75)+c:b<2.5/2.75?d*(7.5625*(b-=2.25/2.75)*b+0.9375)+c:d*(7.5625*(b-=2.625/2.75)*b+0.984375)+c},easeInOutBounce:function(a, +c,d,e,f){return c").css({position:"absolute",visibility:"visible",left:-j*(e/d),top:-i*(f/c)}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:e/d,height:f/c,left:h.left+j*(e/d)+("show"==a.options.mode?(j-Math.floor(d/2))*(e/d):0),top:h.top+i*(f/c)+("show"==a.options.mode?(i-Math.floor(c/2))*(f/c):0),opacity:"show"==a.options.mode?0:1}).animate({left:h.left+j*(e/d)+("show"==a.options.mode?0:(j-Math.floor(d/2))*(e/d)),top:h.top+ +i*(f/c)+("show"==a.options.mode?0:(i-Math.floor(c/2))*(f/c)),opacity:"show"==a.options.mode?1:0},a.duration||500);setTimeout(function(){"show"==a.options.mode?g.css({visibility:"visible"}):g.css({visibility:"visible"}).hide();a.callback&&a.callback.apply(g[0]);g.dequeue();b("div.ui-effects-explode").remove()},a.duration||500)})}})(jQuery); +(function(b){b.effects.fade=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"hide");c.animate({opacity:d},{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +(function(b){b.effects.fold=function(a){return this.queue(function(){var c=b(this),d=["position","top","bottom","left","right"],g=b.effects.setMode(c,a.options.mode||"hide"),h=a.options.size||15,e=!!a.options.horizFirst,f=a.duration?a.duration/2:b.fx.speeds._default/2;b.effects.save(c,d);c.show();var i=b.effects.createWrapper(c).css({overflow:"hidden"}),j="show"==g!=e,k=j?["width","height"]:["height","width"],j=j?[i.width(),i.height()]:[i.height(),i.width()],l=/([0-9]+)%/.exec(h);l&&(h=parseInt(l[1], +10)/100*j["hide"==g?0:1]);"show"==g&&i.css(e?{height:0,width:h}:{height:h,width:0});e={};l={};e[k[0]]="show"==g?j[0]:h;l[k[1]]="show"==g?j[1]:0;i.animate(e,f,a.options.easing).animate(l,f,a.options.easing,function(){"hide"==g&&c.hide();b.effects.restore(c,d);b.effects.removeWrapper(c);a.callback&&a.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery); +(function(b){b.effects.highlight=function(a){return this.queue(function(){var c=b(this),d=["backgroundImage","backgroundColor","opacity"],g=b.effects.setMode(c,a.options.mode||"show"),h={backgroundColor:c.css("backgroundColor")};"hide"==g&&(h.opacity=0);b.effects.save(c,d);c.show().css({backgroundImage:"none",backgroundColor:a.options.color||"#ffff99"}).animate(h,{queue:!1,duration:a.duration,easing:a.options.easing,complete:function(){g=="hide"&&c.hide();b.effects.restore(c,d);g=="show"&&!b.support.opacity&& +this.style.removeAttribute("filter");a.callback&&a.callback.apply(this,arguments);c.dequeue()}})})}})(jQuery); +(function(b){b.effects.pulsate=function(a){return this.queue(function(){var c=b(this),d=b.effects.setMode(c,a.options.mode||"show");times=2*(a.options.times||5)-1;duration=a.duration?a.duration/2:b.fx.speeds._default/2;isVisible=c.is(":visible");animateTo=0;isVisible||(c.css("opacity",0).show(),animateTo=1);("hide"==d&&isVisible||"show"==d&&!isVisible)&×--;for(d=0;d').appendTo(document.body).addClass(a.options.className).css({top:g.top,left:g.left,height:c.innerHeight(),width:c.innerWidth(),position:"absolute"}).animate(d,a.duration,a.options.easing,function(){h.remove();a.callback&&a.callback.apply(c[0],arguments);c.dequeue()})})}})(jQuery); +/* + * jQuery Highlight plugin + * Based on highlight v3 by Johann Burkard + * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html + * Copyright (c) 2009 Bartek Szopka http://bartaz.github.com/sandbox.js/jquery.highlight.html + * Licensed under MIT license. + */ +jQuery.extend({highlight:function(a,c,b,e){if(a.nodeType===3){if(c=a.data.match(c)){b=document.createElement(b||"span");b.className=e||"highlight";a=a.splitText(c.index);a.splitText(c[0].length);e=a.cloneNode(true);b.appendChild(e);a.parentNode.replaceChild(b,a);return 1}}else if(a.nodeType===1&&a.childNodes&&!/(script|style)/i.test(a.tagName)&&!(a.tagName===b.toUpperCase()&&a.className===e))for(var d=0;d').appendTo("body"); + var d = { width: $c.width() - $c[0].clientWidth, height: $c.height() - $c[0].clientHeight }; + $c.remove(); + window.scrollbarWidth = d.width; + window.scrollbarHeight = d.height; + return dim.match(/^(width|height)$/) ? d[dim] : d; + } + + + /** + * Returns hash container 'display' and 'visibility' + * + * @see $.swap() - swaps CSS, runs callback, resets CSS + */ +, showInvisibly: function ($E, force) { + if (!$E) return {}; + if (!$E.jquery) $E = $($E); + var CSS = { + display: $E.css('display') + , visibility: $E.css('visibility') + }; + if (force || CSS.display === "none") { // only if not *already hidden* + $E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured + return CSS; + } + else return {}; + } + + /** + * Returns data for setting size of an element (container or a pane). + * + * @see _create(), onWindowResize() for container, plus others for pane + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ +, getElementDimensions: function ($E) { + var + d = {} // dimensions hash + , x = d.css = {} // CSS hash + , i = {} // TEMP insets + , b, p // TEMP border, padding + , N = $.layout.cssNum + , off = $E.offset() + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { // e = edge + b = x["border" + e] = $.layout.borderWidth($E, e); + p = x["padding"+ e] = $.layout.cssNum($E, "padding"+e); + i[e] = b + p; // total offset of content from outer side + d["inset"+ e] = p; + }); + + d.offsetWidth = $E.innerWidth(); // offsetWidth is used in calc when doing manual resize + d.offsetHeight = $E.innerHeight(); // ditto + d.outerWidth = $E.outerWidth(); + d.outerHeight = $E.outerHeight(); + d.innerWidth = max(0, d.outerWidth - i.Left - i.Right); + d.innerHeight = max(0, d.outerHeight - i.Top - i.Bottom); + + x.width = $E.width(); + x.height = $E.height(); + x.top = N($E,"top",true); + x.bottom = N($E,"bottom",true); + x.left = N($E,"left",true); + x.right = N($E,"right",true); + + //d.visible = $E.is(":visible");// && x.width > 0 && x.height > 0; + + return d; + } + +, getElementCSS: function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p === "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + } + + /** + * Return the innerWidth for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerWidth (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerWidth of the elem by subtracting padding and borders + */ +, cssWidth: function ($E, outerWidth) { + var + b = $.layout.borderWidth + , n = $.layout.cssNum + ; + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + if (!$.support.boxModel) return outerWidth; + + // strip border and padding from outerWidth to get CSS Width + var W = outerWidth + - b($E, "Left") + - b($E, "Right") + - n($E, "paddingLeft") + - n($E, "paddingRight") + ; + + return max(0,W); + } + + /** + * Return the innerHeight for the current browser/doctype + * + * @see initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {number=} outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @return {number} Returns the innerHeight of the elem by subtracting padding and borders + */ +, cssHeight: function ($E, outerHeight) { + var + b = $.layout.borderWidth + , n = $.layout.cssNum + ; + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + if (!$.support.boxModel) return outerHeight; + + // strip border and padding from outerHeight to get CSS Height + var H = outerHeight + - b($E, "Top") + - b($E, "Bottom") + - n($E, "paddingTop") + - n($E, "paddingBottom") + ; + + return max(0,H); + } + + /** + * Returns the 'current CSS numeric value' for a CSS property - 0 if property does not exist + * + * @see Called by many methods + * @param {Array.} $E Must pass a jQuery object - first element is processed + * @param {string} prop The name of the CSS property, eg: top, width, etc. + * @param {boolean=} [allowAuto=false] true = return 'auto' if that is value; false = return 0 + * @return {(string|number)} Usually used to get an integer value for position (top, left) or size (height, width) + */ +, cssNum: function ($E, prop, allowAuto) { + if (!$E.jquery) $E = $($E); + var CSS = $.layout.showInvisibly($E) + , p = $.curCSS($E[0], prop, true) + , v = allowAuto && p=="auto" ? p : (parseInt(p, 10) || 0); + $E.css( CSS ); // RESET + return v; + } + +, borderWidth: function (el, side) { + if (el.jquery) el = el[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.curCSS(el, b+"Style", true) === "none" ? 0 : (parseInt($.curCSS(el, b+"Width", true), 10) || 0); + } + + /** + * Mouse-tracking utility - FUTURE REFERENCE + * + * init: if (!window.mouse) { + * window.mouse = { x: 0, y: 0 }; + * $(document).mousemove( $.layout.trackMouse ); + * } + * + * @param {Object} evt + * +, trackMouse: function (evt) { + window.mouse = { x: evt.clientX, y: evt.clientY }; + } + */ + + /** + * SUBROUTINE for preventPrematureSlideClose option + * + * @param {Object} evt + * @param {Object=} el + */ +, isMouseOverElem: function (evt, el) { + var + $E = $(el || this) + , d = $E.offset() + , T = d.top + , L = d.left + , R = L + $E.outerWidth() + , B = T + $E.outerHeight() + , x = evt.pageX // evt.clientX ? + , y = evt.pageY // evt.clientY ? + ; + // if X & Y are < 0, probably means is over an open SELECT + return ($.layout.browser.msie && x < 0 && y < 0) || ((x >= L && x <= R) && (y >= T && y <= B)); + } + + /** + * Message/Logging Utility + * + * @example $.layout.msg("My message"); // log text + * @example $.layout.msg("My message", true); // alert text + * @example $.layout.msg({ foo: "bar" }, "Title"); // log hash-data, with custom title + * @example $.layout.msg({ foo: "bar" }, true, "Title", { sort: false }); -OR- + * @example $.layout.msg({ foo: "bar" }, "Title", { sort: false, display: true }); // alert hash-data + * + * @param {(Object|string)} info String message OR Hash/Array + * @param {(Boolean|string|Object)=} [popup=false] True means alert-box - can be skipped + * @param {(Object|string)=} [debugTitle=""] Title for Hash data - can be skipped + * @param {Object=} [debutOpts={}] Extra options for debug output + */ +, msg: function (info, popup, debugTitle, debugOpts) { + if ($.isPlainObject(info) && window.debugData) { + if (typeof popup === "string") { + debugOpts = debugTitle; + debugTitle = popup; + } + else if (typeof debugTitle === "object") { + debugOpts = debugTitle; + debugTitle = null; + } + var t = debugTitle || "log( )" + , o = $.extend({ sort: false, returnHTML: false, display: false }, debugOpts); + if (popup === true || o.display) + debugData( info, t, o ); + else if (window.console) + console.log(debugData( info, t, o )); + } + else if (popup) + alert(info); + else if (window.console) + console.log(info); + else { + var id = "#layoutLogger" + , $l = $(id); + if (!$l.length) + $l = createLog(); + $l.children("ul").append('
    • '+ info.replace(/\/g,">") +'
    • '); + } + + function createLog () { + var pos = $.support.fixedPosition ? 'fixed' : 'absolute' + , $e = $('
      ' + + '
      ' + + 'XLayout console.log
      ' + + '
        ' + + '
        ' + ).appendTo("body"); + $e.css('left', $(window).width() - $e.outerWidth() - 5) + if ($.ui.draggable) $e.draggable({ handle: ':first-child' }); + return $e; + }; + } + +}; + +var lang = $.layout.language; // alias used in defaults... + +// DEFAULT OPTIONS - CHANGE IF DESIRED +$.layout.defaults = { +/* + * LAYOUT & LAYOUT-CONTAINER OPTIONS + * - none of these options are applicable to individual panes + */ + name: "" // Not required, but useful for buttons and used for the state-cookie +, containerSelector: "" // ONLY used when specifying a childOptions - to find container-element that is NOT directly-nested +, containerClass: "ui-layout-container" // layout-container element +, scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) +, resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event +, resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky +, resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized +, onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific +, onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific +, onload_start: null // CALLBACK when Layout inits - after options initialized, but before elements +, onload_end: null // CALLBACK when Layout inits - after EVERYTHING has been initialized +, onunload_start: null // CALLBACK when Layout is destroyed OR onWindowUnload +, onunload_end: null // CALLBACK when Layout is destroyed OR onWindowUnload +, autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them +, initPanes: true // false = DO NOT initialize the panes onLoad - will init later +, showErrorMessages: true // enables fatal error messages to warn developers of common errors +, showDebugMessages: false // display console-and-alert debug msgs - IF this Layout version _has_ debugging code! +// Changing this zIndex value will cause other zIndex values to automatically change +, zIndex: null // the PANE zIndex - resizers and masks will be +1 +// DO NOT CHANGE the zIndex values below unless you clearly understand their relationships +, zIndexes: { // set _default_ z-index values here... + pane_normal: 0 // normal z-index for panes + , content_mask: 1 // applied to overlays used to mask content INSIDE panes during resizing + , resizer_normal: 2 // normal z-index for resizer-bars + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } +/* + * PANE DEFAULT SETTINGS + * - settings under the 'panes' key become the default settings for *all panes* + * - ALL pane-options can also be set specifically for each panes, which will override these 'default values' + */ +, panes: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' + , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // Layout Pane + , resizerClass: "ui-layout-resizer" // Resizer Bar + , togglerClass: "ui-layout-toggler" // Toggler Button + , buttonClass: "ui-layout-button" // CUSTOM Buttons - eg: '[ui-layout-button]-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerTip_open: lang.Close // Toggler tool-tip (title) + , togglerTip_closed: lang.Open // ditto + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskContents: false // true = add DIV-mask over-or-inside this pane so can 'drag' over IFRAMES + , maskObjects: false // true = add IFRAME-mask over-or-inside this pane to cover objects/applets - content-mask will overlay this mask + , maskZindex: null // will override zIndexes.content_mask if specified - not applicable to iframe-panes + , resizingGrid: false // grid size that the resizers will snap-to during resizing, eg: [20,20] + , livePaneResizing: false // true = LIVE Resizing as resizer is dragged + , liveContentResizing: false // true = re-measure header/footer heights as resizer is dragged + , liveResizingTolerance: 1 // how many px change before pane resizes, to control performance + // TIPS & MESSAGES - also see lang object + , noRoomToOpenTip: lang.noRoomToOpenTip + , resizerTip: lang.Resize // Resizer tool-tip (title) + , sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseenter + , slideTrigger_close: "mouseleave"// click, mouseleave + , slideDelay_open: 300 // applies only for mouseenter event - 0 = instant open + , slideDelay_close: 300 // applies only for mouseleave event (300ms is the minimum!) + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , preventQuickSlideClose: $.layout.browser.webkit // Chrome triggers slideClosed as it is opening + , preventPrematureSlideClose: false // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open, fxSss_close & fxSss_size options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale -- only relevant to 'open' & 'close', NOT 'size' + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + , animatePaneSizing: false // true = animate resizing after dragging resizer-bar OR sizePane() is called + /* NOTE: Action-specific FX options are auto-generated from the options above if not specifically set: + fxName_open: "slide" // 'Open' pane animation + fnName_close: "slide" // 'Close' pane animation + fxName_size: "slide" // 'Size' pane animation - when animatePaneSizing = true + fxSpeed_open: null + fxSpeed_close: null + fxSpeed_size: null + fxSettings_open: {} + fxSettings_close: {} + fxSettings_size: {} + */ + // CHILD/NESTED LAYOUTS + , childOptions: null // Layout-options for nested/child layout - even {} is valid as options + , initChildLayout: true // true = child layout will be created as soon as _this_ layout completes initialization + , destroyChildLayout: true // true = destroy child-layout if this pane is destroyed + , resizeChildLayout: true // true = trigger child-layout.resizeAll() when this pane is resized + // PANE CALLBACKS + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsDuringLiveResize: true // true = trigger onresize callback REPEATEDLY if livePaneResizing==true + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS + , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS + , onswap_start: null // CALLBACK when pane STARTS to Swap + , onswap_end: null // CALLBACK when pane ENDS being Swapped + , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized + , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized + } +/* + * PANE-SPECIFIC SETTINGS + * - options listed below MUST be specified per-pane - they CANNOT be set under 'panes' + * - all options under the 'panes' key can also be set specifically for any pane + * - most options under the 'panes' key apply only to 'border-panes' - NOT the the center-pane + */ +, north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", .30, 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode (43) OR a character ("o") + } +, south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } +, east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } +, west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } +, center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } +}; + +$.layout.optionsMap = { + // layout/global options - NOT pane-options + layout: ("stateManagement,effects,zIndexes," + + "name,zIndex,scrollToBookmarkOnLoad,showErrorMessages," + + "resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay," + + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons").split(",") +// borderPanes: [ ALL options that are NOT specified as 'layout' ] + // default.panes options that apply to the center-pane (most options apply _only_ to border-panes) +, center: ("paneClass,contentSelector,contentIgnoreSelector,findNestedContent,applyDemoStyles,triggerEventsOnLoad," + + "showOverflowOnHover,maskContents,maskObjects,liveContentResizing," + + "childOptions,initChildLayout,resizeChildLayout,destroyChildLayout," + + "onresize,onresize_start,onresize_end,onsizecontent,onsizecontent_start,onsizecontent_end").split(",") + // options that MUST be specifically set 'per-pane' - CANNOT set in the panes (defaults) key +, noDefault: ("paneSelector,resizerCursor,customHotkey").split(",") +}; + +/** + * Processes options passed in converts flat-format data into subkey (JSON) format + * In flat-format, subkeys are _currently_ separated with 2 underscores, like north__optName + * Plugins may also call this method so they can transform their own data + * + * @param {!Object} hash Data/options passed by user - may be a single level or nested levels + * @return {Object} Returns hash of minWidth & minHeight + */ +$.layout.transformData = function (hash) { + var json = { panes: {}, center: {} } // init return object + , data, branch, optKey, keys, key, val, i, c; + + if (typeof hash !== "object") return json; // no options passed + + // convert all 'flat-keys' to 'sub-key' format + for (optKey in hash) { + branch = json; + data = $.layout.optionsMap.layout; + val = hash[ optKey ]; + keys = optKey.split("__"); // eg: west__size or north__fxSettings__duration + c = keys.length - 1; + // convert underscore-delimited to subkeys + for (i=0; i <= c; i++) { + key = keys[i]; + if (i === c) + branch[key] = val; + else if (!branch[key]) + branch[key] = {}; // create the subkey + // recurse to sub-key for next loop - if not done + branch = branch[key]; + } + } + + return json; +} + +// INTERNAL CONFIG DATA - DO NOT CHANGE THIS! +$.layout.backwardCompatibility = { + // data used by renameOldOptions() + map: { + // OLD Option Name: NEW Option Name + applyDefaultStyles: "applyDemoStyles" + , resizeNestedLayout: "resizeChildLayout" + , resizeWhileDragging: "livePaneResizing" + , resizeContentWhileDragging: "liveContentResizing" + , triggerEventsWhileDragging: "triggerEventsDuringLiveResize" + , maskIframesOnResize: "maskContents" + , useStateCookie: "stateManagement.enabled" + , "cookie.autoLoad": "stateManagement.autoLoad" + , "cookie.autoSave": "stateManagement.autoSave" + , "cookie.keys": "stateManagement.stateKeys" + , "cookie.name": "stateManagement.cookie.name" + , "cookie.domain": "stateManagement.cookie.domain" + , "cookie.path": "stateManagement.cookie.path" + , "cookie.expires": "stateManagement.cookie.expires" + , "cookie.secure": "stateManagement.cookie.secure" + } + /** + * @param {Object} opts + */ +, renameOptions: function (opts) { + var map = $.layout.backwardCompatibility.map + , oldData, newData, value + ; + for (var itemPath in map) { + oldData = getBranch( itemPath ); + value = oldData.branch[ oldData.key ] + if (value !== undefined) { + newData = getBranch( map[itemPath], true ) + newData.branch[ newData.key ] = value; + delete oldData.branch[ oldData.key ]; + } + } + + /** + * @param {string} path + * @param {boolean=} [create=false] Create path if does not exist + */ + function getBranch (path, create) { + var a = path.split(".") // split keys into array + , c = a.length - 1 + , D = { branch: opts, key: a[c] } // init branch at top & set key (last item) + , i = 0, k, undef; + for (; i 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerHeight + * @param {boolean=} [autoHide=false] + */ +, setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el, h; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!browser.mozilla) // FireFox refreshes iframes - IE does not + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + } + + /** + * @param {(string|!Object)} el + * @param {number=} outerSize + * @param {boolean=} [autoHide=false] + */ +, setOuterSize = function (el, outerSize, autoHide) { + if (_c[pane].dir=="horz") // pane = north or south + setOuterHeight(el, outerSize, autoHide); + else // pane = east or west + setOuterWidth(el, outerSize, autoHide); + } + + + /** + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + /** + * @param {string} pane + * @param {(string|number)=} size + * @param {string=} [dir] + * @return {number} + */ +, _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (isStr(size) && size.match(/%/)) + size = (size === '100%') ? -1 : parseInt(size, 10) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size, 10); + + var o = options, avail = 0; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + + if (size === -1) // -1 == 100% + return avail; + else if (size > 0) // percentage, eg: .25 + return round(avail * size); + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var dim = (dir === "horz" ? "height" : "width") + , $P = $Ps[pane] + , $C = dim === 'height' ? $Cs[pane] : false + , vis = $.layout.showInvisibly($P) // show pane invisibly if hidden + , szP = $P.css(dim) // SAVE current pane size + , szC = $C ? $C.css(dim) : 0 // SAVE current content size + ; + $P.css(dim, "auto"); + if ($C) $C.css(dim, "auto"); + size = (dim === "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, szP).css(vis); // RESET size & visibility + if ($C) $C.css(dim, szC); + return size; + } + } + + /** + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @param {(string|!Object)} pane + * @param {boolean=} [inclSpace=false] + * @return {number} Returns EITHER Width for east/west panes OR Height for north/south panes - adjusted for boxModel & browser + */ +, getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir === "horz") + return $P.outerHeight() + oSp; + else // dir === "vert" + return $P.outerWidth() + oSp; + } + + /** + * Calculate min/max pane dimensions and limits for resizing + * + * @param {string} pane + * @param {boolean=} [slide=false] + */ +, setSizeLimits = function (pane, slide) { + if (!isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , side = c.side.toLowerCase() + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.oppositeEdge[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.insetTop + , left = sC.insetLeft + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + } + + /** + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @return JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ +, calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + // NOTE: sC = state.container + // calc center-pane outer dimensions + d.width = sC.innerWidth - d.left - d.right; // outerWidth + d.height = sC.innerHeight - d.bottom - d.top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + d.top += sC.insetTop; + d.bottom += sC.insetBottom; + d.left += sC.insetLeft; + d.right += sC.insetRight; + + return d; + } + + + /** + * @param {!Object} el + * @param {boolean=} [allStates=false] + */ +, getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state === _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + } +, addHover = function (evt, el) { + var $E = $(el || this); + if (evt && $E.data("layoutRole") === "toggler") + evt.stopPropagation(); // prevent triggering 'slide' on Resizer-bar + $E.addClass( getHoverClasses($E) ); + } +, removeHover = function (evt, el) { + var $E = $(el || this); + $E.removeClass( getHoverClasses($E, true) ); + } + +, onResizerEnter = function (evt) { // ALSO called by toggler.mouseenter + if ($.fn.disableSelection) + $("body").disableSelection(); + } +, onResizerLeave = function (evt, el) { + var + e = el || this // el is only passed when called by the timer + , pane = $(e).data("layoutEdge") + , name = pane +"ResizerLeave" + ; + timer.clear(pane+"_openSlider"); // cancel slideOpen timer, if set + timer.clear(name); // cancel enableSelection timer - may re/set below + // this method calls itself on a timer because it needs to allow + // enough time for dragging to kick-in and set the isResizing flag + // dragging has a 100ms delay set, so this delay must be >100 + if (!el) // 1st call - mouseleave event + timer.set(name, function(){ onResizerLeave(evt, e); }, 200); + // if user is resizing, then dragStop will enableSelection(), so can skip it here + else if (!state[pane].isResizing && $.fn.enableSelection) // 2nd call - by timer + $("body").enableSelection(); + } + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see none - triggered onInit + * @return mixed true = fully initialized | false = panes not initialized (yet) | 'cancel' = abort + */ +, _create = function () { + // initialize config/options + initOptions(); + var o = options; + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // init plugins for this layout, if there are any (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onCreate ); + + // options & state have been initialized, so now run beforeLoad callback + // onload will CANCEL layout creation if it returns false + if (false === _runCallbacks("onload_start")) + return 'cancel'; + + // initialize the container element + _initContainer(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + // init plugins for this layout, if there are any (eg: customButtons) + runPluginCallbacks( Instance, $.layout.onLoad ); + + // if layout elements are hidden, then layout WILL NOT complete initialization! + // initLayoutElements will set initialized=true and run the onload callback IF successful + if (o.initPanes) _initLayoutElements(); + + delete state.creatingLayout; + + return state.initialized; + } + + /** + * Initialize the layout IF not already + * + * @see All methods in Instance run this test + * @return boolean true = layoutElements have been initialized | false = panes are not initialized (yet) + */ +, isInitialized = function () { + if (state.initialized || state.creatingLayout) return true; // already initialized + else return _initLayoutElements(); // try to init panes NOW + } + + /** + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @see _create() & isInitialized + * @return An object pointer to the instance created + */ +, _initLayoutElements = function (retry) { + // initialize config/options + var o = options; + + // CANNOT init panes inside a hidden container! + if (!$N.is(":visible")) { + // handle Chrome bug where popup window 'has no height' + // if layout is BODY element, try again in 50ms + // SEE: http://layout.jquery-dev.net/samples/test_popup_window.html + if ( !retry && browser.webkit && $N[0].tagName === "BODY" ) + setTimeout(function(){ _initLayoutElements(true); }, 50); + return false; + } + + // a center pane is required, so make sure it exists + if (!getPane("center").length) { + if (options.showErrorMessages) + _log( lang.errCenterPaneMissing, true ); + return false; + } + + // TEMP state so isInitialized returns true during init process + state.creatingLayout = true; + + // update Container dims + $.extend(sC, elDims( $N )); + + // initialize all layout elements + initPanes(); // size & position panes - calls initHandles() - which calls initResizable() + + if (o.scrollToBookmarkOnLoad) { + var l = self.location; + if (l.hash) l.replace( l.hash ); // scrollTo Bookmark + } + + // check to see if this layout 'nested' inside a pane + if (Instance.hasParentLayout) + o.resizeWithWindow = false; + // bind resizeAll() for 'this layout instance' to window.resize event + else if (o.resizeWithWindow) + $(window).bind("resize."+ sID, windowResize); + + delete state.creatingLayout; + state.initialized = true; + + // init plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onReady ); + + // now run the onload callback, if exists + _runCallbacks("onload_end"); + + return true; // elements initialized successfully + } + + /** + * Initialize nested layouts - called when _initLayoutElements completes + * + * NOT CURRENTLY USED + * + * @see _initLayoutElements + * @return An object pointer to the instance created + */ +, _initChildLayouts = function () { + $.each(_c.allPanes, function (idx, pane) { + if (options[pane].initChildLayout) + createChildLayout( pane ); + }); + } + + /** + * Initialize nested layouts for a specific pane - can optionally pass layout-options + * + * @see _initChildLayouts + * @param {string} pane The pane being opened, ie: north, south, east, or west + * @param {Object=} [opts] Layout-options - if passed, will OVERRRIDE options[pane].childOptions + * @return An object pointer to the layout instance created - or null + */ +, createChildLayout = function (evt_or_pane, opts) { + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , C = children + ; + if ($P) { + var $C = $Cs[pane] + , o = opts || options[pane].childOptions + , d = "layout" + // determine which element is supposed to be the 'child container' + // if pane has a 'containerSelector' OR a 'content-div', use those instead of the pane + , $Cont = o.containerSelector ? $P.find( o.containerSelector ) : ($C || $P) + , containerFound = $Cont.length + // see if a child-layout ALREADY exists on this element + , child = containerFound ? (C[pane] = $Cont.data(d) || null) : null + ; + // if no layout exists, but childOptions are set, try to create the layout now + if (!child && containerFound && o) + child = C[pane] = $Cont.eq(0).layout(o) || null; + if (child) + child.hasParentLayout = true; // set parent-flag in child + } + Instance[pane].child = C[pane]; // ALWAYS set pane-object pointer, even if null + } + +, windowResize = function () { + var delay = Number(options.resizeWithWindowDelay); + if (delay < 10) delay = 100; // MUST have a delay! + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + timer.clear("winResize"); // if already running + timer.set("winResize", function(){ + timer.clear("winResize"); + timer.clear("winResizeRepeater"); + var dims = elDims( $N ); + // only trigger resizeAll() if container has changed size + if (dims.innerWidth !== sC.innerWidth || dims.innerHeight !== sC.innerHeight) + resizeAll(); + }, delay); + // ALSO set fixed-delay timer, if not already running + if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); + } + +, setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + } + +, unload = function () { + var o = options; + + _runCallbacks("onunload_start"); + + // trigger plugin callabacks for this layout (eg: stateManagement) + runPluginCallbacks( Instance, $.layout.onUnload ); + + _runCallbacks("onunload_end"); + } + + /** + * Validate and initialize container CSS and events + * + * @see _create() + */ +, _initContainer = function () { + var + N = $N[0] + , tag = sC.tagName = N.tagName + , id = sC.id = N.id + , cls = sC.className = N.className + , o = options + , name = o.name + , fullPage= (tag === "BODY") + , props = "overflow,position,margin,padding,border" + , css = "layoutCSS" + , CSS = {} + , hid = "hidden" // used A LOT! + // see if this container is a 'pane' inside an outer-layout + , parent = $N.data("parentLayout") // parent-layout Instance + , pane = $N.data("layoutEdge") // pane-name in parent-layout + , isChild = parent && pane + ; + // sC -> state.container + sC.selector = $N.selector.split(".slice")[0]; + sC.ref = (o.name ? o.name +' layout / ' : '') + tag + (id ? "#"+id : cls ? '.['+cls+']' : ''); // used in messages + + $N .data({ + layout: Instance + , layoutContainer: sID // FLAG to indicate this is a layout-container - contains unique internal ID + }) + .addClass(o.containerClass) + ; + var layoutMethods = { + destroy: '' + , initPanes: '' + , resizeAll: 'resizeAll' + , resize: 'resizeAll' + } + , name; + // loop hash and bind all methods - include layoutID namespacing + for (name in layoutMethods) { + $N.bind("layout"+ name.toLowerCase() +"."+ sID, Instance[ layoutMethods[name] || name ]); + } + + // if this container is another layout's 'pane', then set child/parent pointers + if (isChild) { + // update parent flag + Instance.hasParentLayout = true; + // set pointers to THIS child-layout (Instance) in parent-layout + // NOTE: parent.PANE.child is an ALIAS to parent.children.PANE + parent[pane].child = parent.children[pane] = $N.data("layout"); + } + + // SAVE original container CSS for use in destroy() + if (!$N.data(css)) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (fullPage) { + CSS = $.extend( elCSS($N, props), { + height: $N.css("height") + , overflow: $N.css("overflow") + , overflowX: $N.css("overflowX") + , overflowY: $N.css("overflowY") + }); + // ALSO SAVE CSS + var $H = $("html"); + $H.data(css, { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + }); + } + else // handle props normally for non-body elements + CSS = elCSS($N, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY"); + + $N.data(css, CSS); + } + + try { // format html/body if this is a full page layout + if (fullPage) { + $("html").css({ + height: "100%" + , overflow: hid + , overflowX: hid + , overflowY: hid + }); + $("body").css({ + position: "relative" + , height: "100%" + , overflow: hid + , overflowX: hid + , overflowY: hid + , margin: 0 + , padding: 0 // TODO: test whether body-padding could be handled? + , border: "none" // a body-border creates problems because it cannot be measured! + }); + + // set current layout-container dimensions + $.extend(sC, elDims( $N )); + } + else { // set required CSS for overflow and position + // ENSURE container will not 'scroll' + CSS = { overflow: hid, overflowX: hid, overflowY: hid } + var + p = $N.css("position") + , h = $N.css("height") + ; + // if this is a NESTED layout, then container/outer-pane ALREADY has position and height + if (!isChild) { + if (!p || !p.match(/fixed|absolute|relative/)) + CSS.position = "relative"; // container MUST have a 'position' + /* + if (!h || h=="auto") + CSS.height = "100%"; // container MUST have a 'height' + */ + } + $N.css( CSS ); + + // set current layout-container dimensions + if ( $N.is(":visible") ) { + $.extend(sC, elDims( $N )); + if (o.showErrorMessages && sC.innerHeight < 1) + _log( lang.errContainerHeight.replace(/CONTAINER/, sC.ref), true ); + } + } + } catch (ex) {} + } + + /** + * Bind layout hotkeys - if options enabled + * + * @see _create() and addPane() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHotkeys = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(panes, function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + } + + /** + * Build final OPTIONS data + * + * @see _create() + */ +, initOptions = function () { + var data, d, pane, key, val, i, c, o; + + // reprocess user's layout-options to have correct options sub-key structure + opts = $.layout.transformData( opts ); // panes = default subkey + + // auto-rename old options for backward compatibility + opts = $.layout.backwardCompatibility.renameAllOptions( opts ); + + // if user-options has 'panes' key (pane-defaults), process it... + if (!$.isEmptyObject(opts.panes)) { + // REMOVE any pane-defaults that MUST be set per-pane + data = $.layout.optionsMap.noDefault; + for (i=0, c=data.length; i 0) { + z.pane_normal = zo; + z.content_mask = max(zo+1, z.content_mask); // MIN = +1 + z.resizer_normal = max(zo+2, z.resizer_normal); // MIN = +2 + } + + function createFxOptions ( pane ) { + var o = options[pane] + , d = options.panes; + // ensure fxSettings key to avoid errors + if (!o.fxSettings) o.fxSettings = {}; + if (!d.fxSettings) d.fxSettings = {}; + + $.each(["_open","_close","_size"], function (i,n) { + var + sName = "fxName"+ n + , sSpeed = "fxSpeed"+ n + , sSettings = "fxSettings"+ n + // recalculate fxName according to specificity rules + , fxName = o[sName] = + o[sName] // options.west.fxName_open + || d[sName] // options.panes.fxName_open + || o.fxName // options.west.fxName + || d.fxName // options.panes.fxName + || "none" // MEANS $.layout.defaults.panes.fxName == "" || false || null || 0 + ; + // validate fxName to ensure is valid effect - MUST have effect-config data in options.effects + if (fxName === "none" || !$.effects || !$.effects[fxName] || !options.effects[fxName]) + fxName = o[sName] = "none"; // effect not loaded OR unrecognized fxName + + // set vars for effects subkeys to simplify logic + var fx = options.effects[fxName] || {} // effects.slide + , fx_all = fx.all || null // effects.slide.all + , fx_pane = fx[pane] || null // effects.slide.west + ; + // create fxSpeed[_open|_close|_size] + o[sSpeed] = + o[sSpeed] // options.west.fxSpeed_open + || d[sSpeed] // options.west.fxSpeed_open + || o.fxSpeed // options.west.fxSpeed + || d.fxSpeed // options.panes.fxSpeed + || null // DEFAULT - let fxSetting.duration control speed + ; + // create fxSettings[_open|_close|_size] + o[sSettings] = $.extend( + {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , d.fxSettings // options.panes.fxSettings + , o.fxSettings // options.west.fxSettings + , d[sSettings] // options.panes.fxSettings_open + , o[sSettings] // options.west.fxSettings_open + ); + }); + + // DONE creating action-specific-settings for this pane, + // so DELETE generic options - are no longer meaningful + delete o.fxName; + delete o.fxSpeed; + delete o.fxSettings; + } + + // DELETE 'panes' key now that we are done - values were copied to EACH pane + delete options.panes; + } + + /** + * Initialize module objects, styling, size and position for all panes + * + * @see _initElements() + * @param {string} pane The pane to process + */ +, getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $N.find(sel).eq(0); + else { // class or other selector + var $P = $N.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $N.children("form:first").children(sel).eq(0); + } + } + +, initPanes = function () { + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes, function (idx, pane) { + addPane( pane, true ); + }); + + // init the pane-handles NOW in case we have to hide or close the pane below + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes, function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // Chrome/Webkit sometimes fires callbacks BEFORE it completes resizing! + // Before RC30.3, there was a 10ms delay here, but that caused layout + // to load asynchrously, which is BAD, so try skipping delay for now + + // process pane contents and callbacks, and init/resize child-layout if exists + $.each(_c.allPanes, function (i, pane) { + var o = options[pane]; + if ($Ps[pane]) { + if (state[pane].isVisible) { // pane is OPEN + sizeContent(pane); + // trigger pane.onResize if triggerEventsOnLoad = true + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildLayout(pane); + } + // init childLayout - even if pane is not visible + if (o.initChildLayout && o.childOptions) + createChildLayout(pane); + } + }); + } + + /** + * Add a pane to the layout - subroutine of initPanes() + * + * @see initPanes() + * @param {string} pane The pane to process + * @param {boolean=} [force=false] Size content after init + */ +, addPane = function (pane, force) { + if (!force && !isInitialized()) return; + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , fx = s.fx + , dir = c.dir + , spacing = o.spacing_open || 0 + , isCenter = (pane === "center") + , CSS = {} + , $P = $Ps[pane] + , size, minSize, maxSize + ; + // if pane-pointer already exists, remove the old one first + if ($P) + removePane( pane, false, true, false ); + else + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return; + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", elCSS($P, props)); + } + + // create alias for pane data in Instance - initHandles will add more + Instance[pane] = { name: pane, pane: $Ps[pane], content: $Cs[pane], options: options[pane], state: state[pane], child: children[pane] }; + + // add classes, attributes & events + $P .data({ + parentLayout: Instance // pointer to Layout Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "pane" + }) + .css(c.cssReq).css("zIndex", options.zIndexes.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + var paneMethods = { + hide: '' + , show: '' + , toggle: '' + , close: '' + , open: '' + , slideOpen: '' + , slideClose: '' + , slideToggle: '' + , size: 'manualSizePane' + , sizePane: 'manualSizePane' + , sizeContent: '' + , sizeHandles: '' + , enableClosable: '' + , disableClosable: '' + , enableSlideable: '' + , disableSlideable: '' + , enableResizable: '' + , disableResizable: '' + , swapPanes: 'swapPanes' + , swap: 'swapPanes' + , move: 'swapPanes' + , removePane: 'removePane' + , remove: 'removePane' + , createChildLayout: '' + , resizeChildLayout: '' + , resizeAll: 'resizeAll' + , resizeLayout: 'resizeAll' + } + , name; + // loop hash and bind all methods - include layoutID namespacing + for (name in paneMethods) { + $P.bind("layoutpane"+ name.toLowerCase() +"."+ sID, Instance[ paneMethods[name] || name ]); + } + + // see if this pane has a 'scrolling-content element' + initContent(pane, false); // false = do NOT sizeContent() - called later + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as its 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + + // state for border-panes + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + + // array for 'pin buttons' whose classNames are auto-updated on pane-open/-close + if (!s.pins) s.pins = []; + } + // states common to ALL panes + s.tagName = $P[0].tagName; + s.edge = pane; // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.insetTop; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "south": CSS.bottom = sC.insetBottom; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "west": CSS.left = sC.insetLeft; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.insetRight; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + + if (dir === "horz") // north or south pane + CSS.height = cssH($P, size); + else if (dir === "vert") // east or west pane + CSS.width = cssW($P, size); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable && !o.initHidden) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + else if (!s.noRoom) + // make the pane visible - in case was initially hidden + $P.css("display","block"); + // ELSE setAsOpen() - called later by initHandles() + + // RESET visibility now - pane will appear IF display:block + $P.css("visibility","visible"); + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + + // if manually adding a pane AFTER layout initialization, then... + if (state.initialized) { + initHandles( pane ); + initHotkeys( pane ); + resizeAll(); // will sizeContent if pane is visible + if (s.isVisible) { // pane is OPEN + if (o.triggerEventsOnLoad) + _runCallbacks("onresize_end", pane); + else // automatic if onresize called, otherwise call it specifically + // resize child - IF inner-layout already exists (created before this layout) + resizeChildLayout(pane); // a previously existing childLayout + } + if (o.initChildLayout && o.childOptions) + createChildLayout(pane); + } + } + + /** + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initHandles = function (panes) { + panes = panes ? panes.split(",") : _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes, function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , rClass = o.resizerClass + , tClass = o.togglerClass + , side = c.side.toLowerCase() + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + , I = Instance[pane] + // INIT RESIZER BAR + , $R = I.resizer = $Rs[pane] = $("
        ") + // INIT TOGGLER BUTTON + , $T = I.toggler = (o.closable ? $Ts[pane] = $("
        ") : false) + ; + + //if (s.isVisible && o.resizable) ... handled by initResizable + if (!s.isVisible && o.slidable) + $R.attr("title", o.sliderTip).css("cursor", o.sliderCursor); + + $R // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-resizer" : "")) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "resizer" + }) + .css(_c.resizers.cssReq).css("zIndex", options.zIndexes.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if resizing is not enabled - handle with CSS instead + .hover(onResizerEnter, onResizerLeave) // ALWAYS NEED resizer.mouseleave to balance toggler.mouseenter + .appendTo($N) // append DIV to container + ; + + if ($T) { + $T // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-toggler" : "")) + .data({ + parentLayout: Instance + , layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + , layoutRole: "toggler" + }) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .hover(addHover, removeHover) // ALWAYS add hover-classes, even if toggling is not enabled - handle with CSS instead + .bind("mouseenter", onResizerEnter) // NEED toggler.mouseenter because mouseenter MAY NOT fire on resizer + .appendTo($R) // append SPAN to resizer DIV + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $(""+ o.togglerContent_open +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-open instead! + ; + if (o.togglerContent_closed) // ui-layout-closed + $(""+ o.togglerContent_closed +"") + .data({ + layoutEdge: pane + , layoutRole: "togglerContent" + }) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + //.hover( addHover, removeHover ) // use ui-layout-toggler-west-hover .content-closed instead! + ; + // ADD TOGGLER.click/.hover + enableClosable(pane); + } + + // add Draggable events + initResizable(pane); + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles(); + } + + + /** + * Initialize scrolling ui-layout-content div - if exists + * + * @see initPane() - or externally after an Ajax injection + * @param {string} [pane] The pane to process + * @param {boolean=} [resize=true] Size content after init + */ +, initContent = function (pane, resize) { + if (!isInitialized()) return; + var + o = options[pane] + , sel = o.contentSelector + , I = Instance[pane] + , $P = $Ps[pane] + , $C + ; + if (sel) $C = I.content = $Cs[pane] = (o.findNestedContent) + ? $P.find(sel).eq(0) // match 1-element only + : $P.children(sel).eq(0) + ; + if ($C && $C.length) { + $C.data("layoutRole", "content"); + // SAVE original Pane CSS + if (!$C.data("layoutCSS")) + $C.data("layoutCSS", elCSS($C, "height")); + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + state[pane].content = {}; // init content state + if (resize !== false) sizeContent(pane); + // sizeContent() is called AFTER init of all elements + } + else + I.content = $Cs[pane] = false; + } + + + /** + * Add resize-bars to all panes that specify it in options + * -dependancy: $.fn.resizable - will skip if not found + * + * @see _create() + * @param {string=} [panes=""] The edge(s) to process + */ +, initResizable = function (panes) { + var draggingAvailable = $.layout.plugins.draggable + , side // set in start() + ; + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (idx, pane) { + var o = options[pane]; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var s = state[pane] + , z = options.zIndexes + , c = _c[pane] + , side = c.dir=="horz" ? "top" : "left" + , opEdge = _c.oppositeEdge[pane] + , masks = pane +",center,"+ opEdge + (c.dir=="horz" ? ",west,east" : "") + , $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + , lastPos = 0 // used when live-resizing + , r, live // set in start because may change + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperPaneLimitClass = base+"-"+pane+"-dragging-limit" // resizer-north-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R.attr("title", o.resizerTip) + .css("cursor", o.resizerCursor); // n-resize, s-resize, etc + + $R.draggable({ + containment: $N[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 0 + , distance: 1 + , grid: o.resizingGrid + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: z.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.livePaneResizing; + + // ondrag_start callback - will CANCEL hide if returns false + // TODO: dragging CANNOT be cancelled like this, so see if there is a way? + if (false === _runCallbacks("ondrag_start", pane)) return false; + + s.isResizing = true; // prevent pane from closing while resizing + timer.clear(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + lastPos = ui.position[ side ] + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // DISABLE TEXT SELECTION (probably already done by resizer.mouseOver) + $('body').disableSelection(); + + // MASK PANES CONTAINING IFRAMES, APPLETS OR OTHER TROUBLESOME ELEMENTS + showMasks( masks ); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .css({ right: "auto", bottom: "auto" }) // fix dir="rtl" issue + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", z.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass +" "+ helperPaneLimitClass ); // at dragging-limit + window.defaultStatus = (limit>0 && pane.match(/north|west/)) || (limit<0 && pane.match(/south|east/)) ? lang.maxSizeWarning : lang.minSizeWarning; + } + else { + ui.helper.removeClass( helperLimitClass +" "+ helperPaneLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + // won't trigger unless resizer has actually moved! + if (live && Math.abs(ui.position[side] - lastPos) >= o.liveResizingTolerance) { + lastPos = ui.position[side]; + resizePanes(e, ui, pane) + } + } + + , stop: function (e, ui) { + $('body').enableSelection(); // RE-ENABLE TEXT SELECTION + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass ); // remove drag classes from Resizer + s.isResizing = false; + resizePanes(e, ui, pane, true, masks); // true = resizingDone + } + + }); + }); + + /** + * resizePanes + * + * Sub-routine called from stop() - and drag() if livePaneResizing + * + * @param {!Object} evt + * @param {!Object} ui + * @param {string} pane + * @param {boolean=} [resizingDone=false] + */ + var resizePanes = function (evt, ui, pane, resizingDone, masks) { + var dragPos = ui.position + , c = _c[pane] + , o = options[pane] + , s = state[pane] + , resizerPos + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.offsetHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.offsetWidth - dragPos.left - o.spacing_open; break; + }; + // remove container margin from resizer position to get the pane size + var newSize = resizerPos - sC["inset"+ c.side]; + + // Disable OR Resize Mask(s) created in drag.start + if (!resizingDone) { + // ensure we meet liveResizingTolerance criteria + if (Math.abs(newSize - s.size) < o.liveResizingTolerance) + return; // SKIP resize this time + // resize the pane + manualSizePane(pane, newSize, false, true); // true = noAnimation + sizeMasks(); // resize all visible masks + } + else { // resizingDone + // ondrag_end callback + if (false !== _runCallbacks("ondrag_end", pane)) + manualSizePane(pane, newSize, false, true); // true = noAnimation + hideMasks(); // hide all masks, which include panes with 'content/iframe-masks' + if (s.isSliding && masks) // RE-SHOW only 'object-masks' so objects won't show through sliding pane + showMasks( masks, true ); // true = onlyForObjects + } + }; + } + + /** + * sizeMask + * + * Needed to overlay a DIV over an IFRAME-pane because mask CANNOT be *inside* the pane + * Called when mask created, and during livePaneResizing + */ +, sizeMask = function () { + var $M = $(this) + , pane = $M.data("layoutMask") // eg: "west" + , s = state[pane] + ; + // only masks over an IFRAME-pane need manual resizing + if (s.tagName == "IFRAME" && s.isVisible) // no need to mask closed/hidden panes + $M.css({ + top: s.offsetTop + , left: s.offsetLeft + , width: s.outerWidth + , height: s.outerHeight + }); + /* ALT Method... + var $P = $Ps[pane]; + $M.css( $P.position() ).css({ width: $P[0].offsetWidth, height: $P[0].offsetHeight }); + */ + } +, sizeMasks = function () { + $Ms.each( sizeMask ); // resize all 'visible' masks + } + +, showMasks = function (panes, onlyForObjects) { + var a = panes ? panes.split(",") : $.layout.config.allPanes + , z = options.zIndexes + , o, s; + $.each(a, function(i,p){ + s = state[p]; + o = options[p]; + if (s.isVisible && ( (!onlyForObjects && o.maskContents) || o.maskObjects )) { + getMasks(p).each(function(){ + sizeMask.call(this); + this.style.zIndex = s.isSliding ? z.pane_sliding+1 : z.pane_normal+1 + this.style.display = "block"; + }); + } + }); + } + +, hideMasks = function () { + // ensure no pane is resizing - could be a timing issue + var skip; + $.each( $.layout.config.borderPanes, function(i,p){ + if (state[p].isResizing) { + skip = true; + return false; // BREAK + } + }); + if (!skip) + $Ms.hide(); // hide ALL masks + } + +, getMasks = function (pane) { + var $Masks = $([]) + , $M, i = 0, c = $Ms.length + ; + for (; i CSS + if (sC.tagName === "BODY" && ($N = $("html")).data(css)) // RESET CSS + $N.css( $N.data(css) ).removeData(css); + + // trigger plugins for this layout, if there are any + runPluginCallbacks( Instance, $.layout.onDestroy ); + + // trigger state-management and onunload callback + unload(); + + // clear the Instance of everything except for container & options (so could recreate) + // RE-CREATE: myLayout = myLayout.container.layout( myLayout.options ); + for (n in Instance) + if (!n.match(/^(container|options)$/)) delete Instance[ n ]; + // add a 'destroyed' flag to make it easy to check + Instance.destroyed = true; + + // if this is a child layout, CLEAR the child-pointer in the parent + /* for now the pointer REMAINS, but with only container, options and destroyed keys + if (parentPane) { + var layout = parentPane.pane.data("parentLayout"); + parentPane.child = layout.children[ parentPane.name ] = null; + } + */ + + return Instance; // for coding convenience + } + + /** + * Remove a pane from the layout - subroutine of destroy() + * + * @see destroy() + * @param {string} pane The pane to process + * @param {boolean=} [remove=false] Remove the DOM element? + * @param {boolean=} [skipResize=false] Skip calling resizeAll()? + */ +, removePane = function (evt_or_pane, remove, skipResize, destroyChild) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $C = $Cs[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + ; + //alert( '$P.length = '+ $P.length ); + // NOTE: elements can still exist even after remove() + // so check for missing data(), which is cleared by removed() + if ($P && $.isEmptyObject( $P.data() )) $P = false; + if ($C && $.isEmptyObject( $C.data() )) $C = false; + if ($R && $.isEmptyObject( $R.data() )) $R = false; + if ($T && $.isEmptyObject( $T.data() )) $T = false; + + if ($P) $P.stop(true, true); + + // check for a child layout + var o = options[pane] + , s = state[pane] + , d = "layout" + , css = "layoutCSS" + , child = children[pane] || ($P ? $P.data(d) : 0) || ($C ? $C.data(d) : 0) || null + , destroy = destroyChild !== undefined ? destroyChild : o.destroyChildLayout + ; + + // FIRST destroy the child-layout(s) + if (destroy && child && !child.destroyed) { + child.destroy(true); // tell child-layout to destroy ALL its child-layouts too + if (child.destroyed) // destroy was successful + child = null; // clear pointer for logic below + } + + if ($P && remove && !child) + $P.remove(); + else if ($P && $P[0]) { + // create list of ALL pane-classes that need to be removed + var root = o.paneClass // default="ui-layout-pane" + , pRoot = root +"-"+ pane // eg: "ui-layout-pane-west" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , classes = [ root, root+_open, root+_closed, root+_sliding, // generic classes + pRoot, pRoot+_open, pRoot+_closed, pRoot+_sliding ] // pane-specific classes + ; + $.merge(classes, getHoverClasses($P, true)); // ADD hover-classes + // remove all Layout classes from pane-element + $P .removeClass( classes.join(" ") ) // remove ALL pane-classes + .removeData("parentLayout") + .removeData("layoutPane") + .removeData("layoutRole") + .removeData("layoutEdge") + .removeData("autoHidden") // in case set + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + //.unbind("mouseenter"+ sID) + //.unbind("mouseleave"+ sID) + ; + // do NOT reset CSS if this pane/content is STILL the container of a nested layout! + // the nested layout will reset its 'container' CSS when/if it is destroyed + if ($C && $C.data(d)) { + // a content-div may not have a specific width, so give it one to contain the Layout + $C.width( $C.width() ); + child.resizeAll(); // now resize the Layout + } + else if ($C) + $C.css( $C.data(css) ).removeData(css).removeData("layoutRole"); + // remove pane AFTER content in case there was a nested layout + if (!$P.data(d)) + $P.css( $P.data(css) ).removeData(css); + } + + // REMOVE pane resizer and toggler elements + if ($T) $T.remove(); + if ($R) $R.remove(); + + // CLEAR all pointers and state data + Instance[pane] = $Ps[pane] = $Cs[pane] = $Rs[pane] = $Ts[pane] = children[pane] = false; + s = { removed: true }; + + if (!skipResize) + resizeAll(); + } + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + +, _hidePane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , s = $P[0].style + ; + if (o.useOffscreenClose) { + if (!$P.data(_c.offscreenReset)) + $P.data(_c.offscreenReset, { left: s.left, right: s.right }); + $P.css( _c.offscreenCSS ); + } + else + $P.hide().removeData(_c.offscreenReset); + } + +, _showPane = function (pane) { + var $P = $Ps[pane] + , o = options[pane] + , off = _c.offscreenCSS + , old = $P.data(_c.offscreenReset) + , s = $P[0].style + ; + $P .show() // ALWAYS show, just in case + .removeData(_c.offscreenReset); + if (o.useOffscreenClose && old) { + if (s.left == off.left) + s.left = old.left; + if (s.right == off.right) + s.right = old.right; + } + } + + + /** + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param {string} pane The pane being hidden, ie: north, south, east, or west + * @param {boolean=} [noAnimation=false] + */ +, hide = function (evt_or_pane, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _runCallbacks("onhide_start", pane)) return; + + s.isSliding = false; // just in case + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + if (!state.initialized) + _hidePane(pane); // no animation when loading page + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _runCallbacks("onhide_end", pane); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + } + + /** + * Show a hidden pane - show as 'closed' by default unless openPane = true + * + * @param {string} pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [openPane=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, show = function (evt_or_pane, openPane, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _runCallbacks("onshow_start", pane)) return; + + s.isSliding = false; // just in case + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + } + + + /** + * Toggles a pane open/closed by calling either open or close + * + * @param {string} pane The pane being toggled, ie: north, south, east, or west + * @param {boolean=} [slide=false] + */ +, toggle = function (evt_or_pane, slide) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + ; + if (evt) // called from to $R.dblclick OR triggerPaneEvent + evt.stopImmediatePropagation(); + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + } + + + /** + * Utility method used during init or other auto-processes + * + * @param {string} pane The pane being closed + * @param {boolean=} [setHandles=false] + */ +, _closePane = function (pane, setHandles) { + var + $P = $Ps[pane] + , s = state[pane] + ; + _hidePane(pane); + s.isClosed = true; + s.isVisible = false; + // UNUSED: if (setHandles) setAsClosed(pane, true); // true = force + } + + /** + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param {string} pane The pane being closed, ie: north, south, east, or west + * @param {boolean=} [force=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [skipCallback=false] + */ +, close = function (evt_or_pane, force, noAnimation, skipCallback) { + var pane = evtPane.call(this, evt_or_pane); + // if pane has been initialized, but NOT the complete layout, close pane instantly + if (!state.initialized && $Ps[pane]) { + _closePane(pane); // INIT pane as closed + return; + } + if (!isInitialized()) return; + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing, isHiding, wasSliding; + + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.closable && !s.isShowing && !s.isHiding) // invalid request // (!o.resizable && !o.closable) ??? + || (!force && s.isClosed && !s.isShowing) // already closed + ) return queueNext(); + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + var abort = !s.isShowing && false === _runCallbacks("onclose_start", pane); + + // transfer logic vars to temp vars + isShowing = s.isShowing; + isHiding = s.isHiding; + wasSliding = s.isSliding; + // now clear the logic vars (REQUIRED before aborting) + delete s.isShowing; + delete s.isHiding; + + if (abort) return queueNext(); + + doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none"); + s.isMoving = true; + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir === "horz" ? "" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + setAsClosed(pane); + + // CLOSE THE PANE + if (doFX) { // animate the close + // mask panes with objects + var masks = "center"+ (c.dir=="horz" ? ",west,east" : ""); + showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + if (s.isClosed) close_2(); + queueNext(); + }); + } + else { // hide the pane without animation + _hidePane(pane); + close_2(); + queueNext(); + }; + }); + + // SUBROUTINE + function close_2 () { + s.isMoving = false; + bindStartSlidingEvent(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + // hide any masks shown while closing + hideMasks(); + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing) _runCallbacks("onclose_end", pane); + // onhide OR onshow callback + if (isShowing) _runCallbacks("onshow_end", pane); + if (isHiding) _runCallbacks("onhide_end", pane); + } + } + } + + /** + * @param {string} pane The pane just closed, ie: north, south, east, or west + */ +, setAsClosed = function (pane) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC[inset]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .unbind("dblclick."+ sID) + ; + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent? + if (o.resizable && $.layout.plugins.draggable) + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.togglerTip_closed) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles(); + } + } + + /** + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param {string} pane The pane being opened, ie: north, south, east, or west + * @param {boolean=} [slide=false] + * @param {boolean=} [noAnimation=false] + * @param {boolean=} [noAlert=false] + */ +, open = function (evt_or_pane, slide, noAnimation, noAlert) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , c = _c[pane] + , doFX, isShowing + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + + if ( !$P + || (!o.resizable && !o.closable && !s.isShowing) // invalid request + || (s.isVisible && !s.isSliding) // already open + ) return queueNext(); + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !s.isShowing) { + queueNext(); // call before show() because it needs the queue free + show(pane, true); + return; + } + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation + else + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); + + // onopen_start callback - will CANCEL open if returns false + var cbReturn = _runCallbacks("onopen_start", pane); + + if (cbReturn === "abort") + return queueNext(); + + // update pane-state again in case options were changed in onopen_start + if (cbReturn !== "NC") // NC = "No Callback" + setSizeLimits(pane, slide); + + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.noRoomToOpenTip) + alert(o.noRoomToOpenTip); + return queueNext(); // ABORT + } + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvent(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + // transfer logic var to temp var + isShowing = s.isShowing; + // now clear the logic var + delete s.isShowing; + + doFX = !noAnimation && s.isClosed && (o.fxName_open != "none"); + s.isMoving = true; + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + // mask panes with objects + var masks = "center"+ (c.dir=="horz" ? ",west,east" : ""); + if (s.isSliding) masks += ","+ _c.oppositeEdge[pane]; + showMasks( masks, true ); // true = ONLY mask panes with maskObjects=true + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + if (s.isVisible) open_2(); // continue + queueNext(); + }); + } + else { // no animation + _showPane(pane);// just show pane and... + open_2(); // continue + queueNext(); + }; + }); + + // SUBROUTINE + function open_2 () { + s.isMoving = false; + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) { // resize all panes adjacent to this one + hideMasks(); // remove any masks shown while opening + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "", false); // false = NOT skipCallback + } + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + }; + + } + + /** + * @param {string} pane The pane just opened, ie: north, south, east, or west + * @param {boolean=} [skipCallback=false] + */ +, setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC[inset] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + if (o.resizerDblClickToggle) + $R.bind("dblclick", toggle ); + removeHover( 0, $R ); // remove hover classes + if (o.resizable && $.layout.plugins.draggable) + $R .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.resizerTip); + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.togglerTip_open); // may be blank + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + // update pane-state dimensions - BEFORE resizing content + $.extend(s, elDims($P)); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles(); + // resize content every time pane opens - to be sure + sizeContent(pane, true); // true = remeasure headers/footers, even if 'pane.isMoving' + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _runCallbacks("onopen_end", pane); + // onshow callback - TODO: should this be here? + if (s.isShowing) _runCallbacks("onshow_end", pane); + + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) + _runCallbacks("onresize_end", pane); + } + + // TODO: Somehow sizePane("north") is being called after this point??? + } + + + /** + * slideOpen / slideClose / slideToggle + * + * Pass-though methods for sliding + */ +, slideOpen = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , s = state[pane] + , delay = options[pane].slideDelay_open + ; + // prevent event from triggering on NEW resizer binding created below + if (evt) evt.stopImmediatePropagation(); + + if (s.isClosed && evt && evt.type === "mouseenter" && delay > 0) + // trigger = mouseenter - use a delay + timer.set(pane+"_openSlider", open_NOW, delay); + else + open_NOW(); // will unbind events if is already open + + /** + * SUBROUTINE for timed open + */ + function open_NOW () { + if (!s.isClosed) // skip if no longer closed! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (!s.isMoving) + open(pane, true); // true = slide - open() will handle binding + }; + } + +, slideClose = function (evt_or_pane) { + if (!isInitialized()) return; + var evt = evtObj(evt_or_pane) + , pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + , delay = s.isMoving ? 1000 : 300 // MINIMUM delay - option may override + ; + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close === "click") + close_NOW(); // close immediately onClick + else if (o.preventQuickSlideClose && s.isMoving) + return; // handle Chrome quick-close on slide-open + else if (o.preventPrematureSlideClose && evt && $.layout.isMouseOverElem(evt, $Ps[pane])) + return; // handle incorrect mouseleave trigger, like when over a SELECT-list in IE + else if (evt) // trigger = mouseleave - use a delay + // 1 sec delay if 'opening', else .3 sec + timer.set(pane+"_closeSlider", close_NOW, max(o.slideDelay_close, delay)); + else // called programically + close_NOW(); + + /** + * SUBROUTINE for timed close + */ + function close_NOW () { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events - TODO: is this needed here? + else if (!s.isMoving) + close(pane); // close will handle unbinding + }; + } + + /** + * @param {string} pane The pane being opened, ie: north, south, east, or west + */ +, slideToggle = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + toggle(pane, true); + } + + + /** + * Must set left/top on East/South panes so animation will work properly + * + * @param {string} pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param {boolean} doLock true = set left/top, false = remove + */ +, lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane] + , s = state[pane] + , o = options[pane] + , z = options.zIndexes + ; + if (doLock) { + $P.css({ zIndex: z.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + // TODO: see if this can be deleted. It causes a quick-close when sliding in Chrome + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + // if pane is positioned 'off-screen', then DO NOT screw with it! + else if (pane=="east" && !$P.css("left").match(/\-99999/)) + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + if (browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + } + + + /** + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @see open(), close() + * @param {string} pane The pane to enable/disable, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable sliding? + */ +, bindStartSlidingEvent = function (pane, enable) { + var o = options[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , evtName = o.slideTrigger_open.toLowerCase() + ; + if (!$R || (enable && !o.slidable)) return; + + // make sure we have a valid event + if (evtName.match(/mouseover/)) + evtName = o.slideTrigger_open = "mouseenter"; + else if (!evtName.match(/click|dblclick|mouseenter/)) + evtName = o.slideTrigger_open = "click"; + + $R + // add or remove event + [enable ? "bind" : "unbind"](evtName +'.'+ sID, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", enable ? o.sliderCursor : "default") + .attr("title", enable ? o.sliderTip : "") + ; + } + + /** + * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvent for code to control 'slide open' + * + * @see slideOpen(), slideClose() + * @param {string} pane The pane to process, 'north', 'south', etc. + * @param {boolean} enable Enable or Disable events? + */ +, bindStopSlidingEvents = function (pane, enable) { + var o = options[pane] + , s = state[pane] + , c = _c[pane] + , z = options.zIndexes + , evtName = o.slideTrigger_close.toLowerCase() + , action = (enable ? "bind" : "unbind") + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + s.isSliding = enable; // logic + timer.clear(pane+"_closeSlider"); // just in case + + // remove 'slideOpen' event from resizer + // ALSO will raise the zIndex of the pane & resizer + if (enable) bindStartSlidingEvent(pane, false); + + // RE/SET zIndex - increases when pane is sliding-open, resets to normal when not + $P.css("zIndex", enable ? z.pane_sliding : z.pane_normal); + $R.css("zIndex", enable ? z.pane_sliding+2 : z.resizer_normal); // NOTE: mask = pane_sliding+1 + + // make sure we have a valid event + if (!evtName.match(/click|mouseleave/)) + evtName = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' + + // add/remove slide triggers + $R[action](evtName, slideClose); // base event on resize + // need extra events for mouseleave + if (evtName === "mouseleave") { + // also close on pane.mouseleave + $P[action]("mouseleave."+ sID, slideClose); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseenter."+ sID, cancelMouseOut); + $P[action]("mouseenter."+ sID, cancelMouseOut); + } + + if (!enable) + timer.clear(pane+"_closeSlider"); + else if (evtName === "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", enable ? o.sliderCursor : "default"); + $R.attr("title", enable ? o.togglerTip_open : ""); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseleave timer clearing + function cancelMouseOut (evt) { + timer.clear(pane+"_closeSlider"); + evt.stopPropagation(); + } + } + + + /** + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + * + * @param {string} pane The pane being resized + * @param {boolean=} [isOpening=false] Called from onOpen? + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, makePaneFit = function (pane, isOpening, skipCallback, force) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir==="vert" + , hasRoom = false + ; + // special handling for center & east/west panes + if (pane === "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the pane + // ERROR: hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + hasRoom = (s.maxHeight >= 0); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + _showPane(pane); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + _hidePane(pane); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane === "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback, force, true); // true = noAnimation + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback, force, true); + // need s.isVisible because new pseudoClose method keeps pane visible, but off-screen + else if ($R && s.isVisible && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var side = c.side.toLowerCase() + , pos = s.size + sC["inset"+ c.side] + ; + if ($.layout.cssNum($R, side) != pos) $R.css( side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (s.isClosed){} // SKIP + else if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + } + + + /** + * sizePane / manualSizePane + * sizePane is called only by internal methods whenever a pane needs to be resized + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param {string} pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [noAnimation=false] + */ +, manualSizePane = function (evt_or_pane, size, skipCallback, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , o = options[pane] + , s = state[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = o.livePaneResizing && !s.isResizing + ; + // ANY call to manualSizePane disables autoResize - ie, percentage sizing + o.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, forceResize, noAnimation); // will animate resize if option enabled + } + + /** + * @param {string} pane The pane being resized + * @param {number} size The *desired* new size for this pane - will be validated + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] Force resizing even if does not seem necessary + * @param {boolean=} [noAnimation=false] + */ +, sizePane = function (evt_or_pane, size, skipCallback, force, noAnimation) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) // probably NEVER called from event? + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side.toLowerCase() + , dimName = _c[pane].sizeType.toLowerCase() + , inset = "inset"+ _c[pane].side + , skipResizeWhileDragging = s.isResizing && !o.triggerEventsDuringLiveResize + , doFX = noAnimation !== true && o.animatePaneSizing + , oldSize, newSize + ; + // QUEUE in case another action/animation is in progress + $N.queue(function( queueNext ){ + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + queueNext(); // call before makePaneFit() because it needs the queue free + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size === oldSize) + return queueNext(); + + // onresize_start callback CANNOT cancel resizing because this would break the layout! + if (!skipCallback && state.initialized && s.isVisible) + _runCallbacks("onresize_start", pane); + + // resize the pane, and make sure its visible + newSize = cssSize(pane, size); + + if (doFX && $P.is(":visible")) { // ANIMATE + var fx = $.layout.effects.size[pane] || $.layout.effects.size.all + , easing = o.fxSettings_size.easing || fx.easing + , z = options.zIndexes + , props = {}; + props[ dimName ] = newSize +'px'; + s.isMoving = true; + // overlay all elements during animation + $P.css({ zIndex: z.pane_animate }) + .show().animate( props, o.fxSpeed_size, easing, function(){ + // reset zIndex after animation + $P.css({ zIndex: (s.isSliding ? z.pane_sliding : z.pane_normal) }); + s.isMoving = false; + sizePane_2(); // continue + queueNext(); + }); + } + else { // no animation + $P.css( dimName, newSize ); // resize pane + // if pane is visible, then + if ($P.is(":visible")) + sizePane_2(); // continue + else { + // pane is NOT VISIBLE, so just update state data... + // when pane is *next opened*, it will have the new size + s.size = size; // update state.size + $.extend(s, elDims($P)); // update state dimensions + } + queueNext(); + }; + + }); + + // SUBROUTINE + function sizePane_2 () { + /* Panes are sometimes not sized precisely in some browsers!? + * This code will resize the pane up to 3 times to nudge the pane to the correct size + */ + var actual = dimName==='width' ? $P.outerWidth() : $P.outerHeight() + , tries = [{ + pane: pane + , count: 1 + , target: size + , actual: actual + , correct: (size === actual) + , attempt: size + , cssSize: newSize + }] + , lastTry = tries[0] + , msg = 'Inaccurate size after resizing the '+ pane +'-pane.' + ; + while ( !lastTry.correct ) { + thisTry = { pane: pane, count: lastTry.count+1, target: size }; + + if (lastTry.actual > size) + thisTry.attempt = max(0, lastTry.attempt - (lastTry.actual - size)); + else // lastTry.actual < size + thisTry.attempt = max(0, lastTry.attempt + (size - lastTry.actual)); + + thisTry.cssSize = cssSize(pane, thisTry.attempt); + $P.css( dimName, thisTry.cssSize ); + + thisTry.actual = dimName=='width' ? $P.outerWidth() : $P.outerHeight(); + thisTry.correct = (size === thisTry.actual); + + // if showDebugMessages, log attempts and alert the user of this *non-fatal error* + if (options.showDebugMessages) { + if ( tries.length === 1) { + _log(msg, false); + _log(lastTry, false); + } + _log(thisTry, false); + } + + // after 4 tries, is as close as its gonna get! + if (tries.length > 3) break; + + tries.push( thisTry ); + lastTry = tries[ tries.length - 1 ]; + } + // END TESTING CODE + + // update pane-state dimensions + s.size = size; + $.extend(s, elDims($P)); + + if (s.isVisible && $P.is(":visible")) { + // reposition the resizer-bar + if ($R) $R.css( side, size + sC[inset] ); + // resize the content-div + sizeContent(pane); + } + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) + _runCallbacks("onresize_end", pane); + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsDuringLiveResize + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "" : "center", skipResizeWhileDragging, force); + sizeHandles(); + } + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.oppositeEdge[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + + // DEBUG - ALERT user/developer so they know there was a sizing problem + if (options.showDebugMessages && tries.length > 1) + _log(msg +'\nSee the Error Console for details.', true); + } + } + + /** + * @see initPanes(), sizePane(), resizeAll(), open(), close(), hide() + * @param {string} panes The pane(s) being resized, comma-delmited string + * @param {boolean=} [skipCallback=false] Should the onresize callback be run? + * @param {boolean=} [force=false] + */ +, sizeMidPanes = function (panes, skipCallback, force) { + panes = (panes ? panes : "east,west,center").split(","); + + $.each(panes, function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + , newCenter = calcNewCenterPaneDims() + ; + // update pane-state dimensions + $.extend(s, elDims($P)); + + if (pane === "center") { + if (!force && s.isVisible && newCenter.width === s.outerWidth && newCenter.height === s.outerHeight) + return true; // SKIP - pane already the correct size + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: newCenter.width + , maxHeight: newCenter.height + }); + CSS = newCenter; + // convert OUTER width/height to CSS width/height + CSS.width = cssW($P, CSS.width); + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, CSS.height); + hasRoom = CSS.width >= 0 && CSS.height >= 0; // height >= 0 = ALWAYS TRUE NOW + // during layout init, try to shrink east/west panes to make room for center + if (!state.initialized && o.minWidth > s.outerWidth) { + var + reqPx = o.minWidth - s.outerWidth + , minE = options.east.minSize || 0 + , minW = options.west.minSize || 0 + , sizeE = state.east.size + , sizeW = state.west.size + , newE = sizeE + , newW = sizeW + ; + if (reqPx > 0 && state.east.isVisible && sizeE > minE) { + newE = max( sizeE-minE, sizeE-reqPx ); + reqPx -= sizeE-newE; + } + if (reqPx > 0 && state.west.isVisible && sizeW > minW) { + newW = max( sizeW-minW, sizeW-reqPx ); + reqPx -= sizeW-newW; + } + // IF we found enough extra space, then resize the border panes as calculated + if (reqPx === 0) { + if (sizeE != minE) + sizePane('east', newE, true, force, true); // true = skipCallback/noAnimation - initPanes will handle when done + if (sizeW != minW) + sizePane('west', newW, true, force, true); + // now start over! + sizeMidPanes('center', skipCallback, force); + return; // abort this loop + } + } + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + if (s.isVisible && !s.noVerticalRoom) + $.extend(s, elDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && newCenter.height === s.outerHeight) + return true; // SKIP - pane already the correct size + // east/west have same top, bottom & height as center + CSS.top = newCenter.top; + CSS.bottom = newCenter.bottom; + // NEW - allow pane to extend 'below' visible area rather than hide it + CSS.height = cssH($P, newCenter.height); + s.maxHeight = CSS.height; + hasRoom = (s.maxHeight >= 0); // ALWAYS TRUE NOW + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_start", pane); + + $P.css(CSS); // apply the CSS to pane + sizeHandles(pane); // also update resizer length + if (s.noRoom && !s.isClosed && !s.isHidden) + makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (s.isVisible) { + $.extend(s, elDims($P)); // update pane dimensions + if (state.initialized) sizeContent(pane); // also resize the contents, if exists + } + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + if (!s.isVisible) + return true; // DONE - next pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + */ + if (pane === "center") { // finished processing midPanes + var b = $.layout.browser; + var fix = b.isIE6 || (b.msie && !$.support.boxModel); + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _runCallbacks("onresize_end", pane); + }); + } + + + /** + * @see window.onresize(), callbacks or custom code + */ +, resizeAll = function () { + if (!state.initialized) { + _initLayoutElements(); + return; // no need to resize since we just initialized! + } + var oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + // cannot size layout when 'container' is hidden or collapsed + if (!$N.is(":visible:") ) return; + $.extend( state.container, elDims( $N ) ); // UPDATE container dimensions + if (!sC.outerHeight) return; + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _runCallbacks("onresizeall_start")) return false; + + var // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , $P, o, s, dir + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + s = state[pane]; + o = options[pane]; + dir = _c[pane].dir; + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true, true); // true=skipCallback/forceResize/noAnimation + else { + setSizeLimits(pane); + makePaneFit(pane, false, true, true); // true=skipCallback/forceResize + } + }); + + sizeMidPanes("", true, true); // true=skipCallback, true=forceResize + sizeHandles(); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + o = options; // reuse alias + $.each(_c.allPanes, function (i, pane) { + $P = $Ps[pane]; + if (!$P) return; // SKIP + if (state[pane].isVisible) // undefined for non-existent panes + _runCallbacks("onresize_end", pane); // callback - if exists + }); + + _runCallbacks("onresizeall_end"); + //_triggerLayoutEvent(pane, 'resizeall'); + } + + /** + * Whenever a pane resizes or opens that has a nested layout, trigger resizeAll + * + * @param {string} pane The pane just resized or opened + */ +, resizeChildLayout = function (evt_or_pane) { + var pane = evtPane.call(this, evt_or_pane); + if (!options[pane].resizeChildLayout) return; + var $P = $Ps[pane] + , $C = $Cs[pane] + , d = "layout" + , P = Instance[pane] + , L = children[pane] + ; + // user may have manually set EITHER instance pointer, so handle that + if (P.child && !L) { + // have to reverse the pointers! + var el = P.child.container; + L = children[pane] = (el ? el.data(d) : 0) || null; // set pointer _directly_ to layout instance + } + + // if a layout-pointer exists, see if child has been destroyed + if (L && L.destroyed) + L = children[pane] = null; // clear child pointers + // no child layout pointer is set - see if there is a child layout NOW + if (!L) L = children[pane] = $P.data(d) || ($C ? $C.data(d) : 0) || null; // set/update child pointers + + // ALWAYS refresh the pane.child alias + P.child = children[pane]; + + if (L) L.resizeAll(); + } + + + /** + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + * + * @param {string=} [panes=""] The pane(s) being resized + * @param {boolean=} [remeasure=false] Should the content (header/footer) be remeasured? + */ +, sizeContent = function (evt_or_panes, remeasure) { + if (!isInitialized()) return; + + var panes = evtPane.call(this, evt_or_panes); + panes = panes ? panes.split(",") : _c.allPanes; + + $.each(panes, function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content // m = measurements + ; + if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip + + // if content-element was REMOVED, update OR remove the pointer + if (!$C.length) { + initContent(pane, false); // false = do NOT sizeContent() - already there! + if (!$C) return; // no replacement element found - pointer have been removed + } + + // onsizecontent_start will CANCEL resizing if returns false + if (false === _runCallbacks("onsizecontent_start", pane)) return; + + // skip re-measuring offsets if live-resizing + if ((!s.isMoving && !s.isResizing) || o.liveContentResizing || remeasure || m.top == undefined) { + _measure(); + // if any footers are below pane-bottom, they may not measure correctly, + // so allow pane overflow and re-measure + if (m.hiddenFooters > 0 && $P.css("overflow") === "hidden") { + $P.css("overflow", "visible"); + _measure(); // remeasure while overflowing + $P.css("overflow", "hidden"); + } + } + // NOTE: spaceAbove/Below *includes* the pane paddingTop/Bottom, but not pane.borders + var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); + + if (!$C.is(":visible") || m.height != newH) { + // size the Content element to fit new pane-size - will autoHide if not enough room + setOuterHeight($C, newH, true); // true=autoHide + m.height = newH; // save new height + }; + + if (state.initialized) + _runCallbacks("onsizecontent_end", pane); + + function _below ($E) { + return max(s.css.paddingBottom, (parseInt($E.css("marginBottom"), 10) || 0)); + }; + + function _measure () { + var + ignore = options[pane].contentIgnoreSelector + , $Fs = $C.nextAll().not(ignore || ':lt(0)') // not :lt(0) = ALL + , $Fs_vis = $Fs.filter(':visible') + , $F = $Fs_vis.filter(':last') + ; + m = { + top: $C[0].offsetTop + , height: $C.outerHeight() + , numFooters: $Fs.length + , hiddenFooters: $Fs.length - $Fs_vis.length + , spaceBelow: 0 // correct if no content footer ($E) + } + m.spaceAbove = m.top; // just for state - not used in calc + m.bottom = m.top + m.height; + if ($F.length) + //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) + m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); + else // no footer - check marginBottom on Content element itself + m.spaceBelow = _below($C); + }; + }); + } + + + /** + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @see initHandles(), open(), close(), resizeAll() + * @param {string=} [panes=""] The pane(s) being resized + */ +, sizeHandles = function (evt_or_panes) { + var panes = evtPane.call(this, evt_or_panes) + panes = panes ? panes.split(",") : _c.borderPanes; + + $.each(panes, function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , left + , offset + , CSS = {} + ; + + if (spacing === 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir === "horz") { // north/south + //paneLen = $P.outerWidth(); // s.outerWidth || + paneLen = sC.innerWidth; // handle offscreen-panes + s.resizerLength = paneLen; + left = $.layout.cssNum($P, "left") + $R.css({ + width: cssW($R, paneLen) // account for borders & padding + , height: cssH($R, spacing) // ditto + , left: left > -9999 ? left : sC.insetLeft // handle offscreen-panes + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: cssH($R, paneLen) // account for borders & padding + , width: cssW($R, spacing) // ditto + , top: sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane? + //, top: $.layout.cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen === 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen === "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (isStr(togAlign)) { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = round((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign, 10); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir === "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: width // account for borders & padding + , height: cssH($T, spacing) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", round((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: height // account for borders & padding + , width: cssW($T, spacing) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", round((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && (o.initHidden || s.noRoom)) { + $R.hide(); + if ($T) $T.hide(); + } + }); + } + + + /** + * @param {string} pane + */ +, enableClosable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + , o = options[pane] + ; + if (!$T) return; + o.closable = true; + $T .bind("click."+ sID, function(evt){ evt.stopPropagation(); toggle(pane); }) + .css("visibility", "visible") + .css("cursor", "pointer") + .attr("title", state[pane].isClosed ? o.togglerTip_closed : o.togglerTip_open) // may be blank + .show(); + } + /** + * @param {string} pane + * @param {boolean=} [hide=false] + */ +, disableClosable = function (evt_or_pane, hide) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $T = $Ts[pane] + ; + if (!$T) return; + options[pane].closable = false; + // is closable is disable, then pane MUST be open! + if (state[pane].isClosed) open(pane, false, true); + $T .unbind("."+ sID) + .css("visibility", hide ? "hidden" : "visible") // instead of hide(), which creates logic issues + .css("cursor", "default") + .attr("title", ""); + } + + + /** + * @param {string} pane + */ +, enableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].slidable = true; + if (s.isClosed) + bindStartSlidingEvent(pane, true); + } + /** + * @param {string} pane + */ +, disableSlidable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R) return; + options[pane].slidable = false; + if (state[pane].isSliding) + close(pane, false, true); + else { + bindStartSlidingEvent(pane, false); + $R .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + } + + + /** + * @param {string} pane + */ +, enableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + , o = options[pane] + ; + if (!$R || !$R.data('draggable')) return; + o.resizable = true; + $R.draggable("enable"); + if (!state[pane].isClosed) + $R .css("cursor", o.resizerCursor) + .attr("title", o.resizerTip); + } + /** + * @param {string} pane + */ +, disableResizable = function (evt_or_pane) { + if (!isInitialized()) return; + var pane = evtPane.call(this, evt_or_pane) + , $R = $Rs[pane] + ; + if (!$R || !$R.data('draggable')) return; + options[pane].resizable = false; + $R .draggable("disable") + .css("cursor", "default") + .attr("title", ""); + removeHover(null, $R[0]); // in case currently hovered + } + + + /** + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + * + * @param {string} pane1 The pane/edge being swapped + * @param {string} pane2 ditto + */ +, swapPanes = function (evt_or_pane1, pane2) { + if (!isInitialized()) return; + var pane1 = evtPane.call(this, evt_or_pane1); + // change state.edge NOW so callbacks can know where pane is headed... + state[pane1].edge = pane2; + state[pane2].edge = pane1; + // run these even if NOT state.initialized + if (false === _runCallbacks("onswap_start", pane1) + || false === _runCallbacks("onswap_start", pane2) + ) { + state[pane1].edge = pane1; // reset + state[pane2].edge = pane2; + return; + } + + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // ALWAYS remove the resizer & toggler elements + if ($Ts[pane1]) $Ts[pane1].remove(); + if ($Ts[pane2]) $Ts[pane2].remove(); + if ($Rs[pane1]) $Rs[pane1].remove(); + if ($Rs[pane2]) $Rs[pane2].remove(); + $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + // run these even if NOT state.initialized + _runCallbacks("onswap_end", pane1); + _runCallbacks("onswap_end", pane2); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend(true, {}, state[n]) + , options: $.extend(true, {}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + , side = c.side.toLowerCase() + , inset = "inset"+ c.side + // save pane-options that should be retained + , s = $.extend({}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + fx[k +"_size"] = o[k +"_size"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data({ + layoutPane: Instance[pane] // NEW pointer to pane-alias-object + , layoutEdge: pane + }) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend({}, oPane.options, fx); + state[pane] = $.extend({}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp(o.paneClass +"-"+ oldPane, "g"); + P.className = P.className.replace(re, o.paneClass +"-"+ pane); + + // ALWAYS regenerate the resizer & toggler elements + initHandles(pane); // create the required resizer & toggler + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true, true); // true/true = skipCallback/noAnimation + } + else // move the resizer here + $Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane); + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + } + + + /** + * INTERNAL method to sync pin-buttons when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), setAsOpen(), setAsClosed() + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns = function (pane, doPin) { + if ($.layout.plugins.buttons) + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(Instance, $(selector), pane, doPin); + }); + } + +; // END var DECLARATIONS + + /** + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @see document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes, function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code === (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * Change/reset a pane overflow setting & zIndex to allow popups/drop-downs to work + * + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or its closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (options.zIndexes.resizer_normal + 1) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && !ofX.match(/visible|auto/)) { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && !ofY.match(/visible|auto/)) { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes, function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + /** + * @param {Object=} [el] (optional) Can also be 'bound' to a click, mouseOver, or other event + */ + function resetOverflow (el) { + if (!isInitialized()) return; + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", options.zIndexes.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $N = $(this).eq(0); // FIRST matching Container element + if (!$N.length) { + if (options.showErrorMessages) + _log( lang.errContainerMissing, true ); + return null; + }; + + // Users retrieve Instance of a layout with: $N.layout() OR $N.data("layout") + // return the Instance-pointer if layout has already been initialized + if ($N.data("layoutContainer") && $N.data("layout")) + return $N.data("layout"); // cached pointer + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + , $Ms = $([]) // Masks - up to 2 masks per pane (IFRAME + DIV) + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create Instance object to expose data & option Properties, and primary action Methods + var Instance = { + // layout data + options: options // property - options hash + , state: state // property - dimensions hash + // object pointers + , container: $N // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , contents: $Cs // property - object pointers for ALL Content: contents.north, contents.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + // border-pane open/close + , hide: hide // method - ditto + , show: show // method - ditto + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , open: open // method - ditto + , close: close // method - ditto + , slideOpen: slideOpen // method - ditto + , slideClose: slideClose // method - ditto + , slideToggle: slideToggle // method - ditto + // pane actions + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , _sizePane: sizePane // method -intended for user by plugins only! + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , sizeContent: sizeContent // method - pass a 'pane' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + // pane element methods + , initContent: initContent // method - ditto + , addPane: addPane // method - pass a 'pane' + , removePane: removePane // method - pass a 'pane' to remove from layout, add 'true' to delete the pane-elem + , createChildLayout: createChildLayout// method - pass a 'pane' and (optional) layout-options (OVERRIDES options[pane].childOptions + // special pane option setting + , enableClosable: enableClosable // method - pass a 'pane' + , disableClosable: disableClosable // method - ditto + , enableSlidable: enableSlidable // method - ditto + , disableSlidable: disableSlidable // method - ditto + , enableResizable: enableResizable // method - ditto + , disableResizable: disableResizable// method - ditto + // utility methods for panes + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + // layout control + , destroy: destroy // method - no parameters + , initPanes: isInitialized // method - no parameters + , resizeAll: resizeAll // method - no parameters + // callback triggering + , runCallbacks: _runCallbacks // method - pass evtName & pane (if a pane-event), eg: trigger("onopen", "west") + // alias collections of options, state and children - created in addPane and extended elsewhere + , hasParentLayout: false // set by initContainer() + , children: children // pointers to child-layouts, eg: Instance.children["west"] + , north: false // alias group: { name: pane, pane: $Ps[pane], options: options[pane], state: state[pane], child: children[pane] } + , south: false // ditto + , west: false // ditto + , east: false // ditto + , center: false // ditto + }; + + // create the border layout NOW + if (_create() === 'cancel') // onload_start callback returned false to CANCEL layout creation + return null; + else // true OR false -- if layout-elements did NOT init (hidden or do not exist), can auto-init later + return Instance; // return the Instance object + +} + + + + +/** + * jquery.layout.state 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2010 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * @dependancies: $.ui.cookie (above) + * + * @support: http://groups.google.com/group/jquery-ui-layout + */ +/* + * State-management options stored in options.stateManagement, which includes a .cookie hash + * Default options saves ALL KEYS for ALL PANES, ie: pane.size, pane.isClosed, pane.isHidden + * + * // STATE/COOKIE OPTIONS + * @example $(el).layout({ + stateManagement: { + enabled: true + , stateKeys: "east.size,west.size,east.isClosed,west.isClosed" + , cookie: { name: "appLayout", path: "/" } + } + }) + * @example $(el).layout({ stateManagement__enabled: true }) // enable auto-state-management using cookies + * @example $(el).layout({ stateManagement__cookie: { name: "appLayout", path: "/" } }) + * @example $(el).layout({ stateManagement__cookie__name: "appLayout", stateManagement__cookie__path: "/" }) + * + * // STATE/COOKIE METHODS + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.loadCookie(); + * @example myLayout.deleteCookie(); + * @example var JSON = myLayout.readState(); // CURRENT Layout State + * @example var JSON = myLayout.readCookie(); // SAVED Layout State (from cookie) + * @example var JSON = myLayout.state.stateData; // LAST LOADED Layout State (cookie saved in layout.state hash) + * + * CUSTOM STATE-MANAGEMENT (eg, saved in a database) + * @example var JSON = myLayout.readState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.loadState( JSON ); + */ + +/** + * UI COOKIE UTILITY + * + * A $.cookie OR $.ui.cookie namespace *should be standard*, but until then... + * This creates $.ui.cookie so Layout does not need the cookie.jquery.js plugin + * NOTE: This utility is REQUIRED by the layout.state plugin + * + * Cookie methods in Layout are created as part of State Management + */ +if (!$.ui) $.ui = {}; +$.ui.cookie = { + + // cookieEnabled is not in DOM specs, but DOES works in all browsers,including IE6 + acceptsCookies: !!navigator.cookieEnabled + +, read: function (name) { + var + c = document.cookie + , cs = c ? c.split(';') : [] + , pair // loop var + ; + for (var i=0, n=cs.length; i < n; i++) { + pair = $.trim(cs[i]).split('='); // name=value pair + if (pair[0] == name) // found the layout cookie + return decodeURIComponent(pair[1]); + + } + return null; + } + +, write: function (name, val, cookieOpts) { + var + params = '' + , date = '' + , clear = false + , o = cookieOpts || {} + , x = o.expires + ; + if (x && x.toUTCString) + date = x; + else if (x === null || typeof x === 'number') { + date = new Date(); + if (x > 0) + date.setDate(date.getDate() + x); + else { + date.setFullYear(1970); + clear = true; + } + } + if (date) params += ';expires='+ date.toUTCString(); + if (o.path) params += ';path='+ o.path; + if (o.domain) params += ';domain='+ o.domain; + if (o.secure) params += ';secure'; + document.cookie = name +'='+ (clear ? "" : encodeURIComponent( val )) + params; // write or clear cookie + } + +, clear: function (name) { + $.ui.cookie.write(name, '', {expires: -1}); + } + +}; +// if cookie.jquery.js is not loaded, create an alias to replicate it +// this may be useful to other plugins or code dependent on that plugin +if (!$.cookie) $.cookie = function (k, v, o) { + var C = $.ui.cookie; + if (v === null) + C.clear(k); + else if (v === undefined) + return C.read(k); + else + C.write(k, v, o); +}; + + +// tell Layout that the state plugin is available +$.layout.plugins.stateManagement = true; + +// Add State-Management options to layout.defaults +$.layout.config.optionRootKeys.push("stateManagement"); +$.layout.defaults.stateManagement = { + enabled: false // true = enable state-management, even if not using cookies +, autoSave: true // Save a state-cookie when page exits? +, autoLoad: true // Load the state-cookie when Layout inits? + // List state-data to save - must be pane-specific +, stateKeys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" +, cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , domain: "" // blank = current domain + , path: "" // blank = current page, '/' = entire website + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + } +}; +// Set stateManagement as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("stateManagement"); + +/* + * State Management methods + */ +$.layout.state = { + + /** + * Get the current layout state and save it to a cookie + * + * myLayout.saveCookie( keys, cookieOpts ) + * + * @param {Object} inst + * @param {(string|Array)=} keys + * @param {Object=} opts + */ + saveCookie: function (inst, keys, cookieOpts) { + var o = inst.options + , oS = o.stateManagement + , oC = $.extend(true, {}, oS.cookie, cookieOpts || null) + , data = inst.state.stateData = inst.readState( keys || oS.stateKeys ) // read current panes-state + ; + $.ui.cookie.write( oC.name || o.name || "Layout", $.layout.state.encodeJSON(data), oC ); + return $.extend(true, {}, data); // return COPY of state.stateData data + } + + /** + * Remove the state cookie + * + * @param {Object} inst + */ +, deleteCookie: function (inst) { + var o = inst.options; + $.ui.cookie.clear( o.stateManagement.cookie.name || o.name || "Layout" ); + } + + /** + * Read & return data from the cookie - as JSON + * + * @param {Object} inst + */ +, readCookie: function (inst) { + var o = inst.options; + var c = $.ui.cookie.read( o.stateManagement.cookie.name || o.name || "Layout" ); + // convert cookie string back to a hash and return it + return c ? $.layout.state.decodeJSON(c) : {}; + } + + /** + * Get data from the cookie and USE IT to loadState + * + * @param {Object} inst + */ +, loadCookie: function (inst) { + var c = $.layout.state.readCookie(inst); // READ the cookie + if (c) { + inst.state.stateData = $.extend(true, {}, c); // SET state.stateData + inst.loadState(c); // LOAD the retrieved state + } + return c; + } + + /** + * Update layout options from the cookie, if one exists + * + * @param {Object} inst + * @param {Object=} stateData + * @param {boolean=} animate + */ +, loadState: function (inst, stateData, animate) { + stateData = $.layout.transformData( stateData ); // panes = default subkey + if ($.isEmptyObject( stateData )) return; + $.extend(true, inst.options, stateData); // update layout options + // if layout has already been initialized, then UPDATE layout state + if (inst.state.initialized) { + var pane, vis, o, s, h, c + , noAnimate = (animate===false) + ; + $.each($.layout.config.borderPanes, function (idx, pane) { + state = inst.state[pane]; + o = stateData[ pane ]; + if (typeof o != 'object') return; // no key, continue + s = o.size; + c = o.initClosed; + h = o.initHidden; + vis = state.isVisible; + // resize BEFORE opening + if (!vis) + inst.sizePane(pane, s, false, false); + if (h === true) inst.hide(pane, noAnimate); + else if (c === false) inst.open (pane, false, noAnimate); + else if (c === true) inst.close(pane, false, noAnimate); + else if (h === false) inst.show (pane, false, noAnimate); + // resize AFTER any other actions + if (vis) + inst.sizePane(pane, s, false, noAnimate); // animate resize if option passed + }); + }; + } + + /** + * Get the *current layout state* and return it as a hash + * + * @param {Object=} inst + * @param {(string|Array)=} keys + */ +, readState: function (inst, keys) { + var + data = {} + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , state = inst.state + , panes = $.layout.config.allPanes + , pair, pane, key, val + ; + if (!keys) keys = inst.options.stateManagement.stateKeys; // if called by user + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0, n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if ($.inArray(pane, panes) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + return data; + } + + /** + * Stringify a JSON hash so can save in a cookie or db-field + */ +, encodeJSON: function (JSON) { + return parse(JSON); + function parse (h) { + var D=[], i=0, k, v, t; // k = key, v = value + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = '"'+ k +'":'+ v; + } + return '{'+ D.join(',') +'}'; + }; + } + + /** + * Convert stringified JSON back to a hash object + * @see $.parseJSON(), adding in jQuery 1.4.1 + */ +, decodeJSON: function (str) { + try { return $.parseJSON ? $.parseJSON(str) : window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + } + + +, _create: function (inst) { + var _ = $.layout.state; + // ADD State-Management plugin methods to inst + $.extend( inst, { + // readCookie - update options from cookie - returns hash of cookie data + readCookie: function () { return _.readCookie(inst); } + // deleteCookie + , deleteCookie: function () { _.deleteCookie(inst); } + // saveCookie - optionally pass keys-list and cookie-options (hash) + , saveCookie: function (keys, cookieOpts) { return _.saveCookie(inst, keys, cookieOpts); } + // loadCookie - readCookie and use to loadState() - returns hash of cookie data + , loadCookie: function () { return _.loadCookie(inst); } + // loadState - pass a hash of state to use to update options + , loadState: function (stateData, animate) { _.loadState(inst, stateData, animate); } + // readState - returns hash of current layout-state + , readState: function (keys) { return _.readState(inst, keys); } + // add JSON utility methods too... + , encodeJSON: _.encodeJSON + , decodeJSON: _.decodeJSON + }); + + // init state.stateData key, even if plugin is initially disabled + inst.state.stateData = {}; + + // read and load cookie-data per options + var oS = inst.options.stateManagement; + if (oS.enabled) { + if (oS.autoLoad) // update the options from the cookie + inst.loadCookie(); + else // don't modify options - just store cookie data in state.stateData + inst.state.stateData = inst.readCookie(); + } + } + +, _unload: function (inst) { + var oS = inst.options.stateManagement; + if (oS.enabled) { + if (oS.autoSave) // save a state-cookie automatically + inst.saveCookie(); + else // don't save a cookie, but do store state-data in state.stateData key + inst.state.stateData = inst.readState(); + } + } + +}; + +// add state initialization method to Layout's onCreate array of functions +$.layout.onCreate.push( $.layout.state._create ); +$.layout.onUnload.push( $.layout.state._unload ); + + + + +/** + * jquery.layout.buttons 1.0 + * $Date: 2011-07-16 08:00:00 (Sat, 16 July 2011) $ + * + * Copyright (c) 2010 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * + * @support: http://groups.google.com/group/jquery-ui-layout + * + * Docs: [ to come ] + * Tips: [ to come ] + */ + +// tell Layout that the state plugin is available +$.layout.plugins.buttons = true; + +// Add buttons options to layout.defaults +$.layout.defaults.autoBindCustomButtons = false; +// Specify autoBindCustomButtons as a layout-option, NOT a pane-option +$.layout.optionsMap.layout.push("autoBindCustomButtons"); + +var lang = $.layout.language; + +/* + * Button methods + */ +$.layout.buttons = { + + /** + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @see _create() + * + * @param {Object} inst Layout Instance object + */ + init: function (inst) { + var pre = "ui-layout-button-" + , layout = inst.options.name || "" + , name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each($.layout.config.borderPanes, function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name === layout) + inst.bindButton(this, action, pane); + }); + }); + }); + } + + /** + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin // action btnClass + * - ui-layout-button-pin-west // action btnClass + pane + * - ui-layout-button-toggle + * - ui-layout-button-open + * - ui-layout-button-close + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * + * @return {Array.} If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise returns null + */ +, get: function (inst, selector, pane, action) { + var $E = $(selector) + , o = inst.options + , err = o.showErrorMessages + ; + if (!$E.length) { // element not found + if (err) $.layout.msg(lang.errButton + lang.selector +": "+ selector, true); + } + else if ($.inArray(pane, $.layout.config.borderPanes) < 0) { // invalid 'pane' sepecified + if (err) $.layout.msg(lang.errButton + lang.pane +": "+ pane, true); + $E = $(""); // NO BUTTON + } + else { // VALID + var btn = o[pane].buttonClass +"-"+ action; + $E .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", o.name); // add layout identifier - even if blank! + } + return $E; + } + + + /** + * NEW syntax for binding layout-buttons - will eventually replace addToggle, addOpen, etc. + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} action + * @param {string} pane + */ +, bind: function (inst, selector, action, pane) { + var _ = $.layout.buttons; + switch (action.toLowerCase()) { + case "toggle": _.addToggle (inst, selector, pane); break; + case "open": _.addOpen (inst, selector, pane); break; + case "close": _.addClose (inst, selector, pane); break; + case "pin": _.addPin (inst, selector, pane); break; + case "toggle-slide": _.addToggle (inst, selector, pane, true); break; + case "open-slide": _.addOpen (inst, selector, pane, true); break; + } + return inst; + } + + /** + * Add a custom Toggler button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addToggle: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "toggle") + .click(function(evt){ + inst.toggle(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Open button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + * @param {boolean=} slide true = slide-open, false = pin-open + */ +, addOpen: function (inst, selector, pane, slide) { + $.layout.buttons.get(inst, selector, pane, "open") + .attr("title", lang.Open) + .click(function (evt) { + inst.open(pane, !!slide); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Close button for a pane + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the button is for: 'north', 'south', etc. + */ +, addClose: function (inst, selector, pane) { + $.layout.buttons.get(inst, selector, pane, "close") + .attr("title", lang.Close) + .click(function (evt) { + inst.close(pane); + evt.stopPropagation(); + }); + return inst; + } + + /** + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param {Object} inst Layout Instance object + * @param {(string|!Object)} selector jQuery selector (or element) for button, eg: ".ui-layout-north .toggle-button" + * @param {string} pane Name of the pane the pin is for: 'north', 'south', etc. + */ +, addPin: function (inst, selector, pane) { + var _ = $.layout.buttons + , $E = _.get(inst, selector, pane, "pin"); + if ($E.length) { + var s = inst.state[pane]; + $E.click(function (evt) { + _.setPinState(inst, $(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) inst.open( pane ); // change from sliding to open + else inst.close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + _.setPinState(inst, $E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + s.pins.push( selector ); // just save the selector string + } + return inst; + } + + /** + * Change the class of the pin button to make it look 'up' or 'down' + * + * @see addPin(), syncPins() + * + * @param {Object} inst Layout Instance object + * @param {Array.} $Pin The pin-span element in a jQuery wrapper + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin true = set the pin 'down', false = set it 'up' + */ +, setPinState: function (inst, $Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin === (updown=="down")) return; // already in correct state + var + pin = inst.options[pane].buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? lang.Unpin : lang.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + } + + /** + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @see open(), close() + * + * @param {Object} inst Layout Instance object + * @param {string} pane These are the params returned to callbacks by layout() + * @param {boolean} doPin True means set the pin 'down', False means 'up' + */ +, syncPinBtns: function (inst, pane, doPin) { + // REAL METHOD IS _INSIDE_ LAYOUT - THIS IS HERE JUST FOR REFERENCE + $.each(state[pane].pins, function (i, selector) { + $.layout.buttons.setPinState(inst, $(selector), pane, doPin); + }); + } + + +, _load: function (inst) { + var _ = $.layout.buttons; + // ADD Button methods to Layout Instance + // Note: sel = jQuery Selector string + $.extend( inst, { + bindButton: function (sel, action, pane) { return _.bind(inst, sel, action, pane); } + // DEPRECATED METHODS + , addToggleBtn: function (sel, pane, slide) { return _.addToggle(inst, sel, pane, slide); } + , addOpenBtn: function (sel, pane, slide) { return _.addOpen(inst, sel, pane, slide); } + , addCloseBtn: function (sel, pane) { return _.addClose(inst, sel, pane); } + , addPinBtn: function (sel, pane) { return _.addPin(inst, sel, pane); } + }); + + // init state array to hold pin-buttons + for (var i=0; i<4; i++) { + var pane = $.layout.config.borderPanes[i]; + inst.state[pane].pins = []; + } + + // auto-init buttons onLoad if option is enabled + if ( inst.options.autoBindCustomButtons ) + _.init(inst); + } + +, _unload: function (inst) { + // TODO: unbind all buttons??? + } + +}; + +// add initialization method to Layout's onLoad array of functions +$.layout.onLoad.push( $.layout.buttons._load ); +//$.layout.onUnload.push( $.layout.buttons._unload ); + + + +/** + * jquery.layout.browserZoom 1.0 + * $Date: 2011-12-29 08:00:00 (Thu, 29 Dec 2011) $ + * + * Copyright (c) 2012 + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * @dependancies: UI Layout 1.3.0.rc30.1 or higher + * + * @support: http://groups.google.com/group/jquery-ui-layout + * + * @todo: Extend logic to handle other problematic zooming in browsers + * @todo: Add hotkey/mousewheel bindings to _instantly_ respond to these zoom event + */ + +// tell Layout that the plugin is available +$.layout.plugins.browserZoom = true; + +$.layout.defaults.browserZoomCheckInterval = 1000; +$.layout.optionsMap.layout.push("browserZoomCheckInterval"); + +/* + * browserZoom methods + */ +$.layout.browserZoom = { + + _init: function (inst) { + // abort if browser does not need this check + if ($.layout.browserZoom.ratio() !== false) + $.layout.browserZoom._setTimer(inst); + } + +, _setTimer: function (inst) { + // abort if layout destroyed or browser does not need this check + if (inst.destroyed) return; + var o = inst.options + , s = inst.state + // don't need check if inst has parentLayout, but check occassionally in case parent destroyed! + // MINIMUM 100ms interval, for performance + , ms = inst.hasParentLayout ? 5000 : Math.max( o.browserZoomCheckInterval, 100 ) + ; + // set the timer + setTimeout(function(){ + if (inst.destroyed || !o.resizeWithWindow) return; + var d = $.layout.browserZoom.ratio(); + if (d !== s.browserZoom) { + s.browserZoom = d; + inst.resizeAll(); + } + // set a NEW timeout + $.layout.browserZoom._setTimer(inst); + } + , ms ); + } + +, ratio: function () { + var w = window + , s = screen + , d = document + , dE = d.documentElement || d.body + , b = $.layout.browser + , v = b.version + , r, sW, cW + ; + // we can ignore all browsers that fire window.resize event onZoom + if ((b.msie && v > 8) + || !b.msie + ) return false; // don't need to track zoom + + if (s.deviceXDPI) + return calc(s.deviceXDPI, s.systemXDPI); + // everything below is just for future reference! + if (b.webkit && (r = d.body.getBoundingClientRect)) + return calc((r.left - r.right), d.body.offsetWidth); + if (b.webkit && (sW = w.outerWidth)) + return calc(sW, w.innerWidth); + if ((sW = s.width) && (cW = dE.clientWidth)) + return calc(sW, cW); + return false; // no match, so cannot - or don't need to - track zoom + + function calc (x,y) { return (parseInt(x,10) / parseInt(y,10) * 100).toFixed(); } + } + +}; +// add initialization method to Layout's onLoad array of functions +$.layout.onReady.push( $.layout.browserZoom._init ); + + + +})( jQuery ); \ No newline at end of file diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif new file mode 100644 index 00000000..085ccaec Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-anim_basic_16x16.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 00000000..5b5dab2a Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_0_aaaaaa_40x100.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png new file mode 100644 index 00000000..47acaadd Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_flat_55_fbec88_40x100.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png new file mode 100644 index 00000000..9d149b1c Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_75_d0e5f5_1x400.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png new file mode 100644 index 00000000..01495152 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_85_dfeffc_1x400.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png new file mode 100644 index 00000000..4443fdc1 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_glass_95_fef1ec_1x400.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png new file mode 100644 index 00000000..81ecc362 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png new file mode 100644 index 00000000..4f3faf8a Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png new file mode 100644 index 00000000..38c38335 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png new file mode 100644 index 00000000..6f4bd87c Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_217bc0_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png new file mode 100644 index 00000000..09d1cdc8 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_2e83ff_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png new file mode 100644 index 00000000..bd2cf079 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_469bdd_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png new file mode 100644 index 00000000..3d6f567f Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_6da8d5_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png new file mode 100644 index 00000000..2ab019b7 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_cd0a0a_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png new file mode 100644 index 00000000..ad2dc6f9 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_d8e7f3_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png new file mode 100644 index 00000000..c7c53cb1 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/theme-redmond/images/ui-icons_f9bd01_256x240.png differ diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css b/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css new file mode 100644 index 00000000..0b173632 --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.2.custom.css @@ -0,0 +1,398 @@ +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +*/ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } +.ui-helper-clearfix { display: inline-block; } +/* required comment for clearfix to work in Opera \*/ +* html .ui-helper-clearfix { height:1%; } +.ui-helper-clearfix { display:block; } +/* end clearfix */ +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/* +* jQuery UI CSS Framework +* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about) +* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +*/ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } +.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; } +.ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-top { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-bottom { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-right { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; border-top-right-radius: 5px; -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } +.ui-corner-left { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; border-top-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-all { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/* Resizable +----------------------------------*/ +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;} +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable +----------------------------------*/ +.ui-selectable-helper { border:1px dotted black } +/* Autocomplete +----------------------------------*/ +.ui-autocomplete { position: absolute; cursor: default; } +.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; } + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ + +/* Menu +----------------------------------*/ +.ui-menu { + list-style:none; + padding: 2px; + margin: 0; + display:block; +} +.ui-menu .ui-menu { + margin-top: -3px; +} +.ui-menu .ui-menu-item { + margin:0; + padding: 0; + zoom: 1; + float: left; + clear: left; + width: 100%; +} +.ui-menu .ui-menu-item a { + text-decoration:none; + display:block; + padding:.2em .4em; + line-height:1.5; + zoom:1; +} +.ui-menu .ui-menu-item a.ui-state-hover, +.ui-menu .ui-menu-item a.ui-state-active { + font-weight: normal; + margin: -1px; +} +/* Button +----------------------------------*/ + +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ + + + + + +/* Dialog +----------------------------------*/ +.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +/* Tabs +----------------------------------*/ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } diff --git a/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.21.custom.css b/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.21.custom.css new file mode 100644 index 00000000..c02c76f5 --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/theme-redmond/jquery-ui-1.8.21.custom.css @@ -0,0 +1,304 @@ +/*! + * jQuery UI CSS Framework 1.8.21 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute !important; clip: rect(1px 1px 1px 1px); clip: rect(1px,1px,1px,1px); } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } + + +/*! + * jQuery UI CSS Framework 1.8.21 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Theming/API + * + * To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Lucida%20Grande,%20Lucida%20Sans,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=5px&bgColorHeader=5c9ccc&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=55&borderColorHeader=4297d7&fcHeader=ffffff&iconColorHeader=d8e7f3&bgColorContent=fcfdfd&bgTextureContent=06_inset_hard.png&bgImgOpacityContent=100&borderColorContent=a6c9e2&fcContent=222222&iconColorContent=469bdd&bgColorDefault=dfeffc&bgTextureDefault=02_glass.png&bgImgOpacityDefault=85&borderColorDefault=c5dbec&fcDefault=2e6e9e&iconColorDefault=6da8d5&bgColorHover=d0e5f5&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=79b7e7&fcHover=1d5987&iconColorHover=217bc0&bgColorActive=f5f8f9&bgTextureActive=06_inset_hard.png&bgImgOpacityActive=100&borderColorActive=79b7e7&fcActive=e17009&iconColorActive=f9bd01&bgColorHighlight=fbec88&bgTextureHighlight=01_flat.png&bgImgOpacityHighlight=55&borderColorHighlight=fad42e&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px + */ + + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1.1em; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Lucida Grande, Lucida Sans, Arial, sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #a6c9e2; background: #fcfdfd url(images/ui-bg_inset-hard_100_fcfdfd_1x100.png) 50% bottom repeat-x; color: #222222; } +.ui-widget-content a { color: #222222; } +.ui-widget-header { border: 1px solid #4297d7; background: #5c9ccc url(images/ui-bg_gloss-wave_55_5c9ccc_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; } +.ui-widget-header a { color: #ffffff; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #c5dbec; background: #dfeffc url(images/ui-bg_glass_85_dfeffc_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #2e6e9e; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #2e6e9e; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #79b7e7; background: #d0e5f5 url(images/ui-bg_glass_75_d0e5f5_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1d5987; } +.ui-state-hover a, .ui-state-hover a:hover { color: #1d5987; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #79b7e7; background: #f5f8f9 url(images/ui-bg_inset-hard_100_f5f8f9_1x100.png) 50% 50% repeat-x; font-weight: bold; color: #e17009; } +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #e17009; text-decoration: none; } +.ui-widget :active { outline: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fad42e; background: #fbec88 url(images/ui-bg_flat_55_fbec88_40x100.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_469bdd_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_d8e7f3_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_6da8d5_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_217bc0_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_f9bd01_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; -khtml-border-top-left-radius: 5px; border-top-left-radius: 5px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 5px; -webkit-border-top-right-radius: 5px; -khtml-border-top-right-radius: 5px; border-top-right-radius: 5px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; -khtml-border-bottom-left-radius: 5px; border-bottom-left-radius: 5px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 5px; -webkit-border-bottom-right-radius: 5px; -khtml-border-bottom-right-radius: 5px; border-bottom-right-radius: 5px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .30;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; }/*! + * jQuery UI Tabs 1.8.21 + * + * Copyright 2012, AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * http://docs.jquery.com/UI/Tabs#theming + */ +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tabs .ui-tabs-hide { display: none !important; } diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/file.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/file.gif new file mode 100644 index 00000000..bd4f9654 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/file.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed.gif new file mode 100644 index 00000000..be6b59c2 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed2.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed2.gif new file mode 100644 index 00000000..54110788 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder-closed2.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/folder.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder.gif new file mode 100644 index 00000000..be6b59c2 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/folder2.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder2.gif new file mode 100644 index 00000000..2b31631c Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/folder2.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/minus.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/minus.gif new file mode 100644 index 00000000..47fb7b76 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/minus.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/plus.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/plus.gif new file mode 100644 index 00000000..69066216 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/plus.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black-line.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black-line.gif new file mode 100644 index 00000000..e5496877 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black-line.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black.gif new file mode 100644 index 00000000..d549b9fc Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-black.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default-line.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default-line.gif new file mode 100644 index 00000000..37114d30 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default-line.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default.gif new file mode 100644 index 00000000..a12ac52f Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-default.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam-line.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam-line.gif new file mode 100644 index 00000000..6e289cec Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam-line.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam.gif new file mode 100644 index 00000000..0cb178e8 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-famfamfam.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray-line.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray-line.gif new file mode 100644 index 00000000..37600447 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray-line.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray.gif new file mode 100644 index 00000000..cfb8a2f0 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-gray.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red-line.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red-line.gif new file mode 100644 index 00000000..df9e749a Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red-line.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red.gif b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red.gif new file mode 100644 index 00000000..3bbb3a15 Binary files /dev/null and b/src/doc/user/webhelp/template/common/jquery/treeview/images/treeview-red.gif differ diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.css b/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.css new file mode 100644 index 00000000..dbf425b2 --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.css @@ -0,0 +1,85 @@ +.treeview, .treeview ul { + padding: 0; + margin: 0; + list-style: none; +} + +.treeview ul { + background-color: white; + margin-top: 4px; +} + +.treeview .hitarea { + background: url(images/treeview-default.gif) -64px -25px no-repeat; + height: 16px; + width: 16px; + margin-left: -16px; + float: left; + cursor: pointer; +} +/* fix for IE6 */ +* html .hitarea { + display: inline; + float:none; +} + +.treeview li { + margin: 0; + padding: 3px 0 3px 16px; +} + +.treeview a.selected { + background-color: #eee; +} + +#treecontrol { margin: 1em 0; display: none; } + +.treeview .hover { color: red; cursor: pointer; } + +.treeview li { background: url(images/treeview-default-line.gif) 0 0 no-repeat; } +.treeview li.collapsable, .treeview li.expandable { background-position: 0 -176px; } + +.treeview .expandable-hitarea { background-position: -80px -3px; } + +.treeview li.last { background-position: 0 -1766px } +.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); } +.treeview li.lastCollapsable { background-position: 0 -111px } +.treeview li.lastExpandable { background-position: -32px -67px } + +.treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; } + +.treeview-red li { background-image: url(images/treeview-red-line.gif); } +.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); } + +.treeview-black li { background-image: url(images/treeview-black-line.gif); } +.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); } + +.treeview-gray li { background-image: url(images/treeview-gray-line.gif); } +.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); } + +.treeview-famfamfam li { background-image: url(images/treeview-famfamfam-line.gif); } +.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); } + + +.filetree li { padding: 3px 0 2px 16px; } +.filetree span.folder, .filetree span.file { padding: 1px 0 1px 16px; display: block; } +.filetree span.folder { background: url(images/folder.gif) 0 0 no-repeat; } +.filetree li.expandable span.folder { background: url(images/folder-closed.gif) 0 0 no-repeat; } +.filetree span.file { background: url(images/file.gif) 0 0 no-repeat; } + +html, body {height:100%; margin: 0; padding: 0; } + +/* +html>body { + font-size: 16px; + font-size: 68.75%; +} Reset Base Font Size */ + /* +body { + font-family: Verdana, helvetica, arial, sans-serif; + font-size: 68.75%; + background: #fff; + color: #333; +} */ + +a img { border: none; } \ No newline at end of file diff --git a/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.min.js b/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.min.js new file mode 100644 index 00000000..e693321d --- /dev/null +++ b/src/doc/user/webhelp/template/common/jquery/treeview/jquery.treeview.min.js @@ -0,0 +1,16 @@ +/* + * Treeview 1.4 - jQuery plugin to hide and show branches of a tree + * + * http://bassistance.de/jquery-plugins/jquery-plugin-treeview/ + * http://docs.jquery.com/Plugins/Treeview + * + * Copyright (c) 2007 Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $ + * kasunbg: changed the cookieid name + * + */;(function($){$.extend($.fn,{swapClass:function(c1,c2){var c1Elements=this.filter('.'+c1);this.filter('.'+c2).removeClass(c2).addClass(c1);c1Elements.removeClass(c1).addClass(c2);return this;},replaceClass:function(c1,c2){return this.filter('.'+c1).removeClass(c1).addClass(c2).end();},hoverClass:function(className){className=className||"hover";return this.hover(function(){$(this).addClass(className);},function(){$(this).removeClass(className);});},heightToggle:function(animated,callback){animated?this.animate({height:"toggle"},animated,callback):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();if(callback)callback.apply(this,arguments);});},heightHide:function(animated,callback){if(animated){this.animate({height:"hide"},animated,callback);}else{this.hide();if(callback)this.each(callback);}},prepareBranches:function(settings){if(!settings.prerendered){this.filter(":last-child:not(ul)").addClass(CLASSES.last);this.filter((settings.collapsed?"":"."+CLASSES.closed)+":not(."+CLASSES.open+")").find(">ul").hide();}return this.filter(":has(>ul)");},applyClasses:function(settings,toggler){this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event){toggler.apply($(this).next());}).add($("a",this)).hoverClass();if(!settings.prerendered){this.filter(":has(>ul:hidden)").addClass(CLASSES.expandable).replaceClass(CLASSES.last,CLASSES.lastExpandable);this.not(":has(>ul:hidden)").addClass(CLASSES.collapsable).replaceClass(CLASSES.last,CLASSES.lastCollapsable);this.prepend("
        ").find("div."+CLASSES.hitarea).each(function(){var classes="";$.each($(this).parent().attr("class").split(" "),function(){classes+=this+"-hitarea ";});$(this).addClass(classes);});}this.find("div."+CLASSES.hitarea).click(toggler);},treeview:function(settings){if(typeof(window.treeCookieId) === 'undefined' || window.treeCookieId === ""){treeCookieId = "treeview";} settings=$.extend({cookieId: treeCookieId},settings);if(settings.add){return this.trigger("add",[settings.add]);}if(settings.toggle){var callback=settings.toggle;settings.toggle=function(){return callback.apply($(this).parent()[0],arguments);};}function treeController(tree,control){function handler(filter){return function(){toggler.apply($("div."+CLASSES.hitarea,tree).filter(function(){return filter?$(this).parent("."+filter).length:true;}));return false;};}$("a:eq(0)",control).click(handler(CLASSES.collapsable));$("a:eq(1)",control).click(handler(CLASSES.expandable));$("a:eq(2)",control).click(handler());}function toggler(){$(this).parent().find(">.hitarea").swapClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).swapClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().swapClass(CLASSES.collapsable,CLASSES.expandable).swapClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightToggle(settings.animated,settings.toggle);if(settings.unique){$(this).parent().siblings().find(">.hitarea").replaceClass(CLASSES.collapsableHitarea,CLASSES.expandableHitarea).replaceClass(CLASSES.lastCollapsableHitarea,CLASSES.lastExpandableHitarea).end().replaceClass(CLASSES.collapsable,CLASSES.expandable).replaceClass(CLASSES.lastCollapsable,CLASSES.lastExpandable).find(">ul").heightHide(settings.animated,settings.toggle);}}function serialize(){function binary(arg){return arg?1:0;}var data=[];branches.each(function(i,e){data[i]=$(e).is(":has(>ul:visible)")?1:0;});$.cookie(settings.cookieId,data.join(""));}function deserialize(){var stored=$.cookie(settings.cookieId);if(stored){var data=stored.split("");branches.each(function(i,e){$(e).find(">ul")[parseInt(data[i])?"show":"hide"]();});}}this.addClass("treeview");var branches=this.find("li").prepareBranches(settings);switch(settings.persist){case"cookie":var toggleCallback=settings.toggle;settings.toggle=function(){serialize();if(toggleCallback){toggleCallback.apply(this,arguments);}};deserialize();break;case"location":var current=this.find("a").filter(function(){return this.href.toLowerCase()==location.href.toLowerCase();});if(current.length){current.addClass("selected").parents("ul, li").add(current.next()).show();}break;}branches.applyClasses(settings,toggler);if(settings.control){treeController(this,settings.control);$(settings.control).show();}return this.bind("add",function(event,branches){$(branches).prev().removeClass(CLASSES.last).removeClass(CLASSES.lastCollapsable).removeClass(CLASSES.lastExpandable).find(">.hitarea").removeClass(CLASSES.lastCollapsableHitarea).removeClass(CLASSES.lastExpandableHitarea);$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings,toggler);});}});var CLASSES=$.fn.treeview.classes={open:"open",closed:"closed",expandable:"expandable",expandableHitarea:"expandable-hitarea",lastExpandableHitarea:"lastExpandable-hitarea",collapsable:"collapsable",collapsableHitarea:"collapsable-hitarea",lastCollapsableHitarea:"lastCollapsable-hitarea",lastCollapsable:"lastCollapsable",lastExpandable:"lastExpandable",last:"last",hitarea:"hitarea"};$.fn.Treeview=$.fn.treeview;})(jQuery); \ No newline at end of file diff --git a/src/doc/user/webhelp/template/common/main.js b/src/doc/user/webhelp/template/common/main.js new file mode 100644 index 00000000..bcc116fb --- /dev/null +++ b/src/doc/user/webhelp/template/common/main.js @@ -0,0 +1,276 @@ +/** + * Miscellaneous js functions for WebHelp + * Kasun Gajasinghe, http://kasunbg.blogspot.com + * David Cramer, http://www.thingbag.net + * + */ + +//Turn ON and OFF the animations for Show/Hide Sidebar. Extend this to other anime as well if any. +var noAnimations=false; + +$(document).ready(function() { + // When you click on a link to an anchor, scroll down + // 105 px to cope with the fact that the banner + // hides the top 95px or so of the page. + // This code deals with the problem when + // you click on a link within a page. + $('a[href*=#]').click(function() { + if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') + && location.hostname == this.hostname) { + var $target = $(this.hash); + $target = $target.length && $target + || $('[id=' + this.hash.slice(1) +']'); + if (!(this.hash == "#searchDiv" || this.hash == "#treeDiv" || this.hash == "") && $target.length) { + var targetOffset = $target.offset().top - 120; + $('#content') + .animate({scrollTop: targetOffset}, 200); + return false; + } + } + }); + + // $("#showHideHighlight").button(); //add jquery button styling to 'Go' button + //Generate tabs in nav-pane with JQuery + $(function() { + $("#tabs").tabs({ + cookie: { + expires: 2 // store cookie for 2 days. + } + }); + }); + + //Generate the tree + $("#ulTreeDiv").attr("style", ""); + $("#tree").treeview({ + collapsed: true, + animated: "medium", + control: "#sidetreecontrol", + persist: "cookie" + }); + + //after toc fully styled, display it. Until loading, a 'loading' image will be displayed + $("#tocLoading").attr("style", "display:none;"); + // $("#ulTreeDiv").attr("style","display:block;"); + + //.searchButton is the css class applied to 'Go' button + $(function() { + $("button", ".searchButton").button(); + + $("button", ".searchButton").click(function() { + return false; + }); + }); + + //'ui-tabs-1' is the cookie name which is used for the persistence of the tabs.(Content/Search tab) + if ($.cookie('ui-tabs-1') === '1') { //search tab is active + if ($.cookie('textToSearch') != undefined && $.cookie('textToSearch').length > 0) { + document.getElementById('textToSearch').value = $.cookie('textToSearch'); + Verifie('searchForm'); + searchHighlight($.cookie('textToSearch')); + $("#showHideHighlight").css("display", "block"); + } + } + + syncToc(); //Synchronize the toc tree with the content pane, when loading the page. + //$("#doSearch").button(); //add jquery button styling to 'Go' button + + // When you click on a link to an anchor, scroll down + // 120 px to cope with the fact that the banner + // hides the top 95px or so of the page. + // This code deals with the problem when + // you click on a link from another page. + var hash = window.location.hash; + if(hash){ + var targetOffset = $(hash).offset().top - 120; + $('html,body').animate({scrollTop: targetOffset}, 200); + return false; + } +}); + + +/** + * If an user moved to another page by clicking on a toc link, and then clicked on #searchDiv, + * search should be performed if the cookie textToSearch is not empty. + */ +function doSearch() { +//'ui-tabs-1' is the cookie name which is used for the persistence of the tabs.(Content/Search tab) + if ($.cookie('textToSearch') != undefined && $.cookie('textToSearch').length > 0) { + document.getElementById('textToSearch').value = $.cookie('textToSearch'); + Verifie('searchForm'); + } +} + +/** + * Synchronize with the tableOfContents + */ +function syncToc() { + var a = document.getElementById("webhelp-currentid"); + if (a != undefined) { + //Expanding the child sections of the selected node. + var nodeClass = a.getAttribute("class"); + if (nodeClass != null && !nodeClass.match(/collapsable/)) { + a.setAttribute("class", "collapsable"); + //remove display:none; css style from
          block in the selected node. + var ulNode = a.getElementsByTagName("ul")[0]; + if (ulNode != undefined) { + if (ulNode.hasAttribute("style")) { + ulNode.setAttribute("style", "display: block; background-color: #D8D8D8 !important;"); + } else { + var ulStyle = document.createAttribute("style"); + ulStyle.nodeValue = "display: block; background-color: #D8D8D8 !important;"; + ulNode.setAttributeNode(ulStyle); + } } + //adjust tree's + sign to - + var divNode = a.getElementsByTagName("div")[0]; + if (divNode != undefined) { + if (divNode.hasAttribute("class")) { + divNode.setAttribute("class", "hitarea collapsable-hitarea"); + } else { + var divClass = document.createAttribute("class"); + divClass.nodeValue = "hitarea collapsable-hitarea"; + divNode.setAttributeNode(divClass); + } } + //set persistence cookie when a node is auto expanded + // setCookieForExpandedNode("webhelp-currentid"); + } + var b = a.getElementsByTagName("a")[0]; + + if (b != undefined) { + //Setting the background for selected node. + var style = a.getAttribute("style", 2); + if (style != null && !style.match(/background-color: Background;/)) { + a.setAttribute("style", "background-color: #D8D8D8; " + style); + b.setAttribute("style", "color: black;"); + } else if (style != null) { + a.setAttribute("style", "background-color: #D8D8D8; " + style); + b.setAttribute("style", "color: black;"); + } else { + a.setAttribute("style", "background-color: #D8D8D8; "); + b.setAttribute("style", "color: black;"); + } + } + + //shows the node related to current content. + //goes a recursive call from current node to ancestor nodes, displaying all of them. + while (a.parentNode && a.parentNode.nodeName) { + var parentNode = a.parentNode; + var nodeName = parentNode.nodeName; + + if (nodeName.toLowerCase() == "ul") { + parentNode.setAttribute("style", "display: block;"); + } else if (nodeName.toLocaleLowerCase() == "li") { + parentNode.setAttribute("class", "collapsable"); + parentNode.firstChild.setAttribute("class", "hitarea collapsable-hitarea "); + } + a = parentNode; +} } } +/* + function setCookieForExpandedNode(nodeName) { + var tocDiv = document.getElementById("tree"); //get table of contents Div + var divs = tocDiv.getElementsByTagName("div"); + var matchedDivNumber; + var i; + for (i = 0; i < divs.length; i++) { //1101001 + var div = divs[i]; + var liNode = div.parentNode; + } +//create a new cookie if a treeview does not exist + if ($.cookie(treeCookieId) == null || $.cookie(treeCookieId) == "") { + var branches = $("#tree").find("li");//.prepareBranches(treesettings); + var data = []; + branches.each(function(i, e) { + data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0; + }); + $.cookie(treeCookieId, data.join("")); + + } + + if (i < divs.length) { + var treeviewCookie = $.cookie(treeCookieId); + var tvCookie1 = treeviewCookie.substring(0, i); + var tvCookie2 = treeviewCookie.substring(i + 1); + var newTVCookie = tvCookie1 + "1" + tvCookie2; + $.cookie(treeCookieId, newTVCookie); + } + } */ + +/** + * Code for Show/Hide TOC + * + */ +function showHideToc() { + var showHideButton = $("#showHideButton"); + var leftNavigation = $("#sidebar"); //hide the parent div of leftnavigation, ie sidebar + var content = $("#content"); + var animeTime=75 + + if (showHideButton != undefined && showHideButton.hasClass("pointLeft")) { + //Hide TOC + showHideButton.removeClass('pointLeft').addClass('pointRight'); + + if(noAnimations) { + leftNavigation.css("display", "none"); + content.css("margin", "125px 0 0 0"); + } else { + leftNavigation.hide(animeTime); + content.animate( { "margin-left": 0 }, animeTime); + } + showHideButton.attr("title", "Show Sidebar"); + } else { + //Show the TOC + showHideButton.removeClass('pointRight').addClass('pointLeft'); + if(noAnimations) { + content.css("margin", "125px 0 0 280px"); + leftNavigation.css("display", "block"); + } else { + content.animate( { "margin-left": '280px' }, animeTime); + leftNavigation.show(animeTime); + } + showHideButton.attr("title", "Hide Sidebar"); + } +} + +/** + * Code for search highlighting + */ +var highlightOn = true; +function searchHighlight(searchText) { + highlightOn = true; + if (searchText != undefined) { + var wList; + var sList = new Array(); //stem list + //Highlight the search terms + searchText = searchText.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, "There is no page containing all the search terms.
          Partial results:"; +var warningMsg = '
          '; +warningMsg+='Please note that due to security settings, Google Chrome does not highlight'; +warningMsg+=' the search results in the right frame.
          '; +warningMsg+='This happens only when the WebHelp files are loaded from the local file system.
          '; +warningMsg+='Workarounds:'; +warningMsg+='
            '; +warningMsg+='
          • Try using another web browser.
          • '; +warningMsg+='
          • Deploy the WebHelp files on a web server.
          • '; +warningMsg+='
          '; +txt_filesfound = 'Results'; +txt_enter_at_least_1_char = "You must enter at least one character."; +txt_enter_more_than_10_words = "Only first 10 words will be processed."; +txt_browser_not_supported = "Your browser is not supported. Use of Mozilla Firefox is recommended."; +txt_please_wait = "Please wait. Search in progress..."; +txt_results_for = "Results for: "; + +/* This function verify the validity of search input by the user + Cette fonction verifie la validite de la recherche entrre par l utilisateur */ +function Verifie(searchForm) { + + // Check browser compatibility + if (navigator.userAgent.indexOf("Konquerer") > -1) { + + alert(txt_browser_not_supported); + return; + } + + searchTextField = trim(document.searchForm.textToSearch.value); + searchTextField = searchTextField.replace(/['"]/g,''); + var expressionInput = searchTextField; + $.cookie('textToSearch', expressionInput); + + if (expressionInput.length < 1) { + + // expression is invalid + alert(txt_enter_at_least_1_char); + // reactive la fenetre de search (utile car cadres) + + document.searchForm.textToSearch.focus(); + } + else { + var splitSpace = searchTextField.split(" "); + var splitWords = []; + for (var i = 0 ; i < splitSpace.length ; i++) { + var splitDot = splitSpace[i].split("."); + + if(!(splitDot.length == 1)){ + splitWords.push(splitSpace[i]); + } + + for (var i1 = 0; i1 < splitDot.length; i1++) { + var splitColon = splitDot[i1].split(":"); + for (var i2 = 0; i2 < splitColon.length; i2++) { + var splitDash = splitColon[i2].split("-"); + for (var i3 = 0; i3 < splitDash.length; i3++) { + if (splitDash[i3].split("").length > 0) { + splitWords.push(splitDash[i3]); + } + } + } + } + } + noWords = splitWords; + if (noWords.length > 9){ + // Allow to search maximum 10 words + alert(txt_enter_more_than_10_words); + expressionInput = ''; + for (var x = 0 ; x < 10 ; x++){ + expressionInput = expressionInput + " " + noWords[x]; + } + Effectuer_recherche(expressionInput); + document.searchForm.textToSearch.focus(); + } else { + // Effectuer la recherche + expressionInput = ''; + for (var x = 0 ; x < noWords.length ; x++) { + expressionInput = expressionInput + " " + noWords[x]; + } + Effectuer_recherche(expressionInput); + // reactive la fenetre de search (utile car cadres) + document.searchForm.textToSearch.focus(); + } + } +} + +var stemQueryMap = new Array(); // A hashtable which maps stems to query words + +/* This function parses the search expression, loads the indices and displays the results*/ +function Effectuer_recherche(expressionInput) { + + /* Display a waiting message */ + //DisplayWaitingMessage(); + + /*data initialisation*/ + var searchFor = ""; // expression en lowercase et sans les caracte res speciaux + //w = new Object(); // hashtable, key=word, value = list of the index of the html files + scriptLetterTab = new Scriptfirstchar(); // Array containing the first letter of each word to look for + var wordsList = new Array(); // Array with the words to look for + var finalWordsList = new Array(); // Array with the words to look for after removing spaces + var linkTab = new Array(); + var fileAndWordList = new Array(); + var txt_wordsnotfound = ""; + + + // -------------------------------------- + // Begin Thu's patch + /*nqu: expressionInput, la recherche est lower cased, plus remplacement des char speciaux*/ + //The original replacement expression is: + //searchFor = expressionInput.toLowerCase().replace(/<\//g, "_st_").replace(/\$_/g, "_di_").replace(/\.|%2C|%3B|%21|%3A|@|\/|\*/g, " ").replace(/(%20)+/g, " ").replace(/_st_/g, " 0){ + var searchedWords = noWords.length; + var foundedWords = fileAndWordList[0][0].motslisteDisplay.split(",").length; + //console.info("search : " + noWords.length + " found : " + fileAndWordList[0][0].motslisteDisplay.split(",").length); + if (searchedWords != foundedWords){ + linkTab.push(partialSearch); + } + } + + + for (var i = 0; i < cpt; i++) { + + var hundredProcent = fileAndWordList[i][0].scoring + 100 * fileAndWordList[i][0].motsnb; + var ttScore_first = fileAndWordList[i][0].scoring; + var numberOfWords = fileAndWordList[i][0].motsnb; + + if (fileAndWordList[i] != undefined) { + linkTab.push("

          " + txt_results_for + " " + "" + fileAndWordList[i][0].motslisteDisplay + "" + "

          "); + + linkTab.push("
            "); + for (t in fileAndWordList[i]) { + //linkTab.push("
          • "+fl[fileAndWordList[i][t].filenb]+"
          • "); + + var ttInfo = fileAndWordList[i][t].filenb; + // Get scoring + var ttScore = fileAndWordList[i][t].scoring; + var tempInfo = fil[ttInfo]; + + var pos1 = tempInfo.indexOf("@@@"); + var pos2 = tempInfo.lastIndexOf("@@@"); + var tempPath = tempInfo.substring(0, pos1); + var tempTitle = tempInfo.substring(pos1 + 3, pos2); + var tempShortdesc = tempInfo.substring(pos2 + 3, tempInfo.length); + + + // toc.html will not be displayed on search result + if (tempPath == 'toc.html'){ + continue; + } + /* + //file:///home/kasun/docbook/WEBHELP/webhelp-draft-output-format-idea/src/main/resources/web/webhelp/installation.html + var linkString = "
          • " + tempTitle + ""; + // var linkString = "
          • " + tempTitle + ""; + */ + var split = fileAndWordList[i][t].motsliste.split(","); + // var splitedValues = expressionInput.split(" "); + // var finalArray = split.concat(splitedValues); + + arrayString = 'Array('; + for(var x in finalArray){ + if (finalArray[x].length > 2 || useCJKTokenizing){ + arrayString+= "'" + finalArray[x] + "',"; + } + } + arrayString = arrayString.substring(0,arrayString.length - 1) + ")"; + var idLink = 'foundLink' + no; + var linkString = '
          • ' + tempTitle + ''; + var starWidth = (ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent) * (numberOfWords/maxNumberOfWords); + starWidth = starWidth < 10 ? (starWidth + 5) : starWidth; + // Keep the 5 stars format + if (starWidth > 85){ + starWidth = 85; + } + /* + var noFullStars = Math.ceil(starWidth/17); + var fullStar = "curr"; + var emptyStar = ""; + if (starWidth % 17 == 0){ + // am stea plina + + } else { + + } + console.info(noFullStars); + */ + // Also check if we have a valid description + if ((tempShortdesc != "null" && tempShortdesc != '...')) { + + linkString += "\n
            " + tempShortdesc + "
            "; + } + linkString += "
          • "; + + // Add rating values for scoring at the list of matches + linkString += "
            "; + linkString += "
            "; + //linkString += "
            " + // + ((ttScore * 100/ hundredProcent)/(ttScore_first/hundredProcent)) * 1 + "
            "; + linkString += "
              "; + linkString += "
            • "; + linkString += "
            "; + + linkString += "
            "; + linkString += "
            "; + linkString += "
            "; + //linkString += 'Rating: ' + ttScore + ''; + + linkTab.push(linkString); + no++; + } + linkTab.push("
          "); + } + } + } + + var results = ""; + if (linkTab.length > 0) { + /*writeln ("

          " + txt_results_for + " " + "" + cleanwordsList + "" + "
          "+"

          ");*/ + results = "

          "; + //write("

            "); + for (t in linkTab) { + results += linkTab[t].toString(); + } + results += "

            "; + } else { + results = "

            " + localeresource.search_no_results + " " + txt_wordsnotfound + "" + "

            "; + } + + + // Verify if the browser is Google Chrome and the WebHelp is used on a local machine + // If browser is Google Chrome and WebHelp is used on a local machine a warning message will appear + // Highlighting will not work in this conditions. There is 2 workarounds + if (verifyBrowser()){ + document.getElementById('searchResults').innerHTML = results; + } else { + document.getElementById('searchResults').innerHTML = warningMsg + results; + } + +} + + +// Verify if the stemmed word is aproximately the same as the searched word +function verifyWord(word, arr){ + for (var i = 0 ; i < arr.length ; i++){ + if (word[0] == arr[i][0] + && word[1] == arr[i][1] + //&& word[2] == arr[i][2] + ){ + return true; + } + } + return false; +} + +// Look for elements that start with searchedValue. +function wordsStartsWith(searchedValue){ + var toReturn = ''; + for (var sv in w){ + if (searchedValue.length < 3){ + continue; + } else { + if (sv.toLowerCase().indexOf(searchedValue.toLowerCase()) == 0){ + toReturn+=sv + ","; + } + } + } + return toReturn.length > 0 ? toReturn : undefined; +} + + +function tokenize(wordsList){ + var stemmedWordsList = new Array(); // Array with the words to look for after removing spaces + var cleanwordsList = new Array(); // Array with the words to look for + // ------------------------------------------------- + // Thu's patch + for(var j=0;j"; + return this.input.substring(this.offset,this.offset+2); + } + + function getAllTokens(){ + while(this.incrementToken()){ + var tmp = this.tokenize(); + this.tokens.push(tmp); + } + return this.unique(this.tokens); +// document.getElementById("content").innerHTML += tokens+" "; +// document.getElementById("content").innerHTML += "
            dada"+sortedTokens+" "; +// console.log(tokens.length+"dsdsds"); + /*for(i=0;i t2.length) { + return 1; + } else { + return -1; + } + //return t1.length - t2.length); +} + +// return false if browser is Google Chrome and WebHelp is used on a local machine, not a web server +function verifyBrowser(){ + var returnedValue = true; + var browser = BrowserDetect.browser; + var addressBar = window.location.href; + if (browser == 'Chrome' && addressBar.indexOf('file://') === 0){ + returnedValue = false; + } + + return returnedValue; +} + +// Remove duplicate values from an array +function removeDuplicate(arr) { + var r = new Array(); + o:for(var i = 0, n = arr.length; i < n; i++) { + for(var x = 0, y = r.length; x < y; x++) { + if(r[x]==arr[i]) continue o; + } + r[r.length] = arr[i]; + } + return r; +} + +// Create startsWith method +String.prototype.startsWith = function(str) { + return (this.match("^"+str)==str); +} + +function trim(str, chars) { + return ltrim(rtrim(str, chars), chars); +} + +function ltrim(str, chars) { + chars = chars || "\\s"; + return str.replace(new RegExp("^[" + chars + "]+", "g"), ""); +} + +function rtrim(str, chars) { + chars = chars || "\\s"; + return str.replace(new RegExp("[" + chars + "]+$", "g"), ""); +} diff --git a/src/doc/user/webhelp/template/search/punctuation.props b/src/doc/user/webhelp/template/search/punctuation.props new file mode 100644 index 00000000..d3e3fcd2 --- /dev/null +++ b/src/doc/user/webhelp/template/search/punctuation.props @@ -0,0 +1,31 @@ +Punct01=\\u3002 +Punct02=\\u3003 +Punct03=\\u300C +Punct04=\\u300D +Punct05=\\u300E +Punct06=\\u300F +Punct07=\\u301D +Punct08=\\u301E +Punct09=\\u301F +Punct10=\\u309B +Punct11=\\u2018 +Punct12=\\u2019 +Punct13=\\u201A +Punct14=\\u201C +Punct15=\\u201D +Punct16=\\u201E +Punct17=\\u2032 +Punct18=\\u2033 +Punct19=\\u2035 +Punct20=\\u2039 +Punct21=\\u203A +Punct22=\\u201E +Punct23=\\u00BB +Punct24=\\u00AB +Punct25= +Punct26= +Punct27=\\u00A0 +Punct28=\\u2014 + + + diff --git a/src/doc/user/webhelp/template/search/stemmers/de_stemmer.js b/src/doc/user/webhelp/template/search/stemmers/de_stemmer.js new file mode 100644 index 00000000..7ff3822a --- /dev/null +++ b/src/doc/user/webhelp/template/search/stemmers/de_stemmer.js @@ -0,0 +1,247 @@ +/* + * Author: Joder Illi + * + * Copyright (c) 2010, FormBlitz AG + * All rights reserved. + * Implementation of the stemming algorithm from http://snowball.tartarus.org/algorithms/german/stemmer.html + * Copyright of the algorithm is: Copyright (c) 2001, Dr Martin Porter and can be found at http://snowball.tartarus.org/license.php + * + * Redistribution and use in source and binary forms, with or without modification, is covered by the standard BSD license. + * + */ + +//var stemmer = function Stemmer() { + /* + German includes the following accented forms, + ä ö ü + and a special letter, ß, equivalent to double s. + The following letters are vowels: + a e i o u y ä ö ü + */ + + var stemmer = function(word) { + /* + Put u and y between vowels into upper case + */ + word = word.replace(/([aeiouyäöü])u([aeiouyäöü])/g, '$1U$2'); + word = word.replace(/([aeiouyäöü])y([aeiouyäöü])/g, '$1Y$2'); + + /* + and then do the following mappings, + (a) replace ß with ss, + (a) replace ae with ä, Not doing these, have trouble with diphtongs + (a) replace oe with ö, Not doing these, have trouble with diphtongs + (a) replace ue with ü unless preceded by q. Not doing these, have trouble with diphtongs + So in quelle, ue is not mapped to ü because it follows q, and in feuer it is not mapped because the first part of the rule changes it to feUer, so the u is not found. + */ + word = word.replace(/ß/g, 'ss'); + //word = word.replace(/ae/g, 'ä'); + //word = word.replace(/oe/g, 'ö'); + //word = word.replace(/([^q])ue/g, '$1ü'); + + /* + R1 and R2 are first set up in the standard way (see the note on R1 and R2), but then R1 is adjusted so that the region before it contains at least 3 letters. + R1 is the region after the first non-vowel following a vowel, or is the null region at the end of the word if there is no such non-vowel. + R2 is the region after the first non-vowel following a vowel in R1, or is the null region at the end of the word if there is no such non-vowel. + */ + + var r1Index = word.search(/[aeiouyäöü][^aeiouyäöü]/); + var r1 = ''; + if (r1Index != -1) { + r1Index += 2; + r1 = word.substring(r1Index); + } + + var r2Index = -1; + var r2 = ''; + + if (r1Index != -1) { + var r2Index = r1.search(/[aeiouyäöü][^aeiouyäöü]/); + if (r2Index != -1) { + r2Index += 2; + r2 = r1.substring(r2Index); + r2Index += r1Index; + } else { + r2 = ''; + } + } + + if (r1Index != -1 && r1Index < 3) { + r1Index = 3; + r1 = word.substring(r1Index); + } + + /* + Define a valid s-ending as one of b, d, f, g, h, k, l, m, n, r or t. + Define a valid st-ending as the same list, excluding letter r. + */ + + /* + Do each of steps 1, 2 and 3. + */ + + /* + Step 1: + Search for the longest among the following suffixes, + (a) em ern er + (b) e en es + (c) s (preceded by a valid s-ending) + */ + var a1Index = word.search(/(em|ern|er)$/g); + var b1Index = word.search(/(e|en|es)$/g); + var c1Index = word.search(/([bdfghklmnrt]s)$/g); + if (c1Index != -1) { + c1Index++; + } + var index1 = 10000; + var optionUsed1 = ''; + if (a1Index != -1 && a1Index < index1) { + optionUsed1 = 'a'; + index1 = a1Index; + } + if (b1Index != -1 && b1Index < index1) { + optionUsed1 = 'b'; + index1 = b1Index; + } + if (c1Index != -1 && c1Index < index1) { + optionUsed1 = 'c'; + index1 = c1Index; + } + + /* + and delete if in R1. (Of course the letter of the valid s-ending is not necessarily in R1.) If an ending of group (b) is deleted, and the ending is preceded by niss, delete the final s. + (For example, äckern -> äck, ackers -> acker, armes -> arm, bedürfnissen -> bedürfnis) + */ + + if (index1 != 10000 && r1Index != -1) { + if (index1 >= r1Index) { + word = word.substring(0, index1); + if (optionUsed1 == 'b') { + if (word.search(/niss$/) != -1) { + word = word.substring(0, word.length -1); + } + } + } + } + /* + Step 2: + Search for the longest among the following suffixes, + (a) en er est + (b) st (preceded by a valid st-ending, itself preceded by at least 3 letters) + */ + + var a2Index = word.search(/(en|er|est)$/g); + var b2Index = word.search(/(.{3}[bdfghklmnt]st)$/g); + if (b2Index != -1) { + b2Index += 4; + } + + var index2 = 10000; + var optionUsed2 = ''; + if (a2Index != -1 && a2Index < index2) { + optionUsed2 = 'a'; + index2 = a2Index; + } + if (b2Index != -1 && b2Index < index2) { + optionUsed2 = 'b'; + index2 = b2Index; + } + + /* + and delete if in R1. + (For example, derbsten -> derbst by step 1, and derbst -> derb by step 2, since b is a valid st-ending, and is preceded by just 3 letters) + */ + + if (index2 != 10000 && r1Index != -1) { + if (index2 >= r1Index) { + word = word.substring(0, index2); + } + } + + /* + Step 3: d-suffixes (*) + Search for the longest among the following suffixes, and perform the action indicated. + end ung + delete if in R2 + if preceded by ig, delete if in R2 and not preceded by e + ig ik isch + delete if in R2 and not preceded by e + lich heit + delete if in R2 + if preceded by er or en, delete if in R1 + keit + delete if in R2 + if preceded by lich or ig, delete if in R2 + */ + + var a3Index = word.search(/(end|ung)$/g); + var b3Index = word.search(/[^e](ig|ik|isch)$/g); + var c3Index = word.search(/(lich|heit)$/g); + var d3Index = word.search(/(keit)$/g); + if (b3Index != -1) { + b3Index ++; + } + + var index3 = 10000; + var optionUsed3 = ''; + if (a3Index != -1 && a3Index < index3) { + optionUsed3 = 'a'; + index3 = a3Index; + } + if (b3Index != -1 && b3Index < index3) { + optionUsed3 = 'b'; + index3 = b3Index; + } + if (c3Index != -1 && c3Index < index3) { + optionUsed3 = 'c'; + index3 = c3Index; + } + if (d3Index != -1 && d3Index < index3) { + optionUsed3 = 'd'; + index3 = d3Index; + } + + if (index3 != 10000 && r2Index != -1) { + if (index3 >= r2Index) { + word = word.substring(0, index3); + var optionIndex = -1; + var optionSubsrt = ''; + if (optionUsed3 == 'a') { + optionIndex = word.search(/[^e](ig)$/); + if (optionIndex != -1) { + optionIndex++; + if (optionIndex >= r2Index) { + word = word.substring(0, optionIndex); + } + } + } else if (optionUsed3 == 'c') { + optionIndex = word.search(/(er|en)$/); + if (optionIndex != -1) { + if (optionIndex >= r1Index) { + word = word.substring(0, optionIndex); + } + } + } else if (optionUsed3 == 'd') { + optionIndex = word.search(/(lich|ig)$/); + if (optionIndex != -1) { + if (optionIndex >= r2Index) { + word = word.substring(0, optionIndex); + } + } + } + } + } + + /* + Finally, + turn U and Y back into lower case, and remove the umlaut accent from a, o and u. + */ + word = word.replace(/U/g, 'u'); + word = word.replace(/Y/g, 'y'); + word = word.replace(/ä/g, 'a'); + word = word.replace(/ö/g, 'o'); + word = word.replace(/ü/g, 'u'); + + return word; + }; +//} \ No newline at end of file diff --git a/src/doc/user/webhelp/template/search/stemmers/en_stemmer.js b/src/doc/user/webhelp/template/search/stemmers/en_stemmer.js new file mode 100644 index 00000000..2117c1bf --- /dev/null +++ b/src/doc/user/webhelp/template/search/stemmers/en_stemmer.js @@ -0,0 +1,234 @@ +// Porter stemmer in Javascript. Few comments, but it's easy to follow against the rules in the original +// paper, in +// +// Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14, +// no. 3, pp 130-137, +// +// see also http://www.tartarus.org/~martin/PorterStemmer + +// Release 1 +// Derived from (http://tartarus.org/~martin/PorterStemmer/js.txt) - cjm (iizuu) Aug 24, 2009 + +var stemmer = (function(){ + var step2list = { + "ational" : "ate", + "tional" : "tion", + "enci" : "ence", + "anci" : "ance", + "izer" : "ize", + "bli" : "ble", + "alli" : "al", + "entli" : "ent", + "eli" : "e", + "ousli" : "ous", + "ization" : "ize", + "ation" : "ate", + "ator" : "ate", + "alism" : "al", + "iveness" : "ive", + "fulness" : "ful", + "ousness" : "ous", + "aliti" : "al", + "iviti" : "ive", + "biliti" : "ble", + "logi" : "log" + }, + + step3list = { + "icate" : "ic", + "ative" : "", + "alize" : "al", + "iciti" : "ic", + "ical" : "ic", + "ful" : "", + "ness" : "" + }, + + c = "[^aeiou]", // consonant + v = "[aeiouy]", // vowel + C = c + "[^aeiouy]*", // consonant sequence + V = v + "[aeiou]*", // vowel sequence + + mgr0 = "^(" + C + ")?" + V + C, // [C]VC... is m>0 + meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$", // [C]VC[V] is m=1 + mgr1 = "^(" + C + ")?" + V + C + V + C, // [C]VCVC... is m>1 + s_v = "^(" + C + ")?" + v; // vowel in stem + + return function (w) { + var stem, + suffix, + firstch, + re, + re2, + re3, + re4, + origword = w; + + if (w.length < 3) { return w; } + + firstch = w.substr(0,1); + if (firstch == "y") { + w = firstch.toUpperCase() + w.substr(1); + } + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) { w = w.replace(re,"$1$2"); } + else if (re2.test(w)) { w = w.replace(re2,"$1$2"); } + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) { w = w + "e"; } + else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } + else if (re4.test(w)) { w = w + "e"; } + } + } + + // Step 1c + re = new RegExp("^(.+" + c + ")y$"); + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) { + w = stem + step2list[suffix]; + } + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) { + w = stem + step3list[suffix]; + } + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) { + w = stem; + } + } else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) { + w = stem; + } + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) { + w = stem; + } + } + + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + + if (firstch == "y") { + w = firstch.toLowerCase() + w.substr(1); + } + + // See http://snowball.tartarus.org/algorithms/english/stemmer.html + // "Exceptional forms in general" + var specialWords = { + "skis" : "ski", + "skies" : "sky", + "dying" : "die", + "lying" : "lie", + "tying" : "tie", + "idly" : "idl", + "gently" : "gentl", + "ugly" : "ugli", + "early": "earli", + "only": "onli", + "singly": "singl" + }; + + if(specialWords[origword]){ + w = specialWords[origword]; + } + + if( "sky news howe atlas cosmos bias \ + andes inning outing canning herring \ + earring proceed exceed succeed".indexOf(origword) !== -1 ){ + w = origword; + } + + // Address words overstemmed as gener- + re = /.*generate?s?d?(ing)?$/; + if( re.test(origword) ){ + w = w + 'at'; + } + re = /.*general(ly)?$/; + if( re.test(origword) ){ + w = w + 'al'; + } + re = /.*generic(ally)?$/; + if( re.test(origword) ){ + w = w + 'ic'; + } + re = /.*generous(ly)?$/; + if( re.test(origword) ){ + w = w + 'ous'; + } + // Address words overstemmed as commun- + re = /.*communit(ies)?y?/; + if( re.test(origword) ){ + w = w + 'iti'; + } + + return w; + } +})(); diff --git a/src/doc/user/webhelp/template/search/stemmers/fr_stemmer.js b/src/doc/user/webhelp/template/search/stemmers/fr_stemmer.js new file mode 100644 index 00000000..34f97431 --- /dev/null +++ b/src/doc/user/webhelp/template/search/stemmers/fr_stemmer.js @@ -0,0 +1,299 @@ +/* + * Author: Kasun Gajasinghe + * E-Mail: kasunbg AT gmail DOT com + * Date: 09.08.2010 + * + * usage: stemmer(word); + * ex: var stem = stemmer(foobar); + * Implementation of the stemming algorithm from http://snowball.tartarus.org/algorithms/french/stemmer.html + * + * LICENSE: + * + * Copyright (c) 2010, Kasun Gajasinghe. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * + * THIS SOFTWARE IS PROVIDED BY KASUN GAJASINGHE ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KASUN GAJASINGHE BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +var stemmer = function(word){ +// Letters in French include the following accented forms, +// â à ç ë é ê è ï î ô û ù +// The following letters are vowels: +// a e i o u y â à ë é ê è ï î ô û ù + + word = word.toLowerCase(); + var oriWord = word; + word = word.replace(/qu/g, 'qU'); //have to perform first, as after the operation, capital U is not treated as a vowel + word = word.replace(/([aeiouyâàëéêèïîôûù])u([aeiouyâàëéêèïîôûù])/g, '$1U$2'); + word = word.replace(/([aeiouyâàëéêèïîôûù])i([aeiouyâàëéêèïîôûù])/g, '$1I$2'); + word = word.replace(/([aeiouyâàëéêèïîôûù])y/g, '$1Y'); + word = word.replace(/y([aeiouyâàëéêèïîôûù])/g, 'Y$1'); + + var rv=''; + var rvIndex = -1; + if(word.search(/^(par|col|tap)/) != -1 || word.search(/^[aeiouyâàëéêèïîôûù]{2}/) != -1){ + rv = word.substring(3); + rvIndex = 3; + } else { + rvIndex = word.substring(1).search(/[aeiouyâàëéêèïîôûù]/); + if(rvIndex != -1){ + rvIndex +=2; //+2 is to supplement the substring(1) used to find rvIndex + rv = word.substring(rvIndex); + } else { + rvIndex = word.length; + } + } + +// R1 is the region after the first non-vowel following a vowel, or the end of the word if there is no such non-vowel. +// R2 is the region after the first non-vowel following a vowel in R1, or the end of the word if there is no such non-vowel + var r1Index = word.search(/[aeiouyâàëéêèïîôûù][^aeiouyâàëéêèïîôûù]/); + var r1 = ''; + if (r1Index != -1) { + r1Index += 2; + r1 = word.substring(r1Index); + } else { + r1Index = word.length; + } + + var r2Index = -1; + var r2 = ''; + if (r1Index != -1) { + r2Index = r1.search(/[aeiouyâàëéêèïîôûù][^aeiouyâàëéêèïîôûù]/); + if (r2Index != -1) { + r2Index += 2; + r2 = r1.substring(r2Index); + r2Index += r1Index; + } else { + r2 = ''; + r2Index = word.length; + } + } + if (r1Index != -1 && r1Index < 3) { + r1Index = 3; + r1 = word.substring(r1Index); + } + + /* + Step 1: Standard suffix removal + */ + var a1Index = word.search(/(ance|iqUe|isme|able|iste|eux|ances|iqUes|ismes|ables|istes)$/); + var a2Index = word.search(/(atrice|ateur|ation|atrices|ateurs|ations)$/); + var a3Index = word.search(/(logie|logies)$/); + var a4Index = word.search(/(usion|ution|usions|utions)$/); + var a5Index = word.search(/(ence|ences)$/); + var a6Index = word.search(/(ement|ements)$/); + var a7Index = word.search(/(ité|ités)$/); + var a8Index = word.search(/(if|ive|ifs|ives)$/); + var a9Index = word.search(/(eaux)$/); + var a10Index = word.search(/(aux)$/); + var a11Index = word.search(/(euse|euses)$/); + var a12Index = word.search(/[^aeiouyâàëéêèïîôûù](issement|issements)$/); + var a13Index = word.search(/(amment)$/); + var a14Index = word.search(/(emment)$/); + var a15Index = word.search(/[aeiouyâàëéêèïîôûù](ment|ments)$/); + + if(a1Index != -1 && a1Index >= r2Index){ + word = word.substring(0,a1Index); + } else if(a2Index != -1 && a2Index >= r2Index){ + word = word.substring(0,a2Index); + var a2Index2 = word.search(/(ic)$/); + if(a2Index2 != -1 && a2Index2 >= r2Index){ + word = word.substring(0, a2Index2); //if preceded by ic, delete if in R2, + } else { //else replace by iqU + word = word.replace(/(ic)$/,'iqU'); + } + } else if(a3Index != -1 && a3Index >= r2Index){ + word = word.replace(/(logie|logies)$/,'log'); //replace with log if in R2 + } else if(a4Index != -1 && a4Index >= r2Index){ + word = word.replace(/(usion|ution|usions|utions)$/,'u'); //replace with u if in R2 + } else if(a5Index != -1 && a5Index >= r2Index){ + word = word.replace(/(ence|ences)$/,'ent'); //replace with ent if in R2 + } else if(a6Index != -1 && a6Index >= rvIndex){ + word = word.substring(0,a6Index); + if(word.search(/(iv)$/) >= r2Index){ + word = word.replace(/(iv)$/, ''); + if(word.search(/(at)$/) >= r2Index){ + word = word.replace(/(at)$/, ''); + } + } else if(word.search(/(eus)$/) != -1){ + var a6Index2 = word.search(/(eus)$/); + if(a6Index2 >=r2Index){ + word = word.substring(0, a6Index2); + } else if(a6Index2 >= r1Index){ + word = word.substring(0,a6Index2)+"eux"; + } + } else if(word.search(/(abl|iqU)$/) >= r2Index){ + word = word.replace(/(abl|iqU)$/,''); //if preceded by abl or iqU, delete if in R2, + } else if(word.search(/(ièr|Ièr)$/) >= rvIndex){ + word = word.replace(/(ièr|Ièr)$/,'i'); //if preceded by abl or iqU, delete if in R2, + } + } else if(a7Index != -1 && a7Index >= r2Index){ + word = word.substring(0,a7Index); //delete if in R2 + if(word.search(/(abil)$/) != -1){ //if preceded by abil, delete if in R2, else replace by abl, otherwise, + var a7Index2 = word.search(/(abil)$/); + if(a7Index2 >=r2Index){ + word = word.substring(0, a7Index2); + } else { + word = word.substring(0,a7Index2)+"abl"; + } + } else if(word.search(/(ic)$/) != -1){ + var a7Index3 = word.search(/(ic)$/); + if(a7Index3 != -1 && a7Index3 >= r2Index){ + word = word.substring(0, a7Index3); //if preceded by ic, delete if in R2, + } else { //else replace by iqU + word = word.replace(/(ic)$/,'iqU'); + } + } else if(word.search(/(iv)$/) != r2Index){ + word = word.replace(/(iv)$/,''); + } + } else if(a8Index != -1 && a8Index >= r2Index){ + word = word.substring(0,a8Index); + if(word.search(/(at)$/) >= r2Index){ + word = word.replace(/(at)$/, ''); + if(word.search(/(ic)$/) >= r2Index){ + word = word.replace(/(ic)$/, ''); + } else { word = word.replace(/(ic)$/, 'iqU'); } + } + } else if(a9Index != -1){ word = word.replace(/(eaux)/,'eau') + } else if(a10Index >= r1Index){ word = word.replace(/(aux)/,'al') + } else if(a11Index != -1 ){ + var a11Index2 = word.search(/(euse|euses)$/); + if(a11Index2 >=r2Index){ + word = word.substring(0, a11Index2); + } else if(a11Index2 >= r1Index){ + word = word.substring(0, a11Index2)+"eux"; + } + } else if(a12Index!=-1 && a12Index>=r1Index){ + word = word.substring(0,a12Index+1); //+1- amendment to non-vowel + } else if(a13Index!=-1 && a13Index>=rvIndex){ + word = word.replace(/(amment)$/,'ant'); + } else if(a14Index!=-1 && a14Index>=rvIndex){ + word = word.replace(/(emment)$/,'ent'); + } else if(a15Index!=-1 && a15Index>=rvIndex){ + word = word.substring(0,a15Index+1); + } + + /* Step 2a: Verb suffixes beginning i*/ + var wordStep1 = word; + var step2aDone = false; + if(oriWord == word.toLowerCase() || oriWord.search(/(amment|emment|ment|ments)$/) != -1){ + step2aDone = true; + var b1Regex = /([^aeiouyâàëéêèïîôûù])(îmes|ît|îtes|i|ie|ies|ir|ira|irai|iraIent|irais|irait|iras|irent|irez|iriez|irions|irons|iront|is|issaIent|issais|issait|issant|issante|issantes|issants|isse|issent|isses|issez|issiez|issions|issons|it)$/i; + if(word.search(b1Regex) >= rvIndex){ + word = word.replace(b1Regex,'$1'); + } + } + + /* Step 2b: Other verb suffixes*/ + if (step2aDone && wordStep1 == word) { + if (word.search(/(ions)$/) >= r2Index) { + word = word.replace(/(ions)$/, ''); + } else { + var b2Regex = /(é|ée|ées|és|èrent|er|era|erai|eraIent|erais|erait|eras|erez|eriez|erions|erons|eront|ez|iez)$/i; + if (word.search(b2Regex) >= rvIndex) { + word = word.replace(b2Regex, ''); + } else { + var b3Regex = /e(âmes|ât|âtes|a|ai|aIent|ais|ait|ant|ante|antes|ants|as|asse|assent|asses|assiez|assions)$/i; + if (word.search(b3Regex) >= rvIndex) { + word = word.replace(b3Regex, ''); + } else { + var b3Regex2 = /(âmes|ât|âtes|a|ai|aIent|ais|ait|ant|ante|antes|ants|as|asse|assent|asses|assiez|assions)$/i; + if (word.search(b3Regex2) >= rvIndex) { + word = word.replace(b3Regex2, ''); + } + } + } + } + } + + if(oriWord != word.toLowerCase()){ + /* Step 3 */ + var rep = ''; + if(word.search(/Y$/) != -1) { + word = word.replace(/Y$/, 'i'); + } else if(word.search(/ç$/) != -1){ + word = word.replace(/ç$/, 'c'); + } + } else { + /* Step 4 */ + //If the word ends s, not preceded by a, i, o, u, è or s, delete it. + if (word.search(/([^aiouès])s$/) >= rvIndex) { + word = word.replace(/([^aiouès])s$/, '$1'); + } + var e1Index = word.search(/ion$/); + if (e1Index >= r2Index && word.search(/[st]ion$/) >= rvIndex) { + word = word.substring(0, e1Index); + } else { + var e2Index = word.search(/(ier|ière|Ier|Ière)$/); + if (e2Index != -1 && e2Index >= rvIndex) { + word = word.substring(0, e2Index) + "i"; + } else { + if (word.search(/e$/) >= rvIndex) { + word = word.replace(/e$/, ''); //delete last e + } else if (word.search(/guë$/) >= rvIndex) { + word = word.replace(/guë$/, 'gu'); + } + } + } + } + + /* Step 5: Undouble */ + //word = word.replace(/(en|on|et|el|eil)(n|t|l)$/,'$1'); + word = word.replace(/(en|on)(n)$/,'$1'); + word = word.replace(/(ett)$/,'et'); + word = word.replace(/(el|eil)(l)$/,'$1'); + + /* Step 6: Un-accent */ + word = word.replace(/[éè]([^aeiouyâàëéêèïîôûù]+)$/,'e$1'); + word = word.toLowerCase(); + return word; +}; + +var eqOut = new Array(); +var noteqOut = new Array(); +var eqCount = 0; +/* +To test the stemming, create two arrays named "voc" and "COut" which are for vocabualary and the stemmed output. +Then add the vocabulary strings and output strings. This method will generate the stemmed output for "voc" and will +compare the output with COut. + (I used porter's voc and out files and did a regex to convert them to js objects. regex: /");\nvoc.push("/g . This + will add strings to voc array such that output would look like: voc.push("foobar"); ) drop me an email for any help. + */ +function testFr(){ + var start = new Date().getTime(); //execution time + eqCount = 0; + eqOut = new Array(); + noteqOut = new Array(); + for(var k=0;k filtertmp && mv -f filtertmp $filter && chmod a+x $filter +done diff --git a/src/filters/msodump.zip b/src/filters/msodump.zip new file mode 100644 index 00000000..a1b6d9e6 Binary files /dev/null and b/src/filters/msodump.zip differ diff --git a/src/filters/ppt-dump.py b/src/filters/ppt-dump.py new file mode 100755 index 00000000..a84eec79 --- /dev/null +++ b/src/filters/ppt-dump.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python2 +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +# mso-dumper is not compatible with python3 + +from __future__ import print_function + +import sys, os.path, getopt +sys.path.append(sys.path[0]+"/msodump.zip") +from msodumper import ole, pptstream, globals, olestream +from msodumper.globals import error + +def usage (exname): + exname = os.path.basename(exname) + msg = """Usage: %s [options] [ppt file] + +Options: + --help displays this help message. + --no-struct-output suppress normal structure analysis output + --dump-text extract and print the textual content + --no-raw-dumps suppress raw hex dumps of uninterpreted areas + --id-select=id1[,id2 ...] limit output to selected record Ids +""" % exname + print(msg) + + +class PPTDumper(object): + + def __init__ (self, filepath, params): + self.filepath = filepath + self.params = params + + def __printDirHeader (self, dirname, byteLen): + dirname = globals.encodeName(dirname) + globals.outputln("") + globals.outputln("="*68) + globals.outputln("%s (size: %d bytes)"%(dirname, byteLen)) + globals.outputln("-"*68) + + def dump (self): + file = open(self.filepath, 'rb') + strm = pptstream.PPTFile(file.read(), self.params) + file.close() + strm.printStreamInfo() + strm.printHeader() + strm.printDirectory() + dirnames = strm.getDirectoryNames() + result = True + for dirname in dirnames: + if len(dirname) == 0 or dirname == 'Root Entry': + continue + + try: + dirstrm = strm.getDirectoryStreamByName(dirname) + except Exception as err: + error("getDirectoryStreamByName(%s): %s - %s\n" % (dirname,str(err),self.filepath)) + # The previous version was killed by the exception + # here, so the equivalent is to break, but maybe there + # is no reason to do so. + break + self.__printDirHeader(dirname, len(dirstrm.bytes)) + if dirname == "PowerPoint Document": + if not self.__readSubStream(dirstrm): + result = False + elif dirname == "Current User": + if not self.__readSubStream(dirstrm): + result = False + elif dirname == "\x05DocumentSummaryInformation": + strm = olestream.PropertySetStream(dirstrm.bytes) + strm.read() + else: + globals.dumpBytes(dirstrm.bytes, 512) + return result + + def __readSubStream (self, strm): + # read all records in substream + return strm.readRecords() + + +def main (args): + exname, args = args[0], args[1:] + if len(args) < 1: + print("takes at least one argument") + usage(exname) + return + + try: + opts, args = getopt.getopt(args, "h", + ["help", "debug", "show-sector-chain", + "no-struct-output", "dump-text", + "id-select=", "no-raw-dumps"]) + for opt, arg in opts: + if opt in ['-h', '--help']: + usage(exname) + return + elif opt in ['--debug']: + globals.params.debug = True + elif opt in ['--show-sector-chain']: + globals.params.showSectorChain = True + elif opt in ['--no-struct-output']: + globals.params.noStructOutput = True + elif opt in ['--dump-text']: + globals.params.dumpText = True + elif opt in ['--no-raw-dumps']: + globals.params.noRawDumps = True + elif opt in ['--id-select']: + globals.params.dumpedIds = arg.split(",") + globals.params.dumpedIds = \ + set([int(val) for val in globals.params.dumpedIds if val]) + else: + error("unknown option %s\n"%opt) + usage() + + except getopt.GetoptError: + error("error parsing input options\n") + usage(exname) + return false + + status = True + try: + dumper = PPTDumper(args[0], globals.params) + if not dumper.dump(): + error("ppt-dump: dump error " + args[0] + "\n") + status = False + except: + error("ppt-dump: FAILURE (bad format?) " + args[0] + "\n") + status = False + + if globals.params.dumpText: + print(globals.textdump.replace("\r", "\n")) + return(status) + +if __name__ == '__main__': + if main(sys.argv): + sys.exit(0) + else: + sys.exit(1) + +# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab: diff --git a/src/filters/rcl7z b/src/filters/rcl7z new file mode 100755 index 00000000..2af73ae6 --- /dev/null +++ b/src/filters/rcl7z @@ -0,0 +1,125 @@ +#!/usr/bin/env python + +# 7-Zip file filter for Recoll + +# Thanks to Recoll user Martin Ziegler +# This is a modified version of rclzip, with some help from rcltar +# Python pylzma library required. See http://www.joachim-bauch.de/projects/pylzma/ + +import sys +import os +import fnmatch +import rclexecm + +try: + import pylzma + from py7zlib import Archive7z +except: + print("RECFILTERROR HELPERNOTFOUND python:pylzma") + sys.exit(1); + +try: + from recoll import rclconfig + hasrclconfig = True +except: + hasrclconfig = False +# As a temporary measure, we also look for rclconfig as a bare +# module. This is so that the intermediate releases of the filter can +# ship and use rclconfig.py with the filter code +if not hasrclconfig: + try: + import rclconfig + hasrclconfig = True + except: + pass + +class SevenZipExtractor: + def __init__(self, em): + self.currentindex = 0 + self.em = em + + def extractone(self, ipath): + #self.em.rclog("extractone: [%s]" % ipath) + docdata = b'' + try: + docdata = self.sevenzip.getmember(ipath).read() + ok = True + except Exception as err: + self.em.rclog("extractone: failed: [%s]" % err) + ok = False + iseof = rclexecm.RclExecM.noteof + if self.currentindex >= len(self.sevenzip.getnames()) -1: + iseof = rclexecm.RclExecM.eofnext + return (ok, docdata, rclexecm.makebytes(ipath), iseof) + + ###### File type handler api, used by rclexecm ----------> + def openfile(self, params): + filename = params["filename:"] + self.currentindex = -1 + self.skiplist = [] + + if hasrclconfig: + config = rclconfig.RclConfig() + config.setKeyDir(os.path.dirname(filename)) + skipped = config.getConfParam("zipSkippedNames") + if skipped is not None: + self.skiplist = skipped.split(" ") + + try: + fp = open(filename, 'rb') + self.sevenzip = Archive7z(fp) + return True + except Exception as err: + self.em.rclog("openfile: failed: [%s]" % err) + return False + + def getipath(self, params): + ipath = params["ipath:"] + ok, data, ipath, eof = self.extractone(ipath) + if ok: + return (ok, data, ipath, eof) + # Not found. Maybe we need to decode the path? + try: + ipath = ipath.decode("utf-8") + return self.extractone(ipath) + except Exception as err: + return (ok, data, ipath, eof) + + def getnext(self, params): + if self.currentindex == -1: + # Return "self" doc + self.currentindex = 0 + self.em.setmimetype('text/plain') + if len(self.sevenzip.getnames()) == 0: + eof = rclexecm.RclExecM.eofnext + else: + eof = rclexecm.RclExecM.noteof + return (True, "", "", eof) + + if self.currentindex >= len(self.sevenzip.getnames()): + #self.em.rclog("getnext: EOF hit") + return (False, "", "", rclexecm.RclExecM.eofnow) + else: + entryname = self.sevenzip.getnames()[self.currentindex] + + if hasrclconfig and len(self.skiplist) != 0: + while self.currentindex < len(self.sevenzip.getnames()): + entryname = self.sevenzip.getnames()[self.currentindex] + for pat in self.skiplist: + if fnmatch.fnmatch(entryname, pat): + entryname = None + break + if entryname is not None: + break + self.currentindex += 1 + if entryname is None: + return (False, "", "", rclexecm.RclExecM.eofnow) + + ret= self.extractone(entryname) + self.currentindex += 1 + return ret + +# Main program: create protocol handler and extractor and run them +proto = rclexecm.RclExecM() +extract = SevenZipExtractor(proto) +rclexecm.main(proto, extract) diff --git a/src/filters/rclabw b/src/filters/rclabw new file mode 100755 index 00000000..f07f0dce --- /dev/null +++ b/src/filters/rclabw @@ -0,0 +1,179 @@ +#!/bin/sh +# @(#$Id: rclabw,v 1.3 2008-10-08 08:27:34 dockes Exp $ (C) 2004 J.F.Dockes +# Parts taken from Estraier: +#================================================================ +# Estraier: a personal full-text search system +# Copyright (C) 2003-2004 Mikio Hirabayashi +#================================================================ +#================================================================ +# Extract text from an abiword file +#================================================================ + +# set variables +LANG=C ; export LANG +LC_ALL=C ; export LC_ALL +progname="rclabw" +filetype=abiword + + +#RECFILTCOMMONCODE +############################################################################## +# !! Leave the previous line unmodified!! Code imported from the +# recfiltcommon file + +# Utility code common to all shell filters. This could be sourced at run +# time, but it's slightly more efficient to include the code in the +# filters at build time (with a sed script). + +# Describe error in a way that can be interpreted by our caller +senderror() +{ + echo RECFILTERROR $* + # Also alert on stderr just in case + echo ":2:$progname::: $*" 1>&2 + exit 1 +} + +iscmd() +{ + cmd=$1 + case $cmd in + */*) + if test -x $cmd -a ! -d $cmd ; then return 0; else return 1; fi ;; + *) + oldifs=$IFS; IFS=":"; set -- $PATH; IFS=$oldifs + for d in $*;do test -x $d/$cmd -a ! -d $d/$cmd && return 0;done + return 1 ;; + esac +} + +checkcmds() +{ + for cmd in $*;do + if iscmd $cmd + then + a=1 + else + senderror HELPERNOTFOUND $cmd + fi + done +} + +# show help message +if test $# -ne 1 -o "$1" = "--help" +then + echo "Convert a $filetype file to HTML text for Recoll indexing." + echo "Usage: $progname [infile]" + exit 1 +fi + +infile="$1" + +# check the input file existence (may be '-' for stdin) +if test "X$infile" != X- -a ! -f "$infile" +then + senderror INPUTNOSUCHFILE "$infile" +fi + +# protect access to our temp files and directories +umask 77 + +############################################################################## +# !! Leave the following line unmodified ! +#ENDRECFILTCOMMONCODE + +checkcmds xsltproc + +xsltproc --nonet --novalid - "$infile" < + + + + + + + + + + + + + + + + + + + +

            + +
            +
            + + + +
            + + +

            + +
            + + + + + + + author + + + + + + + + + keywords + + + + + + + + + keywords + + + + + + + + + abstract + + + + + + + + <xsl:value-of select="."/> + + + + + + + + +
            +EOF + +# exit normally +exit 0 diff --git a/src/filters/rclaptosidman b/src/filters/rclaptosidman new file mode 100755 index 00000000..661329b7 --- /dev/null +++ b/src/filters/rclaptosidman @@ -0,0 +1,93 @@ +#!/bin/sh +# @(#$Id: rclaptosidman,v 1.1 2010-12-11 12:40:05 dockes Exp $ (C) 2004 J.F.Dockes +# Parts taken from Estraier: +#================================================================ +# Estraier: a personal full-text search system +# Copyright (C) 2003-2004 Mikio Hirabayashi +#================================================================ +#================================================================ +# rclaptosidman +# Strip the menu part from aptosid manual pages to improve search precision +#================================================================ + +# set variables +LANG=C ; export LANG +LC_ALL=C ; export LC_ALL +progname="rclaptosidman" +filetype="aptosid manual htm" + + +#RECFILTCOMMONCODE +############################################################################## +# !! Leave the previous line unmodified!! Code imported from the +# recfiltcommon file + +# Utility code common to all shell filters. This could be sourced at run +# time, but it's slightly more efficient to include the code in the +# filters at build time (with a sed script). + +# Describe error in a way that can be interpreted by our caller +senderror() +{ + echo RECFILTERROR $* + # Also alert on stderr just in case + echo ":2:$progname::: $*" 1>&2 + exit 1 +} + +iscmd() +{ + cmd=$1 + case $cmd in + */*) + if test -x $cmd -a ! -d $cmd ; then return 0; else return 1; fi ;; + *) + oldifs=$IFS; IFS=":"; set -- $PATH; IFS=$oldifs + for d in $*;do test -x $d/$cmd -a ! -d $d/$cmd && return 0;done + return 1 ;; + esac +} + +checkcmds() +{ + for cmd in $*;do + if iscmd $cmd + then + a=1 + else + senderror HELPERNOTFOUND $cmd + fi + done +} + +# show help message +if test $# -ne 1 -o "$1" = "--help" +then + echo "Convert a $filetype file to HTML text for Recoll indexing." + echo "Usage: $progname [infile]" + exit 1 +fi + +infile="$1" + +# check the input file existence (may be '-' for stdin) +if test "X$infile" != X- -a ! -f "$infile" +then + senderror INPUTNOSUCHFILE "$infile" +fi + +# protect access to our temp files and directories +umask 77 + +############################################################################## +# !! Leave the following line unmodified ! +#ENDRECFILTCOMMONCODE + +checkcmds sed +# Delete everything from
          + +

          Lemmatisation

          + +

          Note: je serais preneur d'une traduction franaise + agrable pour "stemming".

          +

          La lemmatisation transforme un mot driv vers sa racine. + Par exemple, aimer, aimerai, aimait, + aimez etc. seraient transforms en aim en + franais. Une recherche de l'un quelconque des drivs peut + automatiquement tre tendue vers tous les autres

          + +

          Certains moteurs de recherche appliquent la transformation + pendant l'indexation. L'index ne stocke que les racines des + mots, avec des exceptions pour les termes qui sont reconnus + comme des noms propres (capitalisation). Au moment de la + recherche, les termes de la requte sont galement transforms + avant comparaison l'index.

          + +

          Cette approche permet un index plus petit, mais elle perd + irrvocablement de l'information pendant l'indexation.

          + +

          Recoll fonctionne diffremment. Les termes sont indexs sans + transformation. L'index rsultant est plus gros, ce qui n'a + probablement pas beaucoup d'importance une poque de disques + de 100 Go principalement remplis d'information multimdia + non indexe. + +

          la fin de l'indexation, Recoll construit un ou plusieurs + dictionnaires de transformation (pour diffrents langages), o + toutes les racines sont listes avec leurs transformations + possibles.

          + + +

          Au moment de la recherche, par dfaut, les termes de + l'utilisateurs sont transforms, et tendus aux drivs par + utilisation du dictionnaire. + Les rsultats obtenus sont analogues ceux de + l'autre mthode. L'avantage est que l'expansion peut tre + contrle au moment de la recherche: +

            +
          • On peut la supprimer pour n'importe quel terme de la + requte, (en le faisant dbuter par une capitale: + Aime par exemple pour chercher la ville d'Aime la + Plagne).
          • +
          • Le langage de transformation peut galement tre chang, + en supposant que plusieurs dictionnaires de transformation + aient t construits lors de l'indexation.
          • +
          + +
        + + + diff --git a/website/helpernotes.html b/website/helpernotes.html new file mode 100644 index 00000000..d8f5a9b9 --- /dev/null +++ b/website/helpernotes.html @@ -0,0 +1,74 @@ + + + + + RECOLL: a personal text search system for + Unix/Linux + + + + + + + + + + + + + +
        +

        Notes about building/using specific external helper + applications

        + +

        The Python midi module

        +

        The normal procedure for building a Python module + applies:

        +
        
        +          tar xvzf midi-0.2.1.tar.gz
        +          cd midi-0.2.1
        +          python setup.py build
        +          sudo python setup.py install
        +      
        + +

        However, the midi module includes an alsa driver interface + which needs Swig to build and probably does not build at all + on recent Linux versions (the last version for the package + dates from 2006). Recoll does not need midi sequencer hardware + :), so if you don't need for other purposes, you can disable + the Alsa interface by editing setup.py and changing the + platform name at line 37 (the Alsa thing is only tried on + Linux):

        + + +
        
        +          37c37
        +          < if platform.startswith('linux'):
        +          ---
        +          > if platform.startswith('NONE'):
        +      
        + +

        The package should then build and install just fine.

        + +
        + + diff --git a/website/id3lib.html b/website/id3lib.html new file mode 100644 index 00000000..13bb6eba --- /dev/null +++ b/website/id3lib.html @@ -0,0 +1,57 @@ + + + + + RECOLL: building id3lib with gcc 4.4 + + + + + + + + + + + + + + +
        + +

        Compiling id3lib with recent gcc versions (2010-06-29)

        +

        Recoll uses a program installed by the id3lib package for + indexing mp3 files. Id3lib has not been updated for some time and + will not compile with gcc versions after 4.4 because of gcc + incompatibilities.

        +

        Here is a minuscule + patch to help compiling id3lib. To use it:

        +

          +
        • Download the patch (right-click the link and use 'Save As').
        • +
        • Extract the id3 lib source + (tar xvzf id3lib-3.8.3.tar.gz).
        • +
        • Change your current directory to the top of the id3lib source + tree and apply the patch:
          + cd id3lib-3.8.3
          + patch -p1 < /path/to/the/saved/patch
        • +
        • Run autoconf (you may have to install it, but your package + manager can certainly do it for you).
        • +
        • Run make and make install.
        • +
        +
        + + + diff --git a/website/idxthreads/Makefile b/website/idxthreads/Makefile new file mode 100644 index 00000000..5915e44a --- /dev/null +++ b/website/idxthreads/Makefile @@ -0,0 +1,7 @@ +.SUFFIXES: .txt .html + +.txt.html: + asciidoc $< + +all: threadingRecoll.html forkingRecoll.html xapDocCopyCrash.html + diff --git a/website/idxthreads/assembly.dia b/website/idxthreads/assembly.dia new file mode 100644 index 00000000..187071ec Binary files /dev/null and b/website/idxthreads/assembly.dia differ diff --git a/website/idxthreads/assembly.png b/website/idxthreads/assembly.png new file mode 100644 index 00000000..aaebf236 Binary files /dev/null and b/website/idxthreads/assembly.png differ diff --git a/website/idxthreads/forkingRecoll.txt b/website/idxthreads/forkingRecoll.txt new file mode 100644 index 00000000..cd6b6633 --- /dev/null +++ b/website/idxthreads/forkingRecoll.txt @@ -0,0 +1,224 @@ += Recoll command execution performance +:Author: Jean-François Dockès +:Email: jfd@recoll.org +:Date: 2015-05-22 + +== Abstract + +== Introduction + +The Recoll indexer, *recollindex*, is a big process which executes many +others, mostly for extracting text from documents. Some of the executed +processes are quite short-lived, and the time used by the process execution +machinery can actually dominate the time used to translate data. This +document explores possible approaches to improving performance without +adding excessive complexity or damaging reliability. + +Studying fork/exec performance is not exactly a new venture, and there are +many texts which address the subject. While researching, though, I found +out that not so many were accurate and that a lot of questions were left as +an exercise to the reader. + +== Issues with fork + +The traditional way for a Unix process to start another is the ++fork()+/+exec()+ system call pair. + ++fork()+ duplicates the process address space and resources (open files +etc.), then duplicates the thread of execution, ending up with 2 mostly +identical processes. + ++exec()+ then replaces part of the newly executing process with an address +space initialized from an executable file, inheriting some of the resources +under various conditions. + +This was all fine with the small processes of the first Unix systems, but +as time progressed, processes became bigger and the copy-before-discard +operation was found to waste significant resources. It was optimized using +two methods (at very different points in time): + + - The first approach was to supplement +fork()+ with the +vfork()+ call, which + is similar but does not duplicate the address space: the new process + thread executes in the old address space. The old thread is blocked + until the new one calls +exec()+ and frees up access to the memory + space. Any modification performed by the child thread persists when + the old one resumes. + + - The more modern approach, which cohexists with +vfork()+, was to replace + the full duplication of the memory space with duplication of the page + descriptors only. The pages in the new process are marked copy-on-write + so that the new process has write access to its memory without + disturbing its parent. This approach was supposed to make +vfork()+ + obsolete, but the operation can still be a significant resource consumer + for big processes mapping a lot of memory, so that +vfork()+ is still + around. Programs can have big memory spaces not only because they have + huge data segments (rare), but just because they are linked to many + shared libraries (more common). + +NOTE: Orders of magnitude: a *recollindex* process will easily grow into a +few hundred of megabytes of virtual space. It executes the small and +efficient *antiword* command to extract text from *ms-word* files. While +indexing multiple such files, *recollindex* can spend '60% of its CPU time' +doing `fork()`/`exec()` housekeeping instead of useful work (this is on Linux, +where `fork()` uses copy-on-write). + +Apart from the performance cost, another issue with +fork()+ is that a big +process can fail executing a small command because of the temporary need to +allocate twice its address space. This is a much discussed subject which we +will leave aside because it generally does not concern *recollindex*, which +in typical conditions uses a small portion of the machine virtual memory, +so that a temporary doubling is not an issue. + +The Recoll indexer is multithreaded, which may introduce other issues. Here +is what happens to threads during the +fork()+/+exec()+ interval: + + - +fork()+: + * The parent process threads all go on their merry way. + * The child process is created with only one thread active, duplicated + from the one which called +fork()+ + - +vfork()+ + * The parent process thread calling +vfork()+ is suspended, the others + are unaffected. + * The child is created with only one thread, as for +fork()+. + This thread shares the memory space with the parent ones, without + having any means to synchronize with them (pthread locks are not + supposed to work across processes): caution needed ! + +NOTE: for a multithreaded program using the classical pipe method to +communicate with children, the sequence between the `pipe()` call and the +parent `close()` of the unused side is a candidate for a critical section: +if several threads can interleave in there, children process may inherit +descriptors which 'belong' to other `fork()`/`exec()` operations, which may +in turn be a problem or not depending on how descriptor cleanup is +performed in the child (if no cleanup is performed, pipes may remain open +at both ends which will prevents seeing EOFs etc.). Thanks to StackExchange +user Celada for explaining this to me. + +For multithreaded programs, both +fork()+ and +vfork()+ introduce possibilities +of deadlock, because the resources held by a non-forking thread in the +parent process can't be released in the child because the thread is not +duplicated. This used to happen from time to time in *recollindex* because +of an error logging call performed if the +exec()+ failed after the +fork()+ +(e.g. command not found). + +With +vfork()+ it is also possible to trigger a deadlock in the parent by +(inadvertently) modifying data in the child. This could happen just +link:http://www.oracle.com/technetwork/server-storage/solaris10/subprocess-136439.html[because +of dynamic linker operation] (which, seriously, should be considered a +system bug). + + +In general, the state of program data in the child process is a semi-random +snapshot of what it was in the parent, and the official word about what you +can do is that you can only call +link:http://man7.org/linux/man-pages/man7/signal.7.html[async-safe library +functions] between +fork()+ and +exec()+. These are functions which are +safe to call from a signal handler because they are either reentrant or +can't be interrupted by a signal. A notable missing entry in the list is +`malloc()`. + +These are normally not issues for programs which only fork to execute +another program (but the devil is in the details as demonstrated by the +logging call issue...). + +One of the approaches often proposed for working around this mine-field is +to use an auxiliary small process to execute any command needed by the main +one. The small process can just use +fork()+/+exec()+ with no performance +issues. This has the inconvenient of complicating communication a lot if +data needs to be transferred one way or another. + +//// +Passing descriptors around +http://stackoverflow.com/questions/909064/portable-way-to-pass-file-descriptor-between-different-processes +http://www.normalesup.org/~george/comp/libancillary/ +http://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux-socket/ + +The process would then be: + - Tell slave to fork/exec cmd (issue with cmd + args format) + - Get fds + - Tell slave to wait, recover status. +//// + +== The posix_spawn() Linux non-event + +Given the performance issues of `fork()` and tricky behaviour of `vfork()`, +a "simpler" method for starting a child process was introduced by Posix: +`posix_spawn()`. + +The `posix_spawn()` function is a black box, externally equivalent to a +`fork()`/`exec()` sequence, and has parameters to specify the usual +house-keeping performed at this time (file descriptors and signals +management etc.). Hiding the internals gives the system a chance to +optimize the performance and avoid `vfork()` pitfalls like the `ld.so` +lockup described in the Oracle article. + +The Linux posix_spawn() is implemented by a `fork()`/`exec()` pair by default. + +`vfork()` is used either if specified by an input flag or no +signal/scheduler/process_group changes are requested. There must be a +reason why signal handling changes would preclude `vfork()` usage, but I +could not find it (signal handling data is stored in the kernel task_struct). + +The Linux glibc `posix_spawn()` currently does nothing that user code could +not do. Still, using it would probably be a good future-proofing idea, but +for a significant problem: there is no way to specify closing all open +descriptors bigger than a specified value (closefrom() equivalent). This is +available on Solaris and quite necessary in fact, because we have no way to +be sure that all open descriptors have the CLOEXEC flag set. + +So, no `posix_spawn()` for us (support was implemented inside +*recollindex*, but the code is normally not used). + +== The chosen solution + +The previous version of +recollindex+ used to use +vfork()+ if it was running +a single thread, and +fork()+ if it ran multiple ones. + +After another careful look at the code, I could see few issues with +using +vfork()+ in the multithreaded indexer, so this was committed. + +The only change necessary was to get rid of an implementation of the +lacking Linux +closefrom()+ call (used to close all open descriptors above a +given value). The previous Recoll implementation listed the +/proc/self/fd+ +directory to look for open descriptors but this was unsafe because of of +possible memory allocations in +opendir()+ etc. + +== Test results + +.Indexing 12500 small .doc files +[options="header"] +|=============================== +|call |real |user |sys +|fork |0m46.025s |0m26.574s |0m39.494s +|vfork |0m18.223s |0m17.753s |0m1.736s +|spawn/fork| 0m45.726s|0m27.082s| 0m40.575s +|spawn/vfork|0m18.915s|0m18.681s|0m3.828s +|recoll 1.18|1m47.589s|0m21.537s|0m29.458s +|================================ + +No surprise here, given the implementation of +posix_spawn()+, it gets the +same times as the +fork()+/+vfork()+ options. + +The tests were performed on an Intel Core i5 750 (4 cores, 4 threads). + +It would be painful to play it safe and discard the 60% reduction in +execution time offered by using +vfork()+, so this was adopted for Recoll +1.21. To this day, no problems were discovered, but, still crossing +fingers... + +The last line in the table is just for the fun: *recollindex* 1.18 +(single-threaded) needed almost 6 times as long to process the same +files... + +//// +Objections to vfork: + sigaction locks +https://bugzilla.redhat.com/show_bug.cgi?id=193631 +Is Linux vfork thread-safe ? Quoting interesting comments from Solaris +implementation: No answer to the issues cited though. +https://sourceware.org/bugzilla/show_bug.cgi?id=378 +Aussi: +http://blog.famzah.net/2009/11/20/fork-gets-slower-as-parent-process-use-more-memory/ +http://blog.famzah.net/2009/11/20/a-much-faster-popen-and-system-implementation-for-linux/ +Avec un workaround basé sur clone (donc linux-only). Tried it but crashes. +//// diff --git a/website/idxthreads/multipara.dia b/website/idxthreads/multipara.dia new file mode 100644 index 00000000..941bf31c Binary files /dev/null and b/website/idxthreads/multipara.dia differ diff --git a/website/idxthreads/multipara.png b/website/idxthreads/multipara.png new file mode 100644 index 00000000..03da2167 Binary files /dev/null and b/website/idxthreads/multipara.png differ diff --git a/website/idxthreads/nothreads.dia b/website/idxthreads/nothreads.dia new file mode 100644 index 00000000..0a216aa9 Binary files /dev/null and b/website/idxthreads/nothreads.dia differ diff --git a/website/idxthreads/nothreads.png b/website/idxthreads/nothreads.png new file mode 100644 index 00000000..aa93710d Binary files /dev/null and b/website/idxthreads/nothreads.png differ diff --git a/website/idxthreads/threadingRecoll.html b/website/idxthreads/threadingRecoll.html new file mode 100644 index 00000000..f6c6e45b --- /dev/null +++ b/website/idxthreads/threadingRecoll.html @@ -0,0 +1,1291 @@ + + + + + +Converting Recoll indexing to multithreading + + + + + +
        +
        +

        Abstract

        +
        +

        This relates lessons learned while modifying Recoll indexing to be +multithreaded. I am by no means a threaded applications expert, so that a +few of the observations I made whole doing this may be of use to other +novices.

        +
        +
        +
        +

        Introduction

        +
        +

        Recoll is a document indexing application, it +allows you to find documents by specifying search terms.

        +

        The documents need to be indexed for searches to be fast. In a nutshell, +we convert the different document formats to text, then split the text into +terms and remember where those occur. This is a time-consuming operation.

        +

        Up to version 1.18 Recoll indexing is single-threaded: routines which +call each other sequentially.

        +

        In most personal indexer contexts, it is also CPU-bound. There is a lot of +conversion work necessary for turning those PDF (or other) files into +appropriately cleaned up pure text, then split it into terms and update the +index. Given the relatively modest amount of data, and the speed of +storage, I/O issues are secondary.

        +

        Looking at the CPU idle top output stuck at 75% on my quad-core CPU, +while waiting for the indexing to finish, was frustrating, and I was +tempted to find a way to keep those other cores at temperature and shorten +the waiting.

        +

        For some usages, the best way to accomplish this may be to just partition +the index and independantly start indexing on different configurations, +using multiple processes to better utilize the available processing power.

        +

        This is not an universal solution though, as it is complicated to set up, +not optimal in general for indexing performance, and not always optimal +either at query time.

        +

        The most natural way to improve indexing times is to increase CPU +utilization by using multiple threads inside an indexing process.

        +

        Something similar had been done with earlier versions of the Recoll GUI, +which had an internal indexing thread. This had been a frequent source of +trouble though, and linking the GUI and indexing process lifetimes was a +bad idea, so, in recent versions, the indexing is always performed by an +external process. Still, this experience had put in light most of the +problem areas, and prepared the code for further work.

        +

        It should be noted that, as recollindex is both nice'd and ionice'd +as a lowest priority process, it will only use free computing power on the +machine, and will step down as soon as anything else wants to work.

        +
        +
        +

        The only case where you may notice that the indexing is at work +is when the machine is short on memory and things (such as +your Web browser) get swapped-out while you are not actively using +them. You then notice a long delay when you want to start, because they +need to be swapped back in. There is little which can be done about +this. Setting idxflushmb to a low value may help in some cases (depending +on the document sizes). May I also suggest in this case that, if your +machine can take more memory, it may be a good idea to procure some, as +memory is nowadays quite cheap, and memory-starved machines are not fun.

        +
        +

        In general, augmenting the machine utilisation by recollindex just does +not change its responsiveness. My PC has a an Intel Pentium Core i5 750 (4 +cores, no hyperthreading), which is far from being a high performance CPU +(nowadays…), and I often forget that I am running indexing tests, it is +just not noticeable. The machine does have a lot of memory though (12GB).

        +
        +
        +
        +

        The Recoll indexing processing flow

        +
        +
        +
        +Basic flow +
        +
        +

        There are 4 main steps in the recollindex processing pipeline:

        +
          +
        1. +

          +Find the file +

          +
        2. +
        3. +

          +Convert it to text +

          +
        4. +
        5. +

          +Process the text (split, strip etc.) and create a Xapian document +

          +
        6. +
        7. +

          +Update the index +

          +
        8. +
        +

        The first step, walking the file system (or some other data source), is +usually much faster than the others, and we just leave it alone to be +performed by the main thread. It outputs file names (and the associated +POSIX stat data).

        +

        The last step, Xapian index updating, can only be single-threaded.

        +

        The first idea is to change the indexing pipeline so that each step is +performed by an independant worker thread, passing its output to the next +thread, in assembly-line fashion.

        +

        In order to achieve this, we need to decouple the different phases. They +are normally linked by procedure calls, which we replace with a job +control object: the WorkQueue.

        +
        +

        The WorkQueue

        +

        The WorkQueue object is implemented by a reasonably simple class, which +manages an input queue on which client append jobs, and a set of worker +threads, which retrieve and perform the jobs, and whose lifetime are +managed by the WorkQueue object. The +implementation is straightforward with +POSIX threads synchronization functions and C++ STL data structures.

        +

        In practise it proved quite simple to modify existing code to create a job +object and put it on the queue, instead of calling the downstream routine +with the job parameters, while keeping the capacity to call the downstream +routine directly. The kind of coupling is determined either by compilation +flags (for global disabling/enabling of multithreading), or according to +configuration data, which allows experimenting with different threads +arrangements just by changing parameters in a file, without recompiling.

        +

        Each WorkQueue accepts two parameters: the length of the input queue +(before a client will block when trying to add a job), and the number of +worker threads. Both parameters can be set in the Recoll configuration +file for each of the three queues used in the indexing pipeline. Setting +the queue length to -1 will disable the corresponding queue (using a direct +call instead).

        +
        +
        +
        +
        +
        +

        The Assembly Line

        +
        +
        +
        +Assembly line +
        +
        +

        So the first idea is to create 3 explicit threads to manage the file +conversion, the term generation, and the Xapian index update. The first +thread prepares a file, passes it on to the term generation thread, and +immediately goes back to work on the next file, etc.

        +

        The presumed advantage of this method is that the different stages, which +perform disjointed processing, should share little, so that we can hope to +minimize the changes necessitated by the threads interactions.

        +

        However some changes to the code were needed to make this work (and a few +bugs were missed, which only became apparent at later stages, confirming +that the low interaction idea was not completely false).

        +
        +

        Converting to multithreading: what to look for

        +

        I am probably stating the obvious here, but when preparing a program for +multi-threading, problems can only arise where non-constant data is +accessed by different threads.

        +

        Once you have solved the core problems posed by the obvious data that needs +to be shared, you will be left to deal with less obvious, hidden, +interactions inside the program.

        +

        Classically this would concern global or static data, but in a C++ program, +class members will be a concern if a single object can be accessed by +several threads.

        +

        Hunting for static data inside a program of non trivial size is not always +obvious. Two approaches can be used: hunting for the static keyword in +source code, or looking at global and static data symbols in nm output.

        +

        Once found, there are mostly three types of static/global data:

        +
          +
        • +

          +Things that need to be eliminated: for example, routines can be made + reentrant by letting the caller supply a storage buffer instead of using + an internal static one (which was a bad idea in the first place + anyway). +

          +
        • +
        • +

          +Things that need to be protected: sometimes, the best approach is just + to protect the access with a mutex lock. It is trivial to encapsulate + the locks in C++ objects to use the "Resource Acquisition is + Initialization" idiom, easily making sure that locks are freed when + exiting the critical section. A very basic + example of implementation + can be found in the Recoll source code. +

          +
        • +
        • +

          +Things which can stay: this is mostly initialization data such as value + tables which are computed once, and then stay logically constant during + program execution. In order to be sure of a correct single-threaded + initialization, it is best to explicitly initialize the modules or + functions that use this kind of data in the main thread when the program + starts. +

          +
        • +
        +
        +
        +

        Assembly line approach: the results

        +

        Unfortunately, the assembly line approach yields very modest improvements +when used inside Recoll indexing. The reason, is that this method needs +stages of equivalent complexity to be efficient. If one of the stages +dominates the others, its thread will be the only one active at any time, +and little will be gained.

        +

        What is especially problematic is that the balance between tasks need not +only exist on average, but also for the majority of individual jobs.

        +

        For Recoll indexing, even if the data preparation and index update steps +are often of the same order of magnitude on average, their balance +depends a lot on the kind of data being processed, so that things are +usually unbalanced at any given time: the index update thread is mostly +idle while processing PDF files, and the data preparation has little to do +when working on HTML or plain text.

        +

        In practice, very modest indexing time improvements from 5% to 15% were +achieved with this method.

        +
        +
        +
        +
        +

        The next step: multi-stage parallelism

        +
        +
        +
        +Multi-stage parallelism +
        +
        +

        Given the limitations of the assembly line approach, the next step in the +transformation of Recoll indexing was to enable full parallelism wherever +possible.

        +

        Of the four processing steps (see figures), two are not candidates for +parallelization:

        +
          +
        • +

          +File system walking is so fast compared to the other steps that using + several threads would make no sense (it would also quite probably become + IO bound if we tried anyway). +

          +
        • +
        • +

          +The Xapian library index updating code is not designed for + multi-threading and must stay protected from multiple accesses. +

          +
        • +
        +

        The two other steps are good candidates.

        +

        Most of the work to make Recoll code reentrant had been performed for the +previous transformation. Going full-parallel only implied protecting the +data structures that needed to be shared by the threads performing a given +processing step.

        +

        Just for the anecdotic value, a list of the elements that needed mutexes:

        +
          +
        • +

          +Filter subprocesses cache: some file conversion subprocesses may be + expensive (starting a Python process is no piece of cake), so they are + cached for reuse after they are done translating a file. The shared cache + needs protection. +

          +
        • +
        • +

          +Status updates: an object used to update the current file name and indexing + status to a shared file. +

          +
        • +
        • +

          +Missing store: the list of missing helper programs +

          +
        • +
        • +

          +The readonly Xapian database object: a Xapian::Database object which is + used for checking the validity of current index data against a file’s + last modification date. +

          +
        • +
        • +

          +Document existence map: a bit array used to store an existence bit about + every document, and purge the disappeared at the end of the indexing + pass. This is accessed both from the file conversion and database update + code, so it also needed protection in the previous assembly line + approach. +

          +
        • +
        • +

          +Mbox offsets cache. Used to store the offsets of individual messages + inside mbox files. +

          +
        • +
        • +

          +iconv control blocks: these are cached for reuse in several places, and + need protection. Actually, it might be better in multithreading context + to just suppress the reuse and locking. Rough tests seem to indicate that + the impact on overall performance is small, but this might change with + higher parallelism (or not…). +

          +
        • +
        +

        The Recoll configuration also used to be managed by a single shared +object, which is mutable as values may depend on what area of the +file-system we are exploring, so that the object is stateful and updated as +we change directories. The choice made here was to duplicate the object +where needed (each indexing thread gets its own). This gave rise to the +sneakiest bug in the whole transformation (see further down).

        +

        Having a dynamic way to define the threads configuration makes it easy to +experiment. For example, the following data defines the configuration that +was finally found to be best overall on my hardware:

        +
        +
        +
        thrQSizes = 2 2 2
        +thrTCounts =  4 2 1
        +
        +

        This is using 3 queues of depth 2, 4 threads working on file conversion, 2 +on text splitting and other document processing, and 1 on Xapian updating +(no choice here).

        +
        +
        +
        +
        +

        Bench results

        +
        +

        So the big question after all the work: was it worth it ? I could only get +a real answer when the program stopped crashing, so this took some time and +a little faith, but the answer is positive, as far as I’m +concerned. Performance has improved significantly and this was a fun +project.

        +
        + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Table 1. Results on a variety of file system areas:
        Area Seconds before Seconds after Percent Improvement Speed Factor

        home

        12742

        6942

        46%

        1.8

        mail

        2700

        1563

        58%

        1.7

        projets

        5022

        1970

        61%

        2.5

        pdf

        2164

        770

        64%

        2.8

        otherhtml

        5593

        4014

        28%

        1.4

        +
        +
        + + ++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Table 2. Characteristics of the data
        Area Files MB Files DB MB Documents

        home

        64106

        44897

        1197

        104797

        mail

        813

        232

        663

        47267

        projets

        2056

        34504

        549

        40281

        pdf

        1123

        1139

        111

        1139

        otherhtml

        3442

        223007

        2080

        221890

        +
        +

        home is my home directory. The high megabyte value is due to a number of +very big and not indexed VirtualBox images. Otherwise, it’s a wide +mix of source files, email, miscellaneous documents and ebooks.

        +

        mail is my mail directory, full of mbox files.

        +

        projets mostly holds source files, and a number of documents.

        +

        pdf holds random pdf files harvested on the internets. The performance +is quite spectacular, because most of the processing time goes to +converting them to text, and this is done in parallel. Probably could be +made a bit faster with more cores, until we hit the Xapian update speed +limit.

        +

        otherhtml holds myriad of small html files, mostly from +wikipedia. The improvement is not great here because a lot of time is +spent in the single-threaded Xapian index update.

        +

        The tests were made with queue depths of 2 on all queues, and 4 threads +working on the file conversion step, 2 on the term generation.

        +
        +
        +
        +

        A variation: linear parallelism

        +
        +

        Once past the assembly-line idea, another possible transformation would be +to get rid of the two downstream queues, and just create a job for each +file and let it go to the end (using a mutex to protect accesses to the +writable Xapian database).

        +

        With the current Recoll code, this can be defined by the following +parameters (one can also use a deeper front queue, this changes little):

        +
        +
        +
        thrQSizes = 2 -1 -1
        +thrTCounts =  4 0 0
        +
        +

        In practise, the performance is close to the one for the multistage +version.

        +

        If we were to hard-code this approach, this would be a simpler +modification, necessitating less changes to the code, but it has a slight +inconvenient: when working on a single big multi-document file, no +parallelism at all can be obtained. In this situation, the multi-stage +approach brings us back to the assembly-line behaviour, so the improvements +are not great, but they do exist.

        +
        +
        +
        +

        Miscellany

        +
        +
        +

        The big gotcha: my stack dump staring days

        +

        Overall, debugging the modified program was reasonably +straightforward. Data access synchronization issues mostly provoke dynamic +data corruption, which can be beastly to debug. I was lucky enough that +most crashes occurred in the code that was actually related to the +corrupted data, not in some randomly located and unrelated dynamic memory +user, so that the issues were reasonably easy to find.

        +

        One issue though kept me working for a few days. The indexing process kept +crashing randomly at an interval of a few thousands documents, segfaulting +on a bad pointer. An access to the configuration data structure seemed to +be involved, but, as each thread was supposed to have its own copy, I was +out of ideas.

        +

        After reviewing all the uses for the configuration data (there are quite a +few), the problem was finally revealed to lie with the filter process +cache. Each filter structure stored in the cache stores a pointer to a +configuration structure. This belonged to the thread which initially +created the filter. But the filter would often be reused by a different +thread, with the consequence that the configuration object was now accessed +and modified by two unsynchronized threads… Resetting the config pointer +at the time of filter reuse was the +ridiculously +simple (almost)single-line fix to this evasive problem.

        +

        Looking at multi-threaded stack dumps is mostly fun for people with several +heads, which is unfortunately not my case, so I was quite elated when this +was over.

        +
        +
        +

        Fork performance issues

        +

        On a quite unrelated note, something that I discovered while evaluating the +program performance is that forking a big process like recollindex can be +quite expensive. Even if the memory space of the forked process is not +copied (it’s Copy On Write, and we write very little before the following +exec), just duplicating the memory maps can be slow when the process uses a +few hundred megabytes.

        +

        I modified the single-threaded version of recollindex to use vfork +instead of fork, but this can’t be used with multiple threads (no +modification of the process memory space is allowed in the child between +vfork and exec, so we’d have to have a way to suspend all the threads +first).

        +

        I did not implement a solution to this issue, and I don’t think +that a simple one exists. The workaround is to use modest Xapian flush +values to prevent the process from becoming too big.

        +

        A longer time solution would be to implement a small slave process to do +the executing of ephemeral external commands.

        +
        +
        +
        +
        +

        + + + diff --git a/website/idxthreads/threadingRecoll.txt b/website/idxthreads/threadingRecoll.txt new file mode 100644 index 00000000..94791345 --- /dev/null +++ b/website/idxthreads/threadingRecoll.txt @@ -0,0 +1,408 @@ += Converting Recoll indexing to multithreading +:Author: Jean-François Dockès +:Email: jfd@recoll.org +:Date: 2012-12-03 + +== Abstract + +This relates lessons learned while modifying *Recoll* indexing to be +multithreaded. I am by no means a threaded applications expert, so that a +few of the observations I made whole doing this may be of use to other +novices. + +== Introduction + +http://www.recoll.org[*Recoll*] is a document indexing application, it +allows you to find documents by specifying search terms. + +The documents need to be _indexed_ for searches to be fast. In a nutshell, +we convert the different document formats to text, then split the text into +terms and remember where those occur. This is a time-consuming operation. + +Up to version 1.18 *Recoll* indexing is single-threaded: routines which +call each other sequentially. + +In most personal indexer contexts, it is also CPU-bound. There is a lot of +conversion work necessary for turning those PDF (or other) files into +appropriately cleaned up pure text, then split it into terms and update the +index. Given the relatively modest amount of data, and the speed of +storage, I/O issues are secondary. + +Looking at the _CPU idle_ *top* output stuck at 75% on my quad-core CPU, +while waiting for the indexing to finish, was frustrating, and I was +tempted to find a way to keep those other cores at temperature and shorten +the waiting. + +For some usages, the best way to accomplish this may be to just partition +the index and independantly start indexing on different configurations, +using multiple processes to better utilize the available processing power. + +This is not an universal solution though, as it is complicated to set up, +not optimal in general for indexing performance, and not always optimal +either at query time. + +The most natural way to improve indexing times is to increase CPU +utilization by using multiple threads inside an indexing process. + +Something similar had been done with earlier versions of the *Recoll* GUI, +which had an internal indexing thread. This had been a frequent source of +trouble though, and linking the GUI and indexing process lifetimes was a +bad idea, so, in recent versions, the indexing is always performed by an +external process. Still, this experience had put in light most of the +problem areas, and prepared the code for further work. + +It should be noted that, as `recollindex` is both _nice_'d and _ionice_'d +as a lowest priority process, it will only use free computing power on the +machine, and will step down as soon as anything else wants to work. + +**** + +The only case where you may notice that the indexing is at work +is when the machine is short on memory and things (such as +your Web browser) get swapped-out while you are not actively using +them. You then notice a long delay when you want to start, because they +need to be swapped back in. There is little which can be done about +this. Setting _idxflushmb_ to a low value may help in some cases (depending +on the document sizes). May I also suggest in this case that, if your +machine can take more memory, it may be a good idea to procure some, as +memory is nowadays quite cheap, and memory-starved machines are not fun. + +**** + +In general, augmenting the machine utilisation by `recollindex` just does +not change its responsiveness. My PC has a an Intel Pentium Core i5 750 (4 +cores, no hyperthreading), which is far from being a high performance CPU +(nowadays...), and I often forget that I am running indexing tests, it is +just not noticeable. The machine does have a lot of memory though (12GB). + + +== The Recoll indexing processing flow + +image::nothreads.png["Basic flow", float="right"] + +There are 4 main steps in the `recollindex` processing pipeline: + + . Find the file + . Convert it to text + . Process the text (split, strip etc.) and create a *Xapian* document + . Update the index + +The first step, walking the file system (or some other data source), is +usually much faster than the others, and we just leave it alone to be +performed by the main thread. It outputs file names (and the associated +*POSIX* _stat_ data). + +The last step, *Xapian* index updating, can only be single-threaded. + +The first idea is to change the indexing pipeline so that each step is +performed by an independant worker thread, passing its output to the next +thread, in assembly-line fashion. + +In order to achieve this, we need to decouple the different phases. They +are normally linked by procedure calls, which we replace with a job +control object: the 'WorkQueue'. + +=== The WorkQueue + + +The _WorkQueue_ object is implemented by a reasonably simple class, which +manages an input queue on which client append jobs, and a set of worker +threads, which retrieve and perform the jobs, and whose lifetime are +managed by the _WorkQueue_ object. The +https://bitbucket.org/medoc/recoll/src/f06f3aba912045d6ad52e9a0fd930b95e363fd10/src/utils/workqueue.h?at=default[implementation] is straightforward with +*POSIX* threads synchronization functions and C++ *STL* data structures. + +In practise it proved quite simple to modify existing code to create a job +object and put it on the queue, instead of calling the downstream routine +with the job parameters, _while keeping the capacity to call the downstream +routine directly_. The kind of coupling is determined either by compilation +flags (for global disabling/enabling of multithreading), or according to +configuration data, which allows experimenting with different threads +arrangements just by changing parameters in a file, without recompiling. + +Each _WorkQueue_ accepts two parameters: the length of the input queue +(before a client will block when trying to add a job), and the number of +worker threads. Both parameters can be set in the *Recoll* configuration +file for each of the three queues used in the indexing pipeline. Setting +the queue length to -1 will disable the corresponding queue (using a direct +call instead). + +unfloat::[] + + +== The Assembly Line + +image::assembly.png["Assembly line", float="right"] + +So the first idea is to create 3 explicit threads to manage the file +conversion, the term generation, and the *Xapian* index update. The first +thread prepares a file, passes it on to the term generation thread, and +immediately goes back to work on the next file, etc. + +The presumed advantage of this method is that the different stages, which +perform disjointed processing, should share little, so that we can hope to +minimize the changes necessitated by the threads interactions. + +However some changes to the code were needed to make this work (and a few +bugs were missed, which only became apparent at later stages, confirming +that the _low interaction_ idea was not completely false). + +=== Converting to multithreading: what to look for + +I am probably stating the obvious here, but when preparing a program for +multi-threading, problems can only arise where non-constant data is +accessed by different threads. + +Once you have solved the core problems posed by the obvious data that needs +to be shared, you will be left to deal with less obvious, hidden, +interactions inside the program. + +Classically this would concern global or static data, but in a C++ program, +class members will be a concern if a single object can be accessed by +several threads. + +Hunting for static data inside a program of non trivial size is not always +obvious. Two approaches can be used: hunting for the _static_ keyword in +source code, or looking at global and static data symbols in *nm* output. + +Once found, there are mostly three types of static/global data: + + * Things that need to be eliminated: for example, routines can be made + reentrant by letting the caller supply a storage buffer instead of using + an internal static one (which was a bad idea in the first place + anyway). + * Things that need to be protected: sometimes, the best approach is just + to protect the access with a mutex lock. It is trivial to encapsulate + the locks in C++ objects to use the "Resource Acquisition is + Initialization" idiom, easily making sure that locks are freed when + exiting the critical section. A very basic + https://bitbucket.org/medoc/recoll/src/f06f3aba9120/src/utils/ptmutex.h?at=default[example of implementation] + can be found in the *Recoll* source code. + * Things which can stay: this is mostly initialization data such as value + tables which are computed once, and then stay logically constant during + program execution. In order to be sure of a correct single-threaded + initialization, it is best to explicitly initialize the modules or + functions that use this kind of data in the main thread when the program + starts. + +=== Assembly line approach: the results + +Unfortunately, the assembly line approach yields very modest improvements +when used inside *Recoll* indexing. The reason, is that this method needs +stages of equivalent complexity to be efficient. If one of the stages +dominates the others, its thread will be the only one active at any time, +and little will be gained. + +What is especially problematic is that the balance between tasks need not +only exist on average, but also for the majority of individual jobs. + +For *Recoll* indexing, even if the data preparation and index update steps +are often of the same order of magnitude _on average_, their balance +depends a lot on the kind of data being processed, so that things are +usually unbalanced at any given time: the index update thread is mostly +idle while processing PDF files, and the data preparation has little to do +when working on HTML or plain text. + +In practice, very modest indexing time improvements from 5% to 15% were +achieved with this method. + +[[recoll.idxthreads.multistage]] +== The next step: multi-stage parallelism + +image::multipara.png["Multi-stage parallelism", float="right"] + +Given the limitations of the assembly line approach, the next step in the +transformation of *Recoll* indexing was to enable full parallelism wherever +possible. + +Of the four processing steps (see figures), two are not candidates for +parallelization: + + * File system walking is so fast compared to the other steps that using + several threads would make no sense (it would also quite probably become + IO bound if we tried anyway). + * The *Xapian* library index updating code is not designed for + multi-threading and must stay protected from multiple accesses. + +The two other steps are good candidates. + +Most of the work to make *Recoll* code reentrant had been performed for the +previous transformation. Going full-parallel only implied protecting the +data structures that needed to be shared by the threads performing a given +processing step. + +Just for the anecdotic value, a list of the elements that needed mutexes: + +- Filter subprocesses cache: some file conversion subprocesses may be + expensive (starting a Python process is no piece of cake), so they are + cached for reuse after they are done translating a file. The shared cache + needs protection. +- Status updates: an object used to update the current file name and indexing + status to a shared file. +- Missing store: the list of missing helper programs +- The readonly *Xapian* database object: a Xapian::Database object which is + used for checking the validity of current index data against a file's + last modification date. +- Document existence map: a bit array used to store an existence bit about + every document, and purge the disappeared at the end of the indexing + pass. This is accessed both from the file conversion and database update + code, so it also needed protection in the previous assembly line + approach. +- Mbox offsets cache. Used to store the offsets of individual messages + inside *mbox* files. +- *iconv* control blocks: these are cached for reuse in several places, and + need protection. Actually, it might be better in multithreading context + to just suppress the reuse and locking. Rough tests seem to indicate that + the impact on overall performance is small, but this might change with + higher parallelism (or not...). + +The *Recoll* configuration also used to be managed by a single shared +object, which is mutable as values may depend on what area of the +file-system we are exploring, so that the object is stateful and updated as +we change directories. The choice made here was to duplicate the object +where needed (each indexing thread gets its own). This gave rise to the +sneakiest bug in the whole transformation (see further down). + +Having a dynamic way to define the threads configuration makes it easy to +experiment. For example, the following data defines the configuration that +was finally found to be best overall on my hardware: + + thrQSizes = 2 2 2 + thrTCounts = 4 2 1 + +This is using 3 queues of depth 2, 4 threads working on file conversion, 2 +on text splitting and other document processing, and 1 on Xapian updating +(no choice here). + +unfloat::[] + +== Bench results + +So the big question after all the work: was it worth it ? I could only get +a real answer when the program stopped crashing, so this took some time and +a little faith, but the answer is positive, as far as I'm +concerned. Performance has improved significantly and this was a fun +project. + + +.Results on a variety of file system areas: +[options="header", width="70%"] +|======================= +|Area |Seconds before |Seconds after| Percent Improvement| Speed Factor +|home |12742 | 6942 | 46%| 1.8 +|mail |2700 | 1563 | 58% | 1.7 +|projets | 5022 | 1970 | 61% | 2.5 +|pdf | 2164 | 770 | 64% | 2.8 +|otherhtml | 5593 | 4014| 28% | 1.4 +|======================= + +.Characteristics of the data +[options="header", width="70%"] +|======================= +|Area | Files MB | Files | DB MB | Documents +|home | 64106 | 44897 | 1197 | 104797 +|mail | 813 | 232 | 663 | 47267 +|projets | 2056 | 34504 | 549 | 40281 +|pdf | 1123 | 1139 | 111 | 1139 +|otherhtml | 3442 | 223007 | 2080 | 221890 | +|======================= + +_home_ is my home directory. The high megabyte value is due to a number of +very big and not indexed *VirtualBox* images. Otherwise, it's a wide +mix of source files, email, miscellaneous documents and ebooks. + +_mail_ is my mail directory, full of *mbox* files. + +_projets_ mostly holds source files, and a number of documents. + +_pdf_ holds random *pdf* files harvested on the internets. The performance +is quite spectacular, because most of the processing time goes to +converting them to text, and this is done in parallel. Probably could be +made a bit faster with more cores, until we hit the *Xapian* update speed +limit. + +_otherhtml_ holds myriad of small html files, mostly from +*wikipedia*. The improvement is not great here because a lot of time is +spent in the single-threaded *Xapian* index update. + +The tests were made with queue depths of 2 on all queues, and 4 threads +working on the file conversion step, 2 on the term generation. + +== A variation: linear parallelism + +Once past the assembly-line idea, another possible transformation would be +to get rid of the two downstream queues, and just create a job for each +file and let it go to the end (using a mutex to protect accesses to the +writable *Xapian* database). + +With the current *Recoll* code, this can be defined by the following +parameters (one can also use a deeper front queue, this changes little): + + thrQSizes = 2 -1 -1 + thrTCounts = 4 0 0 + +In practise, the performance is close to the one for the multistage +version. + +If we were to hard-code this approach, this would be a simpler +modification, necessitating less changes to the code, but it has a slight +inconvenient: when working on a single big multi-document file, no +parallelism at all can be obtained. In this situation, the multi-stage +approach brings us back to the assembly-line behaviour, so the improvements +are not great, but they do exist. + + + +== Miscellany + +=== The big gotcha: my stack dump staring days + +Overall, debugging the modified program was reasonably +straightforward. Data access synchronization issues mostly provoke dynamic +data corruption, which can be beastly to debug. I was lucky enough that +most crashes occurred in the code that was actually related to the +corrupted data, not in some randomly located and unrelated dynamic memory +user, so that the issues were reasonably easy to find. + +One issue though kept me working for a few days. The indexing process kept +crashing randomly at an interval of a few thousands documents, segfaulting +on a bad pointer. An access to the configuration data structure seemed to +be involved, but, as each thread was supposed to have its own copy, I was +out of ideas. + +After reviewing all the uses for the configuration data (there are quite a +few), the problem was finally revealed to lie with the filter process +cache. Each filter structure stored in the cache stores a pointer to a +configuration structure. This belonged to the thread which initially +created the filter. But the filter would often be reused by a different +thread, with the consequence that the configuration object was now accessed +and modified by two unsynchronized threads... Resetting the config pointer +at the time of filter reuse was the +https://bitbucket.org/medoc/recoll/commits/943de4b78818079b0eb6ffd0fcbdfdd0746b4a40[ridiculously +simple (almost)single-line fix] to this evasive problem. + +Looking at multi-threaded stack dumps is mostly fun for people with several +heads, which is unfortunately not my case, so I was quite elated when this +was over. + +=== Fork performance issues + +On a quite unrelated note, something that I discovered while evaluating the +program performance is that forking a big process like `recollindex` can be +quite expensive. Even if the memory space of the forked process is not +copied (it's Copy On Write, and we write very little before the following +exec), just duplicating the memory maps can be slow when the process uses a +few hundred megabytes. + +I modified the single-threaded version of `recollindex` to use *vfork* +instead of *fork*, but this can't be used with multiple threads (no +modification of the process memory space is allowed in the child between +*vfork* and *exec*, so we'd have to have a way to suspend all the threads +first). + +I did not implement a solution to this issue, and I don't think +that a simple one exists. The workaround is to use modest *Xapian* flush +values to prevent the process from becoming too big. + +A longer time solution would be to implement a small slave process to do +the executing of ephemeral external commands. diff --git a/website/idxthreads/xapDocCopyCrash.txt b/website/idxthreads/xapDocCopyCrash.txt new file mode 100644 index 00000000..91833651 --- /dev/null +++ b/website/idxthreads/xapDocCopyCrash.txt @@ -0,0 +1,138 @@ += The case of the bad Xapian::Document copy + +== How things were supposed to work + +Coming from the link:threadingRecoll.html[threading *Recoll*] page, +you may remember that the third stage of the +processing pipeline breaks up text into terms, producing a *Xapian* +document (+Xapian::Document+) which is finally processed by the last stage, +the index updater. + +What happens in practise is that the main routine in this stage has a local ++Xapian::Document+ object, automatically allocated on the stack, which it +updates appropriately and then copies into a task object which is placed on +the input queue for the last stage. + +The text-splitting routine then returns, and its local +Xapian::Document+ +object is (implicitely) deleted while the stack unwinds. + +The idea is that the *copy* of the document which is on the queue should be +unaffected, it is independant of the original and will further be processed +by the index update thread, without interaction with the text-splitting one. + +At no point do multiple threads access the +Xapian::Document+ data, so +there should be no problem. + +== The problem + +Most *Xapian* objects are reference-counted, which means that the object +itself is a small block of house-keeping variables. The actual data is +allocated on the heap through eventual calls to new/malloc, and is shared +by multiple copies of the object. This is the case for +Xapian::Document+ + +This is aboundantly documented, and users are encouraged to use copies +instead of passing pointers around (copies are cheap because only a small +block of auxiliary data is actually duplicated). This in general makes +memory management easier. + +This is well-known, and it would not appear to be a problem in the above +case as the +Xapian::Document+ actual data is never accessed by multiple +threads. + +The problem is that the reference counter which keeps track of the object +usage and triggers actual deletion when it goes to zero is accessed by two +threads: + + - It is decremented while the first local object is destroyed during the + stack unwind in the first thread + - It is also updated by the last stage thread, incremented if copies are + made, then decremented until it finally goes down to 0 when we are done + with the object, at which point the document data is unallocated. + +As the counter is not protected in any way against concurrent access, the +actual sequence of events is undefined and at least two kinds of problems +may occur: double deletion of the data, or accesses to already freed heap +data (potentially thrashing other threads allocations, or reading modified +data). + +A relatively simple fix for this would be to use atomic test-and-set +operations for the counter (which is what the GNU +std::string+ does). But +the choice made by *Xapian* to let the application deal with all +synchronization issues is legitimate and documented, nothing to complain +about here. I just goofed. + +Because the counter test and update operations are very fast, and occur +among a lot of processing from the final stage thread, the chances of +concurrent access are low, which is why the problem manifests itself very +rarely. Depending on thread scheduling and all manners of semi-random +conditions, it is basically impossible to reproduce reliably. + +== The fix + +The implemented fix was trivial: the upstream thread allocates the initial ++Xapian::Document+ on the heap, copies the pointer to the queue object, and +forgets about it. The index-updating thread peruses the object then ++delete+'s it. Real easy. + +An alternative solution would have been to try and use locking to protect +the counter updates. The only place where such locking operations could +reasonably occur is inside the +Xapian::Document+ refcounted pointer +object, which we can't modify. Otherwise, we would have to protect the +_whole scopes of existence_ of the Xapian::Document object in any routine +which creates/copies or (implicitely) deletes it, which would cause many +problems and/or contention issues + +== Why did I miss this ? + +The mechanism of the crashes is simple enough, quasi-obvious. +How on earth could I miss this problem while writing the code ? + +For the sake of anecdote, my first brush with atomicity for updates of +reference counters was while debugging a System V release 4 kernel VFS file +system module, at the time when SVR4 got a preemptive kernel with SVR4-MP, +circa 1990... I ended up replacing a +counter+++ with +atomic_add()+ after +a set of _interesting_ debugging sessions interspersed with kernel crashes +and +fsck+ waits. This should have left some memories. So what went wrong ? +Here follow a list of possible reasons: + +- Reasoning by analogy: std::string are safe to use in this way. The other + objects used in the indexing pipe are also safe. I just used + +Xapian::Document+ in the same way without thinking further. +- Probably not how I would do it: faced with designing +Xapian::Document+, + (not clever enough to do this anyway), I'd probably conclude that not + wanting to deal with full-on concurrency is one thing, not protecting the + reference counters is another, and going too far. +- The problem was not so easily visible because the object deletion is + implicitely performed during the stack unwind: this provides no clue, no + specific operation to think about. +- Pure lazyness. + + +As a conclusion, a humble request to library designers: when an +interface works counter to the reasonable expectations of at least some of +the users (for example because it looks like, but works differently, than a +standard library interface), it is worth it to be very specific in the +documentation and header file comments about the gotcha's. Saving people +from their own deficiencies is a worthy goal. + +Here, a simple statement that the reference count was not mt-safe +(admittedly redundant with the general statement that the *Xapian* library +does not deal with threads), would have got me thinking and avoided the +error. + +++++ +

        Comments

        + +
        + + + comments powered by Disqus + +++++ diff --git a/website/index.html.en b/website/index.html.en new file mode 100644 index 00000000..74bc404f --- /dev/null +++ b/website/index.html.en @@ -0,0 +1,372 @@ + + + + Recoll text search finds your documents + + + + + + + + + + + + + + + +
        + +

        + Recoll is + a desktop full-text search tool.

        + +

        Recoll finds keywords + inside documents as well as file names.

        +
          +
        • It can search + most document + formats. You may + need external applications for text extraction.
        • +
        • It can reach any storage place: files, + archive members, email attachments, transparently + handling decompression.
        • +
        • One click will open the document inside a native editor or + display an even quicker text preview.
        • +
        • The software is free, open source, + and licensed under the GPL.
        • +
        • Detailed features and + application requirements for supported document types.
        • +
        + +

        The current Recoll version is + 1.22.4 + (Release notes, + known + bugs, Release history).

        + + +

        Recoll is based on the very + capable Xapian search + engine library, for which it provides a powerful text + extraction layer and a complete, yet easy to use, Qt graphical + interface.

        + +

        Recoll will index an MS-Word document + stored as an attachment to an e-mail message inside + a Thunderbird folder archived in a Zip file (and + more...). It will also help you search for it with a friendly and + powerful interface, and let you open a copy of a PDF at the right + page with two clicks. There is little that will remain + hidden on your disk.

        + +

        Recoll has extensive + documentation. If you run into a problem, or want to + propose improvements, you are welcome to use + the + mailing list or problem + tracker.

        + +

        Recoll user ? Maybe there are still a few useful + search tricks that you don't know about. A quick look at + the search + tips might prove useful ! Also the + + Faqs and Howtos on bitbucket.org, and some contributed + result list formats.

        + +

        News

        +
        + +
        +
        2016-11-25
        Release 1.22.4 is available and fixes + an ennoying qt5 glitch (advanced search 'start search' + button doing nothing).
        + +
        2016-06-21
        Release 1.22.3 is available. This is + going to replace 1.21 as the main release. See + the the release + notes. Some input handler dependancies have changed.
        + +
        2016-05-11
        Release 1.21.7 fixes an ennoying but + benign GUI crash-on-exit bug reported on Fedora 23 (qt5).
        + +
        2016-04-21
        I experimented with installing + the Recoll + Web UI with Apache, and found out + that this + is really easy, actually both easier to set up and + more useful than running it standalone. Recently added: + instructions for running with Nginx instead of Apache.
        + +
        2016-04-18
        Found a GUI + crash bug with a reasonably easy workaround.
        + +
        2016-04-14
        Release 1.22.0 is now available from + the download area. The binary packages should wait until + enough brave souls have tested it. See + the the release notes.
        + +
        2016-04-07
        Release 1.21.6 adds KDE5 compatibility + for the KIO slave.
        + +
        2016-01-29
        Release 1.21.5 is out. It fixes a + relatively nasty bug affecting all previous 1.21 versions: + the query language parser processed incorrectly multiple + mime type or category specifications, with missing results + as a consequence
        + +
        2016-01-12
        It seems that we currently have a + relatively frequent problem resulting in damaged indexes. If + you are experimenting heavy reindexing (incremental indexing + takes longer than it should), or missing search results, + please take a look at the top of + the known bugs page
        + +
        2015-11-09
        +
        + Recoll on MS-Windows + Recoll for + MS-Windows. Still a few things missing (like + real-time monitoring), but it does work, and it has a proper + installer, so you can easily get rid of it if you don't like + it. Have a look.. + This is an almost-native port, based on Qt and the Windows + API, no need for Cygwin. Thanks to Christian Motz for + helping with the filter interface (and the rest). I would + love some feedback!
        +
        + +
        2015-10-17
        +
        A bug in the verification of configuration file path variables + generates spurious warnings from recollindex when the + skippedPaths variable contains elements with wildcards. This + has no consequence except for the spurious error + message.
        + +
        2015-10-01
        +
        Release 1.21.2 is out, and replaces 1.20 as production + release.
        + +
        2015-06-30
        +
        A new rclpdf filter, with improved compatibility with + recent poppler pdftotext + versions. See rclpdf + filter.
        + +
        2015-06-16
        +
        Recoll 1.21.0 is out. This has a new query parser and + should be considered an instable release, please do not + package it (1.20.6 is the one you want for stability). It + also changes the way + filters are executed for better performance. See the + release notes for more + detail about the few other changes.
        + +
        2015-04-25
        +
        Recoll 1.20.6 is out, with mostly small fixes to + compressed file handling, which may make a big difference in + some cases. See the release + notes. Of course it also incorportates the Qt 5 + compatibility from 1.20.5 (Qt + 5.3.2 ok, 5.2 does not work).
        + +
        2015-03-30
        +
        Recoll 1.20.4 released. This fixes real time indexing of + the web history (when using the Firefox plugin).
        + +
        2014-12-27
        +
        + Unrtf 21.8 has been released. This fixes many issues + in unrtf, some with possible security implications. You + really want to use this version.
        + +
        2014-12-18
        Recoll 1.20.1 is out and replaces 1.19 + as the main version. I have been using 1.20 for months + (along with a number of fearless builders-from-source), and + it's as stable as 1.19, with nice + small new features. Packages + will follow shortly. It is recommended (but not strictly + required, see the notes) to run an index reset when + upgrading.
        + +
        2014-12-10
        The aspell command used for + orthographic suggestions is broken on Debian Jessie (because + of an aspell packaging issue), and this will not be fixed + for the Debian release. See the + simple workaround here.
        + +
        2014-11-09
        If you are still running anything + older than 1.19.14p2, YOU SHOULD + UPGRADE. In + particular, this index + corruption issue leading to repeated reindexing of + documents, and possibly query problems too, can be pretty + ennoying.
        + GOTO download and + install 1.19.14p2 or 1.20. Reset your index after + upgrading (rm -rf ~/.recoll/xapiandb).
        + +
        2014-07-28
        A nice new application to complement + Recoll: recollfs + implements a Fuse filesystem where Recoll queries are + represented as directories, the contents of which are links + to the result documents.
        + +
        2014-07-16
        Recoll version 1.19.14p2 fixes more + resource management issues in the Python module (only the + Python package needs upgrading for this), and the processing + of Bengali characters (no more diacritics stripping).
        + +
        2014-06-24
        An + updated filter for Open/LibreOffice documents. The + previous version merged words which were tab-separated in + the input.
        + +
        2014-06-17
        The source tarball for version 1.20.0 + has been released. This version has + a number of improvements over + 1.19, but also some incompatibilities. The first minor + releases for 1.20 may contain some functional changes in + addition to bug fixes, so they may be slightly less stable + than 1.19, and 1.19 packages remain the "safe Recoll" for + now. Still, if you build from source, there are a few nice + things in 1.20...
        + +
        2014-06-07
        Version 1.19.14 is out and fixes a + handful of minor-to-ennoying indexing glitches (see the + Release notes).
        + +
        2014-05-06
        Version 1.19.13 is out and hopefully + fixes the remaining (rare) crashes of multithreaded + indexing.
        + +
        2014-04-03
        I have separated the code for the + Recoll + Unity Scope from the main body of code, in hope that it may + interest someone to work on it. It's Python and simple, + mostly depending on the Unity API. The Ubuntu Unity API is + apparently going to change *again* for the next version, and + I think I've seen enough of it.
        + +
        2014-04-02
        1.19.12 is out. It's mostly identical + to 1.19.11 apart from a new parameter to change the max size + of stored attributes. No need to update in general.
        + +
        2014-02-27
        I hear from time to time about + recollindex crashes. These appear to be quite rare, but they + do happen, and I think that they are linked to a yet unfound + bug in multithread indexing. If you experience such crashes or + stalls, you can disable multithreading by adding the following + to your recoll.conf: +
        thrQSizes = -1 -1 -1
        +
        + +
        2014-02-27
        While working on a + + Recoll-Mutt interface I discovered incidentally that + the Recoll + Webui Web interface works quite well with the + links web browser + inside a terminal window. This appears to be an interesting + solution for people looking for a search interface usable in + a non-GUI environment.
        + +
        2013-11-19
        A new + filter for PowerPoint files. The previous one was + based on the ancient catppt from the catdoc + utilities and usually extracted nothing from more recent + PowerPoint files (this is about .ppt: .pptx is handled by a native + Recoll filter).
        + +
        2013-05-18
        Sometimes things + + just work...
        + +
        2013-04-30
        Thanks to some of its users, Recoll now + has filters to + + index and retrieve Lotus Notes messages + (some + + implementation notes from an early user), and there is + also now a + + Web browser interface for querying your Recoll + indexes.
        + +
        2012-10-25
        A problem with a simple workaround has caused + several reported recollindex + crashes recently (for 1.17). If you store and index + Mozilla/Thunderbird email out of the standard location + (~/.thunderbird), you should add the following at the end of + your configuration file (e.g.: + ~/.recoll/recoll.conf):
        
        +              [/path/to/my/mozilla/mail]
        +              mhmboxquirks = tbird
        +          
        Adjust the path to your local value of course... + Without this hint, recollindex has trouble finding the + message delimiters inside the folder files, and will + possibly use all the computer's memory and crash. Apart from + crashes, which only occur for very big folders, this also + causes incorrect mail indexing. +
        + +
        2012-09-11
        A new user-contributed script for those who use + real-time indexing on laptops: stop or start indexing + according to AC power status. See the details on + the + Wiki.
        + +
        2012-04-07
        We now have a Chinese user manual: + Recoll现在有中文手册咯: + + Recoll中文手册,HTML
        + + +
        +
        + +

        Thanks

        +

        Recoll borrows a lot of code + from other packages, and welcomes code and ideas from + contributors, see some of the + Credits.

        + +

        On the side

        + +
        +
        +

        We rent + a big country house in the Aude area, in the south of + France (see + map on the site). If you are + looking for a wonderful country place with a pool to + spend holidays with a big bunch of family and/or + friends in a nice historical but very quiet area, this may be it.

        +
        +
        + +
        + + diff --git a/website/index.html.fr b/website/index.html.fr new file mode 100644 index 00000000..99093865 --- /dev/null +++ b/website/index.html.fr @@ -0,0 +1,187 @@ + + + + + RECOLL: un outil personnel de recherche textuelle pour + Unix et Linux + + + + + + + + + + + + + + +
        + +

        + Recoll est + un outil personnel de recherche textuelle pour Unix et Linux

        + +

        Il est bas sur le puissant moteur d'indexation Xapian, pour lequel il offre une + interface graphique QT facile d'utilisation, riche, et facile + mettre en oeuvre.

        + +

        Recoll est un logiciel libre + gratuit, dont le code source est disponible sous licence GPL. + La dernire version est + 1.22.3 + (notes sur la version, en + anglais)

        + +

        L'interface utilisateur de + Recoll est traduite en + Franais, mais pas encore la documentation, malheureusement, + et la plupart des liens de cette page pointent sur des textes + en Anglais.

        + + +

        Caractristiques:

        + +
          +
        • Installation facile, peu de dpendances. Pas besoin de + dmon permanent, de serveur http, d'un environnement de bureau + particulier ou d'un langage exotique.
        • + +
        • Tourne sur la plupart des + systmes fonds sur + Unix.
        • + +
        • Interface conue avec + Qt 4. (Qt 3 est support jusqu'aux versions 1.14.x).
        • + +
        • Traite la plupart des + types de documents courants, les messages et leurs fichiers + attachs. Peut aussi traiter leurs versions comprimes + (gzip ou bzip2) de tous ces documents. + Application externes pour + l'extraction du texte.
        • + +
        • Fonctions de recherche puissantes, avec expressions Boolennes, + phrases et proximit, wildcards, filtrage sur les types de fichiers + ou l'emplacement.
        • + +
        • Multi-langage et multi-jeu de caractres, utilisant + Unicode en interne.
        • + +
        • + (plus de dtails)
        • + +
        + +

        Dj utilisateur ? Il est possible qu'il + y ait encore quelques astuces qui vous aient chappes. Un coup + d'oeil rapide sur la page des petites + recettes de recherche (en anglais) pourrait s'avrer + fructueux ! galement, en anglais, la + + page des questions frquentes et trucs divers sur + bitbucket.org

        + +

        Nouvelles:

        + +
        + 2016-11-23
        Version 1.22.4.
        +
        2016-06-15
        La version 1.22.3 est disponible et va + progressivement remplacer 1.21 comme version + principale. Notes de version + (en anglais).
        + +
        2016-05-11
        Release 1.21.7: corrige un crash bnin + mais agaant au moment de quitter l'interface utilisateur + (Fedora 23 / qt5).
        + +
        2015-11-09
        +
        Recoll indexe Windows ! Il y a encore quelques lments + manquants, comme l'indexation temps-rel, et la traduction + en Franais, mais a marche suffisamment bien pour tre + essay. Il y a un installeur standard, donc si vous n'aimez + pas, c'est facile dsinstaller... + Pas de traduction Franaise pour le moment. Il y + a quelques + explications en Anglais sur l'installation . + Si vous l'essayez, dites moi ce que vous en pensez ! +
        + +
        2012-10-25
        Un problme avec une solution simple + peut provoquer + des plantages de + recollindex. + Si vous indexez des messages mail Mozilla/Thunderbird + ailleurs qu' l'endroit standard (~/.thunderbird), vous + devriez ajouter les lignes qui suivent la fin de votre + fichier de configuration (~/.recoll/recoll.conf): +
        
        +              [/path/to/my/mozilla/mail]
        +              mhmboxquirks = tbird
        +          
        Changez le chemin d'accs pour le votre bien + sr. Sans cette indication, recollindex a des difficults + dterminer les limites de message dans les fichiers mailbox, + et peut arriver utiliser toute la mmoire de la machine, + et se planter. Dans les cas moins graves (avec des + fichiers de taille "raisonnable"), cela provoque aussi une + indexation incorrecte des messages. +
        + +
        2010-11-20
        Un petit script pour activer/cacher recoll sur un + bureau gnome d'un seul coup de clavier: + + recette d'installation.
        + + + +

        Support

        + +

        Si vous avez un problme quelconque avec le logiciel ou son + installation, ou une ide de fonctions ajouter, merci de me + contacter.

        + +

        Voir aussi la page sur le + dveloppement.

        +

        Liste des problèmes connus (en + anglais).

        + +

        Remerciements

        +

        Recoll emprunte beaucoup de code + d'autres logiciels libres, et accueille volontiers les + contributions en code ou en suggestions, voir la page des + Attributions.

        + +

        Autres

        +

        Je loue une + + grande maison sympa dans l'Aude :), et nous produisons aussi + du + bois de chauffage. (Il faut bien que cette page me serve + tout de mme quelque chose moi aussi de temps + en temps !).

        + +
        + + diff --git a/website/pages/Makefile b/website/pages/Makefile new file mode 100644 index 00000000..b430acf3 --- /dev/null +++ b/website/pages/Makefile @@ -0,0 +1,10 @@ +.SUFFIXES: .txt .html + +.txt.html: + asciidoc $< + +all: recoll-windows.html recoll-windows-faq.html \ + recoll-webui-install-wsgi.html + +clean: + rm -f *.html diff --git a/website/pages/recoll-webui-install-wsgi.txt b/website/pages/recoll-webui-install-wsgi.txt new file mode 100644 index 00000000..33ce3b6c --- /dev/null +++ b/website/pages/recoll-webui-install-wsgi.txt @@ -0,0 +1,280 @@ += Recoll WebUI Apache and nginx installation from scratch + +NOTE: thanks to Michael L. Wilson for the `nginx` part. + +The https://github.com/koniu/recoll-webui[Recoll WebUI] offers an +alternative, WEB-based, interface for querying a Recoll index. + +It can be quite useful to extend the use of a shared index to multiple +workstations, without the need for a local Recoll installation and shared +data storage. + +The Recoll WebUI is based on the +http://bottlepy.org/docs/dev/index.html[Bottle Python framework], which has +a built-in WEB server, and the simplest deployment approach is to run it +standalone. However the built-in server is restricted to handling one +request at a time, which is problematic in multi-user situations, +especially because some requests, like extracting a result list into a CSV +file, can take a significant amount of time. + +The Bottle framework can work with several multi-threading Python HTTP +server libraries, but, given the limitations of the Recoll Python module +and the Python interpreter itself, this will not yield optimal performance, +and, especially can't efficiently leverage the now ubiquitous +multiprocessors. + +In multi-user situations, you can get better performance and ease of use +from the Recoll WebUI by running it under Apache or Nginx rather than as a +standalone process. With this approach, a few requests per second can +easily be handled even in the presence of long-running ones. + +Neither Recoll nor the WebUI are optimized for high multi-user load, and it +would be very unwise to use them as the search interface to a busy WEB +site. + +The instructions about using the WebUI under Apache as given in the +repository README are a bit terse, and are missing a few details, +especially ones which impact performance. + +Here follows the synopsis of three WebUI installations on initially +Apache-less Ubuntu (14.04) and DragonFly BSD systems, and for +Nginx/BSD. The first should extend easily to other Debian-based systems, +the second at least to FreeBSD. rpm-based systems are left as an exercise +to the reader, at least for now... + + +CAUTION: THE CONFIGURATIONS DESCRIBED HAVE NO ACCESS CONTROL. ANYONE WITH +ACCESS TO THE NETWORK WHERE THE SERVER IS LOCATED CAN RETRIEVE ANY +DOCUMENT. + +link:#nginx[Jump to the nginx section]. + +[[apache]] +== Apache +=== On a Debian/Ubuntu system + +==== Install recoll + + sudo apt-get install recoll python-recoll + +Configure the indexing and check that the normal search works (I spent +quite a lot of time trying to understand why the WebUI did not work, when +in fact it was the normal recoll configuration which was broken and the +regular search did not work either). + +Take care to be logged in as the user you want to run the web search as +while you do this. + + +==== Install the WebUI + +Clone the github repository, or extract the master tar installation, and +move it to '/var/www/recoll-webui-master/'. Take care that it is read/execute +accessible by your user. + +==== Install Apache and mod-wsgi + + + sudo apt-get install apache2 libapache2-mod-wsgi + +I then got the following message: + + AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message + +To clear it, I added a ServerName directive to the Apache config, maybe you +won't need it. Edit '/etc/apache2/sites-available/000-default.conf' and add +the following at the top (globally). Things work without this fix anyway, +this is just to suppress the error message. You probably need to adjust the +address or use a real host name: + + ServerName 192.168.4.6 + + +Edit '/etc/apache2/mods-enabled/wsgi.conf', add the following at the end of +the "IfModule" section. + +Change the user ('dockes' in the example) taking care that he is the one who +owns the index ('.recoll' is in his home directory). + + WSGIDaemonProcess recoll user=dockes group=dockes \ + threads=1 processes=5 display-name=%{GROUP} \ + python-path=/var/www/recoll-webui-master + WSGIScriptAlias /recoll /var/www/recoll-webui-master/webui-wsgi.py + + WSGIProcessGroup recoll + Order allow,deny + allow from all + + +NOTE: the Recoll WebUI application is mostly single-threaded, so it is of +little use (and may actually be counter-productive in some cases) to +specify multiple threads on the WSGIDaemonProcess line. Specify multiple +processes instead to put multiple CPUs to work on simultaneous requests. + + +Then run the following to restart Apache: + + sudo apachectl restart + +The Recoll WebUI should now be accessible. on 'http://my.server.com/recoll/' + +NOTE: Take care that you need a '/' at the end of the URL used to access +the search (use: 'http://my.server.com/recoll/', not +'http://my.server.com/recoll'), else files other than the script itself are +not found (the page looks weird and the search does not work). + +CAUTION: THERE IS NO ACCESS CONTROL. ANYONE WITH ACCESS TO THE NETWORK +WHERE THE SERVER IS LOCATED CAN RETRIEVE ANY DOCUMENT. + +=== Apache Variant for BSD/ports + +==== Packages + +As root: + + pkg install recoll + + +Do what you need to do to configure the indexing and check that the normal +search works. + +Take care to be logged in as the user you want to run the web search as +while you do this. + + pkg install apache24 + +Add apache24_enable="YES" in /etc/rc.conf + + pkg install ap24-mod_wsgi4 + pkg install git + +==== Clone the webui repository + + cd /usr/local/www/apache24/ + git clone https://github.com/koniu/recoll-webui.git recoll-webui-master + +Important: most input handler helper applications (e.g. 'pdftotext') are +installed in '/usr/local/bin' which is not in the PATH as seen by Apache +(at least on DragonFly). The simplest way to fix this is to modify the +launcher module for the webui app so that it fixes the PATH. + +Edit 'recoll-webui-master/webui-wsgi.py' and add the following line after +the 'import os' line: + + os.environ['PATH'] = os.environ['PATH'] + ':' + '/usr/local/bin' + + + +==== Configure Apache + +Edit /usr/local/etc/apache24/modules.d/270_mod_wsgi.conf + +Uncomment the LoadModule line, and add the directives to alias /recoll/ to +the webui script. + +Change the user (dockes in the example) taking care that he is the one who +owns the index (.recoll is in his home directory). + +Contents of the file: + + ## $FreeBSD$ + ## vim: set filetype=apache: + ## + ## module file for mod_wsgi + ## + ## PROVIDE: mod_wsgi + ## REQUIRE: + + LoadModule wsgi_module libexec/apache24/mod_wsgi.so + + WSGIDaemonProcess recoll user=dockes group=dockes \ + threads=1 processes=5 display-name=%{GROUP} \ + python-path=/usr/local/www/apache24/recoll-webui-master/ + WSGIScriptAlias /recoll /usr/local/www/apache24/recoll-webui-master/webui-wsgi.py + + + WSGIProcessGroup recoll + Require all granted + + +==== Restart Apache + +As root: + + apachectl restart + + +[[nginx]] +== Nginx +=== Nginx for BSD/ports + +As root: + + pkg install recoll + +Do what you need to do to configure the indexing and check that the normal +search works. Take care to be logged in as the user you want to run the web +search as while you do this. + +Install required packages: + + pkg install nginx uwsgi git + +=== Nginx: clone the webui repository + + rm /usr/local/www/nginx + mkdir /usr/local/www/nginx + cd /usr/local/www/nginx + git clone https://github.com/koniu/recoll-webui.git recoll-webui-master + +Important: most input handler helper applications (e.g. 'pdftotext') are +installed in '/usr/local/bin' which is not in the PATH as seen by Nginx +(at least on DragonFly). The simplest way to fix this is to modify the +launcher module for the webui app so that it fixes the PATH. + +Edit 'recoll-webui-master/webui-wsgi.py' and add the following line after +the 'import os' line: + + os.environ['PATH'] = os.environ['PATH'] + ':' + '/usr/local/bin' + +Also change the following to find the correct path: + + #os.chdir(os.path.dirname(__file__)) + os.chdir('/usr/local/www/nginx/recoll-webui-master') + + +=== Nginx: configure uWSGI + +Assuming the user running the search is "dockes" (change it to your user), + +sysrc uwsgi_uid=$(id -u dockes) +sysrc uwsgi_gid=$(id -g dockes) +sysrc uwsgi_flags="-M -L --wsgi-file /usr/local/www/nginx/recoll-webui-master/webui-wsgi.py" + +(ALTERNATIVELY) + +Add the following to rc.conf + +uwsgi_uid="dockes" +uwsgi_gid="dockes" +uwsgi_flags="-M -L --wsgi-file /usr/local/www/nginx/recoll-webui-master/webui-wsgi.py" + + +=== Configure nginx + +Edit /usr/local/etc/nginx/nginx.conf and set up a proxy to uwsgi service: + + location / { + include uwsgi_params; + uwsgi_pass unix:///tmp/uwsgi.sock; + } + +=== Enable and start both services + +As root: + + sysrc uwsgi_enable=YES #Or uwsgi_enable="YES" (in rc.conf) + sysrc nginx_enable=YES #Or nginx_enable="YES" (in rc.conf) + + service uwsgi start + service nginx start diff --git a/website/pages/recoll-windows-faq.txt b/website/pages/recoll-windows-faq.txt new file mode 100644 index 00000000..772a1d21 --- /dev/null +++ b/website/pages/recoll-windows-faq.txt @@ -0,0 +1,88 @@ += Recoll on Windows tips and tricks +Jean-Francois Dockes +:toc: + +== Checking that Python is in the PATH + +Recoll input handlers are the programs which extract the documents text +content for indexing. Most of these programs are Python scripts. If Recoll +can find documents by file name but not by content, the first thing to +check is that you do have the Python interpreter in your PATH. + +NOTE: Only Python 2 is supported at the moment (2.7 and later were +tested). This limitation is not caused by the Recoll scripts themselves but +to some of the auxiliary libraries (e.g.: the one used for LibreOffice text +extraction). If you also have Python 3 installed, you will have to arrange +for Recoll to only 'see' the Python 2 version. + +For simple cases, to check that the Python interpreter is in the PATH, the +easiest approach is to start a command window and type 'python' in it. You +should see messages from the Python interpreter, which you can then +exit by typing 'quit()'. If the command interpreter complains about Python +not being found, you probably need to adjust the PATH. + +NOTE: To start a command window, type 'command' in the start menu input +area and select 'Command Prompt'. + +If the Python interpreter is not found, check that Python 2 is indeed +installed. Adding the Python binary to the PATH is an option during +installation (so one approach to fix the issue is to just run the +installation again). + +You can also edit the environment variable directly: + + - Start the Control Panel + - Select 'System and Security' + - Select 'System' + - Select 'Advanced system settings' in the left panel, + - Select 'Environment Variables' at the bottom of the dialog + - Edit 'Path' inside 'System variables' and add: + `C:\Python27\;C:\Python27\Scripts;` to it. + +== Using an alternate configuration directory + +This tip is useful if you want to manage several configurations, or if you +really have some reason to not let the configuration directory stay in its +default location ($HOMEDIR/AppData/Local/Recoll). If your concerns are only +a bout storage space, and do not actually want to manage multiple +configuration directories, you can more simply change the index storage +location from the GUI 'Index Configuration' panel. + +The easiest approach is to create a shortcut on the desktop and have it +start the GUI with a '-c' option. For example, set the shortcut's 'Target' +to something like: + +---- +"C:\Program Files (x86)\Recoll\recoll.exe" -c c:/path/to/my/configdir +---- + +_Do use forward slashes for the configuration directory path_. This will +hopefully be fixed some day. + +You will need to create the configuration directory, Recoll will not do it +by itself. You can just leave it empty, Recoll will then propose to start +the configuration editor. + +You can find a more complete and general explanation about using shortcuts, +for example http://www.rjlsoftware.com/support/faq/sa.cfm?q=6&n=61[on this +page]. + + +== File name character case sensitivity + +_This should be fixed as of the the November 2016 version. Please report +the problem if you still see case sensitivity issues_ + +Recoll was born on Unix, on which file names are case-sensitive. At the +moment this is also the case for path-related queries on Windows, including +the drive letters. + +When filtering results on location (e.g. with a 'dir:' clause), you need to +enter all path elements as they appear in the URLs in result lists (and use +forward slashes). + +It is also advisable to enter configuration filenames with their actual +case (e.g. _topdirs_). + +I am looking into fixing this, but this made a bit complicated by non ASCII +character sets issues. diff --git a/website/pages/recoll-windows.txt b/website/pages/recoll-windows.txt new file mode 100644 index 00000000..f3f72465 --- /dev/null +++ b/website/pages/recoll-windows.txt @@ -0,0 +1,166 @@ += Recoll on Windows +Jean-Francois Dockes +:date: + +:recollversion: 1.23.0-2bfd80-20161115 + +image:recoll-windows10-thumb.png[link="recoll-windows10.png"] + +Recoll for Windows was built on Windows 7, and tried on Windows 7 and +10. It does not work on Windows XP. + +Recoll is free and licensed under the GPL. You will be asked to accept the +license during the installation. For a regular user, and in a nutshell, the +license means that you are free to do what you want with the program (use, +copy, share, etc.). If you are a developper and intend to modify and +distribute the program, you probably know the GPL, else you should read it. + +If you use Recoll on Windows, please consider contributing to its development: +image:/donations/btn_donate_LG.gif[link="/donations/index.html"] + +== Installation + +- Download the + http://www.recoll.org/windows/recoll-setup-{recollversion}.exe[Recoll + setup file]. + +- Execute the setup file. This is a vanilla installer generated by Inno + Setup, and it will ask the usual questions. + +- Download and install Python 2.7.10 or 2.7.11 (e.g. + https://www.python.org/ftp/python/2.7.11/python-2.7.11.msi[Python + 2.7.11]). Recoll currently does not work with Python3. *_On the + `Customize installation` screen, select "Add python.exe to Path"_* + +- Optional: download and install the 7-zip program from + http://www.7-zip.org/. This is only useful if you need to index files + compressed with Unix methods (not needed for zip files). + +NOTE: The installer needs administrator rights in order to install to +`C:\Program Files`. If you want to install on a machine where you have no +administrator rights, you can use the +http://www.recoll.org/windows/recoll-archive-{recollversion}.7z[installation +directory archive] instead and extract it anywhere, this works just the +same (you will need the free http://www.7-zip.org/[7z] to extract it). If +you are in this case, you can ignore the setup-related steps of the +procedure of course. + +== Configuration + +- Start recoll. It will ask if you want to customize the configuration. + The default is to index the content of your user directory. Then start + indexing. This can take some time. +- The default result list font is particularly ugly. Change it from + `Preferences->GUI Configuration->Result List->Result List Font` + +- Have a look at the + https://www.lesbonscomptes.com/recoll/usermanual/webhelp/docs/index.html[Recoll +manual] ! +- I have also started a small link:recoll-windows-faq.html[Recoll on + MS-Windows FAQ]. + +== Support + +Please use the +https://bitbucket.org/medoc/recoll/issues[BitBucket Recoll issues tracker] +for reporting problems, or contact me by email: jfd at recoll.org. + + +== Known problems: + +- Indexing is very slow, especially when using external commands (e.g. for + PDF files). I don't know if this is a case of my doing something stupid, + or if the general architecture is really bad fitted for Windows. If + someone with good Windows programming knowledge reads this, I'd be very + interested by a discussion. Windows indexing can be ten times slower than + the Linux version. The index formats are compatible, so, if you have + shared Linux/Windows data, it's best to process it on Linux. + +- Filtering by directory location ('dir:' clauses) used to be + case-sensitive, including drive letters. This is hopefully fixed by the + November 2016 version. + +- Also, when filtering the search with a `dir:` clause, an absolute path + should be specified as `/c/mydir` instead of `c:/mydir` + +- There is no real-time or scheduled indexing as on Linux. For now, you + create and update the index by using the `File` menu (or executing + `recollindex.exe` from a command window). + +== Change Log + +Changes in 20161115 + +- File path names case sensitivity and other small path issues should be fixed. +- Based on Xapian 1.4. New stemming languages are available (e.g. Arabic). +- Fixed date display encoding issues. + +Changes in 20160414 + +- The setup script has changed back to needing administrator rights, + because this is what is convenient for most people. Use the installation + directory archive to install in a non-standard location without admin + rights. +- Fixed a bug which had the whole indexing stop if a script would time out + on a specific file (it will very rarely happen that a pathologically bad + file can throw an input handler in a loop). + + +Changes in 20160317 + +- Small change to the setup script so that administrative rights are not + required. + +Changes/fixes in 20160129 + +- Changed the method used for checking that index data is up to date with + documents. This will impose a re-indexing of all data, but it was + necessary because the previous method was incorrect. +- Fixed crash which occured after changing some configuration parameters. +- Warn when editing a temporary copy of a document (e.g. a temp file + extracted from a zip archive. + +Changes in 20151202 + +- Fixed mbox parsing. This was getting the message separators completely + wrong, and taking a lot of time to do it. This should be especially + welcome by Thunderbird users. + +- Fixed email attachement processing. A fault in the code which saved + attachment data to disk for further processing resulted in a practical + fuzzing experiment on the input processors. Especially, frequent crashes + in the image tag extractor caused very ennoying Windows popups about + a Python error. + +Fixed in 20151115 and later + +- A relatively rare crash which seemed to occur mostly on some email + messages +- Forgotten MIME settings for .cs, .js and .css + +Fixed in 20151112 and later + +- Forgotten dll prevents the unrtf program to work, so no rtf indexing. + +Fixed in 20151109 (hopefully?) + +- The GUI sometimes crashes when you click `Preview` or `Open`. This does + not occur often, and usually for one of the first tries after starting + the program. Don't despair. This seems to be fixed in the latest version + (20151109), but I am not 100% certain that it is gone. + +++++ +

        Comments

        + +
        + + + comments powered by Disqus +++++ diff --git a/website/perfs.html b/website/perfs.html new file mode 100644 index 00000000..64d2c768 --- /dev/null +++ b/website/perfs.html @@ -0,0 +1,416 @@ + + + + + RECOLL indexing performance and index sizes + + + + + + + + + + + + + + +
        + +

        Recoll: Indexing performance and index sizes

        + +

        The time needed to index a given set of documents, and the + resulting index size depend of many factors. + +

        The index size depends almost only on the size of the + uncompressed input text, and you can expect it to be roughly + of the same order of magnitude. Depending on the type of file, + the proportion of text to file size varies very widely, going + from close to 1 for pure text files to a very small factor + for, e.g., metadata tags in mp3 files.

        + +

        Estimating indexing time is a much more complicated issue, + depending on the type and size of input and on system + performance. There is no general way to determine what part of + the hardware should be optimized. Depending on the type of + input, performance may be bound by I/O read or write + performance, CPU single-processing speed, or combined + multi-processing speed.

        + +

        It should be noted that Recoll performance will not be an + issue for most people. The indexer can process 1000 typical + PDF files per minute, or 500 Wikipedia HTML pages per second + on medium-range hardware, meaning that the initial indexing of + a typical dataset will need a few dozen minutes at + most. Further incremental index updates will be much faster + because most files will not need to be processed again.

        + +

        However, there are Recoll installations with + terabyte-sized datasets, on which indexing can take days. For + such operations (or even much smaller ones), it is very + important to know what kind of performance can be expected, + and what aspects of the hardware should be optimized.

        + +

        In order to provide some reference points, I have run a + number of benchs on medium-sized datasets, using typical + mid-range desktop hardware, and varying the indexing + configuration parameters to show how they affect the results.

        + +

        The following may help you check that you are getting typical + performance for your indexing, and give some indications about + what to adjust to improve it.

        + +

        From time to time, I receive a report about a system becoming + unusable during indexing. As far as I know, with the default + Recoll configuration, and barring an exceptional issue (bug), + this is always due to a system problem (typically bad hardware + such as a disk doing retries). The tests below were mostly run + while I was using the desktop, which never became + unusable. However, some tests rendered it less responsive and + this is noted with the results.

        + +

        The following text refers to the indexing parameters without + further explanation. Here follow links to more explanation about the + processing + model and + configuration + parameters.

        + + +

        All text were run without generating the stemming database or + aspell dictionary. These phases are relatively short and there + is nothing which can be optimized about them.

        + +

        Hardware

        + +

        The tests were run on what could be considered a mid-range + desktop PC: +

          +
        • Intel Core I7-4770T CPU: 2.5 Ghz, 4 physical cores, and + hyper-threading for a total of 8 hardware threads
        • +
        • 8 GBytes of RAM
        • +
        • Asus H87I-Plus motherboard, Samsung 850 EVO SSD storage
        • +
        +

        + +

        This is usually a fanless PC, but I did run a fan on the + external case fins during some of the tests (esp. PDF + indexing), because the CPU was running a bit too hot.

        + + +

        Indexing PDF files

        + + +

        The tests were run on 18000 random PDFs harvested on + Google, with a total size of around 30 GB, using Recoll 1.22.3 + and Xapian 1.2.22. The resulting index size was 1.2 GB.

        + +

        PDF: storage

        + +

        Typical PDF files have a low text to file size ratio, and a + lot of data needs to be read for indexing. With the test + configuration, the indexer needs to read around 45 MBytes / S + from multiple files. This means that input storage makes a + difference and that you need an SSD or a fast array for + optimal performance.

        + + + + + + + + + + + + + + + + + + + + + + + +
        StorageidxflushmbthrTCountsReal Time
        NFS drive (gigabit)2006/4/124m40
        local SSD2006/4/111m40
        + + +

        PDF: threading

        + +

        Because PDF files are bulky and complicated to process, the + dominant step for indexing them is input processing. PDF text + extraction is performed by multiple instances + the pdftotext program, and parallelisation works very + well.

        + +

        The following table shows the indexing times with a variety + of threading parameters.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        idxflushmbthrQSizesthrTCountsTime R/U/S
        2002/2/22/1/119m21
        2002/2/210/10/110m38
        2002/2/2100/10/111m
        + +

        10/10/1 was the best value for thrTCounts for this test. The + total CPU time was around 78 mn.

        + +

        The last line shows the effect of a ridiculously high thread + count value for the input step, which is not much. Using + sligthly lower values than the optimum has not much impact + either. The only thing which really degrades performance is + configuring less threads than available from the hardware.

        + +

        With the optimal parameters above, the peak recollindex + resident memory size is around 930 MB, to which we should add + ten instances of pdftotext (10MB typical), and of the + rclpdf.py Python input handler (around 15 MB each). This means + that the total resident memory used by indexing is around 1200 + MB, quite a modest value in 2016.

        + + +

        PDF: Xapian flushes

        + +

        idxflushmb has practically no influence on the indexing time + (tested from 40 to 1000), which is not too surprising because + the Xapian index size is very small relatively to the input + size, so that the cost of Xapian flushes to disk is not very + significant. The value of 200 used for the threading tests + could be lowered in practise, which would decrease memory + usage and not change the indexing time significantly.

        + +

        PDF: conclusion

        + +

        For indexing PDF files, you need many cores and a fast + input storage system. Neither single-thread performance nor + amount of memory will be critical aspects.

        + +

        Running the PDF indexing tests had no influence on the system + "feel", I could work on it just as if it were quiescent.

        + + +

        Indexing HTML files

        + +

        The tests were run on an (old) French Wikipedia dump: 2.9 + million HTML files stored in 42000 directories, for an + approximate total size of 41 GB (average file size + 14 KB). + +

        The files are stored on a local SSD. Just reading them with + find+cpio takes close to 8 mn.

        + +

        The resulting index has a size of around 30 GB.

        + +

        I was too lazy to extract 3 million entries tar file on a + spinning disk, so all tests were performed with the data + stored on a local SSD.

        + +

        For this test, the indexing time is dominated by the Xapian + index updates. As these are single threaded, only the flush + interval has a real influence.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        idxflushmbthrQSizesthrTCountsTime R/U/S
        2002/2/22/1/188m
        2002/2/26/4/191m
        2002/2/21/1/196m
        1002/2/21/2/1120m
        1002/2/26/4/1121m
        402/2/21/2/1173m
        + + +

        The indexing process becomes quite big (resident size around + 4GB), and the combination of high I/O load and high memory + usage makes the system less responsive at times (but not + unusable). As this happens principally when switching + applications, my guess would be that some program pages + (e.g. from the window manager and X) get flushed out, and take + time being read in, during which time the display appears + frozen.

        + +

        For this kind of data, single-threaded CPU performance and + storage write speed can make a difference. Multithreading does + not help.

        + +

        Adjusting hardware to improve indexing performance

        + +

        I think that the following multi-step approach has a good + chance to improve performance: +

          +
        • Check that multithreading is enabled (it is, by default + with recent Recoll versions).
        • +
        • Increase the flush threshold until the machine begins to + have memory issues. Maybe add memory.
        • +
        • Store the index on an SSD. If possible, also store the + data on an SSD. Actually, when using many threads, it is + probably almost more important to have the data on an + SSD.
        • +
        • If you have many files which will need temporary copies + (email attachments, archive members, compressed files): use + a memory temporary directory. Add memory.
        • +
        • More CPUs...
        • +
        +

        + +

        At some point, the index updating and writing may become the + bottleneck (this depends on the data mix, very quickly with + HTML or text files). As far as I can think, the only possible + approach is then to partition the index. You can query the + multiple Xapian indices either by using the Recoll external + index capability, or by actually merging the results with + xapian-compact.

        + + + +
        Old benchmarks
        + +

        To provide a point of comparison for the evolution of + hardware and software...

        + +

        The following very old data was obtained (around 2007?) on a + machine with a 1800 Mhz AMD Duron CPU, 768Mb of Ram, and a + 7200 RPM 160 GBytes IDE disk, running Suse 10.1.

        + +

        recollindex (version 1.8.2 with xapian 1.0.0) is + executed with the default flush threshold value. + The process memory usage is the one given by ps

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        DataData sizeIndexing timeIndex sizePeak process memory usage
        Random pdfs harvested on Google1.7 GB, 3564 files27 mn230 MB225 MB
        Ietf mailing list archive211 MB, 44,000 messages8 mn350 MB90 MB
        Partial Wikipedia dump15 GB, one million files6H3010 GB324 MB
        Random pdfs harvested on Google
        + Recoll 1.9, idxflushmb set to 10
        1.7 GB, 3564 files25 mn262 MB65 MB
        + +

        Notice how the index size for the mail archive is bigger than + the data size. Myriads of small pure text documents will do + this. The factor of expansion would be even much worse with + compressed folders of course (the test was on uncompressed + data).

        + +

        The last test was performed with Recoll 1.9.0 which has an + ajustable flush threshold (idxflushmb parameter), here + set to 10 MB. Notice the much lower peak memory usage, with no + performance degradation. The resulting index is bigger though, + the exact reason is not known to me, possibly because of + additional fragmentation

        + +
        + + + diff --git a/website/pics/00REMAKEALB.sh b/website/pics/00REMAKEALB.sh new file mode 100644 index 00000000..b90c0ea0 --- /dev/null +++ b/website/pics/00REMAKEALB.sh @@ -0,0 +1,2 @@ +#!/bin/sh +onlylist=1 photalb . . diff --git a/website/pics/index.html b/website/pics/index.html new file mode 100644 index 00000000..3eab3b14 --- /dev/null +++ b/website/pics/index.html @@ -0,0 +1,44 @@ + + + + + Recoll screenshots + + + + + + + + + + + + + + +
        + +

        Recoll Screenshots

        +
      • Back to Recoll home
      • + + + + + + + + + + + + + + + + +
        + diff --git a/website/pics/index.html.head b/website/pics/index.html.head new file mode 100644 index 00000000..32eed3ce --- /dev/null +++ b/website/pics/index.html.head @@ -0,0 +1,27 @@ + + + + + Recoll screenshots + + + + + + + + + + + + + + +
        + +

        Recoll Screenshots

        +
      • Back to Recoll home
      • + diff --git a/website/pics/mario.png b/website/pics/mario.png new file mode 100644 index 00000000..773946b0 Binary files /dev/null and b/website/pics/mario.png differ diff --git a/website/pics/piclist.txt b/website/pics/piclist.txt new file mode 100644 index 00000000..b395b8d9 --- /dev/null +++ b/website/pics/piclist.txt @@ -0,0 +1,9 @@ +recoll0.png +result-table.png +recoll1.png +recoll2.png +recoll3.png +recoll4.png +recoll5.png +recoll_chinese.png +recoll-HTML_search_results.png diff --git a/website/pics/recoll-HTML_search_results-thumb.png b/website/pics/recoll-HTML_search_results-thumb.png new file mode 100644 index 00000000..51fe26f9 Binary files /dev/null and b/website/pics/recoll-HTML_search_results-thumb.png differ diff --git a/website/pics/recoll-HTML_search_results.html b/website/pics/recoll-HTML_search_results.html new file mode 100644 index 00000000..3985edb3 --- /dev/null +++ b/website/pics/recoll-HTML_search_results.html @@ -0,0 +1,40 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        A customized result list, thanks to Michael Croes. The html code follows, +it should be pasted into the +Preferences->Query Configuration->Result paragraph format string entry. + +

        +<table border="1" bgcolor="lightyellow">
        +    <tr>
        +        <td rowspan="4" width="40px" align="center"
        +                valign="center">
        +            <img src="%I" width="32" height="32">
        +            <p><b>%R</b></p>
        +            <p><a href="P%N">Aperu</a></p>
        +        </td>
        +        <th colspan="3" bgcolor="lightgrey">%T</th>
        +    </tr>
        +    <tr>
        +        <td align="center">%M</td>
        +        <td align="center">%D</td>
        +        <td align="center">%S</td>
        +    </tr>
        +    <tr>
        +        <td colspan="3"><a href="E%N">%U</a></td>
        +    </tr>
        +    <tr>
        +        <td colspan="3">%A</td>
        +    </tr>
        +</table>
        +

        +

        + + diff --git a/website/pics/recoll-HTML_search_results.png b/website/pics/recoll-HTML_search_results.png new file mode 100644 index 00000000..918a596b Binary files /dev/null and b/website/pics/recoll-HTML_search_results.png differ diff --git a/website/pics/recoll-HTML_search_results.txt b/website/pics/recoll-HTML_search_results.txt new file mode 100644 index 00000000..04cc7845 --- /dev/null +++ b/website/pics/recoll-HTML_search_results.txt @@ -0,0 +1,28 @@ +A customized result list, thanks to Michael Croes. The html code follows, +it should be pasted into the +Preferences->Query Configuration->Result paragraph format string entry. + +
        +<table border="1" bgcolor="lightyellow">
        +    <tr>
        +        <td rowspan="4" width="40px" align="center"
        +                valign="center">
        +            <img src="%I" width="32" height="32">
        +            <p><b>%R</b></p>
        +            <p><a href="P%N">Aperu</a></p>
        +        </td>
        +        <th colspan="3" bgcolor="lightgrey">%T</th>
        +    </tr>
        +    <tr>
        +        <td align="center">%M</td>
        +        <td align="center">%D</td>
        +        <td align="center">%S</td>
        +    </tr>
        +    <tr>
        +        <td colspan="3"><a href="E%N">%U</a></td>
        +    </tr>
        +    <tr>
        +        <td colspan="3">%A</td>
        +    </tr>
        +</table>
        +
        diff --git a/website/pics/recoll0-thumb.png b/website/pics/recoll0-thumb.png new file mode 100644 index 00000000..e403f4b0 Binary files /dev/null and b/website/pics/recoll0-thumb.png differ diff --git a/website/pics/recoll0.html b/website/pics/recoll0.html new file mode 100644 index 00000000..c5208800 --- /dev/null +++ b/website/pics/recoll0.html @@ -0,0 +1,13 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        Search results.

        +

        + + diff --git a/website/pics/recoll0.png b/website/pics/recoll0.png new file mode 100644 index 00000000..62c64a99 Binary files /dev/null and b/website/pics/recoll0.png differ diff --git a/website/pics/recoll0.txt b/website/pics/recoll0.txt new file mode 100644 index 00000000..9009b211 --- /dev/null +++ b/website/pics/recoll0.txt @@ -0,0 +1,2 @@ +Search results. + diff --git a/website/pics/recoll1-thumb.png b/website/pics/recoll1-thumb.png new file mode 100644 index 00000000..a675fb9f Binary files /dev/null and b/website/pics/recoll1-thumb.png differ diff --git a/website/pics/recoll1.html b/website/pics/recoll1.html new file mode 100644 index 00000000..882ae903 --- /dev/null +++ b/website/pics/recoll1.html @@ -0,0 +1,13 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        A result list with a preview window open.

        +

        + + diff --git a/website/pics/recoll1.png b/website/pics/recoll1.png new file mode 100644 index 00000000..a6104b22 Binary files /dev/null and b/website/pics/recoll1.png differ diff --git a/website/pics/recoll1.txt b/website/pics/recoll1.txt new file mode 100644 index 00000000..798a77b6 --- /dev/null +++ b/website/pics/recoll1.txt @@ -0,0 +1,4 @@ +A result list with a preview window open. + + + diff --git a/website/pics/recoll2-thumb.png b/website/pics/recoll2-thumb.png new file mode 100644 index 00000000..4f4cf021 Binary files /dev/null and b/website/pics/recoll2-thumb.png differ diff --git a/website/pics/recoll2.html b/website/pics/recoll2.html new file mode 100644 index 00000000..d410d3ab --- /dev/null +++ b/website/pics/recoll2.html @@ -0,0 +1,13 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        The two tabs in the advanced search dialog.

        +

        + + diff --git a/website/pics/recoll2.png b/website/pics/recoll2.png new file mode 100644 index 00000000..2fa3a339 Binary files /dev/null and b/website/pics/recoll2.png differ diff --git a/website/pics/recoll2.txt b/website/pics/recoll2.txt new file mode 100644 index 00000000..4e503cb3 --- /dev/null +++ b/website/pics/recoll2.txt @@ -0,0 +1 @@ +The two tabs in the advanced search dialog. diff --git a/website/pics/recoll3-thumb.png b/website/pics/recoll3-thumb.png new file mode 100644 index 00000000..ac6230a7 Binary files /dev/null and b/website/pics/recoll3-thumb.png differ diff --git a/website/pics/recoll3.html b/website/pics/recoll3.html new file mode 100644 index 00000000..74d8ba5f --- /dev/null +++ b/website/pics/recoll3.html @@ -0,0 +1,14 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        A result list from which the native application (firefox) +was started by clicking the Edit link.

        +

        + + diff --git a/website/pics/recoll3.png b/website/pics/recoll3.png new file mode 100644 index 00000000..85de6328 Binary files /dev/null and b/website/pics/recoll3.png differ diff --git a/website/pics/recoll3.txt b/website/pics/recoll3.txt new file mode 100644 index 00000000..47ebed25 --- /dev/null +++ b/website/pics/recoll3.txt @@ -0,0 +1,2 @@ +A result list from which the native application (firefox) +was started by clicking the Edit link. diff --git a/website/pics/recoll4-thumb.png b/website/pics/recoll4-thumb.png new file mode 100644 index 00000000..9ba6aafc Binary files /dev/null and b/website/pics/recoll4-thumb.png differ diff --git a/website/pics/recoll4.html b/website/pics/recoll4.html new file mode 100644 index 00000000..505f8444 --- /dev/null +++ b/website/pics/recoll4.html @@ -0,0 +1,14 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        The document history window looks a little like a result list +I'm afraid...

        +

        + + diff --git a/website/pics/recoll4.png b/website/pics/recoll4.png new file mode 100644 index 00000000..a46290ff Binary files /dev/null and b/website/pics/recoll4.png differ diff --git a/website/pics/recoll4.txt b/website/pics/recoll4.txt new file mode 100644 index 00000000..5cfea539 --- /dev/null +++ b/website/pics/recoll4.txt @@ -0,0 +1,2 @@ +The document history window looks a little like a result list +I'm afraid... diff --git a/website/pics/recoll5-thumb.png b/website/pics/recoll5-thumb.png new file mode 100644 index 00000000..f6e9ff2e Binary files /dev/null and b/website/pics/recoll5-thumb.png differ diff --git a/website/pics/recoll5.html b/website/pics/recoll5.html new file mode 100644 index 00000000..479ccf87 --- /dev/null +++ b/website/pics/recoll5.html @@ -0,0 +1,13 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        The term explorer tool in phonetic mode.

        +

        + + diff --git a/website/pics/recoll5.png b/website/pics/recoll5.png new file mode 100644 index 00000000..09108030 Binary files /dev/null and b/website/pics/recoll5.png differ diff --git a/website/pics/recoll5.txt b/website/pics/recoll5.txt new file mode 100644 index 00000000..ff689efa --- /dev/null +++ b/website/pics/recoll5.txt @@ -0,0 +1 @@ +The term explorer tool in phonetic mode. diff --git a/website/pics/recoll64.png b/website/pics/recoll64.png new file mode 100644 index 00000000..aae65ec0 Binary files /dev/null and b/website/pics/recoll64.png differ diff --git a/website/pics/recoll_chinese-thumb.png b/website/pics/recoll_chinese-thumb.png new file mode 100644 index 00000000..c44549a0 Binary files /dev/null and b/website/pics/recoll_chinese-thumb.png differ diff --git a/website/pics/recoll_chinese.html b/website/pics/recoll_chinese.html new file mode 100644 index 00000000..bbe5b132 --- /dev/null +++ b/website/pics/recoll_chinese.html @@ -0,0 +1,14 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        Recoll searching Chinese text. Chinese text search is based on n-grams and +relatively rough, but still useful (I am told).

        +

        + + diff --git a/website/pics/recoll_chinese.png b/website/pics/recoll_chinese.png new file mode 100644 index 00000000..2dbe6235 Binary files /dev/null and b/website/pics/recoll_chinese.png differ diff --git a/website/pics/recoll_chinese.txt b/website/pics/recoll_chinese.txt new file mode 100644 index 00000000..da25aac6 --- /dev/null +++ b/website/pics/recoll_chinese.txt @@ -0,0 +1,2 @@ +Recoll searching Chinese text. Chinese text search is based on n-grams and +relatively rough, but still useful (I am told). diff --git a/website/pics/result-table-thumb.png b/website/pics/result-table-thumb.png new file mode 100644 index 00000000..f653c595 Binary files /dev/null and b/website/pics/result-table-thumb.png differ diff --git a/website/pics/result-table.html b/website/pics/result-table.html new file mode 100644 index 00000000..262d20d4 --- /dev/null +++ b/website/pics/result-table.html @@ -0,0 +1,13 @@ + + + + Photo + + +

        Prev Up + Next      + Image

        +

        +

        + + diff --git a/website/pics/result-table.png b/website/pics/result-table.png new file mode 100644 index 00000000..c1124226 Binary files /dev/null and b/website/pics/result-table.png differ diff --git a/website/pics/smile.png b/website/pics/smile.png new file mode 100644 index 00000000..49d678dd Binary files /dev/null and b/website/pics/smile.png differ diff --git a/website/rclidxfmt.html b/website/rclidxfmt.html new file mode 100644 index 00000000..0cbdfef4 --- /dev/null +++ b/website/rclidxfmt.html @@ -0,0 +1,196 @@ + + + + Recoll Index format + + + + + + + + + + + +
        +

        Recoll index format details

        + +

        A comparison of index formats for recoll 1.17 and omega + 1.0.1

        + +

        Recoll terms are not stemmed before being stored. They are turned to + all minuscule letters with no accents. An auxiliary database + handles stem expansion. Omega stores both raw + terms (with prefix R) and stemmed versions (with prefix Z). + The xapian-side of the information here comes from the relevant + xapian-omega documentation + page. +

        + +

        Special prefixed terms:

        + +

        A comparison of prefixed term usage between Recoll and + omega/xapian.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        Pref.Recoll useOmega use
        AAuthorSame
        BUnusedReserved
        CUnusedReserved
        Ddate: modification date of file, like + YYYYMMDDSame
        EUnused. Recoll uses XEfile name extension folded to lowercase
        FUnusedReserved
        GUnusednewGroup / forum name
        HUnusedhost name
        IUnused"Can see"
        JUnusedReserved
        KKeywordSame
        LUnusedISO language code
        Mmonth: YYYYMMSame
        NUnusedISO country code
        OUnusedOwner
        PUnusedPath part of URL
        QUnique Id. fs backend: trunc-hashed path+ipath + Other backends may use a different unique id. + Unique Id
        RUnusedRaw (unstemmed) term
        SSubject/titleSame
        Tmime typeSame
        UUnusedFull Url of indexed + document. Truncated/hashed version of URL. Used for + duplicate checks.
        VUnused"Can't see"
        WUnusedOwner
        XPrefix prefix for multichar prefixesSame
        Yyear YYYYSame
        ZUnusedStemmed term
        XEFile name extension folded as lowercase + (omega uses E)Unused
        XPPath elements (for phrase-based directory filtering) + Unused
        XSFNutf8 lowercased/unaccented version of + file name. Used for specific file name searches. NOT SPLIT + (spaces as normal chars).None
        XTORecipientNone
        XXSTNot really a prefix: start of field + marker (for anchored phrase searches)None
        XXNDNot really a prefix: end of field + marker (for anchored phrase searches)None
        + + +

        Values

        + + + + + + + + + + + + +
        Value slotRecoll useOmega use
        0UnusedUnix modification time
        1MD5Same
        2UnusedSize
        10Signature: value to be checked for + up-to-dateness, ie mtime|size for the fs + backendUnused
        + + +

        Document data record format

        + +

        Recoll has the same line based / prefixed data record format + as omega (name=value\n). The Omega data below is quite out of + date.

        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        PrefixRecoll useOmega use
        url=Full url. Always file://abspath. The path is not + encoded to utf-8, this is the system file name ,usable as an + argument to open()Same
        mtype=mime type (omega: type)type=
        fmtime=file modification datemodtime=
        dmtime= document modification dateNone
        origcharset= character set the text was + converted fromNone
        fbytes= file size in bytessize=
        dbytes=document size in bytesNone
        ipath=internal path for docs in multidoc + filesNone
        caption=title of document, utf8Same
        keywords=key words, utf8None
        abstract=document abstract, utf8sample=
        +
        + +
        +
        Jean-Francois Dockes
        + + +Last modified: Sat Feb 25 09:14:38 CEST 2012 + + + diff --git a/website/recoll_XMP/index.html b/website/recoll_XMP/index.html new file mode 100644 index 00000000..6b577cee --- /dev/null +++ b/website/recoll_XMP/index.html @@ -0,0 +1,125 @@ + + +Indexing PDF XMP-metadata + + + + +

        Introduction

        +

        Organizing and searching a large collection of PDFs as part of a research project can be a demanding task. +XMP metadata stored in a PDF, such as journal title, publication year, and user-added keywords, are often useful when searching for a publication. +Here, we describe the use of a custom Recoll filter to retrieve this metadata, an indexing configuration to store it, and result paragraph format to display it. See also a related wiki entry, Generating a custom field and using it to sort results, for sorting results on PDF page count. + +

        Saving metadata to PDFs

        +

        Bibliographic metadata can be saved in the PDF file itself. In the JabRef bibliography manager, this is done with the "Write XMP-metadata to PDFs" menu item. Note the presence of the keywords in the screenshot below; this field is a good place to tag the PDF with any words of your choosing to describe genre, topic, etc. +

        + +

        Custom indexing (fields file)

        +

        Let's create two fields named "year" and "journal". The prefixes starting with "XY" are extension prefixes that are added to the terms in the Xapian database (Recoll internally does not use prefixes starting with XY). Additionally, the year and journal are stored so they can be displayed in the results list. Some other types of metadata, such as title, author and keywords, are already indexed by Recoll (the default rclpdf finds them using the pdftotext command) so there is no need to add those to the [prefixes] section. +

        Add this text to the fields file in your Recoll configuration directory (~/.recoll/fields). +

        +[prefixes]
        +year = XYEAR
        +journal = XYJOUR
        +
        +[stored]
        +year =
        +journal =
        +
        + +

        Custom filter (rclpdf file)

        +

        This is where the heavy lifting happens. The filter should create HTML meta elements for each of the named index fields. Below is a diff between the default rclpdf and a customized one. The PDF metadata is gathered using the pdfinfo command. Then, grep and sed are used to extract the publication year and journal name from metadata fields beginning with "bibtex:" (part of the XMP metadata written by JabRef, in XML format). That information is fed to awk, which puts together the output. The crucial part in the customized awk script is the inclusion of the HTML meta elements with the names "year" and "journal". +

        There is some additional processing carried out by the l2html function. This replaces some LaTeX-style accents (stored in the PDF metadata if the BibTeX file contains them) with HTML entities. Only a few examples are shown here; other LaTeX accents could be processed in a similar manner. If desired, the sed commands could be modified to give UTF-8 characters instead of the HTML entities. +

        The l2html function also converts the LaTeX \emph{...} (emphasized text) to HTML markup for italics, <i>...</i>. With this, and the markup="html" attribute in the HTML meta elements (given in the awk script for the title and at the end of the filter for the author), italicized text and accented characters represented by HTML entities will be shown in the results. +

        One other thing to note: the filter changes the "Subject" HTML meta tag (created by pdftotext) to "Abstract"; this is so that the actual abstract - of the journal article, stored in the BibTeX database and written as metadata to the PDF, and reported by pdftotext as the "Subject" - is indexed independently of the title. Otherwise, terms in the "Subject" and "title" meta tags by default get indexed together by Recoll, so a title: query would actually match words appearing in the abstract. +

        Grab the default rclpdf for Recoll 1.18.1 (most likely /usr/share/recoll/filters/rclpdf) then apply this patch and save the result in ~/.recoll/filters/rclpdf . +

        +104a105,126
        +> 
        +> l2html() 
        +> {
        +>   # redirect the stdin so the function can be used in a pipe
        +>   cat |
        +>   # use sed to replace some accented (LaTeX format) characters
        +>   sed -e 's/\\"a/\&auml;/g' |      # a umlaut
        +>   sed -e "s/\\\'a/\&aacute;/g" |   # a acute
        +>   sed -e "s/\\\\\`a/\&agrave;/g" | # a grave
        +>   sed -e 's/\\u{a}/\&#x103;/g' |   # a breve
        +>   # linebreak so multiple \emph{.*} can be replaced
        +>   sed -e 's/\\emph{/\n&/g' |          
        +>   # \emph{.*} to <i>.*</i> 
        +>   sed -e 's/\\emph{\(.*\)}/\&lt;i\&gt;\1\&lt;\/i\&gt;/g'
        +> }
        +> 
        +> # get PDF metadata
        +> PDFINFO=`pdfinfo -meta "$infile" 2>/dev/null`
        +> # need grep -a (--text) becuase sometimes it treats input as binary
        +> YEAR=`echo "$PDFINFO" | grep -a bibtex:year | sed -e 's/<\/.*>//g' | sed -e 's/<.*>//g'`
        +> JOURNAL=`echo "$PDFINFO" | grep -a bibtex:journal | sed -e 's/<\/.*>//g' | sed -e 's/<.*>//g'`
        +> 
        +107c129
        +< awk 'BEGIN'\
        +---
        +> awk -v year="$YEAR" -v journal="$JOURNAL" 'BEGIN'\
        +111a134,136
        +>   yearmeta = "<meta name=\"year\" content=\""
        +>   journalmeta = "<meta name=\"journal\" content=\""
        +>   endmeta = "\">\n"
        +115a141,146
        +>   if(doescape == 0 && $0 ~ /<\/head>/) {
        +>     match($0, /<\/head>/)
        +>     part1 = substr($0, 0, RSTART-1)
        +>     part2 = substr($0, RSTART, length($0))
        +>     $0 =  part1 yearmeta year endmeta journalmeta journal endmeta part2
        +>   }
        +133c164
        +<     mid = "<title>" mid "</title>"
        +---
        +>     mid = "<meta name=\"title\" markup=\"html\" content=\"" mid "\">"
        +167c198
        +< ' 
        +---
        +> ' | 
        +168a200,205
        +> # replace latex with html markup
        +> l2html |
        +> # replace "Subject" with "Abstract"
        +> sed -e s/\<meta\ name=\"Subject\"/\<meta\ name=\"Abstract\"/g |
        +> # add markup="html" to author meta element
        +> sed -e s/\<meta\ name=\"Author\"/\<meta\ name=\"Author\"\ markup=\"html\"/g
        +
        + +

        Use the source (mimeconf file)

        +

        Recoll needs to know about your custom rclpdf. Make sure the rclpdf is executable, and add this to ~/.recoll/mimeconf (replace <username> with your username). +

        +[index]
        +application/pdf = exec /home/<username>/.recoll/filters/rclpdf
        +
        +

        Then index away! +

        Note that you can also run the rclpdf script manually, e.g. rclpdf /path/to/some.pdf, to inspect the output. If things are working correctly, the <head> consists of the HTML meta elements, and the <body> contains the text of the PDF. + +

        Result paragraph format

        +

        Here, the result is formatted to show the title, which is a link to open the document, in blue with underlining turned off. The next two lines contain the authors, then the journal title in green italicized text followed by year (in parentheses). The keywords are listed in red after the abstract/text snippet. +

        Edit this using the Recoll GUI: Preferences > GUI configuration > Result List > Edit result paragraph format string. +

        +<a href="P%N"><img src="%I" align="left"></a>
        +&nbsp;<span style=font-size:1.15em><a style=text-decoration:none href="E%N">%(title)</a></span><br>
        +&nbsp;%(author)<br>
        +&nbsp;<font color="#009000"><i>%(journal)</i></font>&nbsp;(%(year))
        +&nbsp;<table bgcolor="#e0e0e0"> <tr><td><div>%A</div></td></tr>
        +</table><font color="#900000">%K</font>
        +<br><br>
        +
        +The screenshot below also has the "Highlight color for query terms" set to black; font-weight:bold; for bold, black text (instead of the blue default). There are various methods for creating the thumbnails; the ones here were made by opening the directory containing the PDFs in the Dolphin file manager (part of KDE) and selecting the Preview option. + +

        A search example

        +

        The simple query is cerevisiae keyword:protein. This returns only PDFs that have the text "cerevisiae" and have been tagged with the "protein" keyword. The LaTeX-style formatting from the BibTeX database is displayed as HTML (note the italicized words in article title, and umlaut in author's name). Other queries could be made based on the PDF metadata, e.g. journal:plos or year:2013 . +

        + +

        More possibilities

        +
          +
        • The sort buttons (up- and down-arrows) in Recoll sort the results by the modified date on the file at the time of indexing. If you want this sorting to reflect the publication year, then the timestamp should be set accordingly. If names of the PDFs contain the year (e.g. BZS2007.pdf, CKE+2011.pdf), the following one-liner would set the modified date to January 1st of the year: for i in `ls *.pdf`; do touch -d `echo $i | sed 's/[^0-9]*//g'`-01-01 $i; done . Note that the publication year could then be shown in the result list using the stored date of the file (using "%D" in the result paragraph format, and date format "%Y") instead of having to add the year to the index as shown above. +
        • The filter can be modified to fill in the "journal" field for BibTex entries that aren't journal articles (e.g. bibtex:booktitle for "InCollection" entries). +
        + + diff --git a/website/recoll_XMP/jabref_metadata.png b/website/recoll_XMP/jabref_metadata.png new file mode 100644 index 00000000..d312add6 Binary files /dev/null and b/website/recoll_XMP/jabref_metadata.png differ diff --git a/website/recoll_XMP/recoll_query.png b/website/recoll_XMP/recoll_query.png new file mode 100644 index 00000000..23b371d3 Binary files /dev/null and b/website/recoll_XMP/recoll_query.png differ diff --git a/website/release-1.14.4.html b/website/release-1.14.4.html new file mode 100644 index 00000000..098e81c2 --- /dev/null +++ b/website/release-1.14.4.html @@ -0,0 +1,53 @@ + + + + Recoll 1.14.4 release notes + + + + + + + + + + + + + + + + +
        + +

        Release notes for Recoll 1.14.4

        + +

        Recoll 1.14.4 fixes a number of small + bugs

        +

        Installing over an older version: version 1.13/14 indexes are + mostly compatible with 1.11, but some new, relatively minor, + features (ie: duplicates collapsing) depend on a full index + rebuild. The 1.14 date search feature does not need an + index rebuild, the data was already in the index. + +
        If installing over 1.10 or older, you need a full + rebuild. The best way to do this is to just delete the old + .recoll/xapiandb directory, + especially if the index was created by an older version. + (ie: rm -rf ~/.recoll/xapiandb/). On very + old indexes, recollindex -z may sometimes end + with a backend doesn't implement metadata error, + which is wasteful because you then need to delete xapiandb and + run the indexing again.

        +
        + + diff --git a/website/release-1.15.html b/website/release-1.15.html new file mode 100644 index 00000000..d305c95c --- /dev/null +++ b/website/release-1.15.html @@ -0,0 +1,194 @@ + + + + Recoll 1.15 series release notes + + + + + + + + + + + + + + + + +
        + +

        Release notes for Recoll 1.15.0/1.15.9

        + +

        Notes: + +

          +
        • 1.15.9 fixes a startup crash in 1.15.8. This occurs only on + some architectures, and if you are not experiencing the problem + (it happens every time if at all), you do not need to + upgrade.
        • + +
        • 1.15.8 fixes quite a few bugs (see + the BUGS file) and also + breaks my promise to only fix bugs in minor releases because + it also has a few small functional improvements (which + actually border on the bug fix category): +
            +
          • Searches now allow negative directory filtering (all + results except from the specified directory). Other + attempts at still impossible negative searches (ie: -mime:) now cause explicit errors + messages instead of lame results. The inverted directory + filtering is accessible from the query language and by + checking a checkbox in the advanced search panel.
          • + +
          • The GUI advanced search panel now allows specifying a + field for each entry (ie: author/recipient, etc).
          • + +
          • Added filters for .war (Konqueror web archive) and + .mhtm (other web archive format).
          • + +
          • Result table: +
              +
            • The detail area now has a popup menu similar + to the one in the result list (open parent, save to + disk etc.).
            • +
            • Estimated result counts are displayed in the + status line.
            • +
            +
          • +
          +
        • 1.15.6 and 1.15.7 almost exclusively fix build issues (except + for the indication of the stemming language in the menu, fixed in + 1.15.7). If you are running 1.15.5, you probably don't need to + upgrade.
        • +
        • 1.15.5 fixes more crashes still in 1.15.2. See the + BUGS file
        • +
        • 1.15.2 fixes the GUI startup crash described below, and an + issue with very long path elements, which manifested itself mainly + while indexing the Beagle queue.
        • +
        • 1.15.1 is identical to 1.15.0 except for a very + small modification to allow building with qt 4.4.
        • +
        +

        + +

        Caveats

        + +

        There have been reports of the recoll 1.15 GUI crashing when + starting up after an upgrade. This was fixed by making a + backup of ~/.config/Recoll.org/recoll.conf and deleting it (Qt + stores the QSettings for the recoll GUI in this file, things + like the search history and mix GUI options).

        + +

        If the result list is displayed with strange indentations, try + to completely clear the result list paragraph format (in query + preferences) to reset it to the default. Next time you open query + preferences, the new default format will be up, and you can make + any desired changes.

        +

        The support for Qt 3 has been removed in this version which + uses only native Qt 4 interfaces. If your system has no + support for Qt 4.4 or newer, you need to stick + with Recoll 1.14, which is + still supported.

        + +

        The defaults for file name searches with multiple fragments + changed from OR to AND: see the changes list below for more + detail.

        + +

        Installing over an older version: version 1.15/14/13 + indexes are mostly compatible with 1.11 indexes, but some features + depend on a full index rebuild. These are: + +

          +
        • Filtering results from a given directory subtree.
        • +
        • Displaying simple filenames in the new result table.
        • +
        +

        + +

        If installing over 1.10 or older, you need a full + rebuild. The best way to do this is to just delete the old + .recoll/xapiandb directory, + especially if the index was created by an older version. + (ie: rm -rf ~/.recoll/xapiandb/). On very + old indexes, recollindex -z may sometimes end + with a backend doesn't implement metadata error, + which is wasteful because you then need to delete xapiandb and + run the indexing again.

        + +

        Changes

        + +

        Recoll 1.15.0 has major new GUI features and fixes a number + of small bugs

        + +
          + +
        • The GUI has a new display for the result list inside a + spreadsheet-like table, with configurable columns and sort by + any column. The table header right-click menu has the reset + sort function and column adding/removing.The "classical" look + is still there, you can dynamically switch between list and + table by clicking the table-like icon in the toolbar.
        • + +
        • The old sort tool is gone. There are now vertical arrows in + the tool bar to directly sort by date ascending or descending, + which was its only significant use.
        • + +
        • We added duplication indicators to the result list when results + are collapsed because they have bit-for-bit identical + contents. The indicater is the collapse count in parentheses, + displayed just after the relevancy percentage.
        • + +
        • There is now a menu entry to clear search history.
        • + +
        • File name search: it used to be that multiple fragments + where OR'ed together to perform the search. They are now AND'ed, + which makes more sense in many cases (remembering several + fragments of the file name but not the order), but means that a + search for *.doc *.odt will always + fail. Use ext:doc OR  ext:odt instead.
        • + +
        • Autophrase now works with the query language where it makes + sense.
        • + +
        • Support for lyrics in midi karaoke files. Works + better with the + Python chardet + character encoding identification module.
        • + +
        • Support newer Purple/Pidgin logs using an html format.
        • + +
        • Support thunderbird extreme brokiness in handling the mbox + format: naked "^From $" separators are now accepted + with mhmboxquirks = tbird.
        • + +
        • A change of method for filtering on directory location makes + it much more efficient and faster.
        • + +
        • The utf-8 file name is now a stored field by default.
        • + +
        • We now catch all exceptions in Python filters to avoid + crash reports from the system on benign filter failures.
        • + +
        • Indexing now creates a lock/pid file inside the + configuration directory.
        • + +
        • Fixed parallel build issue on FreeBSD.
        • + + +
        + + +
        + + diff --git a/website/release-1.16.html b/website/release-1.16.html new file mode 100644 index 00000000..b0bf9ce9 --- /dev/null +++ b/website/release-1.16.html @@ -0,0 +1,206 @@ + + + + Recoll 1.16 series release notes + + + + + + + + + + + + + + + + +
        + +

        Release notes for Recoll 1.16.x

        + + +

        Caveats

        + +

        Installing over an older version: 1.16 is + mostly compatible with 1.15 indexes, except for a few differences + for weird terms containing punctuation signs. Perform a full index + pass if installing over an older version. The simplest way to do + this is to quit all recoll programs and just delete the index + directory (rm -rf ~/.recoll/xapiandb), then + start recoll or recollindex. recollindex -z will do the same in most + cases.

        + +

        Also, using the anchored search feature requires a full reindex.

        + +

        1.16.2: this is a bug fix release, (see the + fixed bugs document), with a few + limited changes: +

          +
        • The indexer now puts itself in the ionice "idle" class by + default (can be changed in the config).
        • + +
        • The verbosity level of some messages were adjusted so that a + simple sequence of indexed files can now be seen while indexing + with the verbosity at level 3 (info).
        • + +
        • New command line options for the recollq program add a fully + parseable base64-encoded output mode, with full control on the + list of fields printed for each result, for use by external + programs.
        • +
        +

        +

        The 1.16.0 GUI can be crashed quite easily, please + just upgrade to 1.16.1 or later.

        + +

        Changes

        + +

        Recoll 1.16 is an incremental improvements release over 1.15, no + major function was introduced or modified.

        + +
          + +
        • Images are displayed in preview. You can get at the fields + and complete extracted text using the popup menu.
        • + +
        • The preview window popup menu has a "save to file" entry + to write a subdocument (ie: mail attachement) to a file.
        • + +
        • The GUI advanced search panel allows specifying a + field for each entry (ie: author/recipient, etc).
        • + +
        • It is now possible to anchor searches to the beginning or + end of the text or field, by using ^ and $ + characters at the beginning or the end of a term or + phrase. A maximum distance can be specified as a phrase + slack either in the advanced search panel, or as a query + language modifier, ie: "^beginterm"o10 would search + for beginterm within 10 terms of the beginning of + the text. This feature was suggested to me (thanks Gkhan), + for searching for a name at the beginning of a text + (in the author list, as opposed to anywhere in + the text). This is useful for example in the very common + case where the metadata for the author list was not + created. More details about this feature are to be found in + the user + manual.
        • + +
        • It is possible to configure the result list snippet + separator, given as an html fragment. This is an ellipsis by + default (&hellip;).
        • + +
        • We can now perform negative directory filtering (-dir:/some/dir), + to return all results except those from the + specified directory (recursive). Other attempts at still + impossible negative searches + (ie: -mime:) now cause explicit + errors messages instead of lame results. The inverted + directory filtering is accessible from the query language + and by checking a checkbox in the advanced search + panel.
        • + +
        • Result table: +
            +
          • The detail area now has a popup menu similar + to the one in the result list (open parent, save to disk + etc.).
          • +
          • The result table header popup menu has an entry to save the + table as a CSV file.
          • +
          • Estimated result counts are displayed in the status line.
          • +
          • Set row height according to default font size, and better + adjust row height and vertical text position in + cells.
          • +
          +
        • + +
        • It is now possible to set an increased weight for indexing + some fields. The title fields gets a boost by default. See + the fields default file for details.
        • + +
        • The query language allows setting weights on terms, ie, + as in: "important"2.5 .
        • + +
        • Improved preservation of indentation for text files + displayed in the preview window.
        • + +
        • Show hidden (dot) files in the indexing configuration + GUI dialogs.
        • + +
        • Added filters for .war (Konqueror web + archive), .mhtm (other web archive format) + and rar archives.
        • + +
        • Improved handling for native cjk punctuation signs.
        • + +
        • Updated the list of native apps in the + default mimeview (ie: xv->gwenview, rox->dolphin, + etc.)
        • + +
        • Added -f option to recollindex to ignore + skippedPaths/Names when used with -i. Allows the use of a + purely external file selection mechanism.
        • + +
        • The performance of email indexing has been slightly + improved (less CPU usage).
        • + +
        • Real time indexer: several configuration + parameters allow adjusting the timing of indexing actions: +
            +
          • monauxinterval: the interval between auxiliary + databases rebuilds (stemdb, aspell).
          • +
          • monixinterval: The waiting period + during which indexing events are accumulated prior to actual + indexing (saves work on duplicate events).
          • +
          • mondelaypatterns: a list of file patterns for + which indexing should be delayed longer (quick changing + files like logs that should be reindexed much slower than + they change).
          • +
          + See the default configuration file for more detail. +
        • + +
        • Fixed bugs: +
            +
          • UTF-8 paths inside ZIP archives were mishandled. Also + fixes problem with colons inside archive member + paths.
          • +
          • Fixed GUI result list doc parent operations (open/preview) + which were broken in 1.15.
          • +
          • Fixed case where indexing could hang or crash after an + error occured while indexing an archive member (which + should have affected only the relevant document).
          • +
          • Real time indexer: uncontrolled concurrent access to + the global configuration could cause a startup crash (mostly of + big file trees because of timing issues).
          • +
          • Fixed sorting by document and file size in the result + table.
          • +
          • Email messages for which there would be an error indexing + an attachment would not be indexed at all.
          • +
          • Text files bigger than 2 GB could not be indexed.
          • +
          • Fixed the handling of compressed man pages.
          • +
          • Memory usage could grow almost unbounded while deleting + documents, because idxflushmb was not used for document + deletions.
          • +
          +
        • + +
        + + +
        + + diff --git a/website/release-1.17.html b/website/release-1.17.html new file mode 100644 index 00000000..64be99f2 --- /dev/null +++ b/website/release-1.17.html @@ -0,0 +1,255 @@ + + + + Recoll 1.17 series release notes + + + + + + + + + + + + + + + + +
        + +

        Release notes for Recoll 1.17.x

        + + +

        Caveats

        + +

        Installing over an older version: 1.17 is mostly + compatible with 1.16 and 1.15 indexes, except for a few + differences for weird terms containing punctuation + signs. Also, file/document size computations have been + improved in 1.17 and you'll need an index reset if you want to + enjoy the new goodness. Always reset the index if installing + over an older version (1.14 and older). The simplest way to do + this is to quit all recoll programs and just delete the index + directory + (rm -rf ~/.recoll/xapiandb), + then start recoll or + recollindex. recollindex -z + will do the same in most cases.

        + +

        Some new, auxiliary, features do require a full reindex to work:

        +
          +
        • The file size filtering functions.
        • +
        • The anchored search feature if the index was created by + release 1.15 or older.
        • +
        + + +

        Notes to the kind packagers:

        + +
          +
        • you need to either depend on libqt4-webkit or run + configure --disable-webkit (1st option preferred if possible + of course).
        • +
        • The default build now installs the Python extension module. + This means that it needs the Python development + package. You can revert to the old behaviour by using + configure --disable-python-module.
        • +
        + + +

        Changes

        + +

        1.17.4 is quite probably the last update on the very stable + 1.17 branch. It has updated German and Greek messages, and fixes + a few bugs, see the BUGS + file.

        + +

        1.17.3 fixed a nasty indexing bug in email processing + code. This was triggered most probably my messages containing + Microsoft mimehtml attachments, but possibly by other ones + too, and caused an indexing crash. Also fixes small glitches + in result list paging.

        +

        1.17.2 fixed a few bugs and + adds a small feature for handling characters that should not + be accented in your language (ie: å in swedish). See + unac_except_transx in the manual configuration + section. Also a new rcldia filter for Dia files.

        +

        1.17.1 was released only for a small function needed for + supporting the Unity Lens. If you don't need it, you can stay + with 1.17.0.

        +

        Recoll 1.17 is an incremental improvements release over 1.16, + with quite a few changes under the hood (like the introduction + of a webkit-based result list), but relatively few obvious + changes for the casual user.

        + + + + +

        Recoll 1.17.0 changes:

        + +
          + +
        • GUI/config: new set of dialogs to set up the indexing + schedule, either as automatic real time indexing started + with the user session or as discrete cron entries. This + will take care of the details of autostart files or crontab + editing.
        • + +
        • Search: Recoll now supports filtering on file sizes. This + is accessible from the advanced search panel, or from the + query langage (ie: "size>10k size<1m"). For + documents stored inside archives, the file size stored in + the index is now the actual one, not the archive's as was + previously the case. Because of this, you will need a full + reindex to completely enable this feature.
        • + +
        • Query language: the "dir:" directive now accepts + non-absolute paths. For example dir:dir1/dir2 will select + any file the path of which includes "dir1/dir2".
        • + +
        • Query language: tilde is now expanded inside a "dir:" + clause.
        • + +
        • General: the Python extension module is now installed by + default. This will make it much easier to use small recoll + integration and extension hacks like the Unity Lens.
        • + +
        • Desktop: there is a new Ubuntu Unity Recoll Lens, it is not + installed by default, but quite easy to install, see + the + Wiki page.
        • + +
        • GUI: it is now possible to cancel a query that takes too + long. Because of limitations in Xapian, this forces a program + exit, but it's probably better than staring at a hung + Recoll.
        • + +
        • GUI/advanced search: the dialog gets new sections for + filtering on file dates and sizes, and has been split into two + tabs: for search terms, and for filtering.
        • + +
        • GUI: use Shift+PageUp instead of Shift+Home to rewind the + result list to the first page. Shift+Home is useful in the + search entry.
        • + +
        • GUI: the preview function will now check that the index is + up to date before fetching the preview data, and propose to + update the index if necessary. This is especially important + for mail folders. It was previously possible that the + preview would display a message unrelated to the current + result.
        • + +
        • GUI: it is now possible to control the date format + displayed by the results (go to Query Preferences).
        • + +
        • GUI: when a search fails to retrieve results, the spelling + suggestions are now presented as links inside the result list + area. Clicking a link will replace the appropriate word inside + the search entry.
        • + +
        • GUI: thumbnails will be displayed in the result list if + found in the standard freedesktop thumbnails directory + (previously created by gimp or some file manager). This Recoll + release will not create thumbnails.
        • + +
        • GUI: it is now possible to Copy/Paste from the term explorer + result list.
        • + +
        • GUI: what used to be the document category filters + (media/text/etc.) are now defined as query language + fragments + inside mimeconf. This means + that you can redefine them freely (see the comments for the + [guifilters] section in the + default mimeconf).
        • + +
        • GUI: it is now possible to use a Qt style sheet to modify + many aspects of Recoll appearance. A style sheet file can be + selected from the GUI query configuration dialog. A sample + skeleton style sheet is to be found in the + share/recoll/examples directory.
        • + +
        • GUI: the result list is now based on the WebKit widget + instead of QTextBrowser. This means better HTML/CSS support, + and even Javascript ... You can force the use the old + QTextBrowser instead by using + configure --disable-webkit. See a few CSS examples in + the result list customisation + examples page
        • + +
        • GUI: added menu entry to show all the mime types actually + indexed.
        • + +
        • GUI/indexing: the indexing thread has been removed. All + indexing is now performed by a separate recollindex + process. This has multiple advantages, the thread was just a + very bad idea. Among others, exiting the GUI has no + influence on an ongoing indexing.
        • + +
        • GUI/indexing: new menu entry to force a full reindex.
        • + +
        • GUI/config: the indexing configuration now only shows the + directories customized by the user, not those which come + from the standard configuration (ie: + ~/.thunderbird). Showing the standard directories was more + often confusing than useful.
        • + +
        • GUI: the default result list paragraph now displays the ipath: + this is very useful for archive members and not too + disturbing for other kinds.
        • + +
        • Command line query: can now select a result slice + (first result rank and count of results). New option for + easy parsing of results by another program.
        • + +
        • Indexing: handle the html5 charset meta tag.
        • +
        • Indexing: added support for Okular notes and Gnumeric.
        • + +
        • Real time indexer: restart automatically when the + configuration changes.
        • + + +
        • Fixed bugs: +
            +
          • Indexing configuration: deleting one customized + directory would sometimes delete the whole list (depending + on Qt version I think).
          • +
          • Indexing configuration: adding a customized directory + would not make it the active/current one (so that + another click was needed to choose it before making + modifications).
          • +
          • The GUI preview now performs an up to date check + before displaying data from a subdocument, and proposes + to reindex the container if it changed. This is mostly + useful for mailbox containers, where preview would + sometimes display the wrong message (if the folder had + been compacted).
          • +
          • Fix a bug in html charset detection. The wrong charset + was sometimes used for GUI preview.
          • +
          • The chm filter can now process files lacking a Topics + node.
          • +
          • The default slack for proximity searches from the query + language (ie: "word1 word2"p) had become 0. It was restored to + 10.
          • + +
          +
        • + +
        + + +
        + + diff --git a/website/release-1.18.html b/website/release-1.18.html new file mode 100644 index 00000000..934ef6c6 --- /dev/null +++ b/website/release-1.18.html @@ -0,0 +1,203 @@ + + + + Recoll 1.18 series release notes + + + + + + + + + + + + + + + + +
        + +

        Release notes for Recoll 1.18.x

        + + +

        Caveats

        + +

        Installing over an older version: 1.18 introduces + significant index formats changes to support optional + character case and diacritics sensitivity, and it will be + advisable to reset the index in most cases. This will be best + done by destroying the index directory (rm -rf + ~/.recoll/xapiandb).
        + If 1.18 is not configured for case and + diacritics sensitivity, it is mostly compatible with 1.17 + indexes.

        + +

        Case/diacritics sensitivity is off by default for this + release. It can be turned on only by editing recoll.conf + ( + see the manual). If you do so, you must then reset the index.

        + +

        Always reset the index if installing over an even older + version (1.16 and older). The simplest way to do this is to + quit all recoll programs and just delete the index directory + (rm -rf ~/.recoll/xapiandb), + then start recoll or + recollindex. recollindex -z +  will do the same in most, but not all, cases.

        + +

        The subdirectories of xapiandb which were previously used to + store the stem expansion database (stem_english, + stem_french...) are not used anymore, because the data is now + stored in the Xapian synonyms table. They will stay around if + you do nothing about them, so you may want to delete them if + you have not chosen to just delete the whole index + directory.

        + +

        Viewer exceptions: + There is a new list of mime types that should be opened with + the locally configured application even when Use + Desktop Preferences is checked. This allows making + use of new functions (direct access to page), which could not + be available through the desktop's xdg-open. The + default list contains PDF, Postscript and DVI, which should be + opened with the evince (or atril for + Mint/MATE users) viewer for the page access functions to + work. If you want to keep the previous behaviour (losing the + page number functionality), you need to prune the list after + installation . This can be done from the Preferences->Gui + Configuration menu.

        + +

        Changes

        + +

        Recoll 1.18 has some major changes, the most visible of + which is the ability to search for exact matches of character case + and diacritics.

        + +
          + +
        • The index can now be configured for case and diacritics + sensitivity, in which case raw terms are indexed. On such an + index, search insensitivity to case and diacriics is obtained, + when desired, by query time expansion, in a similar manner to + what is used for stemming. See the + + manual chapter for details about controlling the + feature. The capacity for case/diacritics sensitivity is + off by default, and you should not see differences in this + respect after upgrading if you do not turn it on + explicitely. Even on a raw index, most searches should + behave like they did in 1.17. Sensitivity must be + explicitely requested in most cases.
        • + +
        • The advanced search screen now has a history + function. While the focus is in this window, you + can walk the history of searches using the up and down + arrows.
        • + +
        • Recoll has a new capacity to store page break locations + and use them when opening a document at the location for a + given match. It will also pass a search string to the viewer + application. This currently works with PDF, Postscript and DVI + documents, and, optimally, the evince viewer.
        • + +
        • The GUI result list has a new "snippets" window for + documents with page numbers, which let the user choose a + snippet and open the document at the appropriate page.
        • + +
        • There is a list of MIME types that should be opened with + the locally configured application even when Use + Desktop Preferences is checked. This will permit, for + example, using evince for its page access + capabilities on PDF files, while letting the desktop handle + all the other mime types. The list is not empty by default, + it contains PDF, Postscript and DVI, so you may want to + reset it after installation if you want to keep the previous + behaviour (losing the page number functionality). This can + be done from the Preferences->Gui Configuration + menu.
        • + +
        • We now allow multiple directory specifications in the query + language, as in: dir:/home/me -dir:tmp
        • + +
        • The search inside the GUI preview window, has been + improved, and allows selecting from a list one of the + initial term groups as the search target.
        • + +
        • A new script dedicated to laptops, which can start or stop + recollindex according to mains power status.
        • + +
        • Added <pre style="white-space: pre-wrap"> to plain + text HTML display options. This will often be the best + option to display plain text: it will better respect + indentation, while folding long lines.
        • + +
        • When running in an UTF-8 locale, and after failing to decode a + plain text file as UTF-8, indexing will try again using an 8 bit + character set heuristically chosen according to the locale + language code. This uses the LANG environment variable.
        • + +
        • On initial installation (when the ~/.recoll + directory does not exist), recoll will install a list of + characters which should not be stripped of diacritics, + according to the detected national language (based on + $LANG). There are currently specific lists for German (don't + strip the umlauts), and Nordic languages (keep the letters + with circle above in addition to the German list). Other + languages currently only have exceptions which result in + decomposing ligatures (fl, fi etc.). You can have a look at + the standard recoll.conf in /usr/share/recoll/examples for + more information.
        • + +
        • A new configuration variable, maxmemberkbs, has been + implemented to limit the size of archive members we process. This + will avoid trying to read a 4 GB ISO from a zip archive as + happened in the past...
        • + +
        • Proper error reporting when a wildcard expansion is + truncated for size. An incomplete search could previously be + performed without any indication.
        • + +
        • More effort is also put in choosing the terms used in + generating the snippets inside the result list.
        • + +
        • Recoll now uses the Xapian "synonyms" mechanism to store all + data about stemming, case, and diacritics expansion (this + replaces the previous ad-hoc stemming expansion + mechanism).
        • + +
        • Partial autodetection of thunderbird mailboxes found out + of the configured location.
        • + +
        • Fixed bugs: +
            +
          • The unac_except_trans mechanism could be buggy in some + cases and generate wrong character translations.
          • +
          • Don't terminate monitor for permissions-related + addwatch error.
          • +
          • Fix handling of ODF documents exported by Google + docs.
          • +
          • It was previously impossible to open the parent of an + embedded document (e.g. the CHM file for an HTML page + inside the CHM) if the parent was itself a member of an + archive.
          • +
          +
        • + +
        + + +
        + + diff --git a/website/release-1.19.html b/website/release-1.19.html new file mode 100644 index 00000000..fef25791 --- /dev/null +++ b/website/release-1.19.html @@ -0,0 +1,261 @@ + + + + Recoll 1.19 series release notes + + + + + + + + + + + + + +
        +

        Release notes for Recoll 1.19.x

        + +

        Caveats

        + +

        Installing over an older version: 1.19

        + +

        Case/diacritics sensitivity is still off by default for this release. It can +be turned on only by editing recoll.conf (see the manual). +If you do so, you must then reset the index.

        + +

        To be safe, always reset the index when upgrading to 1.19. There + was a persistent index corruption issue in 1.18 + and earlier versions. + The simplest way to do this is to quit all Recoll + programs and just delete the index directory ( + rm -rf ~/.recoll/xapiandb), then start + recoll or recollindex.
        + recollindex -z  will do the same in most, but + not all, cases. It's better to use the rm method, which will also + ensure that no debris from older releases remain (e.g.: old stemming files + which are not used any more).

        + +

        Installing 1.19 over an 1.18 index will force a lot of reindexing anyway +because Recoll switched to using st_ctime instead of st_mtime to +detect file modifications, meaning that all files which were modified since +created will be updated.

        + +

        Viewer exceptions: as in 1.18 (but we kept +this section for 1.17 users), there is a list of mime types that should be +opened with the locally configured application even when Use Desktop +Preferences is checked. This allows making use of new functions (direct +access to page), which could not be available through the desktop's +xdg-open. The default list contains PDF, Postscript and DVI, which +should be opened with the evince (or atril for Mint/MATE +users) viewer for the page access functions to work. If you want to keep the +previous behaviour (losing the page number functionality), you need to prune +the list after installation . This can be done from the Preferences->Gui +Configuration menu.

        + +

        Minor releases at a glance

        +
          +
        • 1.19.14p2 fixes another reference count issue in the Python + module (a problem with the Query iterator put in evidence by the + change in 1.19.14p1). It also changes the handling of diacritics + for Bengali (accents are now unstripped, as for Hindi).
        • + +
        • 1.19.14p1 fixes a descriptor and memory leak in the Python + module. The main library and programs are unchanged.
        • + +
        • 1.19.14 fixes relatively minor but ennoying issues in + indexing, plus a few other glitches: +
            +
          • The use of a separate readonly + Database object + for querying the index while indexing would trigger Xapian + errors, (bad block reads), and subsequent up-to-date check + failures (leading to unnecessary reindexing). The jury is out + as to the cause, but using the same object for reading and + writing seems to eliminate the problem. This is linked to + a Xapian + ticket.
          • +
          • An unnecessary log message in the child process between + forking and executing the filter could block on a mutex, and + lead to a 20 mn timeout for the affected father process thread + (happened only in multithread mode).
          • +
          • Also a possible overflow of the filter stack. This could only + really happen in pathological situations (hand-crafted recursive + zip file...).
          • +
          +
        • + +
        • 1.19.13 hopefully fixes the rare but longstanding multithread + indexing crashes, which I hope were actually due to the now + corrected mismanagement of Xapian::Document objects. It also + silences noisy but mostly harmless ppt-dump.py crashes.
        • +
        • 1.19.12p2 fulfills an old promise that I had forgotten: have a + double-click in the result table run an "open file" action. It just + had waited for too long...
        • +
        • 1.19.12p1 fixes the 1.19.12 install script which did not + actually copy the xls filter...
        • +
        • 1.19.12 adds a parameter for setting the truncation size of the + stored metadata attributes, and a new XLS filter.
        • +
        • 1.19.11 is a fix to the install script in 1.19.10. The latter + did not copy the new ppt extraction code to the filters directory.
        • +
        • 1.19.10 has a bit more changes than + usually goes into a Recoll minor version, and could have been + 1.20.0 instead. On the other hand, it + brings some features which needed to be released, and did not + really warrant a major version. So here goes: +
            +
          • Python3 compatibility for the Python Recoll module.
          • +
          • A Ubuntu Unity Scope for saucy (13.10), replacing the + lens (and which needed Python 3).
          • +
          • A new PPT format text extractor. Catppt just did not extract + anything from more recent .ppt files.
          • +
          Mostly, if you are not running Ubuntu (Saucy or later), you + can just download the ppt + filter and stay with 1.19.9. +
        • 1.19.9 fixes a few + significant bugs, mostly a very + serious one about date filtering, and a quite common GUI + crash.
        • +
        • 1.19.8 changes the way we handle Hindi / Devanagari + text (no more stripping of diacritics), and also has a fix for the + results table dups and snippets links.
        • +
        • 1.19.7 is 1.19.5 with a few build and packaging fixes. No need + to update.
        • +
        • 1.19.5 works around a Linux kernel bug that would make it + impossible to index data from a network share mounted through cifs + (this worked in 1.18 and stopped working in 1.19 because of its + wider use of extended attributes)
        • +
        • 1.19.4 has a German translation, and a few fixes + for relatively ennoying + bugs.
        • +
        • 1.19.3 has more translations (Spanish, Russian, Czech), and a few + minor bug and usability fixes.
        • +
        • 1.19.2 fixes a bug in path translations for additional indexes.
        • +
        • 1.19.1 was released 2 hours after 1.19.0 (book of records anyone?) + because of a bug in the advanced search history feature which crashed + the GUI as soon as a filename search was performed.
        • +
        + +

        Changes in Recoll 1.19.0

        +
          +
        • Indexing can use multiple threads. This can be a major performance boost + for people with multiprocessor machines and big indexes. The threads setup + is roughly auto-configured when recollindex starts, based on the number of + processors, but it is also possible to taylor it in the configuration.There + is a section + in the manual to describe the configuration, and also some notes about + the transformation and the performance improvements.
        • +
        • There is a new result list/table popup menu option to display all the + sub-documents for a given one. This is mostly useful to display the + attachments to an email. The resulting screen can be used to select + multiple entries and save them to files.
        • +
        • It is now possible to use OR with "dir:" clauses, and wildcards have been + enabled.
        • +
        • When the option to follow symbolic links is not set -which is the + default- symbolic links are now indexed as such (name and + content).
        • +
        • The advanced search panel now has a history feature. Use the + up/down arrows to walk the search history list.
        • +
        • There are new GUI configuration options to run in "search as you type" + mode (which I don't find useful at all...), and to disable the Qt + auto-completion inside the simple search string. The completion was often + more confusing and ennoying than useful, especially because it is + case-insensitive when case sometimes matter for Recoll searches + (capitalization to disable stemming).
        • +
        • When the option to collapse identical results is used, documents which do + have duplicates are shown with a link to list the clones. This function + needs new data from the index, so it will only completely work after a full + 1.19 reindex.
        • +
        • Recoll should now behave reasonably on video files: index the name and + propose an Open button in the result list to start the configured + player.
        • +
        • Thanks to Recoll user Koniu, you + can now access your Recoll indexes through a Web browser interface. The + server side is based on the Bottle + Python Web framework and the Recoll Python module, and can run + self-contained (no necessity to run apache or another web server), so it's + quite simple to set up. See: See the Recoll WebUI project on + GitHub.
        • +
        • Thanks to Recoll user David, there is now a filter to index and retrieve + Lotus Notes messages. See the software site on + sourceforge and some notes + from a user with a slightly different configuration.
        • +
        • There is a new path translation facility, with a GUI interface, to make + it easier to share an index from a network share on clients on which the + mount points might be different. This could also probably be put to use to + design a "portable index" feature (for removable media).
        • +
        • The first indexing run after Recoll installation (for a new user) will + run in a fashion which will put data likely to be useful into the index + faster, so that an impatient user can more quickly try searches.
        • +
        • Implemented cache for last file uncompressed. This will much improve + usage, e.g. for people fetching successive messages from a compressed mail + folder.
        • +
        • Recollindex will now change its current directory to a temporary one + (e.g. /tmp) to mitigate the problems of some filters creating temporary + files and not cleaning them.
        • +
        • There is a new recursive explicit reindex option to the command line + indexer.
        • +
        • The default result list paragraph format has been slightly tweaked + (removed the relevance percentage and small ordering and formatting + changes).
        • +
        • Mime type wildcard expansion is now performed against the index, not the + configuration. This fixes many problems when searching for, e.g., media + files indexed only by name.
        • +
        • The choice for case/diacritics sensitivity is now fully processed during + wildcard expansion (for case-sensitive indexes).
        • +
        • The Snippets popup (list of pages and excerpts typically produced for PDF + documents) can now use an external CSS stylesheet. This is useful because + the Qt Webkit objects do not fully inherit the Qt configuration so that, + for example, a style sheet is needed for using a different background + color. The style sheet is chosen from the Preferences->GUI + configuration->Result list panel.
        • +
        • Improved handling of filters during indexing resulting in less + subprocesses.
        • +
        • Added function to import tags from external application (e.g. Tmsu).
        • +
        • Changed format for rclaptg field. Was colon-separated, now uses normal + value/attributes syntax with an empty value like: +
                      localfields = ; attr1 = val1 ; attr2 = val2
          +    
          +
        • +
        • Extended file attributes are now indexed by default. As a side effect, + recoll now uses st_ctime, not st_mtime to detect file changes. This means + that installing 1.19 will reindex many files (all those that were modified + since created). Recoll also now processes the charset and + mime_type standardized extended attributes.
        • +
        • The Python module has been expanded to include the interface for + extracting data. This means that you could now write most of the Recoll GUI + in Python if you wished. There is a bit + of sample code in the source package doing just this. A few + incompatible changes had to be made to the Python module. Especially the + "Query.next" field is gone and the module structure has been changed + (different import statement needed). Adapting your code is trivial, have a + look at the changes in the Unity + Lens module for an example. The new module is compatible with the Python Database API + Specification v2.0 for the parts that make sense for a non-relational + DB.
        • +
        • Recoll now uses a dynamic library for the code shared by the query + interface, the indexer and the Python module. This should have no visible + impact but was rendered necessary by the Python module evolutions.
        • +
        • And quite a few Fixed bugs
        • +
        +
        + + diff --git a/website/release-1.20.html b/website/release-1.20.html new file mode 100644 index 00000000..c062f493 --- /dev/null +++ b/website/release-1.20.html @@ -0,0 +1,255 @@ + + + + Recoll 1.20 series release notes + + + + + + + + + + + + + +
        +

        Release notes for Recoll 1.20.x

        + +

        Caveats

        + +

        Installing over an older version: 1.19

        + +

        Installing 1.20 over an 1.19 index is possible, but there + have been small changes in the way compound words (e.g. email + addresses) are indexed, so it will be best to reset the + index. Still, in a pinch, 1.20 search can mostly use an 1.19 + index.

        + +

        Always reset the index if you do not know by which version it + was created (you're not sure it's at least 1.18). The best method + is to quit all Recoll programs and delete the index directory + ( + rm -rf ~/.recoll/xapiandb), then start recoll + or recollindex.
        + + recollindex -z will do the same + in most, but not all, cases. It's better to use + the rm method, which will also ensure that no debris + from older releases remain (e.g.: old stemming files which are + not used any more).

        + +

        Case/diacritics sensitivity is off by default. It can be + turned on only by editing + recoll.conf ( + + see the manual). If you do so, you must then reset the + index.

        + + +

        Minor releases at a glance

        + +
          +
        • 1.20.6 fixes some decompression issues with serious + performance and system load consequences in some cases + (depending on data): minimum checking that enough temp + space is available before uncompressing, no need to + uncompress tar.gz files. Also: rclscribus fixes, Danish + translation and fix messages in two places which were + not translated.
          + Uncompressing big files to /tmp for nothing (and re-doing it on + the next indexing pass...) was, I believe the main + remaining reason why Recoll indexing could cause system + performance issues.
        • +
        • 1.20.5 is 1.20.4 with a few Qt 5 compatibility + tweaks. Builds and runs with Qt 5.3.2, fails with 5.2.
        • +
        • 1.20.4 has a fix to skip compress file system images + like xxx.img.gz by default. This should have been in 1.20.3
        • +
        • 1.20.3 has a very minor change to copy the Query + Fragments Window config file from the default if it does + not exist in the user config dir.
        • +
        • 1.20.2 fixes a bug which prevented the real time indexer + from indexing the web history queue (this was still processed + when starting up). It also adds systray capability to + the GUI.
        • +
        + + +

        Changes in Recoll 1.20.1

        + +
          + +
        • An Open With entry was added to the result list + and result table popup menus. This lets you choose an + alternative application to open a document. The list of + applications is built from the information inside + the + /usr/share/applications desktop files.
        • + +
        • A new way for specifying multiple terms to be searched + inside a given field: it used to be that an entry lacking + whitespace but splittable, like [term1,term2] was + transformed into a phrase search, which made sense in some + cases, but no so many. The code was changed so that + [term1,term2] now means [term1 AND term2], and + [term1/term2] means [term1 OR term2]. This is + useful for field searches where you would previously be + forced to repeat the field name for every term. + [somefield:term1 somefield:term2] can now be expressed as + [somefield:term1,term2]. +
        • + +
        • (1.20.1) The Query Fragments tool was added to + the GUI. This is a window with customizable buttons to add + arbitrary query language fragments to the current + search. The buttons and fragments are defined in an xml + file inside the recoll configuration + directory ~/.recoll/fragbuts.xml. This + makes it easy to define "pre-cooked" filters for things + that you need repeatedly. + + See the manual for more details.
        • + +
        • We changed the way terms are generated from a compound + string (e.g. an email address). Previously, for an address + like jfd@recoll.org, only the simple terms and + the terms anchored at the start were generated + (jfd, recoll, org, jfd@recoll, jfd@recoll.org). The + new text splitter generates all the other possible terms + (here, recoll.org only), so that it is now + possible to search for left-truncated versions of the + compound, e.g., all emails from a given domain.
        • + +
        • (1.20.1) New keyboard accelerators for the result table: Ctrl+r + switches the focus from the search entry to the table, + Ctrl+o opens the document for the current line, Ctrl+Shift+o + opens document and closes recoll, Ctrl+d previews the + document.
        • + +
        • (1.20.1) A special term is now indexed for results from the web + history: use "-rclbes:BGL" to exclude the web results, + "rclbes:BGL" to restrict the results to the web ones. This + is difficult to remember, but the Query Fragments feature + means that you don't need to (this is in the sample Query + Fragments file).
        • + +
        • Recoll now indexes #hashtags as such.
        • + +
        • It is now possible to configure the GUI in wide form + factor by dragging the toolbars to one of the sides (their + location is remembered between sessions), and moving the + category filters to a menu (can be set in the + "Preferences->GUI configuration" panel).
        • + +
        • We added the indexedmimetypes and + excludedmimetypes variables to the configuration + GUI, which was also compacted a bit. A bunch of + ininteresting variables were also removed.
        • + +
        • When indexing, we no longer add the top container + file name as a term for the contained sub-documents (if + any). This made no sense in most cases, as it meant that + you would get hits on all the sections from a chm or epub + when the top file name matched the search, when you + probably wanted only the parent document in this case.
          + However, the container file name was sometimes useful for + filtering results, and it is still accessible, in a + different way: the top container file name is added as a + term to all the sub-documents, only for searching with + a prefix. The field name + is containerfilename, and no + match on the subdocuments will occur if the field is not + specified (this is different from + previous filename processing, + which was indexed as a general + term. containerfilename is + also set on files without sub-documents (e.g. a pdf).
        • + +
        • A new attribute, pfxonly, + was created to support the above change. This can be set + on any metadata field inside + the [prefixes] section of + the fields file. The + affected field terms will be indexed only with a + prefix, so they will cause a hit only for a field + search (the general behaviour is that field terms are + indexed both prefixed and not, so they can also cause a + hit when searched as general terms).
        • + +
        • A new [queryaliases] + section was created in + the fields, for definining + field name aliases to be used only at query time (to avoid + unwanted collection of data on random fields during + indexing). The section is empty by default, but 2 obvious + aliases are commented: filename=fn + and containerfilename=cfn. Setting + them in your personal file may save you some typing if you + search on file names.
        • + +
        • You can now use both -e and -i for + erasing then updating the index for the given file + arguments with the same recollindex command.
        • + +
        • We now allow access to the Xapian docid for Recoll + documents in recollq and + Python API search results. This allows writing scripts + which combine Recoll and pure Xapian operations. A sample + Python program to find document duplicates, using MD5 + terms was added. See + src/python/samples/docdups.py
        • + +
        • The command used to identify the mime types of files + when the internal method fails used to be hard-coded + as file -i. It is now + possible to customize this command by setting + the systemfilecommand in the + configuration. A suggested value would + be xdg-mime, which sometimes + works better than file.
        • + +
        • The result list has two new elements: %P substitution + for printing the parent folder name, and an F + link target which will open the parent folder in a + file manager window. e.g. <a href='F%N'>Open parent directory</a> +
        • + +
        • /media was added to the default + skippedPaths list mostly as a reminder that blindly + processing these with the general indexer is a bad idea + (use separate indexes instead).
        • + +
        • recollq + and recoll -t get a new + option -N to print field + names between values when + -F is used. In addition, + -F "" is taken as a + directive to print all fields.
        • + +
        • Unicode hyphen (0x2010) is + now translated to ASCII + minus + during indexing and searching. There is no good way to + handle this character, given the varius misuses of minus + and hyphen. This choice was deemed "less bad" than the + previous one.
        • + + + +
        + + +
        + + diff --git a/website/release-1.21.html b/website/release-1.21.html new file mode 100644 index 00000000..ff8ddc95 --- /dev/null +++ b/website/release-1.21.html @@ -0,0 +1,158 @@ + + + + Recoll 1.21 series release notes + + + + + + + + + + + + + +
        +

        Release notes for Recoll 1.21.x

        + +

        Caveats

        + +

        Installing over an older version: 1.19

        + +

        1.20 and 1.21 indexes are fully compatible. Installing 1.21 + over an 1.19 index is possible, but there have been small + changes in the way compound words (e.g. email addresses) are + indexed, so it will be best to reset the index. Still, in a + pinch, 1.21 search can mostly use an 1.19 index.

        + +

        Always reset the index if you do not know by which version it + was created (you're not sure it's at least 1.18). The best method + is to quit all Recoll programs and delete the index directory + ( + rm -rf ~/.recoll/xapiandb), then start recoll + or recollindex.
        + + recollindex -z will do the same + in most, but not all, cases. It's better to use + the rm method, which will also ensure that no debris + from older releases remain (e.g.: old stemming files which are + not used any more).

        + +

        Case/diacritics sensitivity is off by default. It can be + turned on only by editing + recoll.conf ( + + see the manual). If you do so, you must then reset the + index.

        + +

        Changes in Recoll 1.21.0

        + +
          +
        • Allow saving queries to files and reloading them + later. Available both for simple and advanced queries, and + based on XML files.
        • +
        • A Bison-based query parser replaces the old regexp-based + one and allows parenthized sub-expressions and easier future + expansions.
        • +
        • The GUI gets a "close to system tray" function.
        • +
        • Avoid retrying to index previously indexed files if + nothing seems to have changed in the filters.
        • +
        • Improve indexing speed by always using vfork() for + spawning external commands.
        • +
        • The pdf filter gains the capability to run OCR (tesseract) on + image-only files. This happens automatically on image-only + pdfs if tesseract is available.
        • +
        • Improved checks about when we should try to uncompress + stuff. Will eliminate some of the most dreadful cases of + recollindex having an impact on system performance.
        • +
        • Warn if non-existent paths are listed in the configuration + file (help with typos).
        • +
        • Adjust background color for webkit-based elements (result + list and snippets window) according to desktop setup.
        • +
        • Listing the results with the KIO slave is now + performed with incremental updates. Bumped max entries to + 10000.
        • +
        + +

        Minor releases

        +
          +
        • 1.21.7: +
            +
          • Sidestep bus error in qt exit code by calling _exit() + instead of exit() in GUI exit code.
          • +
          • Avoid dependance of librecoll.so on libX11.
          • +
          • Hungarian translation.
          • +
          +
        • +
        • 1.21.6: +
            +
          • New version of the kio slave for KDE5.
          • +
          • Very minor other fixes.
          • +
          +
        • +
        • 1.21.5: +
          • Fixes a nasty bug affecting all previous 1.21 versions: + the query language parser processed incorrectly multiple + mime type or category specifications, with missing results + as a consequence.
          • +
          +
        • + +
        • 1.21.4: +
            +
          • Show confirmation dialog when opening a temporary file + (to warn the user about possible lost edits). The dialog + has a 'disable' checkbox.
          • +
          • Fixed bug which would crash the GUI when clicking an + Open link after modifying the indexing configuration + through the GUI tool.
          • +
          • Fix not showing results with paths over 1000 + characters.
          • +
          • Fix Show subdocs: too many docs were shown in some + cases, and the Preview button in the dialog was inactive.
          • +
          +
        • 1.21.3: +
            +
          • Web cache: fixed the GUI config to not cap the size at + 1 GB. added append function to test driver/maintenance + utility. +
          • +
          +
        • 1.21.2: +
            +
          • Added GUI dialog to perform partial indexing.
          • +
          • Avanced search in "Any Clause" mode: directory filter + would not filter but add an ORed clause.
          • +
          • Fix bogus syntax errors about parentheses around + phrases.
          • +
          • Fixed a few boundary conditions detected by VC++
          • +
          • Misc other small fixes, see commit log.
          • +
          +
        • +
        • 1.21.1: +
            +
          • Force memory usage limits on external filters.
          • +
          • GUI: add Ctrl+l as a shortcut to return focus to the + search entry (compat with web browsers).
          • +
          • result list popup allows saving results from web cache + to files.
          • +
          • The web history indexer also processes non-html files + (e.g.: pdfs).
          • + +
          +
        • +
        + +
        + + diff --git a/website/release-1.22.html b/website/release-1.22.html new file mode 100644 index 00000000..69353e49 --- /dev/null +++ b/website/release-1.22.html @@ -0,0 +1,154 @@ + + + + Recoll 1.22 series release notes + + + + + + + + + + + + + +
        +

        Release notes for Recoll 1.22.x

        + +

        Caveats

        + +

        Some of the input handlers were converted from shell scripts + to Python programs, and some helper dependancies changed. For + example, you will need to install python-libxml2 and + python-libxslt1 in most cases (for replacing xsltproc).

        + +

        Installing over an older version: 1.19

        + +

        1.20-22 indexes are fully compatible. Installing 1.22 + over an 1.19 index is possible, but there have been small + changes in the way compound words (e.g. email addresses) are + indexed, so it will be best to reset the index. Still, in a + pinch, 1.22 search can mostly use an 1.19 index.

        + +

        Always reset the index if you do not know by which version it + was created (e.g.: you're not sure it's at least 1.18). The + best method is to quit all Recoll programs and delete the + index directory ( + rm -rf ~/.recoll/xapiandb), then start recoll + or recollindex.
        + + recollindex -z will do the same + in most, but not all, cases. It's better to use + the rm method, which will also ensure that no debris + from older releases remain (e.g.: old stemming files which are + not used any more).

        + +

        Case/diacritics sensitivity is off by default. It can be + turned on only by editing + recoll.conf ( + + see the manual). If you do so, you must then reset the + index.

        + +

        Changes in Recoll 1.22.0

        + +
          + +
        • The main "feature" in recoll 1.22 is that it has + a Microsoft Windows + version. This is has been tested on Windows 7 and + Windows 10, and it works mostly like the Unix version, with + the notable exceptions that it has no real-time mode (need to + start indexing by hand from the GUI, or arrange something with + the command-line recollindex.exe). Also there are a few very + Unix-y file types which are not processed on Windows, and the + indexer is single-threaded.
        • + +
        • It is now possible to define synonyms groups, used only at + query-time to expand the query terms to their defined + synonyms. + + More details.
        • + +
        • Many shell-script input handlers have been converted to + Python and are now persistent. Most are compatible with + Python3 (the only ones which are not are kept back by the + library they use). There are still a few shell handlers, + mostly for less used and Linux-only formats. And a single + Perl-based one (rclimg, which uses the excellent exiftool + Perl library).
        • + +
        • The Unix/Linux build system has been converted to use the + autotools in a fairly standard way. The Windows build is + based on Qt Creator and MinGW.
        • + +
        • Make dehyphenation (co-worker->coworker in addition to the + normal terms) optional, active by default.
        • + +
        • For people using the Firefox web page indexer add-on: a + new tool in the GUI to list and delete entries from the Web + cache.
        • + +
        • Improved index statistics in the GUI, and improved display + while the indexer is working.
        • + +
        + +

        Minor releases

        +
          +
        • 1.22.4: +
            +
          • Fix advanced search 'start search' button doing + nothing under qt5.
          • +
          • Fix html escaping with newer versions of + pdftotext.
          • +
          • New Danish and Dutch messages.
          • +
          +
        • +
        • 1.22.3: +
            +
          • Python module: do not limit result fetches to initial + Xapian result count, which is often underestimated.
          • +
          • Small bug fix in the text splitter: which resulted in + missing results when matching a file name extension + using, e.g. filename:doc$ instead of ext:doc.
          • +
          • Added suffix associations for .java and .sql, to fix + problems caused by the switch from 'file' to 'xdg-mime'.
          • +
          +
        • +
        • 1.22.2: +
            +
          • Small fixes for building the KIO
          • +
          • Fixed debian packaging issues.
          • +
          +
        • +
        • 1.22.1: +
            +
          • Sidestep bus error in qt exit code by calling _exit() + instead of exit() in GUI exit code.
          • +
          • Eliminate the dependance of librecoll.so on libX11.
          • +
          • Hungarian translation.
          • +
          • GUI: enable displaying the Xapian docid in the result + list with %x.
          • +
          • GUI, advanced search: fix crash which occurred when + restoring clause list bigger than the default size (6 + clauses).
          • +
          • The documentation (user manual and man page) for + recoll.conf is now generated from the structured + comments in the sample file.
          • +
          +
        • + +
        + + diff --git a/website/release-history.html b/website/release-history.html new file mode 100644 index 00000000..83b218ec --- /dev/null +++ b/website/release-history.html @@ -0,0 +1,177 @@ + + + + Recoll release history + + + + + + + + + + + + + +
        +

        Major Recoll releases at a glance

        + +

        A summary of the major releases and the main features which + came with them.

        + +
        + +
        Release 1.23: C++11
        +
        +
          +
        • Replace a bunch of locally grown hacks with c++11 + standard features, esp. std::thread, std::mutex etc. As + c++11 support is now mandatory, get rid of compatibility + code (e.g. switches to use c++11 smart pointers or the + local version).
        • +
        • Convert the logging facility to use c++ streams + instead of stdio.
        • +
        • Allow execm input handlers to set arbitrary data + fields. Previously, the only way for handlers to provide + metadata was through HTML meta fields.
        • +
        • fn and cfn queryaliases enabled by default.
        • +
        + + +
        Release 1.22: Windows + port, autotools-based Unix/Linux build system.
        +
        +
          +
        • A new autotools-based build system replaces the old + mostly homegrown one for Unix-like platforms.
        • +
        • Recoll was ported to Windows, where the build is based + on MinGW and Qt Creator.
        • +
        • New synonyms expansion feature.
        • +
        +
        + + +
        Release 1.21: new + query parser
        +
        +
          +
        • A Bison-based query parser replaces the old + regexp-based one and allows parenthized + sub-expressions and easier future + expansions.
        • +
        • Avoid retrying to index previously + indexed files if nothing seems to have + changed in the filters.
        • +
        • Allow saving queries to files and reload them + later. Available both for simple and advanced queries, and + based on XML files.
        • +
        • Improve indexing speed by always using + vfork() for spawning external commands.
        • +
        • GUI gets "close to system tray" function.
        • +
        +
        + +
        Release 1.20: small + improvements
        +
        +
          +
        • Open With results list popup menu entry.
        • +
        • fieldname:term1,term2 + and fieldname:term1/term2 shortcuts for AND/OR + searches inside fields.
        • +
        • Query fragments tool.
        • +
        • Better handling of compound terms like mail + addresses.
        • +
        • Selection on source collection type (Web history / File + system).
        • +
        • Configurable GUI geometry.
        • +
        • Different handling + of container file / subdocuments file name searches.
        • +
        • Simultaneous -e -i options to recollindex.
        • +
        +
        + +
        Release 1.19: multithreads + indexing
        +
        +
          +
        • Better indexing performance through + multithreading.
        • +
        • Display list of subdocuments (e.g. attachments) for a + given result.
        • +
        • Collapsed duplicate results display link.
        • +
        • Path translation facility (for portable indexes).
        • +
        • Caches last uncompressed file (e.g. for fast + compressed mbox access).
        • +
        • Partial recursive reindex option to command line + indexer.
        • +
        • Can import tags from external application.
        • +
        • Extended attributes indexing is on by default.
        • +
        • New Python interface for data access. API re-modeled against + newer Python Database API 2.0.
        • +
        • Shared librecoll.so.
        • +
        +
        + +
        Release 1.18: case and + diacritics switchable sensitivity
        +
        +
          +
        • Index configuration for case and diacritics sensitivity.
        • +
        • Advanced search history.
        • +
        • Page-level access when opening PDFs, and snippets + window.
        • +
        • Use Xapian Synonyms tables for query expansion.
        • +
        +
        + +
        Release 1.17: small + improvements
        +
        +
          +
        • Language-dependant unaccenting.
        • +
        • GUI dialogs for indexing schedule setup.
        • +
        • Phrase-based dir: filtering, accepting path + fragments. Size filtering.
        • +
        • Python module default install and Unity Lens.
        • +
        • Result list switched to WebKit: drops qt3 support.
        • +
        • Indexing always performed by separate process.
        • +
        • Dynamic category filters (defined as language fragments).
        • +
        +
        + +
        Release 1.16: small + improvements
        +
        +
          +
        • Images displayed in preview window.
        • +
        • Save to file popup in preview.
        • +
        • Fields in advanced search.
        • +
        • Searches anchored to beginning or end of text.
        • +
        • Saving the result table to CSV.
        • +
        • Improved indentation in preview window.
        • +
        +
        + +
        Release 1.15: results + table
        +
        +
          +
        • Optional spreadsheet presentation of results.
        • +
        • Clear search history.
        • +
        • Better thunderbird mbox format handling.
        • +
        +
        + +
        + + diff --git a/website/resparpics/christopher.png b/website/resparpics/christopher.png new file mode 100644 index 00000000..530c1e98 Binary files /dev/null and b/website/resparpics/christopher.png differ diff --git a/website/resparpics/clean.png b/website/resparpics/clean.png new file mode 100644 index 00000000..23a46c96 Binary files /dev/null and b/website/resparpics/clean.png differ diff --git a/website/resparpics/default.png b/website/resparpics/default.png new file mode 100644 index 00000000..a20e8938 Binary files /dev/null and b/website/resparpics/default.png differ diff --git a/website/resparpics/detailSmallGreyTable.png b/website/resparpics/detailSmallGreyTable.png new file mode 100644 index 00000000..98dc29bd Binary files /dev/null and b/website/resparpics/detailSmallGreyTable.png differ diff --git a/website/resparpics/issue73+table.png b/website/resparpics/issue73+table.png new file mode 100644 index 00000000..7f7d2267 Binary files /dev/null and b/website/resparpics/issue73+table.png differ diff --git a/website/resparpics/issue73.png b/website/resparpics/issue73.png new file mode 100644 index 00000000..a5c90c8a Binary files /dev/null and b/website/resparpics/issue73.png differ diff --git a/website/resparpics/pip.png b/website/resparpics/pip.png new file mode 100644 index 00000000..76869fa5 Binary files /dev/null and b/website/resparpics/pip.png differ diff --git a/website/resparpics/pz3.png b/website/resparpics/pz3.png new file mode 100644 index 00000000..c6157527 Binary files /dev/null and b/website/resparpics/pz3.png differ diff --git a/website/resparpics/structuredTable.png b/website/resparpics/structuredTable.png new file mode 100644 index 00000000..817bf0dd Binary files /dev/null and b/website/resparpics/structuredTable.png differ diff --git a/website/resparpics/weblike.png b/website/resparpics/weblike.png new file mode 100644 index 00000000..340f0313 Binary files /dev/null and b/website/resparpics/weblike.png differ diff --git a/website/styles/style.css b/website/styles/style.css new file mode 100644 index 00000000..62bf869e --- /dev/null +++ b/website/styles/style.css @@ -0,0 +1,122 @@ +/*--General-----------------------------------------------*/ +html { + margin: 0; +} +body { + position: relative; + color: black; + font-family: Verdana, Helvetica, Arial, sans-serif; + margin: 1em; +} + +a img { + border:none; + margin:0px; + padding:0px; +} + +/*- Menu---------------------------------------*/ + +div.rightlinks { + width: 130px; + float: right; + font-size: 80%; + padding-top: 4em; +} + +.rightlinks ul { + margin-left: 2px ; + padding-left: 1.5em ; + line-height: 200%; +} + +/*-Main content area-------------------------*/ +.content { + margin-top: 2em; + margin-left: 2em; + margin-right: 145px; +} + +.content img { + margin: 0.3em; +} + +.content dt { + font-weight: bold; +} + +h1, h2, h3, h4, h5, h6 { + margin-left: -1em; + color: #222299; +} + +h1 { + font-weight: normal; + font-size: 140%; + padding-bottom: 1em; +} +h2 { + font-weight: normal; + font-size: 120%; + padding-top: 1em; +} +h3 { + font-weight: bold; + font-size: 100%; + padding-top: 1em; +} +p.indexthumb { + margin-left: 1em; +} +.guimenu, .guimenuitem, .guisubmenu, +.guilabel, .interface, .guibutton, +.shortcut, .shortcut .keycap { + background-color: #F0F0F0; + font-family: monospace; +} + +p.remark { + color: #888888; + font-size: 80%; + font-style: italic; + margin-left: 4em; + margin-right: 4em; +} +div.news { + font-size: 90%; + margin-right: 5em; +} +.application { + font-weight: bold; +} +.literal { + font-family: monospace; +} +.command { + font-family: monospace; +} +.filename { + font-family: monospace; + color: #007a00; +} + +.important { + background: yellow; +} +a.weak { + color: #aaaaaa; +} + +table { empty-cells:show; } +div.intrapage { + background: #ccccff; + padding-left: 1em; + margin-left: -2em; +} +.code { + white-space: pre; + font-size: 100%; + font-family: monospace; + margin-left: 2em; +} + diff --git a/website/support.html.en b/website/support.html.en new file mode 100644 index 00000000..a20fe60d --- /dev/null +++ b/website/support.html.en @@ -0,0 +1,65 @@ + + + + + RECOLL: a personal text search system for + Unix/Linux + + + + + + + + + + + + + + +
        + +

        Support

        + +

        If you have any problem with Recoll, or a suggestion for + improvement, please provide feedback. There are three + possible channels, depending on your preferences: +

        +

        + +

        Mailing list information: +

        +

        + +

        The list of known bugs is here

        +
        + + + diff --git a/website/usermanual/README-dir.txt b/website/usermanual/README-dir.txt new file mode 100644 index 00000000..4fba138b --- /dev/null +++ b/website/usermanual/README-dir.txt @@ -0,0 +1 @@ +This file is needed because of mercurial neglect of empty directories. diff --git a/website/xapUpg100.html b/website/xapUpg100.html new file mode 100644 index 00000000..f4c4bd33 --- /dev/null +++ b/website/xapUpg100.html @@ -0,0 +1,69 @@ + + + + + Upgrading to xapian 1.0.x + + + + + + + + + + + + + + + + +
        + +

        Upgrading to Xapian 1.0

        + +

        Xapian has supported two main index formats for quite some + time: the older Quartz format, and the + newer Flint

        + +

        Up to Xapian release 1.0, Quartz was the + default. This is also quite probably what your Recoll index + used, except if you had explicitely required a Flint + index by setting the XAPIAN_PREFER_FLINT environment + variable.

        + +

        When upgrading an existing Recoll installation to Recoll 1.9, + which is normally built with Xapian 1.0 (0.9 is still + supported), or after rebuilding Recoll 1.8.2 with Xapian 1.0, + you probably want to convert your index format + to Flint, which is faster and more efficient (if you + were using the default Quartz, you can also elect to + just do nothing, the older Quartz format is still + supported).

        + +

        The index format upgrade will not happen automatically, and + you will need to destroy the old index explicitely, then + restart the indexer (this will cause a full indexing pass, of + course, which may take some time, so you may prefer to let it + work overnight).

        + +

        To destroy the old index, you just need to erase the xapiandb + directory: typically: rm -rf ~/.recoll/xapiandb, except if you + specified a special storage place with the dbdir + configuration variable.

        + +

        If you were using Flint with Xapian 0.9, + you must destroy the old index, + because Flint had an incompatible format change + between 0.9 and 1.0

        + +
        + +