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 DebugSession::jumpToCursor() { if (KDevelop::IDocument* doc = KDevelop::ICore::self()->documentController()->activeDocument()) { KTextEditor::Cursor cursor = doc->cursorPosition(); if ( cursor.isValid() ) { // TODO disable all other breakpoints addSimpleUserCommand(QString("jump " + QString::number(cursor.line() + 1)).toAscii()); } } }
void DebugSession::runToCursor() { if (KDevelop::IDocument* doc = KDevelop::ICore::self()->documentController()->activeDocument()) { KTextEditor::Cursor cursor = doc->cursorPosition(); if ( cursor.isValid() ) { // TODO disable all other breakpoints QString temporaryBreakpointLocation = doc->url().path() + ':' + QString::number(cursor.line() + 1); InternalPdbCommand* temporaryBreakpointCmd = new InternalPdbCommand(0, 0, "tbreak " + temporaryBreakpointLocation + '\n'); addCommand(temporaryBreakpointCmd); addSimpleInternalCommand("continue"); updateLocation(); } } }
bool SwapFile::recover(QDataStream& stream, bool checkDigest) { if (!isValidSwapFile(stream, checkDigest)) { return false; } // disconnect current signals setTrackingEnabled(false); // needed to set undo/redo cursors in a sane way bool firstEditInGroup = false; KTextEditor::Cursor undoCursor = KTextEditor::Cursor::invalid(); KTextEditor::Cursor redoCursor = KTextEditor::Cursor::invalid(); // replay swapfile bool editRunning = false; bool brokenSwapFile = false; while (!stream.atEnd()) { if (brokenSwapFile) break; qint8 type; stream >> type; switch (type) { case EA_StartEditing: { m_document->editStart(); editRunning = true; firstEditInGroup = true; undoCursor = KTextEditor::Cursor::invalid(); redoCursor = KTextEditor::Cursor::invalid(); break; } case EA_FinishEditing: { m_document->editEnd(); // empty editStart() / editEnd() groups exist: only set cursor if required if (!firstEditInGroup) { // set undo/redo cursor of last KateUndoGroup of the undo manager m_document->undoManager()->setUndoRedoCursorsOfLastGroup(undoCursor, redoCursor); m_document->undoManager()->undoSafePoint(); } firstEditInGroup = false; editRunning = false; break; } case EA_WrapLine: { if (!editRunning) { brokenSwapFile = true; break; } int line = 0, column = 0; stream >> line >> column; // emulate buffer unwrapLine with document m_document->editWrapLine(line, column, true); // track undo/redo cursor if (firstEditInGroup) { firstEditInGroup = false; undoCursor = KTextEditor::Cursor(line, column); } redoCursor = KTextEditor::Cursor(line + 1, 0); break; } case EA_UnwrapLine: { if (!editRunning) { brokenSwapFile = true; break; } int line = 0; stream >> line; // assert valid line Q_ASSERT (line > 0); const int undoColumn = m_document->lineLength(line - 1); // emulate buffer unwrapLine with document m_document->editUnWrapLine(line - 1, true, 0); // track undo/redo cursor if (firstEditInGroup) { firstEditInGroup = false; undoCursor = KTextEditor::Cursor(line, 0); } redoCursor = KTextEditor::Cursor(line - 1, undoColumn); break; } case EA_InsertText: { if (!editRunning) { brokenSwapFile = true; break; } int line, column; QByteArray text; stream >> line >> column >> text; m_document->insertText(KTextEditor::Cursor(line, column), QString::fromUtf8 (text.data (), text.size())); // track undo/redo cursor if (firstEditInGroup) { firstEditInGroup = false; undoCursor = KTextEditor::Cursor(line, column); } redoCursor = KTextEditor::Cursor(line, column + text.size()); break; } case EA_RemoveText: { if (!editRunning) { brokenSwapFile = true; break; } int line, startColumn, endColumn; stream >> line >> startColumn >> endColumn; m_document->removeText (KTextEditor::Range(KTextEditor::Cursor(line, startColumn), KTextEditor::Cursor(line, endColumn))); // track undo/redo cursor if (firstEditInGroup) { firstEditInGroup = false; undoCursor = KTextEditor::Cursor(line, endColumn); } redoCursor = KTextEditor::Cursor(line, startColumn); break; } default: { kWarning( 13020 ) << "Unknown type:" << type; } } } // balanced editStart and editEnd? if (editRunning) { brokenSwapFile = true; m_document->editEnd(); } // warn the user if the swap file is not complete if (brokenSwapFile) { kWarning ( 13020 ) << "Some data might be lost"; } else { // set sane final cursor, if possible KTextEditor::View * view = m_document->activeView(); redoCursor = m_document->undoManager()->lastRedoCursor(); if (view && redoCursor.isValid()) { view->setCursorPosition(redoCursor); } } // reconnect the signals setTrackingEnabled(true); return true; }