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