void CodeDocument::insert (const String& text, const int insertPos, const bool undoable) { if (text.isNotEmpty()) { if (undoable) { undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos)); } else { Position pos (*this, insertPos); const int firstAffectedLine = pos.getLineNumber(); CodeDocumentLine* const firstLine = lines [firstAffectedLine]; String textInsideOriginalLine (text); if (firstLine != nullptr) { const int index = pos.getIndexInLine(); textInsideOriginalLine = firstLine->line.substring (0, index) + textInsideOriginalLine + firstLine->line.substring (index); } maximumLineLength = -1; Array <CodeDocumentLine*> newLines; CodeDocumentLine::createLines (newLines, textInsideOriginalLine); jassert (newLines.size() > 0); CodeDocumentLine* const newFirstLine = newLines.getUnchecked (0); newFirstLine->lineStartInFile = firstLine != nullptr ? firstLine->lineStartInFile : 0; lines.set (firstAffectedLine, newFirstLine); if (newLines.size() > 1) lines.insertArray (firstAffectedLine + 1, newLines.getRawDataPointer() + 1, newLines.size() - 1); int lineStart = newFirstLine->lineStartInFile; for (int i = firstAffectedLine; i < lines.size(); ++i) { CodeDocumentLine& l = *lines.getUnchecked (i); l.lineStartInFile = lineStart; lineStart += l.lineLength; } checkLastLineStatus(); const int newTextLength = text.length(); for (int i = 0; i < positionsToMaintain.size(); ++i) { CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i); if (p.getPosition() >= insertPos) p.setPosition (p.getPosition() + newTextLength); } listeners.call (&CodeDocument::Listener::codeDocumentTextInserted, text, insertPos); } } }
void CodeDocument::remove (const int startPos, const int endPos, const bool undoable) { if (endPos <= startPos) return; if (undoable && !undoDisabled) { undoManager.perform (new DeleteAction (*this, startPos, endPos)); } else { Position startPosition (*this, startPos); Position endPosition (*this, endPos); maximumLineLength = -1; auto firstAffectedLine = startPosition.getLineNumber(); auto endLine = endPosition.getLineNumber(); auto& firstLine = *lines.getUnchecked (firstAffectedLine); if (firstAffectedLine == endLine) { firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine()) + firstLine.line.substring (endPosition.getIndexInLine()); firstLine.updateLength(); } else { auto& lastLine = *lines.getUnchecked (endLine); firstLine.line = firstLine.line.substring (0, startPosition.getIndexInLine()) + lastLine.line.substring (endPosition.getIndexInLine()); firstLine.updateLength(); int numLinesToRemove = endLine - firstAffectedLine; lines.removeRange (firstAffectedLine + 1, numLinesToRemove); } for (int i = firstAffectedLine + 1; i < lines.size(); ++i) { auto& l = *lines.getUnchecked (i); auto& previousLine = *lines.getUnchecked (i - 1); l.lineStartInFile = previousLine.lineStartInFile + previousLine.lineLength; } checkLastLineStatus(); auto totalChars = getNumCharacters(); for (auto* p : positionsToMaintain) { if (p->getPosition() > startPosition.getPosition()) p->setPosition (jmax (startPos, p->getPosition() + startPos - endPos)); if (p->getPosition() > totalChars) p->setPosition (totalChars); } listeners.call (&CodeDocument::Listener::codeDocumentTextDeleted, startPos, endPos); } }
void CodeDocument::remove (const int startPos, const int endPos, const bool undoable) { if (endPos <= startPos) return; if (undoable) { undoManager.perform (new CodeDocumentDeleteAction (*this, startPos, endPos)); } else { Position startPosition (this, startPos); Position endPosition (this, endPos); maximumLineLength = -1; const int firstAffectedLine = startPosition.getLineNumber(); const int endLine = endPosition.getLineNumber(); int lastAffectedLine = firstAffectedLine + 1; CodeDocumentLine* const firstLine = lines.getUnchecked (firstAffectedLine); if (firstAffectedLine == endLine) { firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine()) + firstLine->line.substring (endPosition.getIndexInLine()); firstLine->updateLength(); } else { lastAffectedLine = lines.size(); CodeDocumentLine* const lastLine = lines.getUnchecked (endLine); jassert (lastLine != nullptr); firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine()) + lastLine->line.substring (endPosition.getIndexInLine()); firstLine->updateLength(); int numLinesToRemove = endLine - firstAffectedLine; lines.removeRange (firstAffectedLine + 1, numLinesToRemove); } int i; for (i = firstAffectedLine + 1; i < lines.size(); ++i) { CodeDocumentLine* const l = lines.getUnchecked (i); const CodeDocumentLine* const previousLine = lines.getUnchecked (i - 1); l->lineStartInFile = previousLine->lineStartInFile + previousLine->lineLength; } checkLastLineStatus(); const int totalChars = getNumCharacters(); for (i = 0; i < positionsToMaintain.size(); ++i) { CodeDocument::Position* p = positionsToMaintain.getUnchecked(i); if (p->getPosition() > startPosition.getPosition()) p->setPosition (jmax (startPos, p->getPosition() + startPos - endPos)); if (p->getPosition() > totalChars) p->setPosition (totalChars); } sendListenerChangeMessage (firstAffectedLine, lastAffectedLine); } }
void CodeDocument::insert (const String& text, const int insertPos, const bool undoable) { if (text.isEmpty()) return; if (undoable) { undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos)); } else { Position pos (this, insertPos); const int firstAffectedLine = pos.getLineNumber(); int lastAffectedLine = firstAffectedLine + 1; CodeDocumentLine* const firstLine = lines [firstAffectedLine]; String textInsideOriginalLine (text); if (firstLine != nullptr) { const int index = pos.getIndexInLine(); textInsideOriginalLine = firstLine->line.substring (0, index) + textInsideOriginalLine + firstLine->line.substring (index); } maximumLineLength = -1; Array <CodeDocumentLine*> newLines; CodeDocumentLine::createLines (newLines, textInsideOriginalLine); jassert (newLines.size() > 0); CodeDocumentLine* const newFirstLine = newLines.getUnchecked (0); newFirstLine->lineStartInFile = firstLine != nullptr ? firstLine->lineStartInFile : 0; lines.set (firstAffectedLine, newFirstLine); if (newLines.size() > 1) { for (int i = 1; i < newLines.size(); ++i) { CodeDocumentLine* const l = newLines.getUnchecked (i); lines.insert (firstAffectedLine + i, l); } lastAffectedLine = lines.size(); } int i, lineStart = newFirstLine->lineStartInFile; for (i = firstAffectedLine; i < lines.size(); ++i) { CodeDocumentLine* const l = lines.getUnchecked (i); l->lineStartInFile = lineStart; lineStart += l->lineLength; } checkLastLineStatus(); const int newTextLength = text.length(); for (i = 0; i < positionsToMaintain.size(); ++i) { CodeDocument::Position* const p = positionsToMaintain.getUnchecked(i); if (p->getPosition() >= insertPos) p->setPosition (p->getPosition() + newTextLength); } sendListenerChangeMessage (firstAffectedLine, lastAffectedLine); } }