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