1st full version of aspell support

This commit is contained in:
dockes 2006-10-11 14:16:26 +00:00
parent 9fe5404390
commit 99372e587b
25 changed files with 975 additions and 145 deletions

View File

@ -1,17 +1,24 @@
#ifndef TEST_RCLASPELL #ifndef TEST_RCLASPELL
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclaspell.cpp,v 1.2 2006-10-09 16:37:08 dockes Exp $ (C) 2006 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclaspell.cpp,v 1.3 2006-10-11 14:16:25 dockes Exp $ (C) 2006 J.F.Dockes";
#endif #endif
#ifdef HAVE_CONFIG_H
#include "autoconfig.h"
#endif
#ifdef RCL_USE_ASPELL
#include <unistd.h> #include <unistd.h>
#include <dlfcn.h> #include <dlfcn.h>
#include <iostream> #include <iostream>
#include "aspell.h" #include ASPELL_INCLUDE
#include "pathut.h" #include "pathut.h"
#include "execmd.h" #include "execmd.h"
#include "rclaspell.h" #include "rclaspell.h"
// Stuff that we don't wish to see in the .h (possible sysdeps, etc.)
class AspellData { class AspellData {
public: public:
AspellData() : m_handle(0) {} AspellData() : m_handle(0) {}
@ -62,22 +69,54 @@ static AspellApi aapi;
badnames += #NM + string(" "); \ badnames += #NM + string(" "); \
} }
bool Aspell::init(const string &basedir, string &reason) const char *aspell_progs[] = {
#ifdef ASPELL_PROG
ASPELL_PROG ,
#endif
"/usr/local/bin/aspell",
"/usr/bin/aspell"
};
bool Aspell::init(string &reason)
{ {
if (m_data == 0) delete m_data;
m_data = new AspellData; m_data = 0;
if (m_data->m_handle) { // Language: we get this from the configuration, else from the NLS
dlclose(m_data->m_handle); // environment. The aspell language names used for selecting language
m_data->m_handle = 0; // definition files (used to create dictionaries) are like en, fr
if (!m_config->getConfParam("aspellLanguage", m_lang)) {
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("_"));
} else {
if (!m_lang.compare("disable")) {
reason = "Aspell disabled in recoll configuration file";
return false;
}
} }
m_data->m_exec = path_cat(basedir, "bin"); m_data = new AspellData;
m_data->m_exec = path_cat(m_data->m_exec, "aspell"); for (unsigned int i = 0; i < sizeof(aspell_progs) / sizeof(char*); i++) {
if (access(m_data->m_exec.c_str(), X_OK) != 0) { if (access(aspell_progs[i], X_OK) == 0) {
reason = m_data->m_exec + " not found or not executable"; m_data->m_exec = aspell_progs[i];
break;
}
}
if (m_data->m_exec.empty()) {
reason = "aspell program not found or not executable";
return false; return false;
} }
string lib = path_cat(basedir, "lib");
// For now, the aspell library has to live under the same prefix as the
// aspell program.
string aspellPrefix = path_getfather(path_getfather(m_data->m_exec));
string lib = path_cat(aspellPrefix, "lib");
lib = path_cat(lib, "libaspell.so"); lib = path_cat(lib, "libaspell.so");
if ((m_data->m_handle = dlopen(lib.c_str(), RTLD_LAZY)) == 0) { if ((m_data->m_handle = dlopen(lib.c_str(), RTLD_LAZY)) == 0) {
reason = "Could not open shared library ["; reason = "Could not open shared library [";
@ -120,6 +159,7 @@ bool Aspell::init(const string &basedir, string &reason)
reason = string("Aspell::init: symbols not found:") + badnames; reason = string("Aspell::init: symbols not found:") + badnames;
return false; return false;
} }
return true; return true;
} }
@ -130,51 +170,58 @@ bool Aspell::ok()
string Aspell::dicPath() string Aspell::dicPath()
{ {
return path_cat(m_conf->getConfDir(), return path_cat(m_config->getConfDir(),
string("aspdict.") + m_lang + string(".rws")); string("aspdict.") + m_lang + string(".rws"));
} }
bool Aspell::buildDict(Rcl::Db &db, string &reason) bool Aspell::buildDict(Rcl::Db &db, string &reason)
{ {
string term; if (!ok())
return false;
// Il faut nettoyer la liste, peut-etre faire un tri unique (verifier), // We create the dictionary by executing the aspell command:
// puis construire le dico // aspell --lang=[lang] create master [dictApath]
Rcl::TermIter *tit = db.termWalkOpen(); ExecCmd aspell;
if (tit == 0) { list<string> args;
reason = "termWalkOpen failed\n"; args.push_back(string("--lang=")+ m_lang);
return false; args.push_back("create");
} args.push_back("master");
ExecCmd aspell; args.push_back(dicPath());
list<string> args; aspell.setStderr("/dev/null");
// aspell --lang=[lang] create master [dictApath]
args.push_back(string("--lang=")+ m_lang); Rcl::TermIter *tit = db.termWalkOpen();
args.push_back("create"); if (tit == 0) {
args.push_back("master"); reason = "termWalkOpen failed\n";
args.push_back(dicPath()); return false;
// aspell.setStderr("/dev/null"); }
string allterms; string allterms, term;
while (db.termWalkNext(tit, term)) { while (db.termWalkNext(tit, term)) {
// Filter out terms beginning with upper case (special stuff) and // Filter out terms beginning with upper case (special stuff) and
// containing numbers // containing numbers
if (term.empty()) if (term.empty())
continue; continue;
if ('A' <= term.at(0) && term.at(0) <= 'Z') if ('A' <= term.at(0) && term.at(0) <= 'Z')
continue; continue;
if (term.find_first_of("0123456789+-._@") != string::npos) if (term.find_first_of("0123456789+-._@") != string::npos)
continue; continue;
allterms += term + "\n"; allterms += term + "\n";
// std::cout << "[" << term << "]" << std::endl; // std::cout << "[" << term << "]" << std::endl;
} }
db.termWalkClose(tit); db.termWalkClose(tit);
aspell.doexec(m_data->m_exec, args, &allterms); if (aspell.doexec(m_data->m_exec, args, &allterms)) {
return true; reason = string("aspell dictionary creation command failed. Check the language data files for lang = ") + m_lang;
return false;
}
return true;
} }
bool Aspell::suggest(Rcl::Db &db, bool Aspell::suggest(Rcl::Db &db,
string &term, list<string> &suggestions, string &reason) string &term, list<string> &suggestions, string &reason)
{ {
if (!ok())
return false;
AspellCanHaveError *ret; AspellCanHaveError *ret;
AspellSpeller *speller; AspellSpeller *speller;
AspellConfig *config; AspellConfig *config;
@ -221,9 +268,16 @@ bool Aspell::suggest(Rcl::Db &db,
return true; return true;
} }
#endif // RCL_USE_ASPELL
#else // TEST_RCLASPELL test driver -> #else // TEST_RCLASPELL test driver ->
#ifdef HAVE_CONFIG_H
#include "autoconfig.h"
#endif
#ifdef RCL_USE_ASPELL
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
@ -304,11 +358,9 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
string lang = "en"; Aspell aspell(rclconfig);
Aspell aspell(rclconfig, lang); if (!aspell.init(reason)) {
if (!aspell.init("/usr/local", reason)) {
cerr << "Init failed: " << reason << endl; cerr << "Init failed: " << reason << endl;
exit(1); exit(1);
} }
@ -331,5 +383,9 @@ int main(int argc, char **argv)
} }
exit(0); exit(0);
} }
#else
int main(int argc, char **argv)
{return 1;}
#endif // RCL_USE_ASPELL
#endif // TEST_RCLASPELL test driver #endif // TEST_RCLASPELL test driver

View File

@ -1,6 +1,9 @@
#ifndef _RCLASPELL_H_INCLUDED_ #ifndef _RCLASPELL_H_INCLUDED_
#define _RCLASPELL_H_INCLUDED_ #define _RCLASPELL_H_INCLUDED_
/* @(#$Id: rclaspell.h,v 1.2 2006-10-09 16:37:08 dockes Exp $ (C) 2006 J.F.Dockes */ /* @(#$Id: rclaspell.h,v 1.3 2006-10-11 14:16:25 dockes Exp $ (C) 2006 J.F.Dockes */
/* autoconfig.h must be included before this file */
#ifdef RCL_USE_ASPELL
/** /**
* Aspell speller interface class. * Aspell speller interface class.
@ -28,15 +31,15 @@ class AspellData;
class Aspell { class Aspell {
public: public:
Aspell(RclConfig *cnf, const string &lang) Aspell(RclConfig *cnf)
: m_conf(cnf), m_lang(lang), m_data(0) {}; : m_config(cnf), m_data(0) {};
~Aspell(); ~Aspell();
/** Check health */ /** Check health */
bool ok(); bool ok();
/** Find the aspell command and shared library, init function pointers */ /** Find the aspell command and shared library, init function pointers */
bool init(const string &basedir, string &reason); bool init(string &reason);
/** Build dictionary out of index term list. This is done at the end /** Build dictionary out of index term list. This is done at the end
* of an indexing pass. */ * of an indexing pass. */
@ -48,9 +51,10 @@ class Aspell {
private: private:
string dicPath(); string dicPath();
RclConfig *m_conf; RclConfig *m_config;
string m_lang; string m_lang;
AspellData *m_data; AspellData *m_data;
}; };
#endif /* RCL_USE_ASPELL */
#endif /* _RCLASPELL_H_INCLUDED_ */ #endif /* _RCLASPELL_H_INCLUDED_ */

View File

@ -8,19 +8,3 @@
/* Path to the aspell program */ /* Path to the aspell program */
#undef ASPELL_PROG #undef ASPELL_PROG
/* 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 version of this package. */
#undef PACKAGE_VERSION

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _RCLCONFIG_H_INCLUDED_ #ifndef _RCLCONFIG_H_INCLUDED_
#define _RCLCONFIG_H_INCLUDED_ #define _RCLCONFIG_H_INCLUDED_
/* @(#$Id: rclconfig.h,v 1.21 2006-09-08 09:02:47 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: rclconfig.h,v 1.22 2006-10-11 14:16:25 dockes Exp $ (C) 2004 J.F.Dockes */
#include <list> #include <list>
@ -41,6 +41,7 @@ class RclConfig {
m_conf->get("guesscharset", str, m_keydir); m_conf->get("guesscharset", str, m_keydir);
guesscharset = stringToBool(str); guesscharset = stringToBool(str);
} }
string getKeyDir() const {return m_keydir;}
/** Get generic configuration parameter according to current keydir */ /** Get generic configuration parameter according to current keydir */
bool getConfParam(const string &name, string &value) bool getConfParam(const string &name, string &value)

380
src/configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.53 for Recoll 1.0. # Generated by GNU Autoconf 2.53 for Recoll 1.6.
# #
# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 # Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
# Free Software Foundation, Inc. # Free Software Foundation, Inc.
@ -254,8 +254,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package. # Identity of this package.
PACKAGE_NAME='Recoll' PACKAGE_NAME='Recoll'
PACKAGE_TARNAME='recoll' PACKAGE_TARNAME='recoll'
PACKAGE_VERSION='1.0' PACKAGE_VERSION='1.6'
PACKAGE_STRING='Recoll 1.0' PACKAGE_STRING='Recoll 1.6'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
ac_unique_file="index/recollindex.cpp" ac_unique_file="index/recollindex.cpp"
@ -719,7 +719,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures Recoll 1.0 to adapt to many kinds of systems. \`configure' configures Recoll 1.6 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -776,7 +776,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of Recoll 1.0:";; short | recursive ) echo "Configuration of Recoll 1.6:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -785,6 +785,12 @@ Optional Features:
--enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-qt4 Use qt version 4 --enable-qt4 Use qt version 4
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-aspell Use aspell spelling package to provide term
expansion to other spellings
Some influential environment variables: Some influential environment variables:
CC C compiler command CC C compiler command
CFLAGS C compiler flags CFLAGS C compiler flags
@ -858,7 +864,7 @@ fi
test -n "$ac_init_help" && exit 0 test -n "$ac_init_help" && exit 0
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
Recoll configure 1.0 Recoll configure 1.6
generated by GNU Autoconf 2.53 generated by GNU Autoconf 2.53
Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002
@ -873,7 +879,7 @@ cat >&5 <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by Recoll $as_me 1.0, which was It was created by Recoll $as_me 1.6, which was
generated by GNU Autoconf 2.53. Invocation command line was generated by GNU Autoconf 2.53. Invocation command line was
$ $0 $@ $ $0 $@
@ -1150,6 +1156,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers common/autoconfig.h"
@ -1166,6 +1174,102 @@ EOF
exit 1 exit 1
fi 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
# Check whether --with-aspell or --without-aspell was given.
if test "${with_aspell+set}" = set; then
withval="$with_aspell"
withAspell=$withval
else
withAspell=yes
fi;
case $withAspell in
no);;
yes)
# Extract the first word of "aspell", so it can be a program name with args.
set dummy aspell; ac_word=$2
echo "$as_me:$LINENO: checking for $ac_word" >&5
echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
if test "${ac_cv_path_aspellProg+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
case $aspellProg in
[\\/]* | ?:[\\/]*)
ac_cv_path_aspellProg="$aspellProg" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_aspellProg="$as_dir/$ac_word$ac_exec_ext"
echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
;;
esac
fi
aspellProg=$ac_cv_path_aspellProg
if test -n "$aspellProg"; then
echo "$as_me:$LINENO: result: $aspellProg" >&5
echo "${ECHO_T}$aspellProg" >&6
else
echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6
fi
;;
*) # The argument should be the path to the aspell program
aspellProg=$withAspell
;;
esac
# if
if test X$withAspell != Xno ; then
cat >>confdefs.h <<\_ACEOF
#define RCL_USE_ASPELL 1
_ACEOF
if test X$aspellProg != X ; then
aspellBase=`dirname $aspellProg`
aspellBase=`dirname $aspellBase`
if test ! -f $aspellBase/include/aspell.h ; then
{ { echo "$as_me:$LINENO: error: aspell.h not found in $aspellBase/include. Specify --with-aspell=no to disable aspell support" >&5
echo "$as_me: error: aspell.h not found in $aspellBase/include. Specify --with-aspell=no to disable aspell support" >&2;}
{ (exit 1); exit 1; }; }
fi
cat >>confdefs.h <<_ACEOF
#define ASPELL_PROG "$aspellProg"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define ASPELL_INCLUDE "$aspellBase/include/aspell.h"
_ACEOF
else
# aspell support enabled but no aspell install yet
{ echo "$as_me:$LINENO: aspell support enabled but aspell package not found. Compiling with internal aspell interface file" >&5
echo "$as_me: aspell support enabled but aspell package not found. Compiling with internal aspell interface file" >&6;}
cat >>confdefs.h <<\_ACEOF
#define ASPELL_INCLUDE "aspell-local.h"
_ACEOF
fi
fi
##### Look for iconv. We first look for libiconv in /usr/local/lib:/usr/lib ##### Look for iconv. We first look for libiconv in /usr/local/lib:/usr/lib
## then in libc (Linux, solaris) ## then in libc (Linux, solaris)
ac_ext=c ac_ext=c
@ -2433,38 +2537,7 @@ s/^[^=]*=[ ]*$//;
}' }'
fi fi
# Transform confdefs.h into DEFS. DEFS=-DHAVE_CONFIG_H
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
# take arguments), then we branch to the quote section. Otherwise,
# look for a macro that doesn't take arguments.
cat >confdef2opt.sed <<\_ACEOF
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
t quote
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
t quote
d
: quote
s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
s,\[,\\&,g
s,\],\\&,g
s,\$,$$,g
p
_ACEOF
# We use echo to avoid assuming a particular line-breaking character.
# The extra dot is to prevent the shell from consuming trailing
# line-breaks from the sub-command output. A line-break within
# single-quotes doesn't work because, if this script is created in a
# platform that uses two characters for line-breaks (e.g., DOS), tr
# would break.
ac_LF_and_DOT=`echo; echo .`
DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
rm -f confdef2opt.sed
: ${CONFIG_STATUS=./config.status} : ${CONFIG_STATUS=./config.status}
@ -2715,7 +2788,7 @@ _ASBOX
} >&5 } >&5
cat >&5 <<_CSEOF cat >&5 <<_CSEOF
This file was extended by Recoll $as_me 1.0, which was This file was extended by Recoll $as_me 1.6, which was
generated by GNU Autoconf 2.53. Invocation command line was generated by GNU Autoconf 2.53. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -2760,16 +2833,21 @@ Usage: $0 [OPTIONS] [FILE]...
--recheck update $as_me by reconfiguring in the same conditions --recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE] --file=FILE[:TEMPLATE]
instantiate the configuration file FILE instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration files: Configuration files:
$config_files $config_files
Configuration headers:
$config_headers
Report bugs to <bug-autoconf@gnu.org>." Report bugs to <bug-autoconf@gnu.org>."
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\ ac_cs_version="\\
Recoll config.status 1.0 Recoll config.status 1.6
configured by $0, generated by GNU Autoconf 2.53, configured by $0, generated by GNU Autoconf 2.53,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
@ -2860,6 +2938,7 @@ do
"Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"sampleconf/recoll.conf" ) CONFIG_FILES="$CONFIG_FILES sampleconf/recoll.conf" ;; "sampleconf/recoll.conf" ) CONFIG_FILES="$CONFIG_FILES sampleconf/recoll.conf" ;;
"$QTGUI/recoll.pro" ) CONFIG_FILES="$CONFIG_FILES $QTGUI/recoll.pro" ;; "$QTGUI/recoll.pro" ) CONFIG_FILES="$CONFIG_FILES $QTGUI/recoll.pro" ;;
"common/autoconfig.h" ) CONFIG_HEADERS="$CONFIG_HEADERS common/autoconfig.h" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;} echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
{ (exit 1); exit 1; }; };; { (exit 1); exit 1; }; };;
@ -2872,6 +2951,7 @@ done
# bizarre bug on SunOS 4.1.3. # bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
fi fi
# Create a temporary directory, and hook for its removal unless debugging. # Create a temporary directory, and hook for its removal unless debugging.
@ -2940,6 +3020,7 @@ s,@ECHO_C@,$ECHO_C,;t t
s,@ECHO_N@,$ECHO_N,;t t s,@ECHO_N@,$ECHO_N,;t t
s,@ECHO_T@,$ECHO_T,;t t s,@ECHO_T@,$ECHO_T,;t t
s,@LIBS@,$LIBS,;t t s,@LIBS@,$LIBS,;t t
s,@aspellProg@,$aspellProg,;t t
s,@CC@,$CC,;t t s,@CC@,$CC,;t t
s,@CFLAGS@,$CFLAGS,;t t s,@CFLAGS@,$CFLAGS,;t t
s,@LDFLAGS@,$LDFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t
@ -3150,6 +3231,223 @@ s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
done done
_ACEOF _ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF
#
# CONFIG_HEADER section.
#
# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)'
ac_dB='[ ].*$,\1#\2'
ac_dC=' '
ac_dD=',;t'
# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
ac_uB='$,\1#\2define\3'
ac_uC=' '
ac_uD=',;t'
for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
# Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
case $ac_file in
- | *:- | *:-:* ) # input from stdin
cat >$tmp/stdin
ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
*:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
* ) ac_file_in=$ac_file.in ;;
esac
test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
echo "$as_me: creating $ac_file" >&6;}
# First look for the input files in the build tree, otherwise in the
# src tree.
ac_file_inputs=`IFS=:
for f in $ac_file_in; do
case $f in
-) echo $tmp/stdin ;;
[\\/$]*)
# Absolute (can't be DOS-style, as IFS=:)
test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
echo $f;;
*) # Relative
if test -f "$f"; then
# Build tree
echo $f
elif test -f "$srcdir/$f"; then
# Source tree
echo $srcdir/$f
else
# /dev/null tree
{ { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
echo "$as_me: error: cannot find input file: $f" >&2;}
{ (exit 1); exit 1; }; }
fi;;
esac
done` || { (exit 1); exit 1; }
# Remove the trailing spaces.
sed 's/[ ]*$//' $ac_file_inputs >$tmp/in
_ACEOF
# Transform confdefs.h into two sed scripts, `conftest.defines' and
# `conftest.undefs', that substitutes the proper values into
# config.h.in to produce config.h. The first handles `#define'
# templates, and the second `#undef' templates.
# And first: Protect against being on the right side of a sed subst in
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
# Using a here document instead of a string reduces the quoting nightmare.
# Putting comments in sed scripts is not portable.
#
# `end' is used to avoid that the second main sed command (meant for
# 0-ary CPP macros) applies to n-ary macro definitions.
# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\_ACEOF
s/[\\&,]/\\&/g
s,[\\$`],\\&,g
t clear
: clear
s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
t end
s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
: end
_ACEOF
# If some macros were called several times there might be several times
# the same #defines, which is useless. Nevertheless, we may not want to
# sort them, since we want the *last* AC-DEFINE to be honored.
uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
rm -f confdef2sed.sed
# This sed command replaces #undef with comments. This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >>conftest.undefs <<\_ACEOF
s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
_ACEOF
# Break up conftest.defines because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
echo ' if egrep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
echo ' :' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.defines >/dev/null
do
# Write a limited-size here document to $tmp/defines.sed.
echo ' cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#define' lines.
echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/defines.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
rm -f conftest.defines
mv conftest.tail conftest.defines
done
rm -f conftest.defines
echo ' fi # egrep' >>$CONFIG_STATUS
echo >>$CONFIG_STATUS
# Break up conftest.undefs because some shells have a limit on the size
# of here documents, and old seds have small limits too (100 cmds).
echo ' # Handle all the #undef templates' >>$CONFIG_STATUS
rm -f conftest.tail
while grep . conftest.undefs >/dev/null
do
# Write a limited-size here document to $tmp/undefs.sed.
echo ' cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
# Speed up: don't consider the non `#undef'
echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS
# Work around the forget-to-reset-the-flag bug.
echo 't clr' >>$CONFIG_STATUS
echo ': clr' >>$CONFIG_STATUS
sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
echo 'CEOF
sed -f $tmp/undefs.sed $tmp/in >$tmp/out
rm -f $tmp/in
mv $tmp/out $tmp/in
' >>$CONFIG_STATUS
sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
rm -f conftest.undefs
mv conftest.tail conftest.undefs
done
rm -f conftest.undefs
cat >>$CONFIG_STATUS <<\_ACEOF
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
if test x"$ac_file" = x-; then
echo "/* Generated by configure. */" >$tmp/config.h
else
echo "/* $ac_file. Generated by configure. */" >$tmp/config.h
fi
cat $tmp/in >>$tmp/config.h
rm -f $tmp/in
if test x"$ac_file" != x-; then
if cmp -s $ac_file $tmp/config.h 2>/dev/null; then
{ echo "$as_me:$LINENO: $ac_file is unchanged" >&5
echo "$as_me: $ac_file is unchanged" >&6;}
else
ac_dir=`(dirname "$ac_file") 2>/dev/null ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| \
. : '\(.\)' 2>/dev/null ||
echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
/^X\(\/\/\)[^/].*/{ s//\1/; q; }
/^X\(\/\/\)$/{ s//\1/; q; }
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
{ case "$ac_dir" in
[\\/]* | ?:[\\/]* ) as_incr_dir=;;
*) as_incr_dir=.;;
esac
as_dummy="$ac_dir"
for as_mkdir_dir in `IFS='/\\'; set X $as_dummy; shift; echo "$@"`; do
case $as_mkdir_dir in
# Skip DOS drivespec
?:) as_incr_dir=$as_mkdir_dir ;;
*)
as_incr_dir=$as_incr_dir/$as_mkdir_dir
test -d "$as_incr_dir" ||
mkdir "$as_incr_dir" ||
{ { echo "$as_me:$LINENO: error: cannot create \"$ac_dir\"" >&5
echo "$as_me: error: cannot create \"$ac_dir\"" >&2;}
{ (exit 1); exit 1; }; }
;;
esac
done; }
rm -f $ac_file
mv $tmp/config.h $ac_file
fi
else
cat $tmp/config.h
rm -f $tmp/config.h
fi
done
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF cat >>$CONFIG_STATUS <<\_ACEOF

View File

@ -1,4 +1,5 @@
AC_INIT(Recoll, 1.0) AC_INIT(Recoll, 1.6)
AC_CONFIG_HEADERS([common/autoconfig.h])
AC_PREREQ(2.53) AC_PREREQ(2.53)
AC_CONFIG_SRCDIR(index/recollindex.cpp) AC_CONFIG_SRCDIR(index/recollindex.cpp)
@ -14,6 +15,44 @@ EOF
exit 1 exit 1
fi 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([--with-aspell],
[Use 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
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`
if test ! -f $aspellBase/include/aspell.h ; then
AC_MSG_ERROR([aspell.h not found in $aspellBase/include. Specify --with-aspell=no to disable aspell support])
fi
AC_DEFINE_UNQUOTED(ASPELL_PROG, "$aspellProg",
[Path to the aspell program])
AC_DEFINE_UNQUOTED(ASPELL_INCLUDE, "$aspellBase/include/aspell.h",
[Path to the aspell api include file])
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
##### Look for iconv. We first look for libiconv in /usr/local/lib:/usr/lib ##### Look for iconv. We first look for libiconv in /usr/local/lib:/usr/lib
## then in libc (Linux, solaris) ## then in libc (Linux, solaris)
AC_LANG(C) AC_LANG(C)

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: indexer.cpp,v 1.35 2006-09-13 13:53:35 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: indexer.cpp,v 1.36 2006-10-11 14:16:25 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -17,6 +17,10 @@ static char rcsid[] = "@(#$Id: indexer.cpp,v 1.35 2006-09-13 13:53:35 dockes Exp
* Free Software Foundation, Inc., * Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#ifdef HAVE_CONFIG_H
#include "autoconfig.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h> #include <unistd.h>
@ -42,6 +46,10 @@ static char rcsid[] = "@(#$Id: indexer.cpp,v 1.35 2006-09-13 13:53:35 dockes Exp
#include "smallut.h" #include "smallut.h"
#include "wipedir.h" #include "wipedir.h"
#ifdef RCL_USE_ASPELL
#include "rclaspell.h"
#endif
#ifndef NO_NAMESPACES #ifndef NO_NAMESPACES
using namespace std; using namespace std;
#endif /* NO_NAMESPACES */ #endif /* NO_NAMESPACES */
@ -137,6 +145,8 @@ bool DbIndexer::indexDb(bool resetbefore, list<string> *topdirs)
} }
} }
createAspellDict();
// The close would be done in our destructor, but we want status here // The close would be done in our destructor, but we want status here
if (m_updater) { if (m_updater) {
m_updater->status.phase = DbIxStatus::DBIXS_CLOSING; m_updater->status.phase = DbIxStatus::DBIXS_CLOSING;
@ -171,6 +181,31 @@ bool DbIndexer::createStemDb(const string &lang)
return m_db.createStemDb(lang); return m_db.createStemDb(lang);
} }
// The language for the aspell dictionary is handled internally by the aspell
// module, either from a configuration variable or the NLS environment.
bool DbIndexer::createAspellDict()
{
LOGDEB2(("DbIndexer::createAspellDict()\n"));
#ifdef RCL_USE_ASPELL
if (!init())
return false;
Aspell aspell(m_config);
string reason;
if (!aspell.init(reason)) {
LOGERR(("DbIndexer::createAspellDict: aspell init failed: %s\n",
reason.c_str()));
return false;
}
LOGDEB(("DbIndexer::createAspellDict: creating dictionary\n"));
if (!aspell.buildDict(m_db, reason)) {
LOGERR(("DbIndexer::createAspellDict: aspell buildDict failed: %s\n",
reason.c_str()));
return false;
}
#endif
return true;
}
/** /**
Index individual files, out of a full tree run. No database purging Index individual files, out of a full tree run. No database purging
*/ */

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _INDEXER_H_INCLUDED_ #ifndef _INDEXER_H_INCLUDED_
#define _INDEXER_H_INCLUDED_ #define _INDEXER_H_INCLUDED_
/* @(#$Id: indexer.h,v 1.16 2006-04-30 07:35:18 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: indexer.h,v 1.17 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
@ -119,6 +119,9 @@ class DbIndexer : public FsTreeWalkerCB {
/** Create stem database for given language */ /** Create stem database for given language */
bool createStemDb(const string &lang); bool createStemDb(const string &lang);
/** Create misspelling expansion dictionary if aspell i/f is available */
bool createAspellDict();
/** Tree walker callback method */ /** Tree walker callback method */
FsTreeWalker::Status FsTreeWalker::Status
processone(const string &, const struct stat *, processone(const string &, const struct stat *,

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.20 2006-09-08 09:02:47 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.21 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -17,6 +17,9 @@ static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.20 2006-09-08 09:02:47 dockes
* Free Software Foundation, Inc., * Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#ifdef HAVE_CONFIG_H
#include "autoconfig.h"
#endif
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
@ -39,37 +42,45 @@ using namespace std;
ConfIndexer *confindexer; ConfIndexer *confindexer;
DbIndexer *dbindexer; DbIndexer *dbindexer;
static bool makeDbIndexer(RclConfig *config)
{
if (dbindexer)
delete dbindexer;
// Note that we do not bother to check for multiple databases,
// which are currently a fiction anyway.
string dbdir = config->getDbDir();
if (dbdir.empty()) {
fprintf(stderr, "makeDbIndexer: no database directory in "
"configuration for %s\n", config->getKeyDir().c_str());
return false;
}
dbindexer = new DbIndexer(config, dbdir);
return true;
}
// Index a list of files // Index a list of files
static bool indexfiles(RclConfig *config, const list<string> &filenames) static bool indexfiles(RclConfig *config, const list<string> &filenames)
{ {
if (filenames.empty()) if (filenames.empty())
return true; return true;
// Note that we do not bother to check for multiple databases,
// which are currently a fiction anyway.
config->setKeyDir(path_getfather(*filenames.begin())); config->setKeyDir(path_getfather(*filenames.begin()));
string dbdir = config->getDbDir();
if (dbdir.empty()) { makeDbIndexer(config);
LOGERR(("indexfiles: no database directory in " if (dbindexer)
"configuration for %s\n", filenames.begin()->c_str())); return dbindexer->indexFiles(filenames);
else
return false; return false;
}
dbindexer = new DbIndexer(config, dbdir);
return dbindexer->indexFiles(filenames);
} }
// Create additional stem database // Create additional stem database
static bool createstemdb(RclConfig *config, const string &lang) static bool createstemdb(RclConfig *config, const string &lang)
{ {
// Note that we do not bother to check for multiple databases, makeDbIndexer(config);
// which are currently a fiction anyway. if (dbindexer)
string dbdir = config->getDbDir(); return dbindexer->createStemDb(lang);
if (dbdir.empty()) { else
LOGERR(("createstemdb: no database directory in configuration\n"));
return false; return false;
}
dbindexer = new DbIndexer(config, dbdir);
return dbindexer->createStemDb(lang);
} }
static void cleanup() static void cleanup()
@ -108,6 +119,7 @@ static int op_flags;
#define OPT_i 0x8 #define OPT_i 0x8
#define OPT_s 0x10 #define OPT_s 0x10
#define OPT_c 0x20 #define OPT_c 0x20
#define OPT_S 0x40
static const char usage [] = static const char usage [] =
"\n" "\n"
@ -120,6 +132,10 @@ static const char usage [] =
" Index individual files. No database purge or stem database updates\n" " Index individual files. No database purge or stem database updates\n"
"recollindex -s <lang>\n" "recollindex -s <lang>\n"
" Build stem database for additional language <lang>\n" " Build stem database for additional language <lang>\n"
#ifdef RCL_USE_ASPELL
"recollindex -S\n"
" Build aspell spelling dictionary.>\n"
#endif
"Common options:\n" "Common options:\n"
" -c <configdir> : specify config directory, overriding $RECOLL_CONFDIR\n" " -c <configdir> : specify config directory, overriding $RECOLL_CONFDIR\n"
; ;
@ -151,6 +167,9 @@ int main(int argc, const char **argv)
case 'h': op_flags |= OPT_h; break; case 'h': op_flags |= OPT_h; break;
case 'i': op_flags |= OPT_i; break; case 'i': op_flags |= OPT_i; break;
case 's': op_flags |= OPT_s; break; case 's': op_flags |= OPT_s; break;
#ifdef RCL_USE_ASPELL
case 'S': op_flags |= OPT_S; break;
#endif
case 'z': op_flags |= OPT_z; break; case 'z': op_flags |= OPT_z; break;
default: Usage(); break; default: Usage(); break;
} }
@ -189,6 +208,14 @@ int main(int argc, const char **argv)
Usage(); Usage();
string lang = *argv++; argc--; string lang = *argv++; argc--;
exit(!createstemdb(config, lang)); exit(!createstemdb(config, lang));
#ifdef RCL_USE_ASPELL
} else if (op_flags & OPT_S) {
makeDbIndexer(config);
if (dbindexer)
exit(!dbindexer->createAspellDict());
else
exit(1);
#endif
} else { } else {
confindexer = new ConfIndexer(config, &updater); confindexer = new ConfIndexer(config, &updater);
bool rezero(op_flags & OPT_z); bool rezero(op_flags & OPT_z);

View File

@ -3,7 +3,7 @@
COMMONCXXFLAGS = -I. -I$(depth)/index \ COMMONCXXFLAGS = -I. -I$(depth)/index \
-I$(depth)/utils -I$(depth)/common \ -I$(depth)/utils -I$(depth)/common \
-I$(depth)/unac -I$(depth)/bincimapmime \ -I$(depth)/unac -I$(depth)/bincimapmime -I$(depth)/aspell \
-I/usr/local/include -I/usr/local/include
# We happen to be using gcc on all platforms for now. Can be overridden in # We happen to be using gcc on all platforms for now. Can be overridden in

View File

@ -10,6 +10,6 @@ datadir = @datadir@
RECOLL_DATADIR = ${datadir}/recoll RECOLL_DATADIR = ${datadir}/recoll
LOCALCXXFLAGS = $(INCICONV) $(XAPIANCXXFLAGS) \ LOCALCXXFLAGS = $(INCICONV) $(XAPIANCXXFLAGS) \
-DRECOLL_DATADIR=\"$(RECOLL_DATADIR)\" -DRECOLL_DATADIR=\"$(RECOLL_DATADIR)\" @DEFS@
CXXFLAGS = -g -O2 -Wall -Wno-unused CXXFLAGS = -g -O2 -Wall -Wno-unused

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

BIN
src/qtgui/images/spell.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: main.cpp,v 1.51 2006-09-28 11:55:30 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: main.cpp,v 1.52 2006-10-11 14:16:26 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -18,6 +18,8 @@ static char rcsid[] = "@(#$Id: main.cpp,v 1.51 2006-09-28 11:55:30 dockes Exp $
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "autoconfig.h"
#include <unistd.h> #include <unistd.h>
//#define WITH_KDE //#define WITH_KDE
@ -51,6 +53,9 @@ static char rcsid[] = "@(#$Id: main.cpp,v 1.51 2006-09-28 11:55:30 dockes Exp $
#endif #endif
#include "rclmain_w.h" #include "rclmain_w.h"
#include "guiutils.h" #include "guiutils.h"
#ifdef RCL_USE_ASPELL
#include "rclaspell.h"
#endif
#ifdef WITH_KDE #ifdef WITH_KDE
static const char description[] = static const char description[] =
@ -68,6 +73,9 @@ const string recoll_datadir = RECOLL_DATADIR;
RclConfig *rclconfig; RclConfig *rclconfig;
Rcl::Db *rcldb; Rcl::Db *rcldb;
#ifdef RCL_USE_ASPELL
Aspell *aspell;
#endif
RclHistory *g_dynconf; RclHistory *g_dynconf;
int recollNeedsExit; int recollNeedsExit;
@ -123,6 +131,10 @@ static void recollCleanup()
rcldb = 0; rcldb = 0;
delete rclconfig; delete rclconfig;
rclconfig = 0; rclconfig = 0;
#ifdef RCL_USE_ASPELL
delete aspell;
aspell = 0;
#endif
LOGDEB2(("recollCleanup: done\n")); LOGDEB2(("recollCleanup: done\n"));
} }
@ -214,6 +226,15 @@ int main(int argc, char **argv)
} }
// fprintf(stderr, "recollinit done\n"); // fprintf(stderr, "recollinit done\n");
#ifdef RCL_USE_ASPELL
aspell = new Aspell(rclconfig);
aspell->init(reason);
if (!aspell || !aspell->ok()) {
LOGDEB(("Aspell speller creation failed %s\n", reason.c_str()));
aspell = 0;
}
#endif
string historyfile = path_cat(rclconfig->getConfDir(), "history"); string historyfile = path_cat(rclconfig->getConfDir(), "history");
g_dynconf = new RclHistory(historyfile); g_dynconf = new RclHistory(historyfile);
if (!g_dynconf || !g_dynconf->ok()) { if (!g_dynconf || !g_dynconf->ok()) {

View File

@ -84,6 +84,7 @@
<action name="toolsDoc_HistoryAction"/> <action name="toolsDoc_HistoryAction"/>
<action name="toolsAdvanced_SearchAction"/> <action name="toolsAdvanced_SearchAction"/>
<action name="toolsSort_parametersAction"/> <action name="toolsSort_parametersAction"/>
<action name="toolsSpellAction"/>
</item> </item>
<item text="&amp;Preferences" name="Preferences"> <item text="&amp;Preferences" name="Preferences">
<action name="preferencesQuery_PrefsAction"/> <action name="preferencesQuery_PrefsAction"/>
@ -106,6 +107,7 @@
<action name="toolsAdvanced_SearchAction"/> <action name="toolsAdvanced_SearchAction"/>
<action name="toolsSort_parametersAction"/> <action name="toolsSort_parametersAction"/>
<action name="toolsDoc_HistoryAction"/> <action name="toolsDoc_HistoryAction"/>
<action name="toolsSpellAction"/>
</toolbar> </toolbar>
<toolbar dock="2"> <toolbar dock="2">
<property name="name"> <property name="name">
@ -251,6 +253,23 @@
<string>Sort parameters</string> <string>Sort parameters</string>
</property> </property>
</action> </action>
<action>
<property name="name">
<cstring>toolsSpellAction</cstring>
</property>
<property name="iconSet">
<iconset>spell.png</iconset>
</property>
<property name="text">
<string>Spelling expansion</string>
</property>
<property name="menuText">
<string>Spelling expansion</string>
</property>
<property name="toolTip">
<string>Spelling expansion tool</string>
</property>
</action>
<action> <action>
<property name="name"> <property name="name">
<cstring>nextPageAction</cstring> <cstring>nextPageAction</cstring>

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.1 2006-09-22 07:41:35 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.2 2006-10-11 14:16:26 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -17,6 +17,7 @@ static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.1 2006-09-22 07:41:35 dockes Ex
* Free Software Foundation, Inc., * Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#include "autoconfig.h"
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
@ -126,6 +127,14 @@ void RclMain::init()
this, SLOT(showAdvSearchDialog())); this, SLOT(showAdvSearchDialog()));
connect(toolsSort_parametersAction, SIGNAL(activated()), connect(toolsSort_parametersAction, SIGNAL(activated()),
this, SLOT(showSortDialog())); this, SLOT(showSortDialog()));
toolsSpellAction->setIconSet(createIconSet("spell.png"));
#ifdef RCL_USE_ASPELL
connect(toolsSpellAction, SIGNAL(activated()),
this, SLOT(showSpellDialog()));
#else
toolsSpellAction->setEnabled(FALSE);
#endif
connect(preferencesQuery_PrefsAction, SIGNAL(activated()), connect(preferencesQuery_PrefsAction, SIGNAL(activated()),
this, SLOT(showUIPrefs())); this, SLOT(showUIPrefs()));
@ -379,6 +388,21 @@ void RclMain::showSortDialog()
} }
void RclMain::showSpellDialog()
{
if (spellform == 0) {
spellform = new SpellW(0, tr("Spell expansion"),
WStyle_Customize | WStyle_NormalBorder |
WStyle_Title | WStyle_SysMenu);
spellform->show();
} else {
// Close and reopen, in hope that makes us visible...
spellform->close();
spellform->show();
}
}
void RclMain::showUIPrefs() void RclMain::showUIPrefs()
{ {
if (uiprefs == 0) { if (uiprefs == 0) {

View File

@ -27,6 +27,7 @@
#include "uiprefs_w.h" #include "uiprefs_w.h"
#include "rcldb.h" #include "rcldb.h"
#include "searchdata.h" #include "searchdata.h"
#include "spell_w.h"
#include "rclmain.h" #include "rclmain.h"
@ -52,6 +53,7 @@ public slots:
virtual void previewClosed(QWidget * w); virtual void previewClosed(QWidget * w);
virtual void showAdvSearchDialog(); virtual void showAdvSearchDialog();
virtual void showSortDialog(); virtual void showSortDialog();
virtual void showSpellDialog();
virtual void showAboutDialog(); virtual void showAboutDialog();
virtual void startManual(); virtual void startManual();
virtual void showDocHistory(); virtual void showDocHistory();
@ -73,6 +75,8 @@ private:
AdvSearch *asearchform; AdvSearch *asearchform;
SortForm *sortform; SortForm *sortform;
UIPrefsDialog *uiprefs; UIPrefsDialog *uiprefs;
SpellW *spellform;
DocSeqSortSpec sortspecs; DocSeqSortSpec sortspecs;
int m_searchId; // Serial number of current search for this process. int m_searchId; // Serial number of current search for this process.
// Used to match to preview windows // Used to match to preview windows

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _RECOLL_H_INCLUDED_ #ifndef _RECOLL_H_INCLUDED_
#define _RECOLL_H_INCLUDED_ #define _RECOLL_H_INCLUDED_
/* @(#$Id: recoll.h,v 1.16 2006-09-11 09:08:44 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: recoll.h,v 1.17 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include "rclconfig.h" #include "rclconfig.h"
@ -34,5 +34,9 @@ extern Rcl::Db *rcldb;
extern int recollNeedsExit; extern int recollNeedsExit;
extern const std::string recoll_datadir; extern const std::string recoll_datadir;
extern RclHistory *g_dynconf; extern RclHistory *g_dynconf;
#ifdef RCL_USE_ASPELL
class Aspell;
extern Aspell *aspell;
#endif
#endif /* _RECOLL_H_INCLUDED_ */ #endif /* _RECOLL_H_INCLUDED_ */

View File

@ -5,6 +5,7 @@ CONFIG += qt warn_on thread release debug
HEADERS += \ HEADERS += \
advsearch_w.h \ advsearch_w.h \
spell_w.h \
preview_w.h \ preview_w.h \
rclmain_w.h \ rclmain_w.h \
reslist.h \ reslist.h \
@ -21,6 +22,7 @@ SOURCES += \
rclmain_w.cpp \ rclmain_w.cpp \
reslist.cpp \ reslist.cpp \
advsearch_w.cpp \ advsearch_w.cpp \
spell_w.cpp \
preview_w.cpp \ preview_w.cpp \
sort_w.cpp \ sort_w.cpp \
ssearch_w.cpp \ ssearch_w.cpp \
@ -28,6 +30,7 @@ SOURCES += \
FORMS = \ FORMS = \
advsearch.ui \ advsearch.ui \
spell.ui \
preview.ui \ preview.ui \
rclmain.ui \ rclmain.ui \
sort.ui \ sort.ui \
@ -40,7 +43,9 @@ IMAGES = images/asearch.png \
images/nextpage.png \ images/nextpage.png \
images/d_prevpage.png \ images/d_prevpage.png \
images/prevpage.png \ images/prevpage.png \
images/sortparms.png images/sortparms.png \
images/d_spell.png \
images/spell.png
unix { unix {
UI_DIR = .ui UI_DIR = .ui
@ -52,7 +57,7 @@ unix {
$(BSTATIC) @LIBXAPIAN@ @LIBICONV@ $(BDYNAMIC) \ $(BSTATIC) @LIBXAPIAN@ @LIBICONV@ $(BDYNAMIC) \
-lz -lz
INCLUDEPATH += ../common ../index ../query ../unac ../utils INCLUDEPATH += ../common ../index ../query ../unac ../utils ../aspell
POST_TARGETDEPS = ../lib/librcl.a POST_TARGETDEPS = ../lib/librcl.a
} }

156
src/qtgui/spell.ui Normal file
View File

@ -0,0 +1,156 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>SpellBase</class>
<widget class="QWidget">
<property name="name">
<cstring>SpellBase</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>0</width>
<height>0</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy>
<hsizetype>5</hsizetype>
<vsizetype>5</vsizetype>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>130</width>
<height>30</height>
</size>
</property>
<property name="caption">
<string>Spelling Explorer</string>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout3</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout4</cstring>
</property>
<vbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLayoutWidget">
<property name="name">
<cstring>layout3</cstring>
</property>
<hbox>
<property name="name">
<cstring>unnamed</cstring>
</property>
<widget class="QLabel">
<property name="name">
<cstring>Label1</cstring>
</property>
<property name="frameShape">
<enum>NoFrame</enum>
</property>
<property name="frameShadow">
<enum>Plain</enum>
</property>
<property name="text">
<string>Enter word</string>
</property>
<property name="buddy" stdset="0">
<cstring>baseWordLE</cstring>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>baseWordLE</cstring>
</property>
<property name="minimumSize">
<size>
<width>200</width>
<height>0</height>
</size>
</property>
<property name="frameShape">
<enum>LineEditPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>expandPB</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Expand </string>
</property>
<property name="accel">
<string>Alt+E</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>clearPB</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Clear</string>
</property>
<property name="accel">
<string>Alt+C</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>dismissPB</cstring>
</property>
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Close</string>
</property>
<property name="accel">
<string>Alt+C</string>
</property>
</widget>
</hbox>
</widget>
</vbox>
</widget>
<widget class="QTextEdit">
<property name="name">
<cstring>suggsTE</cstring>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
</widget>
</vbox>
</widget>
</vbox>
</widget>
<layoutdefaults spacing="6" margin="11"/>
</UI>

94
src/qtgui/spell_w.cpp Normal file
View File

@ -0,0 +1,94 @@
#ifndef lint
static char rcsid[] = "@(#$Id: spell_w.cpp,v 1.1 2006-10-11 14:16:26 dockes Exp $ (C) 2005 J.F.Dockes";
#endif
/*
* 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 <unistd.h>
#include <list>
#include <qmessagebox.h>
#include <qpushbutton.h>
#include <qtextedit.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qlayout.h>
#include <qtooltip.h>
#include "debuglog.h"
#include "recoll.h"
#include "spell_w.h"
#ifdef RCL_USE_ASPELL
#include "rclaspell.h"
#endif
void SpellW::init()
{
// signals and slots connections
connect(baseWordLE, SIGNAL(textChanged(const QString&)),
this, SLOT(wordChanged(const QString&)));
connect(baseWordLE, SIGNAL(returnPressed()), this, SLOT(doExpand()));
connect(expandPB, SIGNAL(clicked()), this, SLOT(doExpand()));
connect(clearPB, SIGNAL(clicked()), baseWordLE, SLOT(clear()));
connect(dismissPB, SIGNAL(clicked()), this, SLOT(close()));
}
void SpellW::doExpand()
{
#ifdef RCL_USE_ASPELL
string reason;
if (!aspell || !maybeOpenDb(reason)) {
LOGDEB(("SpellW::doExpand: error aspell %p db: %s\n", aspell,
reason.c_str()));
return;
}
if (!baseWordLE->text().isEmpty()) {
list<string> suggs;
string word = string((const char *)baseWordLE->text().utf8());
if (!aspell->suggest(*rcldb, word, suggs, reason)) {
LOGERR(("SpellW::doExpand:suggest failed: %s\n", reason.c_str()));
return;
}
suggsTE->clear();
if (suggs.empty()) {
suggsTE->append(tr("No spelling expansion found"));
} else {
for (list<string>::iterator it = suggs.begin();
it != suggs.end(); it++) {
suggsTE->append(QString::fromUtf8(it->c_str()));
}
suggsTE->setCursorPosition(0,0);
suggsTE->ensureCursorVisible();
}
}
#endif
}
void SpellW::wordChanged(const QString &text)
{
if (text.isEmpty()) {
expandPB->setEnabled(false);
clearPB->setEnabled(false);
suggsTE->clear();
} else {
expandPB->setEnabled(true);
clearPB->setEnabled(true);
}
}

48
src/qtgui/spell_w.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef _ASPELL_W_H_INCLUDED_
#define _ASPELL_W_H_INCLUDED_
/* @(#$Id: spell_w.h,v 1.1 2006-10-11 14:16:26 dockes Exp $ (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 <qvariant.h>
#include <qwidget.h>
#include "rcldb.h"
#include "spell.h"
class SpellW : public SpellBase
{
Q_OBJECT
public:
SpellW(QWidget* parent = 0, const char* name = 0, WFlags fl = 0) :
SpellBase(parent,name,fl) {init();}
~SpellW(){}
public slots:
virtual void doExpand();
virtual void wordChanged(const QString&);
// virtual void textDoubleClicked(int, int);
signals:
// void wordSelect(QString);
private:
void init();
};
#endif /* _ASPELL_W_H_INCLUDED_ */

View File

@ -1,4 +1,4 @@
# @(#$Id: recoll.conf.in,v 1.11 2006-09-13 13:53:35 dockes Exp $ (C) 2004 J.F.Dockes # @(#$Id: recoll.conf.in,v 1.12 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes
# #
# Recoll default configuration file. This should be copied to # Recoll default configuration file. This should be copied to
# ~/.recoll/recoll.conf # ~/.recoll/recoll.conf
@ -60,6 +60,13 @@ indexallfilenames = 1
# bigger db # bigger db
# idxabsmlen = 250 # idxabsmlen = 250
# 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.
# The default is english: "en"
# You can use a value of "disable" to disable aspell support.
# aspellLanguage = en
# You could specify different parameters for a subdirectory like this: # You could specify different parameters for a subdirectory like this:
#[~/hungariandocs/plain] #[~/hungariandocs/plain]
#defaultcharset = iso-8859-2 #defaultcharset = iso-8859-2

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: smallut.cpp,v 1.16 2006-04-11 06:49:45 dockes Exp $ (C) 2004 J.F.Dockes"; static char rcsid[] = "@(#$Id: smallut.cpp,v 1.17 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -242,6 +242,7 @@ bool stringToStrings(const string &s, std::list<string> &tokens)
case ' ': case ' ':
case '\t': case '\t':
case '\n':
switch(state) { switch(state) {
case SPACE: case SPACE:
continue; continue;

View File

@ -16,7 +16,7 @@
*/ */
#ifndef _SMALLUT_H_INCLUDED_ #ifndef _SMALLUT_H_INCLUDED_
#define _SMALLUT_H_INCLUDED_ #define _SMALLUT_H_INCLUDED_
/* @(#$Id: smallut.h,v 1.16 2006-04-11 06:49:45 dockes Exp $ (C) 2004 J.F.Dockes */ /* @(#$Id: smallut.h,v 1.17 2006-10-11 14:16:26 dockes Exp $ (C) 2004 J.F.Dockes */
#include <string> #include <string>
#include <list> #include <list>
@ -38,7 +38,7 @@ extern string stringlistdisp(const list<string>& strs);
/** /**
* Parse input string into list of strings. * Parse input string into list of strings.
* *
* Token delimiter is " \t" except inside dquotes. dquote inside * Token delimiter is " \t\n" except inside dquotes. dquote inside
* dquotes can be escaped with \ etc... * dquotes can be escaped with \ etc...
*/ */
extern bool stringToStrings(const string &s, list<string> &tokens); extern bool stringToStrings(const string &s, list<string> &tokens);