22 #include <QtCore/QStack>
32 using namespace KTextEditor;
45 #ifdef SHOULD_DEBUG_CHILD_ORDER
46 #define DEBUG_CHILD_ORDER \
48 KTextEditor::Cursor lastEnd = KTextEditor::Cursor(-1,-1);\
49 for(int a = 0; a < m_childRanges.size(); ++a) {\
50 Q_ASSERT(m_childRanges[a]->end() >= lastEnd);\
51 Q_ASSERT(m_childRanges[a]->start() >= start());\
52 Q_ASSERT(m_childRanges[a]->end() <= end());\
53 lastEnd = m_childRanges[a]->end();\
58 #define DEBUG_CHILD_ORDER
61 #ifdef SHOULD_DEBUG_OVERLAP
62 #define DEBUG_CHILD_OVERLAP \
64 QVector<int> counter(m_childRanges.size(), 0);\
66 for(int a = 0; a < m_childRanges.size(); ++a) {\
67 const SmartRange& overlapper(*m_childRanges[a]);\
68 for(int b = 0; b < a; ++b) {\
69 const SmartRange& overlapped(*m_childRanges[b]);\
70 Q_ASSERT(overlapped.end() <= overlapper.end());\
71 if(overlapped.end() > overlapper.start()) {\
76 for(int a = 0; a < m_childRanges.size(); ++a) {\
77 Q_ASSERT(m_childRanges[a]->m_overlapCount == counter[a]);\
81 #define DEBUG_PARENT_OVERLAP \
83 QVector<int> counter(m_parentRange->m_childRanges.size(), 0);\
85 for(int a = 0; a < m_parentRange->m_childRanges.size(); ++a) {\
86 const SmartRange& overlapper(*m_parentRange->m_childRanges[a]);\
87 for(int b = 0; b < a; ++b) {\
88 const SmartRange& overlapped(*m_parentRange->m_childRanges[b]);\
89 Q_ASSERT(overlapped.end() <= overlapper.end());\
90 if(overlapped.end() > overlapper.start()) {\
95 for(int a = 0; a < m_parentRange->m_childRanges.size(); ++a) {\
96 Q_ASSERT(m_parentRange->m_childRanges[a]->m_overlapCount == counter[a]);\
101 #define DEBUG_CHILD_OVERLAP
102 #define DEBUG_PARENT_OVERLAP
110 int n = ranges.count();
117 middle = begin + half;
118 if(ranges[middle]->
end() > pos) {
133 int n = ranges.count();
140 middle = begin + half;
141 if(ranges[begin] == range)
143 if(ranges[middle] == range)
146 if(ranges[middle]->
end() > pos) {
159 int childCount = ranges.count();
162 while(index < childCount && ranges[index] != smartRange)
165 if(index == childCount) {
167 return ranges.indexOf(const_cast<SmartRange*>(smartRange));
181 , m_parentRange(parent)
182 , m_ownsAttribute(false)
191 m_parentRange->insertChildRange(
this);
246 return m_childRanges;
251 int index =
findIndex(m_childRanges, range, range);
254 return m_childRanges[index];
261 int index =
findIndex(m_childRanges, range, range);
262 if (index != -1 && ++index < m_childRanges.count())
263 return m_childRanges[index];
267 void SmartRange::insertChildRange(
SmartRange * newChild )
279 m_childRanges.insert(insertAt, newChild);
282 for(
int current = insertAt-1; current >= 0; --current) {
284 Q_ASSERT(range.end() <= newChild->
end());
286 if(range.end() > newChild->
start()) {
287 ++range.m_overlapCount;
295 for(
int current = insertAt+1; current < m_childRanges.size(); ++current) {
297 Q_ASSERT(range.end() >= newChild->
end());
299 if(range.start() < newChild->
end())
300 ++newChild->m_overlapCount;
302 if(!range.m_overlapCount)
310 QMutableListIterator<SmartRange*> it = m_childRanges;
323 void SmartRange::removeChildRange(
SmartRange* child)
327 int index =
findIndex(m_childRanges, child, child);
329 m_childRanges.removeAt(index);
332 for(
int current = index-1; current >= 0; --current) {
334 Q_ASSERT(range.end() <= child->
end());
335 if(range.end() <= child->
start()) {
338 if(range.m_overlapCount) {
339 --range.m_overlapCount;
342 #ifdef SHOULD_DEBUG_OVERLAP
351 child->m_overlapCount = 0;
373 while(child != m_childRanges.size()) {
377 if(mostSpecific == 0 ||
378 ((candidate->
end() - candidate->
start()) < (mostSpecific->end() - mostSpecific->start())) ||
379 (candidate->
end() < mostSpecific->end()))
380 mostSpecific = candidate;
383 if(r->m_overlapCount == 0)
423 return m_overlapCount;
428 QList<SmartRange*> ret;
435 while(child != m_childRanges.size()) {
440 if(r->m_overlapCount == 0)
449 return ret << const_cast<SmartRange*>(
this);
459 rangesExited->append(range);
466 return deepestRangeContainingInternal(pos, rangesEntered, rangesExited,
true);
469 SmartRange * SmartRange::deepestRangeContainingInternal(
const Cursor & pos, QStack<SmartRange*>* rangesEntered, QStack<SmartRange*>* rangesExited,
bool first )
const
472 if (!first && rangesEntered)
473 rangesEntered->push(const_cast<SmartRange*>(
this));
477 QStack<SmartRange*> mostSpecificStack;
480 while(child != m_childRanges.size()) {
483 QStack<SmartRange*> candidateStack;
484 SmartRange* candidateRange = r->deepestRangeContainingInternal(pos, rangesEntered ? &candidateStack : 0, 0);
486 Q_ASSERT(!rangesEntered || !candidateStack.isEmpty());
487 Q_ASSERT(candidateRange);
490 ((candidateRange->
end() - candidateRange->
start()) < (mostSpecific->
end() - mostSpecific->
start())) ||
491 (candidateRange->
end() < mostSpecific->
end())) {
492 mostSpecific = candidateRange;
493 mostSpecificStack = candidateStack;
497 if(r->m_overlapCount == 0)
505 *rangesEntered += mostSpecificStack;
513 rangesExited->push(const_cast<SmartRange*>(
this));
519 return parentRange()->deepestRangeContainingInternal(pos, rangesEntered, rangesExited,
true);
530 m_associatedActions.append(action);
537 action->setEnabled(enable);
539 if (m_associatedActions.count() == 1)
545 m_associatedActions.removeAll(action);
546 if (!m_associatedActions.count())
552 m_associatedActions.clear();
576 qDeleteAll(m_childRanges);
579 m_childRanges.clear();
588 qDeleteAll(m_childRanges);
591 m_childRanges.clear();
596 if (m_parentRange == r)
602 m_parentRange->removeChildRange(
this);
609 m_parentRange->insertChildRange(
this);
622 if (attribute == m_attribute)
657 return s1->
end() < s2->
end();
666 for(
int a = 0; a < m_childRanges.size(); ++a) {
668 overlapper.m_overlapCount = 0;
671 for(
int current = a-1; current >= 0; --current) {
673 Q_ASSERT(range.
end() <= overlapper.
end());
675 if(range.
end() > overlapper.
start()) {
676 ++range.m_overlapCount;
689 #ifdef SHOULD_DEBUG_CHILD_ORDER
692 QList<SmartRange*>& parentChildren(
parentRange()->m_childRanges);
694 int index =
findIndex(parentChildren,
this, &from);
695 Q_ASSERT(index != -1);
696 Q_ASSERT(parentChildren[index] ==
this);
697 const Range* lastRange = 0;
698 for(
int a = 0; a < index; ++a) {
700 Q_ASSERT(lastRange->
end() <= parentChildren[a]->end());
702 lastRange = parentChildren[a];
706 Q_ASSERT(lastRange->
end() <= from.
end());
709 if(index+1 < parentChildren.size()) {
710 Q_ASSERT(from.
end() <= parentChildren[index+1]->end());
714 for(
int a = index+1; a < parentChildren.size(); ++a) {
716 Q_ASSERT(lastRange->
end() <= parentChildren[a]->end());
718 lastRange = parentChildren[a];
726 QList<SmartRange*>& parentChildren(
parentRange()->m_childRanges);
728 int index =
findIndex(parentChildren,
this, &from);
729 Q_ASSERT(index != -1);
730 Q_ASSERT(parentChildren[index] ==
this);
733 for(
int current = index-1; current >= 0; --current) {
735 Q_ASSERT(range.
end() <= from.
end());
739 if(range.m_overlapCount) {
740 --range.m_overlapCount;
742 #ifdef SHOULD_DEBUG_OVERLAP
750 for(
int current = index+1; current < parentChildren.size(); ++current) {
752 Q_ASSERT(range.
end() >= from.
end());
757 if(!range.m_overlapCount)
765 while(index > 0 && parentChildren[index-1]->
end() >
end()) {
766 parentChildren[index] = parentChildren[index-1];
767 parentChildren[index-1] =
this;
772 while( index+1 < parentChildren.size() && (parentChildren[index+1]->end() <
end()) ) {
773 parentChildren[index] = parentChildren[index+1];
774 parentChildren[index+1] =
this;
779 Q_ASSERT(parentChildren[index] ==
this);
782 for(
int current = index-1; current >= 0; --current) {
784 Q_ASSERT(range.
end() <=
end());
787 ++range.m_overlapCount;
795 for(
int current = index+1; current < parentChildren.size(); ++current) {
797 Q_ASSERT(range.
end() >=
end());
802 if(!range.m_overlapCount)
818 if(!m_childRanges.isEmpty()) {
823 else if(!child->m_overlapCount)
831 QList<SmartRange*> oldChildRanges = m_childRanges;
833 for(
int a = oldChildRanges.size()-1; a >= 0; --a) {
834 if(oldChildRanges[a]->
end() <=
end())
836 oldChildRanges[a]->end() =
end();
893 if (!m_watchers.contains(watcher))
894 m_watchers.append(watcher);
901 m_watchers.removeAll(watcher);
907 if (m_notifiers.isEmpty())
910 return m_notifiers.first();
920 if (!m_notifiers.contains(notifier))
921 m_notifiers.append(notifier);
928 m_notifiers.removeAll(notifier);
934 if (m_notifiers.isEmpty())