1 #include "latexstructure.h"
2 #include "latexdocument.h"
3
4
StructureEntry(LatexDocument * doc,Type newType)5 StructureEntry::StructureEntry(LatexDocument *doc, Type newType): type(newType), level(0), valid(false), expanded(false), parent(nullptr), document(doc), columnNumber(0), parentRow(-1), lineHandle(nullptr), lineNumber(-1), m_contexts(Unknown)
6 {
7 #ifndef QT_NO_DEBUG
8 Q_ASSERT(document);
9 document->StructureContent.insert(this);
10 #endif
11 }
12
~StructureEntry()13 StructureEntry::~StructureEntry()
14 {
15 level = -1; //invalidate entry
16 foreach (StructureEntry *se, children)
17 delete se;
18 #ifndef QT_NO_DEBUG
19 Q_ASSERT(document);
20 bool removed = document->StructureContent.remove(this);
21 Q_ASSERT(removed); //prevent double deletion
22 #endif
23 }
24
add(StructureEntry * child)25 void StructureEntry::add(StructureEntry *child)
26 {
27 Q_ASSERT(child != nullptr);
28 children.append(child);
29 child->parent = this;
30 }
31
insert(int pos,StructureEntry * child)32 void StructureEntry::insert(int pos, StructureEntry *child)
33 {
34 Q_ASSERT(child != nullptr);
35 children.insert(pos, child);
36 child->parent = this;
37 }
38
setLine(QDocumentLineHandle * handle,int lineNr)39 void StructureEntry::setLine(QDocumentLineHandle *handle, int lineNr)
40 {
41 lineHandle = handle;
42 lineNumber = lineNr;
43 }
44
getLineHandle() const45 QDocumentLineHandle *StructureEntry::getLineHandle() const
46 {
47 return lineHandle;
48 }
49
getCachedLineNumber() const50 int StructureEntry::getCachedLineNumber() const
51 {
52 return lineNumber;
53 }
54
getRealLineNumber() const55 int StructureEntry::getRealLineNumber() const
56 {
57 lineNumber = document->indexOf(lineHandle, lineNumber);
58 Q_ASSERT(lineNumber == -1 || document->line(lineNumber).handle() == lineHandle);
59 return lineNumber;
60 }
61
hintedIndexOf(const QList<T * > & list,const T * elem,int hint)62 template <typename T> inline int hintedIndexOf (const QList<T *> &list, const T *elem, int hint)
63 {
64 if (hint < 2) return list.indexOf(const_cast<T *>(elem));
65 int backward = hint, forward = hint + 1;
66 for (; backward >= 0 && forward < list.size();
67 backward--, forward++) {
68 if (list[backward] == elem) return backward;
69 if (list[forward] == elem) return forward;
70 }
71 if (backward >= list.size()) backward = list.size() - 1;
72 for (; backward >= 0; backward--)
73 if (list[backward] == elem) return backward;
74 if (forward < 0) forward = 0;
75 for (; forward < list.size(); forward++)
76 if (list[forward] == elem) return forward;
77 return -1;
78 }
79
getRealParentRow() const80 int StructureEntry::getRealParentRow() const
81 {
82 REQUIRE_RET(parent, -1);
83 parentRow = hintedIndexOf<StructureEntry>(parent->children, this, parentRow);
84 return parentRow;
85 }
86
debugPrint(const char * message) const87 void StructureEntry::debugPrint(const char *message) const
88 {
89 qDebug("%s %p", message, this);
90 qDebug()<<" level: "<< level;
91 qDebug()<<" type: "<< static_cast<int>(type);
92 qDebug()<<" line nr: "<< lineNumber;
93 qDebug()<<" title: " << title;
94 }
95
StructureEntryIterator(StructureEntry * entry)96 StructureEntryIterator::StructureEntryIterator(StructureEntry *entry)
97 {
98 if (!entry) return;
99 while (entry->parent) {
100 entryHierarchy.prepend(entry);
101 indexHierarchy.prepend(entry->getRealParentRow());
102 entry = entry->parent;
103 }
104 entryHierarchy.prepend(entry);
105 indexHierarchy.prepend(0);
106 }
107
hasNext()108 bool StructureEntryIterator::hasNext()
109 {
110 return !entryHierarchy.isEmpty();
111 }
112
next()113 StructureEntry *StructureEntryIterator::next()
114 {
115 if (!hasNext()) return nullptr;
116 StructureEntry *result = entryHierarchy.last();
117 if (!result->children.isEmpty()) { //first child is next element, go a level deeper
118 entryHierarchy.append(result->children.at(0));
119 indexHierarchy.append(0);
120 } else { //no child, go to next on same level
121 entryHierarchy.removeLast();
122 indexHierarchy.last()++;
123 while (!entryHierarchy.isEmpty() && indexHierarchy.last() >= entryHierarchy.last()->children.size()) {
124 //doesn't exists, proceed to travel upwards
125 entryHierarchy.removeLast();
126 indexHierarchy.removeLast();
127 indexHierarchy.last()++;
128 }
129 if (!entryHierarchy.isEmpty())
130 entryHierarchy.append(entryHierarchy.last()->children.at(indexHierarchy.last()));
131 }
132 return result;
133 }
134
135
136
137
138