Class: Cosmos::CompletionTextEdit

Inherits:
Qt::PlainTextEdit show all
Defined in:
lib/cosmos/gui/text/completion_text_edit.rb

Direct Known Subclasses

CompletionLineEdit, RubyEditor

Defined Under Namespace

Classes: SelectionDetails

Constant Summary collapse

TRUE_VARIANT =
Qt::Variant.new(true)
SELECTION_DETAILS_POOL =
[]

Constants inherited from Qt::PlainTextEdit

Qt::PlainTextEdit::AMP, Qt::PlainTextEdit::BLANK, Qt::PlainTextEdit::BREAK, Qt::PlainTextEdit::GT, Qt::PlainTextEdit::LT, Qt::PlainTextEdit::NBSP

Instance Method Summary collapse

Methods inherited from Qt::PlainTextEdit

#addText, #add_formatted_text, #appendText, #flush, #selected_lines, #selection_end_line, #selection_start_line

Constructor Details

#initialize(parent) ⇒ CompletionTextEdit

Returns a new instance of CompletionTextEdit.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 33

def initialize(parent)
  super(parent)
  setFocusPolicy(Qt::StrongFocus)
  setLineWrapMode(Qt::PlainTextEdit::NoWrap)

  @cursor = Qt::TextCursor.new(document())
  @selection_details = SELECTION_DETAILS_POOL.pop
  @selection_details = SelectionDetails.new unless @selection_details
  @selection_details.format.setProperty(Qt::TextFormat::FullWidthSelection, TRUE_VARIANT)
  @selection_details.selection.format = @selection_details.format
  @selection_details.selection.cursor = @cursor

  @last_hightlighted_line = 1
  @code_completion = nil
  begin
    @code_completion = Completion.new(self)
  rescue
    # Oh well - no completion
  end
end

Instance Method Details

#disposeObject



54
55
56
57
58
59
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 54

def dispose
  super()
  @cursor.dispose
  SELECTION_DETAILS_POOL << @selection_details
  @code_completion.dispose if @code_completion
end

#highlight_line(line, color = 'palegreen') ⇒ Object

102, 255, 102



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 148

def highlight_line(line, color = 'palegreen') #102, 255, 102
  color = Cosmos::getColor(color)
  # Store the line number in case we need to rehighlight this line
  @last_hightlighted_line = line
  brush = Cosmos.getBrush(color)
  @selection_details.format.setBackground(brush)
  # Get the textCursor and move it to the specified line
  @cursor.movePosition(Qt::TextCursor::Start)
  # The line number is based in 1 based but the PlainTextEdit is 0 based
  @cursor.movePosition(Qt::TextCursor::Down, Qt::TextCursor::MoveAnchor, line-1)
  @cursor.clearSelection
  # By setting the text cursor after moving it we ensure we can see the highlight
  # If we just called setExtraSelections without setting the cursor we might not be able to see it
  setTextCursor(@cursor)
  @selection_details.selection.format = @selection_details.format
  @selection_details.selection.cursor = @cursor
  setExtraSelections([@selection_details.selection])
  # Center the cursor to ensure it is visible
  centerCursor()
end

#indent_selectionObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 92

def indent_selection
  cursor = textCursor
  # Figure out if the cursor has a selection
  no_selection = true
  no_selection = false if cursor.hasSelection

  # Start the edit block so this can be all undone with a single undo step
  cursor.beginEditBlock
  selection_end = cursor.selectionEnd
  # Initially place the cursor at the beginning of the selection
  # If nothing is selected this will just put the cursor at the beginning of the current line
  cursor.setPosition(textCursor.selectionStart)
  cursor.movePosition(Qt::TextCursor::StartOfLine)
  result = true
  while (cursor.position < selection_end and result == true) or (no_selection)
    # Add two spaces for a standard Ruby indent
    cursor.insertText('  ')
    # Move the cursor to the beginning of the next line
    cursor.movePosition(Qt::TextCursor::StartOfLine)
    result = cursor.movePosition(Qt::TextCursor::Down)
    # Since we inserted two spaces we need to move the end position by two
    selection_end += 2
    # If nothing was selected then we're working with a single line and we can break
    break if no_selection
  end
  cursor.endEditBlock
end

#keyPressCallback=(callback) ⇒ Object



61
62
63
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 61

def keyPressCallback=(callback)
  @keypress_callback = callback
end

#keyPressEvent(event) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 65

def keyPressEvent(event)
  # If the completion popup is visible then ignore the event and allow the popup to handle it
  if (@code_completion and @code_completion.popup.isVisible)
    case event.key
    when Qt::Key_Return, Qt::Key_Enter
      event.ignore
      return
    end
  end

  continue = @keypress_callback.call(event) if @keypress_callback

  case event.key
  when Qt::Key_Tab
    if event.modifiers == Qt::NoModifier
      indent_selection()
    end
  when Qt::Key_Backtab
    unindent_selection()
  else
    if continue != false
      super(event)
      @code_completion.handle_keypress(event) if @code_completion
    end
  end
end

#rehighlight(color = 'palegreen') ⇒ Object



174
175
176
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 174

def rehighlight(color = 'palegreen')
  highlight_line(@last_hightlighted_line, color)
end

#stop_highlightObject



169
170
171
172
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 169

def stop_highlight
  # Clearing the extra selections with a nil array clears the selection
  self.setExtraSelections([])
end

#unindent_selectionObject



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/cosmos/gui/text/completion_text_edit.rb', line 120

def unindent_selection
  cursor = textCursor
  # Start the edit block so this can be undone with a single undo step
  cursor.beginEditBlock
  # Initially place the cursor at the beginning of the selection
  # If nothing is selected this will just put the cursor at the beginning of the current line
  selection_end = cursor.selectionEnd
  cursor.setPosition(textCursor.selectionStart)
  cursor.movePosition(Qt::TextCursor::StartOfLine)
  result = true
  while cursor.position <= selection_end and result == true
    # Since we inserted two spaces for an indentation we remove a single character twice
    2.times do
      # Only remove the text if we have spaces to remove
      if cursor.block.text =~ /^\s/
        cursor.deleteChar
        # Adjust the selection end since we just removed a character
        selection_end -= 1
      end
    end
    # Move down to the next line in case we have to unindent that
    # We store the result which is false if the move couldn't complete
    # For example if we're on the last line in the editor
    result = cursor.movePosition(Qt::TextCursor::Down)
  end
  cursor.endEditBlock
end