Browse Source

Added read-only support for the CodeEditorComponent.

tags/2021-05-28
jules 11 years ago
parent
commit
f89c2ca05d
2 changed files with 81 additions and 50 deletions
  1. +74
    -49
      modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp
  2. +7
    -1
      modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h

+ 74
- 49
modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.cpp View File

@@ -340,6 +340,7 @@ CodeEditorComponent::CodeEditorComponent (CodeDocument& doc, CodeTokeniser* cons
columnsOnScreen (0),
scrollbarThickness (16),
columnToTryToMaintain (-1),
readOnly (false),
useSpacesForTabs (false),
showLineNumbers (false),
shouldFollowDocumentChanges (false),
@@ -435,6 +436,11 @@ void CodeEditorComponent::setLineNumbersShown (const bool shouldBeShown)
}
}
void CodeEditorComponent::setReadOnly (bool b) noexcept
{
readOnly = b;
}
//==============================================================================
void CodeEditorComponent::resized()
{
@@ -745,37 +751,43 @@ void CodeEditorComponent::insertTextAtCaret (const String& newText)
void CodeEditorComponent::insertText (const String& newText)
{
document.deleteSection (selectionStart, selectionEnd);
if (! readOnly)
{
document.deleteSection (selectionStart, selectionEnd);
if (newText.isNotEmpty())
document.insertText (caretPos, newText);
if (newText.isNotEmpty())
document.insertText (caretPos, newText);
scrollToKeepCaretOnScreen();
scrollToKeepCaretOnScreen();
}
}
void CodeEditorComponent::insertTabAtCaret()
{
if (CharacterFunctions::isWhitespace (caretPos.getCharacter())
&& caretPos.getLineNumber() == caretPos.movedBy (1).getLineNumber())
if (! readOnly)
{
moveCaretTo (document.findWordBreakAfter (caretPos), false);
}
if (CharacterFunctions::isWhitespace (caretPos.getCharacter())
&& caretPos.getLineNumber() == caretPos.movedBy (1).getLineNumber())
{
moveCaretTo (document.findWordBreakAfter (caretPos), false);
}
if (useSpacesForTabs)
{
const int caretCol = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine());
const int spacesNeeded = spacesPerTab - (caretCol % spacesPerTab);
insertTextAtCaret (String::repeatedString (" ", spacesNeeded));
}
else
{
insertTextAtCaret ("\t");
if (useSpacesForTabs)
{
const int caretCol = indexToColumn (caretPos.getLineNumber(), caretPos.getIndexInLine());
const int spacesNeeded = spacesPerTab - (caretCol % spacesPerTab);
insertTextAtCaret (String::repeatedString (" ", spacesNeeded));
}
else
{
insertTextAtCaret ("\t");
}
}
}
bool CodeEditorComponent::deleteWhitespaceBackwardsToTabStop()
{
if (getHighlightedRegion().isEmpty())
if (getHighlightedRegion().isEmpty() && ! readOnly)
{
for (;;)
{
@@ -804,43 +816,46 @@ void CodeEditorComponent::unindentSelection() { indentSelectedLines (-spacesPe
void CodeEditorComponent::indentSelectedLines (const int spacesToAdd)
{
newTransaction();
CodeDocument::Position oldSelectionStart (selectionStart), oldSelectionEnd (selectionEnd), oldCaret (caretPos);
oldSelectionStart.setPositionMaintained (true);
oldSelectionEnd.setPositionMaintained (true);
oldCaret.setPositionMaintained (true);
if (! readOnly)
{
newTransaction();
const int lineStart = selectionStart.getLineNumber();
int lineEnd = selectionEnd.getLineNumber();
CodeDocument::Position oldSelectionStart (selectionStart), oldSelectionEnd (selectionEnd), oldCaret (caretPos);
oldSelectionStart.setPositionMaintained (true);
oldSelectionEnd.setPositionMaintained (true);
oldCaret.setPositionMaintained (true);
if (lineEnd > lineStart && selectionEnd.getIndexInLine() == 0)
--lineEnd;
const int lineStart = selectionStart.getLineNumber();
int lineEnd = selectionEnd.getLineNumber();
for (int line = lineStart; line <= lineEnd; ++line)
{
const String lineText (document.getLine (line));
const int nonWhitespaceStart = CodeEditorHelpers::findFirstNonWhitespaceChar (lineText);
if (lineEnd > lineStart && selectionEnd.getIndexInLine() == 0)
--lineEnd;
if (nonWhitespaceStart > 0 || lineText.trimStart().isNotEmpty())
for (int line = lineStart; line <= lineEnd; ++line)
{
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);
const String lineText (document.getLine (line));
const int nonWhitespaceStart = CodeEditorHelpers::findFirstNonWhitespaceChar (lineText);
if (newNumLeadingSpaces != numLeadingSpaces)
if (nonWhitespaceStart > 0 || lineText.trimStart().isNotEmpty())
{
document.deleteSection (wsStart, wsEnd);
document.insertText (wsStart, getTabString (newNumLeadingSpaces));
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);
if (newNumLeadingSpaces != numLeadingSpaces)
{
document.deleteSection (wsStart, wsEnd);
document.insertText (wsStart, getTabString (newNumLeadingSpaces));
}
}
}
}
selectionStart = oldSelectionStart;
selectionEnd = oldSelectionEnd;
caretPos = oldCaret;
selectionStart = oldSelectionStart;
selectionEnd = oldSelectionEnd;
caretPos = oldCaret;
}
}
void CodeEditorComponent::cut()
@@ -1116,6 +1131,9 @@ void CodeEditorComponent::selectRegion (const CodeDocument::Position& start,
//==============================================================================
bool CodeEditorComponent::undo()
{
if (readOnly)
return false;
ScopedValueSetter<bool> svs (shouldFollowDocumentChanges, true, false);
document.undo();
scrollToKeepCaretOnScreen();
@@ -1124,6 +1142,9 @@ bool CodeEditorComponent::undo()
bool CodeEditorComponent::redo()
{
if (readOnly)
return false;
ScopedValueSetter<bool> svs (shouldFollowDocumentChanges, true, false);
document.redo();
scrollToKeepCaretOnScreen();
@@ -1169,6 +1190,9 @@ bool CodeEditorComponent::keyPressed (const KeyPress& key)
{
if (! TextEditorKeyMapper<CodeEditorComponent>::invokeKeyFunction (*this, key))
{
if (readOnly)
return false;
if (key == KeyPress::tabKey || key.getTextCharacter() == '\t') handleTabKey();
else if (key == KeyPress::returnKey) handleReturnKey();
else if (key == KeyPress::escapeKey) handleEscapeKey();
@@ -1224,7 +1248,7 @@ void CodeEditorComponent::getCommandInfo (const CommandID commandID, Application
{
case StandardApplicationCommandIDs::cut:
result.setInfo (TRANS ("Cut"), TRANS ("Copies the currently selected text to the clipboard and deletes it."), "Editing", 0);
result.setActive (anythingSelected);
result.setActive (anythingSelected && ! readOnly);
result.defaultKeypresses.add (KeyPress ('x', ModifierKeys::commandModifier, 0));
break;
@@ -1236,12 +1260,13 @@ void CodeEditorComponent::getCommandInfo (const CommandID commandID, Application
case StandardApplicationCommandIDs::paste:
result.setInfo (TRANS ("Paste"), TRANS ("Inserts text from the clipboard."), "Editing", 0);
result.setActive (! readOnly);
result.defaultKeypresses.add (KeyPress ('v', ModifierKeys::commandModifier, 0));
break;
case StandardApplicationCommandIDs::del:
result.setInfo (TRANS ("Delete"), TRANS ("Deletes any selected text."), "Editing", 0);
result.setActive (anythingSelected);
result.setActive (anythingSelected && ! readOnly);
break;
case StandardApplicationCommandIDs::selectAll:
@@ -1252,13 +1277,13 @@ void CodeEditorComponent::getCommandInfo (const CommandID commandID, Application
case StandardApplicationCommandIDs::undo:
result.setInfo (TRANS ("Undo"), TRANS ("Undo"), "Editing", 0);
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::commandModifier, 0));
result.setActive (document.getUndoManager().canUndo());
result.setActive (document.getUndoManager().canUndo() && ! readOnly);
break;
case StandardApplicationCommandIDs::redo:
result.setInfo (TRANS ("Redo"), TRANS ("Redo"), "Editing", 0);
result.defaultKeypresses.add (KeyPress ('z', ModifierKeys::commandModifier | ModifierKeys::shiftModifier, 0));
result.setActive (document.getUndoManager().canRedo());
result.setActive (document.getUndoManager().canRedo() && ! readOnly);
break;
default:


+ 7
- 1
modules/juce_gui_extra/code_editor/juce_CodeEditorComponent.h View File

@@ -204,6 +204,12 @@ public:
/** Returns the font that the editor is using. */
const Font& getFont() const noexcept { return font; }
/** Makes the editor read-only. */
void setReadOnly (bool shouldBeReadOnly) noexcept;
/** Returns true if the editor is set to be read-only. */
bool isReadOnly() const noexcept { return readOnly; }
//==============================================================================
struct JUCE_API ColourScheme
{
@@ -352,7 +358,7 @@ private:
float charWidth;
int lineHeight, linesOnScreen, columnsOnScreen;
int scrollbarThickness, columnToTryToMaintain;
bool useSpacesForTabs, showLineNumbers, shouldFollowDocumentChanges;
bool readOnly, useSpacesForTabs, showLineNumbers, shouldFollowDocumentChanges;
double xOffset;
CodeDocument::Position caretPos, selectionStart, selectionEnd;


Loading…
Cancel
Save