void RangeTest::rangeCheck(KTextEditor::Range &valid) { QVERIFY(valid.isValid() && valid.start() <= valid.end()); KTextEditor::Cursor before(0, 1), start(0, 2), end(1, 4), after(1, 10); KTextEditor::Range result(start, end); QVERIFY(valid.isValid() && valid.start() <= valid.end()); valid.setRange(start, end); QVERIFY(valid.isValid() && valid.start() <= valid.end()); QCOMPARE(valid, result); valid.setRange(end, start); QVERIFY(valid.isValid() && valid.start() <= valid.end()); QCOMPARE(valid, result); valid.setStart(after); QVERIFY(valid.isValid() && valid.start() <= valid.end()); QCOMPARE(valid, KTextEditor::Range(after, after)); valid = result; QCOMPARE(valid, result); valid.setEnd(before); QVERIFY(valid.isValid() && valid.start() <= valid.end()); QCOMPARE(valid, KTextEditor::Range(before, before)); }
void AdaptSignatureAssistant::textChanged(KTextEditor::View* view, const KTextEditor::Range& invocationRange, const QString& removedText) { reset(); m_view = view; //FIXME: update signature assistant to play well with the rename assistant KTextEditor::Range sigAssistRange = invocationRange; if (!removedText.isEmpty()) { sigAssistRange.setRange(sigAssistRange.start(), sigAssistRange.start()); } m_document = view->document()->url(); DUChainReadLocker lock(DUChain::lock(), 300); if(!lock.locked()) { qCDebug(CPP) << "failed to lock duchain in time"; return; } KTextEditor::Range simpleInvocationRange = KTextEditor::Range(sigAssistRange); Declaration* funDecl = getDeclarationAtCursor(simpleInvocationRange.start(), m_document); if(!funDecl || !funDecl->type<FunctionType>()) return; if(QtFunctionDeclaration* classFun = dynamic_cast<QtFunctionDeclaration*>(funDecl)) { if (classFun->isSignal()) { // do not offer to change signature of a signal, as the implementation will be generated by moc return; } } Declaration* otherSide = 0; FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(funDecl); if (definition) { m_editingDefinition = true; otherSide = definition->declaration(); } else if ((definition = FunctionDefinition::definition(funDecl))) { m_editingDefinition = false; otherSide = definition; } if (!otherSide) return; m_otherSideContext = DUContextPointer(DUChainUtils::getFunctionContext(otherSide)); if (!m_otherSideContext) return; m_declarationName = funDecl->identifier(); m_otherSideId = otherSide->id(); m_otherSideTopContext = ReferencedTopDUContext(otherSide->topContext()); m_oldSignature = getDeclarationSignature(otherSide, m_otherSideContext.data(), true); //Schedule an update, to make sure the ranges match DUChain::self()->updateContextForUrl(m_otherSideTopContext->url(), TopDUContext::AllDeclarationsAndContexts); }
void TextHistory::transformRange(KTextEditor::Range &range, KTextEditor::MovingRange::InsertBehaviors insertBehaviors, KTextEditor::MovingRange::EmptyBehavior emptyBehavior, qint64 fromRevision, qint64 toRevision) { /** * invalidate on empty? */ bool invalidateIfEmpty = emptyBehavior == KTextEditor::MovingRange::InvalidateIfEmpty; if (invalidateIfEmpty && range.end() <= range.start()) { range = KTextEditor::Range::invalid(); return; } /** * -1 special meaning for from/toRevision */ if (fromRevision == -1) { fromRevision = revision(); } if (toRevision == -1) { toRevision = revision(); } /** * shortcut, same revision */ if (fromRevision == toRevision) { return; } /** * some invariants must hold */ Q_ASSERT(!m_historyEntries.empty()); Q_ASSERT(fromRevision != toRevision); Q_ASSERT(fromRevision >= m_firstHistoryEntryRevision); Q_ASSERT(fromRevision < (m_firstHistoryEntryRevision + m_historyEntries.size())); Q_ASSERT(toRevision >= m_firstHistoryEntryRevision); Q_ASSERT(toRevision < (m_firstHistoryEntryRevision + m_historyEntries.size())); /** * transform cursors */ // first: copy cursors, without range association int startLine = range.start().line(), startColumn = range.start().column(), endLine = range.end().line(), endColumn = range.end().column(); bool moveOnInsertStart = !(insertBehaviors & KTextEditor::MovingRange::ExpandLeft); bool moveOnInsertEnd = (insertBehaviors & KTextEditor::MovingRange::ExpandRight); /** * forward or reverse transform? */ if (toRevision > fromRevision) { for (int rev = fromRevision - m_firstHistoryEntryRevision + 1; rev <= (toRevision - m_firstHistoryEntryRevision); ++rev) { const Entry &entry = m_historyEntries.at(rev); entry.transformCursor(startLine, startColumn, moveOnInsertStart); entry.transformCursor(endLine, endColumn, moveOnInsertEnd); // got empty? if (endLine < startLine || (endLine == startLine && endColumn <= startColumn)) { if (invalidateIfEmpty) { range = KTextEditor::Range::invalid(); return; } else { // else normalize them endLine = startLine; endColumn = startColumn; } } } } else { for (int rev = fromRevision - m_firstHistoryEntryRevision; rev >= (toRevision - m_firstHistoryEntryRevision + 1); --rev) { const Entry &entry = m_historyEntries.at(rev); entry.reverseTransformCursor(startLine, startColumn, moveOnInsertStart); entry.reverseTransformCursor(endLine, endColumn, moveOnInsertEnd); // got empty? if (endLine < startLine || (endLine == startLine && endColumn <= startColumn)) { if (invalidateIfEmpty) { range = KTextEditor::Range::invalid(); return; } else { // else normalize them endLine = startLine; endColumn = startColumn; } } } } // now, copy cursors back range.setRange(KTextEditor::Cursor(startLine, startColumn), KTextEditor::Cursor(endLine, endColumn)); }