]> git.lyx.org Git - lyx.git/blob - src/toc.C
2442053a935d2a62a52f6219877fa833ad119ae4
[lyx.git] / src / toc.C
1 /**
2  * \file toc.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Jean-Marc Lasgouttes
7  * \author Angus Leeming
8  * \author Abdelrazak Younes
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "toc.h"
16
17 #include "buffer.h"
18 #include "bufferparams.h"
19 #include "FloatList.h"
20 #include "funcrequest.h"
21 #include "LyXAction.h"
22 #include "paragraph.h"
23 #include "cursor.h"
24 #include "debug.h"
25
26 #include "frontends/LyXView.h"
27
28 #include "insets/insetfloat.h"
29 #include "insets/insetoptarg.h"
30 #include "insets/insetwrap.h"
31
32 #include "support/convert.h"
33
34 #include <iostream>
35 #include <map>
36
37 using std::map;
38 using std::pair;
39 using std::make_pair;
40 using std::vector;
41 using std::max;
42 using std::ostream;
43 using std::string;
44 using std::cout;
45 using std::endl;
46
47 namespace lyx {
48 namespace toc {
49
50 typedef map<Buffer const *, lyx::TocBackend> TocMap;
51 static TocMap toc_backend_;
52
53 ///////////////////////////////////////////////////////////////////////////
54 // Interface to toc_backend_
55
56 void updateToc(Buffer const & buf)
57 {
58         TocMap::iterator it = toc_backend_.find(&buf);
59         if (it == toc_backend_.end()) {
60                 pair<TocMap::iterator, bool> result
61                         = toc_backend_.insert(make_pair(&buf, TocBackend(&buf)));
62                 if (!result.second)
63                         return;
64
65                 it = result.first;
66         }
67
68         it->second.update();
69 }
70
71
72 TocList const & getTocList(Buffer const & buf)
73 {
74         return toc_backend_[&buf].tocs();
75 }
76
77
78 Toc const & getToc(Buffer const & buf, std::string const & type)
79 {
80         return toc_backend_[&buf].toc(type);
81 }
82
83
84 TocIterator const getCurrentTocItem(Buffer const & buf, LCursor const & cur,
85                                                                 std::string const & type)
86 {
87         return toc_backend_[&buf].item(type, ParConstIterator(cur));
88 }
89
90
91 vector<string> const & getTypes(Buffer const & buf)
92 {
93         return toc_backend_[&buf].types();
94 }
95
96
97 void asciiTocList(string const & type, Buffer const & buf, ostream & os)
98 {
99         toc_backend_[&buf].asciiTocList(type, os);
100 }
101
102 ///////////////////////////////////////////////////////////////////////////
103 // Other functions
104
105 string const getType(string const & cmdName)
106 {
107         // special case
108         if (cmdName == "tableofcontents")
109                 return "TOC";
110         else
111                 return cmdName;
112 }
113
114
115 string const getGuiName(string const & type, Buffer const & buffer)
116 {
117         FloatList const & floats =
118                 buffer.params().getLyXTextClass().floats();
119         if (floats.typeExist(type))
120                 return floats.getType(type).name();
121         else
122                 return type;
123 }
124
125
126 void outline(OutlineOp mode, Buffer * buf, pit_type & pit)
127 {
128         ParagraphList & pars = buf->text().paragraphs();
129         ParagraphList::iterator bgn = pars.begin();
130         ParagraphList::iterator s = boost::next(bgn, pit);
131         ParagraphList::iterator p = s;
132         ParagraphList::iterator end = pars.end();
133
134         LyXTextClass::const_iterator lit =
135                 buf->params().getLyXTextClass().begin();
136         LyXTextClass::const_iterator const lend =
137                 buf->params().getLyXTextClass().end();
138
139         int const thistoclevel = s->layout()->toclevel;
140         int toclevel;
141         switch (mode) {
142                 case UP: {
143                         if (p != end)
144                                 ++p;
145                         for (; p != end; ++p) {
146                                 toclevel = p->layout()->toclevel;
147                                 if (toclevel != LyXLayout::NOT_IN_TOC
148                                     && toclevel <= thistoclevel) {
149                                         break;
150                                 }
151                         }
152                         ParagraphList::iterator q = s;
153                         if (q != bgn)
154                                 --q;
155                         else
156                                 break;
157                         for (; q != bgn; --q) {
158                                 toclevel = q->layout()->toclevel;
159                                 if (toclevel != LyXLayout::NOT_IN_TOC
160                                     && toclevel <= thistoclevel) {
161                                         break;
162                                 }
163                         }
164                         pit_type const newpit = std::distance(pars.begin(), q);
165                         pit_type const len = std::distance(s, p);
166                         pit += len;
167                         pars.insert(q, s, p);
168                         s = boost::next(pars.begin(), pit);
169                         ParagraphList::iterator t = boost::next(s, len);
170                         pit = newpit;
171                         pars.erase(s, t);
172                 break;
173                 }
174                 case DOWN: {
175                            if (p != end)
176                                 ++p;
177                         for (; p != end; ++p) {
178                                 toclevel = p->layout()->toclevel;
179                                 if (toclevel != LyXLayout::NOT_IN_TOC
180                                     && toclevel <= thistoclevel) {
181                                         break;
182                                 }
183                         }
184                         ParagraphList::iterator q = p;
185                         if (q != end)
186                                 ++q;
187                         else
188                                 break;
189                         for (; q != end; ++q) {
190                                 toclevel = q->layout()->toclevel;
191                                 if (toclevel != LyXLayout::NOT_IN_TOC
192                                     && toclevel <= thistoclevel) {
193                                         break;
194                                 }
195                         }
196                         pit_type const newpit = std::distance(pars.begin(), q);
197                         pit_type const len = std::distance(s, p);
198                         pars.insert(q, s, p);
199                         s = boost::next(pars.begin(), pit);
200                         ParagraphList::iterator t = boost::next(s, len);
201                         pit = newpit - len;
202                         pars.erase(s, t);
203                 break;
204                 }
205                 case IN:
206                         for (; lit != lend; ++lit) {
207                                 if ((*lit)->toclevel == thistoclevel + 1) {
208                                         s->layout((*lit));
209                                         break;
210                                 }
211                         }
212                 break;
213                 case OUT:
214                         for (; lit != lend; ++lit) {
215                                 if ((*lit)->toclevel == thistoclevel - 1) {
216                                         s->layout((*lit));
217                                         break;
218                                 }
219                         }
220                 break;
221                 default:
222                 break;
223         }
224 }
225
226
227 } // namespace toc
228 } // namespace lyx