Subversion Repositories Scribus

Rev

Rev 317 | Rev 357 | 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;
249 Franz 52
        HyCount = doc->HyCount;
3 paul 53
        QString pfad = PREL;
54
        if (Sap->Sprachen.contains(doc->Language))
55
                Language = doc->Language;
56
        else
164 Franz 57
        {
3 paul 58
                Language = Sap->Prefs.Language;
59
                doc->Language = Language;
164 Franz 60
        }
3 paul 61
        pfad += "/lib/scribus/dicts/" + Sap->Sprachen[Language];
106 Franz 62
        QFile f(pfad);
63
        if (f.open(IO_ReadOnly))
164 Franz 64
        {
106 Franz 65
                QTextStream st(&f);
164 Franz 66
        QString line;
67
        line = st.readLine();
106 Franz 68
                codec = QTextCodec::codecForName(line);
69
                f.close();
164 Franz 70
        }
106 Franz 71
        else
164 Franz 72
        {
106 Franz 73
                useAble = false;
74
                hdict = NULL;
75
                return;
164 Franz 76
        }
3 paul 77
        QCString fn = pfad.latin1();
78
        filename = fn.data();
105 Franz 79
        hdict = hnj_hyphen_load(filename);
164 Franz 80
        useAble = hdict == NULL ? false : true;
3 paul 81
}
82
 
159 Franz 83
/*!
84
 \fn Hyphenator::~Hyphenator()
85
 \brief Safely cleans hyphen.
86
 \date
87
 \author Franz Schmid
88
 \param None
89
 \retval None
90
 */
3 paul 91
Hyphenator::~Hyphenator()
92
{
93
        hnj_hyphen_free(hdict);
94
}
95
 
159 Franz 96
/*!
97
 \fn void Hyphenator::slotNewDict(QString name)
98
 \brief Loads dictionary and fills parameters like \a useAble, \a codec, \a hdict.
99
 \date
100
 \author Franz Schmid
101
 \param name is the name of specified language - filename.
102
 \retval None
103
 */
3 paul 104
void Hyphenator::slotNewDict(QString name)
105
{
106
        if (!Sap->Sprachen.contains(name))
107
                return;
164 Franz 108
        char *filename = NULL;
3 paul 109
        if (hdict != NULL)
110
                hnj_hyphen_free(hdict);
111
        QString pfad = PREL;
112
        Language = name;
113
        doc->Language = name;
114
        pfad += "/lib/scribus/dicts/" + Sap->Sprachen[Language];
106 Franz 115
        QFile f(pfad);
116
        if (f.open(IO_ReadOnly))
164 Franz 117
        {
106 Franz 118
                QTextStream st(&f);
164 Franz 119
                QString line;
120
                line = st.readLine();
106 Franz 121
                codec = QTextCodec::codecForName(line);
122
                f.close();
164 Franz 123
        }
106 Franz 124
        else
164 Franz 125
        {
106 Franz 126
                useAble = false;
127
                hdict = NULL;
128
                return;
164 Franz 129
        }
3 paul 130
        QCString fn = pfad.latin1();
131
        filename = fn.data();
105 Franz 132
        hdict = hnj_hyphen_load(filename);
164 Franz 133
        useAble = hdict == NULL ? false : true;
3 paul 134
}
135
 
159 Franz 136
/*!
137
 \fn void Hyphenator::slotNewSettings(int Wordlen, bool Autom, bool ACheck)
138
 \brief Writes actual hyphen configuration into \a doc object.
139
 \date
140
 \author Franz Schmid
141
 \param WordLen lenght of the word.
142
 \param Autom is automatic flag.
143
 \param ACheck AutoCheck flag.
144
 \retval None
145
 */
249 Franz 146
void Hyphenator::slotNewSettings(int Wordlen, bool Autom, bool ACheck, int Num)
3 paul 147
{
148
        MinWordLen = Wordlen;
149
        Automatic = Autom;
150
        AutoCheck = ACheck;
249 Franz 151
        HyCount = Num;
3 paul 152
        doc->MinWordLen = Wordlen;
153
        doc->Automatic = Autom;
154
        doc->AutoCheck = AutoCheck;
249 Franz 155
        doc->HyCount = Num;
3 paul 156
}
157
 
159 Franz 158
/*!
159
 \fn void Hyphenator::slotHyphenateWord(PageItem* it, QString text, int firstC)
160
 \brief Make hyphenation when user edits text in text frame manually.
161
 \detail If is everything set correctly and textframe selected language fits the
162
    dictionary language. At first removes any old hyphens then sets new one.
163
 \param it references \see PageItem - text frame.
164
 \param text is a word to hyphenate.
165
 \param firstC is the first character of the word in \a it item.
166
 \retval None
167
 */
3 paul 168
void Hyphenator::slotHyphenateWord(PageItem* it, QString text, int firstC)
169
{
164 Franz 170
        if ((!useAble) || (!Sap->Sprachen.contains(it->Language)))
171
                return;
3 paul 172
        const char *word;
164 Franz 173
        char *buffer;
174
        const int BORDER = 2;
3 paul 175
        QCString te;
164 Franz 176
 
118 Franz 177
        uint maxC = it->Ptext.count() - 1;
3 paul 178
        QString found = text;
179
        if (static_cast<int>(found.length()) > MinWordLen)
164 Franz 180
        {
181
                te = codec->fromUnicode( found );
3 paul 182
                word = te.data();
183
                buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
184
                if (buffer == NULL)
185
                        return;
186
                if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer));
164 Franz 187
                {
3 paul 188
                        uint i = 0;
164 Franz 189
                        buffer[strlen(word)] = '\0';
118 Franz 190
                        for (i = 1; i < found.length()-1; ++i)
191
                                it->Ptext.at(QMIN(maxC, i+firstC))->cstyle &= 127;              // Delete any old Hyphens
192
                        for (i = 1; i < found.length()-1; ++i)
164 Franz 193
                        {
3 paul 194
                                if(buffer[i] & 1)
317 Franz 195
                                        it->Ptext.at(QMIN(maxC, i+firstC))->cstyle |= 128;      // Set new Hyphens according Buffer
3 paul 196
                        }
164 Franz 197
                }
3 paul 198
                free(buffer);
164 Franz 199
        }
3 paul 200
}
201
 
159 Franz 202
/*!
203
 \fn void Hyphenator::slotHyphenate(PageItem* it)
204
 \brief Make hyphenation as described in \see slotHyphenateWord for the whole text frame.
205
 \date
206
 \author Franz Schmid
207
 \param it references \see PageItem - text frame.
208
 \retval None
209
 */
3 paul 210
void Hyphenator::slotHyphenate(PageItem* it)
211
{
356 Franz 212
        PageItem *nb = it;
213
        PageItem *nb1;
214
        while (nb != 0)
215
        {
216
                if (nb->BackBox != 0)
217
                        nb = nb->BackBox;
218
                else
219
                        break;
220
        }
221
        nb1 = nb;
222
        while (nb != 0)
223
        {
224
                uint a = nb->Ptext.count();
225
                for (uint s = 0; s < a; ++s)
226
                        nb1->Ptext.append(nb->Ptext.take(0));
227
                nb->MaxChars = 0;
228
                nb->CPos = 0;
229
                nb = nb->NextBox;
230
        }
231
        if ((!useAble) || (nb1->PType != 4) || (nb1 ->Ptext.count() == 0))
164 Franz 232
                return;
3 paul 233
        const char *word;
164 Franz 234
        char *buffer;
235
        const int BORDER = 2;
3 paul 236
        QString text = "";
237
        QString buf;
238
        QCString te;
356 Franz 239
        for (uint a = 0; a < nb1->Ptext.count(); ++a)
164 Franz 240
        {
356 Franz 241
                if (nb1->HasSel)
3 paul 242
                {
356 Franz 243
                        if (nb1->Ptext.at(a)->cselect)
244
                                text += nb1->Ptext.at(a)->ch;
164 Franz 245
                }
3 paul 246
                else
356 Franz 247
                        text += nb1->Ptext.at(a)->ch;
164 Franz 248
        }
3 paul 249
        int firstC = 0;
356 Franz 250
        if (nb1->HasSel)
164 Franz 251
        {
356 Franz 252
                for (uint a = 0; a < nb1->Ptext.count(); ++a)
3 paul 253
                {
356 Franz 254
                        if (nb1->Ptext.at(a)->cselect)
3 paul 255
                        {
256
                                firstC = static_cast<int>(a);
257
                                break;
258
                        }
259
                }
164 Franz 260
        }
3 paul 261
        int lastC = 0;
262
        int Ccount = 0;
263
        QString found = "";
264
        QString found2 = "";
356 Franz 265
        uint maxC = nb1->Ptext.count() - 1;
164 Franz 266
        qApp->setOverrideCursor(QCursor(waitCursor), true);
267
        while ((firstC+Ccount < static_cast<int>(text.length())) && (firstC != -1) &&
268
                        (lastC < static_cast<int>(text.length())))
269
        {
3 paul 270
                firstC = text.find(QRegExp("\\w"), firstC+Ccount);
271
                if (firstC < 0)
272
                        break;
139 Franz 273
                lastC = text.find(QRegExp("\\s|\\W|\\d|\\n|\\r|\\t"), firstC);
3 paul 274
                if (lastC < 0)
275
                        lastC = static_cast<int>(text.length());
276
                Ccount = lastC - firstC;
277
                if (Ccount > MinWordLen)
164 Franz 278
                {
3 paul 279
                        found = text.mid(firstC, Ccount).lower();
280
                        found2 = text.mid(firstC, Ccount);
164 Franz 281
                        te = codec->fromUnicode( found );
3 paul 282
                        word = te.data();
283
                        buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
284
                        if (buffer == NULL)
285
                                break;
286
                        if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer));
164 Franz 287
                        {
288
                                uint i = 0;
289
                                buffer[strlen(word)] = '\0';
118 Franz 290
                                for (i = 1; i < found.length()-1; ++i)
356 Franz 291
                                        nb1->Ptext.at(QMIN(maxC, i+firstC))->cstyle &= 127;             // Delete any old Hyphens
3 paul 292
                                bool hasHyphen = false;
118 Franz 293
                                for (i = 1; i < found.length()-1; ++i)
164 Franz 294
                                {
295
                                        if(buffer[i] & 1)
3 paul 296
                                        {
297
                                                hasHyphen = true;
298
                                                break;
299
                                        }
164 Franz 300
                                }
3 paul 301
                                if (hasHyphen)
164 Franz 302
                                {
303
                                        if (!Automatic)
3 paul 304
                                        {
305
                                                QString outs = "";
306
                                                outs += found2[0];
118 Franz 307
                                                for (i = 1; i < found.length()-1; ++i)
164 Franz 308
                                                {
3 paul 309
                                                        outs += found2[i];
310
                                                        if(buffer[i] & 1)
311
                                                                outs += "-";
164 Franz 312
                                                }
3 paul 313
                                                outs += found2.right(1);
314
                                                qApp->setOverrideCursor(QCursor(ArrowCursor), true);
315
                                                HyAsk *dia = new HyAsk((QWidget*)parent(), outs);
316
                                                qApp->processEvents();
317
                                                if (dia->exec())
164 Franz 318
                                                {
3 paul 319
                                                        outs = dia->Wort->text();
320
                                                        uint ii = 0;
321
                                                        for (i = 1; i < outs.length()-1; ++i)
164 Franz 322
                                                        {
3 paul 323
                                                                QChar cht = outs[i];
324
                                                                if (cht == "-")
356 Franz 325
                                                                        nb1->Ptext.at(QMIN(maxC, ii+firstC))->cstyle |= 128;
3 paul 326
                                                                else
327
                                                                        ii++;
328
                                                        }
164 Franz 329
                                                }
3 paul 330
                                                else
164 Franz 331
                                                {
3 paul 332
                                                        free(buffer);
333
                                                        delete dia;
334
                                                        break;
164 Franz 335
                                                }
3 paul 336
                                                delete dia;
164 Franz 337
                                                qApp->setOverrideCursor(QCursor(waitCursor), true);
338
                                        }
3 paul 339
                                        else
164 Franz 340
                                        {
341
                                                for (i = 1; i < found.length()-1; ++i)
3 paul 342
                                                {
343
                                                        if(buffer[i] & 1)
356 Franz 344
                                                                nb1->Ptext.at(QMIN(maxC, i+firstC))->cstyle |= 128;
164 Franz 345
                                                }
3 paul 346
                                        }
347
                                }
164 Franz 348
                        }
3 paul 349
                        free(buffer);
350
                        buffer = NULL;
164 Franz 351
                }
3 paul 352
                if (Ccount == 0)
353
                        Ccount++;
164 Franz 354
        }
356 Franz 355
        nb1->Dirty = true;
3 paul 356
        qApp->setOverrideCursor(QCursor(ArrowCursor), true);
356 Franz 357
        nb1->OwnPage->RefreshItem(nb1);
3 paul 358
}