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