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