00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <qdom.h>
00023
#include <qfile.h>
00024
#include <qtextcodec.h>
00025
#include <qstring.h>
00026
00027
#include <klocale.h>
00028
#include <kapplication.h>
00029
#include <kstandarddirs.h>
00030
#include <kstaticdeleter.h>
00031
00032
#include "kohyphen.h"
00033
#include <kdebug.h>
00034
00035
00036
00037
00038
KoHyphenator* KoHyphenator::s_self;
00039
static KStaticDeleter<KoHyphenator> kohyphensd;
00040
00041 KoHyphenator*
KoHyphenator::self()
00042 {
00043
if ( !s_self )
00044 kohyphensd.setObject( s_self,
new KoHyphenator );
00045
return s_self;
00046 }
00047
00048 KoHyphenator::KoHyphenator()
00049 {
00050
00051
00052
QString path = kapp->dirs()->findResource(
"data",
"koffice/hyphdicts/dicts.xml");
00053
#ifdef DEBUG_HYPHENATOR
00054
kdDebug() << path << endl;
00055
#endif
00056
00057
QFile *f;
00058
if (!path.isNull())
00059 f =
new QFile(path);
00060
else
00061
throw KoHyphenatorException(i18n(
"Could not create KoHyphenator instance."));
00062
00063
QDomDocument config;
00064
QDomNodeList records;
00065 config.setContent(f);
00066
00067
for (
QDomNode n = config.firstChild(); !n.isNull(); n = n.nextSibling())
00068
if (n.nodeName() ==
"dicts")
00069 {
00070 records = n.childNodes();
00071
for (uint i = 0; i < records.count(); i++)
00072 {
00073
QDomNamedNodeMap attr = records.item(i).attributes();
00074
if (attr.contains(
"lang") && attr.contains(
"encoding")) {
00075
QString lang = attr.namedItem(
"lang").nodeValue();
00076
QString encoding = attr.namedItem(
"encoding").nodeValue();
00077
#ifdef DEBUG_HYPHENATOR
00078
kdDebug() <<
"KoHyphenator: found lang=" << lang <<
" encoding=" << encoding << endl;
00079
#endif
00080
encodings.insert( lang,
00081 EncodingStruct( encoding.latin1() ) );
00082 }
00083 }
00084 }
00085
00086
delete f;
00087 }
00088
00089 KoHyphenator::~KoHyphenator()
00090 {
00091
for (
QMap<QString, HyphenDict*>::iterator it = dicts.begin(); it != dicts.end(); it++)
00092 {
00093
if ((*it) != 0)
00094 hnj_hyphen_free((*it));
00095 }
00096 }
00097
00098 char *
KoHyphenator::hyphens(
const QString& str,
const QString& lang)
const
00099
{
00100
char *x =
new char[str.length()+1];
00101
try
00102 {
00103
QTextCodec *codec = codecForLang(lang);
00104 hnj_hyphen_hyphenate(dict(lang), (
const char *)(codec->fromUnicode(str)), str.length(), x);
00105 }
00106
catch (KoHyphenatorException &e)
00107 {
00108
#ifdef DEBUG_HYPHENATOR
00109
kdDebug() << e.message().latin1() << endl;
00110
#endif
00111
for (uint j = 0; j < str.length(); j++)
00112 x[j] =
'0';
00113 x[str.length()] =
'\0';
00114 }
00115
return x;
00116 }
00117
00118 QString KoHyphenator::hyphenate(
const QString& str,
const QString& lang)
const
00119
{
00120
char* x =
new char[str.length()+1];
00121
QString res = str;
00122
try
00123 {
00124
QTextCodec *codec = codecForLang(lang);
00125 hnj_hyphen_hyphenate(dict(lang), (
const char *)(codec->fromUnicode(str)), str.length(), x);
00126 }
00127
catch (KoHyphenatorException &e)
00128 {
00129
#ifdef DEBUG_HYPHENATOR
00130
kdDebug() << e.message() << endl;
00131
#endif
00132
delete[] x;
00133
return str;
00134 }
00135
int i = 0, j = 0;
00136
int len = strlen(x);
00137
for (; i < len; i++)
00138 {
00139
#ifdef DEBUG_HYPHENATOR
00140
kdDebug() <<
"loop: i=" << i <<
", j=" << j <<
", x=" << x <<
", res=" << res << endl;
00141
#endif
00142
if ((x[i] % 2) != 0)
00143 {
00144 res.insert(j+1,
QChar(0xad));
00145 j++;
00146 }
00147 j++;
00148 }
00149
delete[] x;
00150
return res;
00151 }
00152
00153 bool KoHyphenator::checkHyphenPos(
const QString& str,
int pos,
const QString& lang)
const
00154
{
00155
#ifdef DEBUG_HYPHENATOR
00156
kdDebug() <<
"string: " << str << endl;
00157
#endif
00158
00159
char *hyph =
hyphens(str, lang);
00160
00161
#ifdef DEBUG_HYPHENATOR
00162
kdDebug() <<
"result: " << hyph << endl;
00163 kdDebug() <<
"checked position: " << pos << endl;
00164
#endif
00165
bool ret = ((hyph[pos] % 2) != 0);
00166
delete[] hyph;
00167
return ret;
00168 }
00169
00170 HyphenDict *KoHyphenator::dict(
const QString &_lang)
const
00171
{
00172
QString lang( _lang );
00173
00174
if (encodings.find(lang) == encodings.end())
00175 {
00176
int underscore = lang.find(
'_');
00177
if ( underscore > -1 ) {
00178 lang.truncate( underscore );
00179
if (encodings.find(lang) == encodings.end())
00180
throw KoHyphenatorException(i18n(
"No dictionary for %1").arg(lang));
00181 }
00182
else
00183
throw KoHyphenatorException(i18n(
"No dictionary for %1").arg(lang));
00184 }
00185
if (dicts.find(lang) == dicts.end())
00186 {
00187
#ifdef DEBUG_HYPHENATOR
00188
kdDebug() <<
"Searching dictionary for '" << lang <<
"' language..." << endl;
00189
#endif
00190
QString path = kapp->dirs()->findResource(
"data",
"koffice/hyphdicts/hyph_" + lang +
".dic");
00191
if (!path.isNull())
00192 {
00193
#ifdef DEBUG_HYPHENATOR
00194
kdDebug() <<
"Loading dictionary for '" << lang <<
"' language: path = " << path << endl;
00195
#endif
00196
const_cast<KoHyphenator*>(
this)->dicts.insert( lang, hnj_hyphen_load(QFile::encodeName(path)) );
00197
if (dicts.find(lang) == dicts.end())
00198 {
00199
#ifdef DEBUG_HYPHENATOR
00200
kdDebug() <<
"No dictionary loaded" << endl;
00201
#endif
00202
throw(KoHyphenatorException(i18n(
"Could not load dictionary for the language: %1").arg(lang)));
00203 }
00204 }
00205
else
00206
throw(KoHyphenatorException(i18n(
"Could not load dictionary for the language: %1").arg(lang)));
00207 }
00208
return dicts[lang];
00209 }
00210
00211
QTextCodec* KoHyphenator::codecForLang(
const QString& lang)
const
00212
{
00213 EncodingMap::Iterator it = encodings.find(lang);
00214
if (it == encodings.end())
00215 {
00216
int underscore = lang.find(
'_');
00217
if ( underscore > -1 ) {
00218
QString _lang( lang );
00219 _lang.truncate( underscore );
00220 it = encodings.find(_lang);
00221 }
00222 }
00223
if (it != encodings.end())
00224 {
00225
if ( (*it).codec )
00226
return (*it).codec;
00227 (*it).codec = QTextCodec::codecForName((*it).encoding);
00228
return (*it).codec;
00229 }
00230
return QTextCodec::codecForMib(106);
00231 }