Subversion Repositories Scribus

Rev

Rev 164 | Rev 317 | 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)
118 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
{
164 Franz 212
        if ((!useAble) || (it->PType != 4) || (it ->Ptext.count() == 0))
213
                return;
3 paul 214
        const char *word;
164 Franz 215
        char *buffer;
216
        const int BORDER = 2;
3 paul 217
        QString text = "";
218
        QString buf;
219
        QCString te;
220
        for (uint a = 0; a < it->Ptext.count(); ++a)
164 Franz 221
        {
222
                if (it->HasSel)
3 paul 223
                {
224
                        if (it->Ptext.at(a)->cselect)
225
                                text += it->Ptext.at(a)->ch;
164 Franz 226
                }
3 paul 227
                else
228
                        text += it->Ptext.at(a)->ch;
164 Franz 229
        }
3 paul 230
        int firstC = 0;
231
        if (it->HasSel)
164 Franz 232
        {
233
                for (uint a = 0; a < it->Ptext.count(); ++a)
3 paul 234
                {
164 Franz 235
                        if (it->Ptext.at(a)->cselect)
3 paul 236
                        {
237
                                firstC = static_cast<int>(a);
238
                                break;
239
                        }
240
                }
164 Franz 241
        }
3 paul 242
        int lastC = 0;
243
        int Ccount = 0;
244
        QString found = "";
245
        QString found2 = "";
118 Franz 246
        uint maxC = it->Ptext.count() - 1;
164 Franz 247
        qApp->setOverrideCursor(QCursor(waitCursor), true);
248
        while ((firstC+Ccount < static_cast<int>(text.length())) && (firstC != -1) &&
249
                        (lastC < static_cast<int>(text.length())))
250
        {
3 paul 251
                firstC = text.find(QRegExp("\\w"), firstC+Ccount);
252
                if (firstC < 0)
253
                        break;
139 Franz 254
                lastC = text.find(QRegExp("\\s|\\W|\\d|\\n|\\r|\\t"), firstC);
3 paul 255
                if (lastC < 0)
256
                        lastC = static_cast<int>(text.length());
257
                Ccount = lastC - firstC;
258
                if (Ccount > MinWordLen)
164 Franz 259
                {
3 paul 260
                        found = text.mid(firstC, Ccount).lower();
261
                        found2 = text.mid(firstC, Ccount);
164 Franz 262
                        te = codec->fromUnicode( found );
3 paul 263
                        word = te.data();
264
                        buffer = static_cast<char*>(malloc(strlen(word)+BORDER+3));
265
                        if (buffer == NULL)
266
                                break;
267
                        if (!hnj_hyphen_hyphenate(hdict, word, strlen(word), buffer));
164 Franz 268
                        {
269
                                uint i = 0;
270
                                buffer[strlen(word)] = '\0';
118 Franz 271
                                for (i = 1; i < found.length()-1; ++i)
272
                                        it->Ptext.at(QMIN(maxC, i+firstC))->cstyle &= 127;              // Delete any old Hyphens
3 paul 273
                                bool hasHyphen = false;
118 Franz 274
                                for (i = 1; i < found.length()-1; ++i)
164 Franz 275
                                {
276
                                        if(buffer[i] & 1)
3 paul 277
                                        {
278
                                                hasHyphen = true;
279
                                                break;
280
                                        }
164 Franz 281
                                }
3 paul 282
                                if (hasHyphen)
164 Franz 283
                                {
284
                                        if (!Automatic)
3 paul 285
                                        {
286
                                                QString outs = "";
287
                                                outs += found2[0];
118 Franz 288
                                                for (i = 1; i < found.length()-1; ++i)
164 Franz 289
                                                {
3 paul 290
                                                        outs += found2[i];
291
                                                        if(buffer[i] & 1)
292
                                                                outs += "-";
164 Franz 293
                                                }
3 paul 294
                                                outs += found2.right(1);
295
                                                qApp->setOverrideCursor(QCursor(ArrowCursor), true);
296
                                                HyAsk *dia = new HyAsk((QWidget*)parent(), outs);
297
                                                qApp->processEvents();
298
                                                if (dia->exec())
164 Franz 299
                                                {
3 paul 300
                                                        outs = dia->Wort->text();
301
                                                        uint ii = 0;
302
                                                        for (i = 1; i < outs.length()-1; ++i)
164 Franz 303
                                                        {
3 paul 304
                                                                QChar cht = outs[i];
305
                                                                if (cht == "-")
164 Franz 306
                                                                        it->Ptext.at(QMIN(maxC, ii+firstC))->cstyle ^= 128;    
3 paul 307
                                                                else
308
                                                                        ii++;
309
                                                        }
164 Franz 310
                                                }
3 paul 311
                                                else
164 Franz 312
                                                {
3 paul 313
                                                        free(buffer);
314
                                                        delete dia;
315
                                                        break;
164 Franz 316
                                                }
3 paul 317
                                                delete dia;
164 Franz 318
                                                qApp->setOverrideCursor(QCursor(waitCursor), true);
319
                                        }
3 paul 320
                                        else
164 Franz 321
                                        {
322
                                                for (i = 1; i < found.length()-1; ++i)
3 paul 323
                                                {
324
                                                        if(buffer[i] & 1)
164 Franz 325
                                                                it->Ptext.at(QMIN(maxC, i+firstC))->cstyle ^= 128;     
326
                                                }
3 paul 327
                                        }
328
                                }
164 Franz 329
                        }
3 paul 330
                        free(buffer);
331
                        buffer = NULL;
164 Franz 332
                }
3 paul 333
                if (Ccount == 0)
334
                        Ccount++;
164 Franz 335
        }
3 paul 336
        it->Dirty = true;
337
        qApp->setOverrideCursor(QCursor(ArrowCursor), true);
107 Franz 338
        it->OwnPage->RefreshItem(it);
3 paul 339
}