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