Changeset View
Changeset View
Standalone View
Standalone View
src/document/katedocument.cpp
Show First 20 Lines • Show All 289 Lines • ▼ Show 20 Line(s) | 214 | { | |||
---|---|---|---|---|---|
290 | connect(m_undoManager, SIGNAL(undoChanged()), this, SIGNAL(undoChanged())); | 290 | connect(m_undoManager, SIGNAL(undoChanged()), this, SIGNAL(undoChanged())); | ||
291 | connect(m_undoManager, SIGNAL(undoStart(KTextEditor::Document*)), this, SIGNAL(editingStarted(KTextEditor::Document*))); | 291 | connect(m_undoManager, SIGNAL(undoStart(KTextEditor::Document*)), this, SIGNAL(editingStarted(KTextEditor::Document*))); | ||
292 | connect(m_undoManager, SIGNAL(undoEnd(KTextEditor::Document*)), this, SIGNAL(editingFinished(KTextEditor::Document*))); | 292 | connect(m_undoManager, SIGNAL(undoEnd(KTextEditor::Document*)), this, SIGNAL(editingFinished(KTextEditor::Document*))); | ||
293 | connect(m_undoManager, SIGNAL(redoStart(KTextEditor::Document*)), this, SIGNAL(editingStarted(KTextEditor::Document*))); | 293 | connect(m_undoManager, SIGNAL(redoStart(KTextEditor::Document*)), this, SIGNAL(editingStarted(KTextEditor::Document*))); | ||
294 | connect(m_undoManager, SIGNAL(redoEnd(KTextEditor::Document*)), this, SIGNAL(editingFinished(KTextEditor::Document*))); | 294 | connect(m_undoManager, SIGNAL(redoEnd(KTextEditor::Document*)), this, SIGNAL(editingFinished(KTextEditor::Document*))); | ||
295 | 295 | | |||
296 | connect(this, SIGNAL(sigQueryClose(bool*,bool*)), this, SLOT(slotQueryClose_save(bool*,bool*))); | 296 | connect(this, SIGNAL(sigQueryClose(bool*,bool*)), this, SLOT(slotQueryClose_save(bool*,bool*))); | ||
297 | 297 | | |||
298 | connect(this, &KTextEditor::DocumentPrivate::textRemoved, this, &KTextEditor::DocumentPrivate::saveEditingPositions); | | |||
299 | connect(this, &KTextEditor::DocumentPrivate::textInserted, this, &KTextEditor::DocumentPrivate::saveEditingPositions); | | |||
300 | connect(this, SIGNAL(aboutToInvalidateMovingInterfaceContent(KTextEditor::Document*)), this, SLOT(clearEditingPosStack())); | 298 | connect(this, SIGNAL(aboutToInvalidateMovingInterfaceContent(KTextEditor::Document*)), this, SLOT(clearEditingPosStack())); | ||
301 | onTheFlySpellCheckingEnabled(config()->onTheFlySpellCheck()); | 299 | onTheFlySpellCheckingEnabled(config()->onTheFlySpellCheck()); | ||
302 | } | 300 | } | ||
303 | 301 | | |||
304 | // | 302 | // | ||
305 | // KTextEditor::DocumentPrivate Destructor | 303 | // KTextEditor::DocumentPrivate Destructor | ||
306 | // | 304 | // | ||
307 | KTextEditor::DocumentPrivate::~DocumentPrivate() | 305 | KTextEditor::DocumentPrivate::~DocumentPrivate() | ||
Show All 34 Lines | 306 | { | |||
342 | } | 340 | } | ||
343 | m_marks.clear(); | 341 | m_marks.clear(); | ||
344 | 342 | | |||
345 | delete m_config; | 343 | delete m_config; | ||
346 | KTextEditor::EditorPrivate::self()->deregisterDocument(this); | 344 | KTextEditor::EditorPrivate::self()->deregisterDocument(this); | ||
347 | } | 345 | } | ||
348 | //END | 346 | //END | ||
349 | 347 | | |||
350 | void KTextEditor::DocumentPrivate::saveEditingPositions(KTextEditor::Document *, const KTextEditor::Range &range) | 348 | void KTextEditor::DocumentPrivate::saveEditingPositions(const KTextEditor::Cursor &cursor) | ||
351 | { | 349 | { | ||
352 | if (m_editingStackPosition != m_editingStack.size() - 1) { | 350 | if (m_editingStackPosition != m_editingStack.size() - 1) { | ||
353 | m_editingStack.resize(m_editingStackPosition); | 351 | m_editingStack.resize(m_editingStackPosition); | ||
354 | } | 352 | } | ||
355 | KTextEditor::MovingInterface *moving = qobject_cast<KTextEditor::MovingInterface *>(this); | 353 | | ||
356 | const auto c = range.start(); | 354 | // try to be clever: reuse existing cursors if possible | ||
357 | QSharedPointer<KTextEditor::MovingCursor> mc (moving->newMovingCursor(c)); | 355 | QSharedPointer<KTextEditor::MovingCursor> mc; | ||
358 | if (!m_editingStack.isEmpty() && c.line() == m_editingStack.top()->line()) { | 356 | | ||
359 | m_editingStack.pop(); | 357 | // we might pop last one: reuse that | ||
358 | if (!m_editingStack.isEmpty() && cursor.line() == m_editingStack.top()->line()) { | ||||
359 | mc = m_editingStack.pop(); | ||||
360 | } | 360 | } | ||
361 | m_editingStack.push(mc); | 361 | | ||
362 | if (m_editingStack.size() > s_editingStackSizeLimit) { | 362 | // we might expire oldest one, reuse that one, if not already one there | ||
363 | // we prefer the other one for reuse, as already on the right line aka in the right block! | ||||
364 | const int editingStackSizeLimit = 32; | ||||
365 | if (m_editingStack.size() >= editingStackSizeLimit) { | ||||
366 | if (mc) { | ||||
363 | m_editingStack.removeFirst(); | 367 | m_editingStack.removeFirst(); | ||
368 | } else { | ||||
369 | mc = m_editingStack.takeFirst(); | ||||
370 | } | ||||
371 | } | ||||
372 | | ||||
373 | // new cursor needed? or adjust existing one? | ||||
374 | if (mc) { | ||||
375 | mc->setPosition(cursor); | ||||
376 | } else { | ||||
377 | mc = QSharedPointer<KTextEditor::MovingCursor> (newMovingCursor(cursor)); | ||||
364 | } | 378 | } | ||
379 | | ||||
380 | // add new one as top of stack | ||||
381 | m_editingStack.push(mc); | ||||
365 | m_editingStackPosition = m_editingStack.size() - 1; | 382 | m_editingStackPosition = m_editingStack.size() - 1; | ||
366 | } | 383 | } | ||
367 | 384 | | |||
368 | KTextEditor::Cursor KTextEditor::DocumentPrivate::lastEditingPosition(EditingPositionKind nextOrPrev, KTextEditor::Cursor currentCursor) | 385 | KTextEditor::Cursor KTextEditor::DocumentPrivate::lastEditingPosition(EditingPositionKind nextOrPrev, KTextEditor::Cursor currentCursor) | ||
369 | { | 386 | { | ||
370 | if (m_editingStack.isEmpty()) { | 387 | if (m_editingStack.isEmpty()) { | ||
371 | return KTextEditor::Cursor::invalid(); | 388 | return KTextEditor::Cursor::invalid(); | ||
372 | } | 389 | } | ||
▲ Show 20 Lines • Show All 350 Lines • ▼ Show 20 Line(s) | 723 | { | |||
723 | if (position.line() > lines()) { | 740 | if (position.line() > lines()) { | ||
724 | int line = lines(); | 741 | int line = lines(); | ||
725 | while (line <= position.line()) { | 742 | while (line <= position.line()) { | ||
726 | editInsertLine(line, QString()); | 743 | editInsertLine(line, QString()); | ||
727 | line++; | 744 | line++; | ||
728 | } | 745 | } | ||
729 | } | 746 | } | ||
730 | 747 | | |||
748 | // compute expanded column for block mode | ||||
749 | int positionColumnExpanded = insertColumn; | ||||
731 | const int tabWidth = config()->tabWidth(); | 750 | const int tabWidth = config()->tabWidth(); | ||
732 | 751 | if (block) { | |||
733 | static const QChar newLineChar(QLatin1Char('\n')); | 752 | if (auto l = plainKateTextLine(currentLine)) { | ||
734 | 753 | positionColumnExpanded = l->toVirtualColumn(insertColumn, tabWidth); | |||
735 | int insertColumnExpanded = insertColumn; | 754 | } | ||
736 | Kate::TextLine l = plainKateTextLine(currentLine); | | |||
737 | if (l) { | | |||
738 | insertColumnExpanded = l->toVirtualColumn(insertColumn, tabWidth); | | |||
739 | } | 755 | } | ||
740 | int positionColumnExpanded = insertColumnExpanded; | | |||
741 | 756 | | |||
742 | int pos = 0; | 757 | int pos = 0; | ||
743 | for (; pos < totalLength; pos++) { | 758 | for (; pos < totalLength; pos++) { | ||
744 | const QChar &ch = text.at(pos); | 759 | const QChar &ch = text.at(pos); | ||
745 | 760 | | |||
746 | if (ch == newLineChar) { | 761 | if (ch == QLatin1Char('\n')) { | ||
747 | // Only perform the text insert if there is text to insert | 762 | // Only perform the text insert if there is text to insert | ||
748 | if (currentLineStart < pos) { | 763 | if (currentLineStart < pos) { | ||
749 | editInsertText(currentLine, insertColumn, text.mid(currentLineStart, pos - currentLineStart)); | 764 | editInsertText(currentLine, insertColumn, text.mid(currentLineStart, pos - currentLineStart)); | ||
750 | } | 765 | } | ||
751 | 766 | | |||
752 | if (!block) { | 767 | if (!block) { | ||
753 | editWrapLine(currentLine, insertColumn + pos - currentLineStart); | 768 | editWrapLine(currentLine, insertColumn + pos - currentLineStart); | ||
754 | insertColumn = 0; | 769 | insertColumn = 0; | ||
755 | } | 770 | } | ||
756 | 771 | | |||
757 | currentLine++; | 772 | currentLine++; | ||
758 | l = plainKateTextLine(currentLine); | | |||
759 | 773 | | |||
760 | if (block) { | 774 | if (block) { | ||
775 | auto l = plainKateTextLine(currentLine); | ||||
761 | if (currentLine == lastLine() + 1) { | 776 | if (currentLine == lastLine() + 1) { | ||
762 | editInsertLine(currentLine, QString()); | 777 | editInsertLine(currentLine, QString()); | ||
763 | } | 778 | } | ||
764 | insertColumn = positionColumnExpanded; | 779 | insertColumn = positionColumnExpanded; | ||
765 | if (l) { | 780 | if (l) { | ||
766 | insertColumn = l->fromVirtualColumn(insertColumn, tabWidth); | 781 | insertColumn = l->fromVirtualColumn(insertColumn, tabWidth); | ||
767 | } | 782 | } | ||
768 | } | 783 | } | ||
769 | 784 | | |||
770 | currentLineStart = pos + 1; | 785 | currentLineStart = pos + 1; | ||
771 | if (l) { | | |||
772 | insertColumnExpanded = l->toVirtualColumn(insertColumn, tabWidth); | | |||
773 | } | | |||
774 | } | 786 | } | ||
775 | } | 787 | } | ||
776 | 788 | | |||
777 | // Only perform the text insert if there is text to insert | 789 | // Only perform the text insert if there is text to insert | ||
778 | if (currentLineStart < pos) { | 790 | if (currentLineStart < pos) { | ||
779 | editInsertText(currentLine, insertColumn, text.mid(currentLineStart, pos - currentLineStart)); | 791 | editInsertText(currentLine, insertColumn, text.mid(currentLineStart, pos - currentLineStart)); | ||
780 | } | 792 | } | ||
781 | 793 | | |||
▲ Show 20 Lines • Show All 203 Lines • ▼ Show 20 Line(s) | 996 | { | |||
985 | editSessionNumber++; | 997 | editSessionNumber++; | ||
986 | 998 | | |||
987 | if (editSessionNumber > 1) { | 999 | if (editSessionNumber > 1) { | ||
988 | return false; | 1000 | return false; | ||
989 | } | 1001 | } | ||
990 | 1002 | | |||
991 | editIsRunning = true; | 1003 | editIsRunning = true; | ||
992 | 1004 | | |||
1005 | // no last change cursor at start | ||||
1006 | m_editLastChangeStartCursor = KTextEditor::Cursor::invalid(); | ||||
1007 | | ||||
993 | m_undoManager->editStart(); | 1008 | m_undoManager->editStart(); | ||
994 | 1009 | | |||
995 | foreach (KTextEditor::ViewPrivate *view, m_views) { | 1010 | foreach (KTextEditor::ViewPrivate *view, m_views) { | ||
996 | view->editStart(); | 1011 | view->editStart(); | ||
997 | } | 1012 | } | ||
998 | 1013 | | |||
999 | m_buffer->editStart(); | 1014 | m_buffer->editStart(); | ||
1000 | return true; | 1015 | return true; | ||
Show All 32 Lines | 1047 | foreach (KTextEditor::ViewPrivate *view, m_views) { | |||
1033 | view->editEnd(m_buffer->editTagStart(), m_buffer->editTagEnd(), m_buffer->editTagFrom()); | 1048 | view->editEnd(m_buffer->editTagStart(), m_buffer->editTagEnd(), m_buffer->editTagFrom()); | ||
1034 | } | 1049 | } | ||
1035 | 1050 | | |||
1036 | if (m_buffer->editChanged()) { | 1051 | if (m_buffer->editChanged()) { | ||
1037 | setModified(true); | 1052 | setModified(true); | ||
1038 | emit textChanged(this); | 1053 | emit textChanged(this); | ||
1039 | } | 1054 | } | ||
1040 | 1055 | | |||
1056 | // remember last change position in the stack, if any | ||||
1057 | // this avoid costly updates for longer editing transactions | ||||
1058 | // before we did that on textInsert/Removed | ||||
1059 | if (m_editLastChangeStartCursor.isValid()) | ||||
1060 | saveEditingPositions(m_editLastChangeStartCursor); | ||||
1061 | | ||||
1041 | editIsRunning = false; | 1062 | editIsRunning = false; | ||
1042 | return true; | 1063 | return true; | ||
1043 | } | 1064 | } | ||
1044 | 1065 | | |||
1045 | void KTextEditor::DocumentPrivate::pushEditState() | 1066 | void KTextEditor::DocumentPrivate::pushEditState() | ||
1046 | { | 1067 | { | ||
1047 | editStateStack.push(editSessionNumber); | 1068 | editStateStack.push(editSessionNumber); | ||
1048 | } | 1069 | } | ||
▲ Show 20 Lines • Show All 174 Lines • ▼ Show 20 Line(s) | 1218 | { | |||
1223 | int col2 = col; | 1244 | int col2 = col; | ||
1224 | if (col2 > l->length()) { | 1245 | if (col2 > l->length()) { | ||
1225 | s2 = QString(col2 - l->length(), QLatin1Char(' ')) + s; | 1246 | s2 = QString(col2 - l->length(), QLatin1Char(' ')) + s; | ||
1226 | col2 = l->length(); | 1247 | col2 = l->length(); | ||
1227 | } | 1248 | } | ||
1228 | 1249 | | |||
1229 | m_undoManager->slotTextInserted(line, col2, s2); | 1250 | m_undoManager->slotTextInserted(line, col2, s2); | ||
1230 | 1251 | | |||
1252 | // remember last change cursor | ||||
1253 | m_editLastChangeStartCursor = KTextEditor::Cursor(line, col2); | ||||
1254 | | ||||
1231 | // insert text into line | 1255 | // insert text into line | ||
1232 | m_buffer->insertText(KTextEditor::Cursor(line, col2), s2); | 1256 | m_buffer->insertText(m_editLastChangeStartCursor, s2); | ||
1233 | 1257 | | |||
1234 | emit textInserted(this, KTextEditor::Range(line, col2, line, col2 + s2.length())); | 1258 | emit textInserted(this, KTextEditor::Range(line, col2, line, col2 + s2.length())); | ||
1235 | 1259 | | |||
1236 | editEnd(); | 1260 | editEnd(); | ||
1237 | 1261 | | |||
1238 | return true; | 1262 | return true; | ||
1239 | } | 1263 | } | ||
1240 | 1264 | | |||
Show All 30 Lines | 1266 | { | |||
1271 | len = qMin(len, l->text().size() - col); | 1295 | len = qMin(len, l->text().size() - col); | ||
1272 | 1296 | | |||
1273 | editStart(); | 1297 | editStart(); | ||
1274 | 1298 | | |||
1275 | QString oldText = l->string().mid(col, len); | 1299 | QString oldText = l->string().mid(col, len); | ||
1276 | 1300 | | |||
1277 | m_undoManager->slotTextRemoved(line, col, oldText); | 1301 | m_undoManager->slotTextRemoved(line, col, oldText); | ||
1278 | 1302 | | |||
1303 | // remember last change cursor | ||||
1304 | m_editLastChangeStartCursor = KTextEditor::Cursor(line, col); | ||||
1305 | | ||||
1279 | // remove text from line | 1306 | // remove text from line | ||
1280 | m_buffer->removeText(KTextEditor::Range(KTextEditor::Cursor(line, col), KTextEditor::Cursor(line, col + len))); | 1307 | m_buffer->removeText(KTextEditor::Range(m_editLastChangeStartCursor, KTextEditor::Cursor(line, col + len))); | ||
1281 | 1308 | | |||
1282 | emit textRemoved(this, KTextEditor::Range(line, col, line, col + len), oldText); | 1309 | emit textRemoved(this, KTextEditor::Range(line, col, line, col + len), oldText); | ||
1283 | 1310 | | |||
1284 | editEnd(); | 1311 | editEnd(); | ||
1285 | 1312 | | |||
1286 | return true; | 1313 | return true; | ||
1287 | } | 1314 | } | ||
1288 | 1315 | | |||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Line(s) | 1401 | } else { | |||
1376 | m_buffer->unwrapLine(line + 2); | 1403 | m_buffer->unwrapLine(line + 2); | ||
1377 | 1404 | | |||
1378 | // no, no new line added ! | 1405 | // no, no new line added ! | ||
1379 | if (newLineAdded) { | 1406 | if (newLineAdded) { | ||
1380 | (*newLineAdded) = false; | 1407 | (*newLineAdded) = false; | ||
1381 | } | 1408 | } | ||
1382 | } | 1409 | } | ||
1383 | 1410 | | |||
1411 | // remember last change cursor | ||||
1412 | m_editLastChangeStartCursor = KTextEditor::Cursor(line, col); | ||||
1413 | | ||||
1384 | emit textInserted(this, KTextEditor::Range(line, col, line + 1, 0)); | 1414 | emit textInserted(this, KTextEditor::Range(line, col, line + 1, 0)); | ||
1385 | 1415 | | |||
1386 | editEnd(); | 1416 | editEnd(); | ||
1387 | 1417 | | |||
1388 | return true; | 1418 | return true; | ||
1389 | } | 1419 | } | ||
1390 | 1420 | | |||
1391 | bool KTextEditor::DocumentPrivate::editUnWrapLine(int line, bool removeLine, int length) | 1421 | bool KTextEditor::DocumentPrivate::editUnWrapLine(int line, bool removeLine, int length) | ||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Line(s) | 1473 | for (int i = 0; i < list.size(); ++i) { | |||
1444 | list.at(i)->line--; | 1474 | list.at(i)->line--; | ||
1445 | m_marks.insert(list.at(i)->line, list.at(i)); | 1475 | m_marks.insert(list.at(i)->line, list.at(i)); | ||
1446 | } | 1476 | } | ||
1447 | 1477 | | |||
1448 | if (!list.isEmpty()) { | 1478 | if (!list.isEmpty()) { | ||
1449 | emit marksChanged(this); | 1479 | emit marksChanged(this); | ||
1450 | } | 1480 | } | ||
1451 | 1481 | | |||
1482 | // remember last change cursor | ||||
1483 | m_editLastChangeStartCursor = KTextEditor::Cursor(line, col); | ||||
1484 | | ||||
1452 | emit textRemoved(this, KTextEditor::Range(line, col, line + 1, 0), QStringLiteral("\n")); | 1485 | emit textRemoved(this, KTextEditor::Range(line, col, line + 1, 0), QStringLiteral("\n")); | ||
1453 | 1486 | | |||
1454 | editEnd(); | 1487 | editEnd(); | ||
1455 | 1488 | | |||
1456 | return true; | 1489 | return true; | ||
1457 | } | 1490 | } | ||
1458 | 1491 | | |||
1459 | bool KTextEditor::DocumentPrivate::editInsertLine(int line, const QString &s) | 1492 | bool KTextEditor::DocumentPrivate::editInsertLine(int line, const QString &s) | ||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Line(s) | 1493 | { | |||
1514 | 1547 | | |||
1515 | if (line) { | 1548 | if (line) { | ||
1516 | Kate::TextLine prevLine = plainKateTextLine(line - 1); | 1549 | Kate::TextLine prevLine = plainKateTextLine(line - 1); | ||
1517 | rangeInserted.setStart(KTextEditor::Cursor(line - 1, prevLine->length())); | 1550 | rangeInserted.setStart(KTextEditor::Cursor(line - 1, prevLine->length())); | ||
1518 | } else { | 1551 | } else { | ||
1519 | rangeInserted.setEnd(KTextEditor::Cursor(line + 1, 0)); | 1552 | rangeInserted.setEnd(KTextEditor::Cursor(line + 1, 0)); | ||
1520 | } | 1553 | } | ||
1521 | 1554 | | |||
1555 | // remember last change cursor | ||||
1556 | m_editLastChangeStartCursor = rangeInserted.start(); | ||||
1557 | | ||||
1522 | emit textInserted(this, rangeInserted); | 1558 | emit textInserted(this, rangeInserted); | ||
1523 | 1559 | | |||
1524 | editEnd(); | 1560 | editEnd(); | ||
1525 | 1561 | | |||
1526 | return true; | 1562 | return true; | ||
1527 | } | 1563 | } | ||
1528 | 1564 | | |||
1529 | bool KTextEditor::DocumentPrivate::editRemoveLine(int line) | 1565 | bool KTextEditor::DocumentPrivate::editRemoveLine(int line) | ||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Line(s) | 1571 | { | |||
1607 | if (to == lastLine() + to - from + 1) { | 1643 | if (to == lastLine() + to - from + 1) { | ||
1608 | rangeRemoved.setEnd(KTextEditor::Cursor(to, oldText.last().length())); | 1644 | rangeRemoved.setEnd(KTextEditor::Cursor(to, oldText.last().length())); | ||
1609 | if (from > 0) { | 1645 | if (from > 0) { | ||
1610 | Kate::TextLine prevLine = plainKateTextLine(from - 1); | 1646 | Kate::TextLine prevLine = plainKateTextLine(from - 1); | ||
1611 | rangeRemoved.setStart(KTextEditor::Cursor(from - 1, prevLine->length())); | 1647 | rangeRemoved.setStart(KTextEditor::Cursor(from - 1, prevLine->length())); | ||
1612 | } | 1648 | } | ||
1613 | } | 1649 | } | ||
1614 | 1650 | | |||
1651 | // remember last change cursor | ||||
1652 | m_editLastChangeStartCursor = rangeRemoved.start(); | ||||
1653 | | ||||
1615 | emit textRemoved(this, rangeRemoved, oldText.join(QStringLiteral("\n")) + QLatin1Char('\n')); | 1654 | emit textRemoved(this, rangeRemoved, oldText.join(QStringLiteral("\n")) + QLatin1Char('\n')); | ||
1616 | 1655 | | |||
1617 | editEnd(); | 1656 | editEnd(); | ||
1618 | 1657 | | |||
1619 | return true; | 1658 | return true; | ||
1620 | } | 1659 | } | ||
1621 | //END | 1660 | //END | ||
1622 | 1661 | | |||
▲ Show 20 Lines • Show All 4359 Lines • Show Last 20 Lines |