20 #include <sys/types.h>
24 #include "katebuffer.h"
25 #include "katebuffer.moc"
27 #include "katedocument.h"
28 #include "katehighlight.h"
29 #include "kateconfig.h"
30 #include "katefactory.h"
31 #include "kateautoindent.h"
34 #include <tdeglobal.h>
35 #include <kcharsets.h>
37 #include <tqpopupmenu.h>
39 #include <tqtextstream.h>
41 #include <tqtextcodec.h>
42 #include <tqcstring.h>
43 #include <tqdatetime.h>
49 static const TQ_ULONG KATE_FILE_LOADER_BS = 256 * 1024;
57 static const TQ_ULONG KATE_AVG_BLOCK_SIZE = 2048 * 80;
58 static const TQ_ULONG KATE_MAX_BLOCK_LINES = 2048;
65 static const uint KATE_HL_LOOKAHEAD = 64;
72 uint KateBuffer::m_maxLoadedBlocks = 16;
77 static const uint KATE_MAX_DYNAMIC_CONTEXTS = 512;
81 m_maxLoadedBlocks = kMax (4U,
count);
87 KateFileLoader (
const TQString &filename, TQTextCodec *codec,
bool removeTrailingSpaces)
89 , m_buffer (kMin ((TQ_ULONG)m_file.size(), KATE_FILE_LOADER_BS))
91 , m_decoder (m_codec->makeDecoder())
95 , lastWasEndOfLine (true)
98 , m_twoByteEncoding (TQString(codec->name()) ==
"ISO-10646-UCS-2")
100 , m_removeTrailingSpaces (removeTrailingSpaces)
102 kdDebug (13020) <<
"OPEN USES ENCODING: " << m_codec->name() <<
endl;
115 if (m_file.open (IO_ReadOnly))
117 int c = m_file.readBlock (m_buffer.data(), m_buffer.size());
122 if ((c >= 2) && (m_codec->mibEnum() == 1000) && (m_buffer[1] == 0x00))
125 char reverseUtf16[3] = {
'\xFF',
'\xFE',
'\x00'};
126 m_decoder->toUnicode(reverseUtf16, 2);
130 m_text = m_decoder->toUnicode (m_buffer, c);
133 m_eof = (c == -1) || (c == 0) || (m_text.length() == 0) || m_file.atEnd();
135 for (uint i=0; i < m_text.length(); i++)
137 if (m_text[i] ==
'\n')
139 m_eol = KateDocumentConfig::eolUnix;
142 else if ((m_text[i] ==
'\r'))
144 if (((i+1) < m_text.length()) && (m_text[i+1] ==
'\n'))
146 m_eol = KateDocumentConfig::eolDos;
151 m_eol = KateDocumentConfig::eolMac;
164 inline bool eof ()
const {
return m_eof && !lastWasEndOfLine && (m_lastLineStart == m_text.length()); }
167 inline int eol ()
const {
return m_eol; }
170 inline bool binary ()
const {
return m_binary; }
173 inline bool removeTrailingSpaces ()
const {
return m_removeTrailingSpaces; }
176 inline const TQChar *unicode ()
const {
return m_text.unicode(); }
179 void readLine (uint &offset, uint &length)
184 while (m_position <= m_text.length())
186 if (m_position == m_text.length())
191 int c = m_file.readBlock (m_buffer.data(), m_buffer.size());
198 TQString str (m_decoder->toUnicode (m_buffer, c));
199 readString = str.length();
201 m_text = m_text.mid (m_lastLineStart, m_position-m_lastLineStart)
205 m_text = m_text.mid (m_lastLineStart, m_position-m_lastLineStart);
208 m_eof = (c == -1) || (c == 0) || (readString == 0) || m_file.atEnd();
211 m_position -= m_lastLineStart;
216 if (m_eof && (m_position == m_text.length()))
218 lastWasEndOfLine =
false;
221 offset = m_lastLineStart;
222 length = m_position-m_lastLineStart;
224 m_lastLineStart = m_position;
230 if (m_text[m_position] ==
'\n')
232 lastWasEndOfLine =
true;
242 offset = m_lastLineStart;
243 length = m_position-m_lastLineStart;
245 m_lastLineStart = m_position+1;
251 else if (m_text[m_position] ==
'\r')
253 lastWasEndOfLine =
true;
257 offset = m_lastLineStart;
258 length = m_position-m_lastLineStart;
260 m_lastLineStart = m_position+1;
267 lastWasEndOfLine =
false;
277 void processNull (uint length)
279 if (m_twoByteEncoding)
281 for (uint i=1; i < length; i+=2)
283 if ((m_buffer[i] == 0) && (m_buffer[i-1] == 0))
292 for (uint i=0; i < length; i++)
294 if (m_buffer[i] == 0)
305 TQByteArray m_buffer;
306 TQTextCodec *m_codec;
307 TQTextDecoder *m_decoder;
310 uint m_lastLineStart;
312 bool lastWasEndOfLine;
315 bool m_twoByteEncoding;
317 bool m_removeTrailingSpaces;
325 editSessionNumber (0),
326 editIsRunning (false),
327 editTagLineStart (0xffffffff),
329 editTagLineFrom (false),
330 editChangesDone (false),
333 m_lastInSyncBlock (0),
334 m_lastFoundBlock (0),
335 m_cacheReadError(false),
336 m_cacheWriteError(false),
337 m_loadingBorked (false),
342 m_lineHighlightedMax (0),
343 m_lineHighlighted (0),
344 m_maxDynamicContexts (KATE_MAX_DYNAMIC_CONTEXTS)
355 for (uint i=0; i < m_blocks.size(); i++)
360 m_highlight->release();
367 if (editSessionNumber > 1)
370 editIsRunning =
true;
372 editTagLineStart = 0xffffffff;
374 editTagLineFrom =
false;
376 editChangesDone =
false;
381 if (editSessionNumber == 0)
386 if (editSessionNumber > 0)
392 if ( m_highlight && !m_highlight->noHighlighting()
393 && (editTagLineStart <= editTagLineEnd)
394 && (editTagLineEnd <= m_lineHighlighted))
400 if (editTagLineStart > 0)
404 bool needContinue =
false;
405 while ((buf2 = findBlock(editTagLineStart)))
407 needContinue = doHighlight (buf2,
409 (editTagLineEnd > buf2->
endLine()) ? buf2->
endLine() : editTagLineEnd,
412 editTagLineStart = (editTagLineEnd > buf2->
endLine()) ? buf2->
endLine() : editTagLineEnd;
414 if ((editTagLineStart >= m_lines) || (editTagLineStart >= editTagLineEnd))
419 m_lineHighlighted = editTagLineStart;
421 if (editTagLineStart > m_lineHighlightedMax)
422 m_lineHighlightedMax = editTagLineStart;
424 else if (editTagLineStart < m_lineHighlightedMax)
425 m_lineHighlightedMax = editTagLineStart;
428 editIsRunning =
false;
433 m_regionTree.clear();
436 for (uint i=0; i < m_blocks.size(); i++)
443 m_blocks.append (block);
446 m_lines = block->
lines();
447 m_lastInSyncBlock = 0;
448 m_lastFoundBlock = 0;
449 m_cacheWriteError =
false;
450 m_cacheReadError =
false;
451 m_loadingBorked =
false;
454 m_lineHighlightedMax = 0;
455 m_lineHighlighted = 0;
460 KateFileLoader file (m_file, m_doc->config()->codec(), m_doc->configFlags() & KateDocument::cfRemoveSpaces);
464 if (stat(TQFile::encodeName(m_file), &sbuf) == 0)
466 if (S_ISREG(sbuf.st_mode) && file.open())
477 if (m_doc->config()->allowEolDetection() && (file.eol() != -1))
478 m_doc->config()->setEol (file.eol());
484 for (uint i=0; i < m_blocks.size(); i++)
492 while (!file.eof() && !m_cacheWriteError)
498 if (m_cacheWriteError || (block->
lines() == 0))
504 m_blocks.append (block);
508 if (m_cacheWriteError)
509 m_loadingBorked =
true;
511 if (m_blocks.isEmpty() || (m_lines == 0))
521 m_regionTree.fixRoot (m_lines);
526 if (!m_highlight || m_highlight->noHighlighting())
528 m_lineHighlighted = m_lines;
529 m_lineHighlightedMax = m_lines;
533 m_binary = file.binary ();
537 return !m_loadingBorked;
542 TQTextCodec *codec = m_doc->config()->codec();
544 kdDebug(13020) <<
"ENC NAME: " << codec->name() <<
endl;
547 if ((TQString(codec->name()) ==
"UTF-8") || (TQString(codec->name()) ==
"ISO-10646-UCS-2"))
550 for (uint i=0; i < m_lines; i++)
552 if (!codec->canEncode (
plainLine(i)->
string()))
566 TQFile file (m_file);
567 TQTextStream stream (&file);
569 if ( !file.open( IO_WriteOnly ) )
574 TQTextCodec *codec = m_doc->config()->codec();
577 stream.setEncoding(TQTextStream::RawUnicode);
580 stream.setCodec(codec);
583 TQString eol = m_doc->config()->eolString ();
586 bool removeTrailingSpaces = m_doc->configFlags() & KateDocument::cfRemoveSpaces;
589 for (uint i=0; i < m_lines; i++)
594 if (removeTrailingSpaces)
596 int lastChar = textline->lastChar();
600 stream << TQConstString (textline->text(), lastChar+1).string();
604 stream << textline->string();
612 m_loadingBorked =
false;
614 return (file.status() == IO_Ok);
621 while ((i >= m_lineHighlighted) && (buf2 = findBlock(m_lineHighlighted)))
623 uint end = kMin(i + KATE_HL_LOOKAHEAD, buf2->
endLine());
626 kMax(m_lineHighlighted, buf2->
startLine()),
630 m_lineHighlighted = end;
634 if (m_lineHighlighted > m_lineHighlightedMax)
635 m_lineHighlightedMax = m_lineHighlighted;
640 KateBufBlock *KateBuffer::findBlock_internal (uint i, uint *index)
642 uint lastLine = m_blocks[m_lastInSyncBlock]->endLine ();
654 (*index) = m_lastFoundBlock;
656 return m_blocks[m_lastFoundBlock];
659 if (i < buf->startLine())
667 if ((m_lastInSyncBlock+1) < m_blocks.size())
672 for (; m_lastInSyncBlock < m_blocks.size(); m_lastInSyncBlock++)
681 if ((i >= lastLine) && (i < buf->endLine()))
684 m_lastFoundBlock = m_lastInSyncBlock;
687 (*index) = m_lastFoundBlock;
693 lastLine += buf->
lines ();
713 editChangesDone =
true;
716 if (i < editTagLineStart)
717 editTagLineStart = i;
719 if (i > editTagLineEnd)
728 buf = findBlock(i-1, &index);
730 buf = findBlock(i, &index);
737 if (m_lineHighlightedMax > i)
738 m_lineHighlightedMax++;
740 if (m_lineHighlighted > i)
746 if (m_lastInSyncBlock > index)
747 m_lastInSyncBlock = index;
750 if (m_lastInSyncBlock < m_lastFoundBlock)
751 m_lastFoundBlock = m_lastInSyncBlock;
754 editChangesDone =
true;
757 if (i < editTagLineStart)
758 editTagLineStart = i;
760 if (i <= editTagLineEnd)
763 if (i > editTagLineEnd)
767 editTagLineFrom =
true;
769 m_regionTree.lineHasBeenInserted (i);
782 if (m_lineHighlightedMax > i)
783 m_lineHighlightedMax--;
785 if (m_lineHighlighted > i)
791 if (buf->
lines() == 0)
794 if (m_lastInSyncBlock >= index)
796 m_lastInSyncBlock = index;
809 m_blocks.erase (m_blocks.begin()+index);
812 if( m_lastInSyncBlock >= index )
813 m_lastInSyncBlock = index - 1;
818 if (m_lastInSyncBlock > index)
819 m_lastInSyncBlock = index;
823 if (m_lastInSyncBlock < m_lastFoundBlock)
824 m_lastFoundBlock = m_lastInSyncBlock;
827 editChangesDone =
true;
830 if (i < editTagLineStart)
831 editTagLineStart = i;
833 if (i < editTagLineEnd)
836 if (i > editTagLineEnd)
840 editTagLineFrom =
true;
842 m_regionTree.lineHasBeenRemoved (i);
845 void KateBuffer::setTabWidth (uint w)
847 if ((m_tabWidth != w) && (m_tabWidth > 0))
851 if (m_highlight && m_highlight->foldingIndentationSensitive())
858 KateHighlighting *h = KateHlManager::self()->getHl(hlMode);
861 if (h != m_highlight)
863 bool invalidate = !h->noHighlighting();
867 m_highlight->release();
874 m_regionTree.clear();
875 m_regionTree.fixRoot(m_lines);
878 if (!h->indentation().isEmpty())
888 m_doc->bufferHlChanged ();
894 m_lineHighlightedMax = 0;
895 m_lineHighlighted = 0;
899 void KateBuffer::updatePreviousNotEmptyLine(
KateBufBlock *blk,uint current_line,
bool addindent,uint deindent)
903 if (current_line>0) current_line--;
911 kdDebug(13020)<<
"updatePreviousNotEmptyLine: block not found, this must not happen"<<
endl;
916 textLine = blk->
line(current_line);
917 }
while (textLine->firstChar()==-1);
918 kdDebug(13020)<<
"updatePreviousNotEmptyLine: updating line:"<<(blk->
startLine()+current_line)<<
endl;
919 TQMemArray<uint> foldingList=textLine->foldingListArray();
920 while ( (foldingList.size()>0) && ( labs(foldingList[foldingList.size()-2])==1)) {
921 foldingList.resize(foldingList.size()-2,TQGArray::SpeedOptim);
923 addIndentBasedFoldingInformation(foldingList,addindent,deindent);
924 textLine->setFoldingList(foldingList);
925 bool retVal_folding =
false;
926 m_regionTree.updateLine (current_line + blk->
startLine(), &foldingList, &retVal_folding,
true,
false);
930 void KateBuffer::addIndentBasedFoldingInformation(TQMemArray<uint> &foldingList,
bool addindent,uint deindent)
935 foldingList.resize (foldingList.size() + 2, TQGArray::SpeedOptim);
936 foldingList[foldingList.size()-2] = 1;
937 foldingList[foldingList.size()-1] = 0;
942 foldingList.resize (foldingList.size() + (deindent*2), TQGArray::SpeedOptim);
944 for (uint z= foldingList.size()-(deindent*2); z < foldingList.size(); z=z+2)
947 foldingList[z+1] = 0;
952 bool KateBuffer::doHighlight (
KateBufBlock *buf, uint startLine, uint endLine,
bool invalidate)
975 if (KateHlManager::self()->countDynamicCtxs() >= m_maxDynamicContexts)
978 if (KateHlManager::self()->resetDynamicCtxs())
980 kdDebug (13020) <<
"HL invalidated - too many dynamic contexts ( >= " << m_maxDynamicContexts <<
")" <<
endl;
983 KateHlManager::self()->setForceNoDCReset(
true);
985 for (KateDocument *doc = KateFactory::self()->documents()->first(); doc; doc = KateFactory::self()->documents()->next())
991 while ((endLine > m_lineHighlighted) && (buf = findBlock(m_lineHighlighted)))
996 kMax(m_lineHighlighted, buf->
startLine()),
1000 m_lineHighlighted =
end;
1003 KateHlManager::self()->setForceNoDCReset(
false);
1009 m_maxDynamicContexts *= 2;
1010 kdDebug (13020) <<
"New dynamic contexts limit: " << m_maxDynamicContexts <<
endl;
1021 else if ((startLine > buf->
startLine()) && (startLine <= buf->endLine()))
1027 bool codeFoldingUpdate =
false;
1030 uint current_line = startLine - buf->
startLine();
1033 bool stillcontinue=
false;
1034 bool indentContinueWhitespace=
false;
1035 bool indentContinueNextWhitespace=
false;
1038 while ( (current_line < buf->lines())
1039 && (stillcontinue || ((current_line + buf->
startLine()) <= endLine)) )
1044 TQMemArray<uint> foldingList;
1045 bool ctxChanged =
false;
1047 m_highlight->doHighlight (prevLine, textLine, &foldingList, &ctxChanged);
1052 bool indentChanged =
false;
1053 if (m_highlight->foldingIndentationSensitive())
1056 TQMemArray<unsigned short> indentDepth;
1057 indentDepth.duplicate (prevLine->indentationDepthArray());
1060 uint iDepth = textLine->indentDepth(m_tabWidth);
1063 indentDepth.resize (1, TQGArray::SpeedOptim);
1064 indentDepth[0] = iDepth;
1067 textLine->setNoIndentBasedFoldingAtStart(prevLine->noIndentBasedFolding());
1069 kdDebug(13020)<<
"current_line:"<<current_line + buf->
startLine()<<
" textLine->noIndentBasedFoldingAtStart"<<textLine->noIndentBasedFoldingAtStart()<<
endl;
1070 if ( (textLine->firstChar() == -1) || textLine->noIndentBasedFoldingAtStart())
1073 if (!prevLine->indentationDepthArray().isEmpty())
1075 iDepth = (prevLine->indentationDepthArray())[prevLine->indentationDepthArray().size()-1];
1076 kdDebug(13020)<<
"reusing old depth as current"<<
endl;
1080 iDepth = prevLine->indentDepth(m_tabWidth);
1081 kdDebug(13020)<<
"creating indentdepth for previous line"<<
endl;
1089 uint nextLineIndentation = 0;
1090 bool nextLineIndentationValid=
true;
1091 indentContinueNextWhitespace=
false;
1092 if ((current_line+1) < buf->
lines())
1094 if (buf->
line(current_line+1)->firstChar() == -1)
1096 nextLineIndentation = iDepth;
1097 indentContinueNextWhitespace=
true;
1100 nextLineIndentation = buf->
line(current_line+1)->indentDepth(m_tabWidth);
1106 if (blk && (blk->
lines() > 0))
1108 if (blk->
line (0)->firstChar() == -1)
1110 nextLineIndentation = iDepth;
1111 indentContinueNextWhitespace=
true;
1114 nextLineIndentation = blk->
line (0)->indentDepth(m_tabWidth);
1116 else nextLineIndentationValid=
false;
1119 if (!textLine->noIndentBasedFoldingAtStart()) {
1121 if ((iDepth > 0) && (indentDepth.isEmpty() || (indentDepth[indentDepth.size()-1] < iDepth)))
1123 kdDebug(13020)<<
"adding depth to \"stack\":"<<iDepth<<
endl;
1124 indentDepth.resize (indentDepth.size()+1, TQGArray::SpeedOptim);
1125 indentDepth[indentDepth.size()-1] = iDepth;
1127 if (!indentDepth.isEmpty())
1129 for (
int z=indentDepth.size()-1; z > -1; z--)
1130 if (indentDepth[z]>iDepth)
1131 indentDepth.resize(z, TQGArray::SpeedOptim);
1132 if ((iDepth > 0) && (indentDepth.isEmpty() || (indentDepth[indentDepth.size()-1] < iDepth)))
1134 kdDebug(13020)<<
"adding depth to \"stack\":"<<iDepth<<
endl;
1135 indentDepth.resize (indentDepth.size()+1, TQGArray::SpeedOptim);
1136 indentDepth[indentDepth.size()-1] = iDepth;
1137 if (prevLine->firstChar()==-1) {
1145 if (!textLine->noIndentBasedFolding())
1147 if (nextLineIndentationValid)
1151 kdDebug(13020)<<
"nextLineIndentation:"<<nextLineIndentation<<
endl;
1152 bool addindent=
false;
1154 if (!indentDepth.isEmpty())
1155 kdDebug()<<
"indentDepth[indentDepth.size()-1]:"<<indentDepth[indentDepth.size()-1]<<
endl;
1156 if ((nextLineIndentation>0) && ( indentDepth.isEmpty() || (indentDepth[indentDepth.size()-1]<nextLineIndentation)))
1161 if ((!indentDepth.isEmpty()) && (indentDepth[indentDepth.size()-1]>nextLineIndentation))
1164 for (
int z=indentDepth.size()-1; z > -1; z--)
1166 kdDebug(13020)<<indentDepth[z]<<
" "<<nextLineIndentation<<
endl;
1167 if (indentDepth[z]>nextLineIndentation)
1175 if ((textLine->firstChar()==-1)) {
1176 updatePreviousNotEmptyLine(buf,current_line,addindent,deindent);
1177 codeFoldingUpdate=
true;
1181 addIndentBasedFoldingInformation(foldingList,addindent,deindent);
1186 indentChanged = !(indentDepth == textLine->indentationDepthArray());
1190 textLine->setIndentationDepth (indentDepth);
1192 indentContinueWhitespace=textLine->firstChar()==-1;
1194 bool foldingColChanged=
false;
1195 bool foldingChanged =
false;
1196 if (foldingList.size()!=textLine->foldingListArray().size()) {
1197 foldingChanged=
true;
1199 TQMemArray<uint>::ConstIterator it=foldingList.begin();
1200 TQMemArray<uint>::ConstIterator it1=textLine->foldingListArray();
1201 bool markerType=
true;
1202 for(;it!=foldingList.end();++it,++it1) {
1204 if ( ((*it)!=(*it1))) {
1205 foldingChanged=
true;
1206 foldingColChanged=
false;
1210 if ((*it)!=(*it1)) {
1211 foldingColChanged=
true;
1214 markerType=!markerType;
1218 if (foldingChanged || foldingColChanged) {
1219 textLine->setFoldingList(foldingList);
1220 if (foldingChanged==
false){
1221 textLine->setFoldingColumnsOutdated(textLine->foldingColumnsOutdated() | foldingColChanged);
1222 }
else textLine->setFoldingColumnsOutdated(
false);
1224 bool retVal_folding =
false;
1226 m_regionTree.updateLine (current_line + buf->
startLine(), &foldingList, &retVal_folding, foldingChanged,foldingColChanged);
1228 codeFoldingUpdate = codeFoldingUpdate | retVal_folding;
1231 stillcontinue = ctxChanged || indentChanged || indentContinueWhitespace || indentContinueNextWhitespace;
1234 prevLine = textLine;
1247 if (codeFoldingUpdate)
1257 return stillcontinue && ((current_line+1) == buf->
lines());
1260 void KateBuffer::codeFoldingColumnUpdate(
unsigned int lineNr) {
1263 if (
line->foldingColumnsOutdated()) {
1264 line->setFoldingColumnsOutdated(
false);
1266 TQMemArray<uint> folding=
line->foldingListArray();
1267 m_regionTree.updateLine(lineNr,&folding,&tmp,
true,
false);
1274 KateFileLoader *stream )
1290 m_startLine = m_prev->
endLine ();
1291 m_prev->m_next =
this;
1295 m_next->m_prev =
this;
1308 m_stringList.push_back (textLine);
1313 m_parent->m_loadedBlocks.
first()->swapOut();
1316 m_state = KateBufBlock::stateDirty;
1317 m_parent->m_loadedBlocks.
append (
this);
1325 m_prev->m_next = m_next;
1328 m_next->m_prev = m_prev;
1332 KateFactory::self()->vm()->free(m_vmblock);
1338 void KateBufBlock::fillBlock (KateFileLoader *stream)
1343 TQByteArray rawData;
1347 rawData.resize ((KATE_AVG_BLOCK_SIZE *
sizeof(TQChar)) + ((KATE_AVG_BLOCK_SIZE/80) * 8));
1349 char *buf = rawData.data ();
1352 while (!stream->eof() && (blockSize < KATE_AVG_BLOCK_SIZE) && (m_lines < KATE_MAX_BLOCK_LINES))
1354 uint offset = 0, length = 0;
1355 stream->readLine(offset, length);
1356 const TQChar *unicodeData = stream->unicode () + offset;
1359 if ( stream->removeTrailingSpaces() )
1363 if (unicodeData[length-1].isSpace())
1370 blockSize += length;
1376 char attr = KateTextLine::flagNoOtherData;
1380 size = size + 1 +
sizeof(uint) + (
sizeof(TQChar)*length);
1382 if (size > rawData.size ())
1384 rawData.resize (size);
1385 buf = rawData.data ();
1388 memcpy(buf+pos, (
char *) &attr, 1);
1391 memcpy(buf+pos, (
char *) &length,
sizeof(uint));
1392 pos +=
sizeof(uint);
1394 memcpy(buf+pos, (
char *) unicodeData,
sizeof(TQChar)*length);
1395 pos +=
sizeof(TQChar)*length;
1400 textLine->insertText (0, length, unicodeData);
1401 m_stringList.push_back (textLine);
1409 m_vmblock = KateFactory::self()->vm()->allocate(size);
1410 m_vmblockSize = size;
1412 if (!rawData.isEmpty())
1414 if (!KateFactory::self()->vm()->copyBlock(m_vmblock, rawData.data(), 0, size))
1417 KateFactory::self()->vm()->free(m_vmblock);
1422 m_parent->m_cacheWriteError =
true;
1427 m_state = KateBufBlock::stateSwapped;
1432 m_state = KateBufBlock::stateDirty;
1433 m_parent->m_loadedBlocks.
append (
this);
1436 kdDebug (13020) <<
"A BLOCK LOADED WITH LINES: " << m_lines <<
endl;
1442 if (m_state == KateBufBlock::stateSwapped)
1446 if (!m_parent->m_loadedBlocks.
isLast(
this))
1447 m_parent->m_loadedBlocks.
append (
this);
1449 return m_stringList[i];
1455 if (m_state == KateBufBlock::stateSwapped)
1458 m_stringList.insert (m_stringList.begin()+i,
line);
1467 if (m_state == KateBufBlock::stateSwapped)
1470 m_stringList.erase (m_stringList.begin()+i);
1478 if (m_state != KateBufBlock::stateSwapped)
1481 if (!m_parent->m_loadedBlocks.
isLast(
this))
1482 m_parent->m_loadedBlocks.
append (
this);
1484 if (m_state == KateBufBlock::stateClean)
1488 KateFactory::self()->vm()->free(m_vmblock);
1494 m_state = KateBufBlock::stateDirty;
1499 void KateBufBlock::swapIn ()
1501 if (m_state != KateBufBlock::stateSwapped)
1504 TQByteArray rawData (m_vmblockSize);
1507 if (!KateFactory::self()->vm()->copyBlock(rawData.data(), m_vmblock, 0, rawData.size()))
1508 m_parent->m_cacheReadError =
true;
1511 m_stringList.reserve (m_lines);
1513 char *buf = rawData.data();
1514 for (uint i=0; i < m_lines; i++)
1517 buf = textLine->restore (buf);
1518 m_stringList.push_back (textLine);
1523 m_parent->m_loadedBlocks.
first()->swapOut();
1526 m_state = KateBufBlock::stateClean;
1527 m_parent->m_loadedBlocks.
append (
this);
1530 void KateBufBlock::swapOut ()
1532 if (m_state == KateBufBlock::stateSwapped)
1535 if (m_state == KateBufBlock::stateDirty)
1537 bool haveHl = m_parent->m_highlight && !m_parent->m_highlight->noHighlighting();
1541 for (uint i=0; i < m_lines; i++)
1542 size += m_stringList[i]->dumpSize (haveHl);
1544 TQByteArray rawData (size);
1545 char *buf = rawData.data();
1548 for (uint i=0; i < m_lines; i++)
1549 buf = m_stringList[i]->dump (buf, haveHl);
1551 m_vmblock = KateFactory::self()->vm()->allocate(rawData.size());
1552 m_vmblockSize = rawData.size();
1554 if (!rawData.isEmpty())
1556 if (!KateFactory::self()->vm()->copyBlock(m_vmblock, rawData.data(), 0, rawData.size()))
1559 KateFactory::self()->vm()->free(m_vmblock);
1564 m_parent->m_cacheWriteError =
true;
1571 m_stringList.clear();
1574 m_state = KateBufBlock::stateSwapped;
1592 buf->list->removeInternal (buf);
1599 m_last->listNext = buf;
1601 buf->listPrev = m_last;
1621 void KateBufBlockList::removeInternal (
KateBufBlock *buf)
1623 if (buf->list !=
this)
1628 if ((buf == m_first) && (buf == m_last))
1634 else if (buf == m_first)
1637 m_first = buf->listNext;
1638 m_first->listPrev = 0;
1640 else if (buf == m_last)
1643 m_last = buf->listPrev;
1644 m_last->listNext = 0;
1648 buf->listPrev->listNext = buf->listNext;
1649 buf->listNext->listPrev = buf->listPrev;
virtual uint modeNumber() const
Mode index of this mode.
KateBufBlockList()
Default Constructor.
KateBufBlock * first()
first block in this list or 0
bool isLast(KateBufBlock *buf)
is buf the last block?
uint count() const
count of blocks in this list
void append(KateBufBlock *buf)
append a block to this list ! will remove it from the list it belonged before !
static void remove(KateBufBlock *buf)
remove the block from the list it belongs to !
The KateBufBlock class contains an amount of data representing a certain number of lines.
~KateBufBlock()
destroy this block and take care of freeing all mem
void setStartLine(uint line)
update the first line, needed to keep it up to date
KateBufBlock * prev()
prev block
void markDirty()
mark this block as dirty, will invalidate the swap data insert/removeLine will mark the block dirty i...
KateTextLine::Ptr line(uint i)
return line i The first line of this block is line 0.
void removeLine(uint i)
remove line i marks the block dirty
uint endLine() const
first line behind this block
void insertLine(uint i, KateTextLine::Ptr line)
insert line in front of line i marks the block dirty
KateBufBlock * next()
next block
uint lines() const
lines in this block
uint startLine() const
startLine
KateBufBlock(KateBuffer *parent, KateBufBlock *prev=0, KateBufBlock *next=0, KateFileLoader *stream=0)
Create an empty block.
The KateBuffer class maintains a collections of lines.
bool openFile(const TQString &m_file)
Open a file, use the given filename.
~KateBuffer()
Goodbye buffer.
void tagLines(int start, int end)
Emitted when the highlighting of a certain range has changed.
void removeLine(uint i)
Remove line i.
uint count() const
Return the total number of lines in the buffer.
void clear()
Clear the buffer.
bool canEncode()
Can the current codec handle all chars.
void changeLine(uint i)
Mark line i as changed !
void insertLine(uint i, KateTextLine::Ptr line)
Insert line in front of line i.
void setHighlight(uint hlMode)
Use highlight for highlighting.
KateBuffer(KateDocument *doc)
Create an empty buffer.
void editEnd()
finish some editing action
bool saveFile(const TQString &m_file)
Save the buffer to a file, use the given filename + codec + end of line chars (internal use of qtexts...
KateTextLine::Ptr line(uint i)
Return line i.
KateTextLine::Ptr plainLine(uint i)
Return line i without triggering highlighting.
void codeFoldingUpdated()
Emittend if codefolding returned with a changed list.
static void setMaxLoadedBlocks(uint count)
modifier for max loaded blocks limit
void invalidateHighlighting()
Invalidate highlighting of whole buffer.
void editStart()
start some editing action
static uint maxLoadedBlocks()
maximal loaded block count
The KateTextLine represents a line of text.
kndbgstream & endl(kndbgstream &s)
kdbgstream kdDebug(int area=0)
const TDEShortcut & end()
const TDEShortcut & open()