Subversion Repositories Scribus

Rev

Rev 159 | Rev 249 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 paul 1
/***************************************************************************
2
                          hyphenator.cpp  -  description
3
                             -------------------
4
    begin                : Sat Nov 02 08:00:00 CEST 2002
5
    copyright            : (C) 2002 by Franz Schmid
6
    email                : Franz.Schmid@altmuehlnet.de
7
 ***************************************************************************/
8
 
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
17
#include "hyphenator.h"
18
#include "hyphenator.moc"
19
#include "hyask.h"
128 Franz 20
 
21
#if (_MSC_VER >= 1200)
22
 #include "win-config.h"
23
#else
24
 #include "config.h"
25
#endif
26
 
3 paul 27
#include <qregexp.h>
28
#include <qcursor.h>
29
#include <qdir.h>
30
#include <cstdlib>
80 Franz 31
#include <string>
3 paul 32
#include "scribus.h"
33
 
159 Franz 34
/*!
35
 \fn Hyphenator::Hyphenator(QWidget* parent, ScribusDoc *dok, ScribusApp* app)
36
 \brief Constructor reads user configuration and sets hyphenator properties.
37
 \date
38
 \author Franz Schmid
39
 \param parent unused
40
 \param dok ScribusDoc reference. It's used for preferences accessing.
41
 \param app ScribusApp reference. It's used for preferences accessing.
42
 \retval None
43
*/
3 paul 44
Hyphenator::Hyphenator(QWidget* parent, ScribusDoc *dok, ScribusApp* app) : QObject( parent, "bu")
45
{
164 Franz 46
        char *filename = NULL;
3 paul 47
        doc = dok;
48
        Sap = app;
49
        MinWordLen = doc->MinWordLen;
50
        Automatic = doc->Automatic;
51
        AutoCheck = doc->AutoCheck;
52
        QString pfad = PREL;
53
        if (Sap->Sprachen.contains(doc->Language))
54
                Language = doc->Language;
55
        else
164 Franz 56
        {
3 paul 57
                Language = Sap->Prefs.Language;
58
                doc->Language = Language;
164 Franz 59
        }
3 paul 60
        pfad += "/lib/scribus/dicts/" + Sap->Sprachen[Language];
106 Franz 61
        QFile f(pfad);
62
        if (f.open(IO_ReadOnly))
164 Franz 63
        {
106 Franz 64
                QTextStream st(&f);
164 Franz 65
        QString line;
66
        line = st.readLine();
106 Franz 67
                codec = QTextCodec::codecForName(line);
68
                f.close();
164 Franz 69
        }
106 Franz 70
        else
164 Franz 71
        {
106 Franz 72
                useAble = false;
73
                hdict = NULL;
74
                return;
164 Franz 75
        }
3 paul 76
        QCString fn = pfad.latin1();
77
        filename = fn.data();
105 Franz 78
        hdict = hnj_hyphen_load(filename);
164 Franz 79
        useAble = hdict == NULL ? false : true;
3 paul 80
}
81
 
159 Franz 82
/*!
83
 \fn Hyphenator::~Hyphenator()
84
 \brief Safely cleans hyphen.
85
 \date
86
 \author Franz Schmid
87
 \param None
88
 \retval None
89
 */
3 paul 90
Hyphenator::~Hyphenator()
91
{
92
        hnj_hyphen_free(hdict);
93
}
94
 
159 Franz 95
/*!
96
 \fn void Hyphenator::slotNewDict(QString name)
97
 \brief Loads dictionary and fills parameters like \a useAble, \a codec, \a hdict.
98
 \date
99
 \author Franz Schmid
100
 \param name is the name of specified language - filename.
101
 \retval None
102
 */
3 paul 103
void Hyphenator::slotNewDict(QString name)
104
{
105
        if (!Sap->Sprachen.contains(name))
106
                return;
164 Franz 107
        char *filename = NULL;
3 paul 108
        if (hdict != NULL)
109
                hnj_hyphen_free(hdict);
110
        QString pfad = PREL;
111
        Language = name;
112
        doc->Language = name;
113
        pfad += "/lib/scribus/dicts/" + Sap->Sprachen[Language];
106 Franz 114
        QFile f(pfad);
115
        if (f.open(IO_ReadOnly))
164 Franz 116
        {
106 Franz 117
                QTextStream st(&f);
164 Franz 118
                QString line;
119
                line = st.readLine();
106 Franz 120
                codec = QTextCodec::codecForName(line);
121
                f.close();
164 Franz 122
        }
106 Franz 123
        else
164 Franz 124
        {
106 Franz 125
                useAble = false;
126
                hdict = NULL;
127
                return;
164 Franz 128
        }
3 paul 129
        QCString fn = pfad.latin1();
130
        filename = fn.data();
105 Franz 131
        hdict = hnj_hyphen_load(filename);
164 Franz 132
        useAble = hdict == NULL ? false : true;
3 paul 133
}
134
 
159 Franz 135
/*!
136
 \fn void Hyphenator::slotNewSettings(int Wordlen, bool Autom, bool ACheck)
137
 \brief Writes actual hyphen configuration into \a doc object.
138
 \date
139
 \author Franz Schmid
140
 \param WordLen lenght of the word.
141
 \param Autom is automatic flag.
142
 \param ACheck AutoCheck flag.
143
 \retval None
144
 */
3 paul 145
void Hyphenator::slotNewSettings(int Wordlen, bool Autom, bool ACheck)
146
{
147
        MinWordLen = Wordlen;
148
        Automatic = Autom;
149
        AutoCheck = ACheck;
150
        doc->MinWordLen = Wordlen;
151
        doc->Automatic = Autom;
152
        doc->AutoCheck = AutoCheck;
153
}
154
 
159 Franz 155
/*!
156
 \fn void Hyphenator::slotHyphenateWord(PageItem* it, QString text, int firstC)
157
 \brief Make hyphenation when user edits text in text frame manually.
158
 \detail If is everything set correctly and textframe selected language fits the
159
    dictionary language. At first removes any old hyphens then sets new one.
160
 \param it references \see PageItem - text frame.
161
 \param text is a word to hyphenate.
162
 \param firstC is the first character of the word in \a it item.
163
 \retval None
164
 */
3 paul 165
void Hyphenator::slotHyphenateWord(PageItem* it, QString text, int firstC)
166
{
164 Franz 167
        if ((!useAble) || (!Sap->Sprachen.contains(it->Language)))
168
                return;
3 paul 169
        const char *word;
164 Franz 170
        char *buffer;
171
        const int BORDER = 2;
3 paul 172
        QCString te;
164 Franz 173
 
118 Franz 174
        uint maxC = it->Ptext.count() - 1;
3 paul 175
        QString found = text;
176
        if (static_cast<int>(found.length()) > MinWordLen)
164 Franz 177
        {
178
                te = codec->fromUnicode( found );
3 paul 179
                word = te.data();
180
                buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
181
                if (buffer == NULL)
182
                        return;
183
                if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer));
164 Franz 184
                {
3 paul 185
                        uint i = 0;
164 Franz 186
                        buffer[strlen(word)] = '\0';
118 Franz 187
                        for (i = 1; i < found.length()-1; ++i)
188
                                it->Ptext.at(QMIN(maxC, i+firstC))->cstyle &= 127;              // Delete any old Hyphens
189
                        for (i = 1; i < found.length()-1; ++i)
164 Franz 190
                        {
3 paul 191
                                if(buffer[i] & 1)
118 Franz 192
                                        it->Ptext.at(QMIN(maxC, i+firstC))->cstyle ^= 128;      // Set new Hyphens according Buffer
3 paul 193
                        }
164 Franz 194
                }
3 paul 195
                free(buffer);
164 Franz 196
        }
3 paul 197
}
198
 
159 Franz 199
/*!
200
 \fn void Hyphenator::slotHyphenate(PageItem* it)
201
 \brief Make hyphenation as described in \see slotHyphenateWord for the whole text frame.
202
 \date
203
 \author Franz Schmid
204
 \param it references \see PageItem - text frame.
205
 \retval None
206
 */
3 paul 207
void Hyphenator::slotHyphenate(PageItem* it)
208
{
164 Franz 209
        if ((!useAble) || (it->PType != 4) || (it ->Ptext.count() == 0))
210
                return;
3 paul 211
        const char *word;
164 Franz 212
        char *buffer;
213
        const int BORDER = 2;
3 paul 214
        QString text = "";
215
        QString buf;
216
        QCString te;
217
        for (uint a = 0; a < it->Ptext.count(); ++a)
164 Franz 218
        {
219
                if (it->HasSel)
3 paul 220
                {
221
                        if (it->Ptext.at(a)->cselect)
222
                                text += it->Ptext.at(a)->ch;
164 Franz 223
                }
3 paul 224
                else
225
                        text += it->Ptext.at(a)->ch;
164 Franz 226
        }
3 paul 227
        int firstC = 0;
228
        if (it->HasSel)
164 Franz 229
        {
230
                for (uint a = 0; a < it->Ptext.count(); ++a)
3 paul 231
                {
164 Franz 232
                        if (it->Ptext.at(a)->cselect)
3 paul 233
                        {
234
                                firstC = static_cast<int>(a);
235
                                break;
236
                        }
237
                }
164 Franz 238
        }
3 paul 239
        int lastC = 0;
240
        int Ccount = 0;
241
        QString found = "";
242
        QString found2 = "";
118 Franz 243
        uint maxC = it->Ptext.count() - 1;
164 Franz 244
        qApp->setOverrideCursor(QCursor(waitCursor), true);
245
        while ((firstC+Ccount < static_cast<int>(text.length())) && (firstC != -1) &&
246
                        (lastC < static_cast<int>(text.length())))
247
        {
3 paul 248
                firstC = text.find(QRegExp("\\w"), firstC+Ccount);
249
                if (firstC < 0)
250
                        break;
139 Franz 251
                lastC = text.find(QRegExp("\\s|\\W|\\d|\\n|\\r|\\t"), firstC);
3 paul 252
                if (lastC < 0)
253
                        lastC = static_cast<int>(text.length());
254
                Ccount = lastC - firstC;
255
                if (Ccount > MinWordLen)
164 Franz 256
                {
3 paul 257
                        found = text.mid(firstC, Ccount).lower();
258
                        found2 = text.mid(firstC, Ccount);
164 Franz 259
                        te = codec->fromUnicode( found );
3 paul 260
                        word = te.data();
261
                        buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
262
                        if (buffer == NULL)
263
                                break;
264
                        if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer));
164 Franz 265
                        {
266
                                uint i = 0;
267
                                buffer[strlen(word)] = '\0';
118 Franz 268
                                for (i = 1; i < found.length()-1; ++i)
269
                                        it->Ptext.at(QMIN(maxC, i+firstC))->cstyle &= 127;              // Delete any old Hyphens
3 paul 270
                                bool hasHyphen = false;
118 Franz 271
                                for (i = 1; i < found.length()-1; ++i)
164 Franz 272
                                {
273
                                        if(buffer[i] & 1)
3 paul 274
                                        {
275
                                                hasHyphen = true;
276
                                                break;
277
                                        }
164 Franz 278
                                }
3 paul 279
                                if (hasHyphen)
164 Franz 280
                                {
281
                                        if (!Automatic)
3 paul 282
                                        {
283
                                                QString outs = "";
284
                                                outs += found2[0];
118 Franz 285
                                                for (i = 1; i < found.length()-1; ++i)
164 Franz 286
                                                {
3 paul 287
                                                        outs += found2[i];
288
                                                        if(buffer[i] & 1)
289
                                                                outs += "-";
164 Franz 290
                                                }
3 paul 291
                                                outs += found2.right(1);
292
                                                qApp->setOverrideCursor(QCursor(ArrowCursor), true);
293
                                                HyAsk *dia = new HyAsk((QWidget*)parent(), outs);
294
                                                qApp->processEvents();
295
                                                if (dia->exec())
164 Franz 296
                                                {
3 paul 297
                                                        outs = dia->Wort->text();
298
                                                        uint ii = 0;
299
                                                        for (i = 1; i < outs.length()-1; ++i)
164 Franz 300
                                                        {
3 paul 301
                                                                QChar cht = outs[i];
302
                                                                if (cht == "-")
164 Franz 303
                                                                        it->Ptext.at(QMIN(maxC, ii+firstC))->cstyle ^= 128;    
3 paul 304
                                                                else
305
                                                                        ii++;
306
                                                        }
164 Franz 307
                                                }
3 paul 308
                                                else
164 Franz 309
                                                {
3 paul 310
                                                        free(buffer);
311
                                                        delete dia;
312
                                                        break;
164 Franz 313
                                                }
3 paul 314
                                                delete dia;
164 Franz 315
                                                qApp->setOverrideCursor(QCursor(waitCursor), true);
316
                                        }
3 paul 317
                                        else
164 Franz 318
                                        {
319
                                                for (i = 1; i < found.length()-1; ++i)
3 paul 320
                                                {
321
                                                        if(buffer[i] & 1)
164 Franz 322
                                                                it->Ptext.at(QMIN(maxC, i+firstC))->cstyle ^= 128;     
323
                                                }
3 paul 324
                                        }
325
                                }
164 Franz 326
                        }
3 paul 327
                        free(buffer);
328
                        buffer = NULL;
164 Franz 329
                }
3 paul 330
                if (Ccount == 0)
331
                        Ccount++;
164 Franz 332
        }
3 paul 333
        it->Dirty = true;
334
        qApp->setOverrideCursor(QCursor(ArrowCursor), true);
107 Franz 335
        it->OwnPage->RefreshItem(it);
3 paul 336
}