Subversion Repositories Scribus

Rev

Rev 23798 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
3 paul 7
/***************************************************************************
8
                          hyphenator.cpp  -  description
9
                             -------------------
10
    begin                : Sat Nov 02 08:00:00 CEST 2002
11
    copyright            : (C) 2002 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23
#include "hyphenator.h"
13650 cbradney 24
#include "ui/hyask.h"
128 Franz 25
 
2688 craig 26
#include "scconfig.h"
128 Franz 27
 
16546 jghali 28
#include <QApplication>
10223 cbradney 29
#include <QCursor>
10242 subik 30
#include <QCheckBox>
9535 fschmid 31
#include <QByteArray>
23660 craig 32
#include <unicode/brkiter.h>
21563 jghali 33
 
12787 pierre 34
#include "langmgr.h"
1693 craig 35
#include "scpaths.h"
5781 cbradney 36
#include "scribuscore.h"
13805 jghali 37
#include "scribusdoc.h"
1866 fschmid 38
#include "prefsfile.h"
2834 cbradney 39
#include "prefsmanager.h"
3 paul 40
 
23660 craig 41
using namespace icu;
42
 
10511 fschmid 43
Hyphenator::Hyphenator(QWidget* parent, ScribusDoc *dok) : QObject( parent ),
18330 jghali 44
        m_doc(dok),
22519 craig 45
        m_hdict(nullptr),
46
        m_codec(nullptr),
21563 jghali 47
        m_automatic(m_doc->hyphAutomatic()),
18330 jghali 48
        AutoCheck(m_doc->hyphAutoCheck())
3 paul 49
{
10170 fschmid 50
        rememberedWords.clear();
51
/* Add reading these special lists from prefs or doc here */
52
        ignoredWords.clear();
53
        specialWords.clear();
3 paul 54
}
55
 
56
Hyphenator::~Hyphenator()
57
{
18330 jghali 58
        if (m_hdict)
59
                hnj_hyphen_free(m_hdict);
3 paul 60
}
61
 
21563 jghali 62
bool Hyphenator::loadDict(const QString& name)
3 paul 63
{
22164 jghali 64
        if (LanguageManager::instance()->getHyphFilename(name).isEmpty())
21563 jghali 65
                return false;
12787 pierre 66
 
21563 jghali 67
        if (m_language != name)
164 Franz 68
        {
21563 jghali 69
                m_language = name;
6931 avox 70
 
21563 jghali 71
                QFile file(LanguageManager::instance()->getHyphFilename(m_language));
6931 avox 72
 
22519 craig 73
                if (m_hdict != nullptr)
18330 jghali 74
                        hnj_hyphen_free(m_hdict);
6931 avox 75
 
21563 jghali 76
                if (file.open(QIODevice::ReadOnly))
6931 avox 77
                {
21563 jghali 78
                        m_codec = QTextCodec::codecForName(file.readLine());
79
                        m_hdict = hnj_hyphen_load(file.fileName().toLocal8Bit().data());
80
                        file.close();
81
                        return true;
6931 avox 82
                }
22600 craig 83
                m_hdict = nullptr;
84
                return false;
164 Franz 85
        }
21563 jghali 86
 
22600 craig 87
        return (m_codec != nullptr && m_hdict != nullptr);
3 paul 88
}
89
 
21563 jghali 90
void Hyphenator::slotNewSettings(bool Autom, bool ACheck)
3 paul 91
{
92
        AutoCheck = ACheck;
18330 jghali 93
        m_doc->setHyphAutomatic(Autom);
94
        m_doc->setHyphAutoCheck(AutoCheck);
3 paul 95
}
96
 
6931 avox 97
void Hyphenator::slotHyphenateWord(PageItem* it, const QString& text, int firstC)
3 paul 98
{
21563 jghali 99
        if (text.contains(SpecialChars::SHYPHEN))
164 Franz 100
                return;
22164 jghali 101
 
21563 jghali 102
        const CharStyle& style = it->itemText.charStyle(firstC);
22165 jghali 103
        if (text.length() < style.hyphenWordMin())
104
                return;
105
 
106
        bool ok = loadDict(style.language());
107
        if (!ok)
108
                return;
109
 
110
        QByteArray te = m_codec->fromUnicode(text);
111
        char *buffer = static_cast<char*>(malloc(te.length() + 5));
22519 craig 112
        if (buffer == nullptr)
22165 jghali 113
                return;
22519 craig 114
        char **rep = nullptr;
115
        int *pos = nullptr;
116
        int *cut = nullptr;
22165 jghali 117
        // TODO: support non-standard hyphenation, see hnj_hyphen_hyphenate2 docs
22519 craig 118
        if (!hnj_hyphen_hyphenate2(m_hdict, te.data(), te.length(), buffer, nullptr, &rep, &pos, &cut))
21563 jghali 119
        {
22165 jghali 120
                buffer[te.length()] = '\0';
121
                it->itemText.hyphenateWord(firstC, text.length(), buffer);
164 Franz 122
        }
22165 jghali 123
        free(buffer);
124
        if (rep)
125
        {
126
                for (int i = 0; i < te.length() - 1; ++i)
127
                        free(rep[i]);
128
        }
129
        free(rep);
130
        free(pos);
131
        free(cut);
3 paul 132
}
133
 
134
void Hyphenator::slotHyphenate(PageItem* it)
135
{
23798 craig 136
        if (!(it->isTextFrame()) || (it->itemText.length() == 0))
164 Franz 137
                return;
18330 jghali 138
        m_doc->DoDrawing = false;
5559 avox 139
 
3 paul 140
        QString text = "";
5559 avox 141
 
6931 avox 142
        int startC = 0;
23940 jghali 143
        if (it->itemText.hasSelection())
164 Franz 144
        {
6931 avox 145
                startC = it->itemText.startOfSelection();
22832 craig 146
                text = it->itemText.text(startC, it->itemText.selectionLength());
164 Franz 147
        }
5559 avox 148
        else {
149
                text = it->itemText.text(0, it->itemText.length());
150
        }
21563 jghali 151
 
9769 fschmid 152
        rememberedWords.clear();
18181 fschmid 153
        qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
21563 jghali 154
 
155
        BreakIterator* bi = StoryText::getWordIterator();
156
        bi->setText((const UChar*) text.utf16());
157
        int pos = bi->first();
158
        while (pos != BreakIterator::DONE)
164 Franz 159
        {
21563 jghali 160
                int firstC = pos;
161
                pos = bi->next();
162
                int lastC = pos;
163
                int countC = lastC - firstC;
164
 
165
                const CharStyle& style = it->itemText.charStyle(firstC);
166
                if (countC > 0 && countC > style.hyphenWordMin() - 1)
7029 avox 167
                {
21563 jghali 168
                        QString word = text.mid(firstC, countC);
169
                        QString wordLower = QLocale(style.language()).toLower(word);
170
                        if (wordLower.contains(SpecialChars::SHYPHEN))
6931 avox 171
                                break;
172
 
21563 jghali 173
                        bool ok = loadDict(style.language());
174
                        if (!ok)
175
                                continue;
6931 avox 176
 
21563 jghali 177
                        QByteArray te = m_codec->fromUnicode(wordLower);
178
                        char *buffer = static_cast<char*>(malloc(te.length() + 5));
22519 craig 179
                        if (buffer == nullptr)
3 paul 180
                                break;
21563 jghali 181
 
22519 craig 182
                        char **rep = nullptr;
183
                        int *pos = nullptr;
184
                        int *cut = nullptr;
21563 jghali 185
                        // TODO: support non-standard hyphenation, see hnj_hyphen_hyphenate2 docs
22519 craig 186
                        if (!hnj_hyphen_hyphenate2(m_hdict, te.data(), te.length(), buffer, nullptr, &rep, &pos, &cut))
164 Franz 187
                        {
8547 cbradney 188
                                int i = 0;
21563 jghali 189
                                buffer[te.length()] = '\0';
3 paul 190
                                bool hasHyphen = false;
21563 jghali 191
                                for (i = 1; i < wordLower.length()-1; ++i)
164 Franz 192
                                {
193
                                        if(buffer[i] & 1)
3 paul 194
                                        {
195
                                                hasHyphen = true;
196
                                                break;
197
                                        }
164 Franz 198
                                }
10170 fschmid 199
                                QString outs = "";
200
                                QString input = "";
21563 jghali 201
                                outs += word[0];
202
                                for (i = 1; i < wordLower.length()-1; ++i)
6931 avox 203
                                {
21563 jghali 204
                                        outs += word[i];
10170 fschmid 205
                                        if(buffer[i] & 1)
206
                                                outs += "-";
6931 avox 207
                                }
22289 craig 208
                                outs += word.rightRef(1);
10170 fschmid 209
                                input = outs;
21563 jghali 210
                                if (!ignoredWords.contains(word))
10170 fschmid 211
                                {
212
                                        if (!hasHyphen)
22519 craig 213
                                                it->itemText.hyphenateWord(startC + firstC, wordLower.length(), nullptr);
21563 jghali 214
                                        else if (m_automatic)
13112 fschmid 215
                                        {
21563 jghali 216
                                                if (specialWords.contains(word))
13112 fschmid 217
                                                {
21563 jghali 218
                                                        outs = specialWords.value(word);
13112 fschmid 219
                                                        uint ii = 1;
220
                                                        for (i = 1; i < outs.length()-1; ++i)
221
                                                        {
222
                                                                QChar cht = outs[i];
223
                                                                if (cht == '-')
224
                                                                        buffer[ii-1] = 1;
225
                                                                else
226
                                                                {
227
                                                                        buffer[ii] = 0;
228
                                                                        ++ii;
229
                                                                }
230
                                                        }
231
                                                }
21563 jghali 232
                                                it->itemText.hyphenateWord(startC + firstC, wordLower.length(), buffer);
13112 fschmid 233
                                        }
10170 fschmid 234
                                        else
3 paul 235
                                        {
21563 jghali 236
                                                if (specialWords.contains(word))
164 Franz 237
                                                {
21563 jghali 238
                                                        outs = specialWords.value(word);
12094 jghali 239
                                                        uint ii = 1;
10170 fschmid 240
                                                        for (i = 1; i < outs.length()-1; ++i)
241
                                                        {
242
                                                                QChar cht = outs[i];
243
                                                                if (cht == '-')
12094 jghali 244
                                                                        buffer[ii-1] = 1;
10170 fschmid 245
                                                                else
12094 jghali 246
                                                                {
10170 fschmid 247
                                                                        buffer[ii] = 0;
12094 jghali 248
                                                                        ++ii;
249
                                                                }
10170 fschmid 250
                                                        }
164 Franz 251
                                                }
10179 fschmid 252
                                                if (rememberedWords.contains(input))
9769 fschmid 253
                                                {
10170 fschmid 254
                                                        outs = rememberedWords.value(input);
12094 jghali 255
                                                        uint ii = 1;
9769 fschmid 256
                                                        for (i = 1; i < outs.length()-1; ++i)
257
                                                        {
258
                                                                QChar cht = outs[i];
259
                                                                if (cht == '-')
12094 jghali 260
                                                                        buffer[ii-1] = 1;
9769 fschmid 261
                                                                else
12094 jghali 262
                                                                {
10170 fschmid 263
                                                                        buffer[ii] = 0;
12094 jghali 264
                                                                        ++ii;
265
                                                                }
9769 fschmid 266
                                                        }
21563 jghali 267
                                                        it->itemText.hyphenateWord(firstC, wordLower.length(), buffer);
9769 fschmid 268
                                                }
269
                                                else
270
                                                {
10170 fschmid 271
                                                        qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
23060 craig 272
                                                        PrefsContext* prefs = PrefsManager::instance().prefsFile->getContext("hyhpen_options");
10170 fschmid 273
                                                        int xpos = prefs->getInt("Xposition", -9999);
274
                                                        int ypos = prefs->getInt("Yposition", -9999);
275
                                                        HyAsk *dia = new HyAsk((QWidget*)parent(), outs);
276
                                                        if ((xpos != -9999) && (ypos != -9999))
277
                                                                dia->move(xpos, ypos);
278
                                                        qApp->processEvents();
279
                                                        if (dia->exec())
280
                                                        {
281
                                                                outs = dia->Wort->text();
12094 jghali 282
                                                                uint ii = 1;
10170 fschmid 283
                                                                for (i = 1; i < outs.length()-1; ++i)
284
                                                                {
285
                                                                        QChar cht = outs[i];
286
                                                                        if (cht == '-')
12094 jghali 287
                                                                                buffer[ii-1] = 1;
10170 fschmid 288
                                                                        else
12094 jghali 289
                                                                        {
10170 fschmid 290
                                                                                buffer[ii] = 0;
12094 jghali 291
                                                                                ++ii;
292
                                                                        }
10170 fschmid 293
                                                                }
294
                                                                if (!rememberedWords.contains(input))
295
                                                                        rememberedWords.insert(input, outs);
296
                                                                if (dia->addToIgnoreList->isChecked())
297
                                                                {
21563 jghali 298
                                                                        if (!ignoredWords.contains(word))
299
                                                                                ignoredWords.insert(word);
10170 fschmid 300
                                                                }
301
                                                                if (dia->addToExceptionList->isChecked())
302
                                                                {
21563 jghali 303
                                                                        if (!specialWords.contains(word))
304
                                                                                specialWords.insert(word, outs);
10170 fschmid 305
                                                                }
21563 jghali 306
                                                                it->itemText.hyphenateWord(firstC, wordLower.length(), buffer);
10170 fschmid 307
                                                        }
308
                                                        else
309
                                                        {
310
                                                                free(buffer);
22519 craig 311
                                                                buffer = nullptr;
10170 fschmid 312
                                                                prefs->set("Xposition", dia->xpos);
313
                                                                prefs->set("Yposition", dia->ypos);
314
                                                                delete dia;
315
                                                                break;
316
                                                        }
9769 fschmid 317
                                                        prefs->set("Xposition", dia->xpos);
318
                                                        prefs->set("Yposition", dia->ypos);
319
                                                        delete dia;
10170 fschmid 320
                                                        qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
9769 fschmid 321
                                                }
164 Franz 322
                                        }
3 paul 323
                                }
164 Franz 324
                        }
3 paul 325
                        free(buffer);
18144 jghali 326
                        if (rep)
327
                        {
21563 jghali 328
                                for (int i = 0; i < te.length() - 1; ++i)
329
                                        free(rep[i]);
18144 jghali 330
                        }
21563 jghali 331
                        free(rep);
332
                        free(pos);
333
                        free(cut);
164 Franz 334
                }
335
        }
18181 fschmid 336
        qApp->restoreOverrideCursor();
18330 jghali 337
        m_doc->DoDrawing = true;
9769 fschmid 338
        rememberedWords.clear();
3 paul 339
}
2621 fschmid 340
 
341
void Hyphenator::slotDeHyphenate(PageItem* it)
342
{
23798 craig 343
        if (!(it->isTextFrame()) || (it ->itemText.length() == 0))
2621 fschmid 344
                return;
5559 avox 345
 
23940 jghali 346
        if (it->itemText.hasSelection())
22832 craig 347
                it->itemText.hyphenateWord(it->itemText.startOfSelection(), it->itemText.selectionLength(), nullptr);
22600 craig 348
        else
13054 pierre 349
        {
22600 craig 350
                int i = it->itemText.length();
351
                it->itemText.hyphenateWord(0, i, nullptr);
13054 pierre 352
        }
18330 jghali 353
        m_doc->DoDrawing = true;
2621 fschmid 354
}