]> git.lyx.org Git - lyx.git/blob - src/toc.C
0a441620324a0c55c32f84a07aa74c71a6f3f973
[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 "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,  LCursor & 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                                 --dest;
68                         else
69                                 break;
70                         // Search previous same-level header above
71                         for (; dest != bgn; --dest) {
72                                 toclevel = dest->layout()->toclevel;
73                                 if (toclevel != LyXLayout::NOT_IN_TOC
74                                     && toclevel <= thistoclevel) {
75                                         break;
76                                 }
77                         }
78                         // Not found; do nothing
79                         if (dest == bgn)
80                                 break;
81                         pit_type const newpit = std::distance(bgn, dest);
82                         pit_type const len = std::distance(start, finish);
83                         pit_type const deletepit = pit + len;
84                         recordUndo(cur, Undo::ATOMIC, newpit, deletepit - 1);
85                         pars.insert(dest, start, finish);
86                         start = boost::next(bgn, deletepit);
87                         pit = newpit;
88                         pars.erase(start, finish);
89                 break;
90                 }
91                 case Down: {
92                         // Go down out of current header:
93                         if (finish != end)
94                                 ++finish;
95                         // Find next same-level header:
96                         for (; finish != end; ++finish) {
97                                 toclevel = finish->layout()->toclevel;
98                                 if (toclevel != LyXLayout::NOT_IN_TOC
99                                     && toclevel <= thistoclevel) {
100                                         break;
101                                 }
102                         }
103                         ParagraphList::iterator dest = finish;
104                         // Go one down from *this* header:
105                         if (dest != end)
106                                 ++dest;
107                         else
108                                 break;
109                         // Go further down to find header to insert in front of:
110                         for (; dest != end; ++dest) {
111                                 toclevel = dest->layout()->toclevel;
112                                 if (toclevel != LyXLayout::NOT_IN_TOC
113                                     && toclevel <= thistoclevel) {
114                                         break;
115                                 }
116                         }
117                         // One such was found:
118                         pit_type newpit = std::distance(bgn, dest);
119                         pit_type const len = std::distance(start, finish);
120                         recordUndo(cur, Undo::ATOMIC, pit, newpit -1);
121                         pars.insert(dest, start, finish);
122                         start = boost::next(bgn, pit);
123                         pit = newpit - len;
124                         pars.erase(start, finish);
125                 break;
126                 }
127                 case In:
128                         recordUndo(cur);
129                         for (; lit != lend; ++lit) {
130                                 if ((*lit)->toclevel == thistoclevel + 1 &&
131                                     start->layout()->labeltype == (*lit)->labeltype) {
132                                         start->layout((*lit));
133                                         break;
134                                 }
135                         }
136                 break;
137                 case Out:
138                         recordUndo(cur);
139                         for (; lit != lend; ++lit) {
140                                 if ((*lit)->toclevel == thistoclevel - 1 &&
141                                     start->layout()->labeltype == (*lit)->labeltype) {
142                                         start->layout((*lit));
143                                         break;
144                                 }
145                         }
146                 break;
147                 default:
148                 break;
149         }
150 }
151
152
153 } // namespace toc
154 } // namespace lyx