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