28 , m_startLine (startLine)
31 m_lines.reserve (m_buffer->m_blockSize);
37 Q_ASSERT (m_lines.empty());
38 Q_ASSERT (m_cursors.empty());
46 Q_ASSERT (startLine >= 0);
47 Q_ASSERT (startLine < m_buffer->
lines ());
61 Q_ASSERT (line < m_lines.size ());
64 return m_lines.at(line);
80 for (
int i = 0; i < m_lines.size(); ++i) {
85 text.append (m_lines.at(i)->text ());
98 Q_ASSERT (position.
column() >= 0);
99 Q_ASSERT (position.
column() <= text.size());
108 if (position.
column() > 0 || text.size() == 0 || m_lines.at(line)->markedAsModified()) {
109 m_lines.at(line + 1)->markAsModified(
true);
110 }
else if (m_lines.at(line)->markedAsSavedOnDisk()) {
111 m_lines.at(line + 1)->markAsSavedOnDisk(
true);
115 if (position.
column() < text.size ()) {
117 m_lines.at(line+1)->textReadWrite() = text.right (text.size() - position.
column());
120 text.chop (text.size() - position.
column());
123 m_lines.at(line)->markAsModified(
true);
131 m_buffer->fixStartLines (fixStartLinesStartIndex);
136 m_buffer->
history().wrapLine (position);
145 if (m_cursors.empty())
166 if (cursor->
column() < position.
column() || !cursor->m_moveOnInsert)
176 cursor->m_column -= position.
column();
181 changedRanges.insert (cursor->
kateRange());
185 foreach (
TextRange *range, changedRanges)
186 range->checkValidity ();
197 Q_ASSERT (previousBlock);
198 Q_ASSERT (previousBlock->
lines () > 0);
202 int lastLineOfPreviousBlock = previousBlock->
lines ()-1;
203 TextLine newFirst = previousBlock->m_lines.last();
204 m_lines[0] = newFirst;
205 previousBlock->m_lines.erase (previousBlock->m_lines.begin() + (previousBlock->
lines () - 1));
207 const int oldSizeOfPreviousLine = newFirst->text().size();
208 if (oldFirst->length() > 0) {
210 newFirst->textReadWrite().append (oldFirst->text());
213 newFirst->markAsModified(
true);
224 m_buffer->fixStartLines (fixStartLinesStartIndex);
229 m_buffer->
history().unwrapLine (startLine () + line, oldSizeOfPreviousLine);
236 if (m_cursors.empty() && previousBlock->m_cursors.empty())
246 cursor->m_column += oldSizeOfPreviousLine;
250 changedRanges.insert (cursor->
kateRange());
256 foreach (
TextCursor *cursor, previousBlock->m_cursors) {
257 if (cursor->
lineInBlock() == lastLineOfPreviousBlock) {
259 cursor->m_block =
this;
260 m_cursors.insert (cursor);
264 changedRanges.insert (cursor->
kateRange());
267 newPreviousCursors.insert (cursor);
269 previousBlock->m_cursors = newPreviousCursors;
272 foreach (
TextRange *range, changedRanges) {
279 foreach (
TextRange *range, changedRanges)
280 range->checkValidity ();
287 const int oldSizeOfPreviousLine = m_lines.at(line-1)->length();
288 const int sizeOfCurrentLine = m_lines.at(line)->length();
289 if (sizeOfCurrentLine > 0)
290 m_lines.at(line-1)->textReadWrite().append (m_lines.at(line)->text());
292 const bool lineChanged = (oldSizeOfPreviousLine > 0 && m_lines.at(line - 1)->markedAsModified())
293 || (sizeOfCurrentLine > 0 && (oldSizeOfPreviousLine > 0 || m_lines.at(line)->markedAsModified()));
294 m_lines.at(line-1)->markAsModified(lineChanged);
295 if (oldSizeOfPreviousLine == 0 && m_lines.at(line)->markedAsSavedOnDisk())
296 m_lines.at(line-1)->markAsSavedOnDisk(
true);
298 m_lines.erase (m_lines.begin () +
line);
305 m_buffer->fixStartLines (fixStartLinesStartIndex);
310 m_buffer->
history().unwrapLine (startLine () + line, oldSizeOfPreviousLine);
317 if (m_cursors.empty())
331 cursor->m_column += oldSizeOfPreviousLine;
339 changedRanges.insert (cursor->
kateRange());
343 foreach (
TextRange *range, changedRanges)
344 range->checkValidity ();
353 QString &textOfLine = m_lines.at(line)->textReadWrite ();
354 int oldLength = textOfLine.size ();
355 m_lines.at(line)->markAsModified(
true);
358 Q_ASSERT (position.
column() >= 0);
359 Q_ASSERT (position.
column() <= textOfLine.size());
367 m_buffer->
history().insertText (position, text.size(), oldLength);
374 if (m_cursors.empty())
387 if (cursor->
column() < position.
column() || !cursor->m_moveOnInsert)
392 if (cursor->m_column <= oldLength)
393 cursor->m_column += text.size ();
396 else if (cursor->m_column < textOfLine.size())
397 cursor->m_column = textOfLine.size();
401 changedRanges.insert (cursor->
kateRange());
405 foreach (
TextRange *range, changedRanges)
406 range->checkValidity ();
415 QString &textOfLine = m_lines.at(line)->textReadWrite ();
416 int oldLength = textOfLine.size ();
420 Q_ASSERT (range.
start().
column() <= textOfLine.size());
422 Q_ASSERT (range.
end().
column() <= textOfLine.size());
429 m_lines.at(line)->markAsModified(
true);
434 m_buffer->
history().removeText (range, oldLength);
441 if (m_cursors.empty())
464 changedRanges.insert (cursor->
kateRange());
468 foreach (
TextRange *range, changedRanges)
469 range->checkValidity ();
475 for (
int i = 0; i < m_lines.size(); ++i)
476 printf (
"%4d - %4d : %4d : '%s'\n", blockIndex,
startLine() + i
477 , m_lines.at(i)->text().size(), qPrintable (m_lines.at(i)->text()));
483 int linesOfNewBlock =
lines () - fromLine;
489 newBlock->m_lines.reserve (linesOfNewBlock);
490 for (
int i = fromLine; i < m_lines.size(); ++i)
491 newBlock->m_lines.append (m_lines.at(i));
492 m_lines.resize (fromLine);
499 cursor->m_block = newBlock;
500 newBlock->m_cursors.insert (cursor);
503 oldBlockSet.insert (cursor);
505 m_cursors = oldBlockSet;
508 QList<TextRange*> allRanges = m_uncachedRanges.toList() + m_cachedLineForRanges.keys();
524 cursor->m_block = targetBlock;
525 targetBlock->m_cursors.insert (cursor);
530 targetBlock->m_lines.reserve (targetBlock->
lines() +
lines ());
531 for (
int i = 0; i < m_lines.size(); ++i)
532 targetBlock->m_lines.append (m_lines.at(i));
536 QList<TextRange*> allRanges = m_uncachedRanges.toList() + m_cachedLineForRanges.keys();
562 cursor->m_column = 0;
564 cursor->m_block = targetBlock;
565 targetBlock->m_cursors.insert (cursor);
566 m_cursors.remove (cursor);
577 for (
int i = 0; i < m_lines.size(); ++i) {
579 if (textLine->markedAsModified())
580 textLine->markAsSavedOnDisk(
true);
591 const bool isSingleLine = startLine == endLine;
596 if ((endLine < m_startLine) || (startLine >= (m_startLine +
lines()))) {
604 if(isSingleLine && m_cachedLineForRanges.contains (range) && (m_cachedLineForRanges.value(range) == startLine - m_startLine))
610 if(!isSingleLine && m_uncachedRanges.contains (range))
625 m_uncachedRanges.insert(range);
632 const int lineOffset = startLine - m_startLine;
637 if (m_cachedRangesForLine.size() <= lineOffset)
638 m_cachedRangesForLine.resize(lineOffset+1);
643 m_cachedRangesForLine[lineOffset].insert(range);
644 m_cachedLineForRanges[range] = lineOffset;
652 if(m_uncachedRanges.remove (range)) {
656 Q_ASSERT (!m_cachedLineForRanges.contains(range));
664 if (it != m_cachedLineForRanges.end()) {
668 Q_ASSERT (!m_uncachedRanges.contains(range));
673 Q_ASSERT (m_cachedRangesForLine.at(*it).contains(range));
678 m_cachedRangesForLine[*it].remove(range);
679 m_cachedLineForRanges.erase(it);
void wrapLine(const KTextEditor::Cursor &position, int fixStartLinesStartIndex)
Wrap line at given cursor position.
void setStartLine(int startLine)
Set start line of this block.
void removeRange(TextRange *range)
Remove a range from this block.
int column() const
Retrieve the column on which this cursor is situated.
void unwrapLine(int line, TextBlock *previousBlock, int fixStartLinesStartIndex)
Unwrap given line.
int lines() const
Number of lines in this block.
int lineInternal() const
Non-virtual version of line(), which is faster.
int startLine() const
Start line of this block.
Class representing a single text line.
void deleteBlockContent()
Delete the block content, delete all lines and delete all cursors not bound to ranges.
void debugPrint(int blockIndex) const
Debug output, print whole block content with line numbers and line length.
TextBlock(TextBuffer *buffer, int startLine)
Construct an empty text block.
~TextBlock()
Destruct the text block.
void updateRange(TextRange *range)
Update a range from this block.
void clearBlockContent(TextBlock *targetBlock)
Clear the block content, delete all lines, move all cursors not bound to range to given block at 0...
void markModifiedLinesAsSaved()
Flag all modified text lines as saved on disk.
int lineInBlock() const
Get offset into block this cursor belongs to, if any.
void removeText(const KTextEditor::Range &range, QString &removedText)
Remove text at given range.
void appendLine(const QString &textOfLine)
Append a new line with given text.
void clearLines()
Clear the lines.
Kate::TextRange * kateRange() const
Get range this cursor belongs to, if any.
void mergeBlock(TextBlock *targetBlock)
Merge this block with given one, the given one must be a direct predecessor.
Class representing a 'clever' text cursor.
QSharedPointer< TextLineData > TextLine
The normal world only accesses the text lines with shared pointers.
CopyJob * copy(const KUrl &src, const KUrl &dest, JobFlags flags=DefaultFlags)
TextLine line(int line) const
Retrieve a text line.
Class representing a text buffer.
TextHistory & history()
TextHistory of this buffer.
void text(QString &text) const
Retrieve text of block.
void insertText(const KTextEditor::Cursor &position, const QString &text)
Insert text at given cursor position.
Class representing a text block.
TextBlock * splitBlock(int fromLine)
Split given block.