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