kate Library API Documentation

katesupercursor.cpp

00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2003 Hamish Rodda <rodda@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00016 Boston, MA 02111-1307, USA. 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 && (m_line > int(line))) 00188 { 00189 m_line++; 00190 00191 emit positionChanged(); 00192 return; 00193 } 00194 else if ( (m_line == int(line)) && (m_col > int(col)) || (m_moveOnInsert && (m_col == int(col))) ) 00195 { 00196 m_line++; 00197 m_col -= col; 00198 00199 emit positionChanged(); 00200 return; 00201 } 00202 00203 emit positionUnChanged(); 00204 } 00205 00206 void KateSuperCursor::editLineUnWrapped(uint line, uint col, bool removeLine, uint length) 00207 { 00208 if (removeLine && (m_line > int(line+1))) 00209 { 00210 m_line--; 00211 00212 emit positionChanged(); 00213 return; 00214 } 00215 else if ( (m_line == int(line+1)) && (removeLine || (m_col < int(length))) ) 00216 { 00217 m_line = line; 00218 m_col += col; 00219 00220 emit positionChanged(); 00221 return; 00222 } 00223 else if ( (m_line == int(line+1)) && (m_col >= int(length)) ) 00224 { 00225 m_col -= length; 00226 00227 emit positionChanged(); 00228 return; 00229 } 00230 00231 emit positionUnChanged(); 00232 } 00233 00234 void KateSuperCursor::editLineInserted (uint line) 00235 { 00236 if (m_line >= int(line)) 00237 { 00238 m_line++; 00239 00240 emit positionChanged(); 00241 return; 00242 } 00243 00244 emit positionUnChanged(); 00245 } 00246 00247 void KateSuperCursor::editLineRemoved(uint line) 00248 { 00249 if (m_line > int(line)) 00250 { 00251 m_line--; 00252 00253 emit positionChanged(); 00254 return; 00255 } 00256 else if (m_line == int(line)) 00257 { 00258 m_line = (line <= m_doc->lastLine()) ? line : (line - 1); 00259 m_col = 0; 00260 00261 emit positionDeleted(); 00262 00263 emit positionChanged(); 00264 return; 00265 } 00266 00267 emit positionUnChanged(); 00268 } 00269 00270 KateSuperCursor::operator QString() 00271 { 00272 return QString("[%1,%1]").arg(line()).arg(col()); 00273 } 00274 00275 KateSuperRange::KateSuperRange(KateSuperCursor* start, KateSuperCursor* end, QObject* parent, const char* name) 00276 : QObject(parent, name) 00277 , m_start(start) 00278 , m_end(end) 00279 , m_evaluate(false) 00280 , m_startChanged(false) 00281 , m_endChanged(false) 00282 , m_deleteCursors(false) 00283 , m_allowZeroLength(false) 00284 { 00285 init(); 00286 } 00287 00288 KateSuperRange::KateSuperRange(KateDocument* doc, const KateRange& range, QObject* parent, const char* name) 00289 : QObject(parent, name) 00290 , m_start(new KateSuperCursor(doc, true, range.start())) 00291 , m_end(new KateSuperCursor(doc, true, range.end())) 00292 , m_evaluate(false) 00293 , m_startChanged(false) 00294 , m_endChanged(false) 00295 , m_deleteCursors(true) 00296 , m_allowZeroLength(false) 00297 { 00298 init(); 00299 } 00300 00301 KateSuperRange::KateSuperRange(KateDocument* doc, const KateTextCursor& start, const KateTextCursor& end, QObject* parent, const char* name) 00302 : QObject(parent, name) 00303 , m_start(new KateSuperCursor(doc, true, start)) 00304 , m_end(new KateSuperCursor(doc, true, end)) 00305 , m_evaluate(false) 00306 , m_startChanged(false) 00307 , m_endChanged(false) 00308 , m_deleteCursors(true) 00309 , m_allowZeroLength(false) 00310 { 00311 init(); 00312 } 00313 00314 void KateSuperRange::init() 00315 { 00316 Q_ASSERT(isValid()); 00317 if (!isValid()) 00318 kdDebug(13020) << superStart() << " " << superEnd() << endl; 00319 00320 insertChild(m_start); 00321 insertChild(m_end); 00322 00323 setBehaviour(DoNotExpand); 00324 00325 // Not necessarily the best implementation 00326 connect(m_start, SIGNAL(positionDirectlyChanged()), SIGNAL(contentsChanged())); 00327 connect(m_end, SIGNAL(positionDirectlyChanged()), SIGNAL(contentsChanged())); 00328 00329 connect(m_start, SIGNAL(positionChanged()), SLOT(slotEvaluateChanged())); 00330 connect(m_end, SIGNAL(positionChanged()), SLOT(slotEvaluateChanged())); 00331 connect(m_start, SIGNAL(positionUnChanged()), SLOT(slotEvaluateUnChanged())); 00332 connect(m_end, SIGNAL(positionUnChanged()), SLOT(slotEvaluateUnChanged())); 00333 connect(m_start, SIGNAL(positionDeleted()), SIGNAL(boundaryDeleted())); 00334 connect(m_end, SIGNAL(positionDeleted()), SIGNAL(boundaryDeleted())); 00335 } 00336 00337 KateSuperRange::~KateSuperRange() 00338 { 00339 if (m_deleteCursors) 00340 { 00341 //insertChild(m_start); 00342 //insertChild(m_end); 00343 delete m_start; 00344 delete m_end; 00345 } 00346 } 00347 00348 KateTextCursor& KateSuperRange::start() 00349 { 00350 return *m_start; 00351 } 00352 00353 const KateTextCursor& KateSuperRange::start() const 00354 { 00355 return *m_start; 00356 } 00357 00358 KateTextCursor& KateSuperRange::end() 00359 { 00360 return *m_end; 00361 } 00362 00363 const KateTextCursor& KateSuperRange::end() const 00364 { 00365 return *m_end; 00366 } 00367 00368 KateSuperCursor& KateSuperRange::superStart() 00369 { 00370 return *m_start; 00371 } 00372 00373 const KateSuperCursor& KateSuperRange::superStart() const 00374 { 00375 return *m_start; 00376 } 00377 00378 KateSuperCursor& KateSuperRange::superEnd() 00379 { 00380 return *m_end; 00381 } 00382 00383 const KateSuperCursor& KateSuperRange::superEnd() const 00384 { 00385 return *m_end; 00386 } 00387 00388 int KateSuperRange::behaviour() const 00389 { 00390 return (m_start->moveOnInsert() ? DoNotExpand : ExpandLeft) | (m_end->moveOnInsert() ? ExpandRight : DoNotExpand); 00391 } 00392 00393 void KateSuperRange::setBehaviour(int behaviour) 00394 { 00395 m_start->setMoveOnInsert(behaviour & ExpandLeft); 00396 m_end->setMoveOnInsert(!(behaviour & ExpandRight)); 00397 } 00398 00399 bool KateSuperRange::isValid() const 00400 { 00401 return superStart() <= superEnd(); 00402 } 00403 00404 bool KateSuperRange::owns(const KateTextCursor& cursor) const 00405 { 00406 if (!includes(cursor)) return false; 00407 00408 if (children()) 00409 for (QObjectListIt it(*children()); *it; ++it) 00410 if ((*it)->inherits("KateSuperRange")) 00411 if (static_cast<KateSuperRange*>(*it)->owns(cursor)) 00412 return false; 00413 00414 return true; 00415 } 00416 00417 bool KateSuperRange::includes(const KateTextCursor& cursor) const 00418 { 00419 return isValid() && cursor >= superStart() && cursor < superEnd(); 00420 } 00421 00422 bool KateSuperRange::includes(uint lineNum) const 00423 { 00424 return isValid() && (int)lineNum >= superStart().line() && (int)lineNum <= superEnd().line(); 00425 } 00426 00427 bool KateSuperRange::includesWholeLine(uint lineNum) const 00428 { 00429 return isValid() && ((int)lineNum > superStart().line() || ((int)lineNum == superStart().line() && superStart().atStartOfLine())) && ((int)lineNum < superEnd().line() || ((int)lineNum == superEnd().line() && superEnd().atEndOfLine())); 00430 } 00431 00432 bool KateSuperRange::boundaryAt(const KateTextCursor& cursor) const 00433 { 00434 return isValid() && (cursor == superStart() || cursor == superEnd()); 00435 } 00436 00437 bool KateSuperRange::boundaryOn(uint lineNum) const 00438 { 00439 return isValid() && (superStart().line() == (int)lineNum || superEnd().line() == (int)lineNum); 00440 } 00441 00442 void KateSuperRange::slotEvaluateChanged() 00443 { 00444 if (sender() == static_cast<QObject*>(m_start)) { 00445 if (m_evaluate) { 00446 if (!m_endChanged) { 00447 // Only one was changed 00448 evaluateEliminated(); 00449 00450 } else { 00451 // Both were changed 00452 evaluatePositionChanged(); 00453 m_endChanged = false; 00454 } 00455 00456 } else { 00457 m_startChanged = true; 00458 } 00459 00460 } else { 00461 if (m_evaluate) { 00462 if (!m_startChanged) { 00463 // Only one was changed 00464 evaluateEliminated(); 00465 00466 } else { 00467 // Both were changed 00468 evaluatePositionChanged(); 00469 m_startChanged = false; 00470 } 00471 00472 } else { 00473 m_endChanged = true; 00474 } 00475 } 00476 00477 m_evaluate = !m_evaluate; 00478 } 00479 00480 void KateSuperRange::slotEvaluateUnChanged() 00481 { 00482 if (sender() == static_cast<QObject*>(m_start)) { 00483 if (m_evaluate) { 00484 if (m_endChanged) { 00485 // Only one changed 00486 evaluateEliminated(); 00487 m_endChanged = false; 00488 00489 } else { 00490 // Neither changed 00491 emit positionUnChanged(); 00492 } 00493 } 00494 00495 } else { 00496 if (m_evaluate) { 00497 if (m_startChanged) { 00498 // Only one changed 00499 evaluateEliminated(); 00500 m_startChanged = false; 00501 00502 } else { 00503 // Neither changed 00504 emit positionUnChanged(); 00505 } 00506 } 00507 } 00508 00509 m_evaluate = !m_evaluate; 00510 } 00511 00512 void KateSuperRange::slotTagRange() 00513 { 00514 emit tagRange(this); 00515 } 00516 00517 void KateSuperRange::evaluateEliminated() 00518 { 00519 if (superStart() == superEnd()) { 00520 if (!m_allowZeroLength) emit eliminated(); 00521 } 00522 else 00523 emit contentsChanged(); 00524 } 00525 00526 void KateSuperRange::evaluatePositionChanged() 00527 { 00528 if (superStart() == superEnd()) 00529 emit eliminated(); 00530 else 00531 emit positionChanged(); 00532 } 00533 00534 int KateSuperCursorList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2) 00535 { 00536 if (*(static_cast<KateSuperCursor*>(item1)) == *(static_cast<KateSuperCursor*>(item2))) 00537 return 0; 00538 00539 return *(static_cast<KateSuperCursor*>(item1)) < *(static_cast<KateSuperCursor*>(item2)) ? -1 : 1; 00540 } 00541 00542 KateSuperRangeList::KateSuperRangeList(bool autoManage, QObject* parent, const char* name) 00543 : QObject(parent, name) 00544 , m_autoManage(autoManage) 00545 , m_connect(true) 00546 , m_trackingBoundaries(false) 00547 { 00548 setAutoManage(autoManage); 00549 } 00550 00551 KateSuperRangeList::KateSuperRangeList(const QPtrList<KateSuperRange>& rangeList, QObject* parent, const char* name) 00552 : QObject(parent, name) 00553 , m_autoManage(false) 00554 , m_connect(false) 00555 , m_trackingBoundaries(false) 00556 { 00557 appendList(rangeList); 00558 } 00559 00560 void KateSuperRangeList::appendList(const QPtrList<KateSuperRange>& rangeList) 00561 { 00562 for (QPtrListIterator<KateSuperRange> it = rangeList; *it; ++it) 00563 append(*it); 00564 } 00565 00566 void KateSuperRangeList::clear() 00567 { 00568 for (KateSuperRange* range = first(); range; range = next()) 00569 emit rangeEliminated(range); 00570 00571 QPtrList<KateSuperRange>::clear(); 00572 } 00573 00574 void KateSuperRangeList::connectAll() 00575 { 00576 if (!m_connect) { 00577 m_connect = true; 00578 for (KateSuperRange* range = first(); range; range = next()) { 00579 connect(range, SIGNAL(destroyed(QObject*)), SLOT(slotDeleted(QObject*))); 00580 connect(range, SIGNAL(eliminated()), SLOT(slotEliminated())); 00581 } 00582 } 00583 } 00584 00585 bool KateSuperRangeList::autoManage() const 00586 { 00587 return m_autoManage; 00588 } 00589 00590 void KateSuperRangeList::setAutoManage(bool autoManage) 00591 { 00592 m_autoManage = autoManage; 00593 setAutoDelete(m_autoManage); 00594 } 00595 00596 QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(const KateTextCursor& cursor) 00597 { 00598 sort(); 00599 00600 QPtrList<KateSuperRange> ret; 00601 00602 for (KateSuperRange* r = first(); r; r = next()) 00603 if (r->includes(cursor)) 00604 ret.append(r); 00605 00606 return ret; 00607 } 00608 00609 QPtrList<KateSuperRange> KateSuperRangeList::rangesIncluding(uint line) 00610 { 00611 sort(); 00612 00613 QPtrList<KateSuperRange> ret; 00614 00615 for (KateSuperRange* r = first(); r; r = next()) 00616 if (r->includes(line)) 00617 ret.append(r); 00618 00619 return ret; 00620 } 00621 00622 bool KateSuperRangeList::rangesInclude(const KateTextCursor& cursor) 00623 { 00624 for (KateSuperRange* r = first(); r; r = next()) 00625 if (r->includes(cursor)) 00626 return true; 00627 00628 return false; 00629 } 00630 00631 void KateSuperRangeList::slotEliminated() 00632 { 00633 if (sender()) { 00634 KateSuperRange* range = static_cast<KateSuperRange*>(const_cast<QObject*>(sender())); 00635 emit rangeEliminated(range); 00636 00637 if (m_trackingBoundaries) { 00638 m_columnBoundaries.removeRef(range->m_start); 00639 m_columnBoundaries.removeRef(range->m_end); 00640 } 00641 00642 if (m_autoManage) 00643 removeRef(range); 00644 00645 if (!count()) 00646 emit listEmpty(); 00647 } 00648 } 00649 00650 void KateSuperRangeList::slotDeleted(QObject* range) 00651 { 00652 //kdDebug(13020)<<"KateSuperRangeList::slotDeleted"<<endl; 00653 KateSuperRange* r = static_cast<KateSuperRange*>(range); 00654 00655 if (m_trackingBoundaries) { 00656 m_columnBoundaries.removeRef(r->m_start); 00657 m_columnBoundaries.removeRef(r->m_end); 00658 } 00659 00660 int index = findRef(r); 00661 if (index != -1) 00662 take(index); 00663 //else kdDebug(13020)<<"Range not found in list"<<endl; 00664 00665 if (!count()) 00666 emit listEmpty(); 00667 } 00668 00669 KateSuperCursor* KateSuperRangeList::firstBoundary(const KateTextCursor* start) 00670 { 00671 if (!m_trackingBoundaries) { 00672 m_trackingBoundaries = true; 00673 00674 for (KateSuperRange* r = first(); r; r = next()) { 00675 m_columnBoundaries.append(&(r->superStart())); 00676 m_columnBoundaries.append(&(r->superEnd())); 00677 } 00678 } 00679 00680 m_columnBoundaries.sort(); 00681 00682 if (start) 00683 // OPTIMISE: QMap with QPtrList for each line? (==> sorting issues :( ) 00684 for (KateSuperCursor* c = m_columnBoundaries.first(); c; c = m_columnBoundaries.next()) 00685 if (*start <= *c) 00686 break; 00687 00688 return m_columnBoundaries.current(); 00689 } 00690 00691 KateSuperCursor* KateSuperRangeList::nextBoundary() 00692 { 00693 KateSuperCursor* current = m_columnBoundaries.current(); 00694 00695 // make sure the new cursor is after the current cursor; multiple cursors with the same position can be in the list. 00696 if (current) 00697 while (m_columnBoundaries.next()) 00698 if (*(m_columnBoundaries.current()) != *current) 00699 break; 00700 00701 return m_columnBoundaries.current(); 00702 } 00703 00704 KateSuperCursor* KateSuperRangeList::currentBoundary() 00705 { 00706 return m_columnBoundaries.current(); 00707 } 00708 00709 int KateSuperRangeList::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2) 00710 { 00711 if (static_cast<KateSuperRange*>(item1)->superStart() == static_cast<KateSuperRange*>(item2)->superStart()) { 00712 if (static_cast<KateSuperRange*>(item1)->superEnd() == static_cast<KateSuperRange*>(item2)->superEnd()) { 00713 return 0; 00714 } else { 00715 return static_cast<KateSuperRange*>(item1)->superEnd() < static_cast<KateSuperRange*>(item2)->superEnd() ? -1 : 1; 00716 } 00717 } 00718 00719 return static_cast<KateSuperRange*>(item1)->superStart() < static_cast<KateSuperRange*>(item2)->superStart() ? -1 : 1; 00720 } 00721 00722 QPtrCollection::Item KateSuperRangeList::newItem(QPtrCollection::Item d) 00723 { 00724 if (m_connect) { 00725 connect(static_cast<KateSuperRange*>(d), SIGNAL(destroyed(QObject*)), SLOT(slotDeleted(QObject*))); 00726 connect(static_cast<KateSuperRange*>(d), SIGNAL(eliminated()), SLOT(slotEliminated())); 00727 connect(static_cast<KateSuperRange*>(d), SIGNAL(tagRange(KateSuperRange*)), SIGNAL(tagRange(KateSuperRange*))); 00728 00729 // HACK HACK 00730 static_cast<KateSuperRange*>(d)->slotTagRange(); 00731 } 00732 00733 if (m_trackingBoundaries) { 00734 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->superStart())); 00735 m_columnBoundaries.append(&(static_cast<KateSuperRange*>(d)->superEnd())); 00736 } 00737 00738 return QPtrList<KateSuperRange>::newItem(d); 00739 } 00740 00741 // kate: space-indent on; indent-width 2; replace-tabs on;
KDE Logo
This file is part of the documentation for kate Library Version 3.4.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Apr 14 00:46:08 2005 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003