Kate
katebuffer.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (c) 2000 Waldo Bastian <bastian@kde.org> 00003 Copyright (C) 2002-2004 Christoph Cullmann <cullmann@kde.org> 00004 Copyright (C) 2007 Mirko Stocker <me@misto.ch> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License version 2 as published by the Free Software Foundation. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #include "katebuffer.h" 00022 #include "katebuffer.moc" 00023 00024 #include <sys/types.h> 00025 #include <sys/stat.h> 00026 #include <unistd.h> 00027 #include <stdlib.h> 00028 00029 #include "katedocument.h" 00030 #include "katehighlight.h" 00031 #include "kateconfig.h" 00032 #include "kateglobal.h" 00033 #include "kateautoindent.h" 00034 00035 #include <kdebug.h> 00036 #include <kglobal.h> 00037 #include <kcharsets.h> 00038 #include <kde_file.h> 00039 00040 // on the fly compression 00041 #include <kfilterdev.h> 00042 #include <kmimetype.h> 00043 00044 #include <QtCore/QFile> 00045 #include <QtCore/QTextStream> 00046 #include <QtCore/QTimer> 00047 #include <QtCore/QTextCodec> 00048 #include <QtCore/QDate> 00049 00050 #include <limits.h> 00051 00057 static const int KATE_HL_LOOKAHEAD = 64; 00058 00062 static const int KATE_MAX_DYNAMIC_CONTEXTS = 512; 00063 00067 KateBuffer::KateBuffer(KateDocument *doc) 00068 : Kate::TextBuffer (doc), 00069 m_doc (doc), 00070 m_brokenEncoding (false), 00071 m_highlight (0), 00072 m_regionTree (this), 00073 m_tabWidth (8), 00074 m_lineHighlighted (0), 00075 m_ctxChanged (true), 00076 m_maxDynamicContexts (KATE_MAX_DYNAMIC_CONTEXTS) 00077 { 00078 // we need kate global to stay alive 00079 KateGlobal::incRef (); 00080 } 00081 00085 KateBuffer::~KateBuffer() 00086 { 00087 // release HL 00088 if (m_highlight) 00089 m_highlight->release(); 00090 00091 // release kate global 00092 KateGlobal::decRef (); 00093 } 00094 00095 void KateBuffer::editStart () 00096 { 00097 if (!startEditing ()) 00098 return; 00099 } 00100 00101 void KateBuffer::editEnd () 00102 { 00103 if (!finishEditing()) 00104 return; 00105 00106 if (editingChangedBuffer ()) 00107 { 00108 // hl update !!! 00109 if (m_highlight && editingMinimalLineChanged () <= editingMaximalLineChanged () && editingMaximalLineChanged () <= m_lineHighlighted) 00110 { 00111 // look one line too far, needed for linecontinue stuff 00112 int editTagLineEnd = editingMaximalLineChanged () + 1; 00113 int editTagLineStart = editingMinimalLineChanged (); 00114 00115 // look one line before, needed nearly 100% only for indentation based folding ! 00116 if (editTagLineStart > 0) 00117 --editTagLineStart; 00118 00119 m_ctxChanged = doHighlight ( 00120 editTagLineStart, 00121 editTagLineEnd, 00122 true); 00123 00124 m_lineHighlighted = editTagLineEnd; 00125 } 00126 } 00127 } 00128 00129 void KateBuffer::clear() 00130 { 00131 // call original clear function 00132 Kate::TextBuffer::clear (); 00133 00134 m_regionTree.clear(); 00135 00136 // reset the state 00137 m_brokenEncoding = false; 00138 00139 m_lineHighlighted = 0; 00140 m_ctxChanged = true; 00141 } 00142 00143 bool KateBuffer::openFile (const QString &m_file) 00144 { 00145 // first: setup fallback and normal encoding 00146 setEncodingProberType (KateGlobalConfig::global()->proberType ()); 00147 setFallbackTextCodec (KateGlobalConfig::global()->fallbackCodec ()); 00148 setTextCodec (m_doc->config()->codec ()); 00149 00150 // setup eol 00151 setEndOfLineMode ((EndOfLineMode) m_doc->config()->eol()); 00152 00153 // remove trailing spaces? 00154 // NOTE: The buffer won't actually remove trailing space on load. This is because 00155 // we need to do it later, after the config and variables have been parsed. 00156 setRemoveTrailingSpaces (m_doc->config()->removeSpaces()); 00157 00158 // then, try to load the file 00159 m_brokenEncoding = false; 00160 if (!load (m_file, m_brokenEncoding)) 00161 return false; 00162 00163 // save back encoding 00164 m_doc->config()->setEncoding (textCodec()->name()); 00165 00166 // set eol mode, if a eol char was found 00167 if (m_doc->config()->allowEolDetection()) 00168 m_doc->config()->setEol (endOfLineMode ()); 00169 00170 // generate a bom? 00171 if (generateByteOrderMark()) 00172 m_doc->config()->setBom (true); 00173 00174 // fix region tree 00175 m_regionTree.fixRoot (lines ()); 00176 00177 // okay, loading did work 00178 return true; 00179 } 00180 00181 bool KateBuffer::canEncode () 00182 { 00183 QTextCodec *codec = m_doc->config()->codec(); 00184 00185 kDebug(13020) << "ENC NAME: " << codec->name(); 00186 00187 // hardcode some unicode encodings which can encode all chars 00188 if ((QString(codec->name()) == "UTF-8") || (QString(codec->name()) == "ISO-10646-UCS-2")) 00189 return true; 00190 00191 for (int i=0; i < lines(); i++) 00192 { 00193 if (!codec->canEncode (line(i)->string())) 00194 { 00195 kDebug(13020) << "STRING LINE: " << line(i)->string(); 00196 kDebug(13020) << "ENC WORKING: FALSE"; 00197 00198 return false; 00199 } 00200 } 00201 00202 return true; 00203 } 00204 00205 bool KateBuffer::saveFile (const QString &m_file) 00206 { 00207 // first: setup fallback and normal encoding 00208 setEncodingProberType (KateGlobalConfig::global()->proberType ()); 00209 setFallbackTextCodec (KateGlobalConfig::global()->fallbackCodec ()); 00210 setTextCodec (m_doc->config()->codec ()); 00211 00212 // setup eol 00213 setEndOfLineMode ((EndOfLineMode) m_doc->config()->eol()); 00214 00215 // generate bom? 00216 setGenerateByteOrderMark (m_doc->config()->bom()); 00217 00218 // remove trailing spaces? 00219 setRemoveTrailingSpaces (m_doc->config()->removeSpaces()); 00220 00221 // try to save 00222 if (!save (m_file)) 00223 return false; 00224 00225 // no longer broken encoding, or we don't care 00226 m_brokenEncoding = false; 00227 00228 // okay 00229 return true; 00230 } 00231 00232 void KateBuffer::ensureHighlighted (int line) 00233 { 00234 // valid line at all? 00235 if (line < 0 || line >= lines ()) 00236 return; 00237 00238 // already hl up-to-date for this line? 00239 if (line < m_lineHighlighted) 00240 return; 00241 00242 // update hl until this line + max KATE_HL_LOOKAHEAD 00243 int end = qMin(line + KATE_HL_LOOKAHEAD, lines ()-1); 00244 00245 m_ctxChanged = doHighlight ( m_lineHighlighted, end, m_ctxChanged ); 00246 00247 m_lineHighlighted = end; 00248 } 00249 00250 void KateBuffer::wrapLine (const KTextEditor::Cursor &position) 00251 { 00252 // call original 00253 Kate::TextBuffer::wrapLine (position); 00254 00255 if (m_lineHighlighted > position.line()+1) 00256 m_lineHighlighted++; 00257 00258 m_regionTree.lineHasBeenInserted (position.line()+1); 00259 00260 } 00261 00262 void KateBuffer::unwrapLine (int line) 00263 { 00264 // call original 00265 Kate::TextBuffer::unwrapLine (line); 00266 00267 if (m_lineHighlighted > line) 00268 m_lineHighlighted--; 00269 00270 m_regionTree.lineHasBeenRemoved (line); 00271 } 00272 00273 void KateBuffer::setTabWidth (int w) 00274 { 00275 if ((m_tabWidth != w) && (m_tabWidth > 0)) 00276 { 00277 m_tabWidth = w; 00278 00279 if (m_highlight && m_highlight->foldingIndentationSensitive()) 00280 invalidateHighlighting(); 00281 } 00282 } 00283 00284 void KateBuffer::setHighlight(int hlMode) 00285 { 00286 KateHighlighting *h = KateHlManager::self()->getHl(hlMode); 00287 00288 // aha, hl will change 00289 if (h != m_highlight) 00290 { 00291 bool invalidate = !h->noHighlighting(); 00292 00293 if (m_highlight) 00294 { 00295 m_highlight->release(); 00296 invalidate = true; 00297 } 00298 00299 h->use(); 00300 00301 // Clear code folding tree (see bug #124102) 00302 m_regionTree.clear(); 00303 m_regionTree.fixRoot(lines()); 00304 00305 m_highlight = h; 00306 00307 if (invalidate) 00308 invalidateHighlighting(); 00309 00310 // inform the document that the hl was really changed 00311 // needed to update attributes and more ;) 00312 m_doc->bufferHlChanged (); 00313 00314 // try to set indentation 00315 if (!h->indentation().isEmpty()) 00316 m_doc->config()->setIndentationMode (h->indentation()); 00317 } 00318 } 00319 00320 void KateBuffer::invalidateHighlighting() 00321 { 00322 m_lineHighlighted = 0; 00323 m_ctxChanged = true; 00324 } 00325 00326 00327 void KateBuffer::updatePreviousNotEmptyLine(int current_line,bool addindent,int deindent) 00328 { 00329 Kate::TextLine textLine; 00330 do { 00331 if (current_line == 0) return; 00332 00333 --current_line; 00334 00335 textLine = plainLine (current_line); 00336 } while (textLine->firstChar()==-1); 00337 00338 kDebug(13020)<<"updatePreviousNotEmptyLine: updating line:"<<current_line; 00339 QVector<int> foldingList=textLine->foldingListArray(); 00340 while ( !foldingList.isEmpty() && abs(foldingList.at(foldingList.size()-2)) == 1) { 00341 foldingList.resize(foldingList.size()-2); 00342 } 00343 addIndentBasedFoldingInformation(foldingList,textLine->length(),addindent,deindent); 00344 textLine->setFoldingList(foldingList); 00345 00346 bool retVal_folding = false; 00347 m_regionTree.updateLine (current_line, &foldingList, &retVal_folding, true,false); 00348 00349 // tagLines() is emitted from KatBuffer::doHighlight()! 00350 } 00351 00352 void KateBuffer::addIndentBasedFoldingInformation(QVector<int> &foldingList,int linelength,bool addindent,int deindent) 00353 { 00354 if (addindent) { 00355 //kDebug(13020)<<"adding indent for line :"<<current_line + buf->startLine()<<" textLine->noIndentBasedFoldingAtStart"<<textLine->noIndentBasedFoldingAtStart(); 00356 //kDebug(13020)<<"adding ident"; 00357 foldingList.resize (foldingList.size() + 2); 00358 foldingList[foldingList.size()-2] = 1; 00359 foldingList[foldingList.size()-1] = 0; 00360 } 00361 //kDebug(13020)<<"DEINDENT: "<<deindent; 00362 if (deindent > 0) 00363 { 00364 //foldingList.resize (foldingList.size() + (deindent*2)); 00365 00366 //Make the whole last line marked as still belonging to the block 00367 for (int z=0;z<deindent;z++) { 00368 foldingList << -1 << linelength+1; 00369 } 00370 00371 /* for (int z= foldingList.size()-(deindent*2); z < foldingList.size(); z=z+2) 00372 { 00373 foldingList[z] = -1; 00374 foldingList[z+1] = 0; 00375 }*/ 00376 } 00377 } 00378 00379 00380 bool KateBuffer::isEmptyLine(Kate::TextLine textline) 00381 { 00382 QLinkedList<QRegExp> l; 00383 l=m_highlight->emptyLines(textline->attribute(0)); 00384 if (l.isEmpty()) return false; 00385 QString txt=textline->string(); 00386 foreach(const QRegExp &re,l) { 00387 if (re.exactMatch(txt)) return true; 00388 } 00389 return false; 00390 } 00391 00392 bool KateBuffer::doHighlight (int startLine, int endLine, bool invalidate) 00393 { 00394 // no hl around, no stuff to do 00395 if (!m_highlight) 00396 return false; 00397 00398 #ifdef BUFFER_DEBUGGING 00399 QTime t; 00400 t.start(); 00401 kDebug (13020) << "HIGHLIGHTED START --- NEED HL, LINESTART: " << startLine << " LINEEND: " << endLine; 00402 kDebug (13020) << "HL UNTIL LINE: " << m_lineHighlighted; 00403 kDebug (13020) << "HL DYN COUNT: " << KateHlManager::self()->countDynamicCtxs() << " MAX: " << m_maxDynamicContexts; 00404 #endif 00405 00406 // see if there are too many dynamic contexts; if yes, invalidate HL of all documents 00407 if (KateHlManager::self()->countDynamicCtxs() >= m_maxDynamicContexts) 00408 { 00409 { 00410 if (KateHlManager::self()->resetDynamicCtxs()) 00411 { 00412 #ifdef BUFFER_DEBUGGING 00413 kDebug (13020) << "HL invalidated - too many dynamic contexts ( >= " << m_maxDynamicContexts << ")"; 00414 #endif 00415 00416 // avoid recursive invalidation 00417 KateHlManager::self()->setForceNoDCReset(true); 00418 00419 foreach(KateDocument* doc, KateGlobal::self()->kateDocuments()) 00420 doc->makeAttribs(); 00421 00422 // doHighlight *shall* do his work. After invalidation, some highlight has 00423 // been recalculated, but *maybe not* until endLine ! So we shall force it manually... 00424 m_ctxChanged = doHighlight ( m_lineHighlighted, endLine, false ); 00425 m_lineHighlighted = endLine; 00426 00427 KateHlManager::self()->setForceNoDCReset(false); 00428 00429 return false; 00430 } 00431 else 00432 { 00433 m_maxDynamicContexts *= 2; 00434 00435 #ifdef BUFFER_DEBUGGING 00436 kDebug (13020) << "New dynamic contexts limit: " << m_maxDynamicContexts; 00437 #endif 00438 } 00439 } 00440 } 00441 00442 // get previous line, if any 00443 Kate::TextLine prevLine; 00444 00445 if (startLine >= 1) 00446 prevLine = plainLine (startLine-1); 00447 else 00448 prevLine = Kate::TextLine (new Kate::TextLineData ()); 00449 00450 // does we need to emit a signal for the folding changes ? 00451 bool codeFoldingUpdate = false; 00452 00453 // here we are atm, start at start line in the block 00454 int current_line = startLine; 00455 int start_spellchecking = -1; 00456 int last_line_spellchecking = -1; 00457 // do we need to continue 00458 bool stillcontinue=false; 00459 bool indentContinueWhitespace=false; 00460 bool indentContinueNextWhitespace=false; 00461 bool ctxChanged = false; 00462 // loop over the lines of the block, from startline to endline or end of block 00463 // if stillcontinue forces us to do so 00464 while ( (current_line < lines()) && (stillcontinue || (current_line <= endLine)) ) 00465 { 00466 // current line 00467 Kate::TextLine textLine = plainLine (current_line); 00468 00469 QVector<int> foldingList; 00470 ctxChanged = false; 00471 00472 m_highlight->doHighlight (prevLine.data(), textLine.data(), foldingList, ctxChanged); 00473 00474 #ifdef BUFFER_DEBUGGING 00475 // debug stuff 00476 kDebug( 13020 ) << "current line to hl: " << current_line + buf->startLine(); 00477 kDebug( 13020 ) << "text length: " << textLine->length() << " attribute list size: " << textLine->attributesList().size(); 00478 00479 const QVector<int> &ml (textLine->attributesList()); 00480 for (int i=2; i < ml.size(); i+=3) 00481 { 00482 kDebug( 13020 ) << "start: " << ml.at(i-2) << " len: " << ml.at(i-1) << " at: " << ml.at(i) << " "; 00483 } 00484 kDebug( 13020 ); 00485 #endif 00486 00487 // 00488 // indentation sensitive folding 00489 // 00490 bool indentChanged = false; 00491 if (m_highlight->foldingIndentationSensitive()) 00492 { 00493 // get the indentation array of the previous line to start with ! 00494 QVector<unsigned short> indentDepth (prevLine->indentationDepthArray()); 00495 00496 // current indentation of this line 00497 int iDepth = textLine->indentDepth(m_tabWidth); 00498 if (current_line==0) 00499 { 00500 indentDepth.resize (1); 00501 indentDepth[0] = iDepth; 00502 } 00503 00504 textLine->setNoIndentBasedFoldingAtStart(prevLine->noIndentBasedFolding()); 00505 00506 // this line is empty, beside spaces, or has indentaion based folding disabled, use indentation depth of the previous line ! 00507 00508 #ifdef BUFFER_DEBUGGING 00509 kDebug(13020)<<"current_line:"<<current_line<<" textLine->noIndentBasedFoldingAtStart"<<textLine->noIndentBasedFoldingAtStart(); 00510 #endif 00511 00512 if ( (textLine->firstChar() == -1) || textLine->noIndentBasedFoldingAtStart() || isEmptyLine(textLine) ) 00513 { 00514 // do this to get skipped empty lines indent right, which was given in the indenation array 00515 if (!prevLine->indentationDepthArray().isEmpty()) 00516 { 00517 iDepth = prevLine->indentationDepthArray().last(); 00518 00519 #ifdef BUFFER_DEBUGGING 00520 kDebug(13020)<<"reusing old depth as current"; 00521 #endif 00522 } 00523 else 00524 { 00525 iDepth = prevLine->indentDepth(m_tabWidth); 00526 00527 #ifdef BUFFER_DEBUGGING 00528 kDebug(13020)<<"creating indentdepth for previous line"; 00529 #endif 00530 } 00531 } 00532 00533 #ifdef BUFFER_DEBUGGING 00534 kDebug(13020)<<"iDepth:"<<iDepth; 00535 #endif 00536 00537 // query the next line indentation, if we are at the end of the block 00538 // use the first line of the next buf block 00539 int nextLineIndentation = 0; 00540 bool nextLineIndentationValid=true; 00541 indentContinueNextWhitespace=false; 00542 if ((current_line+1) < lines()) 00543 { 00544 if ( (plainLine (current_line+1)->firstChar() == -1) || isEmptyLine(plainLine (current_line+1)) ) 00545 { 00546 nextLineIndentation = iDepth; 00547 indentContinueNextWhitespace=true; 00548 } 00549 else 00550 nextLineIndentation = plainLine (current_line+1)->indentDepth(m_tabWidth); 00551 } 00552 else 00553 { 00554 nextLineIndentationValid=false; 00555 } 00556 00557 if (!textLine->noIndentBasedFoldingAtStart()) { 00558 00559 if ((iDepth > 0) && (indentDepth.isEmpty() || (indentDepth.last() < iDepth))) 00560 { 00561 #ifdef BUFFER_DEBUGGING 00562 kDebug(13020)<<"adding depth to \"stack\":"<<iDepth; 00563 #endif 00564 00565 indentDepth.append (iDepth); 00566 } else { 00567 if (!indentDepth.isEmpty()) 00568 { 00569 for (int z=indentDepth.size()-1; z > -1; z--) 00570 if (indentDepth.at(z) > iDepth) 00571 indentDepth.resize(z); 00572 if ((iDepth > 0) && (indentDepth.isEmpty() || (indentDepth.last() < iDepth))) 00573 { 00574 #ifdef BUFFER_DEBUGGING 00575 kDebug(13020)<<"adding depth to \"stack\":"<<iDepth; 00576 #endif 00577 00578 indentDepth.append (iDepth); 00579 if (prevLine->firstChar()==-1) { 00580 00581 } 00582 } 00583 } 00584 } 00585 } 00586 00587 if (!textLine->noIndentBasedFolding()) 00588 { 00589 if (nextLineIndentationValid) 00590 { 00591 //if (textLine->firstChar()!=-1) 00592 { 00593 #ifdef BUFFER_DEBUGGING 00594 kDebug(13020)<<"nextLineIndentation:"<<nextLineIndentation; 00595 #endif 00596 00597 bool addindent=false; 00598 int deindent=0; 00599 00600 #ifdef BUFFER_DEBUGGING 00601 if (!indentDepth.isEmpty()) 00602 kDebug(13020)<<"indentDepth.last():"<<indentDepth.last(); 00603 #endif 00604 00605 if (nextLineIndentation > 0 && ( indentDepth.isEmpty() || indentDepth.last() < nextLineIndentation)) 00606 { 00607 #ifdef BUFFER_DEBUGGING 00608 kDebug(13020)<<"addindent==true"; 00609 #endif 00610 00611 addindent=true; 00612 } else { 00613 if (!indentDepth.isEmpty() && indentDepth.last() > nextLineIndentation) 00614 { 00615 #ifdef BUFFER_DEBUGGING 00616 kDebug(13020)<<"...."; 00617 #endif 00618 00619 for (int z=indentDepth.size()-1; z > -1; z--) 00620 { 00621 #ifdef BUFFER_DEBUGGING 00622 kDebug(13020)<<indentDepth.at(z)<<" "<<nextLineIndentation; 00623 #endif 00624 00625 if (indentDepth.at(z) > nextLineIndentation) 00626 deindent++; 00627 } 00628 } 00629 } 00630 /* } 00631 if (textLine->noIndentBasedFolding()) kDebug(13020)<<"=============================indentation based folding disabled======================"; 00632 if (!textLine->noIndentBasedFolding()) {*/ 00633 if ((textLine->firstChar()==-1)) { 00634 updatePreviousNotEmptyLine(current_line,addindent,deindent); 00635 codeFoldingUpdate=true; 00636 } 00637 else 00638 { 00639 addIndentBasedFoldingInformation(foldingList,textLine->length(),addindent,deindent); 00640 } 00641 } 00642 } 00643 } 00644 indentChanged = !(indentDepth == textLine->indentationDepthArray()); 00645 00646 // assign the new array to the textline ! 00647 if (indentChanged) 00648 textLine->setIndentationDepth (indentDepth); 00649 00650 indentContinueWhitespace=textLine->firstChar()==-1; 00651 } 00652 bool foldingColChanged=false; 00653 bool foldingChanged = false; 00654 if (foldingList.size()!=textLine->foldingListArray().size()) { 00655 foldingChanged=true; 00656 } else { 00657 QVector<int>::ConstIterator it=foldingList.constBegin(); 00658 QVector<int>::ConstIterator it1=textLine->foldingListArray().constBegin(); 00659 bool markerType=true; 00660 for(;it!=foldingList.constEnd();++it,++it1) { 00661 if (markerType) { 00662 if ( ((*it)!=(*it1))) { 00663 foldingChanged=true; 00664 foldingColChanged=false; 00665 break; 00666 } 00667 } else { 00668 if ((*it)!=(*it1)) { 00669 foldingColChanged=true; 00670 } 00671 } 00672 markerType=!markerType; 00673 } 00674 } 00675 00676 if (foldingChanged || foldingColChanged) { 00677 textLine->setFoldingList(foldingList); 00678 if (foldingChanged==false){ 00679 textLine->setFoldingColumnsOutdated(textLine->foldingColumnsOutdated() | foldingColChanged); 00680 } else textLine->setFoldingColumnsOutdated(false); 00681 } 00682 bool retVal_folding = false; 00683 //perhaps make en enums out of the change flags 00684 m_regionTree.updateLine (current_line, &foldingList, &retVal_folding, foldingChanged,foldingColChanged); 00685 00686 codeFoldingUpdate = codeFoldingUpdate | retVal_folding; 00687 00688 // need we to continue ? 00689 stillcontinue = indentChanged || indentContinueWhitespace || indentContinueNextWhitespace; 00690 if (stillcontinue && start_spellchecking < 0) { 00691 start_spellchecking=current_line; 00692 } 00693 else if (!stillcontinue && start_spellchecking >= 0) { 00694 last_line_spellchecking=current_line; 00695 } 00696 // move around the lines 00697 prevLine = textLine; 00698 00699 // increment line 00700 current_line++; 00701 } 00702 00703 // tag the changed lines ! 00704 if (invalidate) { 00705 // prevent infinite recursion 00706 int temp = m_lineHighlighted; 00707 m_lineHighlighted = INT_MAX; 00708 emit tagLines (startLine, current_line); 00709 m_lineHighlighted = temp; 00710 00711 if(start_spellchecking >= 0 && lines() > 0) { 00712 emit respellCheckBlock(start_spellchecking, 00713 qMin(lines()-1, (last_line_spellchecking==-1)?current_line:last_line_spellchecking)); 00714 } 00715 } 00716 // emit that we have changed the folding 00717 if (codeFoldingUpdate) 00718 emit codeFoldingUpdated(); 00719 00720 #ifdef BUFFER_DEBUGGING 00721 kDebug (13020) << "HIGHLIGHTED END --- NEED HL, LINESTART: " << startLine << " LINEEND: " << endLine; 00722 kDebug (13020) << "HL UNTIL LINE: " << m_lineHighlighted; 00723 kDebug (13020) << "HL DYN COUNT: " << KateHlManager::self()->countDynamicCtxs() << " MAX: " << m_maxDynamicContexts; 00724 kDebug (13020) << "TIME TAKEN: " << t.elapsed(); 00725 #endif 00726 00727 // if we are at the last line of the block + we still need to continue 00728 // return the need of that ! 00729 return ctxChanged; 00730 } 00731 00732 void KateBuffer::codeFoldingColumnUpdate(int lineNr) { 00733 Kate::TextLine line=plainLine(lineNr); 00734 if (!line) return; 00735 if (line->foldingColumnsOutdated()) { 00736 line->setFoldingColumnsOutdated(false); 00737 bool tmp; 00738 QVector<int> folding=line->foldingListArray(); 00739 m_regionTree.updateLine(lineNr,&folding,&tmp,true,false); 00740 } 00741 } 00742 00743 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE 4.6 API Reference