]> git.lyx.org Git - lyx.git/blob - src/TexRow.cpp
173634b0032d652b69004ccae4b66995da30a071
[lyx.git] / src / TexRow.cpp
1 /**
2  * \file TexRow.cpp
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Matthias Ettrich
7  * \author Lars Gullik Bjønnes
8  * \author John Levon
9  *
10  * Full author contact details are available in file CREDITS.
11  */
12
13 #include <config.h>
14
15 #include "DocIterator.h"
16 #include "Paragraph.h"
17 #include "TexRow.h"
18
19 #include "support/debug.h"
20
21 #include <algorithm>
22
23
24 namespace lyx {
25
26
27 void TexRow::reset(bool enable)
28 {
29         rowlist.clear();
30         lastid = -1;
31         lastpos = -1;
32         enabled_ = enable;
33 }
34
35
36 void TexRow::start(int id, int pos)
37 {
38         if (!enabled_ || started)
39                 return;
40         lastid = id;
41         lastpos = pos;
42         started = true;
43 }
44
45
46 void TexRow::newline()
47 {
48         if (!enabled_)
49                 return;
50         RowList::value_type tmp(lastid, lastpos);
51         rowlist.push_back(tmp);
52         started = false;
53 }
54
55 void TexRow::newlines(int num_lines)
56 {
57         if (!enabled_)
58                 return;
59         for (int i = 0; i < num_lines; ++i) {
60                 newline();
61         }
62 }
63
64 void TexRow::finalize()
65 {
66         if (!enabled_)
67                 return;
68         newline();
69 }
70
71 bool TexRow::getIdFromRow(int row, int & id, int & pos) const
72 {
73         if (row <= 0 || row > int(rowlist.size())) {
74                 id = -1;
75                 pos = 0;
76                 return false;
77         }
78
79         id = rowlist[row - 1].id();
80         pos = rowlist[row - 1].pos();
81         return true;
82 }
83
84
85 std::pair<int,int> TexRow::rowFromDocIterator(DocIterator const & dit) const
86 {
87         bool found = false;
88         size_t best_slice = 0;
89         size_t const n = dit.depth();
90         // this loop finds the last row of the topmost possible CursorSlice
91         RowList::const_iterator best_beg_row = rowlist.begin();
92         RowList::const_iterator best_end_row = rowlist.begin();
93         RowList::const_iterator it = rowlist.begin();
94         RowList::const_iterator const end = rowlist.end();
95         for (; it != end; ++it) {
96                 if (found) {
97                         // Compute the best end row. It is the one that matches pos+1.
98                         CursorSlice const & best = dit[best_slice];
99                         if (best.text()
100                                 && it->id() == best.paragraph().id()
101                                 && it->pos() == best.pos() + 1
102                                 && (best_end_row->id() != it->id()
103                                         || best_end_row->pos() < it->pos()))
104                                         best_end_row = it;
105                 }
106                 for (size_t i = best_slice; i < n && dit[i].text(); ++i) {
107                         int const id = dit[i].paragraph().id();
108                         if (it->id() == id) {
109                                 if (it->pos() <= dit[i].pos()
110                                         && (best_beg_row->id() != id
111                                                 || it->pos() > best_beg_row->pos())) {
112                                         found = true;
113                                         best_slice = i;
114                                         best_beg_row = best_end_row = it;
115                                 }
116                                 //found CursorSlice
117                                 break;
118                         }
119                 }
120         }
121         if (!found)
122                 return std::make_pair(-1,-1);
123         int const beg_i = distance(rowlist.begin(), best_beg_row) + 1;
124         // remove one to the end
125         int const end_i = std::max(beg_i,
126                                                            (int)distance(rowlist.begin(), best_end_row));
127         return std::make_pair(beg_i,end_i);
128 }
129
130
131 LyXErr & operator<<(LyXErr & l, TexRow & texrow)
132 {
133         if (l.enabled()) {
134                 for (int i = 0; i < texrow.rows(); i++) {
135                         int id,pos;
136                         if (texrow.getIdFromRow(i+1,id,pos) && id>0)
137                                 l << i+1 << ":" << id << ":" << pos << "\n";
138                 }
139         }
140         return l;
141 }
142
143
144
145 } // namespace lyx