00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "koAutoFormat.h"
00022
00023 #include "kotextobject.h"
00024 #include "kotextparag.h"
00025 #include "kovariable.h"
00026 #include "koparagcounter.h"
00027 #include <koDocument.h>
00028 #include <koSearchDia.h>
00029 #include <kozoomhandler.h>
00030 #include <koGlobal.h>
00031
00032 #include <kdeversion.h>
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kinstance.h>
00036 #include <kconfig.h>
00037 #include <kstandarddirs.h>
00038 #include <kglobal.h>
00039 #include <kcommand.h>
00040
00041 #include <kcompletion.h>
00042 #include <kcalendarsystem.h>
00043
00044 #include <qfile.h>
00045 #include <qlabel.h>
00046 #include <qtooltip.h>
00047 #include <qwhatsthis.h>
00048 #include <qdom.h>
00049 #include <qregexp.h>
00050
00051
00052 KoCompletionBox::KoCompletionBox( QWidget * parent, const char * name, WFlags f)
00053 : QLabel(parent,name,f)
00054 {
00055 setBackgroundColor(QColor("#FFFFE6"));
00056 setFocusPolicy(QWidget::NoFocus);
00057 setFrameShape(QFrame::Box);
00058 }
00059
00060 KoCompletionBox::~KoCompletionBox()
00061 {
00062 }
00063
00064 void KoCompletionBox::mousePressEvent( QMouseEvent *)
00065 {
00066 hide();
00067 }
00068
00069 QString& KoCompletionBox::lastWord()
00070 {
00071 return m_lastWord;
00072 }
00073
00074 void KoCompletionBox::setLastWord( QString const &lastword)
00075 {
00076 m_lastWord = lastword;
00077 }
00078
00079 KoAutoFormatEntry::KoAutoFormatEntry(const QString& replace)
00080 : m_replace( replace )
00081 {
00082 m_formatOptions= 0L;
00083 }
00084
00085 KoAutoFormatEntry::~KoAutoFormatEntry()
00086 {
00087 delete m_formatOptions;
00088 m_formatOptions=0L;
00089 }
00090
00091 KoSearchContext *KoAutoFormatEntry::formatEntryContext() const
00092 {
00093 return m_formatOptions;
00094 }
00095
00096 void KoAutoFormatEntry::createNewEntryContext()
00097 {
00098 if ( !m_formatOptions )
00099 {
00100 m_formatOptions = new KoSearchContext();
00101 }
00102 }
00103
00104 void KoAutoFormatEntry::setFormatEntryContext( KoSearchContext *_cont )
00105 {
00106 delete m_formatOptions;
00107 m_formatOptions=_cont;
00108 }
00109
00110 void KoAutoFormatEntry::clearFormatEntryContext( )
00111 {
00112 delete m_formatOptions;
00113 m_formatOptions = 0L;
00114 }
00115
00116
00117
00118
00119
00120 KoAutoFormat::KoAutoFormat( KoDocument *_doc, KoVariableCollection *_varCollection, KoVariableFormatCollection *_varFormatCollection )
00121 : m_doc( _doc ),
00122 m_varCollection(_varCollection),
00123 m_varFormatCollection(_varFormatCollection),
00124 m_autoFormatLanguage( QString::null),
00125 m_configRead( false ),
00126 m_convertUpperCase( false ), m_convertUpperUpper( false ),
00127 m_advancedAutoCorrect( true ),
00128 m_autoDetectUrl( false ),
00129 m_ignoreDoubleSpace( false ),
00130 m_removeSpaceBeginEndLine( false ),
00131 m_useBulletStyle(false),
00132 m_autoChangeFormat(false),
00133 m_autoReplaceNumber(false),
00134 m_useAutoNumberStyle(false),
00135 m_completion(false),
00136 m_toolTipCompletion(false),
00137 m_completionAppendSpace(false),
00138 m_addCompletionWord(true),
00139 m_includeTwoUpperLetterException(false),
00140 m_includeAbbreviation(false),
00141 m_ignoreUpperCase(false),
00142 m_bAutoFormatActive(true),
00143 m_bAutoSuperScript( false ),
00144 m_bAutoCorrectionWithFormat( false ),
00145 m_bCapitalizeNameOfDays( false ),
00146 m_wordInserted( false ),
00147 m_bulletStyle(),
00148 m_typographicSimpleQuotes(),
00149 m_typographicDoubleQuotes(),
00150 m_typographicDefaultDoubleQuotes(),
00151 m_typographicDefaultSimpleQuotes(),
00152 m_listCompletion( new KCompletion ),
00153 m_entries(17,false),
00154 m_allLanguages(17,false),
00155 m_superScriptEntries(),
00156 m_upperCaseExceptions(),
00157 m_twoUpperLetterException(),
00158 m_maxFindLength( 0 ),
00159 m_minCompletionWordLength( 5 ),
00160 m_nbMaxCompletionWord( 500 ),
00161 m_countMaxWords(0),
00162 m_completionBox(0),
00163 m_keyCompletionAction( Enter )
00164
00165 {
00166
00167 loadListOfWordCompletion();
00168 m_listCompletion->setIgnoreCase( true );
00169 updateMaxWords();
00170 KLocale klocale(m_doc->instance()->instanceName());
00171 for (int i = 1; i <=7; i++)
00172 {
00173 m_cacheNameOfDays.append(klocale.calendar()->weekDayName( i ).lower());
00174 }
00175 }
00176
00177 KoAutoFormat::KoAutoFormat( const KoAutoFormat& format )
00178 : m_doc( format.m_doc ),
00179 m_varCollection( format.m_varCollection ),
00180 m_varFormatCollection( format.m_varFormatCollection ),
00181 m_autoFormatLanguage( format.m_autoFormatLanguage),
00182 m_configRead( format.m_configRead ),
00183 m_convertUpperCase( format.m_convertUpperCase ),
00184 m_convertUpperUpper( format.m_convertUpperUpper ),
00185 m_advancedAutoCorrect( format.m_advancedAutoCorrect ),
00186 m_autoDetectUrl( format.m_autoDetectUrl ),
00187 m_ignoreDoubleSpace( format.m_ignoreDoubleSpace ),
00188 m_removeSpaceBeginEndLine( format.m_removeSpaceBeginEndLine ),
00189 m_useBulletStyle( format.m_useBulletStyle ),
00190 m_autoChangeFormat( format.m_autoChangeFormat ),
00191 m_autoReplaceNumber( format.m_autoReplaceNumber ),
00192 m_useAutoNumberStyle( format.m_useAutoNumberStyle ),
00193 m_completion( format.m_completion ),
00194 m_toolTipCompletion( format.m_toolTipCompletion),
00195 m_completionAppendSpace( format.m_completionAppendSpace ),
00196 m_addCompletionWord( format.m_addCompletionWord ),
00197 m_includeTwoUpperLetterException( format.m_includeTwoUpperLetterException ),
00198 m_includeAbbreviation( format.m_includeAbbreviation ),
00199 m_ignoreUpperCase( format.m_ignoreUpperCase ),
00200 m_bAutoFormatActive( format.m_bAutoFormatActive ),
00201 m_bAutoSuperScript( format.m_bAutoSuperScript ),
00202 m_bAutoCorrectionWithFormat( format.m_bAutoCorrectionWithFormat),
00203 m_bCapitalizeNameOfDays( format.m_bCapitalizeNameOfDays),
00204 m_bulletStyle( format.m_bulletStyle ),
00205 m_typographicSimpleQuotes( format.m_typographicSimpleQuotes ),
00206 m_typographicDoubleQuotes( format.m_typographicDoubleQuotes ),
00207 m_typographicDefaultDoubleQuotes( format.m_typographicDefaultDoubleQuotes),
00208 m_typographicDefaultSimpleQuotes( format.m_typographicDefaultSimpleQuotes),
00209 m_listCompletion( 0L ),
00210 m_entries(17,false ),
00211 m_allLanguages(17,false),
00212 m_superScriptEntries ( format.m_superScriptEntries ),
00213 m_upperCaseExceptions( format.m_upperCaseExceptions ),
00214 m_twoUpperLetterException( format.m_twoUpperLetterException ),
00215 m_maxFindLength( format.m_maxFindLength ),
00216 m_minCompletionWordLength( format.m_minCompletionWordLength ),
00217 m_nbMaxCompletionWord( format.m_nbMaxCompletionWord ),
00218 m_cacheNameOfDays( format.m_cacheNameOfDays),
00219 m_completionBox(0),
00220 m_keyCompletionAction( format.m_keyCompletionAction )
00221 {
00222
00223
00224
00225 }
00226
00227 KoAutoFormat::~KoAutoFormat()
00228 {
00229 delete m_listCompletion;
00230 m_entries.setAutoDelete( true );
00231 m_entries.clear();
00232 m_allLanguages.setAutoDelete( true );
00233 m_allLanguages.clear();
00234 }
00235
00236 void KoAutoFormat::updateMaxWords()
00237 {
00238 QStringList list = m_listCompletion->items();
00239 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it )
00240 {
00241 QString tmp = *it;
00242 uint maxword = 1;
00243
00244 for (uint i=0; i < (uint)tmp.length(); i++)
00245 if ( tmp.at(i).isSpace() || tmp.at(i).isPunct() )
00246 maxword++;
00247 if (maxword > m_countMaxWords )
00248 m_countMaxWords = maxword;
00249 }
00250 kdDebug() << "m_countMaxWords: " << m_countMaxWords << endl;
00251 }
00252
00253 void KoAutoFormat::loadListOfWordCompletion()
00254 {
00255 KConfig* config = KoGlobal::kofficeConfig();
00256 KConfigGroupSaver cgs( config, "Completion Word" );
00257 m_listCompletion->insertItems(config->readListEntry( "list" ));
00258 }
00259
00260 void KoAutoFormat::readConfig(bool force)
00261 {
00262
00263
00264
00265 if ( m_configRead && !force )
00266 return;
00267 KConfig* config = KoGlobal::kofficeConfig();
00268 KConfigGroupSaver cgs( config, "AutoFormat" );
00269
00270 if ( !force)
00271 m_autoFormatLanguage = config->readEntry("formatLanguage", QString::null);
00272
00273 m_convertUpperCase = config->readBoolEntry( "ConvertUpperCase", false );
00274 m_convertUpperUpper = config->readBoolEntry( "ConvertUpperUpper", false );
00275 m_includeTwoUpperLetterException = config->readBoolEntry( "includeTwoLetterException", false );
00276 m_includeAbbreviation = config->readBoolEntry( "includeAbbreviation", false );
00277
00278 m_advancedAutoCorrect = config->readBoolEntry( "AdvancedAutocorrect", true );
00279 m_bAutoCorrectionWithFormat = config->readBoolEntry( "AutoCorrectionWithFormat",false );
00280 m_bCapitalizeNameOfDays = config->readBoolEntry( "CapitalizeNameOfDays",false );
00281
00282 m_autoDetectUrl = config->readBoolEntry("AutoDetectUrl",false);
00283 m_ignoreDoubleSpace = config->readBoolEntry("IgnoreDoubleSpace",false);
00284 m_removeSpaceBeginEndLine = config->readBoolEntry("RemoveSpaceBeginEndLine",false);
00285
00286 m_useBulletStyle = config->readBoolEntry("UseBulletStyle",false);
00287 QString tmp = config->readEntry( "BulletStyle", "" );
00288 m_bulletStyle = tmp.isEmpty() ? QChar() : tmp[0];
00289
00290 m_autoChangeFormat = config->readBoolEntry( "AutoChangeFormat", false );
00291
00292 m_autoReplaceNumber = config->readBoolEntry( "AutoReplaceNumber", false );
00293
00294 m_useAutoNumberStyle = config->readBoolEntry( "AutoNumberStyle", false );
00295
00296
00297 QString beginDoubleQuote = config->readEntry( "TypographicQuotesBegin" );
00298 QString endDoubleQuote = config->readEntry( "TypographicQuotesEnd" );
00299
00300 m_typographicDoubleQuotes.replace = config->readBoolEntry( "TypographicQuotesEnabled", false );
00301
00302 QString begin = config->readEntry( "TypographicSimpleQuotesBegin" );
00303 QString end = config->readEntry( "TypographicSimpleQuotesEnd" );
00304 m_typographicSimpleQuotes.replace = config->readBoolEntry( "TypographicSimpleQuotesEnabled", false );
00305
00306 m_bAutoSuperScript = config->readBoolEntry( "AutoSuperScript", false );
00307
00308 config->setGroup( "completion" );
00309 m_completion = config->readBoolEntry( "completion", false );
00310
00311 m_completionAppendSpace = config->readBoolEntry( "CompletionAppendSpace", false );
00312 m_minCompletionWordLength = config->readUnsignedNumEntry( "CompletionMinWordLength", 5 );
00313 m_nbMaxCompletionWord = config->readUnsignedNumEntry( "NbMaxCompletionWord", 100 );
00314 m_addCompletionWord = config->readBoolEntry( "AddCompletionWord", true );
00315 m_toolTipCompletion = config->readBoolEntry( "ToolTipCompletion", true );
00316 m_keyCompletionAction = ( KoAutoFormat::KeyCompletionAction )config->readUnsignedNumEntry( "CompletionKeyAction", 0 );
00317
00318 if ( force )
00319 {
00320 m_entries.setAutoDelete(true);
00321 m_entries.clear();
00322 m_entries.setAutoDelete(false);
00323 m_allLanguages.setAutoDelete(true);
00324 m_allLanguages.clear();
00325 m_allLanguages.setAutoDelete(false);
00326 m_upperCaseExceptions.clear();
00327 m_superScriptEntries.clear();
00328 m_twoUpperLetterException.clear();
00329
00330 }
00331
00332
00333
00334 readAutoCorrectConfig();
00335
00336 if( beginDoubleQuote.isEmpty())
00337 {
00338 if( m_typographicDefaultDoubleQuotes.begin.isNull())
00339 m_typographicDoubleQuotes.begin = QChar('«');
00340 else
00341 m_typographicDoubleQuotes.begin = m_typographicDefaultDoubleQuotes.begin;
00342 }
00343 else
00344 m_typographicDoubleQuotes.begin = beginDoubleQuote[0];
00345
00346 if( endDoubleQuote.isEmpty() )
00347 {
00348 if( m_typographicDefaultDoubleQuotes.end.isNull())
00349 m_typographicDoubleQuotes.end = QChar('»');
00350 else
00351 m_typographicDoubleQuotes.end = m_typographicDefaultDoubleQuotes.end;
00352 }
00353 else
00354 m_typographicDoubleQuotes.end = endDoubleQuote[0];
00355
00356 m_typographicDoubleQuotes.replace = m_typographicDoubleQuotes.replace
00357 && !m_typographicDoubleQuotes.begin.isNull()
00358 && !m_typographicDoubleQuotes.end.isNull();
00359
00360
00361 if( begin.isEmpty())
00362 {
00363 if( m_typographicDefaultSimpleQuotes.begin.isNull())
00364 m_typographicSimpleQuotes.begin = QChar('\'');
00365 else
00366 m_typographicSimpleQuotes.begin = m_typographicDefaultSimpleQuotes.begin;
00367 }
00368 else
00369 m_typographicSimpleQuotes.begin = begin[0];
00370
00371 if( end.isEmpty() )
00372 {
00373 if( m_typographicDefaultSimpleQuotes.end.isNull())
00374 m_typographicSimpleQuotes.end = QChar('\'');
00375 else
00376 m_typographicSimpleQuotes.end = m_typographicDefaultSimpleQuotes.end;
00377 }
00378 else
00379 m_typographicSimpleQuotes.end = end[0];
00380
00381 m_typographicSimpleQuotes.replace = m_typographicSimpleQuotes.replace
00382 && !m_typographicSimpleQuotes.end.isNull()
00383 && !m_typographicSimpleQuotes.begin.isNull();
00384
00385
00386 loadAllLanguagesAutoCorrection();
00387 buildMaxLen();
00388 autoFormatIsActive();
00389 m_configRead = true;
00390 }
00391
00392 void KoAutoFormat::readAutoCorrectConfig()
00393 {
00394 Q_ASSERT( m_entries.isEmpty() );
00395 KLocale klocale(m_doc->instance()->instanceName());
00396 QString kdelang = klocale.languageList().front();
00397 kdelang.remove( QRegExp( "@.*" ) );
00398 kdDebug(32500) << "KoAutoFormat: m_autoFormatLanguage=" << m_autoFormatLanguage << " kdelang=" << kdelang << endl;
00399 QString fname;
00400 if ( !m_autoFormatLanguage.isEmpty() )
00401 {
00402 fname = locate( "data", "koffice/autocorrect/" + m_autoFormatLanguage + ".xml", m_doc->instance() );
00403 }
00404 if ( m_autoFormatLanguage != "all_languages" )
00405 {
00406 if ( fname.isEmpty() && !kdelang.isEmpty() )
00407 fname = locate( "data", "koffice/autocorrect/" + kdelang + ".xml", m_doc->instance() );
00408 if ( fname.isEmpty() && kdelang.contains("_") )
00409 {
00410 kdelang.remove( QRegExp( "_.*" ) );
00411 fname = locate( "data", "koffice/autocorrect/" + kdelang + ".xml", m_doc->instance() );
00412 }
00413 if ( fname.isEmpty() )
00414 fname = locate( "data", "koffice/autocorrect/autocorrect.xml", m_doc->instance() );
00415 }
00416 if ( fname.isEmpty() )
00417 return;
00418 QFile xmlFile(fname);
00419 if(!xmlFile.open(IO_ReadOnly))
00420 return;
00421
00422 QDomDocument doc;
00423 if(!doc.setContent(&xmlFile))
00424 return;
00425
00426 if(doc.doctype().name() != "autocorrection") {
00427
00428 }
00429 QDomElement de=doc.documentElement();
00430
00431 loadAutoCorrection( de );
00432
00433 QDomElement upper = de.namedItem( "UpperCaseExceptions" ).toElement();
00434 if(!upper.isNull())
00435 {
00436 QDomNodeList nl = upper.childNodes();
00437 for(uint i = 0; i < nl.count(); i++)
00438 {
00439 m_upperCaseExceptions+= nl.item(i).toElement().attribute("exception");
00440 }
00441 }
00442
00443 QDomElement twoUpper = de.namedItem( "TwoUpperLetterExceptions" ).toElement();
00444 if(!twoUpper.isNull())
00445 {
00446 QDomNodeList nl = twoUpper.childNodes();
00447 for(uint i = 0; i < nl.count(); i++)
00448 {
00449 m_twoUpperLetterException+= nl.item(i).toElement().attribute("exception");
00450 }
00451 }
00452
00453 QDomElement superScript = de.namedItem( "SuperScript" ).toElement();
00454 if(!superScript.isNull())
00455 {
00456 QDomNodeList nl = superScript.childNodes();
00457 for(uint i = 0; i < nl.count() ; i++) {
00458
00459
00460 m_superScriptEntries.insert( nl.item(i).toElement().attribute("find"), KoAutoFormatEntry(nl.item(i).toElement().attribute("super")),FALSE );
00461 }
00462 }
00463
00464 QDomElement doubleQuote = de.namedItem( "DoubleQuote" ).toElement();
00465 if(!doubleQuote.isNull())
00466 {
00467 QDomElement childItem = doubleQuote.namedItem("doublequote").toElement();
00468 if ( !childItem.isNull() )
00469 {
00470 QString attr = childItem.attribute( "begin" );
00471 if ( !attr.isEmpty() && attr[0] != 0 )
00472 m_typographicDefaultDoubleQuotes.begin = attr[0];
00473 attr = childItem.attribute( "end" );
00474 if ( !attr.isEmpty() && attr[0] != 0 )
00475 m_typographicDefaultDoubleQuotes.end = attr[0];
00476 }
00477 }
00478 QDomElement simpleQuote = de.namedItem( "SimpleQuote" ).toElement();
00479 if(!simpleQuote.isNull())
00480 {
00481 QDomElement childItem = simpleQuote.namedItem("simplequote").toElement();
00482 if ( !childItem.isNull() )
00483 {
00484 QString attr = childItem.attribute( "begin" );
00485 if ( !attr.isEmpty() && attr[0] != 0 )
00486 m_typographicDefaultSimpleQuotes.begin = attr[0];
00487 attr = childItem.attribute( "end" );
00488 if ( !attr.isEmpty() && attr[0] != 0 )
00489 m_typographicDefaultSimpleQuotes.end = attr[0];
00490 }
00491 }
00492 }
00493
00494 void KoAutoFormat::loadAllLanguagesAutoCorrection()
00495 {
00496 QString fname = locate( "data", "koffice/autocorrect/all_languages.xml", m_doc->instance() );
00497 if ( fname.isEmpty() )
00498 return;
00499 QFile xmlFile( fname );
00500 if(xmlFile.open(IO_ReadOnly))
00501 {
00502 QDomDocument doc;
00503 if(!doc.setContent(&xmlFile)) {
00504 return;
00505 }
00506 if(doc.doctype().name() != "autocorrection") {
00507
00508 }
00509 QDomElement de=doc.documentElement();
00510
00511 loadAutoCorrection( de, true );
00512 xmlFile.close();
00513 }
00514 }
00515
00516 void KoAutoFormat::loadAutoCorrection( const QDomElement & _de, bool _allLanguages )
00517 {
00518 QDomElement item = _de.namedItem( "items" ).toElement();
00519 if(!item.isNull())
00520 {
00521 QDomNodeList nl = item.childNodes();
00522 m_maxFindLength=nl.count();
00523 for(uint i = 0; i < m_maxFindLength; i++) {
00524 loadEntry( nl.item(i).toElement(), _allLanguages);
00525 }
00526 }
00527 }
00528
00529 void KoAutoFormat::loadEntry( const QDomElement &nl, bool _allLanguages)
00530 {
00531 KoAutoFormatEntry *tmp =new KoAutoFormatEntry(nl.attribute("replace"));
00532 if ( nl.hasAttribute("FONT"))
00533 {
00534 tmp->createNewEntryContext();
00535 tmp->formatEntryContext()->m_family=nl.attribute("FONT");
00536 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Family;
00537 }
00538 if ( nl.hasAttribute("SIZE" ))
00539 {
00540 tmp->createNewEntryContext();
00541 tmp->formatEntryContext()->m_size = nl.attribute("SIZE" ).toInt();
00542 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Size;
00543 }
00544 if (nl.hasAttribute("BOLD" ))
00545 {
00546 tmp->createNewEntryContext();
00547 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Bold;
00548 QString value = nl.attribute("BOLD");
00549 if ( value.toInt() == 1 )
00550 tmp->formatEntryContext()->m_options |= KoSearchContext::Bold;
00551 }
00552 if (nl.hasAttribute("ITALIC" ))
00553 {
00554 tmp->createNewEntryContext();
00555 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Italic;
00556 QString value = nl.attribute("ITALIC");
00557 if ( value.toInt() == 1 )
00558 tmp->formatEntryContext()->m_options |= KoSearchContext::Italic;
00559 }
00560 if (nl.hasAttribute("UNDERLINE" ))
00561 {
00562 tmp->createNewEntryContext();
00563 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Underline;
00564 QString value = nl.attribute("UNDERLINE");
00565 if ( value =="single" )
00566 tmp->formatEntryContext()->m_underline = KoTextFormat::U_SIMPLE;
00567 else if ( value =="double" )
00568 tmp->formatEntryContext()->m_underline = KoTextFormat::U_DOUBLE;
00569 else if ( value =="single-bold" )
00570 tmp->formatEntryContext()->m_underline = KoTextFormat::U_SIMPLE_BOLD;
00571 else
00572 tmp->formatEntryContext()->m_underline = KoTextFormat::U_NONE;
00573 }
00574 if (nl.hasAttribute("STRIKEOUT" ))
00575 {
00576 tmp->createNewEntryContext();
00577 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::StrikeOut;
00578 QString value = nl.attribute("STRIKEOUT");
00579 if ( value =="single" )
00580 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_SIMPLE;
00581 else if ( value =="double" )
00582 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_DOUBLE;
00583 else if ( value =="single-bold" )
00584 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_SIMPLE_BOLD;
00585 else
00586 tmp->formatEntryContext()->m_strikeOut = KoTextFormat::S_NONE;
00587 }
00588 if (nl.hasAttribute("VERTALIGN" ))
00589 {
00590 tmp->createNewEntryContext();
00591 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::VertAlign;
00592 QString value = nl.attribute("VERTALIGN");
00593 tmp->formatEntryContext()->m_vertAlign=static_cast<KoTextFormat::VerticalAlignment>( value.toInt() );
00594
00595 }
00596 if ( nl.hasAttribute("TEXTCOLOR" ))
00597 {
00598 tmp->createNewEntryContext();
00599 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::Color;
00600 QColor col( nl.attribute("TEXTCOLOR" ));
00601 tmp->formatEntryContext()->m_color = col;
00602 }
00603 if ( nl.hasAttribute("TEXTBGCOLOR" ))
00604 {
00605 tmp->createNewEntryContext();
00606 tmp->formatEntryContext()->m_optionsMask |= KoSearchContext::BgColor;
00607 QColor col( nl.attribute("TEXTBGCOLOR" ));
00608 tmp->formatEntryContext()->m_backGroundColor = col;
00609 }
00610 if ( !_allLanguages )
00611 m_entries.insert( nl.attribute("find"), tmp );
00612 else
00613 m_allLanguages.insert( nl.attribute("find"), tmp );
00614
00615 }
00616
00617 void KoAutoFormat::saveConfig()
00618 {
00619 KConfig* config = KoGlobal::kofficeConfig();
00620 KLocale klocale(m_doc->instance()->instanceName());
00621
00622 KConfigGroupSaver cgs( config, "AutoFormat" );
00623 config->writeEntry( "ConvertUpperCase", m_convertUpperCase );
00624 config->writeEntry( "formatLanguage", m_autoFormatLanguage=="all_languages" ? klocale.languageList().front() : m_autoFormatLanguage);
00625
00626 config->writeEntry( "ConvertUpperUpper", m_convertUpperUpper );
00627 config->writeEntry( "includeTwoLetterException", m_includeTwoUpperLetterException );
00628 config->writeEntry( "includeAbbreviation", m_includeAbbreviation );
00629
00630 config->writeEntry( "TypographicQuotesBegin", QString( m_typographicDoubleQuotes.begin ) );
00631 config->writeEntry( "TypographicQuotesEnd", QString( m_typographicDoubleQuotes.end ) );
00632 config->writeEntry( "TypographicQuotesEnabled", m_typographicDoubleQuotes.replace );
00633 config->writeEntry( "TypographicSimpleQuotesBegin", QString( m_typographicSimpleQuotes.begin ) );
00634 config->writeEntry( "TypographicSimpleQuotesEnd", QString( m_typographicSimpleQuotes.end ) );
00635 config->writeEntry( "TypographicSimpleQuotesEnabled", m_typographicSimpleQuotes.replace );
00636
00637 config->writeEntry( "AdvancedAutocorrect", m_advancedAutoCorrect );
00638 config->writeEntry( "AutoCorrectionWithFormat", m_bAutoCorrectionWithFormat );
00639 config->writeEntry( "CapitalizeNameOfDays", m_bCapitalizeNameOfDays );
00640
00641 config->writeEntry( "AutoDetectUrl",m_autoDetectUrl);
00642
00643 config->writeEntry( "IgnoreDoubleSpace",m_ignoreDoubleSpace );
00644 config->writeEntry( "RemoveSpaceBeginEndLine",m_removeSpaceBeginEndLine );
00645
00646 config->writeEntry( "UseBulletStyle", m_useBulletStyle);
00647 config->writeEntry( "BulletStyle", QString(m_bulletStyle));
00648
00649 config->writeEntry( "AutoChangeFormat", m_autoChangeFormat);
00650
00651 config->writeEntry( "AutoReplaceNumber", m_autoReplaceNumber);
00652
00653 config->writeEntry( "AutoNumberStyle", m_useAutoNumberStyle );
00654
00655 config->writeEntry( "AutoSuperScript", m_bAutoSuperScript );
00656
00657 config->setGroup( "completion" );
00658 config->writeEntry( "completion", m_completion );
00659 config->writeEntry( "CompletionAppendSpace", m_completionAppendSpace );
00660 config->writeEntry( "CompletionMinWordLength", m_minCompletionWordLength);
00661 config->writeEntry( "NbMaxCompletionWord", m_nbMaxCompletionWord);
00662 config->writeEntry( "AddCompletionWord", m_addCompletionWord );
00663 config->writeEntry( "ToolTipCompletion", m_toolTipCompletion );
00664 config->writeEntry( "CompletionKeyAction", ( int )m_keyCompletionAction );
00665
00666 config->setGroup( "AutoFormatEntries" );
00667 QDictIterator<KoAutoFormatEntry> it( m_entries );
00668
00669
00670 m_maxFindLength=0;
00671 QDomDocument doc("autocorrection");
00672
00673 QDomElement begin = doc.createElement( "Word" );
00674 doc.appendChild( begin );
00675 QDomElement items;
00676 items = doc.createElement("items");
00677 QDomElement data;
00678 for ( ; it.current() ; ++it )
00679 {
00680 items.appendChild(saveEntry( it, doc));
00681
00682 }
00683 buildMaxLen();
00684 begin.appendChild(items);
00685
00686 QDomElement upper;
00687 upper = doc.createElement("UpperCaseExceptions");
00688 for ( QStringList::Iterator it = m_upperCaseExceptions.begin(); it != m_upperCaseExceptions.end();++it )
00689 {
00690 data = doc.createElement("word");
00691 data.setAttribute("exception",(*it) );
00692 upper.appendChild(data);
00693 }
00694 begin.appendChild(upper);
00695
00696 QDomElement twoUpper;
00697 twoUpper = doc.createElement("TwoUpperLetterExceptions");
00698
00699 for ( QStringList::Iterator it = m_twoUpperLetterException.begin(); it != m_twoUpperLetterException.end();++it )
00700 {
00701 data = doc.createElement("word");
00702 data.setAttribute("exception",(*it) );
00703 twoUpper.appendChild(data);
00704 }
00705 begin.appendChild(twoUpper);
00706
00707 QDomElement super;
00708 super = doc.createElement("SuperScript");
00709 KoAutoFormatEntryMap::Iterator it2 = m_superScriptEntries.begin();
00710 for ( ; it2 != m_superScriptEntries.end() ; ++it2 )
00711 {
00712 data = doc.createElement("superscript");
00713 data.setAttribute("find", it2.key());
00714 data.setAttribute("super", it2.data().replace());
00715 super.appendChild(data);
00716 }
00717 begin.appendChild(super);
00718
00719 QDomElement doubleQuote;
00720 doubleQuote = doc.createElement("DoubleQuote");
00721 data = doc.createElement("doublequote");
00722 data.setAttribute("begin", QString(m_typographicDefaultDoubleQuotes.begin));
00723 data.setAttribute("end", QString(m_typographicDefaultDoubleQuotes.end));
00724 doubleQuote.appendChild(data);
00725 begin.appendChild(doubleQuote);
00726
00727
00728 QDomElement simpleQuote;
00729 simpleQuote = doc.createElement("SimpleQuote");
00730 data = doc.createElement("simplequote");
00731 data.setAttribute("begin", QString(m_typographicDefaultSimpleQuotes.begin));
00732 data.setAttribute("end", QString(m_typographicDefaultSimpleQuotes.end));
00733 simpleQuote.appendChild(data);
00734 begin.appendChild(simpleQuote);
00735 QFile f;
00736 if ( m_autoFormatLanguage.isEmpty())
00737 f.setName(locateLocal("data", "koffice/autocorrect/"+klocale.languageList().front() + ".xml",m_doc->instance()));
00738 else
00739 f.setName(locateLocal("data", "koffice/autocorrect/"+m_autoFormatLanguage + ".xml",m_doc->instance()));
00740 if(!f.open(IO_WriteOnly)) {
00741 kdWarning()<<"Error during saving autoformat to " << f.name() << endl;
00742 return;
00743 }
00744 QTextStream ts(&f);
00745 doc.save(ts, 2);
00746 f.close();
00747 autoFormatIsActive();
00748 config->sync();
00749 }
00750
00751 QDomElement KoAutoFormat::saveEntry( QDictIterator<KoAutoFormatEntry> _entry, QDomDocument doc)
00752 {
00753 QDomElement data;
00754 data = doc.createElement("item");
00755 data.setAttribute("find", _entry.currentKey());
00756 data.setAttribute("replace", _entry.current()->replace());
00757 if ( _entry.current()->formatEntryContext() )
00758 {
00759 KoSearchContext *tmp = _entry.current()->formatEntryContext();
00760 if ( tmp->m_optionsMask & KoSearchContext::Family )
00761 {
00762 data.setAttribute("FONT", tmp->m_family);
00763 }
00764 if ( tmp->m_optionsMask & KoSearchContext::Size )
00765 {
00766 data.setAttribute("SIZE", tmp->m_size);
00767 }
00768 if ( tmp->m_optionsMask & KoSearchContext::Italic )
00769 {
00770 data.setAttribute("ITALIC", static_cast<bool>(tmp->m_options & KoSearchContext::Italic));
00771 }
00772 if ( tmp->m_optionsMask & KoSearchContext::Bold )
00773 {
00774 data.setAttribute("BOLD", static_cast<bool>(tmp->m_options & KoSearchContext::Bold));
00775 }
00776 if ( tmp->m_optionsMask & KoSearchContext::Shadow )
00777 {
00778 data.setAttribute("SHADOWTEXT", static_cast<bool>(tmp->m_options & KoSearchContext::Shadow));
00779 }
00780 if ( tmp->m_optionsMask & KoSearchContext::WordByWord )
00781 {
00782 data.setAttribute("WORDBYWORD", static_cast<bool>(tmp->m_options & KoSearchContext::WordByWord));
00783 }
00784
00785 if ( tmp->m_optionsMask & KoSearchContext::Underline )
00786 {
00787 switch( tmp->m_underline )
00788 {
00789 case KoTextFormat::U_SIMPLE:
00790 data.setAttribute("UNDERLINE", "single");
00791 break;
00792 case KoTextFormat::U_DOUBLE:
00793 data.setAttribute("UNDERLINE", "double");
00794 break;
00795 case KoTextFormat::U_SIMPLE_BOLD:
00796 data.setAttribute("UNDERLINE", "single-bold");
00797 break;
00798 case KoTextFormat::U_WAVE:
00799 data.setAttribute("UNDERLINE", "wave");
00800 break;
00801 case KoTextFormat::U_NONE:
00802 data.setAttribute("UNDERLINE", "none");
00803 break;
00804 }
00805 }
00806 if ( tmp->m_optionsMask & KoSearchContext::StrikeOut )
00807 {
00808 switch( tmp->m_strikeOut )
00809 {
00810 case KoTextFormat::S_SIMPLE:
00811 data.setAttribute("STRIKEOUT", "single");
00812 break;
00813 case KoTextFormat::S_DOUBLE:
00814 data.setAttribute("STRIKEOUT", "double");
00815 break;
00816 case KoTextFormat::S_NONE:
00817 data.setAttribute("STRIKEOUT", "none");
00818 break;
00819 case KoTextFormat::S_SIMPLE_BOLD:
00820 data.setAttribute("STRIKEOUT", "single-bold");
00821 break;
00822 }
00823 }
00824 if ( tmp->m_optionsMask & KoSearchContext::Attribute )
00825 {
00826 data.setAttribute("FONTATTRIBUTE", KoTextFormat::attributeFontToString( tmp->m_attribute ) );
00827 }
00828
00829 if ( tmp->m_optionsMask & KoSearchContext::VertAlign)
00830 {
00831 data.setAttribute( "VERTALIGN", static_cast<int>(tmp->m_vertAlign) );
00832 }
00833 if ( tmp->m_optionsMask & KoSearchContext::BgColor )
00834 {
00835 data.setAttribute( "TEXTCOLOR", tmp->m_color.name());
00836 }
00837 if ( tmp->m_optionsMask & KoSearchContext::Color )
00838 {
00839 data.setAttribute( "TEXTCOLOR", tmp->m_color.name());
00840 }
00841 if ( tmp->m_optionsMask & KoSearchContext::BgColor )
00842 {
00843 data.setAttribute( "TEXTBGCOLOR", tmp->m_backGroundColor.name());
00844 }
00845 if ( tmp->m_optionsMask & KoSearchContext::Language )
00846 data.setAttribute( "LANGUAGE", tmp->m_language );
00847 }
00848 return data;
00849 }
00850
00851 void KoAutoFormat::addAutoFormatEntry( const QString &key, const QString &replace )
00852 {
00853 KoAutoFormatEntry *findEntry = m_entries.find( key);
00854 if ( findEntry )
00855 {
00856 if ( findEntry->replace().lower() == replace.lower() )
00857 return;
00858 }
00859
00860 KoAutoFormatEntry *tmp = new KoAutoFormatEntry( replace );
00861 m_entries.insert( key, tmp );
00862 saveConfig();
00863 buildMaxLen();
00864 }
00865
00866 QString KoAutoFormat::getLastWord(KoTextParag *parag, int const index)
00867 {
00868 QString lastWord;
00869 KoTextString *s = parag->string();
00870 for ( int i = index - 1; i >= 0; --i )
00871 {
00872 QChar ch = s->at( i ).c;
00873 if ( ch.isSpace() || ch.isPunct() )
00874 break;
00875 lastWord.prepend( ch );
00876 }
00877 return lastWord;
00878 }
00879
00880 QString KoAutoFormat::getLastWord(const int max_words, KoTextParag *parag, int const index)
00881 {
00882 QString lastWord;
00883 KoTextString const *s = parag->string();
00884 int words = 0;
00885 for ( int i = index - 1; i >= 0; --i )
00886 {
00887 QChar ch = s->at( i ).c;
00888 if ( ch.isSpace() || ch.isPunct() )
00889 {
00890 ++words;
00891 if (words >= max_words)
00892 break;
00893 }
00894 lastWord.prepend( ch );
00895 }
00896 return lastWord;
00897 }
00898
00899 QString KoAutoFormat::getWordAfterSpace(KoTextParag *parag, int const index)
00900 {
00901 QString word;
00902 KoTextString *s = parag->string();
00903 for ( int i = index - 1; i >= 0; --i )
00904 {
00905 QChar ch = s->at( i ).c;
00906 if ( ch.isSpace() )
00907 break;
00908 word.prepend( ch );
00909 }
00910 return word;
00911
00912 }
00913
00914 bool KoAutoFormat::doCompletion( KoTextCursor* textEditCursor, KoTextParag *parag, int const index, KoTextObject *txtObj )
00915 {
00916 if( m_completion )
00917 {
00918 bool part=false;
00919 QString lastWord, word;
00920 if (m_completionBox && m_completionBox->isShown() )
00921 {
00922 word = m_completionBox->text();
00923 lastWord = m_completionBox->lastWord();
00924 }
00925 else
00926 {
00927 QStringList wordlist, new_wordlist;
00928 for (uint i=1; i <= m_countMaxWords; i++ )
00929 {
00930 lastWord = getLastWord(i, parag, index+1);
00931 wordlist += m_listCompletion->substringCompletion( lastWord );
00932 }
00933 uint maxlength = 0;
00934 for ( QStringList::ConstIterator it = wordlist.begin(); it != wordlist.end(); ++it )
00935 {
00936 if ( (*it).startsWith( lastWord, false ) && new_wordlist.find(*it) == new_wordlist.end() )
00937 {
00938 if ( (*it).length() > maxlength )
00939 maxlength = (*it).length();
00940 new_wordlist.append(*it);
00941
00942 }
00943 }
00944 if ( new_wordlist.isEmpty() )
00945 return false;
00946 if ( new_wordlist.count() == 1 )
00947 word = new_wordlist.first();
00948 else
00949 {
00950
00951 for (uint i = lastWord.length(); i<maxlength && !part; i++)
00952 {
00953 QChar ch = new_wordlist.first().at(i);
00954 for (QStringList::ConstIterator it = new_wordlist.begin(); it != new_wordlist.end(); ++it )
00955 {
00956 if ( (*it).at(i).lower() != ch.lower() )
00957 {
00958 word = (*it).left(i);
00959
00960 part=true;
00961 break;
00962 }
00963 }
00964 }
00965 }
00966 if (word == lastWord)
00967 return false;
00968
00969 word=lastWord+word.right(word.length()-lastWord.length() );
00970 }
00971 if( !word.isEmpty() )
00972 {
00973 int const lastword_length = lastWord.length();
00974 int const start = index+1 - lastword_length;
00975 int const length = word.length();
00976
00977 KMacroCommand *macro = new KMacroCommand( i18n("Completion Word"));
00978 KoTextCursor cursor( parag->document() );
00979 cursor.setParag( parag );
00980 cursor.setIndex( start );
00981 KoTextDocument * textdoc = parag->textDocument();
00982 if( m_completionAppendSpace && !part)
00983 word+=" ";
00984 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
00985 cursor.setIndex( start + lastword_length );
00986 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
00987
00988 macro->addCommand( txtObj->replaceSelectionCommand( textEditCursor, word,
00989 KoTextObject::HighlightSelection,
00990 i18n("Completion Word") ));
00991
00992 if ( m_completionAppendSpace && !m_ignoreUpperCase && (m_convertUpperUpper || m_convertUpperCase) && !part)
00993 {
00994
00995 for (uint i=1; i < word.length(); i++)
00996 if ( word.at(i).isSpace() || word.at(i).isPunct() )
00997 {
00998 word.truncate(i);
00999 break;
01000 }
01001 int const newPos = start + word.length();
01002 KCommand *cmd = doUpperCase( textEditCursor, parag, newPos, word, txtObj );
01003 if( cmd )
01004 macro->addCommand( cmd );
01005 txtObj->emitHideCursor();
01006 textEditCursor->setIndex(start+ length+1);
01007 }
01008 else
01009 {
01010 txtObj->emitHideCursor();
01011 textEditCursor->setIndex(start+ length);
01012 }
01013 txtObj->emitNewCommand( macro );
01014
01015
01016
01017
01018 txtObj->emitShowCursor();
01019 return true;
01020 }
01021 }
01022 return false;
01023 }
01024
01025 bool KoAutoFormat::doToolTipCompletion( KoTextCursor* textEditCursor, KoTextParag *parag, int index, KoTextObject *txtObj, int keyPressed )
01026 {
01027 if( m_completion && m_toolTipCompletion && m_completionBox && m_completionBox->isShown() )
01028 {
01029 if ( ( keyPressed == Qt::Key_Return && m_keyCompletionAction==Enter )
01030 || ( keyPressed == Qt::Key_Enter && m_keyCompletionAction==Enter )
01031 || ( keyPressed == Qt::Key_Tab && m_keyCompletionAction==Tab )
01032 || ( keyPressed == Qt::Key_Space && m_keyCompletionAction==Space )
01033 || ( keyPressed == Qt::Key_End && m_keyCompletionAction==End )
01034 || ( keyPressed == Qt::Key_Right && m_keyCompletionAction==Right ))
01035 {
01036 return doCompletion(textEditCursor, parag, index, txtObj);
01037 }
01038 }
01039 return false;
01040 }
01041 void KoAutoFormat::showToolTipBox(KoTextParag *parag, int index, QWidget *widget, const QPoint &pos )
01042 {
01043
01044 if( m_completion && m_toolTipCompletion)
01045 {
01046 QString lastWord, word;
01047 for (uint i=1; i <= m_countMaxWords; i++ )
01048 {
01049 lastWord = getLastWord(i, parag, index+1);
01050 word=m_listCompletion->makeCompletion( lastWord );
01051 if ( !word.isEmpty())
01052 break;
01053 }
01054 if( !word.isEmpty() && word!=lastWord )
01055 {
01056 uint const length = lastWord.length();
01057 if (length<=3)
01058 return;
01059 word=lastWord+word.right(word.length()-length);
01060 if (!m_completionBox)
01061 m_completionBox = new KoCompletionBox(0,0,Qt::WType_Popup);
01062 QPoint const show_pos = widget->mapToGlobal(pos);
01063 m_completionBox->setText(word);
01064 m_completionBox->setLastWord(lastWord);
01065 m_completionBox->adjustSize();
01066 int const height = m_completionBox->sizeHint().height();
01067 m_completionBox->move( show_pos.x(), show_pos.y() - height );
01068
01069 if (!m_completionBox->isShown() )
01070 {
01071 m_completionBox->show();
01072 widget->setFocus();
01073 }
01074 }
01075 else
01076 removeToolTipCompletion();
01077 }
01078 }
01079 void KoAutoFormat::removeToolTipCompletion()
01080 {
01081 if (m_completion && m_toolTipCompletion && m_completionBox && m_completionBox->isShown())
01082 m_completionBox->hide();
01083 }
01084
01085 void KoAutoFormat::autoFormatIsActive()
01086 {
01087 m_bAutoFormatActive = m_useBulletStyle ||
01088 m_removeSpaceBeginEndLine ||
01089 m_autoDetectUrl ||
01090 m_convertUpperUpper ||
01091 m_convertUpperCase ||
01092 m_autoReplaceNumber ||
01093 m_autoChangeFormat ||
01094 m_completion ||
01095 m_typographicDoubleQuotes.replace ||
01096 m_typographicSimpleQuotes.replace ||
01097 m_entries.count()!=0 ||
01098 m_allLanguages.count()!=0;
01099 }
01100
01101 void KoAutoFormat::doAutoFormat( KoTextCursor* textEditCursor, KoTextParag *parag, int index, QChar ch,KoTextObject *txtObj )
01102 {
01103 m_ignoreUpperCase = false;
01104
01105 if ( !m_configRead )
01106 readConfig();
01107
01108 if ( !m_bAutoFormatActive )
01109 return;
01110
01111 if( ch.isSpace())
01112 {
01113
01114
01115
01116
01117 QString word=getWordAfterSpace(parag,index);
01118
01119 if ( m_autoChangeFormat && index > 3)
01120 {
01121 KCommand *cmd =doAutoChangeFormat( textEditCursor, parag, index, word, txtObj );
01122 if ( cmd )
01123 txtObj->emitNewCommand( cmd );
01124
01125 }
01126 if ( m_autoReplaceNumber )
01127 {
01128 KCommand *cmd = doAutoReplaceNumber( textEditCursor, parag, index, word, txtObj );
01129 if ( cmd )
01130 txtObj->emitNewCommand( cmd );
01131 }
01132 }
01133
01134 if( ch =='\n' )
01135 {
01136
01137 if( m_removeSpaceBeginEndLine && index > 1)
01138 {
01139 KCommand *cmd = doRemoveSpaceBeginEndLine( textEditCursor, parag, txtObj, index );
01140 if ( cmd )
01141 txtObj->emitNewCommand( cmd );
01142 }
01143 if( m_useBulletStyle && index > 3)
01144 {
01145 KCommand *cmd =doUseBulletStyle( textEditCursor, parag, txtObj, index );
01146 if ( cmd )
01147 txtObj->emitNewCommand( cmd );
01148 }
01149 if( m_useAutoNumberStyle && index > 3 )
01150 {
01151 KCommand *cmd =doUseNumberStyle( textEditCursor, parag, txtObj, index );
01152 if ( cmd )
01153 txtObj->emitNewCommand( cmd );
01154 }
01155 if( m_convertUpperUpper && m_includeTwoUpperLetterException )
01156 doAutoIncludeUpperUpper(textEditCursor, parag, txtObj );
01157 if( m_convertUpperCase && m_includeAbbreviation )
01158 doAutoIncludeAbbreviation(textEditCursor, parag, txtObj );
01159 }
01160
01161
01162
01163
01164
01165 if ( (ch.isSpace() || ch==':' || ch=='?' || ch=='!' || ch==',' || ch=='<' || ch=='>' || (m_advancedAutoCorrect && ch=='.') ) && index > 0 )
01166 {
01167 KCommand *cmd = 0L;
01168 KMacroCommand *macro = 0L;
01169 QString lastWord = getWordAfterSpace(parag, index);
01170
01171
01172 if ( ch == '.')
01173 detectStartOfLink( parag, index, true );
01174 else
01175 detectStartOfLink( parag, index, false );
01176
01177 if ( !m_wordInserted && m_advancedAutoCorrect && !m_ignoreUpperCase)
01178 {
01179 int const completionBeginPos = index -lastWord.length();
01180 int newPos = index;
01181 cmd = doAutoCorrect( textEditCursor, parag, newPos, txtObj );
01182
01183 if( cmd )
01184 {
01185 if (!macro)
01186 macro = new KMacroCommand(i18n("Autocorrection"));
01187 macro->addCommand( cmd );
01188 }
01189
01190 int const endPos=textEditCursor->index();
01191 bool was_a_replacement;
01192 if (index == newPos)
01193 was_a_replacement = false;
01194 else
01195 was_a_replacement = true;
01196
01197 if( was_a_replacement)
01198 {
01199 txtObj->emitHideCursor();
01200 if(endPos==0)
01201 {
01202 textEditCursor->gotoUp();
01203 textEditCursor->gotoLineEnd();
01204 newPos=textEditCursor->index();
01205 }
01206 else
01207 newPos= endPos-1;
01208
01209 m_wordInserted = true;
01210 for(int i=completionBeginPos; i<newPos;i++)
01211 {
01212 textEditCursor->setIndex(i);
01213 doAutoFormat( textEditCursor, parag, i, parag->toString().at(i),txtObj );
01214
01215 }
01216 textEditCursor->setIndex(newPos);
01217 doAutoFormat( textEditCursor, parag, newPos, ch,txtObj );
01218 m_wordInserted = false;
01219 if (endPos==0)
01220 {
01221 textEditCursor->gotoLineStart();
01222 textEditCursor->gotoDown();
01223 }
01224 else
01225 textEditCursor->setIndex(newPos+1);
01226 txtObj->emitShowCursor();
01227 return;
01228 }
01229
01230 }
01231
01232 if (!m_ignoreUpperCase && m_bCapitalizeNameOfDays)
01233 {
01234 KCommand *cmd = doCapitalizeNameOfDays( textEditCursor, parag, index, lastWord, txtObj );
01235
01236 if( cmd )
01237 {
01238 if (!macro)
01239 macro = new KMacroCommand(i18n("Autocorrection"));
01240 macro->addCommand( cmd );
01241 m_ignoreUpperCase = true;
01242 }
01243 }
01244
01245 if (ch=='.')
01246 return;
01247
01248
01249 if( !m_ignoreUpperCase && m_completion && m_addCompletionWord && m_listCompletion->items().count() < m_nbMaxCompletionWord )
01250 {
01251 QString completionWord("");
01252 QChar ch;
01253 for (uint i=0;i<lastWord.length();i++)
01254 {
01255 ch = lastWord.at(i);
01256 if (ch.isPunct() && ch!='-' && ch!='=' )
01257 {
01258 if (completionWord.at(0) == '-')
01259 completionWord.remove(0,1);
01260
01261 if (completionWord.length()>= m_minCompletionWordLength && !completionWord.isEmpty() && m_listCompletion->makeCompletion(completionWord).isEmpty())
01262 {
01263 kdDebug() << "Adding:" << completionWord << endl;
01264 m_listCompletion->addItem( completionWord );
01265 if ( completionWord.length() > m_countMaxWords )
01266 m_countMaxWords = completionWord.length();
01267
01268 }
01269 completionWord = "";
01270 }
01271 else
01272 {
01273 completionWord.append(ch);
01274 if (i==lastWord.length()-1)
01275 {
01276 if (completionWord.at(0) == '-')
01277 completionWord.remove(0,1);
01278 if (completionWord.at(completionWord.length()-1) == '-')
01279 completionWord.truncate(completionWord.length()-1);
01280 completionWord.remove('=');
01281 if (completionWord.length()>= m_minCompletionWordLength && !completionWord.isEmpty() && m_listCompletion->makeCompletion(completionWord).isEmpty())
01282 {
01283 kdDebug() << "Adding:" << completionWord << endl;
01284 m_listCompletion->addItem( completionWord );
01285 if ( completionWord.length() > m_countMaxWords )
01286 m_countMaxWords = completionWord.length();
01287 }
01288 }
01289 }
01290 }
01291 }
01292
01293 if( m_autoDetectUrl && m_ignoreUpperCase && (ch!='?' || lastWord.at(lastWord.length()-1)=='?') )
01294 {
01295 doAutoDetectUrl( textEditCursor, parag, index, lastWord, txtObj );
01296
01297 }
01298
01299 if (!m_ignoreUpperCase && (m_convertUpperUpper || m_convertUpperCase) )
01300 {
01301 cmd = doUpperCase( textEditCursor, parag, index, lastWord, txtObj );
01302
01303 if( cmd )
01304 {
01305 if (!macro)
01306 macro = new KMacroCommand(i18n("Autocorrection"));
01307 macro->addCommand( cmd );
01308 }
01309 }
01310
01311 if ( macro )
01312 txtObj->emitNewCommand( macro );
01313
01314 if(!m_ignoreUpperCase && m_bAutoSuperScript && m_superScriptEntries.count()>0)
01315 {
01316 if( lastWord.at(0).isPunct() )
01317 lastWord.remove(0,1);
01318 KCommand * cmd = doAutoSuperScript( textEditCursor, parag, index, lastWord, txtObj );
01319 if ( cmd )
01320 txtObj->emitNewCommand( cmd );
01321 }
01322
01323 }
01324 else
01325 {
01326 if ( ch == '"' && m_typographicDoubleQuotes.replace )
01327 {
01328 KCommand *cmd = doTypographicQuotes( textEditCursor, parag, index, txtObj, true );
01329 if ( cmd )
01330 txtObj->emitNewCommand( cmd );
01331 }
01332 else if ( ch == '\'' && m_typographicDoubleQuotes.replace )
01333 {
01334 KCommand *cmd = doTypographicQuotes( textEditCursor, parag, index, txtObj, false );
01335 if ( cmd )
01336 txtObj->emitNewCommand( cmd );
01337 }
01338 }
01339 }
01340
01341 KCommand *KoAutoFormat::doAutoCorrect( KoTextCursor* textEditCursor, KoTextParag *parag, int &index, KoTextObject *txtObj )
01342 {
01343
01344
01345
01346
01347
01348 QString * wordArray = new QString[m_maxFindLength+1];
01349 {
01350 QString word;
01351 KoTextString *s = parag->string();
01352 for ( int i = index - 1; i >= 0; --i )
01353 {
01354 QChar ch = s->at( i ).c;
01355
01356 if ( ch.isSpace() || i==0)
01357 {
01358 if(i==0 && word.length()<m_maxFindLength)
01359 word.prepend( ch );
01360 wordArray[word.length()]=word;
01361 }
01362 word.prepend( ch );
01363 if (((index - 1)-i) == (int)m_maxFindLength)
01364 break;
01365 }
01366
01367 }
01368 KCommand *cmd = autoFormatWord( textEditCursor, parag, index, txtObj, wordArray, false );
01369 if ( !cmd )
01370 cmd = autoFormatWord( textEditCursor, parag, index, txtObj, wordArray, true );
01371 delete [] wordArray;
01372 return cmd;
01373 }
01374
01375
01376 KCommand *KoAutoFormat::autoFormatWord( KoTextCursor* textEditCursor, KoTextParag *parag, int &index, KoTextObject *txtObj, QString * _wordArray, bool _allLanguages )
01377 {
01378 KoTextDocument * textdoc = parag->textDocument();
01379
01380
01381
01382
01383 for(int i=m_maxFindLength;i>0;--i)
01384 {
01385 if ( !_wordArray[i].isEmpty())
01386 {
01387 KoAutoFormatEntry* it = 0L;
01388 if ( _allLanguages )
01389 it = m_allLanguages[ _wordArray[i] ];
01390 else
01391 it = m_entries[ _wordArray[i] ];
01392 if ( _wordArray[i]!=0 && it )
01393 {
01394 unsigned int length = _wordArray[i].length();
01395 int const start = index - length;
01396 KoTextCursor cursor( parag->document() );
01397 cursor.setParag( parag );
01398 cursor.setIndex( start );
01399 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01400 cursor.setIndex( start + length );
01401 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01402 KCommand *cmd = 0L;
01403 kdDebug()<<"it->replace() :"<<it->replace()<<endl;
01404 if (!it->formatEntryContext() || !m_bAutoCorrectionWithFormat)
01405 {
01406 cmd = txtObj->replaceSelectionCommand( textEditCursor, it->replace(),
01407 KoTextObject::HighlightSelection,
01408 i18n("Autocorrect Word") );
01409 }
01410 else
01411 {
01412 int flags = 0;
01413 KoTextFormat * lastFormat = parag->at( start )->format();
01414 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
01415 changeTextFormat(it->formatEntryContext(), newFormat, flags );
01416 KMacroCommand *macro = new KMacroCommand( i18n("Autocorrect Word with Format"));
01417 KCommand *cmd2=txtObj->replaceSelectionCommand( textEditCursor, it->replace(),
01418 KoTextObject::HighlightSelection,
01419 i18n("Autocorrect Word") );
01420 if ( cmd2 )
01421 macro->addCommand(cmd2);
01422 KoTextCursor cursor( parag->document() );
01423 cursor.setParag( parag );
01424 cursor.setIndex( start );
01425 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01426 cursor.setIndex( start + it->replace().length() );
01427 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01428
01429 cmd2 =txtObj->setFormatCommand( textEditCursor, &lastFormat, newFormat, flags, false, KoTextObject::HighlightSelection );
01430 macro->addCommand( cmd2);
01431
01432 index = index - length + it->replace().length();
01433 textEditCursor->setIndex(index+1);
01434 cmd2 =txtObj->setFormatCommand( textEditCursor, &newFormat, lastFormat, 0 );
01435 macro->addCommand( cmd2);
01436 parag->at( index+1 )->setFormat(lastFormat);
01437
01438 cmd = macro;
01439 txtObj->emitHideCursor();
01440 textEditCursor->gotoRight();
01441 txtObj->emitShowCursor();
01442
01443 return cmd;
01444 }
01445
01446
01447
01448 txtObj->emitHideCursor();
01449 textEditCursor->gotoRight();
01450 txtObj->emitShowCursor();
01451 index = index - length + it->replace().length();
01452 return cmd;
01453 }
01454 }
01455 }
01456 return 0L;
01457 }
01458
01459 KCommand *KoAutoFormat::doTypographicQuotes( KoTextCursor* textEditCursor, KoTextParag *parag, int index, KoTextObject *txtObj, bool doubleQuotes )
01460 {
01461
01462 KoTextDocument * textdoc = parag->textDocument();
01463 KoTextCursor cursor( parag->document() );
01464 cursor.setParag( parag );
01465 cursor.setIndex( index );
01466 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01467 cursor.setIndex( index + 1 );
01468 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01469
01470
01471
01472
01473 QString replacement;
01474 if ( index > 0 && !parag->at( index - 1 )->c.isSpace() )
01475 {
01476 if( doubleQuotes )
01477 replacement = m_typographicDoubleQuotes.end;
01478 else
01479 replacement = m_typographicSimpleQuotes.end;
01480 }
01481 else
01482 {
01483 if( doubleQuotes )
01484 replacement = m_typographicDoubleQuotes.begin;
01485 else
01486 replacement = m_typographicSimpleQuotes.begin;
01487 }
01488 return txtObj->replaceSelectionCommand( textEditCursor, replacement,
01489 KoTextObject::HighlightSelection,
01490 i18n("Typographic Quote") );
01491 }
01492
01493 KCommand * KoAutoFormat::doUpperCase( KoTextCursor *textEditCursor, KoTextParag *parag,
01494 int index, const QString & word, KoTextObject *txtObj )
01495 {
01496 KoTextDocument * textdoc = parag->textDocument();
01497 unsigned int length = word.length();
01498 if (word.at(length-1) == '.' )
01499 {
01500 --index;
01501 --length;
01502 }
01503 int const start = index - length;
01504 KoTextCursor backCursor( parag->document() );
01505 backCursor.setParag( parag );
01506 backCursor.setIndex( start );
01507
01508
01509 QChar const firstChar = backCursor.parag()->at( backCursor.index() )->c;
01510
01511 bool bNeedMove = false;
01512 KCommand *cmd = 0L;
01513 if ( m_convertUpperCase && isLower( firstChar ) )
01514 {
01515 bool beginningOfSentence = true;
01516
01517 while ( backCursor.index() > 0 || backCursor.parag()->prev() )
01518 {
01519 beginningOfSentence = false;
01520 backCursor.gotoLeft();
01521 if ( !backCursor.parag()->at( backCursor.index() )->c.isSpace() )
01522 break;
01523 }
01524
01525 if ( !beginningOfSentence )
01526 beginningOfSentence = isMark( backCursor.parag()->at( backCursor.index() )->c);
01527
01528 if ( !beginningOfSentence && start==0 )
01529 if ( parag->counter() || backCursor.parag()->at( backCursor.index() )->c.isPunct() )
01530 beginningOfSentence = true;
01531
01532
01533 if ( beginningOfSentence )
01534 {
01535 QChar const punct = backCursor.parag()->at( backCursor.index() )->c;
01536 QString const text = getLastWord( backCursor.parag(), backCursor.index() )
01537 + punct;
01538 kdDebug() << "text: " << text << endl;
01539
01540 beginningOfSentence = (m_upperCaseExceptions.findIndex(text)==-1);
01541 }
01542
01543 if ( beginningOfSentence )
01544 {
01545 KoTextCursor cursor( parag->document() );
01546 cursor.setParag( parag );
01547 cursor.setIndex( start );
01548 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01549 cursor.setIndex( start + 1 );
01550 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01551 cmd = txtObj->replaceSelectionCommand( textEditCursor, QString( firstChar.upper() ),
01552 KoTextObject::HighlightSelection,
01553 i18n("Autocorrect (capitalize first letter)") );
01554 bNeedMove = true;
01555 }
01556 }
01557 else if ( m_convertUpperUpper && isUpper( firstChar ) && length > 2 )
01558 {
01559 backCursor.setIndex( backCursor.index() + 1 );
01560 QChar secondChar = backCursor.parag()->at( backCursor.index() )->c;
01561
01562 if ( isUpper( secondChar ) )
01563 {
01564
01565 backCursor.setIndex( backCursor.index() + 1 );
01566 QChar thirdChar = backCursor.parag()->at( backCursor.index() )->c;
01567 if ( isLower( thirdChar ) && (m_twoUpperLetterException.findIndex(word)==-1))
01568 {
01569
01570 KoTextCursor cursor( parag->document() );
01571 cursor.setParag( parag );
01572 cursor.setIndex( start + 1 );
01573 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01574 cursor.setIndex( start + 2 );
01575 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01576
01577 QString replacement = word[1].lower();
01578 cmd = txtObj->replaceSelectionCommand( textEditCursor, replacement,KoTextObject::HighlightSelection,i18n("Autocorrect (Convert two upper case letters to one upper case and one lower case letter.)") );
01579
01580 bNeedMove = true;
01581 }
01582 }
01583 }
01584 if ( bNeedMove )
01585 {
01586 if (word.at(word.length()-1) == '.' )
01587 ++index;
01588 txtObj->emitHideCursor();
01589 textEditCursor->setParag( parag );
01590 textEditCursor->setIndex( index );
01591 textEditCursor->gotoRight();
01592 txtObj->emitShowCursor();
01593 }
01594 return cmd;
01595 }
01596
01597 KCommand * KoAutoFormat::doAutoReplaceNumber( KoTextCursor* textEditCursor, KoTextParag *parag, int& index, const QString & word , KoTextObject *txtObj )
01598 {
01599 unsigned int length = word.length();
01600 if ( length != 3 )
01601 return 0L;
01602 KoTextDocument * textdoc = parag->textDocument();
01603 int start = index - length;
01604 if( word == QString("1/2") || word == QString("1/4") || word == QString("3/4") )
01605 {
01606 KoTextCursor cursor( parag->document() );
01607 cursor.setParag( parag );
01608 cursor.setIndex( start );
01609 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01610 cursor.setIndex( start + length );
01611 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01612 QString replacement;
01613 if( word == QString("1/2") )
01614 replacement=QString("½");
01615 else if (word == QString("1/4") )
01616 replacement=QString("¼");
01617 else if (word == QString("3/4") )
01618 replacement=QString("¾");
01619 QString cmdName=i18n("Autocorrect (replace 1/2... with ")+QString("½...)");
01620 KCommand *cmd =txtObj->replaceSelectionCommand( textEditCursor, replacement,
01621 KoTextObject::HighlightSelection,
01622 cmdName );
01623 txtObj->emitHideCursor();
01624 textEditCursor->gotoRight();
01625 txtObj->emitShowCursor();
01626 index = index - length + replacement.length();
01627 return cmd;
01628 }
01629 return 0L;
01630 }
01631
01632 void KoAutoFormat::detectStartOfLink(KoTextParag * parag, int const index, bool const insertedDot)
01633 {
01634 QString word;
01635 KoTextString *s = parag->string();
01636 for ( int i = 0; i < index; ++i )
01637 {
01638 word.append( s->at( i ).c );
01639 }
01640
01641 if (word.find("http")!=-1 || word.find("https")!=-1 || word.find("mailto")!=-1 || word.find("ftp")!=-1 || word.find("file")!=-1
01642 || word.find("news")!=-1 || word.find('@')!=-1)
01643 m_ignoreUpperCase=true;
01644 else
01645 {
01646 int const tmp_pos=word.find("www.");
01647 if (tmp_pos!=-1 && (word.find('.',tmp_pos+4)!=-1 || insertedDot) )
01648 m_ignoreUpperCase=true;
01649 }
01650 }
01651
01652 void KoAutoFormat::doAutoDetectUrl( KoTextCursor *textEditCursor, KoTextParag *parag, int &index, QString & word, KoTextObject *txtObj )
01653 {
01654 kdDebug() << "link:" << word << endl;
01655 char link_type = 0;
01656 int pos = word.find("http://");
01657 int tmp_pos = word.find("https://");
01658 if(tmp_pos<pos && tmp_pos!=-1)
01659 pos = tmp_pos;
01660 tmp_pos = word.find("mailto:/");
01661 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
01662 pos = tmp_pos;
01663 tmp_pos = word.find("ftp://");
01664 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
01665 pos = tmp_pos;
01666 tmp_pos = word.find("ftp.");
01667 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
01668 {
01669 pos = tmp_pos;
01670 link_type = 3;
01671 }
01672 tmp_pos = word.find("file:/");
01673 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
01674 pos = tmp_pos;
01675 tmp_pos = word.find("news:");
01676 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1)
01677 pos = tmp_pos;
01678 tmp_pos = word.find("www.");
01679 if((tmp_pos<pos || pos==-1 ) && tmp_pos!=-1 && word.find('.',tmp_pos+4)!=-1 )
01680 {
01681 pos = tmp_pos;
01682 link_type = 2;
01683 }
01684 tmp_pos = word.find('@');
01685 if ( pos == -1 && tmp_pos != -1 )
01686 {
01687 pos = tmp_pos-1;
01688 QChar c;
01689 while( pos>=0 )
01690 {
01691 c = word.at(pos);
01692 if ( c.isPunct() && c!='.'&& c!='_' && c!='<' && c!='>' ) break;
01693 else --pos;
01694 }
01695 if ( pos == tmp_pos-1 )
01696 {
01697 m_ignoreUpperCase = false;
01698 pos = -1;
01699 }
01700 else
01701 ++pos;
01702 link_type = 1;
01703 }
01704 if(pos!=-1)
01705 {
01706
01707 while ( !word.at(word.length()-1).isLetter() && !word.at(word.length()-1).isDigit() && word.at(word.length()-1)!='/')
01708 {
01709 word.truncate(word.length()-1);
01710 --index;
01711 }
01712 word.remove(0,pos);
01713 unsigned int const length = word.length();
01714 int const start = index - length;
01715 KoTextCursor cursor( parag->document() );
01716 KoTextDocument * textdoc = parag->textDocument();
01717 cursor.setParag( parag );
01718 cursor.setIndex( start );
01719 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01720 cursor.setIndex( start + length );
01721 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01722 QString newWord = word;
01723 if(link_type==1)
01724 newWord = QString("mailto:") + word;
01725 else if(link_type==2)
01726 newWord = QString("http://") + word;
01727 else if(link_type==3)
01728 newWord = QString("ftp://") + word;
01729
01730 KoVariable* var = new KoLinkVariable( textdoc, word, newWord, m_varFormatCollection->format( "STRING" ), m_varCollection );
01731 CustomItemsMap customItemsMap;
01732 customItemsMap.insert( 0, var );
01733 KoTextFormat * lastFormat = parag->at( start )->format();
01734 int origCursorIndex = textEditCursor->index();
01735 txtObj->insert( textEditCursor, lastFormat, KoTextObject::customItemChar(), false, true, i18n("Insert Variable"), customItemsMap,KoTextObject::HighlightSelection );
01736 var->recalc();
01737 parag->invalidate(0);
01738 parag->setChanged( true );
01739
01740
01741 index -= length-1;
01742
01743 txtObj->emitHideCursor();
01744 textEditCursor->setIndex( origCursorIndex - (length-1) );
01745 txtObj->emitShowCursor();
01746
01747
01748 if ( m_completion && m_addCompletionWord && m_listCompletion->items().count() < m_nbMaxCompletionWord )
01749 {
01750 if (word.length()>= m_minCompletionWordLength && !word.isEmpty() && m_listCompletion->makeCompletion(word).isEmpty())
01751 {
01752 kdDebug() << "Adding:" << word << endl;
01753 m_listCompletion->addItem( word );
01754 if ( word.length() > m_countMaxWords )
01755 m_countMaxWords = word.length();
01756 }
01757 }
01758 }
01759 }
01760
01761 void KoAutoFormat::doAutoIncludeUpperUpper(KoTextCursor* , KoTextParag *parag, KoTextObject* )
01762 {
01763 KoTextString *s = parag->string();
01764
01765 if( s->length() < 2 )
01766 return;
01767
01768 for (int i=0; i<=(s->length() - 1);i++)
01769 {
01770 QString word;
01771 for ( int j = i ; j < s->length() - 1; j++ )
01772 {
01773 QChar ch = s->at( j ).c;
01774 if ( ch.isSpace() )
01775 break;
01776 word.append( ch );
01777 }
01778 if( word.length() > 2 && word.left(2)==word.left(2).upper() && word.at(3)!=word.at(3).upper() )
01779 {
01780 if ( m_twoUpperLetterException.findIndex(word )==-1)
01781 m_twoUpperLetterException.append( word);
01782 }
01783 i+=word.length();
01784 }
01785
01786 }
01787
01788
01789 void KoAutoFormat::doAutoIncludeAbbreviation(KoTextCursor* , KoTextParag *parag, KoTextObject* )
01790 {
01791 KoTextString *s = parag->string();
01792 if( s->length() < 2 )
01793 return;
01794 for (int i=0; i<=(s->length() - 1);i++)
01795 {
01796 QString wordAfter;
01797 QString word;
01798
01799 for ( int j = i ; j < s->length() - 1; j++ )
01800 {
01801 QChar ch = s->at( j ).c;
01802 if ( ch.isSpace() )
01803 break;
01804 word.append( ch );
01805 }
01806 if ( isMark( word.at(word.length()-1)) )
01807 {
01808 for ( int j = i+word.length()+1 ; j < s->length() - 1; j++ )
01809 {
01810 QChar ch = s->at( j ).c;
01811 if ( ch.isSpace() )
01812 break;
01813 wordAfter.append( ch );
01814 }
01815 if( word.length()>1 && !wordAfter.isEmpty() && wordAfter.at(0)==wordAfter.at(0).lower())
01816 {
01817 if ( m_upperCaseExceptions.findIndex(word )==-1)
01818 m_upperCaseExceptions.append( word );
01819 }
01820 }
01821 i+=word.length();
01822 if( !wordAfter.isEmpty())
01823 {
01824 i+=wordAfter.length()+1;
01825 }
01826 }
01827
01828 }
01829
01830
01831 KCommand * KoAutoFormat::doAutoChangeFormat( KoTextCursor *textEditCursor, KoTextParag *parag,int index, const QString & word, KoTextObject *txtObj )
01832 {
01833 bool underline = (word.at(0)=='_' && word.at(word.length()-1)=='_');
01834 bool bold = (word.at(0)=='*' && word.at(word.length()-1)=='*');
01835 if( bold || underline)
01836 {
01837 QString replacement=word.mid(1,word.length()-2);
01838 int start = index - word.length();
01839 KoTextDocument * textdoc = parag->textDocument();
01840 KMacroCommand *macro=new KMacroCommand(i18n("Autocorrection: Change Format"));
01841 KoTextCursor cursor( parag->document() );
01842
01843 cursor.setParag( parag );
01844 cursor.setIndex( start );
01845 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01846 cursor.setIndex( start + word.length() );
01847 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01848 macro->addCommand(txtObj->replaceSelectionCommand( textEditCursor, replacement,
01849 KoTextObject::HighlightSelection,
01850 i18n("Autocorrect Word") ));
01851
01852 KoTextFormat * lastFormat = parag->at( start )->format();
01853 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
01854 cursor.setIndex( start );
01855 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01856 cursor.setIndex( start + word.length()-2 );
01857 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01858
01859 if( bold)
01860 {
01861 newFormat->setBold(true);
01862 macro->addCommand(txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::Bold , false,KoTextObject::HighlightSelection ));
01863 }
01864 else if( underline )
01865 {
01866 newFormat->setUnderline(true);
01867 macro->addCommand(txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::Underline , false,KoTextObject::HighlightSelection ));
01868 }
01869 txtObj->emitHideCursor();
01870 textEditCursor->gotoRight();
01871 txtObj->emitShowCursor();
01872 return macro;
01873 }
01874 return 0L;
01875 }
01876
01877 KCommand *KoAutoFormat::doUseBulletStyle(KoTextCursor * , KoTextParag *parag, KoTextObject *txtObj, int& index )
01878 {
01879 KoTextDocument * textdoc = parag->textDocument();
01880 KoTextCursor cursor( parag->document() );
01881 KoTextString *s = parag->string();
01882 QChar ch = s->at( 0 ).c;
01883
01884 if( m_useBulletStyle && (ch =='*' || ch == '-' || ch =='+') && (s->at(1).c).isSpace())
01885 {
01886 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_FOOTNOTE )
01887 return 0L;
01888 KMacroCommand *macroCmd = new KMacroCommand( i18n("Autocorrect (use bullet style)"));
01889 cursor.setParag( parag );
01890 cursor.setIndex( 0 );
01891 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01892 cursor.setParag( parag );
01893 cursor.setIndex( 2 );
01894 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01895 KCommand *cmd=txtObj->removeSelectedTextCommand( &cursor, KoTextObject::HighlightSelection );
01896
01897 index -= 2;
01898 if(cmd)
01899 macroCmd->addCommand(cmd);
01900
01901 cursor.setParag( parag );
01902 cursor.setIndex( 0 );
01903 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01904
01905 cursor.setIndex( 2 );
01906 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01907
01908
01909 KoParagCounter c;
01910 if( m_bulletStyle.isNull() && (ch == '*' || ch == '+' || ch == '-'))
01911 {
01912 if ( ch =='*')
01913 {
01914 c.setNumbering( KoParagCounter::NUM_LIST );
01915 c.setStyle( KoParagCounter::STYLE_DISCBULLET );
01916 }
01917 else if ( ch =='+' || ch=='-')
01918 {
01919 c.setNumbering( KoParagCounter::NUM_LIST );
01920 c.setStyle( KoParagCounter::STYLE_CUSTOMBULLET );
01921 if ( ch =='-' )
01922 c.setCustomBulletCharacter( '-' );
01923 else if ( ch=='+')
01924 c.setCustomBulletCharacter( '+' );
01925 }
01926 }
01927 else
01928 {
01929 c.setNumbering( KoParagCounter::NUM_LIST );
01930 c.setStyle( KoParagCounter::STYLE_CUSTOMBULLET );
01931 c.setCustomBulletCharacter( m_bulletStyle );
01932 }
01933 c.setSuffix(QString::null);
01934 cmd=txtObj->setCounterCommand( &cursor, c ,KoTextObject::HighlightSelection );
01935 if( cmd)
01936 macroCmd->addCommand(cmd);
01937 if (parag->next() )
01938 cursor.setParag( parag->next() );
01939 else
01940 return 0L;
01941
01942 cursor.setIndex( 0 );
01943 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01944 cursor.setIndex( 0 );
01945 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01946 cmd=txtObj->setCounterCommand( &cursor, c ,KoTextObject::HighlightSelection );
01947 if(cmd)
01948 macroCmd->addCommand(cmd);
01949 return macroCmd;
01950 }
01951 return 0L;
01952
01953 }
01954
01955 KCommand *KoAutoFormat::doUseNumberStyle(KoTextCursor * , KoTextParag *parag, KoTextObject *txtObj, int& index )
01956 {
01957 if ( parag->counter() && parag->counter()->numbering() == KoParagCounter::NUM_FOOTNOTE )
01958 return 0L;
01959 KoTextDocument * textdoc = parag->textDocument();
01960 KoTextCursor cursor( parag->document() );
01961 KoTextString *s = parag->string();
01962 QString word;
01963 for ( int i = 0 ; i < s->length() - 1; i++ )
01964 {
01965 QChar ch = s->at( i ).c;
01966 if ( ch.isSpace() )
01967 break;
01968 word.append( ch );
01969 }
01970 QChar punct=word[word.length()-1];
01971 if( punct.isPunct() )
01972 {
01973 QString number=word.mid(0,word.length()-1);
01974 bool ok;
01975 uint val=number.toUInt(&ok);
01976 if( ok )
01977 {
01978 KMacroCommand *macroCmd = new KMacroCommand( i18n("Autocorrect (use number style)"));
01979 cursor.setParag( parag );
01980 cursor.setIndex( 0 );
01981 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01982 cursor.setParag( parag );
01983 cursor.setIndex( word.length()+1 );
01984 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01985 KCommand *cmd=txtObj->removeSelectedTextCommand( &cursor, KoTextObject::HighlightSelection );
01986
01987 index -= word.length()+1;
01988 if(cmd)
01989 macroCmd->addCommand(cmd);
01990
01991
01992 cursor.setParag( parag );
01993 cursor.setIndex( 0 );
01994 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
01995
01996 cursor.setIndex( 2 );
01997 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
01998
01999 KoParagCounter c;
02000 c.setNumbering( KoParagCounter::NUM_LIST );
02001 c.setStyle( KoParagCounter::STYLE_NUM );
02002 c.setSuffix(QString( punct ));
02003 c.setStartNumber( (int)val);
02004
02005
02006
02007
02008 if ( c.number( parag ) != (int)val )
02009 c.setRestartCounter( true );
02010
02011 cmd=txtObj->setCounterCommand( &cursor, c, KoTextObject::HighlightSelection );
02012 if( cmd)
02013 macroCmd->addCommand(cmd);
02014
02015
02016 c.setRestartCounter( false );
02017 cursor.setParag( parag->next() );
02018 cursor.setIndex( 0 );
02019 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
02020 cursor.setIndex( 0 );
02021 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
02022 cmd=txtObj->setCounterCommand( &cursor, c, KoTextObject::HighlightSelection );
02023 if(cmd)
02024 macroCmd->addCommand(cmd);
02025 return macroCmd;
02026 }
02027 }
02028 return 0L;
02029 }
02030
02031
02032 KCommand * KoAutoFormat::doRemoveSpaceBeginEndLine( KoTextCursor *textEditCursor, KoTextParag *parag, KoTextObject *txtObj, int &index )
02033 {
02034 KoTextString *s = parag->string();
02035 KoTextDocument * textdoc = parag->textDocument();
02036 KoTextCursor cursor( parag->document() );
02037
02038 KMacroCommand *macroCmd = 0L;
02039
02040 for ( int i = parag->lastCharPos(); i >= 0; --i )
02041 {
02042 QChar ch = s->at( i ).c;
02043 if ( ch != ' ' )
02044 {
02045 if( i == parag->lastCharPos() )
02046 break;
02047 cursor.setParag( parag );
02048 cursor.setIndex( i+1 );
02049 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
02050 cursor.setParag( parag );
02051 cursor.setIndex( parag->lastCharPos()+1 );
02052 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
02053 KCommand *cmd=txtObj->replaceSelectionCommand( &cursor, "", KoTextObject::HighlightSelection, QString::null );
02054
02055 if(cmd)
02056 {
02057 if ( index > i )
02058 index = i;
02059 if ( !macroCmd )
02060 macroCmd = new KMacroCommand( i18n("Autocorrect (remove start and end line space)"));
02061 macroCmd->addCommand(cmd);
02062 }
02063 break;
02064 }
02065 }
02066
02067
02068
02069 for ( int i = 0 ; i <= parag->lastCharPos() ; i++ )
02070 {
02071 QChar ch = s->at( i ).c;
02072 if ( ch != ' ' )
02073 {
02074 if( i == 0 )
02075 break;
02076
02077 cursor.setParag( parag );
02078 cursor.setIndex( 0 );
02079 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
02080 cursor.setParag( parag );
02081 cursor.setIndex( i );
02082 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
02083 KCommand *cmd=txtObj->replaceSelectionCommand( &cursor, "", KoTextObject::HighlightSelection, QString::null );
02084
02085 if(cmd)
02086 {
02087 index -= i;
02088 if ( !macroCmd )
02089 macroCmd = new KMacroCommand( i18n("Autocorrect (remove start and end line space)"));
02090 macroCmd->addCommand(cmd);
02091 }
02092 break;
02093 }
02094 }
02095
02096 if( macroCmd )
02097 {
02098 txtObj->emitHideCursor();
02099 textEditCursor->setParag( parag->next() );
02100
02101 txtObj->emitShowCursor();
02102 }
02103 return macroCmd;
02104 }
02105
02106 KCommand *KoAutoFormat::doCapitalizeNameOfDays( KoTextCursor* textEditCursor, KoTextParag *parag, int index, const QString & word , KoTextObject *txtObj )
02107 {
02108
02109
02110 int pos = m_cacheNameOfDays.findIndex( word.lower() );
02111 if ( pos == -1 )
02112 return 0L;
02113 KoTextDocument * textdoc = parag->textDocument();
02114 QString replaceStr= m_cacheNameOfDays[pos];
02115 int start = index - replaceStr.length();
02116 int length = replaceStr.length();
02117 if( word.at(0).isLetter() && word.at(0)==word.at(0).lower() )
02118 {
02119 KoTextCursor cursor( parag->document() );
02120 cursor.setParag( parag );
02121 cursor.setIndex( start );
02122 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
02123 cursor.setIndex( start + length );
02124 QString replacement = replaceStr.at(0).upper() + replaceStr.right( length-1 );
02125 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
02126 QString cmdName=i18n("Capitalize Name of Days");
02127 KCommand *cmd =txtObj->replaceSelectionCommand( textEditCursor, replacement,
02128 KoTextObject::HighlightSelection,
02129 cmdName );
02130 txtObj->emitHideCursor();
02131 textEditCursor->gotoRight();
02132 txtObj->emitShowCursor();
02133 return cmd;
02134 }
02135 return 0L;
02136 }
02137
02138 KCommand *KoAutoFormat::doAutoSuperScript( KoTextCursor* textEditCursor, KoTextParag *parag, int index, const QString & word , KoTextObject *txtObj )
02139 {
02140 KoAutoFormatEntryMap::Iterator it = m_superScriptEntries.begin();
02141 bool found = false;
02142 QString replace;
02143 for ( ; it != m_superScriptEntries.end() ; ++it )
02144 {
02145 if( it.key()==word)
02146 {
02147 replace = it.data().replace();
02148 found = true;
02149 break;
02150 }
02151 else if ( it.key()=="othernb")
02152 {
02153 QString tmp = it.data().replace();
02154 int pos = word.find( tmp );
02155 if( pos != -1)
02156 {
02157 if( pos + tmp.length() == word.length())
02158 {
02159 bool ok;
02160 word.left( pos ).toInt( &ok);
02161 if( ok )
02162 {
02163 replace = tmp;
02164 found = true;
02165 break;
02166 }
02167 }
02168 }
02169 }
02170 }
02171 if (found )
02172 {
02173 KoTextDocument * textdoc = parag->textDocument();
02174
02175 int start = index - replace.length();
02176 KoTextFormat * lastFormat = parag->at( start )->format();
02177 KoTextFormat * newFormat = new KoTextFormat(*lastFormat);
02178 KoTextCursor cursor( parag->document() );
02179
02180 cursor.setParag( parag );
02181 cursor.setIndex( start );
02182 textdoc->setSelectionStart( KoTextObject::HighlightSelection, &cursor );
02183 cursor.setIndex( start + word.length() -1 );
02184 textdoc->setSelectionEnd( KoTextObject::HighlightSelection, &cursor );
02185 newFormat->setVAlign(KoTextFormat::AlignSuperScript);
02186 KCommand *cmd =txtObj->setFormatCommand( textEditCursor, 0L, newFormat, KoTextFormat::VAlign , false,KoTextObject::HighlightSelection );
02187 textdoc->removeSelection( KoTextObject::HighlightSelection );
02188
02189 return cmd;
02190 }
02191 return 0L;
02192 }
02193
02194 bool KoAutoFormat::doIgnoreDoubleSpace( KoTextParag *parag, int index, QChar ch )
02195 {
02196 if( m_ignoreDoubleSpace && ch==' ' && index >= 0 )
02197 {
02198 KoTextString *s = parag->string();
02199 QChar ch = s->at( index ).c;
02200 if ( ch==' ' )
02201 return true;
02202 }
02203 return false;
02204 }
02205
02206 void KoAutoFormat::configTypographicSimpleQuotes( TypographicQuotes _tq )
02207 {
02208 m_typographicSimpleQuotes = _tq;
02209 }
02210
02211 void KoAutoFormat::configTypographicDoubleQuotes( TypographicQuotes _tq )
02212 {
02213 m_typographicDoubleQuotes = _tq;
02214 }
02215
02216 void KoAutoFormat::configUpperCase( bool _uc )
02217 {
02218 m_convertUpperCase = _uc;
02219 }
02220
02221 void KoAutoFormat::configUpperUpper( bool _uu )
02222 {
02223 m_convertUpperUpper = _uu;
02224 }
02225
02226 void KoAutoFormat::configAdvancedAutocorrect( bool _aa )
02227 {
02228 m_advancedAutoCorrect = _aa;
02229 }
02230
02231 void KoAutoFormat::configAutoDetectUrl(bool _au)
02232 {
02233 m_autoDetectUrl=_au;
02234 }
02235
02236 void KoAutoFormat::configIgnoreDoubleSpace( bool _ids)
02237 {
02238 m_ignoreDoubleSpace=_ids;
02239 }
02240
02241 void KoAutoFormat::configRemoveSpaceBeginEndLine( bool _space)
02242 {
02243 m_removeSpaceBeginEndLine=_space;
02244 }
02245
02246 void KoAutoFormat::configUseBulletStyle( bool _ubs)
02247 {
02248 m_useBulletStyle=_ubs;
02249 }
02250
02251 void KoAutoFormat::configBulletStyle( QChar b )
02252 {
02253 m_bulletStyle = b;
02254 }
02255
02256 void KoAutoFormat::configAutoChangeFormat( bool b)
02257 {
02258 m_autoChangeFormat = b;
02259 }
02260
02261
02262 void KoAutoFormat::configAutoReplaceNumber( bool b )
02263 {
02264 m_autoReplaceNumber = b;
02265 }
02266
02267 void KoAutoFormat::configAutoNumberStyle( bool b )
02268 {
02269 m_useAutoNumberStyle = b;
02270 }
02271
02272 void KoAutoFormat::configCompletion( bool b )
02273 {
02274 m_completion = b;
02275 }
02276
02277 void KoAutoFormat::configToolTipCompletion( bool b )
02278 {
02279 m_toolTipCompletion = b;
02280 if (!b && m_completionBox)
02281 {
02282 delete m_completionBox;
02283 m_completionBox = 0;
02284 }
02285 }
02286
02287 void KoAutoFormat::configKeyCompletionAction( KeyCompletionAction action )
02288 {
02289 m_keyCompletionAction = action;
02290 }
02291
02292 void KoAutoFormat::configAppendSpace( bool b)
02293 {
02294 m_completionAppendSpace= b;
02295 }
02296
02297 void KoAutoFormat::configMinWordLength( uint val )
02298 {
02299 m_minCompletionWordLength = val;
02300 }
02301
02302 void KoAutoFormat::configNbMaxCompletionWord( uint val )
02303 {
02304 m_nbMaxCompletionWord = val;
02305 }
02306
02307
02308 void KoAutoFormat::configAddCompletionWord( bool b )
02309 {
02310 m_addCompletionWord= b;
02311 }
02312
02313 bool KoAutoFormat::isUpper( const QChar &c )
02314 {
02315 return c.lower() != c;
02316 }
02317
02318 bool KoAutoFormat::isLower( const QChar &c )
02319 {
02320
02321
02322 return c.upper() != c;
02323 }
02324
02325 bool KoAutoFormat::isMark( const QChar &c )
02326 {
02327 return ( c == QChar( '.' ) ||
02328 c == QChar( '?' ) ||
02329 c == QChar( '!' ) );
02330 }
02331
02332 bool KoAutoFormat::isSeparator( const QChar &c )
02333 {
02334 return ( !c.isLetter() && !c.isNumber() && !c.isDigit() );
02335 }
02336
02337 void KoAutoFormat::buildMaxLen()
02338 {
02339 m_maxFindLength = 0;
02340 QDictIterator<KoAutoFormatEntry> it( m_entries );
02341 for( ; it.current(); ++it )
02342 {
02343 m_maxFindLength = QMAX( m_maxFindLength, it.currentKey().length() );
02344 }
02345 QDictIterator<KoAutoFormatEntry> it2( m_allLanguages );
02346 for( ; it2.current(); ++it2 )
02347 {
02348 m_maxFindLength = QMAX( m_maxFindLength, it2.currentKey().length() );
02349 }
02350 }
02351
02352 QStringList KoAutoFormat::listCompletion() const
02353 {
02354 return m_listCompletion->items();
02355 }
02356
02357
02358 void KoAutoFormat::configIncludeTwoUpperUpperLetterException( bool b)
02359 {
02360 m_includeTwoUpperLetterException = b;
02361 }
02362
02363 void KoAutoFormat::configIncludeAbbreviation( bool b )
02364 {
02365 m_includeAbbreviation = b;
02366 }
02367
02368 void KoAutoFormat::configAutoSuperScript( bool b )
02369 {
02370 m_bAutoSuperScript = b;
02371 }
02372
02373 void KoAutoFormat::configCorrectionWithFormat( bool b)
02374 {
02375 m_bAutoCorrectionWithFormat = b;
02376 }
02377
02378 void KoAutoFormat::configCapitalizeNameOfDays( bool b)
02379 {
02380 m_bCapitalizeNameOfDays = b;
02381 }
02382
02383 void KoAutoFormat::configAutoFormatLanguage( const QString &_lang)
02384 {
02385 m_autoFormatLanguage=_lang;
02386 }
02387
02388 KCommand *KoAutoFormat::applyAutoFormat( KoTextObject * obj )
02389 {
02390 KoTextParag * parag = obj->textDocument()->firstParag();
02391 KoTextCursor *cursor = new KoTextCursor( obj->textDocument() );
02392 KMacroCommand *macro = 0L;
02393 while ( parag )
02394 {
02395 cursor->setIndex(0);
02396 for (int i=0;i<parag->length();i++)
02397 {
02398 cursor->gotoRight();
02399
02400 if (i == parag->length()-1)
02401 doAutoFormat(cursor,parag,i,'\n',obj);
02402 else
02403 doAutoFormat(cursor,parag,i, parag->string()->at(i).c,obj);
02404 }
02405 parag = parag->next();
02406
02407 }
02408 delete cursor;
02409 return macro;
02410 }
02411
02412 void KoAutoFormat::changeTextFormat(KoSearchContext *formatOptions, KoTextFormat * format, int & flags )
02413 {
02414 if (formatOptions )
02415 {
02416 if (formatOptions->m_optionsMask & KoSearchContext::Bold)
02417 {
02418 format->setBold( formatOptions->m_options & KoSearchContext::Bold);
02419 flags |=KoTextFormat::Bold;
02420 }
02421 if ( formatOptions->m_optionsMask & KoSearchContext::Size)
02422 {
02423 format->setPointSize( formatOptions->m_size );
02424 flags |=KoTextFormat::Size;
02425 }
02426 if ( formatOptions->m_optionsMask & KoSearchContext::Family)
02427 {
02428 format->setFamily( formatOptions->m_family );
02429 flags |=KoTextFormat::Family;
02430 }
02431 if ( formatOptions->m_optionsMask & KoSearchContext::Color)
02432 {
02433 format->setColor(formatOptions->m_color);
02434 flags |=KoTextFormat::Color;
02435 }
02436 if ( formatOptions->m_optionsMask & KoSearchContext::BgColor)
02437 {
02438 format->setTextBackgroundColor(formatOptions->m_backGroundColor);
02439 flags |=KoTextFormat::TextBackgroundColor;
02440 }
02441
02442 if ( formatOptions->m_optionsMask & KoSearchContext::Italic)
02443 {
02444 format->setItalic( formatOptions->m_options & KoSearchContext::Italic);
02445 flags |=KoTextFormat::Italic;
02446 }
02447 if ( formatOptions->m_optionsMask & KoSearchContext::WordByWord)
02448 {
02449 format->setWordByWord( formatOptions->m_options & KoSearchContext::WordByWord );
02450 flags |=KoTextFormat::WordByWord;
02451 }
02452 if ( formatOptions->m_optionsMask & KoSearchContext::Shadow)
02453 {
02454 if ( formatOptions->m_options & KoSearchContext::Shadow )
02455 format->setShadow( 1, 1, Qt::gray );
02456 else
02457 format->setShadow( 0, 0, QColor() );
02458 flags |=KoTextFormat::ShadowText;
02459 }
02460
02461 if ( formatOptions->m_optionsMask & KoSearchContext::Underline)
02462 {
02463 format->setUnderlineType(formatOptions->m_underline);
02464 flags |=KoTextFormat::ExtendUnderLine;
02465 }
02466 if ( formatOptions->m_optionsMask & KoSearchContext::StrikeOut)
02467 {
02468 format->setStrikeOutType(formatOptions->m_strikeOut);
02469 flags |= KoTextFormat::StrikeOut;
02470 }
02471 if ( formatOptions->m_optionsMask & KoSearchContext::VertAlign)
02472 {
02473 format->setVAlign(formatOptions->m_vertAlign);
02474 flags |=KoTextFormat::VAlign;
02475 }
02476 if ( formatOptions->m_optionsMask & KoSearchContext::Attribute)
02477 {
02478 format->setAttributeFont(formatOptions->m_attribute);
02479 flags |= KoTextFormat::Attribute;
02480 }
02481 if (formatOptions->m_optionsMask & KoSearchContext::Language)
02482 {
02483 flags |= KoTextFormat::Language;
02484 format->setLanguage( formatOptions->m_language );
02485 }
02486 }
02487 }
02488
02489 #include "koAutoFormat.moc"