]> git.lyx.org Git - lyx.git/blob - src/toc.cpp
rename MathArray into MathData
[lyx.git] / src / toc.cpp
1 /**
2  * \file toc.cpp
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 "FuncRequest.h"
20 #include "LyXText.h"
21 #include "LyXAction.h"
22 #include "Paragraph.h"
23 #include "ParIterator.h"
24 #include "Cursor.h"
25 #include "debug.h"
26 #include "Undo.h"
27
28
29 namespace lyx {
30 namespace toc {
31
32 void outline(OutlineOp mode,  Cursor & cur)
33 {
34         Buffer * buf = & cur.buffer();
35         pit_type & pit = cur.pit();
36         ParagraphList & pars = buf->text().paragraphs();
37         ParagraphList::iterator bgn = pars.begin();
38         // The first paragraph of the area to be copied:
39         ParagraphList::iterator start = boost::next(bgn, pit);
40         // The final paragraph of area to be copied:
41         ParagraphList::iterator finish = start;
42         ParagraphList::iterator end = pars.end();
43
44         LyXTextClass::const_iterator lit =
45                 buf->params().getLyXTextClass().begin();
46         LyXTextClass::const_iterator const lend =
47                 buf->params().getLyXTextClass().end();
48
49         int const thistoclevel = start->layout()->toclevel;
50         int toclevel;
51         switch (mode) {
52                 case Up: {
53                         // Move out (down) from this section header
54                         if (finish != end)
55                                 ++finish;
56                         // Seek the one (on same level) below
57                         for (; finish != end; ++finish) {
58                                 toclevel = finish->layout()->toclevel;
59                                 if (toclevel != LyXLayout::NOT_IN_TOC
60                                     && toclevel <= thistoclevel) {
61                                         break;
62                                 }
63                         }
64                         ParagraphList::iterator dest = start;
65                         // Move out (up) from this header
66                         if (dest == bgn)
67                                 break;
68                         // Search previous same-level header above
69                         do {
70                                 --dest;
71                                 toclevel = dest->layout()->toclevel;
72                         } while(dest != bgn
73                                 && (toclevel == LyXLayout::NOT_IN_TOC
74                                     || toclevel > thistoclevel));
75                         // Not found; do nothing
76                         if (toclevel == LyXLayout::NOT_IN_TOC
77                             || toclevel > thistoclevel)
78                                 break;
79                         pit_type const newpit = std::distance(bgn, dest);
80                         pit_type const len = std::distance(start, finish);
81                         pit_type const deletepit = pit + len;
82                         recordUndo(cur, Undo::ATOMIC, newpit, deletepit - 1);
83                         pars.insert(dest, start, finish);
84                         start = boost::next(pars.begin(), deletepit);
85                         pit = newpit;
86                         pars.erase(start, finish);
87                 break;
88                 }
89                 case Down: {
90                         // Go down out of current header:
91                         if (finish != end)
92                                 ++finish;
93                         // Find next same-level header:
94                         for (; finish != end; ++finish) {
95                                 toclevel = finish->layout()->toclevel;
96                                 if (toclevel != LyXLayout::NOT_IN_TOC
97                                     && toclevel <= thistoclevel) {
98                                         break;
99                                 }
100                         }
101                         ParagraphList::iterator dest = finish;
102                         // Go one down from *this* header:
103                         if (dest != end)
104                                 ++dest;
105                         else
106                                 break;
107                         // Go further down to find header to insert in front of:
108                         for (; dest != end; ++dest) {
109                                 toclevel = dest->layout()->toclevel;
110                                 if (toclevel != LyXLayout::NOT_IN_TOC
111                                     && toclevel <= thistoclevel) {
112                                         break;
113                                 }
114                         }
115                         // One such was found:
116                         pit_type newpit = std::distance(bgn, dest);
117                         pit_type const len = std::distance(start, finish);
118                         recordUndo(cur, Undo::ATOMIC, pit, newpit - 1);
119                         pars.insert(dest, start, finish);
120                         start = boost::next(bgn, pit);
121                         pit = newpit - len;
122                         pars.erase(start, finish);
123                 break;
124                 }
125                 case In:
126                         recordUndo(cur);
127                         for (; lit != lend; ++lit) {
128                                 if ((*lit)->toclevel == thistoclevel + 1 &&
129                                     start->layout()->labeltype == (*lit)->labeltype) {
130                                         start->layout((*lit));
131                                         break;
132                                 }
133                         }
134                 break;
135                 case Out:
136                         recordUndo(cur);
137                         for (; lit != lend; ++lit) {
138                                 if ((*lit)->toclevel == thistoclevel - 1 &&
139                                     start->layout()->labeltype == (*lit)->labeltype) {
140                                         start->layout((*lit));
141                                         break;
142                                 }
143                         }
144                 break;
145                 default:
146                 break;
147         }
148 }
149
150
151 } // namespace toc
152 } // namespace lyx