lib

KoAutoFormat.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 2001 Sven Leiber <s.leiber@web.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19*/
20
21#include "KoAutoFormat.h"
22
23#include "KoTextObject.h"
24#include "KoTextParag.h"
25#include "KoVariable.h"
26#include "KoParagCounter.h"
27#include <KoDocument.h>
28#include <KoSearchDia.h>
29#include <KoGlobal.h>
30
31#include <kdebug.h>
32#include <tdelocale.h>
33#include <tdeinstance.h>
34#include <tdeconfig.h>
35#include <kstandarddirs.h>
36#include <tdeglobal.h>
37#include <kcommand.h>
38//#include <KoTextFormat.h>
39#include <kcompletion.h>
40#include <kcalendarsystem.h>
41
42#include <tqfile.h>
43#include <tqlabel.h>
44#include <tqtooltip.h>
45#include <tqwhatsthis.h>
46#include <tqdom.h>
47#include <tqregexp.h>
48
49
50KoCompletionBox::KoCompletionBox( TQWidget * parent, const char * name, WFlags f)
51 : TQLabel(parent,name,f)
52{
53 setBackgroundColor(TQColor("#FFFFE6"));
54 setFocusPolicy(TQWidget::NoFocus);
55 setFrameShape(TQFrame::Box);
56}
57
58KoCompletionBox::~KoCompletionBox()
59{
60}
61
62void KoCompletionBox::mousePressEvent( TQMouseEvent *)
63{
64 hide();
65}
66
67TQString& KoCompletionBox::lastWord()
68{
69 return m_lastWord;
70}
71
72void KoCompletionBox::setLastWord( TQString const &lastword)
73{
74 m_lastWord = lastword;
75}
76
77KoAutoFormatEntry::KoAutoFormatEntry(const TQString& replace)
78 : m_replace( replace )
79{
80 m_formatOptions= 0L;
81}
82
83KoAutoFormatEntry::~KoAutoFormatEntry()
84{
85 delete m_formatOptions;
86 m_formatOptions=0L;
87}
88
89KoSearchContext *KoAutoFormatEntry::formatEntryContext() const
90{
91 return m_formatOptions;
92}
93
94void KoAutoFormatEntry::createNewEntryContext()
95{
96 if ( !m_formatOptions )
97 {
98 m_formatOptions = new KoSearchContext();
99 }
100}
101
102void KoAutoFormatEntry::setFormatEntryContext( KoSearchContext *_cont )
103{
104 delete m_formatOptions;
105 m_formatOptions=_cont;
106}
107
108void KoAutoFormatEntry::clearFormatEntryContext( )
109{
110 delete m_formatOptions;
111 m_formatOptions = 0L;
112}
113
114
115/******************************************************************/
116/* Class: KoAutoFormat */
117/******************************************************************/
118KoAutoFormat::KoAutoFormat( KoDocument *_doc, KoVariableCollection *_varCollection, KoVariableFormatCollection *_varFormatCollection )
119 : m_doc( _doc ),
120 m_varCollection(_varCollection),
121 m_varFormatCollection(_varFormatCollection),
122 m_autoFormatLanguage( TQString()),
123 m_configRead( false ),
124 m_convertUpperCase( false ), m_convertUpperUpper( false ),
125 m_advancedAutoCorrect( true ),
126 m_autoDetectUrl( false ),
127 m_ignoreDoubleSpace( false ),
128 m_removeSpaceBeginEndLine( false ),
129 m_useBulletStyle(false),
130 m_autoChangeFormat(false),
131 m_autoReplaceNumber(false),
132 m_useAutoNumberStyle(false),
133 m_completion(false),
134 m_toolTipCompletion(false),
135 m_completionAppendSpace(false),
136 m_addCompletionWord(true),
137 m_includeTwoUpperLetterException(false),
138 m_includeAbbreviation(false),
139 m_ignoreUpperCase(false),
140 m_bAutoFormatActive(true),
141 m_bAutoSuperScript( false ),
142 m_bAutoCorrectionWithFormat( false ),
143 m_bCapitalizeNameOfDays( false ),
144 m_wordInserted( false ),
145 m_bulletStyle(),
146 m_typographicSimpleQuotes(),
147 m_typographicDoubleQuotes(),
148 m_typographicDefaultDoubleQuotes(),
149 m_typographicDefaultSimpleQuotes(),
150 m_listCompletion( new TDECompletion ),
151 m_entries(17,false),
152 m_allLanguages(17,false),
153 m_superScriptEntries(),
154 m_upperCaseExceptions(),
155 m_twoUpperLetterException(),
156 m_maxFindLength( 0 ),
157 m_minCompletionWordLength( 5 ),
158 m_nbMaxCompletionWord( 500 ),
159 m_countMaxWords(0),
160 m_completionBox(0),
161 m_keyCompletionAction( Enter )
162
163{
164 //load once this list not each time that we "readConfig"
165 loadListOfWordCompletion();
166 m_listCompletion->setIgnoreCase( true );
167 updateMaxWords();
168 TDELocale tdelocale(m_doc->instance()->instanceName());
169 for (int i = 1; i <=7; i++)
170 {
171 m_cacheNameOfDays.append(tdelocale.calendar()->weekDayName( i ).lower());
172 }
173}
174
175KoAutoFormat::KoAutoFormat( const KoAutoFormat& format )
176 : m_doc( format.m_doc ),
177 m_varCollection( format.m_varCollection ),
178 m_varFormatCollection( format.m_varFormatCollection ),
179 m_autoFormatLanguage( format.m_autoFormatLanguage),
180 m_configRead( format.m_configRead ),
181 m_convertUpperCase( format.m_convertUpperCase ),
182 m_convertUpperUpper( format.m_convertUpperUpper ),
183 m_advancedAutoCorrect( format.m_advancedAutoCorrect ),
184 m_autoDetectUrl( format.m_autoDetectUrl ),
185 m_ignoreDoubleSpace( format.m_ignoreDoubleSpace ),
186 m_removeSpaceBeginEndLine( format.m_removeSpaceBeginEndLine ),
187 m_useBulletStyle( format.m_useBulletStyle ),
188 m_autoChangeFormat( format.m_autoChangeFormat ),
189 m_autoReplaceNumber( format.m_autoReplaceNumber ),
190 m_useAutoNumberStyle( format.m_useAutoNumberStyle ),
191 m_completion( format.m_completion ),
192 m_toolTipCompletion( format.m_toolTipCompletion),
193 m_completionAppendSpace( format.m_completionAppendSpace ),
194 m_addCompletionWord( format.m_addCompletionWord ),
195 m_includeTwoUpperLetterException( format.m_includeTwoUpperLetterException ),
196 m_includeAbbreviation( format.m_includeAbbreviation ),
197 m_ignoreUpperCase( format.m_ignoreUpperCase ),
198 m_bAutoFormatActive( format.m_bAutoFormatActive ),
199 m_bAutoSuperScript( format.m_bAutoSuperScript ),
200 m_bAutoCorrectionWithFormat( format.m_bAutoCorrectionWithFormat),
201 m_bCapitalizeNameOfDays( format.m_bCapitalizeNameOfDays),
202 m_bulletStyle( format.m_bulletStyle ),
203 m_typographicSimpleQuotes( format.m_typographicSimpleQuotes ),
204 m_typographicDoubleQuotes( format.m_typographicDoubleQuotes ),
205 m_typographicDefaultDoubleQuotes( format.m_typographicDefaultDoubleQuotes),
206 m_typographicDefaultSimpleQuotes( format.m_typographicDefaultSimpleQuotes),
207 m_listCompletion( 0L ), // don't copy it!
208 m_entries(17,false ),//don't copy it.
209 m_allLanguages(17,false), //don't copy it
210 m_superScriptEntries ( format.m_superScriptEntries ),
211 m_upperCaseExceptions( format.m_upperCaseExceptions ),
212 m_twoUpperLetterException( format.m_twoUpperLetterException ),
213 m_maxFindLength( format.m_maxFindLength ),
214 m_minCompletionWordLength( format.m_minCompletionWordLength ),
215 m_nbMaxCompletionWord( format.m_nbMaxCompletionWord ),
216 m_cacheNameOfDays( format.m_cacheNameOfDays),
217 m_completionBox(0),
218 m_keyCompletionAction( format.m_keyCompletionAction )
219{
220 //m_listCompletion=new TDECompletion();
221 //m_listCompletion->setItems( autoFormat.listCompletion() );
222 //copyAutoFormatEntries( autoFormat );
223}
224
225KoAutoFormat::~KoAutoFormat()
226{
227 delete m_listCompletion;
228 m_entries.setAutoDelete( true );
229 m_entries.clear();
230 m_allLanguages.setAutoDelete( true );
231 m_allLanguages.clear();
232}
233
234void KoAutoFormat::updateMaxWords()
235{
236 TQStringList list = m_listCompletion->items();
237 for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it )
238 {
239 TQString tmp = *it;
240 uint maxword = 1;
241
242 for (uint i=0; i < (uint)tmp.length(); i++)
243 if ( tmp.at(i).isSpace() || tmp.at(i).isPunct() )
244 maxword++;
245 if (maxword > m_countMaxWords )
246 m_countMaxWords = maxword;
247 }
248 kdDebug() << "m_countMaxWords: " << m_countMaxWords << endl;
249}
250
251void KoAutoFormat::loadListOfWordCompletion()
252{
253 TDEConfig* config = KoGlobal::kofficeConfig();
254 TDEConfigGroupSaver cgs( config, "Completion Word" );
255 m_listCompletion->insertItems(config->readListEntry( "list" ));
256}
257
258void KoAutoFormat::readConfig(bool force)
259{
260 // Read the autoformat configuration
261 // This is done on demand (when typing the first char, or when opening the config dialog)
262 // so that loading is faster and to avoid doing it for readonly documents.
263 if ( m_configRead && !force )
264 return;
265 TDEConfig* config = KoGlobal::kofficeConfig();
266 TDEConfigGroupSaver cgs( config, "AutoFormat" );
267 //when we force don't load format language.
268 if ( !force)
269 m_autoFormatLanguage = config->readEntry("formatLanguage", TQString());
270
271 m_convertUpperCase = config->readBoolEntry( "ConvertUpperCase", false );
272 m_convertUpperUpper = config->readBoolEntry( "ConvertUpperUpper", false );
273 m_includeTwoUpperLetterException = config->readBoolEntry( "includeTwoLetterException", false );
274 m_includeAbbreviation = config->readBoolEntry( "includeAbbreviation", false );
275
276 m_advancedAutoCorrect = config->readBoolEntry( "AdvancedAutocorrect", true );
277 m_bAutoCorrectionWithFormat = config->readBoolEntry( "AutoCorrectionWithFormat",false );
278 m_bCapitalizeNameOfDays = config->readBoolEntry( "CapitalizeNameOfDays",false );
279
280 m_autoDetectUrl = config->readBoolEntry("AutoDetectUrl",false);
281 m_ignoreDoubleSpace = config->readBoolEntry("IgnoreDoubleSpace", true);
282 m_removeSpaceBeginEndLine = config->readBoolEntry("RemoveSpaceBeginEndLine", true);
283
284 m_useBulletStyle = config->readBoolEntry("UseBulletStyle",false);
285 TQString tmp = config->readEntry( "BulletStyle", "" );
286 m_bulletStyle = tmp.isEmpty() ? TQChar() : tmp[0];
287
288 m_autoChangeFormat = config->readBoolEntry( "AutoChangeFormat", false );
289
290 m_autoReplaceNumber = config->readBoolEntry( "AutoReplaceNumber", true );
291
292 m_useAutoNumberStyle = config->readBoolEntry( "AutoNumberStyle", false );
293
294
295 TQString beginDoubleQuote = config->readEntry( "TypographicQuotesBegin" );
296 TQString endDoubleQuote = config->readEntry( "TypographicQuotesEnd" );
297
298 m_typographicDoubleQuotes.replace = config->readBoolEntry( "TypographicQuotesEnabled", false );
299
300 TQString begin = config->readEntry( "TypographicSimpleQuotesBegin" );
301 TQString end = config->readEntry( "TypographicSimpleQuotesEnd" );
302 m_typographicSimpleQuotes.replace = config->readBoolEntry( "TypographicSimpleQuotesEnabled", false );
303
304 m_bAutoSuperScript = config->readBoolEntry( "AutoSuperScript", true );
305
306 config->setGroup( "completion" );
307 m_completion = config->readBoolEntry( "completion", false );
308
309 m_completionAppendSpace = config->readBoolEntry( "CompletionAppendSpace", false );
310 m_minCompletionWordLength = config->readUnsignedNumEntry( "CompletionMinWordLength", 5 );
311 m_nbMaxCompletionWord = config->readUnsignedNumEntry( "NbMaxCompletionWord", 100 );
312 m_addCompletionWord = config->readBoolEntry( "AddCompletionWord", true );
313 m_toolTipCompletion = config->readBoolEntry( "ToolTipCompletion", true );
314 m_keyCompletionAction = ( KoAutoFormat::KeyCompletionAction )config->readUnsignedNumEntry( "CompletionKeyAction", 0 );
315
316 if ( force )
317 {
318 m_entries.setAutoDelete(true);
319 m_entries.clear();
320 m_entries.setAutoDelete(false);
321 m_allLanguages.setAutoDelete(true);
322 m_allLanguages.clear();
323 m_allLanguages.setAutoDelete(false);
324 m_upperCaseExceptions.clear();
325 m_superScriptEntries.clear();
326 m_twoUpperLetterException.clear();
327
328 }
329
330 //config->setGroup( "AutoFormatEntries" );
331
332 readAutoCorrectConfig();
333
334 if( beginDoubleQuote.isEmpty())
335 {
336 if( m_typographicDefaultDoubleQuotes.begin.isNull())
337 m_typographicDoubleQuotes.begin = TQChar('«');
338 else
339 m_typographicDoubleQuotes.begin = m_typographicDefaultDoubleQuotes.begin;
340 }
341 else
342 m_typographicDoubleQuotes.begin = beginDoubleQuote[0];
343
344 if( endDoubleQuote.isEmpty() )
345 {
346 if( m_typographicDefaultDoubleQuotes.end.isNull())
347 m_typographicDoubleQuotes.end = TQChar('»');
348 else
349 m_typographicDoubleQuotes.end = m_typographicDefaultDoubleQuotes.end;
350 }
351 else
352 m_typographicDoubleQuotes.end = endDoubleQuote[0];
353
354 m_typographicDoubleQuotes.replace = m_typographicDoubleQuotes.replace
355 && !m_typographicDoubleQuotes.begin.isNull()
356 && !m_typographicDoubleQuotes.end.isNull();
357
358
359 if( begin.isEmpty())
360 {
361 if( m_typographicDefaultSimpleQuotes.begin.isNull())
362 m_typographicSimpleQuotes.begin = TQChar('\'');
363 else
364 m_typographicSimpleQuotes.begin = m_typographicDefaultSimpleQuotes.begin;
365 }
366 else
367 m_typographicSimpleQuotes.begin = begin[0];
368
369 if( end.isEmpty() )
370 {
371 if( m_typographicDefaultSimpleQuotes.end.isNull())
372 m_typographicSimpleQuotes.end = TQChar('\'');
373 else
374 m_typographicSimpleQuotes.end = m_typographicDefaultSimpleQuotes.end;
375 }
376 else
377 m_typographicSimpleQuotes.end = end[0];
378
379 m_typographicSimpleQuotes.replace = m_typographicSimpleQuotes.replace
380 && !m_typographicSimpleQuotes.end.isNull()
381 && !m_typographicSimpleQuotes.begin.isNull();
382
383
384 loadAllLanguagesAutoCorrection();
385 buildMaxLen();
386 autoFormatIsActive();
387 m_configRead = true;
388}
389
390void KoAutoFormat::readAutoCorrectConfig()
391{
392 Q_ASSERT( m_entries.isEmpty() ); // readConfig is only called once...
393 TDELocale tdelocale(m_doc->instance()->instanceName());
394 TQString kdelang = tdelocale.languageList().front();
395 kdelang.remove( TQRegExp( "@.*" ) );
396 kdDebug(32500) << "KoAutoFormat: m_autoFormatLanguage=" << m_autoFormatLanguage << " kdelang=" << kdelang << endl;
397 TQString fname;
398 if ( !m_autoFormatLanguage.isEmpty() )
399 {
400 fname = locate( "data", "koffice/autocorrect/" + m_autoFormatLanguage + ".xml", m_doc->instance() );
401 }
402 if ( m_autoFormatLanguage != "all_languages" )
403 {
404 if ( fname.isEmpty() && !kdelang.isEmpty() )
405 fname = locate( "data", "koffice/autocorrect/" + kdelang + ".xml", m_doc->instance() );
406 if ( fname.isEmpty() && kdelang.contains("_") )
407 {
408 kdelang.remove( TQRegExp( "_.*" ) );
409 fname = locate( "data", "koffice/autocorrect/" + kdelang + ".xml", m_doc->instance() );
410 }
411 if ( fname.isEmpty() )
412 fname = locate( "data", "koffice/autocorrect/autocorrect.xml", m_doc->instance() );
413 }
414 if ( fname.isEmpty() )
415 return;
416 TQFile xmlFile(fname);
417 if(!xmlFile.open(IO_ReadOnly))
418 return;
419
420 TQDomDocument doc;
421 if(!doc.setContent(&xmlFile))
422 return;
423
424 if(doc.doctype().name() != "autocorrection") {
425 //return;
426 }
427 TQDomElement de=doc.documentElement();
428
429 loadAutoCorrection( de );
430
431 TQDomElement upper = de.namedItem( "UpperCaseExceptions" ).toElement();
432 if(!upper.isNull())
433 {
434 TQDomNodeList nl = upper.childNodes();
435 for(uint i = 0; i < nl.count(); i++)
436 {
437 m_upperCaseExceptions+= nl.item(i).toElement().attribute("exception");
438 }
439 }
440
441 TQDomElement twoUpper = de.namedItem( "TwoUpperLetterExceptions" ).toElement();
442 if(!twoUpper.isNull())
443 {
444 TQDomNodeList nl = twoUpper.childNodes();
445 for(uint i = 0; i < nl.count(); i++)
446 {
447 m_twoUpperLetterException+= nl.item(i).toElement().attribute("exception");
448 }
449 }
450
451 TQDomElement superScript = de.namedItem( "SuperScript" ).toElement();
452 if(!superScript.isNull())
453 {
454 TQDomNodeList nl = superScript.childNodes();
455 for(uint i = 0; i < nl.count() ; i++) {
456 //bug in qmap we overwrite = false doesn't work
457 //so we can't add multiple "othernb"
458 m_superScriptEntries.insert( nl.item(i).toElement().attribute("find"), KoAutoFormatEntry(nl.item(i).toElement().attribute("super")),false );
459 }
460 }
461
462 TQDomElement doubleQuote = de.namedItem( "DoubleQuote" ).toElement();
463 if(!doubleQuote.isNull())
464 {
465 TQDomElement childItem = doubleQuote.namedItem("doublequote").toElement();
466 if ( !childItem.isNull() )
467 {
468 TQString attr = childItem.attribute( "begin" );
469 if ( !attr.isEmpty() && attr[0] != 0 )
470 m_typographicDefaultDoubleQuotes.begin = attr[0];
471 attr = childItem.attribute( "end" );
472 if ( !attr.isEmpty() && attr[0] != 0 )
473 m_typographicDefaultDoubleQuotes.end = attr[0];
474 }
475 }
476 TQDomElement simpleQuote = de.namedItem( "SimpleQuote" ).toElement();
477 if(!simpleQuote.isNull())
478 {
479 TQDomElement childItem = simpleQuote.namedItem("simplequote").toElement();
480 if ( !childItem.isNull() )
481 {
482 TQString attr = childItem.attribute( "begin" );
483 if ( !attr.isEmpty() && attr[0] != 0 )
484 m_typographicDefaultSimpleQuotes.begin = attr[0];
485 attr = childItem.attribute( "end" );
486 if ( !attr.isEmpty() && attr[0] != 0 )
487 m_typographicDefaultSimpleQuotes.end = attr[0];
488 }
489 }
490}
491
492void KoAutoFormat::loadAllLanguagesAutoCorrection()
493{
494 TQString fname = locate( "data", "koffice/autocorrect/all_languages.xml", m_doc->instance() );
495 if ( fname.isEmpty() )
496 return;
497 TQFile xmlFile( fname );
498 if(xmlFile.open(IO_ReadOnly))
499 {
500 TQDomDocument doc;
501 if(!doc.setContent(&xmlFile)) {
502 return;
503 }
504 if(doc.doctype().name() != "autocorrection") {
505 //return;
506 }
507 TQDomElement de=doc.documentElement();
508
509 loadAutoCorrection( de, true );
510 xmlFile.close();
511 }
512}
513
514void KoAutoFormat::loadAutoCorrection( const TQDomElement & _de, bool _allLanguages )
515{
516 TQDomElement item = _de.namedItem( "items" ).toElement();
517 if(!item.isNull())
518 {
519 TQDomNodeList nl = item.childNodes();
520 m_maxFindLength=nl.count();
521 for(uint i = 0; i < m_maxFindLength; i++) {
522 loadEntry( nl.item(i).toElement(), _allLanguages);
523 }
524 }
525}
526
527void KoAutoFormat::loadEntry( const TQDomElement &nl, bool _allLanguages)
528{
529 KoAutoFormatEntry *tmp =new KoAutoFormatEntry(nl.attribute("replace"));
530 if ( nl.hasAttribute("FONT"))
531 {
532 tmp->createNewEntryContext();
533 tmp->formatEntryContext()->m_family=nl.attribute("FONT");
534 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Family;
535 }
536 if ( nl.hasAttribute("SIZE" ))
537 {
538 tmp->createNewEntryContext();
539 tmp->formatEntryContext()->m_size = nl.attribute("SIZE" ).toInt();
540 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Size;
541 }
542 if (nl.hasAttribute("BOLD" ))
543 {
544 tmp->createNewEntryContext();
545 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Bold;
546 TQString value = nl.attribute("BOLD");
547 if ( value.toInt() == 1 )
548 tmp->formatEntryContext()->m_options |= KoSearchContext::Bold;
549 }
550 if (nl.hasAttribute("ITALIC" ))
551 {
552 tmp->createNewEntryContext();
553 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Italic;
554 TQString value = nl.attribute("ITALIC");
555 if ( value.toInt() == 1 )
556 tmp->formatEntryContext()->m_options |= KoSearchContext::Italic;
557 }
558 if (nl.hasAttribute("UNDERLINE" ))
559 {
560 tmp->createNewEntryContext();
561 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Underline;
562 TQString value = nl.attribute("UNDERLINE");
563 if ( value =="single" )
564 tmp->formatEntryContext()->m_underline = KoTextFormat::U_SIMPLE;
565 else if ( value =="double" )
566 tmp->formatEntryContext()->m_underline = KoTextFormat::U_DOUBLE;
567 else if ( value =="single-bold" )
568 tmp->formatEntryContext()->m_underline = KoTextFormat::U_SIMPLE_BOLD;
569 else
570 tmp->formatEntryContext()->m_underline = KoTextFormat::U_NONE;
571 }
572 if (nl.hasAttribute("STRIKEOUT" ))
573 {
574 tmp->createNewEntryContext();
575 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::StrikeOut;
576 TQString value = nl.attribute("STRIKEOUT");
577 if ( value =="single" )
578 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_SIMPLE;
579 else if ( value =="double" )
580 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_DOUBLE;
581 else if ( value =="single-bold" )
582 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_SIMPLE_BOLD;
583 else
584 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_NONE;
585 }
586 if (nl.hasAttribute("VERTALIGN" ))
587 {
588 tmp->createNewEntryContext();
589 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::VertAlign;
590 TQString value = nl.attribute("VERTALIGN");
591 tmp->formatEntryContext()->m_vertAlign=static_cast<KoTextFormat::VerticalAlignment>( value.toInt() );
592
593 }
594 if ( nl.hasAttribute("TEXTCOLOR" ))
595 {
596 tmp->createNewEntryContext();
597 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Color;
598 TQColor col( nl.attribute("TEXTCOLOR" ));
599 tmp->formatEntryContext()->m_color = col;
600 }
601 if ( nl.hasAttribute("TEXTBGCOLOR" ))
602 {
603 tmp->createNewEntryContext();
604 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::BgColor;
605 TQColor col( nl.attribute("TEXTBGCOLOR" ));
606 tmp->formatEntryContext()->m_backGroundColor = col;
607 }
608 if ( !_allLanguages )
609 m_entries.insert( nl.attribute("find"), tmp );
610 else
611 m_allLanguages.insert( nl.attribute("find"), tmp );
612
613}
614
615void KoAutoFormat::saveConfig()
616{
617 TDEConfig* config = KoGlobal::kofficeConfig();
618 TDELocale tdelocale(m_doc->instance()->instanceName());
619
620 TDEConfigGroupSaver cgs( config, "AutoFormat" );
621 config->writeEntry( "ConvertUpperCase", m_convertUpperCase );
622 config->writeEntry( "formatLanguage", m_autoFormatLanguage=="all_languages" ? tdelocale.languageList().front() : m_autoFormatLanguage);
623
624 config->writeEntry( "ConvertUpperUpper", m_convertUpperUpper );
625 config->writeEntry( "includeTwoLetterException", m_includeTwoUpperLetterException );
626 config->writeEntry( "includeAbbreviation", m_includeAbbreviation );
627
628 config->writeEntry( "TypographicQuotesBegin", TQString( m_typographicDoubleQuotes.begin ) );
629 config->writeEntry( "TypographicQuotesEnd", TQString( m_typographicDoubleQuotes.end ) );
630 config->writeEntry( "TypographicQuotesEnabled", m_typographicDoubleQuotes.replace );
631 config->writeEntry( "TypographicSimpleQuotesBegin", TQString( m_typographicSimpleQuotes.begin ) );
632 config->writeEntry( "TypographicSimpleQuotesEnd", TQString( m_typographicSimpleQuotes.end ) );
633 config->writeEntry( "TypographicSimpleQuotesEnabled", m_typographicSimpleQuotes.replace );
634
635 config->writeEntry( "AdvancedAutocorrect", m_advancedAutoCorrect );
636 config->writeEntry( "AutoCorrectionWithFormat", m_bAutoCorrectionWithFormat );
637 config->writeEntry( "CapitalizeNameOfDays", m_bCapitalizeNameOfDays );
638
639 config->writeEntry( "AutoDetectUrl",m_autoDetectUrl);
640
641 config->writeEntry( "IgnoreDoubleSpace",m_ignoreDoubleSpace );
642 config->writeEntry( "RemoveSpaceBeginEndLine",m_removeSpaceBeginEndLine );
643
644 config->writeEntry( "UseBulletStyle", m_useBulletStyle);
645 config->writeEntry( "BulletStyle", TQString(m_bulletStyle));
646
647 config->writeEntry( "AutoChangeFormat", m_autoChangeFormat);
648
649 config->writeEntry( "AutoReplaceNumber", m_autoReplaceNumber);
650
651 config->writeEntry( "AutoNumberStyle", m_useAutoNumberStyle );
652
653 config->writeEntry( "AutoSuperScript", m_bAutoSuperScript );
654
655 config->setGroup( "completion" );
656 config->writeEntry( "completion", m_completion );
657 config->writeEntry( "CompletionAppendSpace", m_completionAppendSpace );
658 config->writeEntry( "CompletionMinWordLength", m_minCompletionWordLength);
659 config->writeEntry( "NbMaxCompletionWord", m_nbMaxCompletionWord);
660 config->writeEntry( "AddCompletionWord", m_addCompletionWord );
661 config->writeEntry( "ToolTipCompletion", m_toolTipCompletion );
662 config->writeEntry( "CompletionKeyAction", ( int )m_keyCompletionAction );
663
664 config->setGroup( "AutoFormatEntries" );
665 TQDictIterator<KoAutoFormatEntry> it( m_entries );
666
667 //refresh m_maxFindLength
668 m_maxFindLength=0;
669 TQDomDocument doc("autocorrection");
670
671 TQDomElement begin = doc.createElement( "Word" );
672 doc.appendChild( begin );
673 TQDomElement items;
674 items = doc.createElement("items");
675 TQDomElement data;
676 for ( ; it.current() ; ++it )
677 {
678 items.appendChild(saveEntry( it, doc));
679 //m_maxFindLength=TQMAX(m_maxFindLength,it.currentKey().length());
680 }
681 buildMaxLen();
682 begin.appendChild(items);
683
684 TQDomElement upper;
685 upper = doc.createElement("UpperCaseExceptions");
686 for ( TQStringList::Iterator it = m_upperCaseExceptions.begin(); it != m_upperCaseExceptions.end();++it )
687 {
688 data = doc.createElement("word");
689 data.setAttribute("exception",(*it) );
690 upper.appendChild(data);
691 }
692 begin.appendChild(upper);
693
694 TQDomElement twoUpper;
695 twoUpper = doc.createElement("TwoUpperLetterExceptions");
696
697 for ( TQStringList::Iterator it = m_twoUpperLetterException.begin(); it != m_twoUpperLetterException.end();++it )
698 {
699 data = doc.createElement("word");
700 data.setAttribute("exception",(*it) );
701 twoUpper.appendChild(data);
702 }
703 begin.appendChild(twoUpper);
704
705 TQDomElement super;
706 super = doc.createElement("SuperScript");
707 KoAutoFormatEntryMap::Iterator it2 = m_superScriptEntries.begin();
708 for ( ; it2 != m_superScriptEntries.end() ; ++it2 )
709 {
710 data = doc.createElement("superscript");
711 data.setAttribute("find", it2.key());
712 data.setAttribute("super", it2.data().replace());
713 super.appendChild(data);
714 }
715 begin.appendChild(super);
716
717 TQDomElement doubleQuote;
718 doubleQuote = doc.createElement("DoubleQuote");
719 data = doc.createElement("doublequote");
720 data.setAttribute("begin", TQString(m_typographicDefaultDoubleQuotes.begin));
721 data.setAttribute("end", TQString(m_typographicDefaultDoubleQuotes.end));
722 doubleQuote.appendChild(data);
723 begin.appendChild(doubleQuote);
724
725
726 TQDomElement simpleQuote;
727 simpleQuote = doc.createElement("SimpleQuote");
728 data = doc.createElement("simplequote");
729 data.setAttribute("begin", TQString(m_typographicDefaultSimpleQuotes.begin));
730 data.setAttribute("end", TQString(m_typographicDefaultSimpleQuotes.end));
731 simpleQuote.appendChild(data);
732 begin.appendChild(simpleQuote);
733 TQFile f;
734 if ( m_autoFormatLanguage.isEmpty())
735 f.setName(locateLocal("data", "koffice/autocorrect/"+tdelocale.languageList().front() + ".xml",m_doc->instance()));
736 else
737 f.setName(locateLocal("data", "koffice/autocorrect/"+m_autoFormatLanguage + ".xml",m_doc->instance()));
738 if(!f.open(IO_WriteOnly)) {
739 kdWarning()<<"Error during saving autoformat to " << f.name() << endl;
740 return;
741 }
742 TQTextStream ts(&f);
743 doc.save(ts, 2);
744 f.close();
745 autoFormatIsActive();
746 config->sync();
747}
748
749TQDomElement KoAutoFormat::saveEntry( TQDictIterator<KoAutoFormatEntry> _entry, TQDomDocument doc)
750{
751 TQDomElement data;
752 data = doc.createElement("item");
753 data.setAttribute("find", _entry.currentKey());
754 data.setAttribute("replace", _entry.current()->replace());
755 if ( _entry.current()->formatEntryContext() )
756 {
757 KoSearchContext *tmp = _entry.current()->formatEntryContext();
758 if ( tmp->m_optionsMask & KoSearchContext::Family )
759 {
760 data.setAttribute("FONT", tmp->m_family);
761 }
762 if ( tmp->m_optionsMask & KoSearchContext::Size )
763 {
764 data.setAttribute("SIZE", tmp->m_size);
765 }
766 if ( tmp->m_optionsMask & KoSearchContext::Italic )
767 {
768 data.setAttribute("ITALIC", static_cast<bool>(tmp->m_options & KoSearchContext::Italic));
769 }
770 if ( tmp->m_optionsMask & KoSearchContext::Bold )
771 {
772 data.setAttribute("BOLD", static_cast<bool>(tmp->m_options & KoSearchContext::Bold));
773 }
774 if ( tmp->m_optionsMask & KoSearchContext::Shadow )
775 {
776 data.setAttribute("SHADOWTEXT", static_cast<bool>(tmp->m_options & KoSearchContext::Shadow));
777 }
778 if ( tmp->m_optionsMask & KoSearchContext::WordByWord )
779 {
780 data.setAttribute("WORDBYWORD", static_cast<bool>(tmp->m_options & KoSearchContext::WordByWord));
781 }
782
783 if ( tmp->m_optionsMask & KoSearchContext::Underline )
784 {
785 switch( tmp->m_underline )
786 {
787 case KoTextFormat::U_SIMPLE:
788 data.setAttribute("UNDERLINE", "single");
789 break;
790 case KoTextFormat::U_DOUBLE:
791 data.setAttribute("UNDERLINE", "double");
792 break;
793 case KoTextFormat::U_SIMPLE_BOLD:
794 data.setAttribute("UNDERLINE", "single-bold");
795 break;
796 case KoTextFormat::U_WAVE:
797 data.setAttribute("UNDERLINE", "wave");
798 break;
799 case KoTextFormat::U_NONE:
800 data.setAttribute("UNDERLINE", "none");
801 break;
802 }
803 }
804 if ( tmp->m_optionsMask & KoSearchContext::StrikeOut )
805 {
806 switch( tmp->m_strikeOut )
807 {
808 case KoTextFormat::S_SIMPLE:
809 data.setAttribute("STRIKEOUT", "single");
810 break;
811 case KoTextFormat::S_DOUBLE:
812 data.setAttribute("STRIKEOUT", "double");
813 break;
814 case KoTextFormat::S_NONE:
815 data.setAttribute("STRIKEOUT", "none");
816 break;
817 case KoTextFormat::S_SIMPLE_BOLD:
818 data.setAttribute("STRIKEOUT", "single-bold");
819 break;
820 }
821 }
822 if ( tmp->m_optionsMask & KoSearchContext::Attribute )
823 {
824 data.setAttribute("FONTATTRIBUTE", KoTextFormat::attributeFontToString( tmp->m_attribute ) );
825 }
826
827 if ( tmp->m_optionsMask & KoSearchContext::VertAlign)
828 {
829 data.setAttribute( "VERTALIGN", static_cast<int>(tmp->m_vertAlign) );
830 }
831 if ( tmp->m_optionsMask & KoSearchContext::BgColor )
832 {
833 data.setAttribute( "TEXTCOLOR", tmp->m_color.name());
834 }
835 if ( tmp->m_optionsMask & KoSearchContext::Color )
836 {
837 data.setAttribute( "TEXTCOLOR", tmp->m_color.name());
838 }
839 if ( tmp->m_optionsMask & KoSearchContext::BgColor )
840 {
841 data.setAttribute( "TEXTBGCOLOR", tmp->m_backGroundColor.name());
842 }
843 if ( tmp->m_optionsMask & KoSearchContext::Language )
844 data.setAttribute( "LANGUAGE", tmp->m_language );
845 }
846 return data;
847}
848
849void KoAutoFormat::addAutoFormatEntry( const TQString &key, const TQString &replace )
850{
851 KoAutoFormatEntry *findEntry = m_entries.find( key);
852 if ( findEntry )
853 {
854 if ( findEntry->replace().lower() == replace.lower() )
855 return;
856 }
857
858 KoAutoFormatEntry *tmp = new KoAutoFormatEntry( replace );
859 m_entries.insert( key, tmp );
860 saveConfig();
861 buildMaxLen();
862}
863
864TQString KoAutoFormat::getLastWord(KoTextParag *parag, int const index)
865{
866 TQString lastWord;
867 KoTextString *s = parag->string();
868 for ( int i = index - 1; i >= 0; --i )
869 {
870 TQChar ch = s->at( i ).c;
871 if ( ch.isSpace() || ch.isPunct() )
872 break;
873 lastWord.prepend( ch );
874 }
875 return lastWord;
876}
877
878TQString KoAutoFormat::getLastWord(const int max_words, KoTextParag *parag, int const index)
879{
880 TQString lastWord;
881 KoTextString const *s = parag->string();
882 int words = 0;
883 for ( int i = index - 1; i >= 0; --i )
884 {
885 TQChar ch = s->at( i ).c;
886 if ( ch.isSpace() || ch.isPunct() )
887 {
888 ++words;
889 if (words >= max_words)
890 break;
891 }
892 lastWord.prepend( ch );
893 }
894 return lastWord;
895}
896
897TQString KoAutoFormat::getWordAfterSpace(KoTextParag *parag, int const index)
898{
899 TQString word;
900 KoTextString *s = parag->string();
901 for ( int i = index - 1; i >= 0; --i )
902 {
903 TQChar ch = s->at( i ).c;
904 if ( ch.isSpace() )
905 break;
906 word.prepend( ch );
907 }
908 return word;
909
910}
911
912bool KoAutoFormat::doCompletion( KoTextCursor* textEditCursor, KoTextParag *parag, int const index, KoTextObject *txtObj )
913{
914 if( m_completion )
915 {
916 bool part=false;
917 TQString lastWord, word;
918 if (m_completionBox && m_completionBox->isShown() ) //word completion with the tool-tip box
919 {
920 word = m_completionBox->text();
921 lastWord = m_completionBox->lastWord();
922 }
923 else
924 {
925 TQStringList wordlist, new_wordlist;
926 for (uint i=1; i <= m_countMaxWords; i++ )
927 {
928 lastWord = getLastWord(i, parag, index+1);
929 wordlist += m_listCompletion->substringCompletion( lastWord ); //find all completion words that contains lastWord
930 }
931 uint maxlength = 0;
932 for ( TQStringList::ConstIterator it = wordlist.begin(); it != wordlist.end(); ++it ) // several completion words were found
933 {
934 if ( (*it).startsWith( lastWord, false ) && new_wordlist.find(*it) == new_wordlist.end() ) //the completion words that begin with lastWord
935 {
936 if ( (*it).length() > maxlength )
937 maxlength = (*it).length();
938 new_wordlist.append(*it);
939 //kdDebug() << "adding word completion:" << *it << endl;
940 }
941 }
942 if ( new_wordlist.isEmpty() )
943 return false;
944 if ( new_wordlist.count() == 1 ) // only one completion word was found
945 word = new_wordlist.first();
946 else
947 {
948 //we must extract the common part of the completions
949 for (uint i = lastWord.length(); i<maxlength && !part; i++) //iterate through all completion words
950 {
951 TQChar ch = new_wordlist.first().at(i);
952 for (TQStringList::ConstIterator it = new_wordlist.begin(); it != new_wordlist.end(); ++it )
953 {
954 if ( (*it).at(i).lower() != ch.lower() )
955 {
956 word = (*it).left(i); //the completion word is truncated here
957 //kdDebug() << "set the word completion to:" << word << endl;
958 part=true; // completion of a part of a word; a space-character after the completion should not be inserted
959 break;
960 }
961 }
962 }
963 }
964 if (word == lastWord)
965 return false;
966
967 word=lastWord+word.right(word.length()-lastWord.length() );
968 }
969 if( !word.isEmpty() )
970 {
971 int const lastword_length = lastWord.length();
972 int const start = index+1 - lastword_length;
973 int const length = word.length();
974
975 KMacroCommand *macro = new KMacroCommand( i18n("Completion Word"));
976 KoTextCursor cursor( parag->document() );
977 cursor.setParag( parag );
978 cursor.setIndex( start );
979 KoTextDocument * textdoc = parag->textDocument();
980 if( m_completionAppendSpace && !part)
981 word+=" ";
982 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
983 cursor.setIndex( start + lastword_length );
984 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
985
986 macro->addCommand( txtObj->replaceSelectionCommand( textEditCursor, word,
987 i18n("Completion Word"),
988 KoTextDocument::HighlightSelection ));
989
990 if ( m_completionAppendSpace && !m_ignoreUpperCase && (m_convertUpperUpper || m_convertUpperCase) && !part)
991 {
992 //find the first word
993 for (uint i=1; i < word.length(); i++)
994 if ( word.at(i).isSpace() || word.at(i).isPunct() )
995 {
996 word.truncate(i);
997 break;
998 }
999 int const newPos = start + word.length();// + index - 3;
1000 KCommand *cmd = doUpperCase( textEditCursor, parag, newPos, word, txtObj );
1001 if( cmd )
1002 macro->addCommand( cmd );
1003 txtObj->emitHideCursor();
1004 textEditCursor->setIndex(start+ length+1);
1005 }
1006 else
1007 {
1008 txtObj->emitHideCursor();
1009 textEditCursor->setIndex(start+ length);
1010 }
1011 txtObj->emitNewCommand( macro );
1012
1013 // The space/tab/CR that we inserted is still there but delete/insert moved the cursor
1014 // -> go right
1015
1016 txtObj->emitShowCursor();
1017 removeToolTipCompletion();
1018 return true;
1019 }
1020 }
1021 return false;
1022}
1023
1024bool KoAutoFormat::doToolTipCompletion( KoTextCursor* textEditCursor, KoTextParag *parag, int index, KoTextObject *txtObj, int keyPressed )
1025{
1026 if( m_completion && m_toolTipCompletion && m_completionBox && m_completionBox->isShown() )
1027 {
1028 if ( ( keyPressed == TQt::Key_Return && m_keyCompletionAction==Enter )
1029 || ( keyPressed == TQt::Key_Enter && m_keyCompletionAction==Enter )
1030 || ( keyPressed == TQt::Key_Tab && m_keyCompletionAction==Tab )
1031 || ( keyPressed == TQt::Key_Space && m_keyCompletionAction==Space )
1032 || ( keyPressed == TQt::Key_End && m_keyCompletionAction==End )
1033 || ( keyPressed == TQt::Key_Right && m_keyCompletionAction==Right ))
1034 {
1035 return doCompletion(textEditCursor, parag, index, txtObj);
1036 }
1037 }
1038 return false;
1039}
1040void KoAutoFormat::showToolTipBox(KoTextParag *parag, int index, TQWidget *widget, const TQPoint &pos )
1041{
1042
1043 if( m_completion && m_toolTipCompletion)
1044 {
1045 TQString lastWord, word;
1046 for (uint i=1; i <= m_countMaxWords; i++ )
1047 {
1048 lastWord = getLastWord(i, parag, index+1);
1049 word=m_listCompletion->makeCompletion( lastWord );
1050 if ( !word.isEmpty())
1051 break;
1052 }
1053 if( !word.isEmpty() && word!=lastWord )
1054 {
1055 uint const length = lastWord.length();
1056 if (length<=3)
1057 return;
1058 word=lastWord+word.right(word.length()-length);
1059 if (!m_completionBox)
1060 m_completionBox = new KoCompletionBox(0,0,TQt::WType_Popup);
1061 TQPoint const show_pos = widget->mapToGlobal(pos);
1062 m_completionBox->setText(word);
1063 m_completionBox->setLastWord(lastWord);
1064 m_completionBox->adjustSize();
1065 int const height = m_completionBox->sizeHint().height();
1066 m_completionBox->move( show_pos.x(), show_pos.y() - height );
1067
1068 if (!m_completionBox->isShown() )
1069 {
1070 m_completionBox->show();
1071 widget->setFocus();
1072 }
1073 }
1074 else
1075 removeToolTipCompletion();
1076 }
1077}
1078void KoAutoFormat::removeToolTipCompletion()
1079{
1080 if (m_completion && m_toolTipCompletion && m_completionBox && m_completionBox->isShown())
1081 m_completionBox->hide();
1082}
1083
1084void KoAutoFormat::autoFormatIsActive()
1085{
1086 m_bAutoFormatActive = m_useBulletStyle ||
1087 m_removeSpaceBeginEndLine ||
1088 m_autoDetectUrl ||
1089 m_convertUpperUpper ||
1090 m_convertUpperCase ||
1091 m_autoReplaceNumber ||
1092 m_autoChangeFormat ||
1093 m_completion ||
1094 m_typographicDoubleQuotes.replace ||
1095 m_typographicSimpleQuotes.replace ||
1096 m_entries.count()!=0 ||
1097 m_allLanguages.count()!=0;
1098}
1099
1100void KoAutoFormat::doAutoFormat( KoTextCursor* textEditCursor, KoTextParag *parag, int index, TQChar ch,KoTextObject *txtObj )
1101{
1102 m_ignoreUpperCase = false;
1103
1104 if ( !m_configRead )
1105 readConfig();
1106
1107 if ( !m_bAutoFormatActive )
1108 return;
1109
1110 if( ch.isSpace())
1111 {
1112 //a link doesn't have a space
1113 //=>m_ignoreUpperCase = false
1114 //m_ignoreUpperCase=false;
1115
1116 TQString word=getWordAfterSpace(parag,index);
1117
1118 if ( m_autoChangeFormat && index > 3)
1119 {
1120 KCommand *cmd =doAutoChangeFormat( textEditCursor, parag, index, word, txtObj );
1121 if ( cmd )
1122 txtObj->emitNewCommand( cmd );
1123
1124 }
1125 if ( m_autoReplaceNumber )
1126 {
1127 KCommand *cmd = doAutoReplaceNumber( textEditCursor, parag, index, word, txtObj );
1128 if ( cmd )
1129 txtObj->emitNewCommand( cmd );
1130 }
1131 }
1132
1133 if( ch =='\n' )
1134 {
1135
1136 if( m_removeSpaceBeginEndLine && index > 1)
1137 {
1138 KCommand *cmd = doRemoveSpaceBeginEndLine( textEditCursor, parag, txtObj, index );
1139 if ( cmd )
1140 txtObj->emitNewCommand( cmd );
1141 }
1142 if( m_useBulletStyle && index > 3)
1143 {
1144 KCommand *cmd =doUseBulletStyle( textEditCursor, parag, txtObj, index );
1145 if ( cmd )
1146 txtObj->emitNewCommand( cmd );
1147 }
1148 if( m_useAutoNumberStyle && index > 3 )
1149 {
1150 KCommand *cmd =doUseNumberStyle( textEditCursor, parag, txtObj, index );
1151 if ( cmd )
1152 txtObj->emitNewCommand( cmd );
1153 }
1154 if( m_convertUpperUpper && m_includeTwoUpperLetterException )
1155 doAutoIncludeUpperUpper(textEditCursor, parag, txtObj );
1156 if( m_convertUpperCase && m_includeAbbreviation )
1157 doAutoIncludeAbbreviation(textEditCursor, parag, txtObj );
1158 }
1159
1160 //kdDebug(32500) << "KoAutoFormat::doAutoFormat ch=" << TQString(ch) << endl;
1161 //if ( !m_enabled )
1162 // return;
1163 // Auto-correction happens when pressing space, tab, CR, punct etc.
1164 if ( (ch.isSpace() || ch==':' || ch=='?' || ch=='!' || ch==',' || (m_advancedAutoCorrect && ch=='.') ) && index > 0 )
1165 {
1166 KCommand *cmd = 0L;
1167 KMacroCommand *macro = 0L;
1168 TQString lastWord = getWordAfterSpace(parag, index);
1169 //kdDebug(32500) << "KoAutoFormat::doAutoFormat lastWord=" << lastWord << endl;
1170
1171 if ( ch == '.')
1172 detectStartOfLink( parag, index, true );
1173 else
1174 detectStartOfLink( parag, index, false );
1175
1176 if ( !m_wordInserted && m_advancedAutoCorrect && !m_ignoreUpperCase)
1177 {
1178 int const completionBeginPos = index -lastWord.length();
1179 int newPos = index;
1180 cmd = doAutoCorrect( textEditCursor, parag, newPos, txtObj );
1181
1182 if( cmd )
1183 {
1184 if (!macro)
1185 macro = new KMacroCommand(i18n("Autocorrection"));
1186 macro->addCommand( cmd );
1187 }
1188
1189 int const endPos=textEditCursor->index();
1190 bool was_a_replacement;
1191 if (index == newPos)
1192 was_a_replacement = false;
1193 else
1194 was_a_replacement = true;
1195
1196 if( was_a_replacement) // a replacement took place
1197 {
1198 txtObj->emitHideCursor();
1199 if(endPos==0) //new line, the user pressed enter
1200 {
1201 textEditCursor->gotoUp();
1202 textEditCursor->gotoLineEnd();
1203 newPos=textEditCursor->index();
1204 }
1205 else
1206 newPos= endPos-1;
1207
1208 m_wordInserted = true; //don't allow other replacements in this replacement
1209 for(int i=completionBeginPos; i<newPos;i++)
1210 {
1211 textEditCursor->setIndex(i);
1212 doAutoFormat( textEditCursor, parag, i, parag->toString().at(i),txtObj );
1213
1214 }
1215 textEditCursor->setIndex(newPos);
1216 doAutoFormat( textEditCursor, parag, newPos, ch,txtObj );
1217 m_wordInserted = false;
1218 if (endPos==0)
1219 {
1220 textEditCursor->gotoLineStart();
1221 textEditCursor->gotoDown();
1222 }
1223 else
1224 textEditCursor->setIndex(newPos+1);
1225 txtObj->emitShowCursor();
1226 return;
1227 }
1228
1229 }
1230
1231 if (!m_ignoreUpperCase && m_bCapitalizeNameOfDays)
1232 {
1233 KCommand *cmd = doCapitalizeNameOfDays( textEditCursor, parag, index, lastWord, txtObj );
1234
1235 if( cmd )
1236 {
1237 if (!macro)
1238 macro = new KMacroCommand(i18n("Autocorrection"));
1239 macro->addCommand( cmd );
1240 m_ignoreUpperCase = true;
1241 }
1242 }
1243
1244 if (ch=='.')
1245 return;
1246
1247 //kdDebug(32500)<<" m_listCompletion->items() :"<<m_listCompletion->items()<<endl;
1248 if( !m_ignoreUpperCase && m_completion && m_addCompletionWord && m_listCompletion->items().count() < m_nbMaxCompletionWord )
1249 {
1250 TQString completionWord("");
1251 TQChar ch;
1252 for (uint i=0;i<lastWord.length();i++)
1253 {
1254 ch = lastWord.at(i);
1255 if (ch.isPunct() && ch!='-' && ch!='=' )
1256 {
1257 if (completionWord.at(0) == '-')
1258 completionWord.remove(0,1);
1259
1260 if (completionWord.length()>= m_minCompletionWordLength && !completionWord.isEmpty() && m_listCompletion->makeCompletion(completionWord).isEmpty())
1261 {
1262 kdDebug() << "Adding:" << completionWord << endl;
1263 m_listCompletion->addItem( completionWord );
1264 if ( completionWord.length() > m_countMaxWords )
1265 m_countMaxWords = completionWord.length();
1266
1267 }
1268 completionWord = "";
1269 }
1270 else
1271 {
1272 completionWord.append(ch);
1273 if (i==lastWord.length()-1)
1274 {
1275 if (completionWord.at(0) == '-')
1276 completionWord.remove(0,1);
1277 if (completionWord.at(completionWord.length()-1) == '-')
1278 completionWord.truncate(completionWord.length()-1);
1279 completionWord.remove('=');
1280 if (completionWord.length()>= m_minCompletionWordLength && !completionWord.isEmpty() && m_listCompletion->makeCompletion(completionWord).isEmpty())
1281 {
1282 kdDebug() << "Adding:" << completionWord << endl;
1283 m_listCompletion->addItem( completionWord );
1284 if ( completionWord.length() > m_countMaxWords )
1285 m_countMaxWords = completionWord.length();
1286 }
1287 }
1288 }
1289 }
1290 }
1291
1292 if( m_autoDetectUrl && m_ignoreUpperCase && (ch!='?' || lastWord.at(lastWord.length()-1)=='?') )
1293 {
1294 doAutoDetectUrl( textEditCursor, parag, index, lastWord, txtObj );
1295 //textEditCursor->gotoRight();
1296 }
1297
1298 if (!m_ignoreUpperCase && (m_convertUpperUpper || m_convertUpperCase) )
1299 {
1300 cmd = doUpperCase( textEditCursor, parag, index, lastWord, txtObj );
1301
1302 if( cmd )
1303 {
1304 if (!macro)
1305 macro = new KMacroCommand(i18n("Autocorrection"));
1306 macro->addCommand( cmd );
1307 }
1308 }
1309
1310 if ( macro )
1311 txtObj->emitNewCommand( macro );
1312
1313 if(!m_ignoreUpperCase && m_bAutoSuperScript && m_superScriptEntries.count()>0)
1314 {
1315 if( lastWord.at(0).isPunct() )
1316 lastWord.remove(0,1);
1317 KCommand * cmd = doAutoSuperScript( textEditCursor, parag, index, lastWord, txtObj );
1318 if ( cmd )
1319 txtObj->emitNewCommand( cmd );
1320 }
1321
1322 }
1323 else
1324 {
1325 if ( ch == '"' && m_typographicDoubleQuotes.replace )
1326 {
1327 KCommand *cmd = doTypographicQuotes( textEditCursor, parag, index, txtObj, true /*double quote*/ );
1328 if ( cmd )
1329 txtObj->emitNewCommand( cmd );
1330 }
1331 else if ( ch == '\'' && m_typographicDoubleQuotes.replace )
1332 {
1333 KCommand *cmd = doTypographicQuotes( textEditCursor, parag, index, txtObj, false /* simple quote*/ );
1334 if ( cmd )
1335 txtObj->emitNewCommand( cmd );
1336 }
1337 }
1338}
1339
1340KCommand *KoAutoFormat::doAutoCorrect( KoTextCursor* textEditCursor, KoTextParag *parag, int &index, KoTextObject *txtObj )
1341{
1342 //if(!m_advancedAutoCorrect)
1343 // return 0L;
1344 // Prepare an array with words of different lengths, all terminating at "index".
1345 // Obviously only full words are put into the array
1346 // But this allows 'find strings' with spaces and punctuation in them.
1347 TQString * wordArray = new TQString[m_maxFindLength+1];
1348 {
1349 TQString word;
1350 KoTextString *s = parag->string();
1351 for ( int i = index - 1; i >= 0; --i )
1352 {
1353 TQChar ch = s->at( i ).c;
1354 // It's necessary to stop at spaces - #99063
1355 if ( ch.isSpace() /*|| ch.isPunct()*/ || i==0)
1356 {
1357 if(i==0 && word.length()<m_maxFindLength)
1358 word.prepend( ch );
1359 wordArray[word.length()]=word;
1360 }
1361 word.prepend( ch );
1362 if (((index - 1)-i) == (int)m_maxFindLength)
1363 break;
1364 }
1365
1366 }
1367 KCommand *cmd = autoFormatWord( textEditCursor, parag, index, txtObj, wordArray, false );
1368 if ( !cmd )
1369 cmd = autoFormatWord( textEditCursor, parag, index, txtObj, wordArray, true );
1370 delete [] wordArray;
1371 return cmd;
1372}
1373
1374
1375KCommand *KoAutoFormat::autoFormatWord( KoTextCursor* textEditCursor, KoTextParag *parag, int &index, KoTextObject *txtObj, TQString * _wordArray, bool _allLanguages )
1376{
1377 KoTextDocument * textdoc = parag->textDocument();
1378
1379 // Now for each entry in the autocorrect list, look if
1380 // the word of the same size in wordArray matches.
1381 // This allows an o(n) behaviour instead of an o(n^2).
1382 for(int i=m_maxFindLength;i>0;--i)
1383 {
1384 if ( !_wordArray[i].isEmpty())
1385 {
1386 KoAutoFormatEntry* it = 0L;
1387 if ( _allLanguages )
1388 it = m_allLanguages[ _wordArray[i] ];
1389 else
1390 it = m_entries[ _wordArray[i] ];
1391 if ( _wordArray[i]!=0 && it )
1392 {
1393 unsigned int length = _wordArray[i].length();
1394 int const start = index - length;
1395 KoTextCursor cursor( parag->document() );
1396 cursor.setParag( parag );
1397 cursor.setIndex( start );
1398 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1399 cursor.setIndex( start + length );
1400 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1401 KCommand *cmd = 0L;
1402 kdDebug()<<"it->replace() :"<<it->replace()<<endl;
1403 if (!it->formatEntryContext() || !m_bAutoCorrectionWithFormat)
1404 {
1405 cmd = txtObj->replaceSelectionCommand( textEditCursor, it->replace(),
1406 i18n("Autocorrect Word"),
1407 KoTextDocument::HighlightSelection );
1408 }
1409 else
1410 {
1411 int flags = 0;
1412 KoTextFormat * lastFormat = parag->at( start )->format();
1413 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
1414 changeTextFormat(it->formatEntryContext(), newFormat, flags );
1415 KMacroCommand *macro = new KMacroCommand( i18n("Autocorrect Word with Format"));
1416 KCommand *cmd2=txtObj->replaceSelectionCommand( textEditCursor, it->replace(),
1417 i18n("Autocorrect Word"),
1418 KoTextDocument::HighlightSelection );
1419 if ( cmd2 )
1420 macro->addCommand(cmd2);
1421 KoTextCursor cursor( parag->document() );
1422 cursor.setParag( parag );
1423 cursor.setIndex( start );
1424 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1425 cursor.setIndex( start + it->replace().length()/*+ length + 1*/ );
1426 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1427
1428 cmd2 =txtObj->setFormatCommand( textEditCursor, &lastFormat, newFormat, flags, false, KoTextDocument::HighlightSelection );
1429 macro->addCommand( cmd2);
1430
1431 index = index - length + it->replace().length();
1432 textEditCursor->setIndex(index+1);
1433 cmd2 =txtObj->setFormatCommand( textEditCursor, &newFormat, lastFormat, 0 );
1434 macro->addCommand( cmd2);
1435 parag->at( index+1 )->setFormat(lastFormat);
1436
1437 cmd = macro;
1438 txtObj->emitHideCursor();
1439 textEditCursor->gotoRight();
1440 txtObj->emitShowCursor();
1441
1442 return cmd;
1443 }
1444 // The space/tab/CR that we inserted is still there but delete/insert moved the cursor
1445 // -> go right
1446
1447 txtObj->emitHideCursor();
1448 textEditCursor->gotoRight();
1449 txtObj->emitShowCursor();
1450 index = index - length + it->replace().length();
1451 return cmd;
1452 }
1453 }
1454 }
1455 return 0L;
1456}
1457
1458KCommand *KoAutoFormat::doTypographicQuotes( KoTextCursor* textEditCursor, KoTextParag *parag, int index, KoTextObject *txtObj, bool doubleQuotes )
1459{
1460 //kdDebug(32500) << "KoAutoFormat::doTypographicQuotes" << endl;
1461 KoTextDocument * textdoc = parag->textDocument();
1462 KoTextCursor cursor( parag->document() );
1463 cursor.setParag( parag );
1464 cursor.setIndex( index );
1465 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1466 cursor.setIndex( index + 1 );
1467 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1468
1469 // Need to determine if we want a starting or ending quote.
1470 // we use a starting quote in three cases:
1471 // 1. if the previous character is a space
1472 // 2. if the previous character is some kind of opening punctuation (e.g., "(", "[", or "{")
1473 // a. and the character before that is not an opening quote (so that we get quotations of single characters
1474 // right)
1475 // 3. if the previous character is an opening quote (so that we get nested quotations right)
1476 // a. and the character before that is not an opening quote (so that we get quotations of single characters
1477 // right)
1478 // b. and the previous quote of a different kind (so that we get empty quotations right)
1479 TQString replacement;
1480 bool ending = true;
1481
1482 if( index > 0 )
1483 {
1484 TQChar::Category c1 = parag->at( index - 1 )->c.category();
1485
1486 // case 1 and 2
1487 if ( c1 == TQChar::Separator_Space || c1 == TQChar::Separator_Line || c1 == TQChar::Separator_Paragraph ||
1488 c1 == TQChar::Punctuation_Open || c1 == TQChar::Other_Control )
1489 ending = false;
1490
1491 // case 3
1492 if ( c1 == TQChar::Punctuation_InitialQuote )
1493 {
1494 TQChar openingQuote;
1495
1496 if( doubleQuotes )
1497 openingQuote = m_typographicDoubleQuotes.begin;
1498 else
1499 openingQuote = m_typographicSimpleQuotes.begin;
1500
1501 // case 3b
1502 if( parag->at( index - 1 )->c != openingQuote )
1503 ending = false;
1504 }
1505 }
1506
1507 // cases 2a and 3a
1508 if( index > 1 && !ending )
1509 {
1510 TQChar::Category c2 = parag->at( index - 2 )->c.category();
1511 ending = (c2 == TQChar::Punctuation_InitialQuote);
1512 }
1513
1514 if( ending )
1515 {
1516 if( doubleQuotes )
1517 replacement = m_typographicDoubleQuotes.end;
1518 else
1519 replacement = m_typographicSimpleQuotes.end;
1520 }
1521 else
1522 {
1523 if( doubleQuotes )
1524 replacement = m_typographicDoubleQuotes.begin;
1525 else
1526 replacement = m_typographicSimpleQuotes.begin;
1527 }
1528 return txtObj->replaceSelectionCommand( textEditCursor, replacement,
1529 i18n("Typographic Quote"),
1530 KoTextDocument::HighlightSelection );
1531}
1532
1533KCommand * KoAutoFormat::doUpperCase( KoTextCursor *textEditCursor, KoTextParag *parag,
1534 int index, const TQString & word, KoTextObject *txtObj )
1535{
1536 KoTextDocument * textdoc = parag->textDocument();
1537 unsigned int length = word.length();
1538 if (word.at(length-1) == '.' )
1539 {
1540 --index;
1541 --length;
1542 }
1543 int const start = index - length;
1544 KoTextCursor backCursor( parag->document() );
1545 backCursor.setParag( parag );
1546 backCursor.setIndex( start );
1547
1548 // backCursor now points at the first char of the word
1549 TQChar const firstChar = backCursor.parag()->at( backCursor.index() )->c;
1550
1551 bool bNeedMove = false;
1552 KCommand *cmd = 0L;
1553 if ( m_convertUpperCase && isLower( firstChar ) )
1554 {
1555 bool beginningOfSentence = true; // true if beginning of text
1556 // Go back over any space/tab/CR
1557 while ( backCursor.index() > 0 || backCursor.parag()->prev() )
1558 {
1559 beginningOfSentence = false; // we could go back -> false unless we'll find '.'
1560 backCursor.gotoLeft();
1561 if ( !backCursor.parag()->at( backCursor.index() )->c.isSpace() )
1562 break;
1563 }
1564 // We are now at the first non-space char before the word
1565 if ( !beginningOfSentence )
1566 beginningOfSentence = isMark( backCursor.parag()->at( backCursor.index() )->c);
1567 //beginningOfSentence = isMark( backCursor.parag()->at( backCursor.index() )->c ) && (backCursor.parag()->at( backCursor.index()+1 )->c.isSpace());
1568 if ( !beginningOfSentence && start==0 )
1569 if ( parag->counter() || backCursor.parag()->at( backCursor.index() )->c.isPunct() )
1570 beginningOfSentence = true;
1571
1572 // Now look for exceptions
1573 if ( beginningOfSentence )
1574 {
1575 TQChar const punct = backCursor.parag()->at( backCursor.index() )->c;
1576 TQString const text = getLastWord( backCursor.parag(), backCursor.index() )
1577 + punct;
1578 kdDebug() << "text: " << text << endl;
1579 // text has the word at the end of the 'sentence', including the termination. Example: "Mr."
1580 beginningOfSentence = (m_upperCaseExceptions.findIndex(text)==-1); // Ok if we can't find it
1581 }
1582
1583 if ( beginningOfSentence )
1584 {
1585 KoTextCursor cursor( parag->document() );
1586 cursor.setParag( parag );
1587 cursor.setIndex( start );
1588 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1589 cursor.setIndex( start + 1 );
1590 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1591 cmd = txtObj->replaceSelectionCommand( textEditCursor, TQString( firstChar.upper() ),
1592 i18n("Autocorrect (capitalize first letter)"),
1593 KoTextDocument::HighlightSelection );
1594 bNeedMove = true;
1595 }
1596 }
1597 else if ( m_convertUpperUpper && isUpper( firstChar ) && length > 2 )
1598 {
1599 backCursor.setIndex( backCursor.index() + 1 );
1600 TQChar secondChar = backCursor.parag()->at( backCursor.index() )->c;
1601 //kdDebug(32500)<<" secondChar :"<<secondChar<<endl;
1602 if ( isUpper( secondChar ) )
1603 {
1604 // Check next letter - we still want to be able to write fully uppercase words...
1605 backCursor.setIndex( backCursor.index() + 1 );
1606 TQChar thirdChar = backCursor.parag()->at( backCursor.index() )->c;
1607 if ( isLower( thirdChar ) && (m_twoUpperLetterException.findIndex(word)==-1))
1608 {
1609 // Ok, convert
1610 KoTextCursor cursor( parag->document() );
1611 cursor.setParag( parag );
1612 cursor.setIndex( start + 1 ); // After all the first letter's fine, so only change the second letter
1613 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1614 cursor.setIndex( start + 2 );
1615 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1616
1617 TQString replacement = word[1].lower();
1618 cmd = txtObj->replaceSelectionCommand( textEditCursor, replacement,
1619 i18n("Autocorrect"),
1620 KoTextDocument::HighlightSelection );
1621
1622 bNeedMove = true;
1623 }
1624 }
1625 }
1626 if ( bNeedMove )
1627 {
1628 if (word.at(word.length()-1) == '.' )
1629 ++index;
1630 txtObj->emitHideCursor();
1631 textEditCursor->setParag( parag );
1632 textEditCursor->setIndex( index );
1633 textEditCursor->gotoRight(); // not the same thing as index+1, in case of CR
1634 txtObj->emitShowCursor();
1635 }
1636 return cmd;
1637}
1638
1639KCommand * KoAutoFormat::doAutoReplaceNumber( KoTextCursor* textEditCursor, KoTextParag *parag, int& index, const TQString & word , KoTextObject *txtObj )
1640{
1641 unsigned int length = word.length();
1642 if ( length != 3 )
1643 return 0L;
1644 KoTextDocument * textdoc = parag->textDocument();
1645 int start = index - length;
1646 if( word == TQString("1/2") || word == TQString("1/4") || word == TQString("3/4") )
1647 {
1648 KoTextCursor cursor( parag->document() );
1649 cursor.setParag( parag );
1650 cursor.setIndex( start );
1651 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1652 cursor.setIndex( start + length );
1653 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1654 TQString replacement;
1655 if( word == TQString("1/2") )
1656 replacement=TQString("½");
1657 else if (word == TQString("1/4") )
1658 replacement=TQString("¼");
1659 else if (word == TQString("3/4") )
1660 replacement=TQString("¾");
1661 TQString cmdName = i18n("Autocorrect for Fraction");
1662 KCommand *cmd =txtObj->replaceSelectionCommand( textEditCursor, replacement,
1663 cmdName,
1664 KoTextDocument::HighlightSelection );
1665 txtObj->emitHideCursor();
1666 textEditCursor->gotoRight();
1667 txtObj->emitShowCursor();
1668 index = index - length + replacement.length();
1669 return cmd;
1670 }
1671 return 0L;
1672}
1673
1674void KoAutoFormat::detectStartOfLink(KoTextParag * parag, int const index, bool const insertedDot)
1675{
1676 TQString word;
1677 KoTextString *s = parag->string();
1678 for ( int i = 0; i < index; ++i )
1679 {
1680 word.append( s->at( i ).c );
1681 }
1682
1683 if (word.find("http")!=-1 || word.find("https")!=-1 || word.find("mailto")!=-1 || word.find("ftp")!=-1 || word.find("file")!=-1
1684 || word.find("news")!=-1 || word.find('@')!=-1)
1685 m_ignoreUpperCase=true;
1686 else
1687 {
1688 int const tmp_pos=word.find("www.");
1689 if (tmp_pos!=-1 && (word.find('.',tmp_pos+4)!=-1 || insertedDot) )
1690 m_ignoreUpperCase=true;
1691 }
1692}
1693
1694void KoAutoFormat::doAutoDetectUrl( KoTextCursor *textEditCursor, KoTextParag *parag, int &index, TQString & word, KoTextObject *txtObj )
1695{
1696 kdDebug() << "link:" << word << endl;
1697 char link_type = 0;
1698 int pos = word.find("http://");
1699 int tmp_pos = word.find("https://");
1700 if(tmp_pos<pos && tmp_pos!=-1)
1701 pos = tmp_pos;
1702 tmp_pos = word.find("mailto:/");
1703 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
1704 pos = tmp_pos;
1705 tmp_pos = word.find("ftp://");
1706 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
1707 pos = tmp_pos;
1708 tmp_pos = word.find("ftp.");
1709 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
1710 {
1711 pos = tmp_pos;
1712 link_type = 3;
1713 }
1714 tmp_pos = word.find("file:/");
1715 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
1716 pos = tmp_pos;
1717 tmp_pos = word.find("news:");
1718 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
1719 pos = tmp_pos;
1720 tmp_pos = word.find("www.");
1721 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1 && word.find('.',tmp_pos+4)!=-1 )
1722 {
1723 pos = tmp_pos;
1724 link_type = 2;
1725 }
1726 tmp_pos = word.find('@');
1727 if ( pos == -1 && tmp_pos != -1 )
1728 {
1729 pos = tmp_pos-1;
1730 TQChar c;
1731 while( pos>=0 )
1732 {
1733 c = word.at(pos);
1734 if ( c.isPunct() && c!='.'&& c!='_') break;
1735 else --pos;
1736 }
1737 if ( pos == tmp_pos-1 ) //it not a valid address
1738 {
1739 m_ignoreUpperCase = false;
1740 pos = -1;
1741 }
1742 else
1743 ++pos;
1744 link_type = 1;
1745 }
1746 if(pos!=-1)
1747 {
1748 // A URL inside e.g. quotes (like "http://www.koffice.org" with the quotes) shouldn't include the quote in the URL.
1749 while ( !word.at(word.length()-1).isLetter() && !word.at(word.length()-1).isDigit() && word.at(word.length()-1)!='/')
1750 {
1751 word.truncate(word.length()-1);
1752 --index;
1753 }
1754 word.remove(0,pos);
1755 unsigned int const length = word.length();
1756 int const start = index - length;
1757 KoTextCursor cursor( parag->document() );
1758 KoTextDocument * textdoc = parag->textDocument();
1759 cursor.setParag( parag );
1760 cursor.setIndex( start );
1761 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1762 cursor.setIndex( start + length );
1763 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1764 TQString newWord = word;
1765 if(link_type==1)
1766 newWord = TQString("mailto:") + word;
1767 else if(link_type==2)
1768 newWord = TQString("http://") + word;
1769 else if(link_type==3)
1770 newWord = TQString("ftp://") + word;
1771
1772 KoVariable* var = new KoLinkVariable( textdoc, word, newWord, m_varFormatCollection->format( "STRING" ), m_varCollection );
1773 CustomItemsMap customItemsMap;
1774 customItemsMap.insert( 0, var );
1775 KoTextFormat * lastFormat = parag->at( start )->format();
1776 int origCursorIndex = textEditCursor->index();
1777 txtObj->insert( textEditCursor, lastFormat, KoTextObject::customItemChar(), i18n("Insert Variable"),
1778 KoTextDocument::HighlightSelection, KoTextObject::DefaultInsertFlags, customItemsMap );
1779 var->recalc();
1780 parag->invalidate(0);
1781 parag->setChanged( true );
1782
1783 // adjust index
1784 index -= length-1; // we removed length chars and inserted one instead
1785
1786 txtObj->emitHideCursor();
1787 textEditCursor->setIndex( origCursorIndex - (length-1) );
1788 txtObj->emitShowCursor();
1789
1790 // ###### TODO: Move to a common method, this code is duplicated...
1791 if ( m_completion && m_addCompletionWord && m_listCompletion->items().count() < m_nbMaxCompletionWord )
1792 {
1793 if (word.length()>= m_minCompletionWordLength && !word.isEmpty() && m_listCompletion->makeCompletion(word).isEmpty())
1794 {
1795 kdDebug() << "Adding:" << word << endl;
1796 m_listCompletion->addItem( word );
1797 if ( word.length() > m_countMaxWords )
1798 m_countMaxWords = word.length();
1799 }
1800 }
1801 }
1802}
1803
1804void KoAutoFormat::doAutoIncludeUpperUpper(KoTextCursor* /*textEditCursor*/, KoTextParag *parag, KoTextObject* /*txtObj*/ )
1805{
1806 KoTextString *s = parag->string();
1807
1808 if( s->length() < 2 )
1809 return;
1810
1811 for (int i=0; i<=(s->length() - 1);i++)
1812 {
1813 TQString word;
1814 for ( int j = i ; j < s->length() - 1; j++ )
1815 {
1816 TQChar ch = s->at( j ).c;
1817 if ( ch.isSpace() )
1818 break;
1819 word.append( ch );
1820 }
1821 if( word.length() > 2 && word.left(2)==word.left(2).upper() && word.at(3)!=word.at(3).upper() )
1822 {
1823 if ( m_twoUpperLetterException.findIndex(word )==-1)
1824 m_twoUpperLetterException.append( word);
1825 }
1826 i+=word.length();
1827 }
1828
1829}
1830
1831
1832void KoAutoFormat::doAutoIncludeAbbreviation(KoTextCursor* /*textEditCursor*/, KoTextParag *parag, KoTextObject* /*txtObj*/ )
1833{
1834 KoTextString *s = parag->string();
1835 if( s->length() < 2 )
1836 return;
1837 for (int i=0; i<=(s->length() - 1);i++)
1838 {
1839 TQString wordAfter;
1840 TQString word;
1841
1842 for ( int j = i ; j < s->length() - 1; j++ )
1843 {
1844 TQChar ch = s->at( j ).c;
1845 if ( ch.isSpace() )
1846 break;
1847 word.append( ch );
1848 }
1849 if ( isMark( word.at(word.length()-1)) )
1850 {
1851 for ( int j = i+word.length()+1 ; j < s->length() - 1; j++ )
1852 {
1853 TQChar ch = s->at( j ).c;
1854 if ( ch.isSpace() )
1855 break;
1856 wordAfter.append( ch );
1857 }
1858 if( word.length()>1 && !wordAfter.isEmpty() && wordAfter.at(0)==wordAfter.at(0).lower())
1859 {
1860 if ( m_upperCaseExceptions.findIndex(word )==-1)
1861 m_upperCaseExceptions.append( word );
1862 }
1863 }
1864 i+=word.length();
1865 if( !wordAfter.isEmpty())
1866 {
1867 i+=wordAfter.length()+1;
1868 }
1869 }
1870
1871}
1872
1873
1874KCommand * KoAutoFormat::doAutoChangeFormat( KoTextCursor *textEditCursor, KoTextParag *parag,int index, const TQString & word, KoTextObject *txtObj )
1875{
1876 bool underline = (word.at(0)=='_' && word.at(word.length()-1)=='_');
1877 bool bold = (word.at(0)=='*' && word.at(word.length()-1)=='*');
1878 if( bold || underline)
1879 {
1880 TQString replacement=word.mid(1,word.length()-2);
1881 int start = index - word.length();
1882 KoTextDocument * textdoc = parag->textDocument();
1883 KMacroCommand *macro=new KMacroCommand(i18n("Autocorrection: Change Format"));
1884 KoTextCursor cursor( parag->document() );
1885
1886 cursor.setParag( parag );
1887 cursor.setIndex( start );
1888 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1889 cursor.setIndex( start + word.length() );
1890 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1891 macro->addCommand(txtObj->replaceSelectionCommand( textEditCursor, replacement,
1892 i18n("Autocorrect Word"),
1893 KoTextDocument::HighlightSelection));
1894
1895 KoTextFormat * lastFormat = parag->at( start )->format();
1896 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
1897 cursor.setIndex( start );
1898 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1899 cursor.setIndex( start + word.length()-2 );
1900 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1901
1902 if( bold)
1903 {
1904 newFormat->setBold(true);
1905 macro->addCommand(txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::Bold , false,KoTextDocument::HighlightSelection ));
1906 }
1907 else if( underline )
1908 {
1909 newFormat->setUnderline(true);
1910 macro->addCommand(txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::Underline , false,KoTextDocument::HighlightSelection ));
1911 }
1912 txtObj->emitHideCursor();
1913 textEditCursor->gotoRight();
1914 txtObj->emitShowCursor();
1915 return macro;
1916 }
1917 return 0L;
1918}
1919
1920KCommand *KoAutoFormat::doUseBulletStyle(KoTextCursor * /*textEditCursor*/, KoTextParag *parag, KoTextObject *txtObj, int& index )
1921{
1922 KoTextDocument * textdoc = parag->textDocument();
1923 KoTextCursor cursor( parag->document() );
1924 KoTextString *s = parag->string();
1925 TQChar ch = s->at( 0 ).c;
1926
1927 if( m_useBulletStyle && (ch =='*' || ch == '-' || ch =='+') && (s->at(1).c).isSpace())
1928 {
1929 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_FOOTNOTE )
1930 return 0L;
1931 KMacroCommand *macroCmd = new KMacroCommand( i18n("Autocorrect (use bullet style)"));
1932 cursor.setParag( parag );
1933 cursor.setIndex( 0 );
1934 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1935 cursor.setParag( parag );
1936 cursor.setIndex( 2 );
1937 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1938 KCommand *cmd=txtObj->removeSelectedTextCommand( &cursor, KoTextDocument::HighlightSelection );
1939 // Adjust index
1940 index -= 2;
1941 if(cmd)
1942 macroCmd->addCommand(cmd);
1943
1944 cursor.setParag( parag );
1945 cursor.setIndex( 0 );
1946 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1947
1948 cursor.setIndex( 2 );
1949 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1950
1951
1952 KoParagCounter c;
1953 if( m_bulletStyle.isNull() && (ch == '*' || ch == '+' || ch == '-'))
1954 {
1955 if ( ch =='*')
1956 {
1957 c.setNumbering( KoParagCounter::NUM_LIST );
1958 c.setStyle( KoParagCounter::STYLE_DISCBULLET );
1959 }
1960 else if ( ch =='+' || ch=='-')
1961 {
1962 c.setNumbering( KoParagCounter::NUM_LIST );
1963 c.setStyle( KoParagCounter::STYLE_CUSTOMBULLET );
1964 if ( ch =='-' )
1965 c.setCustomBulletCharacter( '-' );
1966 else if ( ch=='+')
1967 c.setCustomBulletCharacter( '+' );
1968 }
1969 }
1970 else
1971 {
1972 c.setNumbering( KoParagCounter::NUM_LIST );
1973 c.setStyle( KoParagCounter::STYLE_CUSTOMBULLET );
1974 c.setCustomBulletCharacter( m_bulletStyle );
1975 }
1976 c.setSuffix(TQString());
1977 cmd=txtObj->setCounterCommand( &cursor, c ,KoTextDocument::HighlightSelection );
1978 if( cmd)
1979 macroCmd->addCommand(cmd);
1980 if (parag->next() )
1981 cursor.setParag( parag->next() );
1982 else
1983 return 0L;
1984
1985 cursor.setIndex( 0 );
1986 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
1987 cursor.setIndex( 0 );
1988 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
1989 cmd=txtObj->setCounterCommand( &cursor, c ,KoTextDocument::HighlightSelection );
1990 if(cmd)
1991 macroCmd->addCommand(cmd);
1992 return macroCmd;
1993 }
1994 return 0L;
1995
1996}
1997
1998KCommand *KoAutoFormat::doUseNumberStyle(KoTextCursor * /*textEditCursor*/, KoTextParag *parag, KoTextObject *txtObj, int& index )
1999{
2000 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_FOOTNOTE )
2001 return 0L;
2002 KoTextDocument * textdoc = parag->textDocument();
2003 KoTextCursor cursor( parag->document() );
2004 KoTextString *s = parag->string();
2005 TQString word;
2006 for ( int i = 0 ; i < s->length() - 1; i++ )
2007 {
2008 TQChar ch = s->at( i ).c;
2009 if ( ch.isSpace() )
2010 break;
2011 word.append( ch );
2012 }
2013 TQChar punct=word[word.length()-1];
2014 if( punct.isPunct() )
2015 {
2016 TQString number=word.mid(0,word.length()-1);
2017 bool ok;
2018 uint val=number.toUInt(&ok);
2019 if( ok )
2020 {
2021 KMacroCommand *macroCmd = new KMacroCommand( i18n("Autocorrect (use number style)"));
2022 cursor.setParag( parag );
2023 cursor.setIndex( 0 );
2024 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2025 cursor.setParag( parag );
2026 cursor.setIndex( word.length()+1 );
2027 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2028 KCommand *cmd=txtObj->removeSelectedTextCommand( &cursor, KoTextDocument::HighlightSelection );
2029 // Adjust index
2030 index -= word.length()+1;
2031 if(cmd)
2032 macroCmd->addCommand(cmd);
2033
2034 // Apply counter to this paragraph
2035 cursor.setParag( parag );
2036 cursor.setIndex( 0 );
2037 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2038
2039 cursor.setIndex( 2 );
2040 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2041
2042 KoParagCounter c;
2043 c.setNumbering( KoParagCounter::NUM_LIST );
2044 c.setStyle( KoParagCounter::STYLE_NUM );
2045 c.setSuffix(TQString( punct ));
2046 c.setStartNumber( (int)val);
2047
2048 // Look at which number this parag will have without a restart counter flag,
2049 // to see if we need it. Thanks to Shaheed for number() taking a parag as param,
2050 // so that it works even if the parag doesn't have this counter yet!
2051 if ( c.number( parag ) != (int)val )
2052 c.setRestartCounter( true );
2053
2054 cmd=txtObj->setCounterCommand( &cursor, c, KoTextDocument::HighlightSelection );
2055 if( cmd)
2056 macroCmd->addCommand(cmd);
2057 // Apply counter to next paragraph too
2058 // but without restart
2059 c.setRestartCounter( false );
2060 cursor.setParag( parag->next() );
2061 cursor.setIndex( 0 );
2062 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2063 cursor.setIndex( 0 );
2064 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2065 cmd=txtObj->setCounterCommand( &cursor, c, KoTextDocument::HighlightSelection );
2066 if(cmd)
2067 macroCmd->addCommand(cmd);
2068 return macroCmd;
2069 }
2070 }
2071 return 0L;
2072}
2073
2074
2075KCommand * KoAutoFormat::doRemoveSpaceBeginEndLine( KoTextCursor *textEditCursor, KoTextParag *parag, KoTextObject *txtObj, int &index )
2076{
2077 KoTextString *s = parag->string();
2078 KoTextDocument * textdoc = parag->textDocument();
2079 KoTextCursor cursor( parag->document() );
2080
2081 KMacroCommand *macroCmd = 0L;
2082 // Cut away spaces at end of paragraph
2083 for ( int i = parag->lastCharPos(); i >= 0; --i )
2084 {
2085 TQChar ch = s->at( i ).c;
2086 if ( ch != ' ' ) // was: !ch.isSpace(), but this includes tabs, and this option is only about spaces
2087 {
2088 if( i == parag->lastCharPos() )
2089 break;
2090 cursor.setParag( parag );
2091 cursor.setIndex( i+1 );
2092 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2093 cursor.setParag( parag );
2094 cursor.setIndex( parag->lastCharPos()+1 );
2095 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2096 KCommand *cmd=txtObj->replaceSelectionCommand( &cursor, "", TQString(), KoTextDocument::HighlightSelection );
2097
2098 if(cmd)
2099 {
2100 if ( index > i )
2101 index = i;
2102 if ( !macroCmd )
2103 macroCmd = new KMacroCommand( i18n("Autocorrect (remove start and end line space)"));
2104 macroCmd->addCommand(cmd);
2105 }
2106 break;
2107 }
2108 }
2109
2110 // Cut away spaces at start of parag.
2111
2112 for ( int i = 0 ; i <= parag->lastCharPos() ; i++ )
2113 {
2114 TQChar ch = s->at( i ).c;
2115 if ( ch != ' ' ) // was: !ch.isSpace(), but this includes tabs, and this option is only about spaces
2116 {
2117 if( i == 0 )
2118 break;
2119
2120 cursor.setParag( parag );
2121 cursor.setIndex( 0 );
2122 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2123 cursor.setParag( parag );
2124 cursor.setIndex( i );
2125 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2126 KCommand *cmd=txtObj->replaceSelectionCommand( &cursor, "", TQString(), KoTextDocument::HighlightSelection );
2127
2128 if(cmd)
2129 {
2130 index -= i; // adjust index
2131 if ( !macroCmd )
2132 macroCmd = new KMacroCommand( i18n("Autocorrect (remove start and end line space)"));
2133 macroCmd->addCommand(cmd);
2134 }
2135 break;
2136 }
2137 }
2138
2139 if( macroCmd )
2140 {
2141 txtObj->emitHideCursor();
2142 textEditCursor->setParag( parag->next() );
2143 //textEditCursor->cursorgotoRight();
2144 txtObj->emitShowCursor();
2145 }
2146 return macroCmd;
2147}
2148
2149KCommand *KoAutoFormat::doCapitalizeNameOfDays( KoTextCursor* textEditCursor, KoTextParag *parag, int index, const TQString & word , KoTextObject *txtObj )
2150{
2151 //m_cacheNameOfDays
2152 //todo
2153 int pos = m_cacheNameOfDays.findIndex( word.lower() );
2154 if ( pos == -1 )
2155 return 0L;
2156 KoTextDocument * textdoc = parag->textDocument();
2157 TQString replaceStr= m_cacheNameOfDays[pos];
2158 int start = index - replaceStr.length();
2159 int length = replaceStr.length();
2160 if( word.at(0).isLetter() && word.at(0)==word.at(0).lower() )
2161 {
2162 KoTextCursor cursor( parag->document() );
2163 cursor.setParag( parag );
2164 cursor.setIndex( start );
2165 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2166 cursor.setIndex( start + length );
2167 TQString replacement = replaceStr.at(0).upper() + replaceStr.right( length-1 );
2168 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2169 TQString cmdName=i18n("Capitalize Name of Days");
2170 KCommand *cmd =txtObj->replaceSelectionCommand( textEditCursor, replacement,
2171 cmdName,
2172 KoTextDocument::HighlightSelection );
2173 txtObj->emitHideCursor();
2174 textEditCursor->gotoRight();
2175 txtObj->emitShowCursor();
2176 return cmd;
2177 }
2178 return 0L;
2179}
2180
2181KCommand *KoAutoFormat::doAutoSuperScript( KoTextCursor* textEditCursor, KoTextParag *parag, int index, const TQString & word , KoTextObject *txtObj )
2182{
2183 KoAutoFormatEntryMap::Iterator it = m_superScriptEntries.begin();
2184 bool found = false;
2185 TQString replace;
2186 for ( ; it != m_superScriptEntries.end() ; ++it )
2187 {
2188 if( it.key()==word)
2189 {
2190 replace = it.data().replace();
2191 found = true;
2192 break;
2193 }
2194 else if ( it.key()=="othernb")
2195 {
2196 TQString tmp = it.data().replace();
2197 int pos = word.find( tmp );
2198 if( pos != -1)
2199 {
2200 if( pos + tmp.length() == word.length())
2201 {
2202 bool ok;
2203 word.left( pos ).toInt( &ok);
2204 if( ok )
2205 {
2206 replace = tmp;
2207 found = true;
2208 break;
2209 }
2210 }
2211 }
2212 }
2213 }
2214 if (found )
2215 {
2216 KoTextDocument * textdoc = parag->textDocument();
2217
2218 int start = index - replace.length();
2219 KoTextFormat * lastFormat = parag->at( start )->format();
2220 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
2221 KoTextCursor cursor( parag->document() );
2222
2223 cursor.setParag( parag );
2224 cursor.setIndex( start );
2225 textdoc->setSelectionStart( KoTextDocument::HighlightSelection, &cursor );
2226 cursor.setIndex( start + word.length() -1 );
2227 textdoc->setSelectionEnd( KoTextDocument::HighlightSelection, &cursor );
2228 newFormat->setVAlign(KoTextFormat::AlignSuperScript);
2229 KCommand *cmd =txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::VAlign , false,KoTextDocument::HighlightSelection );
2230 textdoc->removeSelection( KoTextDocument::HighlightSelection );
2231
2232 return cmd;
2233 }
2234 return 0L;
2235}
2236
2237bool KoAutoFormat::doIgnoreDoubleSpace( KoTextParag *parag, int index, TQChar ch )
2238{
2239 if( m_ignoreDoubleSpace && ch==' ' && index >= 0 && !parag->hasAnySelection() )
2240 {
2241 KoTextString *s = parag->string();
2242 TQChar ch = s->at( index ).c;
2243 if ( ch==' ' )
2244 return true;
2245 }
2246 return false;
2247}
2248
2249void KoAutoFormat::configTypographicSimpleQuotes( TypographicQuotes _tq )
2250{
2251 m_typographicSimpleQuotes = _tq;
2252}
2253
2254void KoAutoFormat::configTypographicDoubleQuotes( TypographicQuotes _tq )
2255{
2256 m_typographicDoubleQuotes = _tq;
2257}
2258
2259void KoAutoFormat::configUpperCase( bool _uc )
2260{
2261 m_convertUpperCase = _uc;
2262}
2263
2264void KoAutoFormat::configUpperUpper( bool _uu )
2265{
2266 m_convertUpperUpper = _uu;
2267}
2268
2269void KoAutoFormat::configAdvancedAutocorrect( bool _aa )
2270{
2271 m_advancedAutoCorrect = _aa;
2272}
2273
2274void KoAutoFormat::configAutoDetectUrl(bool _au)
2275{
2276 m_autoDetectUrl=_au;
2277}
2278
2279void KoAutoFormat::configIgnoreDoubleSpace( bool _ids)
2280{
2281 m_ignoreDoubleSpace=_ids;
2282}
2283
2284void KoAutoFormat::configRemoveSpaceBeginEndLine( bool _space)
2285{
2286 m_removeSpaceBeginEndLine=_space;
2287}
2288
2289void KoAutoFormat::configUseBulletStyle( bool _ubs)
2290{
2291 m_useBulletStyle=_ubs;
2292}
2293
2294void KoAutoFormat::configBulletStyle( TQChar b )
2295{
2296 m_bulletStyle = b;
2297}
2298
2299void KoAutoFormat::configAutoChangeFormat( bool b)
2300{
2301 m_autoChangeFormat = b;
2302}
2303
2304
2305void KoAutoFormat::configAutoReplaceNumber( bool b )
2306{
2307 m_autoReplaceNumber = b;
2308}
2309
2310void KoAutoFormat::configAutoNumberStyle( bool b )
2311{
2312 m_useAutoNumberStyle = b;
2313}
2314
2315void KoAutoFormat::configCompletion( bool b )
2316{
2317 m_completion = b;
2318}
2319
2320void KoAutoFormat::configToolTipCompletion( bool b )
2321{
2322 m_toolTipCompletion = b;
2323 if (!b && m_completionBox)
2324 {
2325 delete m_completionBox;
2326 m_completionBox = 0;
2327 }
2328}
2329
2330void KoAutoFormat::configKeyCompletionAction( KeyCompletionAction action )
2331{
2332 m_keyCompletionAction = action;
2333}
2334
2335void KoAutoFormat::configAppendSpace( bool b)
2336{
2337 m_completionAppendSpace= b;
2338}
2339
2340void KoAutoFormat::configMinWordLength( uint val )
2341{
2342 m_minCompletionWordLength = val;
2343}
2344
2345void KoAutoFormat::configNbMaxCompletionWord( uint val )
2346{
2347 m_nbMaxCompletionWord = val;
2348}
2349
2350
2351void KoAutoFormat::configAddCompletionWord( bool b )
2352{
2353 m_addCompletionWord= b;
2354}
2355
2356bool KoAutoFormat::isUpper( const TQChar &c )
2357{
2358 return c.lower() != c;
2359}
2360
2361bool KoAutoFormat::isLower( const TQChar &c )
2362{
2363 // Note that this is not the same as !isUpper !
2364 // For instance '1' is not lower nor upper,
2365 return c.upper() != c;
2366}
2367
2368bool KoAutoFormat::isMark( const TQChar &c )
2369{
2370 return ( c == TQChar( '.' ) ||
2371 c == TQChar( '?' ) ||
2372 c == TQChar( '!' ) );
2373}
2374
2375bool KoAutoFormat::isSeparator( const TQChar &c )
2376{
2377 return ( !c.isLetter() && !c.isNumber() && !c.isDigit() );
2378}
2379
2380void KoAutoFormat::buildMaxLen()
2381{
2382 m_maxFindLength = 0;
2383 TQDictIterator<KoAutoFormatEntry> it( m_entries );
2384 for( ; it.current(); ++it )
2385 {
2386 m_maxFindLength = TQMAX( m_maxFindLength, it.currentKey().length() );
2387 }
2388 TQDictIterator<KoAutoFormatEntry> it2( m_allLanguages );
2389 for( ; it2.current(); ++it2 )
2390 {
2391 m_maxFindLength = TQMAX( m_maxFindLength, it2.currentKey().length() );
2392 }
2393}
2394
2395TQStringList KoAutoFormat::listCompletion() const
2396{
2397 return m_listCompletion->items();
2398}
2399
2400
2401void KoAutoFormat::configIncludeTwoUpperUpperLetterException( bool b)
2402{
2403 m_includeTwoUpperLetterException = b;
2404}
2405
2406void KoAutoFormat::configIncludeAbbreviation( bool b )
2407{
2408 m_includeAbbreviation = b;
2409}
2410
2411void KoAutoFormat::configAutoSuperScript( bool b )
2412{
2413 m_bAutoSuperScript = b;
2414}
2415
2416void KoAutoFormat::configCorrectionWithFormat( bool b)
2417{
2418 m_bAutoCorrectionWithFormat = b;
2419}
2420
2421void KoAutoFormat::configCapitalizeNameOfDays( bool b)
2422{
2423 m_bCapitalizeNameOfDays = b;
2424}
2425
2426void KoAutoFormat::configAutoFormatLanguage( const TQString &_lang)
2427{
2428 m_autoFormatLanguage=_lang;
2429}
2430
2431KCommand *KoAutoFormat::applyAutoFormat( KoTextObject * obj )
2432{
2433 KoTextParag * parag = obj->textDocument()->firstParag();
2434 KoTextCursor *cursor = new KoTextCursor( obj->textDocument() );
2435 KMacroCommand *macro = 0L;
2436 while ( parag )
2437 {
2438 cursor->setIndex(0);
2439 for (int i=0;i<parag->length();i++)
2440 {
2441 cursor->gotoRight();
2442 //kdDebug() << "ch:" << parag->string()->at(i).c << endl;
2443 if (i == parag->length()-1)
2444 doAutoFormat(cursor,parag,i,'\n',obj);
2445 else
2446 doAutoFormat(cursor,parag,i, parag->string()->at(i).c,obj);
2447 }
2448 parag = parag->next();
2449
2450 }
2451 delete cursor;
2452 return macro;
2453}
2454
2455void KoAutoFormat::changeTextFormat(KoSearchContext *formatOptions, KoTextFormat * format, int & flags )
2456{
2457 if (formatOptions )
2458 {
2459 if (formatOptions->m_optionsMask & KoSearchContext::Bold)
2460 {
2461 format->setBold( formatOptions->m_options & KoSearchContext::Bold);
2462 flags |=KoTextFormat::Bold;
2463 }
2464 if ( formatOptions->m_optionsMask & KoSearchContext::Size)
2465 {
2466 format->setPointSize( formatOptions->m_size );
2467 flags |=KoTextFormat::Size;
2468 }
2469 if ( formatOptions->m_optionsMask & KoSearchContext::Family)
2470 {
2471 format->setFamily( formatOptions->m_family );
2472 flags |=KoTextFormat::Family;
2473 }
2474 if ( formatOptions->m_optionsMask & KoSearchContext::Color)
2475 {
2476 format->setColor(formatOptions->m_color);
2477 flags |=KoTextFormat::Color;
2478 }
2479 if ( formatOptions->m_optionsMask & KoSearchContext::BgColor)
2480 {
2481 format->setTextBackgroundColor(formatOptions->m_backGroundColor);
2482 flags |=KoTextFormat::TextBackgroundColor;
2483 }
2484
2485 if ( formatOptions->m_optionsMask & KoSearchContext::Italic)
2486 {
2487 format->setItalic( formatOptions->m_options & KoSearchContext::Italic);
2488 flags |=KoTextFormat::Italic;
2489 }
2490 if ( formatOptions->m_optionsMask & KoSearchContext::WordByWord)
2491 {
2492 format->setWordByWord( formatOptions->m_options & KoSearchContext::WordByWord );
2493 flags |=KoTextFormat::WordByWord;
2494 }
2495 if ( formatOptions->m_optionsMask & KoSearchContext::Shadow)
2496 {
2497 if ( formatOptions->m_options & KoSearchContext::Shadow )
2498 format->setShadow( 1, 1, TQt::gray );
2499 else
2500 format->setShadow( 0, 0, TQColor() );
2501 flags |=KoTextFormat::ShadowText;
2502 }
2503
2504 if ( formatOptions->m_optionsMask & KoSearchContext::Underline)
2505 {
2506 format->setUnderlineType(formatOptions->m_underline);
2507 flags |=KoTextFormat::ExtendUnderLine;
2508 }
2509 if ( formatOptions->m_optionsMask & KoSearchContext::StrikeOut)
2510 {
2511 format->setStrikeOutType(formatOptions->m_strikeOut);
2512 flags |= KoTextFormat::StrikeOut;
2513 }
2514 if ( formatOptions->m_optionsMask & KoSearchContext::VertAlign)
2515 {
2516 format->setVAlign(formatOptions->m_vertAlign);
2517 flags |=KoTextFormat::VAlign;
2518 }
2519 if ( formatOptions->m_optionsMask & KoSearchContext::Attribute)
2520 {
2521 format->setAttributeFont(formatOptions->m_attribute);
2522 flags |= KoTextFormat::Attribute;
2523 }
2524 if (formatOptions->m_optionsMask & KoSearchContext::Language)
2525 {
2526 flags |= KoTextFormat::Language;
2527 format->setLanguage( formatOptions->m_language );
2528 }
2529 }
2530}
2531
2532#include "KoAutoFormat.moc"
void addCommand(KCommand *command)
The KOffice document class.
Definition KoDocument.h:61
Numbering numbering() const
Numbering type and style.
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
Each character (KoTextStringChar) points to a KoTextFormat that defines the formatting of that charac...
The KoTextObject is the high-level object that contains a KoTextDocument (the list of paragraphs),...
void insert(KoTextCursor *cursor, KoTextFormat *currentFormat, const TQString &text, const TQString &commandName, KoTextDocument::SelectionId selectionId=KoTextDocument::Standard, int insertFlags=DefaultInsertFlags, CustomItemsMap customItemsMap=CustomItemsMap())
The main "insert" method, including undo/redo creation/update.
KoTextDocument * textDocument() const
Return the text document contained in this KoTextObject.
KCommand * setFormatCommand(const KoTextFormat *format, int flags, bool zoomFont=false)
Implementation of setFormatCommand from KoTextFormatInterface - apply change to the whole document.
The collection of formats for variables.
Definition KoVariable.h:263
TDEAction * action(StdAction act_enum, const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0L)
TDEAction * replace(const TQObject *recvr, const char *slot, TDEActionCollection *parent, const char *name=0)
const char * name(StdAction id)