]> git.lyx.org Git - lyx.git/blob - src/frontends/kde/FormToc.C
small cleanup, doxygen, formatting changes
[lyx.git] / src / frontends / kde / FormToc.C
1 /**
2  * \file FormToc.C
3  * Copyright 2001 the LyX Team
4  * Read the file COPYING
5  *
6  * \author John Levon
7  */
8
9 #include <config.h>
10
11 #include <stack>
12
13 #include "tocdlg.h"
14
15 #include "Dialogs.h"
16 #include "FormToc.h"
17 #include "gettext.h"
18 #include "buffer.h"
19 #include "support/lstrings.h"
20 #include "QtLyXView.h"
21 #include "lyxfunc.h"
22 #include "debug.h"
23
24 using std::vector;
25 using std::pair;
26 using std::stack;
27 using std::endl;
28  
29 // FIXME: we should be able to move sections around like klyx1 can
30
31 FormToc::FormToc(LyXView *v, Dialogs *d)
32         : dialog_(0), lv_(v), d_(d), inset_(0), h_(0), u_(0), ih_(0),
33         toclist(0), type(Buffer::TOC_TOC), depth(1)
34 {
35         // let the dialog be shown
36         // This is a permanent connection so we won't bother
37         // storing a copy because we won't be disconnecting.
38         d->showTOC.connect(slot(this, &FormToc::showTOC));
39         d->createTOC.connect(slot(this, &FormToc::createTOC));
40 }
41
42
43 FormToc::~FormToc()
44 {
45         delete dialog_;
46 }
47
48
49 void FormToc::showTOC(InsetCommand * const inset)
50 {
51         // FIXME: when could inset be 0 here ?
52         if (inset == 0)
53                 return;
54
55         inset_ = inset;
56         ih_ = inset_->hide.connect(slot(this,&FormToc::hide));
57         params = inset->params();
58         
59         show();
60 }
61
62
63 void FormToc::createTOC(string const & arg)
64 {
65         if (inset_)
66                 close();
67
68         params.setFromString(arg);
69         show();
70 }
71
72
73 void FormToc::updateToc(int newdepth)
74 {
75         if (!lv_->view()->available()) {
76                 toclist.clear();
77                 dialog_->tree->clear();
78                 return;
79         }
80
81         vector< vector<Buffer::TocItem> > tmp =
82                 lv_->view()->buffer()->getTocList();
83
84         // Check if all elements are the same.
85         if (newdepth == depth && toclist.size() == tmp[type].size()) {
86                 unsigned int i = 0;
87                 for (; i < toclist.size(); ++i) {
88                         if (toclist[i] !=  tmp[type][i])
89                                 break;
90                 }
91                 if (i >= toclist.size())
92                         return;
93         }
94
95         depth=newdepth;
96
97         toclist = tmp[type];
98
99         dialog_->tree->clear();
100         if (toclist.empty()) 
101                 return;
102
103         dialog_->tree->setUpdatesEnabled(false);
104
105         int curdepth = 0;
106         stack< pair< QListViewItem *, QListViewItem *> > istack;
107         QListViewItem * last = 0;
108         QListViewItem * parent = 0;
109         QListViewItem * item;
110
111         // Yes, it is this ugly. Two reasons - root items must have a QListView parent,
112         // rather than QListViewItem; and the TOC can move in and out an arbitrary number
113         // of levels
114
115         for (vector< Buffer::TocItem >::const_iterator iter = toclist.begin();
116                 iter != toclist.end(); ++iter) {
117                 if (iter->depth == curdepth) {
118                         // insert it after the last one we processed
119                         if (!parent)
120                                 item = (last) ? (new QListViewItem(dialog_->tree,last)) : (new QListViewItem(dialog_->tree));
121                         else
122                                 item = (last) ? (new QListViewItem(parent,last)) : (new QListViewItem(parent));
123                 } else if (iter->depth > curdepth) {
124                         int diff = iter->depth - curdepth;
125                         // first save old parent and last
126                         while (diff--)
127                                 istack.push(pair< QListViewItem *, QListViewItem * >(parent,last));
128                         item = (last) ? (new QListViewItem(last)) : (new QListViewItem(dialog_->tree));
129                         parent = last;
130                 } else {
131                         int diff = curdepth - iter->depth;
132                         pair< QListViewItem *, QListViewItem * > top;
133                         // restore context
134                         while (diff--) {
135                                 top = istack.top();
136                                 istack.pop();
137                         }
138                         parent = top.first;
139                         last = top.second;
140                         // insert it after the last one we processed
141                         if (!parent)
142                                 item = (last) ? (new QListViewItem(dialog_->tree,last)) : (new QListViewItem(dialog_->tree));
143                         else
144                                 item = (last) ? (new QListViewItem(parent,last)) : (new QListViewItem(parent));
145                 }
146                 lyxerr[Debug::GUI] << "Table of contents" << endl << "Added item " << iter->str.c_str()
147                         << " at depth " << iter->depth << ", previous sibling \"" << (last ? last->text(0) : "0")
148                         << "\", parent \"" << (parent ? parent->text(0) : "0") << "\"" << endl;
149                 item->setText(0,iter->str.c_str());
150                 item->setOpen(iter->depth < depth);
151                 curdepth = iter->depth;
152                 last = item;
153         }
154
155         dialog_->tree->setUpdatesEnabled(true);
156         dialog_->tree->update();
157 }
158
159
160 void FormToc::setType(Buffer::TocType toctype)
161 {
162         type = toctype;
163         switch (type) {
164                 case Buffer::TOC_TOC:
165                         dialog_->setCaption(_("Table of Contents"));
166                         dialog_->tree->setColumnText(0,_("Table of Contents"));
167                         dialog_->depth->setEnabled(true);
168                         break;
169                 case Buffer::TOC_LOF:
170                         dialog_->setCaption(_("List of Figures"));
171                         dialog_->tree->setColumnText(0,_("List of Figures"));
172                         dialog_->depth->setEnabled(false);
173                         break;
174                 case Buffer::TOC_LOT:
175                         dialog_->setCaption(_("List of Tables"));
176                         dialog_->tree->setColumnText(0,_("List of Tables"));
177                         dialog_->depth->setEnabled(false);
178                         break;
179                 case Buffer::TOC_LOA:
180                         dialog_->setCaption(_("List of Algorithms"));
181                         dialog_->tree->setColumnText(0,_("List of Algorithms"));
182                         dialog_->depth->setEnabled(false);
183                         break;
184         }
185 }
186
187
188 void FormToc::set_depth(int newdepth)
189 {
190         if (newdepth != depth)
191                 updateToc(newdepth);
192 }
193
194
195 // we can safely ignore the parameter because we can always update
196 void FormToc::update(bool)
197 {
198         if (params.getCmdName() == "tableofcontents") {
199                 setType(Buffer::TOC_TOC);
200                 dialog_->menu->setCurrentItem(0);
201         } else if (params.getCmdName() == "listoffigures") {
202                 setType(Buffer::TOC_LOF);
203                 dialog_->menu->setCurrentItem(1);
204         } else if (params.getCmdName() == "listoftables") {
205                 setType(Buffer::TOC_LOT);
206                 dialog_->menu->setCurrentItem(2);
207         } else {
208                 setType(Buffer::TOC_LOA);
209                 dialog_->menu->setCurrentItem(3);
210         }
211
212         updateToc(depth);
213 }
214
215
216 void FormToc::select(char const * text)
217 {
218         if (!lv_->view()->available())
219                 return;
220
221         vector <Buffer::TocItem>::const_iterator iter = toclist.begin();
222         for (; iter != toclist.end(); ++iter) {
223                 if (iter->str == text)
224                         break;
225         }
226         
227         if (iter == toclist.end()) {
228                 lyxerr[Debug::GUI] << "Couldn't find highlighted TOC entry : " << text << endl;
229                 return;
230         }
231
232         lv_->getLyXFunc()->Dispatch(LFUN_GOTO_PARAGRAPH, tostr(iter->par->id()).c_str());
233 }
234
235
236 void FormToc::set_type(Buffer::TocType toctype)
237 {
238         if (toctype == type)
239                 return;
240
241         setType(toctype);
242         updateToc(depth);
243 }
244
245
246 void FormToc::show()
247 {
248         if (!dialog_)
249                 dialog_ = new TocDialog(this, 0, _("LyX: Table of Contents"), false);
250
251         if (!dialog_->isVisible()) {
252                 h_ = d_->hideBufferDependent.connect(slot(this, &FormToc::hide));
253                 u_ = d_->updateBufferDependent.connect(slot(this, &FormToc::update));
254         }
255
256         dialog_->raise();
257         dialog_->setActiveWindow();
258
259         update();
260         dialog_->show();
261 }
262
263
264 void FormToc::close()
265 {
266         h_.disconnect();
267         u_.disconnect();
268         ih_.disconnect();
269         inset_ = 0;
270 }
271
272
273 void FormToc::hide()
274 {
275         dialog_->hide();
276         close();
277 }