00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "smartrange.h"
00021
00022 #include <QtCore/QStack>
00023
00024 #include "document.h"
00025 #include "view.h"
00026 #include "attribute.h"
00027 #include "rangefeedback.h"
00028
00029 #include <kaction.h>
00030 #include <kdebug.h>
00031
00032 using namespace KTextEditor;
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #ifdef SHOULD_DEBUG_CHILD_ORDER
00046 #define DEBUG_CHILD_ORDER \
00047 {\
00048 KTextEditor::Cursor lastEnd = KTextEditor::Cursor(-1,-1);\
00049 for(int a = 0; a < m_childRanges.size(); ++a) {\
00050 Q_ASSERT(m_childRanges[a]->end() >= lastEnd);\
00051 Q_ASSERT(m_childRanges[a]->start() >= start());\
00052 Q_ASSERT(m_childRanges[a]->end() <= end());\
00053 lastEnd = m_childRanges[a]->end();\
00054 }\
00055 }\
00056
00057 #else
00058 #define DEBUG_CHILD_ORDER
00059 #endif
00060
00061 #ifdef SHOULD_DEBUG_OVERLAP
00062 #define DEBUG_CHILD_OVERLAP \
00063 {\
00064 QVector<int> counter(m_childRanges.size(), 0);\
00065 \
00066 for(int a = 0; a < m_childRanges.size(); ++a) {\
00067 const SmartRange& overlapper(*m_childRanges[a]);\
00068 for(int b = 0; b < a; ++b) {\
00069 const SmartRange& overlapped(*m_childRanges[b]);\
00070 Q_ASSERT(overlapped.end() <= overlapper.end());\
00071 if(overlapped.end() > overlapper.start()) {\
00072 ++counter[b];\
00073 }\
00074 }\
00075 }\
00076 for(int a = 0; a < m_childRanges.size(); ++a) {\
00077 Q_ASSERT(m_childRanges[a]->m_overlapCount == counter[a]);\
00078 }\
00079 }\
00080
00081 #define DEBUG_PARENT_OVERLAP \
00082 if(m_parentRange) {\
00083 QVector<int> counter(m_parentRange->m_childRanges.size(), 0);\
00084 \
00085 for(int a = 0; a < m_parentRange->m_childRanges.size(); ++a) {\
00086 const SmartRange& overlapper(*m_parentRange->m_childRanges[a]);\
00087 for(int b = 0; b < a; ++b) {\
00088 const SmartRange& overlapped(*m_parentRange->m_childRanges[b]);\
00089 Q_ASSERT(overlapped.end() <= overlapper.end());\
00090 if(overlapped.end() > overlapper.start()) {\
00091 ++counter[b];\
00092 }\
00093 }\
00094 }\
00095 for(int a = 0; a < m_parentRange->m_childRanges.size(); ++a) {\
00096 Q_ASSERT(m_parentRange->m_childRanges[a]->m_overlapCount == counter[a]);\
00097 }\
00098 }\
00099
00100 #else
00101 #define DEBUG_CHILD_OVERLAP
00102 #define DEBUG_PARENT_OVERLAP
00103 #endif
00104
00107 static int lowerBound(const QList<SmartRange*>& ranges, const Cursor& pos)
00108 {
00109 int begin = 0;
00110 int n = ranges.count();
00111
00112 int half;
00113 int middle;
00114
00115 while (n > 0) {
00116 half = n >> 1;
00117 middle = begin + half;
00118 if(ranges[middle]->end() > pos) {
00119 n = half;
00120 }else{
00121 begin = middle + 1;
00122 n -= half + 1;
00123 }
00124 }
00125 return begin;
00126 }
00127
00130 static int lowerBoundRange(const QList<SmartRange*>& ranges, const Cursor& pos, const SmartRange* range)
00131 {
00132 int begin = 0;
00133 int n = ranges.count();
00134
00135 int half;
00136 int middle;
00137
00138 while (n > 0) {
00139 half = n >> 1;
00140 middle = begin + half;
00141 if(ranges[begin] == range)
00142 return begin;
00143 if(ranges[middle] == range)
00144 return middle;
00145
00146 if(ranges[middle]->end() > pos) {
00147 n = half;
00148 }else{
00149 begin = middle + 1;
00150 n -= half + 1;
00151 }
00152 }
00153 return begin;
00154 }
00155
00157 static int findIndex(const QList<SmartRange*>& ranges, const SmartRange* smartRange, const Range* range) {
00158 int index = lowerBoundRange(ranges, range->start(), smartRange);
00159 int childCount = ranges.count();
00160
00161
00162 while(index < childCount && ranges[index] != smartRange)
00163 ++index;
00164
00165 if(index == childCount) {
00166
00167 return ranges.indexOf(const_cast<SmartRange*>(smartRange));
00168
00169
00170
00171
00172 return -1;
00173 }
00174
00175 return index;
00176 }
00177
00178 SmartRange::SmartRange(SmartCursor* start, SmartCursor* end, SmartRange * parent, InsertBehaviors insertBehavior )
00179 : Range(start, end)
00180 , m_attribute(0L)
00181 , m_parentRange(parent)
00182 , m_ownsAttribute(false)
00183 , m_overlapCount(0)
00184 {
00185 setInsertBehavior(insertBehavior);
00186
00187
00188
00189
00190 if (m_parentRange)
00191 m_parentRange->insertChildRange(this);
00192 }
00193
00194 SmartRange::~SmartRange( )
00195 {
00196 deleteChildRanges();
00197
00198 setParentRange(0L);
00199
00200
00201
00202
00203
00204
00205
00206 }
00207
00208 bool SmartRange::confineToRange(const Range& range)
00209 {
00210 if (!Range::confineToRange(range))
00211
00212 return false;
00213
00214 foreach (SmartRange* child, m_childRanges)
00215 child->confineToRange(*this);
00216
00217 return true;
00218 }
00219
00220 bool SmartRange::expandToRange(const Range& range)
00221 {
00222 if (!Range::expandToRange(range))
00223
00224 return false;
00225
00226 if (parentRange())
00227 parentRange()->expandToRange(*this);
00228
00229 return true;
00230 }
00231
00232 void SmartRange::setRange(const Range& range)
00233 {
00234 if (range == *this)
00235 return;
00236
00237 Range old = *this;
00238
00239 Range::setRange(range);
00240
00241 DEBUG_CHILD_OVERLAP
00242 }
00243
00244 const QList<SmartRange*>& SmartRange::childRanges() const
00245 {
00246 return m_childRanges;
00247 }
00248
00249 SmartRange * SmartRange::childBefore( const SmartRange * range ) const
00250 {
00251 int index = findIndex(m_childRanges, range, range);
00252
00253 if (--index >= 0)
00254 return m_childRanges[index];
00255
00256 return 0L;
00257 }
00258
00259 SmartRange * SmartRange::childAfter( const SmartRange * range ) const
00260 {
00261 int index = findIndex(m_childRanges, range, range);
00262 if (index != -1 && ++index < m_childRanges.count())
00263 return m_childRanges[index];
00264 return 0L;
00265 }
00266
00267 void SmartRange::insertChildRange( SmartRange * newChild )
00268 {
00269 DEBUG_CHILD_OVERLAP
00270
00271 Q_ASSERT(newChild->parentRange() == this);
00272
00273
00274 expandToRange(*newChild);
00275
00276 DEBUG_CHILD_ORDER
00277
00278 int insertAt = lowerBound(m_childRanges, newChild->end());
00279 m_childRanges.insert(insertAt, newChild);
00280
00281
00282 for(int current = insertAt-1; current >= 0; --current) {
00283 SmartRange& range(*m_childRanges[current]);
00284 Q_ASSERT(range.end() <= newChild->end());
00285
00286 if(range.end() > newChild->start()) {
00287 ++range.m_overlapCount;
00288 }else{
00289
00290 break;
00291 }
00292 }
00293
00294
00295 for(int current = insertAt+1; current < m_childRanges.size(); ++current) {
00296 SmartRange& range(*m_childRanges[current]);
00297 Q_ASSERT(range.end() >= newChild->end());
00298
00299 if(range.start() < newChild->end())
00300 ++newChild->m_overlapCount;
00301
00302 if(!range.m_overlapCount)
00303 break;
00304 }
00305
00306 DEBUG_CHILD_OVERLAP
00307
00308 DEBUG_CHILD_ORDER
00309
00310 QMutableListIterator<SmartRange*> it = m_childRanges;
00311 it.toBack();
00312
00313 foreach (SmartRangeNotifier* n, m_notifiers)
00314 emit n->childRangeInserted(this, newChild);
00315
00316 foreach (SmartRangeWatcher* w, m_watchers)
00317 w->childRangeInserted(this, newChild);
00318
00319 DEBUG_CHILD_OVERLAP
00320 DEBUG_CHILD_ORDER
00321 }
00322
00323 void SmartRange::removeChildRange(SmartRange* child)
00324 {
00325 DEBUG_CHILD_OVERLAP
00326
00327 int index = findIndex(m_childRanges, child, child);
00328 if (index != -1) {
00329 m_childRanges.removeAt(index);
00330
00331
00332 for(int current = index-1; current >= 0; --current) {
00333 SmartRange& range(*m_childRanges[current]);
00334 Q_ASSERT(range.end() <= child->end());
00335 if(range.end() <= child->start()) {
00336 break;
00337 }else{
00338 if(range.m_overlapCount) {
00339 --range.m_overlapCount;
00340 } else {
00341
00342 #ifdef SHOULD_DEBUG_OVERLAP
00343 Q_ASSERT(0);
00344 #endif
00345 }
00346 }
00347 }
00348
00349 DEBUG_CHILD_OVERLAP
00350
00351 child->m_overlapCount = 0;
00352
00353 foreach (SmartRangeNotifier* n, m_notifiers)
00354 emit n->childRangeInserted(this, child);
00355
00356 foreach (SmartRangeWatcher* w, m_watchers)
00357 w->childRangeInserted(this, child);
00358 }
00359
00360 DEBUG_CHILD_OVERLAP
00361 }
00362
00363 SmartRange * SmartRange::mostSpecificRange( const Range & input ) const
00364 {
00365 if (!input.isValid())
00366 return 0L;
00367
00368 if (contains(input)) {
00369 int child = lowerBound(m_childRanges, input.start());
00370
00371 SmartRange* mostSpecific = 0;
00372
00373 while(child != m_childRanges.size()) {
00374 SmartRange* r = m_childRanges[child];
00375 if(r->contains(input)) {
00376 SmartRange* candidate = r->mostSpecificRange(input);
00377 if(mostSpecific == 0 ||
00378 ((candidate->end() - candidate->start()) < (mostSpecific->end() - mostSpecific->start())) ||
00379 (candidate->end() < mostSpecific->end()))
00380 mostSpecific = candidate;
00381 }
00382
00383 if(r->m_overlapCount == 0)
00384 break;
00385
00386 ++child;
00387 }
00388
00389 if(mostSpecific)
00390 return mostSpecific;
00391 else
00392 return const_cast<SmartRange*>(this);
00393
00394 } else if (parentRange()) {
00395 return parentRange()->mostSpecificRange(input);
00396
00397 } else {
00398 return 0L;
00399 }
00400 }
00401
00402 SmartRange * SmartRange::firstRangeContaining( const Cursor & pos ) const
00403 {
00404 if (!pos.isValid())
00405 return 0L;
00406
00407 if (contains(pos)) {
00408 if (parentRange() && parentRange()->contains(pos))
00409 return parentRange()->firstRangeContaining(pos);
00410
00411 return const_cast<SmartRange*>(this);
00412
00413 } else {
00414 if (!parentRange())
00415 return 0L;
00416
00417 return parentRange()->firstRangeContaining(pos);
00418 }
00419 }
00420
00421 int SmartRange::overlapCount() const
00422 {
00423 return m_overlapCount;
00424 }
00425
00426 QList<SmartRange*> SmartRange::deepestRangesContaining(const Cursor& pos) const
00427 {
00428 QList<SmartRange*> ret;
00429
00430 if(!contains(pos))
00431 return ret;
00432
00433 int child = lowerBound(m_childRanges, pos);
00434
00435 while(child != m_childRanges.size()) {
00436 SmartRange* r = m_childRanges[child];
00437
00438 ret += r->deepestRangesContaining(pos);
00439
00440 if(r->m_overlapCount == 0)
00441 break;
00442
00443 ++child;
00444 }
00445
00446 if(!ret.isEmpty())
00447 return ret;
00448 else
00449 return ret << const_cast<SmartRange*>(this);
00450 }
00451
00452 SmartRange * SmartRange::deepestRangeContaining( const Cursor & pos, QStack<SmartRange*>* rangesEntered, QStack<SmartRange*>* rangesExited ) const
00453 {
00454 if (!pos.isValid()) {
00455
00456 if (rangesExited) {
00457 SmartRange* range = const_cast<SmartRange*>(this);
00458 while (range) {
00459 rangesExited->append(range);
00460 range = range->parentRange();
00461 }
00462 }
00463 return 0L;
00464 }
00465
00466 return deepestRangeContainingInternal(pos, rangesEntered, rangesExited, true);
00467 }
00468
00469 SmartRange * SmartRange::deepestRangeContainingInternal( const Cursor & pos, QStack<SmartRange*>* rangesEntered, QStack<SmartRange*>* rangesExited, bool first ) const
00470 {
00471 if (contains(pos)) {
00472 if (!first && rangesEntered)
00473 rangesEntered->push(const_cast<SmartRange*>(this));
00474
00475 int child = lowerBound(m_childRanges, pos);
00476
00477 QStack<SmartRange*> mostSpecificStack;
00478 SmartRange* mostSpecific = 0;
00479
00480 while(child != m_childRanges.size()) {
00481 SmartRange* r = m_childRanges[child];
00482 if(r->contains(pos)) {
00483 QStack<SmartRange*> candidateStack;
00484 SmartRange* candidateRange = r->deepestRangeContainingInternal(pos, rangesEntered ? &candidateStack : 0, 0);
00485
00486 Q_ASSERT(!rangesEntered || !candidateStack.isEmpty());
00487 Q_ASSERT(candidateRange);
00488
00489 if(!mostSpecific ||
00490 ((candidateRange->end() - candidateRange->start()) < (mostSpecific->end() - mostSpecific->start())) ||
00491 (candidateRange->end() < mostSpecific->end())) {
00492 mostSpecific = candidateRange;
00493 mostSpecificStack = candidateStack;
00494 }
00495 }
00496
00497 if(r->m_overlapCount == 0)
00498 break;
00499
00500 ++child;
00501 }
00502
00503 if(mostSpecific) {
00504 if(rangesEntered)
00505 *rangesEntered += mostSpecificStack;
00506 return mostSpecific;
00507 }
00508
00509 return const_cast<SmartRange*>(this);
00510
00511 } else {
00512 if (rangesExited)
00513 rangesExited->push(const_cast<SmartRange*>(this));
00514
00515 if (!parentRange())
00516 return 0L;
00517
00518
00519 return parentRange()->deepestRangeContainingInternal(pos, rangesEntered, rangesExited, true);
00520 }
00521 }
00522
00523 Document* SmartRange::document( ) const
00524 {
00525 return smartStart().document();
00526 }
00527
00528 void SmartRange::associateAction( KAction * action )
00529 {
00530 m_associatedActions.append(action);
00531
00532 bool enable = false;
00533 if (View* v = document()->activeView())
00534 if (contains(v->cursorPosition()))
00535 enable = true;
00536
00537 action->setEnabled(enable);
00538
00539 if (m_associatedActions.count() == 1)
00540 checkFeedback();
00541 }
00542
00543 void SmartRange::dissociateAction( KAction * action )
00544 {
00545 m_associatedActions.removeAll(action);
00546 if (!m_associatedActions.count())
00547 checkFeedback();
00548 }
00549
00550 void SmartRange::clearAssociatedActions( )
00551 {
00552 m_associatedActions.clear();
00553 checkFeedback();
00554 }
00555
00556 SmartRange::InsertBehaviors SmartRange::insertBehavior( ) const
00557 {
00558 return ((smartStart().insertBehavior() == SmartCursor::MoveOnInsert) ? DoNotExpand : ExpandLeft) | ((smartEnd().insertBehavior() == SmartCursor::MoveOnInsert) ? ExpandRight : DoNotExpand);
00559 }
00560
00561 void SmartRange::setInsertBehavior(SmartRange::InsertBehaviors behavior)
00562 {
00563 static_cast<SmartCursor*>(m_start)->setInsertBehavior((behavior & ExpandLeft) ? SmartCursor::StayOnInsert : SmartCursor::MoveOnInsert);
00564 static_cast<SmartCursor*>(m_end)->setInsertBehavior((behavior & ExpandRight) ? SmartCursor::MoveOnInsert : SmartCursor::StayOnInsert);
00565 }
00566
00567 void SmartRange::clearChildRanges()
00568 {
00569 foreach (SmartRange* r, m_childRanges)
00570 r->removeText();
00571 }
00572
00573 void SmartRange::deleteChildRanges()
00574 {
00575
00576 qDeleteAll(m_childRanges);
00577
00578
00579 m_childRanges.clear();
00580 }
00581
00582 void SmartRange::clearAndDeleteChildRanges( )
00583 {
00584
00585 foreach (SmartRange* r, m_childRanges)
00586 r->removeText();
00587
00588 qDeleteAll(m_childRanges);
00589
00590
00591 m_childRanges.clear();
00592 }
00593
00594 void SmartRange::setParentRange( SmartRange * r )
00595 {
00596 if (m_parentRange == r)
00597 return;
00598
00599 DEBUG_PARENT_OVERLAP
00600
00601 if (m_parentRange)
00602 m_parentRange->removeChildRange(this);
00603
00604 SmartRange* oldParent = m_parentRange;
00605
00606 m_parentRange = r;
00607
00608 if (m_parentRange)
00609 m_parentRange->insertChildRange(this);
00610
00611 foreach (SmartRangeNotifier* n, m_notifiers)
00612 emit n->parentRangeChanged(this, m_parentRange, oldParent);
00613
00614 foreach (SmartRangeWatcher* w, m_watchers)
00615 w->parentRangeChanged(this, m_parentRange, oldParent);
00616
00617 DEBUG_PARENT_OVERLAP
00618 }
00619
00620 void SmartRange::setAttribute( Attribute::Ptr attribute )
00621 {
00622 if (attribute == m_attribute)
00623 return;
00624
00625 Attribute::Ptr prev = m_attribute;
00626
00627 m_attribute = attribute;
00628
00629 foreach (SmartRangeNotifier* n, m_notifiers)
00630 emit n->rangeAttributeChanged(this, attribute, prev);
00631
00632 foreach (SmartRangeWatcher* w, m_watchers)
00633 w->rangeAttributeChanged(this, attribute, prev);
00634 }
00635
00636 Attribute::Ptr SmartRange::attribute( ) const
00637 {
00638 return m_attribute;
00639 }
00640
00641 QStringList SmartRange::text( bool block ) const
00642 {
00643 return document()->textLines(*this, block);
00644 }
00645
00646 bool SmartRange::replaceText( const QStringList & text, bool block )
00647 {
00648 return document()->replaceText(*this, text, block);
00649 }
00650
00651 bool SmartRange::removeText( bool block )
00652 {
00653 return document()->removeText(*this, block);
00654 }
00655
00656 static bool rangeEndLessThan(const SmartRange* s1, const SmartRange* s2) {
00657 return s1->end() < s2->end();
00658 }
00659
00660 void SmartRange::rebuildChildStructure() {
00661
00663 qStableSort(m_childRanges.begin(), m_childRanges.end(), rangeEndLessThan);
00664 DEBUG_CHILD_ORDER
00666 for(int a = 0; a < m_childRanges.size(); ++a) {
00667 SmartRange& overlapper(*m_childRanges[a]);
00668 overlapper.m_overlapCount = 0;
00669
00670
00671 for(int current = a-1; current >= 0; --current) {
00672 SmartRange& range(*m_childRanges[current]);
00673 Q_ASSERT(range.end() <= overlapper.end());
00674
00675 if(range.end() > overlapper.start()) {
00676 ++range.m_overlapCount;
00677 }else{
00678
00679 break;
00680 }
00681 }
00682 }
00683
00684 DEBUG_CHILD_OVERLAP
00685 }
00686
00687 void SmartRange::rangeChanged( Cursor* c, const Range& from )
00688 {
00689 #ifdef SHOULD_DEBUG_CHILD_ORDER
00690 if (parentRange() ) {
00691
00692 QList<SmartRange*>& parentChildren(parentRange()->m_childRanges);
00693
00694 int index = findIndex(parentChildren, this, &from);
00695 Q_ASSERT(index != -1);
00696 Q_ASSERT(parentChildren[index] == this);
00697 const Range* lastRange = 0;
00698 for(int a = 0; a < index; ++a) {
00699 if(lastRange) {
00700 Q_ASSERT(lastRange->end() <= parentChildren[a]->end());
00701 }
00702 lastRange = parentChildren[a];
00703 }
00704
00705 if(lastRange) {
00706 Q_ASSERT(lastRange->end() <= from.end());
00707 }
00708
00709 if(index+1 < parentChildren.size()) {
00710 Q_ASSERT(from.end() <= parentChildren[index+1]->end());
00711 }
00712 lastRange = &from;
00713
00714 for(int a = index+1; a < parentChildren.size(); ++a) {
00715 if(lastRange) {
00716 Q_ASSERT(lastRange->end() <= parentChildren[a]->end());
00717 }
00718 lastRange = parentChildren[a];
00719 }
00720 }
00721 #endif
00722 Range::rangeChanged(c, from);
00723
00724
00725 if (parentRange() ) {
00726 QList<SmartRange*>& parentChildren(parentRange()->m_childRanges);
00727
00728 int index = findIndex(parentChildren, this, &from);
00729 Q_ASSERT(index != -1);
00730 Q_ASSERT(parentChildren[index] == this);
00731
00732
00733 for(int current = index-1; current >= 0; --current) {
00734 SmartRange& range(*parentChildren[current]);
00735 Q_ASSERT(range.end() <= from.end());
00736 if(range.end() <= from.start()) {
00737
00738 }else{
00739 if(range.m_overlapCount) {
00740 --range.m_overlapCount;
00741 }else{
00742 #ifdef SHOULD_DEBUG_OVERLAP
00743 Q_ASSERT(0);
00744 #endif
00745 }
00746 }
00747 }
00748
00749
00750 for(int current = index+1; current < parentChildren.size(); ++current) {
00751 SmartRange& range(*parentChildren[current]);
00752 Q_ASSERT(range.end() >= from.end());
00753
00754 if(range.start() < from.end())
00755 --m_overlapCount;
00756
00757 if(!range.m_overlapCount)
00758 break;
00759 }
00760
00761 if(from.end() != end()) {
00762
00763 if(from.end() > end()) {
00764
00765 while(index > 0 && parentChildren[index-1]->end() > end()) {
00766 parentChildren[index] = parentChildren[index-1];
00767 parentChildren[index-1] = this;
00768 --index;
00769 }
00770 }else{
00771
00772 while( index+1 < parentChildren.size() && (parentChildren[index+1]->end() < end()) ) {
00773 parentChildren[index] = parentChildren[index+1];
00774 parentChildren[index+1] = this;
00775 ++index;
00776 }
00777 }
00778 }
00779 Q_ASSERT(parentChildren[index] == this);
00780
00781
00782 for(int current = index-1; current >= 0; --current) {
00783 SmartRange& range(*parentChildren[current]);
00784 Q_ASSERT(range.end() <= end());
00785
00786 if(range.end() > start()) {
00787 ++range.m_overlapCount;
00788 }else{
00789
00790 break;
00791 }
00792 }
00793
00794
00795 for(int current = index+1; current < parentChildren.size(); ++current) {
00796 SmartRange& range(*parentChildren[current]);
00797 Q_ASSERT(range.end() >= end());
00798
00799 if(range.start() < end())
00800 ++m_overlapCount;
00801
00802 if(!range.m_overlapCount)
00803 break;
00804 }
00805
00806 DEBUG_CHILD_ORDER
00807 DEBUG_PARENT_OVERLAP
00808
00809
00810 if ((start() < from.start() || end() > from.end()))
00811 parentRange()->expandToRange(*this);
00812 }
00813
00814 DEBUG_CHILD_OVERLAP
00815
00816
00817
00818 if(!m_childRanges.isEmpty()) {
00819 if (start() > from.start()) {
00820 foreach(SmartRange* child, m_childRanges) {
00821 if(child->start() < start())
00822 child->start() = start();
00823 else if(!child->m_overlapCount)
00824 break;
00825 }
00826 }
00827
00828 if (end() < from.end()) {
00829
00830
00831 QList<SmartRange*> oldChildRanges = m_childRanges;
00832
00833 for(int a = oldChildRanges.size()-1; a >= 0; --a) {
00834 if(oldChildRanges[a]->end() <= end())
00835 break;
00836 oldChildRanges[a]->end() = end();
00837 }
00838 }
00839 }
00840
00841 DEBUG_CHILD_ORDER
00842 DEBUG_CHILD_OVERLAP
00843
00844
00845
00846 foreach (SmartRangeNotifier* n, m_notifiers)
00847 if (n->wantsDirectChanges()) {
00848 emit n->rangePositionChanged(this);
00849 emit n->rangeContentsChanged(this);
00850
00851 if (start() == end())
00852 emit n->rangeEliminated(this);
00853 }
00854
00855 foreach (SmartRangeWatcher* w, m_watchers)
00856 if (w->wantsDirectChanges()) {
00857 w->rangePositionChanged(this);
00858 w->rangeContentsChanged(this);
00859
00860 if (start() == end())
00861 w->rangeEliminated(this);
00862 }
00863 }
00864
00865 bool SmartRange::isSmartRange( ) const
00866 {
00867 return true;
00868 }
00869
00870 SmartRange* SmartRange::toSmartRange( ) const
00871 {
00872 return const_cast<SmartRange*>(this);
00873 }
00874
00875 bool SmartRange::hasParent( SmartRange * parent ) const
00876 {
00877 if (parentRange() == parent)
00878 return true;
00879
00880 if (parentRange())
00881 return parentRange()->hasParent(parent);
00882
00883 return false;
00884 }
00885
00886 const QList< SmartRangeWatcher * > & SmartRange::watchers( ) const
00887 {
00888 return m_watchers;
00889 }
00890
00891 void SmartRange::addWatcher( SmartRangeWatcher * watcher )
00892 {
00893 if (!m_watchers.contains(watcher))
00894 m_watchers.append(watcher);
00895
00896 checkFeedback();
00897 }
00898
00899 void SmartRange::removeWatcher( SmartRangeWatcher * watcher )
00900 {
00901 m_watchers.removeAll(watcher);
00902 checkFeedback();
00903 }
00904
00905 SmartRangeNotifier * SmartRange::primaryNotifier( )
00906 {
00907 if (m_notifiers.isEmpty())
00908 m_notifiers.append(createNotifier());
00909
00910 return m_notifiers.first();
00911 }
00912
00913 const QList< SmartRangeNotifier * > SmartRange::notifiers( ) const
00914 {
00915 return m_notifiers;
00916 }
00917
00918 void SmartRange::addNotifier( SmartRangeNotifier * notifier )
00919 {
00920 if (!m_notifiers.contains(notifier))
00921 m_notifiers.append(notifier);
00922
00923 checkFeedback();
00924 }
00925
00926 void SmartRange::removeNotifier( SmartRangeNotifier * notifier )
00927 {
00928 m_notifiers.removeAll(notifier);
00929 checkFeedback();
00930 }
00931
00932 void SmartRange::deletePrimaryNotifier( )
00933 {
00934 if (m_notifiers.isEmpty())
00935 return;
00936
00937 SmartRangeNotifier* n = m_notifiers.first();
00938 removeNotifier(n);
00939 delete n;
00940 }
00941
00942 void SmartRange::checkFeedback( )
00943 {
00944 }
00945
00946