Beispiel #1
0
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);
    }
}