mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
Minor optimisations. New method OwnedArray::insertArray(). Changed some CodeDocument inner class constructors to use references rather than pointers.
This commit is contained in:
parent
98e37b8e7a
commit
d4ae8f3d55
8 changed files with 236 additions and 235 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -15,6 +15,7 @@
|
|||
*.manifest.res
|
||||
*.o
|
||||
*.d
|
||||
*.sdf
|
||||
xcuserdata
|
||||
contents.xcworkspacedata
|
||||
.DS_Store
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ void SourceCodeEditor::highlightLine (int lineNum, int characterIndex)
|
|||
editor->getDocument().getNumLines() - editor->getNumLinesOnScreen())));
|
||||
}
|
||||
|
||||
editor->moveCaretTo (CodeDocument::Position (&editor->getDocument(), lineNum - 1, characterIndex), false);
|
||||
editor->moveCaretTo (CodeDocument::Position (editor->getDocument(), lineNum - 1, characterIndex), false);
|
||||
}
|
||||
|
||||
void SourceCodeEditor::resized()
|
||||
|
|
|
|||
|
|
@ -135,10 +135,10 @@ void ResamplingAudioSource::getNextAudioBlock (const AudioSourceChannelInfo& inf
|
|||
for (int m = info.numSamples; --m >= 0;)
|
||||
{
|
||||
const float alpha = (float) subSampleOffset;
|
||||
const float invAlpha = 1.0f - alpha;
|
||||
|
||||
for (int channel = 0; channel < channelsToProcess; ++channel)
|
||||
*destBuffers[channel]++ = srcBuffers[channel][bufferPos] * invAlpha + srcBuffers[channel][nextPos] * alpha;
|
||||
*destBuffers[channel]++ = srcBuffers[channel][bufferPos]
|
||||
+ alpha * (srcBuffers[channel][nextPos] - srcBuffers[channel][bufferPos]);
|
||||
|
||||
subSampleOffset += localRatio;
|
||||
|
||||
|
|
|
|||
|
|
@ -460,17 +460,17 @@ public:
|
|||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (numUsed + numberOfElements);
|
||||
ElementType* insertPos;
|
||||
ElementType* insertPos = data.elements;
|
||||
|
||||
if (isPositiveAndBelow (indexToInsertAt, numUsed))
|
||||
{
|
||||
insertPos = data.elements + indexToInsertAt;
|
||||
insertPos += indexToInsertAt;
|
||||
const int numberToMove = numUsed - indexToInsertAt;
|
||||
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertPos = data.elements + numUsed;
|
||||
insertPos += numUsed;
|
||||
}
|
||||
|
||||
numUsed += numberOfElements;
|
||||
|
|
|
|||
|
|
@ -292,6 +292,46 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
/** Inserts an array of values into this array at a given position.
|
||||
|
||||
If the index is less than 0 or greater than the size of the array, the
|
||||
new elements will be added to the end of the array.
|
||||
Otherwise, they will be inserted into the array, moving all the later elements
|
||||
along to make room.
|
||||
|
||||
@param indexToInsertAt the index at which the first new element should be inserted
|
||||
@param newObjects the new values to add to the array
|
||||
@param numberOfElements how many items are in the array
|
||||
@see insert, add, addSorted, set
|
||||
*/
|
||||
void insertArray (int indexToInsertAt,
|
||||
ObjectClass* const* newObjects,
|
||||
int numberOfElements)
|
||||
{
|
||||
if (numberOfElements > 0)
|
||||
{
|
||||
const ScopedLockType lock (getLock());
|
||||
data.ensureAllocatedSize (numUsed + numberOfElements);
|
||||
ObjectClass** insertPos = data.elements;
|
||||
|
||||
if (isPositiveAndBelow (indexToInsertAt, numUsed))
|
||||
{
|
||||
insertPos += indexToInsertAt;
|
||||
const int numberToMove = numUsed - indexToInsertAt;
|
||||
memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ObjectClass*));
|
||||
}
|
||||
else
|
||||
{
|
||||
insertPos += numUsed;
|
||||
}
|
||||
|
||||
numUsed += numberOfElements;
|
||||
|
||||
while (--numberOfElements >= 0)
|
||||
*insertPos++ = *newObjects++;
|
||||
}
|
||||
}
|
||||
|
||||
/** Appends a new object at the end of the array as long as the array doesn't
|
||||
already contain it.
|
||||
|
||||
|
|
|
|||
|
|
@ -123,15 +123,15 @@ public:
|
|||
};
|
||||
|
||||
//==============================================================================
|
||||
CodeDocument::Iterator::Iterator (CodeDocument* const document_)
|
||||
: document (document_),
|
||||
CodeDocument::Iterator::Iterator (const CodeDocument& document_) noexcept
|
||||
: document (&document_),
|
||||
charPointer (nullptr),
|
||||
line (0),
|
||||
position (0)
|
||||
{
|
||||
}
|
||||
|
||||
CodeDocument::Iterator::Iterator (const CodeDocument::Iterator& other)
|
||||
CodeDocument::Iterator::Iterator (const CodeDocument::Iterator& other) noexcept
|
||||
: document (other.document),
|
||||
charPointer (other.charPointer),
|
||||
line (other.line),
|
||||
|
|
@ -153,13 +153,13 @@ CodeDocument::Iterator::~Iterator() noexcept
|
|||
{
|
||||
}
|
||||
|
||||
juce_wchar CodeDocument::Iterator::nextChar()
|
||||
juce_wchar CodeDocument::Iterator::nextChar() noexcept
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (charPointer.getAddress() == nullptr)
|
||||
{
|
||||
CodeDocumentLine* const l = document->lines[line];
|
||||
const CodeDocumentLine* const l = document->lines[line];
|
||||
|
||||
if (l == nullptr)
|
||||
return 0;
|
||||
|
|
@ -182,16 +182,16 @@ juce_wchar CodeDocument::Iterator::nextChar()
|
|||
}
|
||||
}
|
||||
|
||||
void CodeDocument::Iterator::skip()
|
||||
void CodeDocument::Iterator::skip() noexcept
|
||||
{
|
||||
nextChar();
|
||||
}
|
||||
|
||||
void CodeDocument::Iterator::skipToEndOfLine()
|
||||
void CodeDocument::Iterator::skipToEndOfLine() noexcept
|
||||
{
|
||||
if (charPointer.getAddress() == nullptr)
|
||||
{
|
||||
CodeDocumentLine* const l = document->lines[line];
|
||||
const CodeDocumentLine* const l = document->lines[line];
|
||||
|
||||
if (l == nullptr)
|
||||
return;
|
||||
|
|
@ -204,11 +204,11 @@ void CodeDocument::Iterator::skipToEndOfLine()
|
|||
charPointer = nullptr;
|
||||
}
|
||||
|
||||
juce_wchar CodeDocument::Iterator::peekNextChar() const
|
||||
juce_wchar CodeDocument::Iterator::peekNextChar() const noexcept
|
||||
{
|
||||
if (charPointer.getAddress() == nullptr)
|
||||
{
|
||||
CodeDocumentLine* const l = document->lines[line];
|
||||
const CodeDocumentLine* const l = document->lines[line];
|
||||
|
||||
if (l == nullptr)
|
||||
return 0;
|
||||
|
|
@ -221,11 +221,11 @@ juce_wchar CodeDocument::Iterator::peekNextChar() const
|
|||
if (c != 0)
|
||||
return c;
|
||||
|
||||
CodeDocumentLine* const l = document->lines [line + 1];
|
||||
const CodeDocumentLine* const l = document->lines [line + 1];
|
||||
return l == nullptr ? 0 : l->line[0];
|
||||
}
|
||||
|
||||
void CodeDocument::Iterator::skipWhitespace()
|
||||
void CodeDocument::Iterator::skipWhitespace() noexcept
|
||||
{
|
||||
while (CharacterFunctions::isWhitespace (peekNextChar()))
|
||||
skip();
|
||||
|
|
@ -238,23 +238,22 @@ bool CodeDocument::Iterator::isEOF() const noexcept
|
|||
|
||||
//==============================================================================
|
||||
CodeDocument::Position::Position() noexcept
|
||||
: owner (0), characterPos (0), line (0),
|
||||
: owner (nullptr), characterPos (0), line (0),
|
||||
indexInLine (0), positionMaintained (false)
|
||||
{
|
||||
}
|
||||
|
||||
CodeDocument::Position::Position (const CodeDocument* const ownerDocument,
|
||||
CodeDocument::Position::Position (const CodeDocument& ownerDocument,
|
||||
const int line_, const int indexInLine_) noexcept
|
||||
: owner (const_cast <CodeDocument*> (ownerDocument)),
|
||||
: owner (const_cast <CodeDocument*> (&ownerDocument)),
|
||||
characterPos (0), line (line_),
|
||||
indexInLine (indexInLine_), positionMaintained (false)
|
||||
{
|
||||
setLineAndIndex (line_, indexInLine_);
|
||||
}
|
||||
|
||||
CodeDocument::Position::Position (const CodeDocument* const ownerDocument,
|
||||
const int characterPos_) noexcept
|
||||
: owner (const_cast <CodeDocument*> (ownerDocument)),
|
||||
CodeDocument::Position::Position (const CodeDocument& ownerDocument, const int characterPos_) noexcept
|
||||
: owner (const_cast <CodeDocument*> (&ownerDocument)),
|
||||
positionMaintained (false)
|
||||
{
|
||||
setPosition (characterPos_);
|
||||
|
|
@ -324,25 +323,22 @@ void CodeDocument::Position::setLineAndIndex (const int newLineNum, const int ne
|
|||
{
|
||||
line = owner->lines.size() - 1;
|
||||
|
||||
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
|
||||
jassert (l != nullptr);
|
||||
|
||||
indexInLine = l->lineLengthWithoutNewLines;
|
||||
characterPos = l->lineStartInFile + indexInLine;
|
||||
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
|
||||
indexInLine = l.lineLengthWithoutNewLines;
|
||||
characterPos = l.lineStartInFile + indexInLine;
|
||||
}
|
||||
else
|
||||
{
|
||||
line = jmax (0, newLineNum);
|
||||
|
||||
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
|
||||
jassert (l != nullptr);
|
||||
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
|
||||
|
||||
if (l->lineLengthWithoutNewLines > 0)
|
||||
indexInLine = jlimit (0, l->lineLengthWithoutNewLines, newIndexInLine);
|
||||
if (l.lineLengthWithoutNewLines > 0)
|
||||
indexInLine = jlimit (0, l.lineLengthWithoutNewLines, newIndexInLine);
|
||||
else
|
||||
indexInLine = 0;
|
||||
|
||||
characterPos = l->lineStartInFile + indexInLine;
|
||||
characterPos = l.lineStartInFile + indexInLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -366,15 +362,14 @@ void CodeDocument::Position::setPosition (const int newPosition)
|
|||
{
|
||||
for (int i = lineStart; i < lineEnd; ++i)
|
||||
{
|
||||
CodeDocumentLine* const l = owner->lines.getUnchecked (i);
|
||||
const CodeDocumentLine& l = *owner->lines.getUnchecked (i);
|
||||
const int index = newPosition - l.lineStartInFile;
|
||||
|
||||
int index = newPosition - l->lineStartInFile;
|
||||
|
||||
if (index >= 0 && (index < l->lineLength || i == lineEnd - 1))
|
||||
if (index >= 0 && (index < l.lineLength || i == lineEnd - 1))
|
||||
{
|
||||
line = i;
|
||||
indexInLine = jmin (l->lineLengthWithoutNewLines, index);
|
||||
characterPos = l->lineStartInFile + indexInLine;
|
||||
indexInLine = jmin (l.lineLengthWithoutNewLines, index);
|
||||
characterPos = l.lineStartInFile + indexInLine;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -383,9 +378,8 @@ void CodeDocument::Position::setPosition (const int newPosition)
|
|||
else
|
||||
{
|
||||
const int midIndex = (lineStart + lineEnd + 1) / 2;
|
||||
CodeDocumentLine* const mid = owner->lines.getUnchecked (midIndex);
|
||||
|
||||
if (newPosition >= mid->lineStartInFile)
|
||||
if (newPosition >= owner->lines.getUnchecked (midIndex)->lineStartInFile)
|
||||
lineStart = midIndex;
|
||||
else
|
||||
lineEnd = midIndex;
|
||||
|
|
@ -405,9 +399,10 @@ void CodeDocument::Position::moveBy (int characterDelta)
|
|||
// If moving right, make sure we don't get stuck between the \r and \n characters..
|
||||
if (line < owner->lines.size())
|
||||
{
|
||||
CodeDocumentLine* const l = owner->lines.getUnchecked (line);
|
||||
if (indexInLine + characterDelta < l->lineLength
|
||||
&& indexInLine + characterDelta >= l->lineLengthWithoutNewLines + 1)
|
||||
const CodeDocumentLine& l = *owner->lines.getUnchecked (line);
|
||||
|
||||
if (indexInLine + characterDelta < l.lineLength
|
||||
&& indexInLine + characterDelta >= l.lineLengthWithoutNewLines + 1)
|
||||
++characterDelta;
|
||||
}
|
||||
}
|
||||
|
|
@ -415,21 +410,21 @@ void CodeDocument::Position::moveBy (int characterDelta)
|
|||
setPosition (characterPos + characterDelta);
|
||||
}
|
||||
|
||||
const CodeDocument::Position CodeDocument::Position::movedBy (const int characterDelta) const
|
||||
CodeDocument::Position CodeDocument::Position::movedBy (const int characterDelta) const
|
||||
{
|
||||
CodeDocument::Position p (*this);
|
||||
p.moveBy (characterDelta);
|
||||
return p;
|
||||
}
|
||||
|
||||
const CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLines) const
|
||||
CodeDocument::Position CodeDocument::Position::movedByLines (const int deltaLines) const
|
||||
{
|
||||
CodeDocument::Position p (*this);
|
||||
p.setLineAndIndex (getLineNumber() + deltaLines, getIndexInLine());
|
||||
return p;
|
||||
}
|
||||
|
||||
const juce_wchar CodeDocument::Position::getCharacter() const
|
||||
juce_wchar CodeDocument::Position::getCharacter() const
|
||||
{
|
||||
const CodeDocumentLine* const l = owner->lines [line];
|
||||
return l == nullptr ? 0 : l->line [getIndexInLine()];
|
||||
|
|
@ -480,8 +475,8 @@ CodeDocument::~CodeDocument()
|
|||
|
||||
String CodeDocument::getAllContent() const
|
||||
{
|
||||
return getTextBetween (Position (this, 0),
|
||||
Position (this, lines.size(), 0));
|
||||
return getTextBetween (Position (*this, 0),
|
||||
Position (*this, lines.size(), 0));
|
||||
}
|
||||
|
||||
String CodeDocument::getTextBetween (const Position& start, const Position& end) const
|
||||
|
|
@ -505,22 +500,22 @@ String CodeDocument::getTextBetween (const Position& start, const Position& end)
|
|||
|
||||
for (int i = jmax (0, startLine); i <= maxLine; ++i)
|
||||
{
|
||||
const CodeDocumentLine* line = lines.getUnchecked(i);
|
||||
int len = line->lineLength;
|
||||
const CodeDocumentLine& line = *lines.getUnchecked(i);
|
||||
int len = line.lineLength;
|
||||
|
||||
if (i == startLine)
|
||||
{
|
||||
const int index = start.getIndexInLine();
|
||||
mo << line->line.substring (index, len);
|
||||
mo << line.line.substring (index, len);
|
||||
}
|
||||
else if (i == endLine)
|
||||
{
|
||||
len = end.getIndexInLine();
|
||||
mo << line->line.substring (0, len);
|
||||
mo << line.line.substring (0, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
mo << line->line;
|
||||
mo << line.line;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -736,20 +731,13 @@ void CodeDocument::checkLastLineStatus()
|
|||
}
|
||||
|
||||
//==============================================================================
|
||||
void CodeDocument::addListener (CodeDocument::Listener* const listener) noexcept
|
||||
{
|
||||
listeners.add (listener);
|
||||
}
|
||||
|
||||
void CodeDocument::removeListener (CodeDocument::Listener* const listener) noexcept
|
||||
{
|
||||
listeners.remove (listener);
|
||||
}
|
||||
void CodeDocument::addListener (CodeDocument::Listener* const l) noexcept { listeners.add (l); }
|
||||
void CodeDocument::removeListener (CodeDocument::Listener* const l) noexcept { listeners.remove (l); }
|
||||
|
||||
void CodeDocument::sendListenerChangeMessage (const int startLine, const int endLine)
|
||||
{
|
||||
Position startPos (this, startLine, 0);
|
||||
Position endPos (this, endLine, 0);
|
||||
Position startPos (*this, startLine, 0);
|
||||
Position endPos (*this, endLine, 0);
|
||||
|
||||
listeners.call (&CodeDocument::Listener::codeDocumentChanged, startPos, endPos);
|
||||
}
|
||||
|
|
@ -758,10 +746,8 @@ void CodeDocument::sendListenerChangeMessage (const int startLine, const int end
|
|||
class CodeDocumentInsertAction : public UndoableAction
|
||||
{
|
||||
public:
|
||||
CodeDocumentInsertAction (CodeDocument& owner_, const String& text_, const int insertPos_) noexcept
|
||||
: owner (owner_),
|
||||
text (text_),
|
||||
insertPos (insertPos_)
|
||||
CodeDocumentInsertAction (CodeDocument& doc, const String& t, const int pos) noexcept
|
||||
: owner (doc), text (t), insertPos (pos)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -784,23 +770,22 @@ public:
|
|||
private:
|
||||
CodeDocument& owner;
|
||||
const String text;
|
||||
int insertPos;
|
||||
const int insertPos;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (CodeDocumentInsertAction);
|
||||
};
|
||||
|
||||
void CodeDocument::insert (const String& text, const int insertPos, const bool undoable)
|
||||
{
|
||||
if (text.isEmpty())
|
||||
return;
|
||||
|
||||
if (text.isNotEmpty())
|
||||
{
|
||||
if (undoable)
|
||||
{
|
||||
undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos));
|
||||
}
|
||||
else
|
||||
{
|
||||
Position pos (this, insertPos);
|
||||
Position pos (*this, insertPos);
|
||||
const int firstAffectedLine = pos.getLineNumber();
|
||||
int lastAffectedLine = firstAffectedLine + 1;
|
||||
|
||||
|
|
@ -826,49 +811,43 @@ void CodeDocument::insert (const String& text, const int insertPos, const bool u
|
|||
|
||||
if (newLines.size() > 1)
|
||||
{
|
||||
for (int i = 1; i < newLines.size(); ++i)
|
||||
{
|
||||
CodeDocumentLine* const l = newLines.getUnchecked (i);
|
||||
lines.insert (firstAffectedLine + i, l);
|
||||
}
|
||||
|
||||
lines.insertArray (firstAffectedLine + 1, newLines.getRawDataPointer() + 1, newLines.size() - 1);
|
||||
lastAffectedLine = lines.size();
|
||||
}
|
||||
|
||||
int i, lineStart = newFirstLine->lineStartInFile;
|
||||
for (i = firstAffectedLine; i < lines.size(); ++i)
|
||||
int lineStart = newFirstLine->lineStartInFile;
|
||||
for (int i = firstAffectedLine; i < lines.size(); ++i)
|
||||
{
|
||||
CodeDocumentLine* const l = lines.getUnchecked (i);
|
||||
l->lineStartInFile = lineStart;
|
||||
lineStart += l->lineLength;
|
||||
CodeDocumentLine& l = *lines.getUnchecked (i);
|
||||
l.lineStartInFile = lineStart;
|
||||
lineStart += l.lineLength;
|
||||
}
|
||||
|
||||
checkLastLineStatus();
|
||||
|
||||
const int newTextLength = text.length();
|
||||
for (i = 0; i < positionsToMaintain.size(); ++i)
|
||||
for (int i = 0; i < positionsToMaintain.size(); ++i)
|
||||
{
|
||||
CodeDocument::Position* const p = positionsToMaintain.getUnchecked(i);
|
||||
CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i);
|
||||
|
||||
if (p->getPosition() >= insertPos)
|
||||
p->setPosition (p->getPosition() + newTextLength);
|
||||
if (p.getPosition() >= insertPos)
|
||||
p.setPosition (p.getPosition() + newTextLength);
|
||||
}
|
||||
|
||||
sendListenerChangeMessage (firstAffectedLine, lastAffectedLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
class CodeDocumentDeleteAction : public UndoableAction
|
||||
{
|
||||
public:
|
||||
CodeDocumentDeleteAction (CodeDocument& owner_, const int startPos_, const int endPos_) noexcept
|
||||
: owner (owner_),
|
||||
startPos (startPos_),
|
||||
endPos (endPos_)
|
||||
CodeDocumentDeleteAction (CodeDocument& doc, const int start, const int end) noexcept
|
||||
: owner (doc), startPos (start), endPos (end),
|
||||
removedText (doc.getTextBetween (CodeDocument::Position (doc, start),
|
||||
CodeDocument::Position (doc, end)))
|
||||
{
|
||||
removedText = owner.getTextBetween (CodeDocument::Position (&owner, startPos),
|
||||
CodeDocument::Position (&owner, endPos));
|
||||
}
|
||||
|
||||
bool perform()
|
||||
|
|
@ -885,12 +864,12 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
int getSizeInUnits() { return removedText.length() + 32; }
|
||||
int getSizeInUnits() { return (endPos - startPos) + 32; }
|
||||
|
||||
private:
|
||||
CodeDocument& owner;
|
||||
int startPos, endPos;
|
||||
String removedText;
|
||||
const int startPos, endPos;
|
||||
const String removedText;
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE (CodeDocumentDeleteAction);
|
||||
};
|
||||
|
|
@ -906,57 +885,55 @@ void CodeDocument::remove (const int startPos, const int endPos, const bool undo
|
|||
}
|
||||
else
|
||||
{
|
||||
Position startPosition (this, startPos);
|
||||
Position endPosition (this, endPos);
|
||||
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);
|
||||
CodeDocumentLine& firstLine = *lines.getUnchecked (firstAffectedLine);
|
||||
|
||||
if (firstAffectedLine == endLine)
|
||||
{
|
||||
firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine())
|
||||
+ firstLine->line.substring (endPosition.getIndexInLine());
|
||||
firstLine->updateLength();
|
||||
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);
|
||||
CodeDocumentLine& lastLine = *lines.getUnchecked (endLine);
|
||||
|
||||
firstLine->line = firstLine->line.substring (0, startPosition.getIndexInLine())
|
||||
+ lastLine->line.substring (endPosition.getIndexInLine());
|
||||
firstLine->updateLength();
|
||||
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)
|
||||
for (int 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;
|
||||
CodeDocumentLine& l = *lines.getUnchecked (i);
|
||||
const CodeDocumentLine& previousLine = *lines.getUnchecked (i - 1);
|
||||
l.lineStartInFile = previousLine.lineStartInFile + previousLine.lineLength;
|
||||
}
|
||||
|
||||
checkLastLineStatus();
|
||||
|
||||
const int totalChars = getNumCharacters();
|
||||
|
||||
for (i = 0; i < positionsToMaintain.size(); ++i)
|
||||
for (int i = 0; i < positionsToMaintain.size(); ++i)
|
||||
{
|
||||
CodeDocument::Position* p = positionsToMaintain.getUnchecked(i);
|
||||
CodeDocument::Position& p = *positionsToMaintain.getUnchecked(i);
|
||||
|
||||
if (p->getPosition() > startPosition.getPosition())
|
||||
p->setPosition (jmax (startPos, p->getPosition() + startPos - endPos));
|
||||
if (p.getPosition() > startPosition.getPosition())
|
||||
p.setPosition (jmax (startPos, p.getPosition() + startPos - endPos));
|
||||
|
||||
if (p->getPosition() > totalChars)
|
||||
p->setPosition (totalChars);
|
||||
if (p.getPosition() > totalChars)
|
||||
p.setPosition (totalChars);
|
||||
}
|
||||
|
||||
sendListenerChangeMessage (firstAffectedLine, lastAffectedLine);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
Lines are numbered from zero, and if the line or index are beyond the bounds of the document,
|
||||
they will be adjusted to keep them within its limits.
|
||||
*/
|
||||
Position (const CodeDocument* ownerDocument,
|
||||
Position (const CodeDocument& ownerDocument,
|
||||
int line, int indexInLine) noexcept;
|
||||
|
||||
/** Creates a position based on a character index in a document.
|
||||
|
|
@ -87,7 +87,7 @@ public:
|
|||
If the position is beyond the range of the document, it'll be adjusted to keep it
|
||||
inside.
|
||||
*/
|
||||
Position (const CodeDocument* ownerDocument,
|
||||
Position (const CodeDocument& ownerDocument,
|
||||
int charactersFromStartOfDocument) noexcept;
|
||||
|
||||
/** Creates a copy of another position.
|
||||
|
|
@ -101,6 +101,7 @@ public:
|
|||
~Position();
|
||||
|
||||
Position& operator= (const Position& other);
|
||||
|
||||
bool operator== (const Position& other) const noexcept;
|
||||
bool operator!= (const Position& other) const noexcept;
|
||||
|
||||
|
|
@ -159,18 +160,18 @@ public:
|
|||
characters.
|
||||
@see moveBy
|
||||
*/
|
||||
const Position movedBy (int characterDelta) const;
|
||||
Position movedBy (int characterDelta) const;
|
||||
|
||||
/** Returns a position which is the same as this one, moved up or down by the specified
|
||||
number of lines.
|
||||
@see movedBy
|
||||
*/
|
||||
const Position movedByLines (int deltaLines) const;
|
||||
Position movedByLines (int deltaLines) const;
|
||||
|
||||
/** Returns the character in the document at this position.
|
||||
@see getLineText
|
||||
*/
|
||||
const juce_wchar getCharacter() const;
|
||||
juce_wchar getCharacter() const;
|
||||
|
||||
/** Returns the line from the document that this position is within.
|
||||
@see getCharacter, getLineNumber
|
||||
|
|
@ -334,32 +335,30 @@ public:
|
|||
class JUCE_API Iterator
|
||||
{
|
||||
public:
|
||||
Iterator (CodeDocument* document);
|
||||
Iterator (const Iterator& other);
|
||||
Iterator (const CodeDocument& document) noexcept;
|
||||
Iterator (const Iterator& other) noexcept;
|
||||
Iterator& operator= (const Iterator& other) noexcept;
|
||||
~Iterator() noexcept;
|
||||
|
||||
/** Reads the next character and returns it.
|
||||
@see peekNextChar
|
||||
*/
|
||||
juce_wchar nextChar();
|
||||
juce_wchar nextChar() noexcept;
|
||||
|
||||
/** Reads the next character without advancing the current position. */
|
||||
juce_wchar peekNextChar() const;
|
||||
juce_wchar peekNextChar() const noexcept;
|
||||
|
||||
/** Advances the position by one character. */
|
||||
void skip();
|
||||
void skip() noexcept;
|
||||
|
||||
/** Returns the position of the next character as its position within the
|
||||
whole document.
|
||||
*/
|
||||
/** Returns the position as the number of characters from the start of the document. */
|
||||
int getPosition() const noexcept { return position; }
|
||||
|
||||
/** Skips over any whitespace characters until the next character is non-whitespace. */
|
||||
void skipWhitespace();
|
||||
void skipWhitespace() noexcept;
|
||||
|
||||
/** Skips forward until the next character will be the first character on the next line */
|
||||
void skipToEndOfLine();
|
||||
void skipToEndOfLine() noexcept;
|
||||
|
||||
/** Returns the line number of the next character. */
|
||||
int getLine() const noexcept { return line; }
|
||||
|
|
@ -368,7 +367,7 @@ public:
|
|||
bool isEOF() const noexcept;
|
||||
|
||||
private:
|
||||
CodeDocument* document;
|
||||
const CodeDocument* document;
|
||||
mutable String::CharPointerType charPointer;
|
||||
int line, position;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public:
|
|||
}
|
||||
else if (lineNum < document.getNumLines())
|
||||
{
|
||||
const CodeDocument::Position pos (&document, lineNum, 0);
|
||||
const CodeDocument::Position pos (document, lineNum, 0);
|
||||
createTokens (pos.getPosition(), pos.getLineText(),
|
||||
source, *tokeniser, newTokens);
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ public:
|
|||
{
|
||||
const String line (document.getLine (lineNum));
|
||||
|
||||
CodeDocument::Position lineStart (&document, lineNum, 0), lineEnd (&document, lineNum + 1, 0);
|
||||
CodeDocument::Position lineStart (document, lineNum, 0), lineEnd (document, lineNum + 1, 0);
|
||||
newHighlightStart = indexToColumn (jmax (0, selectionStart.getPosition() - lineStart.getPosition()),
|
||||
line, spacesPerTab);
|
||||
newHighlightEnd = indexToColumn (jmin (lineEnd.getPosition() - lineStart.getPosition(), selectionEnd.getPosition() - lineStart.getPosition()),
|
||||
|
|
@ -71,25 +71,10 @@ public:
|
|||
highlightColumnStart = newHighlightStart;
|
||||
highlightColumnEnd = newHighlightEnd;
|
||||
}
|
||||
else
|
||||
else if (tokens == newTokens)
|
||||
{
|
||||
if (tokens.size() == newTokens.size())
|
||||
{
|
||||
bool allTheSame = true;
|
||||
|
||||
for (int i = newTokens.size(); --i >= 0;)
|
||||
{
|
||||
if (tokens.getReference(i) != newTokens.getReference(i))
|
||||
{
|
||||
allTheSame = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allTheSame)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
tokens.swapWithArray (newTokens);
|
||||
return true;
|
||||
|
|
@ -144,14 +129,14 @@ public:
|
|||
private:
|
||||
struct SyntaxToken
|
||||
{
|
||||
SyntaxToken (const String& text_, const int type) noexcept
|
||||
: text (text_), tokenType (type), width (-1.0f)
|
||||
SyntaxToken (const String& t, const int type) noexcept
|
||||
: text (t), tokenType (type), width (-1.0f)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator!= (const SyntaxToken& other) const noexcept
|
||||
bool operator== (const SyntaxToken& other) const noexcept
|
||||
{
|
||||
return text != other.text || tokenType != other.tokenType;
|
||||
return tokenType == other.tokenType && text == other.text;
|
||||
}
|
||||
|
||||
String text;
|
||||
|
|
@ -321,13 +306,13 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& document_,
|
|||
horizontalScrollBar (false),
|
||||
codeTokeniser (codeTokeniser_)
|
||||
{
|
||||
caretPos = CodeDocument::Position (&document_, 0, 0);
|
||||
caretPos = CodeDocument::Position (document_, 0, 0);
|
||||
caretPos.setPositionMaintained (true);
|
||||
|
||||
selectionStart = CodeDocument::Position (&document_, 0, 0);
|
||||
selectionStart = CodeDocument::Position (document_, 0, 0);
|
||||
selectionStart.setPositionMaintained (true);
|
||||
|
||||
selectionEnd = CodeDocument::Position (&document_, 0, 0);
|
||||
selectionEnd = CodeDocument::Position (document_, 0, 0);
|
||||
selectionEnd.setPositionMaintained (true);
|
||||
|
||||
setOpaque (true);
|
||||
|
|
@ -509,8 +494,8 @@ void CodeEditorComponent::rebuildLineTokens()
|
|||
|
||||
jassert (numNeeded == lines.size());
|
||||
|
||||
CodeDocument::Iterator source (&document);
|
||||
getIteratorForPosition (CodeDocument::Position (&document, firstLineOnScreen, 0).getPosition(), source);
|
||||
CodeDocument::Iterator source (document);
|
||||
getIteratorForPosition (CodeDocument::Position (document, firstLineOnScreen, 0).getPosition(), source);
|
||||
|
||||
for (int i = 0; i < numNeeded; ++i)
|
||||
{
|
||||
|
|
@ -686,7 +671,7 @@ CodeDocument::Position CodeEditorComponent::getPositionAt (int x, int y)
|
|||
const int column = roundToInt ((x - (getGutterSize() - xOffset * charWidth)) / charWidth);
|
||||
const int index = columnToIndex (line, column);
|
||||
|
||||
return CodeDocument::Position (&document, line, index);
|
||||
return CodeDocument::Position (document, line, index);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -727,9 +712,8 @@ void CodeEditorComponent::insertTabAtCaret()
|
|||
|
||||
bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop()
|
||||
{
|
||||
if (! getHighlightedRegion().isEmpty())
|
||||
return false;
|
||||
|
||||
if (getHighlightedRegion().isEmpty())
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine());
|
||||
|
|
@ -747,6 +731,7 @@ bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop()
|
|||
cut();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -776,8 +761,8 @@ void CodeEditorComponent::indentSelectedLines (const int spacesToAdd)
|
|||
|
||||
if (nonWhitespaceStart > 0 || lineText.trimStart().isNotEmpty())
|
||||
{
|
||||
const CodeDocument::Position wsStart (&document, line, 0);
|
||||
const CodeDocument::Position wsEnd (&document, line, nonWhitespaceStart);
|
||||
const CodeDocument::Position wsStart (document, line, 0);
|
||||
const CodeDocument::Position wsEnd (document, line, nonWhitespaceStart);
|
||||
|
||||
const int numLeadingSpaces = indexToColumn (line, wsEnd.getIndexInLine());
|
||||
const int newNumLeadingSpaces = jmax (0, numLeadingSpaces + spacesToAdd);
|
||||
|
|
@ -803,7 +788,6 @@ void CodeEditorComponent::cut()
|
|||
bool CodeEditorComponent::copyToClipboard()
|
||||
{
|
||||
newTransaction();
|
||||
|
||||
const String selection (document.getTextBetween (selectionStart, selectionEnd));
|
||||
|
||||
if (selection.isNotEmpty())
|
||||
|
|
@ -876,7 +860,7 @@ bool CodeEditorComponent::moveCaretDown (const bool selecting)
|
|||
newTransaction();
|
||||
|
||||
if (caretPos.getLineNumber() == document.getNumLines() - 1)
|
||||
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
|
||||
else
|
||||
moveLineDelta (1, selecting);
|
||||
|
||||
|
|
@ -888,7 +872,7 @@ bool CodeEditorComponent::moveCaretUp (const bool selecting)
|
|||
newTransaction();
|
||||
|
||||
if (caretPos.getLineNumber() == 0)
|
||||
moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, 0, 0), selecting);
|
||||
else
|
||||
moveLineDelta (-1, selecting);
|
||||
|
||||
|
|
@ -936,7 +920,7 @@ bool CodeEditorComponent::scrollDown()
|
|||
bool CodeEditorComponent::moveCaretToTop (const bool selecting)
|
||||
{
|
||||
newTransaction();
|
||||
moveCaretTo (CodeDocument::Position (&document, 0, 0), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, 0, 0), selecting);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -949,21 +933,21 @@ bool CodeEditorComponent::moveCaretToStartOfLine (const bool selecting)
|
|||
if (index >= caretPos.getIndexInLine() && caretPos.getIndexInLine() > 0)
|
||||
index = 0;
|
||||
|
||||
moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), index), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, caretPos.getLineNumber(), index), selecting);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeEditorComponent::moveCaretToEnd (const bool selecting)
|
||||
{
|
||||
newTransaction();
|
||||
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), selecting);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CodeEditorComponent::moveCaretToEndOfLine (const bool selecting)
|
||||
{
|
||||
newTransaction();
|
||||
moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting);
|
||||
moveCaretTo (CodeDocument::Position (document, caretPos.getLineNumber(), std::numeric_limits<int>::max()), selecting);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1031,8 +1015,8 @@ bool CodeEditorComponent::deleteForwards (const bool moveInWholeWordSteps)
|
|||
bool CodeEditorComponent::selectAll()
|
||||
{
|
||||
newTransaction();
|
||||
moveCaretTo (CodeDocument::Position (&document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false);
|
||||
moveCaretTo (CodeDocument::Position (&document, 0, 0), true);
|
||||
moveCaretTo (CodeDocument::Position (document, std::numeric_limits<int>::max(), std::numeric_limits<int>::max()), false);
|
||||
moveCaretTo (CodeDocument::Position (document, 0, 0), true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1070,14 +1054,14 @@ Range<int> CodeEditorComponent::getHighlightedRegion() const
|
|||
|
||||
void CodeEditorComponent::setHighlightedRegion (const Range<int>& newRange)
|
||||
{
|
||||
moveCaretTo (CodeDocument::Position (&document, newRange.getStart()), false);
|
||||
moveCaretTo (CodeDocument::Position (&document, newRange.getEnd()), true);
|
||||
moveCaretTo (CodeDocument::Position (document, newRange.getStart()), false);
|
||||
moveCaretTo (CodeDocument::Position (document, newRange.getEnd()), true);
|
||||
}
|
||||
|
||||
String CodeEditorComponent::getTextInRange (const Range<int>& range) const
|
||||
{
|
||||
return document.getTextBetween (CodeDocument::Position (&document, range.getStart()),
|
||||
CodeDocument::Position (&document, range.getEnd()));
|
||||
return document.getTextBetween (CodeDocument::Position (document, range.getStart()),
|
||||
CodeDocument::Position (document, range.getEnd()));
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
|
|
@ -1379,7 +1363,7 @@ void CodeEditorComponent::updateCachedIterators (int maxLineNum)
|
|||
const int linesBetweenCachedSources = jmax (10, document.getNumLines() / maxNumCachedPositions);
|
||||
|
||||
if (cachedIterators.size() == 0)
|
||||
cachedIterators.add (new CodeDocument::Iterator (&document));
|
||||
cachedIterators.add (new CodeDocument::Iterator (document));
|
||||
|
||||
if (codeTokeniser != nullptr)
|
||||
{
|
||||
|
|
@ -1458,8 +1442,8 @@ CodeEditorComponent::State::State (const State& other) noexcept
|
|||
|
||||
void CodeEditorComponent::State::restoreState (CodeEditorComponent& editor) const
|
||||
{
|
||||
editor.moveCaretTo (CodeDocument::Position (&editor.getDocument(), lastSelectionEnd), false);
|
||||
editor.moveCaretTo (CodeDocument::Position (&editor.getDocument(), lastCaretPos), true);
|
||||
editor.moveCaretTo (CodeDocument::Position (editor.getDocument(), lastSelectionEnd), false);
|
||||
editor.moveCaretTo (CodeDocument::Position (editor.getDocument(), lastCaretPos), true);
|
||||
|
||||
if (lastTopLine > 0 && lastTopLine < editor.getDocument().getNumLines())
|
||||
editor.scrollToLine (lastTopLine);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue