Subversion Repositories Scribus

Rev

Rev 2834 | Rev 3987 | 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
 
2688 craig 21
#include "scconfig.h"
128 Franz 22
 
3 paul 23
#include <qregexp.h>
24
#include <qcursor.h>
25
#include <qdir.h>
26
#include <cstdlib>
80 Franz 27
#include <string>
1693 craig 28
#include "scpaths.h"
3 paul 29
#include "scribus.h"
1866 fschmid 30
#include "prefsfile.h"
2834 cbradney 31
#include "prefsmanager.h"
3 paul 32
 
1866 fschmid 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;
1693 craig 53
        QString pfad = ScPaths::instance().libDir();
3 paul 54
        if (Sap->Sprachen.contains(doc->Language))
55
                Language = doc->Language;
56
        else
164 Franz 57
        {
2834 cbradney 58
                Language = PrefsManager::instance()->appPrefs.Language;
3 paul 59
                doc->Language = Language;
164 Franz 60
        }
872 cbradney 61
        pfad += "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);
1693 craig 111
        QString pfad = ScPaths::instance().libDir();
3 paul 112
        Language = name;
113
        doc->Language = name;
872 cbradney 114
        pfad += "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
 
1065 cbradney 177
        uint maxC = it->itemText.count() - 1;
3 paul 178
        QString found = text;
1933 fschmid 179
        if (static_cast<int>(found.length()) > MinWordLen-1)
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;
2743 fschmid 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)
2185 fschmid 191
                                it->itemText.at(QMIN(maxC, i+firstC))->cstyle &= 1919;          // Delete any old Hyphens
118 Franz 192
                        for (i = 1; i < found.length()-1; ++i)
164 Franz 193
                        {
3 paul 194
                                if(buffer[i] & 1)
1065 cbradney 195
                                        it->itemText.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
{
1957 cbradney 212
        PageItem *nextItem = it;
356 Franz 213
        PageItem *nb1;
1957 cbradney 214
        while (nextItem != 0)
356 Franz 215
        {
1957 cbradney 216
                if (nextItem->BackBox != 0)
217
                        nextItem = nextItem->BackBox;
356 Franz 218
                else
219
                        break;
220
        }
1957 cbradney 221
        nb1 = nextItem;
222
        while (nextItem != 0)
356 Franz 223
        {
1957 cbradney 224
                uint a = nextItem->itemText.count();
356 Franz 225
                for (uint s = 0; s < a; ++s)
1957 cbradney 226
                        nb1->itemText.append(nextItem->itemText.take(0));
227
                nextItem->MaxChars = 0;
228
                nextItem->CPos = 0;
229
                nextItem = nextItem->NextBox;
356 Franz 230
        }
1460 cbradney 231
        if ((!useAble) || (nb1->itemType() != PageItem::TextFrame) || (nb1 ->itemText.count() == 0))
164 Franz 232
                return;
357 Franz 233
        doc->DoDrawing = false;
3 paul 234
        const char *word;
164 Franz 235
        char *buffer;
236
        const int BORDER = 2;
3 paul 237
        QString text = "";
238
        QString buf;
239
        QCString te;
1065 cbradney 240
        for (uint a = 0; a < nb1->itemText.count(); ++a)
164 Franz 241
        {
356 Franz 242
                if (nb1->HasSel)
3 paul 243
                {
1065 cbradney 244
                        if (nb1->itemText.at(a)->cselect)
245
                                text += nb1->itemText.at(a)->ch;
164 Franz 246
                }
3 paul 247
                else
1065 cbradney 248
                        text += nb1->itemText.at(a)->ch;
164 Franz 249
        }
3 paul 250
        int firstC = 0;
356 Franz 251
        if (nb1->HasSel)
164 Franz 252
        {
1065 cbradney 253
                for (uint a = 0; a < nb1->itemText.count(); ++a)
3 paul 254
                {
1065 cbradney 255
                        if (nb1->itemText.at(a)->cselect)
3 paul 256
                        {
257
                                firstC = static_cast<int>(a);
258
                                break;
259
                        }
260
                }
164 Franz 261
        }
3 paul 262
        int lastC = 0;
263
        int Ccount = 0;
264
        QString found = "";
265
        QString found2 = "";
1065 cbradney 266
        uint maxC = nb1->itemText.count() - 1;
164 Franz 267
        qApp->setOverrideCursor(QCursor(waitCursor), true);
268
        while ((firstC+Ccount < static_cast<int>(text.length())) && (firstC != -1) &&
269
                        (lastC < static_cast<int>(text.length())))
270
        {
3 paul 271
                firstC = text.find(QRegExp("\\w"), firstC+Ccount);
272
                if (firstC < 0)
273
                        break;
139 Franz 274
                lastC = text.find(QRegExp("\\s|\\W|\\d|\\n|\\r|\\t"), firstC);
3 paul 275
                if (lastC < 0)
276
                        lastC = static_cast<int>(text.length());
277
                Ccount = lastC - firstC;
1933 fschmid 278
                if (Ccount > MinWordLen-1)
164 Franz 279
                {
3 paul 280
                        found = text.mid(firstC, Ccount).lower();
281
                        found2 = text.mid(firstC, Ccount);
164 Franz 282
                        te = codec->fromUnicode( found );
3 paul 283
                        word = te.data();
284
                        buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
285
                        if (buffer == NULL)
286
                                break;
2743 fschmid 287
                        if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer))
164 Franz 288
                        {
289
                                uint i = 0;
290
                                buffer[strlen(word)] = '\0';
118 Franz 291
                                for (i = 1; i < found.length()-1; ++i)
2185 fschmid 292
                                        nb1->itemText.at(QMIN(maxC, i+firstC))->cstyle &= 1919;         // Delete any old Hyphens
3 paul 293
                                bool hasHyphen = false;
118 Franz 294
                                for (i = 1; i < found.length()-1; ++i)
164 Franz 295
                                {
296
                                        if(buffer[i] & 1)
3 paul 297
                                        {
298
                                                hasHyphen = true;
299
                                                break;
300
                                        }
164 Franz 301
                                }
3 paul 302
                                if (hasHyphen)
164 Franz 303
                                {
304
                                        if (!Automatic)
3 paul 305
                                        {
306
                                                QString outs = "";
307
                                                outs += found2[0];
118 Franz 308
                                                for (i = 1; i < found.length()-1; ++i)
164 Franz 309
                                                {
3 paul 310
                                                        outs += found2[i];
311
                                                        if(buffer[i] & 1)
312
                                                                outs += "-";
164 Franz 313
                                                }
3 paul 314
                                                outs += found2.right(1);
315
                                                qApp->setOverrideCursor(QCursor(ArrowCursor), true);
2856 cbradney 316
                                                PrefsContext* prefs = PrefsManager::instance()->prefsFile->getContext("hyhpen_options");
1866 fschmid 317
                                                int xpos = prefs->getInt("Xposition", -9999);
318
                                                int ypos = prefs->getInt("Yposition", -9999);
3 paul 319
                                                HyAsk *dia = new HyAsk((QWidget*)parent(), outs);
1866 fschmid 320
                                                if ((xpos != -9999) && (ypos != -9999))
321
                                                        dia->move(xpos, ypos);
3 paul 322
                                                qApp->processEvents();
323
                                                if (dia->exec())
164 Franz 324
                                                {
3 paul 325
                                                        outs = dia->Wort->text();
326
                                                        uint ii = 0;
327
                                                        for (i = 1; i < outs.length()-1; ++i)
164 Franz 328
                                                        {
3 paul 329
                                                                QChar cht = outs[i];
330
                                                                if (cht == "-")
1065 cbradney 331
                                                                        nb1->itemText.at(QMIN(maxC, ii+firstC))->cstyle |= 128;
3 paul 332
                                                                else
333
                                                                        ii++;
334
                                                        }
164 Franz 335
                                                }
3 paul 336
                                                else
164 Franz 337
                                                {
3 paul 338
                                                        free(buffer);
1866 fschmid 339
                                                        prefs->set("Xposition", dia->xpos);
340
                                                        prefs->set("Yposition", dia->ypos);
3 paul 341
                                                        delete dia;
342
                                                        break;
164 Franz 343
                                                }
1866 fschmid 344
                                                prefs->set("Xposition", dia->xpos);
345
                                                prefs->set("Yposition", dia->ypos);
3 paul 346
                                                delete dia;
164 Franz 347
                                                qApp->setOverrideCursor(QCursor(waitCursor), true);
348
                                        }
3 paul 349
                                        else
164 Franz 350
                                        {
351
                                                for (i = 1; i < found.length()-1; ++i)
3 paul 352
                                                {
353
                                                        if(buffer[i] & 1)
1065 cbradney 354
                                                                nb1->itemText.at(QMIN(maxC, i+firstC))->cstyle |= 128;
164 Franz 355
                                                }
3 paul 356
                                        }
357
                                }
164 Franz 358
                        }
3 paul 359
                        free(buffer);
360
                        buffer = NULL;
164 Franz 361
                }
3 paul 362
                if (Ccount == 0)
363
                        Ccount++;
164 Franz 364
        }
3 paul 365
        qApp->setOverrideCursor(QCursor(ArrowCursor), true);
357 Franz 366
        doc->DoDrawing = true;
3 paul 367
}
2621 fschmid 368
 
369
/*!
370
 \fn void Hyphenator::slotDeHyphenate(PageItem* it)
371
 \brief Removes hyphenation either for the whole text frame or the selected text if there is a selection.
372
 \date
373
 \author Franz Schmid
374
 \param it references \see PageItem - text frame.
375
 \retval None
376
 */
377
void Hyphenator::slotDeHyphenate(PageItem* it)
378
{
379
        PageItem *nextItem = it;
380
        PageItem *nb1;
381
        if ((it->itemType() != PageItem::TextFrame) || (it ->itemText.count() == 0))
382
                return;
383
        while (nextItem != 0)
384
        {
385
                if (nextItem->BackBox != 0)
386
                        nextItem = nextItem->BackBox;
387
                else
388
                        break;
389
        }
390
        nb1 = nextItem;
391
        while (nextItem != 0)
392
        {
393
                uint a = nextItem->itemText.count();
394
                for (uint s = 0; s < a; ++s)
395
                        nb1->itemText.append(nextItem->itemText.take(0));
396
                nextItem->MaxChars = 0;
397
                nextItem->CPos = 0;
398
                nextItem = nextItem->NextBox;
399
        }
400
        doc->DoDrawing = false;
401
        for (uint a = 0; a < nb1->itemText.count(); ++a)
402
        {
403
                if (nb1->HasSel)
404
                {
405
                        if (nb1->itemText.at(a)->cselect)
406
                                nb1->itemText.at(a)->cstyle &= 1919;
407
                }
408
                else
409
                        nb1->itemText.at(a)->cstyle &= 1919;
410
        }
411
        qApp->setOverrideCursor(QCursor(ArrowCursor), true);
412
        doc->DoDrawing = true;
413
}