]> git.lyx.org Git - lyx.git/blob - src/frontends/qt2/QToc.C
reverse last change
[lyx.git] / src / frontends / qt2 / QToc.C
1 /**
2  * \file QToc.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author John Levon
7  *
8  * Full author contact details are available in file CREDITS
9  */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include <stack>
18
19 #include "LyXView.h"
20 #include "qt_helpers.h"
21 #include "support/lstrings.h"
22 #include "debug.h"
23
24 #include "ControlToc.h"
25 #include "QToc.h"
26 #include "QTocDialog.h"
27 #include "Qt2BC.h"
28
29 #include <qslider.h>
30 #include <qlistview.h>
31 #include <qpushbutton.h>
32 #include <qcombobox.h>
33
34 using std::endl;
35 using std::pair;
36 using std::stack;
37 using std::vector;
38
39 typedef Qt2CB<ControlToc, Qt2DB<QTocDialog> > base_class;
40
41 QToc::QToc()
42         : base_class(qt_("Table of contents")), depth_(1)
43 {}
44
45
46 void QToc::build_dialog()
47 {
48         dialog_.reset(new QTocDialog(this));
49
50         // Manage the cancel/close button
51         bc().setCancel(dialog_->closePB);
52 }
53
54
55 void QToc::updateType()
56 {
57         dialog_->typeCO->clear();
58
59         vector<string> const & choice = controller().getTypes();
60         string const & type = toc::getType(controller().params().getCmdName());
61
62         for (vector<string>::const_iterator it = choice.begin();
63                 it != choice.end(); ++it) {
64                 dialog_->typeCO->insertItem(toqstr(*it));
65                 if (*it == type) {
66                         dialog_->typeCO->setCurrentItem(it - choice.begin());
67                         dialog_->setCaption(toqstr(type));
68                 }
69         }
70 }
71
72
73 void QToc::update_contents()
74 {
75         updateType();
76         updateToc(depth_);
77 }
78
79
80 void QToc::updateToc(int newdepth)
81 {
82         string type = fromqstr(dialog_->typeCO->currentText());
83
84         toc::Toc const & contents = controller().getContents(type);
85
86         // Check if all elements are the same.
87         if (newdepth == depth_ && toclist == contents) {
88                 return;
89         }
90
91         dialog_->tocLV->clear();
92
93         depth_ = newdepth;
94
95         toclist = contents;
96
97         if (toclist.empty())
98                 return;
99
100         dialog_->tocLV->setUpdatesEnabled(false);
101
102         int curdepth = 0;
103         stack<pair<QListViewItem *, QListViewItem *> > istack;
104         QListViewItem * last = 0;
105         QListViewItem * parent = 0;
106         QListViewItem * item;
107
108         // Yes, it is this ugly. Two reasons - root items must have
109         // a QListView parent, rather than QListViewItem; and the
110         // TOC can move in and out an arbitrary number of levels
111
112         for (toc::Toc::const_iterator iter = toclist.begin();
113              iter != toclist.end(); ++iter) {
114                 if (iter->depth == curdepth) {
115                         // insert it after the last one we processed
116                         if (!parent)
117                                 item = (last ? new QListViewItem(dialog_->tocLV,last) : new QListViewItem(dialog_->tocLV));
118                         else
119                                 item = (last ? new QListViewItem(parent,last) : new QListViewItem(parent));
120                 } else if (iter->depth > curdepth) {
121                         int diff = iter->depth - curdepth;
122                         // first save old parent and last
123                         while (diff--)
124                                 istack.push(pair< QListViewItem *, QListViewItem * >(parent,last));
125                         item = (last ? new QListViewItem(last) : new QListViewItem(dialog_->tocLV));
126                         parent = last;
127                 } else {
128                         int diff = curdepth - iter->depth;
129                         pair<QListViewItem *, QListViewItem * > top;
130                         // restore context
131                         while (diff--) {
132                                 top = istack.top();
133                                 istack.pop();
134                         }
135                         parent = top.first;
136                         last = top.second;
137                         // insert it after the last one we processed
138                         if (!parent)
139                                 item = (last ? new QListViewItem(dialog_->tocLV,last) : new QListViewItem(dialog_->tocLV));
140                         else
141                                 item = (last ? new QListViewItem(parent,last) : new QListViewItem(parent));
142                 }
143
144                 lyxerr[Debug::GUI]
145                         << "Table of contents\n"
146                         << "Added item " << iter->str
147                         << " at depth " << iter->depth
148                         << ", previous sibling \""
149                         << (last ? fromqstr(last->text(0)) : "0")
150                         << "\", parent \""
151                         << (parent ? fromqstr(parent->text(0)) : "0") << '"'
152                         << endl;
153                 item->setText(0, toqstr(iter->str));
154                 item->setOpen(iter->depth < depth_);
155                 curdepth = iter->depth;
156                 last = item;
157         }
158
159         dialog_->tocLV->setUpdatesEnabled(true);
160         dialog_->tocLV->update();
161 }
162
163
164 void QToc::select(string const & text)
165 {
166         toc::Toc::const_iterator iter = toclist.begin();
167
168         for (; iter != toclist.end(); ++iter) {
169                 if (iter->str == text)
170                         break;
171         }
172
173         if (iter == toclist.end()) {
174                 lyxerr[Debug::GUI] << "Couldn't find highlighted TOC entry: "
175                         << text << endl;
176                 return;
177         }
178
179         controller().goTo(*iter);
180 }
181
182
183 void QToc::set_depth(int depth)
184 {
185         if (depth != depth_)
186                 updateToc(depth);
187 }