]> git.lyx.org Git - lyx.git/blob - src/frontends/kde/FormToc.C
A few tweaks needed by cxx
[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 "formtocdialog.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  
35 FormToc::FormToc(LyXView *v, Dialogs *d)
36         : dialog_(0), lv_(v), d_(d), inset_(0), h_(0), u_(0), ih_(0),
37         toclist(0), type(Buffer::TOC_TOC)
38 {
39         // let the dialog be shown
40         // This is a permanent connection so we won't bother
41         // storing a copy because we won't be disconnecting.
42         d->showTOC.connect(slot(this, &FormToc::showTOC));
43         d->createTOC.connect(slot(this, &FormToc::createTOC));
44 }
45
46 FormToc::~FormToc()
47 {
48         delete dialog_;
49 }
50
51 void FormToc::showTOC(InsetCommand * const inset)
52 {
53         // FIXME: when could inset be 0 here ?
54         if (inset==0)
55                 return;
56
57         inset_ = inset;
58         ih_ = inset_->hide.connect(slot(this,&FormToc::hide));
59         params = inset->params();
60         
61         show();
62 }
63  
64 void FormToc::createTOC(string const & arg)
65 {
66         if (inset_)
67                 close();
68  
69         params.setFromString(arg);
70         show();
71 }
72  
73 void FormToc::updateToc()
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 (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         toclist = tmp[type];
96
97         dialog_->tree->clear();
98
99         dialog_->tree->setUpdatesEnabled(false);
100
101         int depth = 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 a QListView parent,
108         // rather than QListViewItem; and the TOC can move in and out an arbitrary number
109         // of levels
110  
111         for (vector< Buffer::TocItem >::const_iterator iter = toclist.begin();
112                 iter != toclist.end(); ++iter) {
113                 if (iter->depth == depth) {
114                         // insert it after the last one we processed
115                         if (!parent)
116                                 item = (last) ? (new QListViewItem(dialog_->tree,last)) : (new QListViewItem(dialog_->tree));
117                         else
118                                 item = (last) ? (new QListViewItem(parent,last)) : (new QListViewItem(parent));
119                 } else if (iter->depth > depth) {
120                         int diff = iter->depth - depth;
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_->tree));
125                         parent = last;
126                 } else {
127                         int diff = depth - 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_->tree,last)) : (new QListViewItem(dialog_->tree));
139                         else
140                                 item = (last) ? (new QListViewItem(parent,last)) : (new QListViewItem(parent));
141                 }
142                 lyxerr[Debug::GUI] << "Table of contents" << endl << "Added item " << iter->str.c_str() 
143                         << " at depth " << iter->depth << ", previous sibling \"" << (last ? last->text(0) : "0") 
144                         << "\", parent \"" << (parent ? parent->text(0) : "0") << "\"" << endl;
145                 item->setText(0,iter->str.c_str());
146                 depth = iter->depth;
147                 last = item;
148         }
149
150         dialog_->tree->setUpdatesEnabled(true);
151         dialog_->tree->update();
152 }
153  
154 void FormToc::setType(Buffer::TocType toctype)
155 {
156         type = toctype;
157         switch (type) {
158                 case Buffer::TOC_TOC:
159                         dialog_->setCaption(_("Table of Contents"));
160                         dialog_->tree->setColumnText(0,_("Table of Contents")); 
161                         break; 
162                 case Buffer::TOC_LOF:
163                         dialog_->setCaption(_("List of Figures"));
164                         dialog_->tree->setColumnText(0,_("List of Figures")); 
165                         break; 
166                 case Buffer::TOC_LOT:
167                         dialog_->setCaption(_("List of Tables"));
168                         dialog_->tree->setColumnText(0,_("List of Tables")); 
169                         break; 
170                 case Buffer::TOC_LOA:
171                         dialog_->setCaption(_("List of Algorithms"));
172                         dialog_->tree->setColumnText(0,_("List of Algorithms")); 
173                         break; 
174         }
175 }
176  
177 void FormToc::update()
178 {
179         if (params.getCmdName()=="tableofcontents") {
180                 setType(Buffer::TOC_TOC);
181                 dialog_->menu->setCurrentItem(0);
182         } else if (params.getCmdName()=="listoffigures") {
183                 setType(Buffer::TOC_LOF); 
184                 dialog_->menu->setCurrentItem(1); 
185         } else if (params.getCmdName()=="listoftables") {
186                 setType(Buffer::TOC_LOT); 
187                 dialog_->menu->setCurrentItem(2); 
188         } else {
189                 setType(Buffer::TOC_LOA); 
190                 dialog_->menu->setCurrentItem(3); 
191         } 
192
193         updateToc();
194 }
195  
196 void FormToc::select(const char *text)
197 {
198         if (!lv_->view()->available())
199                 return;
200  
201         vector <Buffer::TocItem>::const_iterator iter = toclist.begin();
202         for (; iter != toclist.end(); ++iter) {
203                 if (iter->str==text)
204                         break;
205         }
206         
207         if (iter==toclist.end()) {
208                 lyxerr[Debug::GUI] << "Couldn't find highlighted TOC entry : " << text << endl;
209                 return;
210         }
211
212         lv_->getLyXFunc()->Dispatch(LFUN_GOTO_PARAGRAPH, tostr(iter->par->id()).c_str());
213 }
214  
215 void FormToc::set_type(Buffer::TocType toctype)
216 {
217         if (toctype==type)
218                 return;
219
220         setType(toctype);
221         updateToc();
222 }
223  
224 void FormToc::show()
225 {
226         if (!dialog_)
227                 dialog_ = new FormTocDialog(this, 0, _("LyX: Table of Contents"), false);
228  
229         if (!dialog_->isVisible()) {
230                 h_ = d_->hideBufferDependent.connect(slot(this, &FormToc::hide));
231                 u_ = d_->updateBufferDependent.connect(slot(this, &FormToc::update));
232         }
233
234         dialog_->raise();
235         dialog_->setActiveWindow();
236  
237         update();
238         dialog_->show();
239 }
240
241 void FormToc::close()
242 {
243         h_.disconnect();
244         u_.disconnect();
245         ih_.disconnect();
246         inset_ = 0;
247 }
248  
249 void FormToc::hide()
250 {
251         dialog_->hide();
252         close();
253 }