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