diff --git a/.gitignore b/.gitignore index 2c80521770..0f123a51f8 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ *.manifest.res *.o *.d +*.sdf xcuserdata contents.xcworkspacedata .DS_Store diff --git a/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp b/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp index 0926637998..c547d5085d 100644 --- a/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp +++ b/extras/Introjucer/Source/Code Editor/jucer_SourceCodeEditor.cpp @@ -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() diff --git a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp index 401462da3b..349eb3338a 100644 --- a/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp +++ b/modules/juce_audio_basics/sources/juce_ResamplingAudioSource.cpp @@ -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; diff --git a/modules/juce_core/containers/juce_Array.h b/modules/juce_core/containers/juce_Array.h index e432f74903..d5d260f67b 100644 --- a/modules/juce_core/containers/juce_Array.h +++ b/modules/juce_core/containers/juce_Array.h @@ -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; diff --git a/modules/juce_core/containers/juce_OwnedArray.h b/modules/juce_core/containers/juce_OwnedArray.h index dd8ce31ed1..13ce71759c 100644 --- a/modules/juce_core/containers/juce_OwnedArray.h +++ b/modules/juce_core/containers/juce_OwnedArray.h @@ -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. diff --git a/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp b/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp index 575ac8191a..0396a119ca 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeDocument.cpp @@ -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 (ownerDocument)), + : owner (const_cast (&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 (ownerDocument)), +CodeDocument::Position::Position (const CodeDocument& ownerDocument, const int characterPos_) noexcept + : owner (const_cast (&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,77 +770,72 @@ 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 (undoable) + if (text.isNotEmpty()) { - 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) + if (undoable) { - const int index = pos.getIndexInLine(); - textInsideOriginalLine = firstLine->line.substring (0, index) - + textInsideOriginalLine - + firstLine->line.substring (index); + undoManager.perform (new CodeDocumentInsertAction (*this, text, insertPos)); } - - maximumLineLength = -1; - Array 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) + else { - for (int i = 1; i < newLines.size(); ++i) + Position pos (*this, insertPos); + const int firstAffectedLine = pos.getLineNumber(); + int lastAffectedLine = firstAffectedLine + 1; + + CodeDocumentLine* const firstLine = lines [firstAffectedLine]; + String textInsideOriginalLine (text); + + if (firstLine != nullptr) { - CodeDocumentLine* const l = newLines.getUnchecked (i); - lines.insert (firstAffectedLine + i, l); + const int index = pos.getIndexInLine(); + textInsideOriginalLine = firstLine->line.substring (0, index) + + textInsideOriginalLine + + firstLine->line.substring (index); } - lastAffectedLine = lines.size(); + maximumLineLength = -1; + Array 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); + lastAffectedLine = lines.size(); + } + + 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); + } + + sendListenerChangeMessage (firstAffectedLine, lastAffectedLine); } - - 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); } } @@ -862,13 +843,11 @@ void CodeDocument::insert (const String& text, const int insertPos, const bool u 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); diff --git a/modules/juce_gui_extra/code_editor/juce_CodeDocument.h b/modules/juce_gui_extra/code_editor/juce_CodeDocument.h index 5fe717269f..9b64d55d21 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeDocument.h +++ b/modules/juce_gui_extra/code_editor/juce_CodeDocument.h @@ -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; }; diff --git a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp index f9c054e04d..34aea9c459 100644 --- a/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp +++ b/modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp @@ -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,24 +71,9 @@ 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; - } + return false; } tokens.swapWithArray (newTokens); @@ -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,25 +712,25 @@ void CodeEditorComponent::insertTabAtCaret() bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop() { - if (! getHighlightedRegion().isEmpty()) - return false; - - for (;;) + if (getHighlightedRegion().isEmpty()) { - const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); + for (;;) + { + const int currentColumn = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine()); - if (currentColumn <= 0 || (currentColumn % spacesPerTab) == 0) - break; + if (currentColumn <= 0 || (currentColumn % spacesPerTab) == 0) + break; - moveCaretLeft (false, true); - } + moveCaretLeft (false, true); + } - const String selected (getTextInRange (getHighlightedRegion())); + const String selected (getTextInRange (getHighlightedRegion())); - if (selected.isNotEmpty() && selected.trim().isEmpty()) - { - cut(); - return true; + if (selected.isNotEmpty() && selected.trim().isEmpty()) + { + 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::max(), std::numeric_limits::max()), selecting); + moveCaretTo (CodeDocument::Position (document, std::numeric_limits::max(), std::numeric_limits::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::max(), std::numeric_limits::max()), selecting); + moveCaretTo (CodeDocument::Position (document, std::numeric_limits::max(), std::numeric_limits::max()), selecting); return true; } bool CodeEditorComponent::moveCaretToEndOfLine (const bool selecting) { newTransaction(); - moveCaretTo (CodeDocument::Position (&document, caretPos.getLineNumber(), std::numeric_limits::max()), selecting); + moveCaretTo (CodeDocument::Position (document, caretPos.getLineNumber(), std::numeric_limits::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::max(), std::numeric_limits::max()), false); - moveCaretTo (CodeDocument::Position (&document, 0, 0), true); + moveCaretTo (CodeDocument::Position (document, std::numeric_limits::max(), std::numeric_limits::max()), false); + moveCaretTo (CodeDocument::Position (document, 0, 0), true); return true; } @@ -1070,14 +1054,14 @@ Range CodeEditorComponent::getHighlightedRegion() const void CodeEditorComponent::setHighlightedRegion (const Range& 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& 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);