bool PythonCodeCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString& inserted, bool userInsertion, const KTextEditor::Cursor& position) { QList<QString> words; words << "for" << "raise" << "except" << "in"; foreach ( const QString& word, words ) { if ( view->document()->line(position.line()).mid(0, position.column()).endsWith(word + " ") ) { return true; } } // shebang / encoding lines if ( view->document()->line(position.line()).mid(0, position.column()).endsWith("#") && position.line() < 2 ) { return true; } // we're probably dealing with string formatting completion // is there any other case where this condition is true? if ( ! userInsertion && inserted.startsWith('{') ) { return true; } return KDevelop::CodeCompletionModel::shouldStartCompletion(view, inserted, userInsertion, position); }
/** * This returns the view line upon which realCursor is situated. * The view line is the number of lines in the view from the first line * The supplied cursor should be in real lines. */ int KateLayoutCache::viewLine(const KTextEditor::Cursor& realCursor) { if (realCursor.column() <= 0 || realCursor.line() < 0) return 0; KateLineLayoutPtr thisLine = line(realCursor.line()); for (int i = 0; i < thisLine->viewLineCount(); ++i) { const KateTextLayout& l = thisLine->viewLine(i); if (realCursor.column() >= l.startCol() && realCursor.column() < l.endCol()) return i; } return thisLine->viewLineCount() - 1; }
/** * Initiate completion when there is \c #include on a line (\c m_range * in a result of \c parseIncludeDirective() not empty -- i.e. there is some file present) * and cursor placed within that range... despite of completeness of the whole line. */ bool IncludeHelperCompletionModel::shouldStartCompletion( KTextEditor::View* view , const QString& inserted_text , bool user_insertion , const KTextEditor::Cursor& position ) { kDebug(DEBUG_AREA) << "position=" << position << ", inserted_text=" << inserted_text << ", ui=" << user_insertion; m_should_complete = false; auto* doc = view->document(); // get current document auto line = doc->line(position.line()); // get current line auto* iface = qobject_cast<KTextEditor::HighlightInterface*>(doc); // Do nothing if no highlighting interface or not suitable document or // a place within it... (we won't to complete smth in non C++ files or comments for example) if (!iface || !isSuitableDocumentAndHighlighting(doc->mimeType(), iface->highlightingModeAt(position))) return m_should_complete; // Try to parse it... auto r = parseIncludeDirective(line, false); m_should_complete = r.m_range.isValid(); if (m_should_complete) { kDebug(DEBUG_AREA) << "range=" << r.m_range; m_should_complete = position.column() >= r.m_range.start().column() && position.column() <= r.m_range.end().column(); if (m_should_complete) { m_closer = r.close_char(); kDebug(DEBUG_AREA) << "closer=" << m_closer; } } else if (position.column() == line.length()) { auto text = tryToCompleteIncludeDirective(line.mid(0, position.column()).trimmed()); m_should_complete = !text.isEmpty(); if (m_should_complete) { /// \todo Hardcoded angle bracket! Better to check what file was selected /// (from system path or session specific) and replace it accordingly... text += QLatin1String(" <"); auto start = position; start.setColumn(0); auto range = KTextEditor::Range{start, position}; view->document()->replaceText(range, text); } } return m_should_complete; }
void TextCursor::setPosition(const KTextEditor::Cursor& position, bool init) { // any change or init? else do nothing if (!init && position.line() == line() && position.column() == m_column) return; // remove cursor from old block in any case if (m_block) m_block->removeCursor (this); // first: validate the line and column, else invalid if (position.column() < 0 || position.line () < 0 || position.line () >= m_buffer.lines ()) { if (!m_range) m_buffer.m_invalidCursors.insert (this); m_block = 0; m_line = m_column = -1; return; } // else, find block TextBlock *block = m_buffer.blockForIndex (m_buffer.blockForLine (position.line())); Q_ASSERT(block); // get line TextLine textLine = block->line (position.line()); #if 0 // this is no good idea, smart cursors don't do that, too, for non-wrapping cursors // now, validate column, else stay invalid if (position.column() > textLine->text().size()) { if (!m_range) m_buffer.m_invalidCursors.insert (this); m_block = 0; m_line = m_column = -1; return; } #endif // if cursor was invalid before, remove it from invalid cursor list if (!m_range && !m_block && !init) { Q_ASSERT(m_buffer.m_invalidCursors.contains (this)); m_buffer.m_invalidCursors.remove (this); } // else: valid cursor m_block = block; m_line = position.line () - m_block->startLine (); m_column = position.column (); m_block->insertCursor (this); }
QString Help::getKeyword(KTextEditor::View *view) { if(!view) { return QString(); } // get current position int row, col, col1, col2; QString word; KTextEditor::Document *doc = view->document(); KTextEditor::Cursor cursor = view->cursorPosition(); row = cursor.line(); col = cursor.column(); if (m_edit->getCurrentWord(doc, row, col, KileDocument::EditorExtension::smTex, word, col1, col2)) { // There is no starred keyword in the references. So if // dani 04.08.2004 // we find one, we better try the unstarred keyword. if(word.right(1) == "*") { return word.left(word.length() - 1); } else { return word; } } else { return QString(); } }
int KateLayoutCache::displayViewLine(const KTextEditor::Cursor& virtualCursor, bool limitToVisible) { KTextEditor::Cursor work = viewCacheStart(); // only try this with valid lines! if (work.isValid()) work.setLine(m_renderer->folding().lineToVisibleLine(work.line())); if (!work.isValid()) return virtualCursor.line(); int limit = m_textLayouts.count(); // Efficient non-word-wrapped path if (!m_renderer->view()->dynWordWrap()) { int ret = virtualCursor.line() - work.line(); if (limitToVisible && (ret < 0 || ret > limit)) return -1; else return ret; } if (work == virtualCursor) { return 0; } int ret = -(int)viewLine(viewCacheStart()); bool forwards = (work < virtualCursor); // FIXME switch to using ranges? faster? if (forwards) { while (work.line() != virtualCursor.line()) { ret += viewLineCount(m_renderer->folding().visibleLineToLine(work.line())); work.setLine(work.line() + 1); if (limitToVisible && ret > limit) return -1; } } else { while (work.line() != virtualCursor.line()) { work.setLine(work.line() - 1); ret -= viewLineCount(m_renderer->folding().visibleLineToLine(work.line())); if (limitToVisible && ret < 0) return -1; } } // final difference KTextEditor::Cursor realCursor = virtualCursor; realCursor.setLine(m_renderer->folding().visibleLineToLine(realCursor.line())); if (realCursor.column() == -1) realCursor.setColumn(m_renderer->doc()->lineLength(realCursor.line())); ret += viewLine(realCursor); if (limitToVisible && (ret < 0 || ret > limit)) return -1; return ret; }
void TextHistory::wrapLine(const KTextEditor::Cursor &position) { // create and add new entry Entry entry; entry.type = Entry::WrapLine; entry.line = position.line(); entry.column = position.column(); addEntry(entry); }
void RangeTest::testCursorStringConversion() { using KTextEditor::Cursor; KTextEditor::Cursor c; QCOMPARE(c.line(), 0); QCOMPARE(c.column(), 0); QCOMPARE(c.toString(), QStringLiteral("(0, 0)")); c = Cursor::fromString(QStringLiteral("(0, 0)")); QCOMPARE(c.toString(), QStringLiteral("(0, 0)")); c = Cursor::fromString(QStringLiteral("(0,0)")); QCOMPARE(c.toString(), QStringLiteral("(0, 0)")); c.setPosition(-1, -1); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-1, -1)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-1,-1)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c.setPosition(12, 42); QCOMPARE(c.toString(), QStringLiteral("(12, 42)")); c = Cursor::fromString(QStringLiteral("(12, 42)")); QCOMPARE(c.toString(), QStringLiteral("(12, 42)")); c = Cursor::fromString(QStringLiteral("( 12,42)")); QCOMPARE(c.toString(), QStringLiteral("(12, 42)")); c.setPosition(12, 42); QCOMPARE(c.toString(), QStringLiteral("(12, 42)")); c = Cursor::fromString(QStringLiteral("(12, 42)")); QCOMPARE(c.toString(), QStringLiteral("(12, 42)")); c.setPosition(-12, 42); QCOMPARE(c.toString(), QStringLiteral("(-12, 42)")); c = Cursor::fromString(QStringLiteral("(-12, 42)")); QCOMPARE(c.toString(), QStringLiteral("(-12, 42)")); c = Cursor::fromString(QStringLiteral("(-12, +42)")); QCOMPARE(c.toString(), QStringLiteral("(-12, 42)")); c = Cursor::fromString(QStringLiteral("( -12 , +42)")); QCOMPARE(c.toString(), QStringLiteral("(-12, 42)")); c = Cursor::fromString(QStringLiteral("(-12 , 42 )")); QCOMPARE(c.toString(), QStringLiteral("(-12, 42)")); // test invalid input c = Cursor::fromString(QStringLiteral("( - 12 , + 42)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(, 42)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-, -)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-, -)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-x,y)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); c = Cursor::fromString(QStringLiteral("(-3,-2y)")); QCOMPARE(c.toString(), QStringLiteral("(-1, -1)")); }
unsigned int KDocumentTextBuffer::cursorToOffset_kte( const KTextEditor::Cursor &cursor ) { unsigned int offset = 0; for( int i = 0; i < cursor.line(); i++ ) { offset += countUnicodeCharacters(kDocument()->line(i)) + 1; // Add newline } offset += countUnicodeCharacters(kDocument()->line(cursor.line()).left(cursor.column())); return offset; }
KTextEditor::Cursor KDocumentTextBuffer::offsetRelativeTo_kte(const KTextEditor::Cursor& cursor, unsigned int offset) { int lineno = cursor.line(); const QString& firstLine = kDocument()->line(lineno).mid(cursor.column()); unsigned int remaining = offset; int surrogates = surrogatesForCodePoints(firstLine, remaining); while ( remaining > 0 ) { remaining -= 1; // for the newline character lineno += 1; if ( remaining == 0 ) { surrogates = 0; break; } const QString& line = kDocument()->line(lineno); Q_ASSERT( lineno < kDocument()->lines() ); surrogates = surrogatesForCodePoints(line, remaining); } return KTextEditor::Cursor(lineno, lineno == cursor.line() ? cursor.column() + surrogates : surrogates); }
Recorder::Recorder(KTextEditor::View *view, Manager *manager) : QObject(view), m_manager(manager), m_view(view) { connect(m_manager, SIGNAL(watchedKeySequencesChanged()), this, SLOT(reloadWatchedKeySequences())); connect(this, SIGNAL(detectedTypedKeySequence(const QString&)), m_manager, SLOT(keySequenceTyped(const QString&))); KTextEditor::Cursor cursor = m_view->cursorPosition(); m_oldLine = cursor.line(); m_oldCol = cursor.column(); reloadWatchedKeySequences(); }
void SwapFile::insertText (const KTextEditor::Cursor &position, const QString &text) { // skip if not open if (!m_swapfile.isOpen ()) return; // format: qint8, int, int, bytearray m_stream << EA_InsertText << position.line() << position.column() << text.toUtf8 (); m_needSync = true; }
void SwapFile::wrapLine (const KTextEditor::Cursor &position) { // skip if not open if (!m_swapfile.isOpen ()) return; // format: qint8, int, int m_stream << EA_WrapLine << position.line() << position.column(); m_needSync = true; }
void TextHistory::insertText(const KTextEditor::Cursor &position, int length, int oldLineLength) { // create and add new entry Entry entry; entry.type = Entry::InsertText; entry.line = position.line(); entry.column = position.column(); entry.length = length; entry.oldLineLength = oldLineLength; addEntry(entry); }
// Return the range containing the word left of the cursor KTextEditor::Range KateNewCompletionModel::completionRange(KTextEditor::View* view, const KTextEditor::Cursor &position) { int line = position.line(); int col = position.column(); KTextEditor::Document *doc = view->document(); // ktuan java case: new List<Integer> // yieldXXX, Ent::load('XXX, genXXX, getXXX { QString text = view->document()->line(position.line()).left(position.column()); const static QRegExp ktuan_new_class("((new \\w*)|(gen\\w*)|(get\\w*))$"); int pos = ktuan_new_class.indexIn(text); if (pos >= 0) { return KTextEditor::Range( KTextEditor::Cursor( line, pos ), position ); } } return KTextEditor::Range( KTextEditor::Cursor( line, col ), position ); }
// Take the given QML line and check if it's a line of the form foo.bar: value. // Return ranges for the key and the value. const QPair<KTextEditor::Range, KTextEditor::Range> parseProperty(const QString& line, const KTextEditor::Cursor& position) { QStringList items = line.split(';'); QString matchingItem; int col_offset = -1; // This is to also support FooAnimation { foo: bar; baz: bang; duration: 200 } // or similar foreach ( const QString& item, items ) { col_offset += item.size() + 1; if ( position.column() < col_offset ) { matchingItem = item; break; } }
bool KateNewCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString &insertedText, bool userInsertion, const KTextEditor::Cursor &position) { if (!userInsertion) return false; if(insertedText.isEmpty()) return false; KateView *v = qobject_cast<KateView*> (view); QString text = view->document()->line(position.line()).left(position.column()); static const QRegExp ktuan_new_class("((new \\w*)|(gen\\w*)|(get\\w*))$"); if (ktuan_new_class.indexIn(text) >= 0) return true; return false; }
// Return the range containing the word left of the cursor KTextEditor::Range KateWordCompletionModel::completionRange(KTextEditor::View* view, const KTextEditor::Cursor &position) { int line = position.line(); int col = position.column(); KTextEditor::Document *doc = view->document(); while ( col > 0 ) { QChar c = ( doc->character( KTextEditor::Cursor( line, col-1 ) ) ); if ( c.isLetterOrNumber() || c.isMark() || c == '_' ) { col--; continue; } break; } return KTextEditor::Range( KTextEditor::Cursor( line, col ), position ); }
bool KateWordCompletionModel::shouldStartCompletion(KTextEditor::View* view, const QString &insertedText, bool userInsertion, const KTextEditor::Cursor &position) { if (!userInsertion) return false; if(insertedText.isEmpty()) return false; KateView *v = qobject_cast<KateView*> (view); QString text = view->document()->line(position.line()).left(position.column()); uint check=v->config()->wordCompletionMinimalWordLength(); if (check<=0) return true; int start=text.length(); int end=text.length()-check; if (end<0) return false; for (int i=start-1;i>=end;i--) { QChar c=text.at(i); if (! (c.isLetter() || (c.isNumber()) || c=='_') ) return false; } return true; }
QString VariableController::expressionUnderCursor(KTextEditor::Document* doc, const KTextEditor::Cursor& cursor) { QString line = doc->line(cursor.line()); int index = cursor.column(); QChar c = line[index]; if (!c.isLetterOrNumber() && c != '_' && c != '$') return QString(); int start = Utils::expressionAt(line, index); int end = index; for (; end < line.size(); ++end) { QChar c = line[end]; if (!(c.isLetterOrNumber() || c == '_' || c == '$')) break; } if (!(start < end)) return QString(); QString expression(line.mid(start, end-start)); expression = expression.trimmed(); return expression; }
bool Recorder::eventFilter(QObject* /* o */, QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = (QKeyEvent*)(e); int curLine, curCol; KTextEditor::Cursor cursor = m_view->cursorPosition(); curLine = cursor.line(); curCol = cursor.column(); if(curLine != m_oldLine || m_oldCol+1 != curCol) { m_typedSequence.clear(); m_oldLine = curLine; m_oldCol = curCol; } else { ++m_oldCol; } m_typedSequence += keyEvent->text(); if(m_typedSequence.length() == m_maxSequenceLength + 1) { m_typedSequence = m_typedSequence.mid(1, m_typedSequence.length() - 1); } return seekForKeySequence(m_typedSequence); } return false; }
void KateLayoutCache::updateViewCache(const KTextEditor::Cursor& startPos, int newViewLineCount, int viewLinesScrolled) { //kDebug( 13033 ) << startPos << " nvlc " << newViewLineCount << " vls " << viewLinesScrolled; int oldViewLineCount = m_textLayouts.count(); if (newViewLineCount == -1) newViewLineCount = oldViewLineCount; enableLayoutCache = true; int realLine; if (newViewLineCount == -1) realLine = m_renderer->folding().visibleLineToLine(m_renderer->folding().lineToVisibleLine(startPos.line())); else realLine = m_renderer->folding().visibleLineToLine(startPos.line()); int _viewLine = 0; if (wrap()) { // TODO check these assumptions are ok... probably they don't give much speedup anyway? if (startPos == m_startPos && m_textLayouts.count()) { _viewLine = m_textLayouts.first().viewLine(); } else if (viewLinesScrolled > 0 && viewLinesScrolled < m_textLayouts.count()) { _viewLine = m_textLayouts[viewLinesScrolled].viewLine(); } else { KateLineLayoutPtr l = line(realLine); if (l) { Q_ASSERT(l->isValid()); Q_ASSERT(l->length() >= startPos.column() || m_renderer->view()->wrapCursor()); for (; _viewLine < l->viewLineCount(); ++_viewLine) { const KateTextLayout& t = l->viewLine(_viewLine); if (t.startCol() >= startPos.column() || _viewLine == l->viewLineCount() - 1) goto foundViewLine; } // FIXME FIXME need to calculate past-end-of-line position here... Q_ASSERT(false); foundViewLine: Q_ASSERT(true); } } } m_startPos = startPos; // Move the text layouts if we've just scrolled... if (viewLinesScrolled != 0) { // loop backwards if we've just scrolled up... bool forwards = viewLinesScrolled >= 0 ? true : false; for (int z = forwards ? 0 : m_textLayouts.count() - 1; forwards ? (z < m_textLayouts.count()) : (z >= 0); forwards ? z++ : z--) { int oldZ = z + viewLinesScrolled; if (oldZ >= 0 && oldZ < m_textLayouts.count()) m_textLayouts[z] = m_textLayouts[oldZ]; } } // Resize functionality if (newViewLineCount > oldViewLineCount) { m_textLayouts.reserve(newViewLineCount); } else if (newViewLineCount < oldViewLineCount) { /* FIXME reintroduce... check we're not missing any int lastLine = m_textLayouts[newSize - 1].line(); for (int i = oldSize; i < newSize; i++) { const KateTextLayout& layout = m_textLayouts[i]; if (layout.line() > lastLine && !layout.viewLine()) layout.kateLineLayout()->layout()->setCacheEnabled(false); }*/ m_textLayouts.resize(newViewLineCount); } KateLineLayoutPtr l = line(realLine); for (int i = 0; i < newViewLineCount; ++i) { if (!l) { if (i < m_textLayouts.count()) { if (m_textLayouts[i].isValid()) m_textLayouts[i] = KateTextLayout::invalid(); } else { m_textLayouts.append(KateTextLayout::invalid()); } continue; } Q_ASSERT(l->isValid()); Q_ASSERT(_viewLine < l->viewLineCount()); if (i < m_textLayouts.count()) { bool dirty = false; if (m_textLayouts[i].line() != realLine || m_textLayouts[i].viewLine() != _viewLine || (!m_textLayouts[i].isValid() && l->viewLine(_viewLine).isValid())) dirty = true; m_textLayouts[i] = l->viewLine(_viewLine); if (dirty) m_textLayouts[i].setDirty(true); } else { m_textLayouts.append(l->viewLine(_viewLine)); } //kDebug( 13033 ) << "Laid out line " << realLine << " (" << l << "), viewLine " << _viewLine << " (" << m_textLayouts[i].kateLineLayout().data() << ")"; //m_textLayouts[i].debugOutput(); _viewLine++; if (_viewLine > l->viewLineCount() - 1) { int virtualLine = l->virtualLine() + 1; realLine = m_renderer->folding().visibleLineToLine(virtualLine); _viewLine = 0; if (realLine < m_renderer->doc()->lines()) { l = line(realLine, virtualLine); } else { l = 0; } } } enableLayoutCache = false; }
/** Conversion function from KTextEditor::Cursor to QtScript cursor */ static QScriptValue cursorToScriptValue(QScriptEngine *engine, const KTextEditor::Cursor &cursor) { QString code = QString("new Cursor(%1, %2);").arg(cursor.line()) .arg(cursor.column()); return engine->evaluate(code); }
int KileScriptDocument::nextNonSpaceColumn(const KTextEditor::Cursor& cursor) { return nextNonSpaceColumn(cursor.line(), cursor.column()); }
bool KileScriptDocument::matchesAt(const KTextEditor::Cursor& cursor, const QString &s) { QString textline = m_document->line(cursor.line()); return textline.mid(cursor.column()).startsWith(s); }
bool KileScriptDocument::truncate(const KTextEditor::Cursor& cursor) { return truncate(cursor.line(), cursor.column()); }
QList<QTextLayout::FormatRange> KateRenderer::decorationsForLine( const Kate::TextLine& textLine, int line, bool selectionsOnly, KateRenderRange* completionHighlight, bool completionSelected ) const { QList<QTextLayout::FormatRange> newHighlight; // Don't compute the highlighting if there isn't going to be any highlighting QList<Kate::TextRange *> rangesWithAttributes = m_doc->buffer().rangesForLine (line, m_printerFriendly ? 0 : m_view, true); if (selectionsOnly || textLine->attributesList().count() || rangesWithAttributes.count()) { RenderRangeList renderRanges; // Add the inbuilt highlighting to the list NormalRenderRange* inbuiltHighlight = new NormalRenderRange(); const QVector<Kate::TextLineData::Attribute> &al = textLine->attributesList(); for (int i = 0; i < al.count(); ++i) if (al[i].length > 0 && al[i].attributeValue > 0) inbuiltHighlight->addRange(new KTextEditor::Range(KTextEditor::Cursor(line, al[i].offset), al[i].length), specificAttribute(al[i].attributeValue)); renderRanges.append(inbuiltHighlight); if (!completionHighlight) { // check for dynamic hl stuff const QSet<Kate::TextRange *> *rangesMouseIn = m_view ? m_view->rangesMouseIn () : 0; const QSet<Kate::TextRange *> *rangesCaretIn = m_view ? m_view->rangesCaretIn () : 0; bool anyDynamicHlsActive = m_view && (!rangesMouseIn->empty() || !rangesCaretIn->empty()); // sort all ranges, we want that the most specific ranges win during rendering, multiple equal ranges are kind of random, still better than old smart rangs behavior ;) qSort (rangesWithAttributes.begin(), rangesWithAttributes.end(), rangeLessThanForRenderer); // loop over all ranges for (int i = 0; i < rangesWithAttributes.size(); ++i) { // real range Kate::TextRange *kateRange = rangesWithAttributes[i]; // calculate attribute, default: normal attribute KTextEditor::Attribute::Ptr attribute = kateRange->attribute(); if (anyDynamicHlsActive) { // check mouse in if (KTextEditor::Attribute::Ptr attributeMouseIn = attribute->dynamicAttribute (KTextEditor::Attribute::ActivateMouseIn)) { if (rangesMouseIn->contains (kateRange)) attribute = attributeMouseIn; } // check caret in if (KTextEditor::Attribute::Ptr attributeCaretIn = attribute->dynamicAttribute (KTextEditor::Attribute::ActivateCaretIn)) { if (rangesCaretIn->contains (kateRange)) attribute = attributeCaretIn; } } // span range NormalRenderRange *additionaHl = new NormalRenderRange(); additionaHl->addRange(new KTextEditor::Range (*kateRange), attribute); renderRanges.append(additionaHl); } } else { // Add the code completion arbitrary highlight to the list renderRanges.append(completionHighlight); } // Add selection highlighting if we're creating the selection decorations if ((selectionsOnly && showSelections() && m_view->selection()) || (completionHighlight && completionSelected) || m_view->blockSelection()) { NormalRenderRange* selectionHighlight = new NormalRenderRange(); // Set up the selection background attribute TODO: move this elsewhere, eg. into the config? static KTextEditor::Attribute::Ptr backgroundAttribute; if (!backgroundAttribute) backgroundAttribute = KTextEditor::Attribute::Ptr(new KTextEditor::Attribute()); backgroundAttribute->setBackground(config()->selectionColor()); backgroundAttribute->setForeground(attribute(KTextEditor::HighlightInterface::dsNormal)->selectedForeground().color()); // Create a range for the current selection if (completionHighlight && completionSelected) selectionHighlight->addRange(new KTextEditor::Range(line, 0, line + 1, 0), backgroundAttribute); else if(m_view->blockSelection() && m_view->selectionRange().overlapsLine(line)) selectionHighlight->addRange(new KTextEditor::Range(m_doc->rangeOnLine(m_view->selectionRange(), line)), backgroundAttribute); else { selectionHighlight->addRange(new KTextEditor::Range(m_view->selectionRange()), backgroundAttribute); } renderRanges.append(selectionHighlight); // highlighting for the vi visual modes } KTextEditor::Cursor currentPosition, endPosition; // Calculate the range which we need to iterate in order to get the highlighting for just this line if (selectionsOnly) { if(m_view->blockSelection()) { KTextEditor::Range subRange = m_doc->rangeOnLine(m_view->selectionRange(), line); currentPosition = subRange.start(); endPosition = subRange.end(); } else { KTextEditor::Range rangeNeeded = m_view->selectionRange() & KTextEditor::Range(line, 0, line + 1, 0); currentPosition = qMax(KTextEditor::Cursor(line, 0), rangeNeeded.start()); endPosition = qMin(KTextEditor::Cursor(line + 1, 0), rangeNeeded.end()); } } else { currentPosition = KTextEditor::Cursor(line, 0); endPosition = KTextEditor::Cursor(line + 1, 0); } // Main iterative loop. This walks through each set of highlighting ranges, and stops each // time the highlighting changes. It then creates the corresponding QTextLayout::FormatRanges. while (currentPosition < endPosition) { renderRanges.advanceTo(currentPosition); if (!renderRanges.hasAttribute()) { // No attribute, don't need to create a FormatRange for this text range currentPosition = renderRanges.nextBoundary(); continue; } KTextEditor::Cursor nextPosition = renderRanges.nextBoundary(); // Create the format range and populate with the correct start, length and format info QTextLayout::FormatRange fr; fr.start = currentPosition.column(); if (nextPosition < endPosition || endPosition.line() <= line) { fr.length = nextPosition.column() - currentPosition.column(); } else { // +1 to force background drawing at the end of the line when it's warranted fr.length = textLine->length() - currentPosition.column() + 1; } KTextEditor::Attribute::Ptr a = renderRanges.generateAttribute(); if (a) { fr.format = *a; if(selectionsOnly) { assignSelectionBrushesFromAttribute(fr, *a); } } newHighlight.append(fr); currentPosition = nextPosition; } if (completionHighlight) // Don't delete external completion render range renderRanges.removeAll(completionHighlight); qDeleteAll(renderRanges); } return newHighlight; }
bool KTEView::setCursorPosition( KTextEditor::Cursor position ) { kDebug() << "KTEView::setCursorPosition x: " << position.column() << " y: " << position.line() << "\n"; m_view->gotoLinePosition(position.line(), position.column()); return true; }
QPoint KTEView::cursorToCoordinate( const KTextEditor::Cursor& cursor ) const { return QPoint( cursor.column(), cursor.line() ); }