00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "katesupercursor.h"
00020 #include "katesupercursor.moc"
00021
00022 #include "katedocument.h"
00023
00024 #include <kdebug.h>
00025
00026 #include <qobjectlist.h>
00027
00028 KateSuperCursor::KateSuperCursor(KateDocument* doc, bool privateC, const KateTextCursor& cursor, QObject* parent, const char* name)
00029 : QObject(parent, name)
00030 , KateDocCursor(cursor.line(), cursor.col(), doc)
00031 , Kate::Cursor ()
00032 , m_doc (doc)
00033 {
00034 m_moveOnInsert = false;
00035 m_lineRemoved = false;
00036 m_privateCursor = privateC;
00037
00038 m_doc->addSuperCursor (this, privateC);
00039 }
00040
00041 KateSuperCursor::KateSuperCursor(KateDocument* doc, bool privateC, int lineNum, int col, QObject* parent, const char* name)
00042 : QObject(parent, name)
00043 , KateDocCursor(lineNum, col, doc)
00044 , Kate::Cursor ()
00045 , m_doc (doc)
00046 {
00047 m_moveOnInsert = false;
00048 m_lineRemoved = false;
00049 m_privateCursor = privateC;
00050
00051 m_doc->addSuperCursor (this, privateC);
00052 }
00053
00054 KateSuperCursor::~KateSuperCursor ()
00055 {
00056 m_doc->removeSuperCursor (this, m_privateCursor);
00057 }
00058
00059 void KateSuperCursor::position(uint *pline, uint *pcol) const
00060 {
00061 KateDocCursor::position(pline, pcol);
00062 }
00063
00064 bool KateSuperCursor::setPosition(uint line, uint col)
00065 {
00066 if (line == uint(-2) && col == uint(-2)) { delete this; return true; }
00067 return KateDocCursor::setPosition(line, col);
00068 }
00069
00070 bool KateSuperCursor::insertText(const QString& s)
00071 {
00072 return KateDocCursor::insertText(s);
00073 }
00074
00075 bool KateSuperCursor::removeText(uint nbChar)
00076 {
00077 return KateDocCursor::removeText(nbChar);
00078 }
00079
00080 QChar KateSuperCursor::currentChar() const
00081 {
00082 return KateDocCursor::currentChar();
00083 }
00084
00085 bool KateSuperCursor::atStartOfLine() const
00086 {
00087 return col() == 0;
00088 }
00089
00090 bool KateSuperCursor::atEndOfLine() const
00091 {
00092 return col() >= (int)m_doc->kateTextLine(line())->length();
00093 }
00094
00095 bool KateSuperCursor::moveOnInsert() const
00096 {
00097 return m_moveOnInsert;
00098 }
00099
00100 void KateSuperCursor::setMoveOnInsert(bool moveOnInsert)
00101 {
00102 m_moveOnInsert = moveOnInsert;
00103 }
00104
00105 void KateSuperCursor::setLine(int lineNum)
00106 {
00107 int tempLine = line(), tempcol = col();
00108 KateDocCursor::setLine(lineNum);
00109
00110 if (tempLine != line() || tempcol != col())
00111 emit positionDirectlyChanged();
00112 }
00113
00114 void KateSuperCursor::setCol(int colNum)
00115 {
00116 KateDocCursor::setCol(colNum);
00117 }
00118
00119 void KateSuperCursor::setPos(const KateTextCursor& pos)
00120 {
00121 KateDocCursor::setPos(pos);
00122 }
00123
00124 void KateSuperCursor::setPos(int lineNum, int colNum)
00125 {
00126 KateDocCursor::setPos(lineNum, colNum);
00127 }
00128
00129 void KateSuperCursor::editTextInserted(uint line, uint col, uint len)
00130 {
00131 if (m_line == int(line))
00132 {
00133 if ((m_col > int(col)) || (m_moveOnInsert && (m_col == int(col))))
00134 {
00135 bool insertedAt = m_col == int(col);
00136
00137 m_col += len;
00138
00139 if (insertedAt)
00140 emit charInsertedAt();
00141
00142 emit positionChanged();
00143 return;
00144 }
00145 }
00146
00147 emit positionUnChanged();
00148 }
00149
00150 void KateSuperCursor::editTextRemoved(uint line, uint col, uint len)
00151 {
00152 if (m_line == int(line))
00153 {
00154 if (m_col > int(col))
00155 {
00156 if (m_col > int(col + len))
00157 {
00158 m_col -= len;
00159 }
00160 else
00161 {
00162 bool prevCharDeleted = m_col == int(col + len);
00163
00164 m_col = col;
00165
00166 if (prevCharDeleted)
00167 emit charDeletedBefore();
00168 else
00169 emit positionDeleted();
00170 }
00171
00172 emit positionChanged();
00173 return;
00174
00175 }
00176 else if (m_col == int(col))
00177 {
00178 emit charDeletedAfter();
00179 }
00180 }
00181
00182 emit positionUnChanged();
00183 }
00184
00185 void KateSuperCursor::editLineWrapped(uint line, uint col, bool newLine)
00186 {
00187 if (newLine)
00188 {
00189 if (m_line > int(line) || (m_line == int(line) && m_col >= int(col)))
00190 {
00191 if(m_line == int(line))
00192 m_col -= col;
00193 m_line++;
00194
00195 emit positionChanged();
00196 return;
00197 }
00198 }
00199 else if ( (m_line == int(line)) && (m_col > int(col)) || (m_moveOnInsert && (m_col == int(col))) )
00200 {
00201 m_line++;
00202 m_col -= col;
00203
00204 emit positionChanged();
00205 return;
00206 }
00207
00208 emit positionUnChanged();
00209 }
00210
00211 void KateSuperCursor::editLineUnWrapped(uint line, uint col, bool removeLine, uint length)
00212 {
00213 if (removeLine && (m_line > int(line+1)))
00214 {
00215 m_line--;
00216
00217 emit positionChanged();
00218 return;
00219 }
00220 else if ( (m_line == int(line+1)) && (removeLine || (m_col < int(length))) )
00221 {
00222 m_line = line;
00223 m_col += col;
00224
00225 emit positionChanged();
00226 return;
00227 }
00228 else if ( (m_line == int(line+1)) && (m_col >= int(length)) )
00229 {
00230 m_col -= length;
00231
00232 emit positionChanged();
00233 return;
00234 }
00235
00236 emit positionUnChanged();
00237 }
00238
00239 void KateSuperCursor::editLineInserted (uint line)
00240 {
00241 if (m_line >= int(line))
00242 {
00243 m_line++;
00244
00245 emit positionChanged();
00246 return;
00247 }
00248
00249 emit positionUnChanged();
00250 }
00251
00252 void KateSuperCursor::editLineRemoved(uint line)
00253 {
00254 if (m_line > int(line))
00255 {
00256 m_line--;
00257
00258 emit positionChanged();
00259 return;
00260 }
00261 else if (m_line == int(line))
00262 {
00263 m_line = (line <= m_doc->lastLine()) ? line : (line - 1);
00264 m_col = 0;
00265
00266 emit positionDeleted();
00267
00268 emit positionChanged();
00269 return;
00270 }
00271
00272 emit positionUnChanged();
00273 }
00274
00275 KateSuperCursor::operator QString()
00276 {
00277 return QString("[%1,%1]").arg(line()).arg(col());
00278 }
00279
00280 KateSuperRange::KateSuperRange(KateSuperCursor* start, KateSuperCursor* end, QObject* parent, const char* name)
00281 : QObject(parent, name)
00282 , m_start(start)
00283 , m_end(end)
00284 , m_evaluate(false)
00285 , m_startChanged(false)
00286 , m_endChanged(false)
00287 , m_deleteCursors(false)
00288 , m_allowZeroLength(false)
00289 {
00290 init();
00291 }
00292
00293 KateSuperRange::KateSuperRange(KateDocument* doc, const KateRange& range, QObject* parent, const char* name)
00294 : QObject(parent, name)
00295 , m_start(new KateSuperCursor(doc, true, range.start()))
00296 , m_end(new KateSuperCursor(doc, true, range.end()))
00297 , m_evaluate(false)
00298 , m_startChanged(false)
00299 , m_endChanged(false)
00300 , m_deleteCursors(true)
00301 , m_allowZeroLength(false)
00302 {
00303 init();
00304 }
00305
00306 KateSuperRange::KateSuperRange(KateDocument* doc, const KateTextCursor& start, const KateTextCursor& end, QObject* parent, const char* name)
00307 : QObject(parent, name)
00308 , m_start(new KateSuperCursor(doc, true, start))
00309 , m_end(new KateSuperCursor(doc, true, end))
00310 , m_evaluate(false)
00311 , m_startChanged(false)
00312 , m_endChanged(false)
00313 , m_deleteCursors(true)
00314 , m_allowZeroLength(false)
00315 {
00316 init();
00317 }
00318
00319 void KateSuperRange::init()
00320 {
00321 Q_ASSERT(isValid());
00322 if (!isValid())
00323 kdDebug(13020) << superStart() << " " << superEnd() << endl;
00324
00325 insertChild(m_start);
00326 insertChild(m_end);
00327
00328 setBehaviour(DoNotExpand);
00329
00330
00331 connect(m_start, SIGNAL(positionDirectlyChanged()), SIGNAL(contentsChanged()));
00332 connect(m_end, SIGNAL(positionDirectlyChanged()), SIGNAL(contentsChanged()));
00333
00334 connect(m_start, SIGNAL(positionChanged()), SLOT(slotEvaluateChanged()));
00335 connect(m_end, SIGNAL(positionChanged()), SLOT(slotEvaluateChanged()));
00336 connect(m_start, SIGNAL(positionUnChanged()), SLOT(slotEvaluateUnChanged()));
00337 connect(m_end, SIGNAL(positionUnChanged()), SLOT(slotEvaluateUnChanged()));
00338 connect(m_start, SIGNAL(positionDeleted()), SIGNAL(boundaryDeleted()));
00339 connect(m_end, SIGNAL(positionDeleted()), SIGNAL(boundaryDeleted()));
00340 }
00341
00342 KateSuperRange::~KateSuperRange()
00343 {
00344 if (m_deleteCursors)
00345 {
00346
00347
00348 delete m_start;
00349 delete m_end;
00350 }
00351 }
00352
00353 KateTextCursor& KateSuperRange::start()
00354 {
00355 return *m_start;
00356 }
00357
00358 const KateTextCursor& KateSuperRange::start() const
00359 {
00360 return *m_start;
00361 }
00362
00363 KateTextCursor& KateSuperRange::end()
00364 {
00365 return *m_end;
00366 }
00367
00368 const KateTextCursor& KateSuperRange::end() const
00369 {
00370 return *m_end;
00371 }
00372
00373 KateSuperCursor& KateSuperRange::superStart()
00374 {
00375 return *m_start;
00376 }
00377
00378 const KateSuperCursor& KateSuperRange::superStart() const
00379 {
00380 return *m_start;
00381 }
00382
00383 KateSuperCursor& KateSuperRange::superEnd()
00384 {
00385 return *m_end;
00386 }
00387
00388 const KateSuperCursor& KateSuperRange::superEnd() const
00389 {
00390 return *m_end;
00391 }
00392
00393 int KateSuperRange::behaviour() const
00394 {
00395 return (m_start->moveOnInsert() ? DoNotExpand : ExpandLeft) | (m_end->moveOnInsert() ? ExpandRight : DoNotExpand);
00396 }
00397
00398 void KateSuperRange::setBehaviour(int behaviour)
00399 {
00400 m_start->setMoveOnInsert(behaviour & ExpandLeft);
00401 m_end->setMoveOnInsert(!(behaviour & ExpandRight));
00402 }
00403
00404 bool KateSuperRange::isValid() const
00405 {
00406 return superStart() <= superEnd();
00407 }
00408
00409 bool KateSuperRange::owns(const KateTextCursor& cursor) const
00410 {
00411 if (!includes(cursor)) return false;
00412
00413 if (children())
00414 for (QObjectListIt it(*children()); *it; ++it)
00415 if ((*it)->inherits("KateSuperRange"))
00416 if (static_cast<KateSuperRange*>(*it)->owns(cursor))
00417 return false;
00418
00419 return true;
00420 }
00421
00422 bool KateSuperRange::includes(const KateTextCursor& cursor) const
00423 {
00424 return isValid() && cursor >= superStart() && cursor < superEnd();
00425 }
00426
00427 bool KateSuperRange::includes(uint lineNum) const
00428 {
00429 return isValid() && (int)lineNum >= superStart().line() && (int)lineNum <= superEnd().line();
00430 }
00431
00432 bool KateSuperRange::includesWholeLine(uint lineNum) const
00433 {
00434 return isValid() && ((int)lineNum > superStart().line() || ((int)lineNum == superStart().line() && superStart().atStartOfLine())) && ((int)lineNum < superEnd().line() || ((int)lineNum == superEnd().line() && superEnd().atEndOfLine()));
00435 }
00436
00437 bool KateSuperRange::boundaryAt(const KateTextCursor& cursor) const
00438 {
00439 return isValid() && (cursor == superStart() || cursor == superEnd());
00440 }
00441
00442 bool KateSuperRange::boundaryOn(uint lineNum) const
00443 {
00444 return isValid() && (superStart().line() == (int)lineNum || superEnd().line() == (int)lineNum);
00445 }
00446
00447 void KateSuperRange::slotEvaluateChanged()
00448 {
00449 if (sender() == static_cast<QObject*>(m_start)) {
00450 if (m_evaluate) {
00451 if (!m_endChanged) {
00452
00453 evaluateEliminated();
00454
00455 } else {
00456
00457 evaluatePositionChanged();
00458 m_endChanged = false;
00459 }
00460
00461 } else {
00462 m_startChanged = true;
00463 }
00464
00465 } else {
00466 if (m_evaluate) {
00467 if (!m_startChanged) {
00468
00469 evaluateEliminated();
00470
00471 } else {
00472
00473 evaluatePositionChanged();
00474 m_startChanged = false;
00475 }
00476
00477 } else {
00478 m_endChanged = true;
00479 }
00480 }
00481
00482 m_evaluate = !m_evaluate;
00483 }
00484
00485 void KateSuperRange::slotEvaluateUnChanged()
00486 {
00487 if (sender() == static_cast<QObject*>(m_start)) {
00488 if (m_evaluate) {
00489 if (m_endChanged) {
00490
00491 evaluateEliminated();
00492 m_endChanged = false;
00493
00494 } else {
00495
00496 emit positionUnChanged();
00497 }
00498 }
00499
00500 } else {
00501 if (m_evaluate) {
00502 if (m_startChanged) {
00503
00504 evaluateEliminated();
00505 m_startChanged = false;
00506
00507 } else {
00508
00509 emit positionUnChanged();
00510 }
00511 }
00512 }
00513
00514 m_evaluate = !m_evaluate;
00515 }
00516
00517 void KateSuperRange::slotTagRange()
00518 {
00519 emit tagRange(this);
00520 }
00521
00522 void KateSuperRange::evaluateEliminated()
00523 {
00524 if (superStart() == superEnd()) {
00525 if (!m_allowZeroLength) emit eliminated();
00526 }
00527 else
00528 emit contentsChanged();
00529 }
00530
00531 void KateSuperRange::evaluatePositionChanged()
00532 {
00533 if (superStart() == superEnd())
00534 emit eliminated();
00535 else
00536 emit positionChanged();
00537 }
00538
00539 int KateSuperCursorList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00540 {
00541 if (*(static_cast<KateSuperCursor*>(item1)) == *(static_cast<KateSuperCursor*>(item2)))
00542 return 0;
00543
00544 return *(static_cast<KateSuperCursor*>(item1)) < *(static_cast<KateSuperCursor*>(item2)) ? -1 : 1;
00545 }
00546
00547 KateSuperRangeList::KateSuperRangeList(bool autoManage, QObject* parent, const char* name)
00548 : QObject(parent, name)
00549 , m_autoManage(autoManage)
00550 , m_connect(true)
00551 , m_trackingBoundaries(false)
00552 {
00553 setAutoManage(autoManage);
00554 }
00555
00556 KateSuperRangeList::KateSuperRangeList(const QPtrList<KateSuperRange>& rangeList, QObject* parent, const char* name)
00557 : QObject(parent, name)
00558 , m_autoManage(false)
00559 , m_connect(false)
00560 , m_trackingBoundaries(false)
00561 {
00562 appendList(rangeList);
00563 }
00564
00565 void KateSuperRangeList::appendList(const QPtrList<KateSuperRange>& rangeList)
00566 {
00567 for (QPtrListIterator<KateSuperRange> it = rangeList; *it; ++it)
00568 append(*it);
00569 }
00570
00571 void KateSuperRangeList::clear()
00572 {
00573 for (KateSuperRange* range = first(); range; range = next())
00574 emit rangeEliminated(range);
00575
00576 QPtrList<KateSuperRange>::clear();
00577 }
00578
00579 void KateSuperRangeList::connectAll()
00580 {
00581 if (!m_connect) {
00582 m_connect = true;
00583 for (KateSuperRange* range = first(); range; range = next()) {
00584 connect(range, SIGNAL(destroyed(QObject*)), SLOT(slotDeleted(QObject*)));
00585 connect(range, SIGNAL(eliminated()), SLOT(slotEliminated()));
00586 }
00587 }
00588 }
00589
00590 bool KateSuperRangeList::autoManage() const
00591 {
00592 return m_autoManage;
00593 }
00594
00595 void KateSuperRangeList::setAutoManage(bool autoManage)
00596 {
00597 m_autoManage = autoManage;
00598 setAutoDelete(m_autoManage);
00599 }
00600
00601 QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(const KateTextCursor& cursor)
00602 {
00603 sort();
00604
00605 QPtrList<KateSuperRange> ret;
00606
00607 for (KateSuperRange* r = first(); r; r = next())
00608 if (r->includes(cursor))
00609 ret.append(r);
00610
00611 return ret;
00612 }
00613
00614 QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(uint line)
00615 {
00616 sort();
00617
00618 QPtrList<KateSuperRange> ret;
00619
00620 for (KateSuperRange* r = first(); r; r = next())
00621 if (r->includes(line))
00622 ret.append(r);
00623
00624 return ret;
00625 }
00626
00627 bool KateSuperRangeList::rangesInclude(const KateTextCursor& cursor)
00628 {
00629 for (KateSuperRange* r = first(); r; r = next())
00630 if (r->includes(cursor))
00631 return true;
00632
00633 return false;
00634 }
00635
00636 void KateSuperRangeList::slotEliminated()
00637 {
00638 if (sender()) {
00639 KateSuperRange* range = static_cast<KateSuperRange*>(const_cast<QObject*>(sender()));
00640 emit rangeEliminated(range);
00641
00642 if (m_trackingBoundaries) {
00643 m_columnBoundaries.removeRef(range->m_start);
00644 m_columnBoundaries.removeRef(range->m_end);
00645 }
00646
00647 if (m_autoManage)
00648 removeRef(range);
00649
00650 if (!count())
00651 emit listEmpty();
00652 }
00653 }
00654
00655 void KateSuperRangeList::slotDeleted(QObject* range)
00656 {
00657
00658 KateSuperRange* r = static_cast<KateSuperRange*>(range);
00659
00660 if (m_trackingBoundaries) {
00661 m_columnBoundaries.removeRef(r->m_start);
00662 m_columnBoundaries.removeRef(r->m_end);
00663 }
00664
00665 int index = findRef(r);
00666 if (index != -1)
00667 take(index);
00668
00669
00670 if (!count())
00671 emit listEmpty();
00672 }
00673
00674 KateSuperCursor* KateSuperRangeList::firstBoundary(const KateTextCursor* start)
00675 {
00676 if (!m_trackingBoundaries) {
00677 m_trackingBoundaries = true;
00678
00679 for (KateSuperRange* r = first(); r; r = next()) {
00680 m_columnBoundaries.append(&(r->superStart()));
00681 m_columnBoundaries.append(&(r->superEnd()));
00682 }
00683 }
00684
00685 m_columnBoundaries.sort();
00686
00687 if (start)
00688
00689 for (KateSuperCursor* c = m_columnBoundaries.first(); c; c = m_columnBoundaries.next())
00690 if (*start <= *c)
00691 break;
00692
00693 return m_columnBoundaries.current();
00694 }
00695
00696 KateSuperCursor* KateSuperRangeList::nextBoundary()
00697 {
00698 KateSuperCursor* current = m_columnBoundaries.current();
00699
00700
00701 if (current)
00702 while (m_columnBoundaries.next())
00703 if (*(m_columnBoundaries.current()) != *current)
00704 break;
00705
00706 return m_columnBoundaries.current();
00707 }
00708
00709 KateSuperCursor* KateSuperRangeList::currentBoundary()
00710 {
00711 return m_columnBoundaries.current();
00712 }
00713
00714 int KateSuperRangeList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2)
00715 {
00716 if (static_cast<KateSuperRange*>(item1)->superStart() == static_cast<KateSuperRange*>(item2)->superStart()) {
00717 if (static_cast<KateSuperRange*>(item1)->superEnd() == static_cast<KateSuperRange*>(item2)->superEnd()) {
00718 return 0;
00719 } else {
00720 return static_cast<KateSuperRange*>(item1)->superEnd() < static_cast<KateSuperRange*>(item2)->superEnd() ? -1 : 1;
00721 }
00722 }
00723
00724 return static_cast<KateSuperRange*>(item1)->superStart() < static_cast<KateSuperRange*>(item2)->superStart() ? -1 : 1;
00725 }
00726
00727 QPtrCollection::Item KateSuperRangeList::newItem(QPtrCollection::Item d)
00728 {
00729 if (m_connect) {
00730 connect(static_cast<KateSuperRange*>(d), SIGNAL(destroyed(QObject*)), SLOT(slotDeleted(QObject*)));
00731 connect(static_cast<KateSuperRange*>(d), SIGNAL(eliminated()), SLOT(slotEliminated()));
00732 connect(static_cast<KateSuperRange*>(d), SIGNAL(tagRange(KateSuperRange*)), SIGNAL(tagRange(KateSuperRange*)));
00733
00734
00735 static_cast<KateSuperRange*>(d)->slotTagRange();
00736 }
00737
00738 if (m_trackingBoundaries) {
00739 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->superStart()));
00740 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->superEnd()));
00741 }
00742
00743 return QPtrList<KateSuperRange>::newItem(d);
00744 }
00745
00746