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