Rev 18330 | Rev 19802 | Go to most recent revision | 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 <QRegExp> |
30 | #include <QCursor> |
||
31 | #include <QDir> |
||
10242 | subik | 32 | #include <QCheckBox> |
8501 | cbradney | 33 | //Added by qt3to4: |
9535 | fschmid | 34 | #include <QByteArray> |
3 | paul | 35 | #include <cstdlib> |
80 | Franz | 36 | #include <string> |
12787 | pierre | 37 | #include "langmgr.h" |
1693 | craig | 38 | #include "scpaths.h" |
5781 | cbradney | 39 | #include "scribuscore.h" |
13805 | jghali | 40 | #include "scribusdoc.h" |
1866 | fschmid | 41 | #include "prefsfile.h" |
2834 | cbradney | 42 | #include "prefsmanager.h" |
3 | paul | 43 | |
10511 | fschmid | 44 | Hyphenator::Hyphenator(QWidget* parent, ScribusDoc *dok) : QObject( parent ), |
18330 | jghali | 45 | m_doc(dok), |
46 | m_hdict(0), |
||
47 | m_usable(false), |
||
48 | m_codec(0), |
||
49 | MinWordLen(m_doc->hyphMinimumWordLength()), |
||
50 | HyCount(m_doc->hyphConsecutiveLines()), |
||
51 | Automatic(m_doc->hyphAutomatic()), |
||
52 | AutoCheck(m_doc->hyphAutoCheck()) |
||
3 | paul | 53 | { |
14924 | cbradney | 54 | //FIXME:av pick up language from charstyle |
12787 | pierre | 55 | LanguageManager * lmgr(LanguageManager::instance()); |
18330 | jghali | 56 | if (!lmgr->getHyphFilename(m_doc->hyphLanguage()).isEmpty() ) |
57 | Language = m_doc->hyphLanguage(); |
||
3 | paul | 58 | else |
164 | Franz | 59 | { |
13955 | cbradney | 60 | Language = PrefsManager::instance()->appPrefs.hyphPrefs.Language; |
18330 | jghali | 61 | m_doc->setHyphLanguage(Language); |
164 | Franz | 62 | } |
18330 | jghali | 63 | QString pfad = lmgr->getHyphFilename(m_doc->hyphLanguage()); |
106 | Franz | 64 | QFile f(pfad); |
8501 | cbradney | 65 | if (f.open(QIODevice::ReadOnly)) |
164 | Franz | 66 | { |
9923 | fschmid | 67 | QTextStream st(&f); |
164 | Franz | 68 | QString line; |
69 | line = st.readLine(); |
||
18330 | jghali | 70 | m_codec = QTextCodec::codecForName(line.toUtf8()); |
106 | Franz | 71 | f.close(); |
164 | Franz | 72 | } |
106 | Franz | 73 | else |
164 | Franz | 74 | { |
18330 | jghali | 75 | m_usable = false; |
76 | m_hdict = NULL; |
||
106 | Franz | 77 | return; |
164 | Franz | 78 | } |
10493 | fschmid | 79 | QByteArray fn = pfad.toLocal8Bit(); |
3987 | craig | 80 | const char * filename = fn.data(); |
18330 | jghali | 81 | m_hdict = hnj_hyphen_load(filename); |
82 | m_usable = m_hdict == NULL ? false : true; |
||
10170 | fschmid | 83 | rememberedWords.clear(); |
84 | /* Add reading these special lists from prefs or doc here */ |
||
85 | ignoredWords.clear(); |
||
86 | specialWords.clear(); |
||
3 | paul | 87 | } |
88 | |||
89 | Hyphenator::~Hyphenator() |
||
90 | { |
||
18330 | jghali | 91 | if (m_hdict) |
92 | hnj_hyphen_free(m_hdict); |
||
3 | paul | 93 | } |
94 | |||
6931 | avox | 95 | void Hyphenator::NewDict(const QString& name) |
3 | paul | 96 | { |
12787 | pierre | 97 | // if (!ScCore->primaryMainWindow()->Sprachen.contains(name)) |
98 | // return; |
||
17798 | craig | 99 | if( LanguageManager::instance()->getHyphFilename(name).isEmpty() ) |
3 | paul | 100 | return; |
12787 | pierre | 101 | |
6931 | avox | 102 | if (Language != name) |
164 | Franz | 103 | { |
6931 | avox | 104 | Language = name; |
105 | |||
106 | char *filename = NULL; |
||
17853 | jghali | 107 | QString pfad = LanguageManager::instance()->getHyphFilename(Language); |
6931 | avox | 108 | |
18330 | jghali | 109 | if (m_hdict != NULL) |
110 | hnj_hyphen_free(m_hdict); |
||
6931 | avox | 111 | |
112 | QFile f(pfad); |
||
8501 | cbradney | 113 | if (f.open(QIODevice::ReadOnly)) |
6931 | avox | 114 | { |
9923 | fschmid | 115 | QTextStream st(&f); |
6931 | avox | 116 | QString line; |
117 | line = st.readLine(); |
||
18330 | jghali | 118 | m_codec = QTextCodec::codecForName(line.toUtf8()); |
6931 | avox | 119 | f.close(); |
120 | } |
||
121 | else |
||
122 | { |
||
18330 | jghali | 123 | m_usable = false; |
124 | m_hdict = NULL; |
||
6931 | avox | 125 | return; |
126 | } |
||
10493 | fschmid | 127 | QByteArray fn = pfad.toLocal8Bit(); |
6931 | avox | 128 | filename = fn.data(); |
18330 | jghali | 129 | m_hdict = hnj_hyphen_load(filename); |
130 | m_usable = m_hdict == NULL ? false : true; |
||
164 | Franz | 131 | } |
3 | paul | 132 | } |
133 | |||
249 | Franz | 134 | void Hyphenator::slotNewSettings(int Wordlen, bool Autom, bool ACheck, int Num) |
3 | paul | 135 | { |
136 | MinWordLen = Wordlen; |
||
137 | Automatic = Autom; |
||
138 | AutoCheck = ACheck; |
||
249 | Franz | 139 | HyCount = Num; |
18330 | jghali | 140 | m_doc->setHyphMinimumWordLength(Wordlen); |
141 | m_doc->setHyphAutomatic(Autom); |
||
142 | m_doc->setHyphAutoCheck(AutoCheck); |
||
143 | m_doc->setHyphConsecutiveLines(Num); |
||
3 | paul | 144 | } |
145 | |||
6931 | avox | 146 | void Hyphenator::slotHyphenateWord(PageItem* it, const QString& text, int firstC) |
3 | paul | 147 | { |
18330 | jghali | 148 | if ((!m_usable))//FIXME:av || (!ScMW->Sprachen.contains(it->Language))) |
164 | Franz | 149 | return; |
3 | paul | 150 | const char *word; |
164 | Franz | 151 | char *buffer; |
152 | const int BORDER = 2; |
||
9535 | fschmid | 153 | QByteArray te; |
164 | Franz | 154 | |
5781 | cbradney | 155 | //uint maxC = it->itemText.length() - 1; |
3 | paul | 156 | QString found = text; |
6931 | avox | 157 | if (found.contains(SpecialChars::SHYPHEN)) |
158 | return; |
||
159 | // else if (findException(found, &buffer) it->itemText.hyphenateWord(firstC, found.length(), buffer); |
||
160 | else if (signed(found.length()) >= MinWordLen) |
||
164 | Franz | 161 | { |
6931 | avox | 162 | NewDict(it->itemText.charStyle(firstC).language()); |
18330 | jghali | 163 | te = m_codec->fromUnicode( found ); |
3 | paul | 164 | word = te.data(); |
18144 | jghali | 165 | int wordlen = strlen(word); |
166 | buffer = static_cast<char*>(malloc(wordlen+BORDER+3)); |
||
3 | paul | 167 | if (buffer == NULL) |
168 | return; |
||
18144 | jghali | 169 | char ** rep = NULL; |
170 | int * pos = NULL; |
||
171 | int * cut = NULL; |
||
18330 | jghali | 172 | if (!hnj_hyphen_hyphenate2(m_hdict, word, wordlen, buffer, NULL, &rep, &pos, &cut)) |
164 | Franz | 173 | { |
5781 | cbradney | 174 | //uint i = 0; |
18144 | jghali | 175 | buffer[wordlen] = '\0'; |
5559 | avox | 176 | it->itemText.hyphenateWord(firstC, found.length(), buffer); |
164 | Franz | 177 | } |
3 | paul | 178 | free(buffer); |
18144 | jghali | 179 | if (rep) |
180 | { |
||
181 | for (int i = 0; i < wordlen - 1; ++i) |
||
182 | if (rep[i]) |
||
183 | free(rep[i]); |
||
184 | free(rep); |
||
185 | } |
||
18245 | jghali | 186 | if (pos) free(pos); |
187 | if (cut) free(cut); |
||
18144 | jghali | 188 | buffer = NULL; |
189 | rep = NULL; |
||
190 | pos = NULL; |
||
191 | cut = NULL; |
||
164 | Franz | 192 | } |
3 | paul | 193 | } |
194 | |||
195 | void Hyphenator::slotHyphenate(PageItem* it) |
||
196 | { |
||
18330 | jghali | 197 | if ((!m_usable) || !(it->asTextFrame()) || (it->itemText.length() == 0)) |
164 | Franz | 198 | return; |
18330 | jghali | 199 | m_doc->DoDrawing = false; |
5559 | avox | 200 | |
3 | paul | 201 | const char *word; |
164 | Franz | 202 | char *buffer; |
203 | const int BORDER = 2; |
||
3 | paul | 204 | QString text = ""; |
205 | QString buf; |
||
9535 | fschmid | 206 | QByteArray te; |
5559 | avox | 207 | |
6931 | avox | 208 | int startC = 0; |
15522 | jghali | 209 | if (it->itemText.lengthOfSelection() > 0) |
164 | Franz | 210 | { |
6931 | avox | 211 | startC = it->itemText.startOfSelection(); |
212 | text = it->itemText.text(startC, it->itemText.lengthOfSelection()); |
||
164 | Franz | 213 | } |
5559 | avox | 214 | else { |
215 | text = it->itemText.text(0, it->itemText.length()); |
||
216 | } |
||
6931 | avox | 217 | int firstC = 0; |
3 | paul | 218 | int lastC = 0; |
219 | int Ccount = 0; |
||
220 | QString found = ""; |
||
221 | QString found2 = ""; |
||
9769 | fschmid | 222 | rememberedWords.clear(); |
5781 | cbradney | 223 | //uint maxC = it->itemText.length() - 1; |
18181 | fschmid | 224 | qApp->setOverrideCursor(QCursor(Qt::WaitCursor)); |
7029 | avox | 225 | QRegExp wordBoundary("\\w"); |
226 | QRegExp whiteSpace("\\s|\\W|\\d|\\n|\\r|\\t"); |
||
6931 | avox | 227 | while ((firstC+Ccount < signed(text.length())) && (firstC != -1) && |
228 | (lastC < signed(text.length()))) |
||
164 | Franz | 229 | { |
10511 | fschmid | 230 | firstC = text.indexOf(wordBoundary, firstC+Ccount); |
3 | paul | 231 | if (firstC < 0) |
232 | break; |
||
7029 | avox | 233 | if (firstC > 0 && text.at(firstC-1) == SpecialChars::SHYPHEN) |
234 | { |
||
235 | Ccount = 1; |
||
236 | continue; |
||
237 | } |
||
10511 | fschmid | 238 | lastC = text.indexOf(whiteSpace, firstC); |
3 | paul | 239 | if (lastC < 0) |
7029 | avox | 240 | lastC = signed(text.length()); |
3 | paul | 241 | Ccount = lastC - firstC; |
7029 | avox | 242 | if (lastC < signed(text.length()) && text.at(lastC) == SpecialChars::SHYPHEN) |
243 | { |
||
244 | ++Ccount; |
||
245 | continue; |
||
246 | } |
||
1933 | fschmid | 247 | if (Ccount > MinWordLen-1) |
164 | Franz | 248 | { |
10398 | cbradney | 249 | found = text.mid(firstC, Ccount).toLower(); |
3 | paul | 250 | found2 = text.mid(firstC, Ccount); |
6931 | avox | 251 | if (found.contains(SpecialChars::SHYPHEN)) |
252 | break; |
||
253 | |||
254 | NewDict(it->itemText.charStyle(firstC).language()); |
||
255 | |||
18330 | jghali | 256 | te = m_codec->fromUnicode( found ); |
3 | paul | 257 | word = te.data(); |
18144 | jghali | 258 | int wordlen = strlen(word); |
259 | buffer = static_cast<char*>(malloc(wordlen+BORDER+3)); |
||
3 | paul | 260 | if (buffer == NULL) |
261 | break; |
||
18144 | jghali | 262 | char ** rep = NULL; |
263 | int * pos = NULL; |
||
264 | int * cut = NULL; |
||
18330 | jghali | 265 | if (!hnj_hyphen_hyphenate2(m_hdict, word, wordlen, buffer, NULL, &rep, &pos, &cut)) |
164 | Franz | 266 | { |
8547 | cbradney | 267 | int i = 0; |
18144 | jghali | 268 | buffer[wordlen] = '\0'; |
3 | paul | 269 | bool hasHyphen = false; |
118 | Franz | 270 | for (i = 1; i < found.length()-1; ++i) |
164 | Franz | 271 | { |
272 | if(buffer[i] & 1) |
||
3 | paul | 273 | { |
274 | hasHyphen = true; |
||
275 | break; |
||
276 | } |
||
164 | Franz | 277 | } |
10170 | fschmid | 278 | QString outs = ""; |
279 | QString input = ""; |
||
280 | outs += found2[0]; |
||
281 | for (i = 1; i < found.length()-1; ++i) |
||
6931 | avox | 282 | { |
10170 | fschmid | 283 | outs += found2[i]; |
284 | if(buffer[i] & 1) |
||
285 | outs += "-"; |
||
6931 | avox | 286 | } |
10170 | fschmid | 287 | outs += found2.right(1); |
288 | input = outs; |
||
289 | if (!ignoredWords.contains(found2)) |
||
290 | { |
||
291 | if (!hasHyphen) |
||
292 | it->itemText.hyphenateWord(startC + firstC, found.length(), NULL); |
||
293 | else if (Automatic) |
||
13112 | fschmid | 294 | { |
295 | if (specialWords.contains(found2)) |
||
296 | { |
||
297 | outs = specialWords.value(found2); |
||
298 | uint ii = 1; |
||
299 | for (i = 1; i < outs.length()-1; ++i) |
||
300 | { |
||
301 | QChar cht = outs[i]; |
||
302 | if (cht == '-') |
||
303 | buffer[ii-1] = 1; |
||
304 | else |
||
305 | { |
||
306 | buffer[ii] = 0; |
||
307 | ++ii; |
||
308 | } |
||
309 | } |
||
310 | } |
||
10170 | fschmid | 311 | it->itemText.hyphenateWord(startC + firstC, found.length(), buffer); |
13112 | fschmid | 312 | } |
10170 | fschmid | 313 | else |
3 | paul | 314 | { |
10170 | fschmid | 315 | if (specialWords.contains(found2)) |
164 | Franz | 316 | { |
10170 | fschmid | 317 | outs = specialWords.value(found2); |
12094 | jghali | 318 | uint ii = 1; |
10170 | fschmid | 319 | for (i = 1; i < outs.length()-1; ++i) |
320 | { |
||
321 | QChar cht = outs[i]; |
||
322 | if (cht == '-') |
||
12094 | jghali | 323 | buffer[ii-1] = 1; |
10170 | fschmid | 324 | else |
12094 | jghali | 325 | { |
10170 | fschmid | 326 | buffer[ii] = 0; |
12094 | jghali | 327 | ++ii; |
328 | } |
||
10170 | fschmid | 329 | } |
164 | Franz | 330 | } |
10179 | fschmid | 331 | if (rememberedWords.contains(input)) |
9769 | fschmid | 332 | { |
10170 | fschmid | 333 | outs = rememberedWords.value(input); |
12094 | jghali | 334 | uint ii = 1; |
9769 | fschmid | 335 | for (i = 1; i < outs.length()-1; ++i) |
336 | { |
||
337 | QChar cht = outs[i]; |
||
338 | if (cht == '-') |
||
12094 | jghali | 339 | buffer[ii-1] = 1; |
9769 | fschmid | 340 | else |
12094 | jghali | 341 | { |
10170 | fschmid | 342 | buffer[ii] = 0; |
12094 | jghali | 343 | ++ii; |
344 | } |
||
9769 | fschmid | 345 | } |
346 | it->itemText.hyphenateWord(firstC, found.length(), buffer); |
||
347 | } |
||
348 | else |
||
349 | { |
||
10170 | fschmid | 350 | qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); |
351 | PrefsContext* prefs = PrefsManager::instance()->prefsFile->getContext("hyhpen_options"); |
||
352 | int xpos = prefs->getInt("Xposition", -9999); |
||
353 | int ypos = prefs->getInt("Yposition", -9999); |
||
354 | HyAsk *dia = new HyAsk((QWidget*)parent(), outs); |
||
355 | if ((xpos != -9999) && (ypos != -9999)) |
||
356 | dia->move(xpos, ypos); |
||
357 | qApp->processEvents(); |
||
358 | if (dia->exec()) |
||
359 | { |
||
360 | outs = dia->Wort->text(); |
||
12094 | jghali | 361 | uint ii = 1; |
10170 | fschmid | 362 | for (i = 1; i < outs.length()-1; ++i) |
363 | { |
||
364 | QChar cht = outs[i]; |
||
365 | if (cht == '-') |
||
12094 | jghali | 366 | buffer[ii-1] = 1; |
10170 | fschmid | 367 | else |
12094 | jghali | 368 | { |
10170 | fschmid | 369 | buffer[ii] = 0; |
12094 | jghali | 370 | ++ii; |
371 | } |
||
10170 | fschmid | 372 | } |
373 | if (!rememberedWords.contains(input)) |
||
374 | rememberedWords.insert(input, outs); |
||
375 | if (dia->addToIgnoreList->isChecked()) |
||
376 | { |
||
377 | if (!ignoredWords.contains(found2)) |
||
378 | ignoredWords.insert(found2); |
||
379 | } |
||
380 | if (dia->addToExceptionList->isChecked()) |
||
381 | { |
||
382 | if (!specialWords.contains(found2)) |
||
383 | specialWords.insert(found2, outs); |
||
384 | } |
||
385 | it->itemText.hyphenateWord(firstC, found.length(), buffer); |
||
386 | } |
||
387 | else |
||
388 | { |
||
389 | free(buffer); |
||
390 | buffer = NULL; |
||
391 | prefs->set("Xposition", dia->xpos); |
||
392 | prefs->set("Yposition", dia->ypos); |
||
393 | delete dia; |
||
394 | break; |
||
395 | } |
||
9769 | fschmid | 396 | prefs->set("Xposition", dia->xpos); |
397 | prefs->set("Yposition", dia->ypos); |
||
398 | delete dia; |
||
10170 | fschmid | 399 | qApp->changeOverrideCursor(QCursor(Qt::WaitCursor)); |
9769 | fschmid | 400 | } |
164 | Franz | 401 | } |
3 | paul | 402 | } |
164 | Franz | 403 | } |
3 | paul | 404 | free(buffer); |
18144 | jghali | 405 | if (rep) |
406 | { |
||
407 | for (int i = 0; i < wordlen - 1; ++i) |
||
408 | if (rep[i]) |
||
409 | free(rep[i]); |
||
410 | free(rep); |
||
411 | } |
||
18245 | jghali | 412 | if (pos) free(pos); |
413 | if (cut) free(cut); |
||
3 | paul | 414 | buffer = NULL; |
18144 | jghali | 415 | rep = NULL; |
416 | pos = NULL; |
||
417 | cut = NULL; |
||
164 | Franz | 418 | } |
3 | paul | 419 | if (Ccount == 0) |
420 | Ccount++; |
||
164 | Franz | 421 | } |
18181 | fschmid | 422 | qApp->restoreOverrideCursor(); |
18330 | jghali | 423 | m_doc->DoDrawing = true; |
9769 | fschmid | 424 | rememberedWords.clear(); |
3 | paul | 425 | } |
2621 | fschmid | 426 | |
427 | void Hyphenator::slotDeHyphenate(PageItem* it) |
||
428 | { |
||
5721 | avox | 429 | if (!(it->asTextFrame()) || (it ->itemText.length() == 0)) |
2621 | fschmid | 430 | return; |
5559 | avox | 431 | |
15522 | jghali | 432 | if (it->itemText.lengthOfSelection() > 0) |
13054 | pierre | 433 | { |
13144 | fschmid | 434 | // int start = it->itemText.startOfSelection(); |
13054 | pierre | 435 | it->itemText.hyphenateWord(it->itemText.startOfSelection(), it->itemText.lengthOfSelection(), NULL); |
436 | } |
||
437 | else { |
||
438 | uint a = it->itemText.length(); |
||
439 | it->itemText.hyphenateWord(0, a, NULL); |
||
440 | } |
||
18330 | jghali | 441 | m_doc->DoDrawing = true; |
2621 | fschmid | 442 | } |