00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "katesmartmanager.h"
00019
00020 #include "katedocument.h"
00021 #include "katesmartcursor.h"
00022 #include "katesmartrange.h"
00023
00024 #include <QThread>
00025 #include <QMutexLocker>
00026
00027 #include <kdebug.h>
00028
00029
00030
00031
00032
00033
00034 static const int s_defaultGroupSize = 40;
00035 static const int s_minimumGroupSize = 20;
00036 static const int s_maximumGroupSize = 60;
00037
00038 using namespace KTextEditor;
00039
00040 static void translate(KateEditInfo* edit, Cursor& ret, SmartCursor::InsertBehavior insertBehavior)
00041 {
00042
00043
00044 if (ret < edit->start())
00045 return;
00046
00047
00048 if (edit->oldRange().overlapsLine(ret.line())) {
00049
00050 if (ret == edit->start()) {
00051
00052 if (insertBehavior == SmartCursor::StayOnInsert)
00053 return;
00054 }
00055
00056
00057 Cursor newPos;
00058 if (edit->oldRange().contains(ret)) {
00059 if (insertBehavior == SmartCursor::MoveOnInsert)
00060 ret = edit->newRange().end();
00061 else
00062 ret = edit->start();
00063
00064 } else {
00065 ret += edit->translate();
00066 }
00067
00068 return;
00069 }
00070
00071
00072 ret.setLine(ret.line() + edit->translate().line());
00073 }
00074
00075 #ifdef DEBUG_TRANSLATION
00076 struct KateSmartManager::KateTranslationDebugger {
00077 KateTranslationDebugger(KateSmartManager* manager, KateEditInfo* edit) : m_manager(manager), m_edit(edit) {
00078 manager->m_currentKateTranslationDebugger = this;
00079 foreach(KateSmartRange* range, manager->m_topRanges)
00080 addRange(range);
00081 }
00082
00083 ~KateTranslationDebugger() {
00084 m_manager->m_currentKateTranslationDebugger = 0;
00085 }
00086
00087 void addRange(SmartRange* _range) {
00088
00089 KateSmartRange* range = dynamic_cast<KateSmartRange*>(_range);
00090 Q_ASSERT(range);
00091
00092 RangeTranslation translation;
00093 translation.from = *range;
00094 KTextEditor::Cursor toStart = range->start();
00095 KTextEditor::Cursor toEnd = range->end();
00096
00097 translate(m_edit, toStart, (range->insertBehavior() & SmartRange::ExpandLeft) ? SmartCursor::StayOnInsert : SmartCursor::MoveOnInsert);
00098 translate(m_edit, toEnd, (range->insertBehavior() & SmartRange::ExpandRight) ? SmartCursor::MoveOnInsert : SmartCursor::StayOnInsert);
00099 translation.to = KTextEditor::Range(toStart, toEnd);
00100
00101 m_rangeTranslations[range] = translation;
00102 m_cursorTranslations[&range->smartStart()] = CursorTranslation(range->start(), toStart);
00103 m_cursorTranslations[&range->smartEnd()] = CursorTranslation(range->end(), toEnd);
00104
00105 foreach(SmartRange* child, range->childRanges())
00106 addRange(child);
00107 }
00108
00109 void verifyAll() {
00110 for(QMap<const SmartRange*, RangeTranslation>::iterator it = m_rangeTranslations.begin(); it != m_rangeTranslations.end(); ++it) {
00111 if(*it.key() != it.value().to) {
00112 kDebug() << "mismatch. Translation should be:" << it.value().to << "translation is:" << *it.key() << "from:" << it.value().from;
00113 kDebug() << "edit:" << m_edit->oldRange() << m_edit->newRange();
00114 Q_ASSERT(0);
00115 }
00116 }
00117 }
00118
00119 void verifyChange(SmartCursor* _cursor) {
00120 if(!m_cursorTranslations.contains(_cursor))
00121 return;
00122 return;
00123 KateSmartCursor* cursor = dynamic_cast<KateSmartCursor*>(_cursor);
00124 Q_ASSERT(cursor);
00125 KTextEditor::Cursor realPos( cursor->m_line + cursor->m_smartGroup->m_newStartLine, cursor->m_column);
00126 kDebug() << "changing cursor from" << m_cursorTranslations[cursor].from << "to" << realPos;
00127
00128 if(m_cursorTranslations[cursor].to != realPos) {
00129 kDebug() << "mismatch. Translation of cursor should be:" << m_cursorTranslations[cursor].to << "is:" << realPos << "from:" << m_cursorTranslations[cursor].from;
00130 kDebug() << "edit:" << m_edit->oldRange() << m_edit->newRange();
00131 Q_ASSERT(0);
00132 }
00133 }
00134
00135 struct RangeTranslation {
00136 KTextEditor::Range from, to;
00137 };
00138
00139 struct CursorTranslation {
00140 CursorTranslation() {
00141 }
00142 CursorTranslation(const KTextEditor::Cursor& _from, const KTextEditor::Cursor& _to) : from(_from), to(_to) {
00143 }
00144 KTextEditor::Cursor from, to;
00145 };
00146
00147 QMap<const SmartRange*, RangeTranslation> m_rangeTranslations;
00148 QMap<const SmartCursor*, CursorTranslation> m_cursorTranslations;
00149 KateSmartManager* m_manager;
00150 KateEditInfo* m_edit;
00151 };
00152 #endif
00153 KateSmartManager::KateSmartManager(KateDocument* parent)
00154 : QObject(parent)
00155 , m_firstGroup(new KateSmartGroup(0, 0, 0L, 0L))
00156 , m_invalidGroup(new KateSmartGroup(-1, -1, 0L, 0L))
00157 , m_clearing(false)
00158 , m_currentKateTranslationDebugger(0)
00159 {
00160 connect(doc()->history(), SIGNAL(editDone(KateEditInfo*)), SLOT(slotTextChanged(KateEditInfo*)));
00161
00162 }
00163
00164 KateSmartManager::~KateSmartManager()
00165 {
00166 clear(true);
00167
00168 KateSmartGroup* smartGroup = m_firstGroup;
00169 while (smartGroup) {
00170 KateSmartGroup* toDelete = smartGroup;
00171 smartGroup = smartGroup->next();
00172 delete toDelete;
00173 }
00174
00175 delete m_invalidGroup;
00176 }
00177
00178 KateDocument * KateSmartManager::doc( ) const
00179 {
00180 return static_cast<KateDocument*>(parent());
00181 }
00182
00183 KateSmartCursor * KateSmartManager::newSmartCursor( const Cursor & position, SmartCursor::InsertBehavior insertBehavior, bool internal )
00184 {
00185 QMutexLocker l(internal ? doc()->smartMutex() : 0);
00186
00187 KateSmartCursor* c;
00188 if (usingRevision() != -1 && !internal)
00189 c = new KateSmartCursor(translateFromRevision(position), doc(), insertBehavior);
00190 else
00191 c = new KateSmartCursor(position, doc(), insertBehavior);
00192
00193 if (internal)
00194 c->setInternal();
00195 return c;
00196 }
00197
00198 KateSmartRange * KateSmartManager::newSmartRange( const Range & range, SmartRange * parent, SmartRange::InsertBehaviors insertBehavior, bool internal )
00199 {
00200 QMutexLocker l(internal ? doc()->smartMutex() : 0);
00201
00202 KateSmartRange* newRange;
00203
00204 if (usingRevision() != -1 && !internal)
00205 newRange = new KateSmartRange(translateFromRevision(range), doc(), parent, insertBehavior);
00206 else
00207 newRange = new KateSmartRange(range, doc(), parent, insertBehavior);
00208
00209 if (internal)
00210 newRange->setInternal();
00211 if (!parent)
00212 rangeLostParent(newRange);
00213 return newRange;
00214 }
00215
00216 KateSmartRange * KateSmartManager::newSmartRange( KateSmartCursor * start, KateSmartCursor * end, SmartRange * parent, SmartRange::InsertBehaviors insertBehavior, bool internal )
00217 {
00218 QMutexLocker l(internal ? doc()->smartMutex() : 0);
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 KateSmartRange* newRange = new KateSmartRange(start, end, parent, insertBehavior);
00229 if (internal)
00230 newRange->setInternal();
00231 if (!parent)
00232 rangeLostParent(newRange);
00233 return newRange;
00234 }
00235
00236 void KateSmartGroup::addCursor( KateSmartCursor * cursor)
00237 {
00238 Q_ASSERT(!m_feedbackCursors.contains(cursor));
00239 Q_ASSERT(!m_normalCursors.contains(cursor));
00240
00241 if (cursor->feedbackEnabled())
00242 m_feedbackCursors.insert(cursor);
00243 else
00244 m_normalCursors.insert(cursor);
00245 }
00246
00247 void KateSmartGroup::changeCursorFeedback( KateSmartCursor * cursor )
00248 {
00249 if (!cursor->feedbackEnabled()) {
00250 Q_ASSERT(!m_feedbackCursors.contains(cursor));
00251 Q_ASSERT(m_normalCursors.contains(cursor));
00252 m_normalCursors.remove(cursor);
00253 m_feedbackCursors.insert(cursor);
00254
00255 } else {
00256 Q_ASSERT(m_feedbackCursors.contains(cursor));
00257 Q_ASSERT(!m_normalCursors.contains(cursor));
00258 m_feedbackCursors.remove(cursor);
00259 m_normalCursors.insert(cursor);
00260 }
00261 }
00262
00263 void KateSmartGroup::removeCursor( KateSmartCursor * cursor)
00264 {
00265 if (cursor->feedbackEnabled()) {
00266 Q_ASSERT(m_feedbackCursors.contains(cursor));
00267 Q_ASSERT(!m_normalCursors.contains(cursor));
00268 m_feedbackCursors.remove(cursor);
00269
00270 } else {
00271 Q_ASSERT(!m_feedbackCursors.contains(cursor));
00272 Q_ASSERT(m_normalCursors.contains(cursor));
00273 m_normalCursors.remove(cursor);
00274 }
00275 }
00276
00277 void KateSmartGroup::joined( KateSmartCursor * cursor )
00278 {
00279 addCursor(cursor);
00280 }
00281
00282 void KateSmartGroup::leaving( KateSmartCursor * cursor )
00283 {
00284 removeCursor(cursor);
00285 }
00286
00287 KateSmartGroup * KateSmartManager::groupForLine( int line ) const
00288 {
00289
00290 if (line == -1)
00291 return m_invalidGroup;
00292
00293
00294 KateSmartGroup* smartGroup = m_firstGroup;
00295 while (smartGroup && !smartGroup->containsLine(line))
00296 smartGroup = smartGroup->next();
00297
00298
00299
00300
00301
00302
00303 Q_ASSERT(smartGroup);
00304 return smartGroup;
00305 }
00306
00307 void KateSmartManager::slotTextChanged(KateEditInfo* edit)
00308 {
00309 QMutexLocker lock(doc()->smartMutex());
00310 #ifdef DEBUG_TRANSLATION
00311 KateTranslationDebugger KateTranslationDebugger(this, edit);
00312 #endif
00313 KateSmartGroup* firstSmartGroup = groupForLine(edit->oldRange().start().line());
00314 KateSmartGroup* currentGroup = firstSmartGroup;
00315
00316
00317 int splitEndLine = edit->translate().line() + firstSmartGroup->endLine();
00318
00319 if (edit->translate().line() > 0) {
00320
00321 KateSmartGroup* endGroup = currentGroup->next();
00322
00323 int currentCanExpand = endGroup ? s_maximumGroupSize - currentGroup->length() : s_defaultGroupSize - currentGroup->length();
00324 int expanded = 0;
00325
00326 if (currentCanExpand) {
00327 int expandBy = qMin(edit->translate().line(), currentCanExpand);
00328
00329 currentGroup->setNewEndLine(currentGroup->endLine() + expandBy);
00330
00331 expanded = expandBy;
00332 }
00333
00334 if (expanded < edit->translate().line()) {
00335
00336 int newStartLine, newEndLine;
00337
00338 do {
00339 newStartLine = currentGroup->newEndLine() + 1;
00340 newEndLine = qMin(newStartLine + s_defaultGroupSize - 1, splitEndLine);
00341 currentGroup = new KateSmartGroup(newStartLine, newEndLine, currentGroup, endGroup);
00342
00343 } while (newEndLine < splitEndLine);
00344 }
00345
00346
00347 } else if (edit->translate().line() < 0) {
00348
00349
00350 while (currentGroup->next() && currentGroup->length() + edit->translate().line() < s_minimumGroupSize)
00351 currentGroup->merge();
00352
00353
00354 currentGroup->setNewEndLine(currentGroup->endLine() + edit->translate().line());
00355 }
00356
00357
00358 if (edit->translate().line())
00359 for (KateSmartGroup* smartGroup = currentGroup->next(); smartGroup; smartGroup = smartGroup->next())
00360 smartGroup->translateShifted(*edit);
00361
00362
00363 for (KateSmartGroup* smartGroup = firstSmartGroup; smartGroup; smartGroup = smartGroup->next()) {
00364 if (smartGroup->startLine() > edit->oldRange().end().line())
00365 break;
00366
00367 smartGroup->translateChanged(*edit);
00368 }
00369
00370
00371 bool groupChanged = true;
00372 for (KateSmartGroup* smartGroup = firstSmartGroup; smartGroup; smartGroup = smartGroup->next()) {
00373 if (groupChanged) {
00374 groupChanged = smartGroup->startLine() <= edit->oldRange().end().line();
00375
00376 if (!groupChanged && !edit->translate().line())
00377 break;
00378 }
00379
00380 if (groupChanged)
00381 smartGroup->translatedChanged(*edit);
00382 else
00383 smartGroup->translatedShifted(*edit);
00384 }
00385
00386
00387 for (KateSmartGroup* smartGroup = firstSmartGroup; smartGroup; smartGroup = smartGroup->next()) {
00388 if (smartGroup->startLine() > edit->oldRange().end().line())
00389 break;
00390
00391 smartGroup->translatedChanged2(*edit);
00392 }
00393
00394 #ifdef DEBUG_TRANSLATION
00395 KateTranslationDebugger.verifyAll();
00396 #endif
00397
00398
00399 foreach (KateSmartRange* range, m_topRanges) {
00400 KateSmartRange* mostSpecific = feedbackRange(*edit, range);
00401
00402 if (!mostSpecific)
00403 mostSpecific = range;
00404 range->feedbackMostSpecific(mostSpecific);
00405 }
00406
00407 #ifdef DEBUG_TRANSLATION
00408 KateTranslationDebugger.verifyAll();
00409 #endif
00410
00411
00412 }
00413
00414 KateSmartRange* KateSmartManager::feedbackRange( const KateEditInfo& edit, KateSmartRange * range )
00415 {
00416 KateSmartRange* mostSpecific = 0L;
00417
00418
00419 if ((range->end() < edit.start() && range->kEnd().lastPosition() < edit.start()) ||
00420 (range->end() == edit.start() && range->kEnd().lastPosition() == edit.start() && !range->isEmpty())
00421 ) {
00422
00423 return mostSpecific;
00424 }
00425
00426 foreach (SmartRange* child, range->childRanges())
00427 if (!mostSpecific)
00428 mostSpecific = feedbackRange(edit, static_cast<KateSmartRange*>(child));
00429 else
00430 feedbackRange(edit, static_cast<KateSmartRange*>(child));
00431
00432
00433
00434 if (range->start() > edit.newRange().end() ||
00435 (range->start() == edit.newRange().end() && range->kStart().lastPosition() == edit.oldRange().end()))
00436 {
00437
00438
00439 range->shifted();
00440
00441 } else {
00442
00443
00444 if (!mostSpecific)
00445 if (range->start() < edit.oldRange().start() && range->end() > edit.oldRange().end())
00446 mostSpecific = range;
00447
00448 range->translated(edit);
00449 }
00450
00451 return mostSpecific;
00452 }
00453
00454
00455 void KateSmartGroup::translateChanged( const KateEditInfo& edit)
00456 {
00457
00458
00459 foreach (KateSmartCursor* cursor, m_feedbackCursors)
00460 cursor->translate(edit);
00461
00462 foreach (KateSmartCursor* cursor, m_normalCursors)
00463 cursor->translate(edit);
00464 }
00465
00466 void KateSmartGroup::translateShifted(const KateEditInfo& edit)
00467 {
00468 m_newStartLine = m_startLine + edit.translate().line();
00469 m_newEndLine = m_endLine + edit.translate().line();
00470
00471 }
00472
00473 void KateSmartGroup::translatedChanged(const KateEditInfo& edit)
00474 {
00475 m_startLine = m_newStartLine;
00476 m_endLine = m_newEndLine;
00477
00478 foreach (KateSmartCursor* cursor, m_feedbackCursors)
00479 cursor->translated(edit);
00480 }
00481
00482 void KateSmartGroup::translatedChanged2(const KateEditInfo& edit)
00483 {
00484
00485 QSet<KTextEditor::SmartRange*> rebuilt;
00486
00487 foreach (KateSmartCursor* cursor, m_normalCursors + m_feedbackCursors) {
00488 KTextEditor::SmartRange* range = cursor->smartRange();
00489 if(range) {
00490 KTextEditor::SmartRange* parent = range->parentRange();
00491 if(parent && !rebuilt.contains(parent)) {
00492 rebuilt.insert(parent);
00493 KateSmartRange* kateSmart = dynamic_cast<KateSmartRange*>(parent);
00494 Q_ASSERT(kateSmart);
00495 kateSmart->rebuildChildStructure();
00496 }
00497 }
00498 }
00499 }
00500
00501 void KateSmartGroup::translatedShifted(const KateEditInfo& edit)
00502 {
00503 if (m_startLine != m_newStartLine) {
00504 m_startLine = m_newStartLine;
00505 m_endLine = m_newEndLine;
00506 }
00507
00508 if (edit.translate().line() == 0)
00509 return;
00510
00511
00512 foreach (KateSmartCursor* cursor, m_feedbackCursors)
00513 cursor->shifted();
00514 }
00515
00516 KateSmartGroup::KateSmartGroup( int startLine, int endLine, KateSmartGroup * previous, KateSmartGroup * next )
00517 : m_startLine(startLine)
00518 , m_newStartLine(startLine)
00519 , m_endLine(endLine)
00520 , m_newEndLine(endLine)
00521 , m_next(next)
00522 , m_previous(previous)
00523 {
00524 if (m_previous)
00525 m_previous->setNext(this);
00526
00527 if (m_next)
00528 m_next->setPrevious(this);
00529 }
00530
00531 void KateSmartGroup::merge( )
00532 {
00533 Q_ASSERT(m_next);
00534
00535 foreach (KateSmartCursor* cursor, next()->feedbackCursors())
00536 cursor->migrate(this);
00537 m_feedbackCursors += next()->feedbackCursors();
00538
00539 foreach (KateSmartCursor* cursor, next()->normalCursors())
00540 cursor->migrate(this);
00541 m_normalCursors += next()->normalCursors();
00542
00543 m_newEndLine = m_endLine = next()->endLine();
00544 KateSmartGroup* newNext = next()->next();
00545 delete m_next;
00546 m_next = newNext;
00547 if (m_next)
00548 m_next->setPrevious(this);
00549 }
00550
00551 const QSet< KateSmartCursor * > & KateSmartGroup::feedbackCursors( ) const
00552 {
00553 return m_feedbackCursors;
00554 }
00555
00556 const QSet< KateSmartCursor * > & KateSmartGroup::normalCursors( ) const
00557 {
00558 return m_normalCursors;
00559 }
00560
00561 void KateSmartManager::debugOutput( ) const
00562 {
00563 int groupCount = 1;
00564 KateSmartGroup* currentGroup = m_firstGroup;
00565 while (currentGroup->next()) {
00566 ++groupCount;
00567 currentGroup = currentGroup->next();
00568 }
00569
00570 kDebug() << "KateSmartManager: SmartGroups " << groupCount << " from " << m_firstGroup->startLine() << " to " << currentGroup->endLine();
00571
00572 currentGroup = m_firstGroup;
00573 while (currentGroup) {
00574 currentGroup->debugOutput();
00575 currentGroup = currentGroup->next();
00576 }
00577 }
00578
00579 void KateSmartGroup::debugOutput( ) const
00580 {
00581 kDebug() << " -> KateSmartGroup: from " << startLine() << " to " << endLine() << "; Cursors " << m_normalCursors.count() + m_feedbackCursors.count() << " (" << m_feedbackCursors.count() << " feedback)";
00582 }
00583
00584 void KateSmartManager::verifyCorrect() const
00585 {
00586 KateSmartGroup* currentGroup = groupForLine(0);
00587 Q_ASSERT(currentGroup);
00588 Q_ASSERT(currentGroup == m_firstGroup);
00589
00590 forever {
00591 if (!currentGroup->previous())
00592 Q_ASSERT(currentGroup->startLine() == 0);
00593
00594 foreach (KateSmartCursor* cursor, currentGroup->feedbackCursors()) {
00595 Q_ASSERT(currentGroup->containsLine(cursor->line()));
00596 Q_ASSERT(cursor->smartGroup() == currentGroup);
00597 }
00598
00599 if (!currentGroup->next())
00600 break;
00601
00602 Q_ASSERT(currentGroup->endLine() == currentGroup->next()->startLine() - 1);
00603 Q_ASSERT(currentGroup->next()->previous() == currentGroup);
00604
00605 currentGroup = currentGroup->next();
00606 }
00607
00608 Q_ASSERT(currentGroup->endLine() == doc()->lines() - 1);
00609
00610 kDebug() << "Verified correct." << currentGroup->endLine() << doc()->lines() - 1;
00611 }
00612
00613 void KateSmartManager::rangeGotParent( KateSmartRange * range )
00614 {
00615 Q_ASSERT(m_topRanges.contains(range));
00616 m_topRanges.remove(range);
00617 }
00618
00619 void KateSmartManager::rangeLostParent( KateSmartRange * range )
00620 {
00621 Q_ASSERT(!m_topRanges.contains(range));
00622 m_topRanges.insert(range);
00623 }
00624
00625 void KateSmartManager::rangeDeleted( KateSmartRange* range )
00626 {
00627 emit signalRangeDeleted(range);
00628
00629 if (!range->parentRange())
00630 m_topRanges.remove(range);
00631 }
00632
00633 void KateSmartManager::unbindSmartRange( SmartRange * range )
00634 {
00635 static_cast<KateSmartRange*>(range)->unbindAndDelete();
00636 }
00637
00638 void KateSmartManager::deleteCursors(bool includingInternal)
00639 {
00640 m_invalidGroup->deleteCursors(includingInternal);
00641 for (KateSmartGroup* g = m_firstGroup; g; g = g->next())
00642 g->deleteCursors(includingInternal);
00643 }
00644
00645 void KateSmartGroup::deleteCursors( bool includingInternal )
00646 {
00647 if (includingInternal) {
00648 qDeleteAll(m_feedbackCursors);
00649 m_feedbackCursors.clear();
00650
00651 qDeleteAll(m_normalCursors);
00652 m_normalCursors.clear();
00653
00654 } else {
00655 deleteCursorsInternal(m_feedbackCursors);
00656 deleteCursorsInternal(m_normalCursors);
00657 }
00658 }
00659
00660 void KateSmartGroup::deleteCursorsInternal( QSet< KateSmartCursor * > & set )
00661 {
00662 foreach (KateSmartCursor* c, set.toList()) {
00663 if (!c->range() && !c->isInternal()) {
00664 set.remove(c);
00665 delete c;
00666 }
00667 }
00668 }
00669
00670 void KateSmartManager::deleteRanges( bool includingInternal )
00671 {
00672 foreach (KateSmartRange* range, m_topRanges.toList()) {
00673 if (includingInternal || !range->isInternal()) {
00674 range->deleteChildRanges();
00675 delete range;
00676
00677 if (!includingInternal)
00678 m_topRanges.remove(range);
00679 }
00680 }
00681
00682 if (includingInternal)
00683 m_topRanges.clear();
00684 }
00685
00686 void KateSmartManager::clear( bool includingInternal )
00687 {
00688 deleteRanges(includingInternal);
00689
00690 m_clearing = true;
00691 deleteCursors(includingInternal);
00692 m_clearing = false;
00693 }
00694
00695 void KateSmartManager::useRevision(int revision)
00696 {
00697 if (!m_usingRevision.hasLocalData())
00698 m_usingRevision.setLocalData(new int);
00699
00700 *m_usingRevision.localData() = revision;
00701 }
00702
00703 int KateSmartManager::usingRevision() const
00704 {
00705 if (m_usingRevision.hasLocalData())
00706 return *m_usingRevision.localData();
00707
00708 return -1;
00709 }
00710
00711 void KateSmartManager::releaseRevision(int revision) const
00712 {
00713 doc()->history()->releaseRevision(revision);
00714 }
00715
00716 int KateSmartManager::currentRevision() const
00717 {
00718 return doc()->history()->revision();
00719 }
00720
00721 Cursor KateSmartManager::translateFromRevision(const Cursor& cursor, SmartCursor::InsertBehavior insertBehavior) const
00722 {
00723 Cursor ret = cursor;
00724
00725 foreach (KateEditInfo* edit, doc()->history()->editsBetweenRevisions(usingRevision()))
00726 translate(edit, ret, insertBehavior);
00727
00728 return ret;
00729 }
00730
00731 Range KateSmartManager::translateFromRevision(const Range& range, KTextEditor::SmartRange::InsertBehaviors insertBehavior) const
00732 {
00733 Cursor start = range.start(), end = range.end();
00734
00735 foreach (KateEditInfo* edit, doc()->history()->editsBetweenRevisions(usingRevision())) {
00736 translate(edit, start, insertBehavior & KTextEditor::SmartRange::ExpandLeft ? SmartCursor::StayOnInsert : SmartCursor::MoveOnInsert);
00737 translate(edit, end, insertBehavior & KTextEditor::SmartRange::ExpandRight ? SmartCursor::MoveOnInsert : SmartCursor::StayOnInsert);
00738 }
00739
00740 return Range(start, end);
00741 }
00742
00743 #include "katesmartmanager.moc"