]> git.lyx.org Git - lyx.git/blob - src/BufferView.C
5 new lfuns, move all apply code out of ControlDocument and into the core.
[lyx.git] / src / BufferView.C
1 /**
2  * \file BufferView.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Alfredo Braunstein
7  * \author Lars Gullik Bjønnes
8  * \author John Levon
9  * \author André Pönitz
10  * \author Jürgen Vigna
11  *
12  * Full author contact details are available in file CREDITS.
13  */
14
15 #include <config.h>
16
17 #include "BufferView.h"
18
19 #include "buffer.h"
20 #include "bufferlist.h"
21 #include "bufferparams.h"
22 #include "BufferView_pimpl.h"
23 #include "CutAndPaste.h"
24 #include "debug.h"
25 #include "funcrequest.h"
26 #include "gettext.h"
27 #include "insetiterator.h"
28 #include "language.h"
29 #include "lyxlayout.h"
30 #include "lyxtext.h"
31 #include "lyxtextclass.h"
32 #include "paragraph.h"
33 #include "paragraph_funcs.h"
34 #include "pariterator.h"
35 #include "texrow.h"
36 #include "undo.h"
37 #include "WordLangTuple.h"
38
39 #include "frontends/Alert.h"
40 #include "frontends/Dialogs.h"
41 #include "frontends/LyXView.h"
42 #include "frontends/screen.h"
43 #include "frontends/WorkArea.h"
44
45 #include "insets/insetcommand.h" // ChangeRefs
46 #include "insets/updatableinset.h"
47 #include "insets/insettext.h"
48
49 #include "support/filetools.h"
50 #include "support/lyxalgo.h" // lyx_count
51
52 using lyx::support::bformat;
53 using lyx::support::MakeAbsPath;
54
55 using lyx::cap::setSelectionRange;
56
57 using std::distance;
58 using std::find;
59 using std::string;
60 using std::swap;
61 using std::vector;
62
63
64 extern BufferList bufferlist;
65
66
67 BufferView::BufferView(LyXView * owner, int xpos, int ypos,
68                        int width, int height)
69         : pimpl_(new Pimpl(*this, owner, xpos, ypos, width, height))
70 {}
71
72
73 BufferView::~BufferView()
74 {
75         delete pimpl_;
76 }
77
78
79 void BufferView::unsetXSel()
80 {
81         pimpl_->xsel_cache_.set = false;
82 }
83
84
85 Buffer * BufferView::buffer() const
86 {
87         return pimpl_->buffer_;
88 }
89
90
91 LyXScreen & BufferView::screen() const
92 {
93         return pimpl_->screen();
94 }
95
96
97 LyXView * BufferView::owner() const
98 {
99         return pimpl_->owner_;
100 }
101
102
103 Painter & BufferView::painter() const
104 {
105         return pimpl_->painter();
106 }
107
108
109 void BufferView::setBuffer(Buffer * b)
110 {
111         pimpl_->setBuffer(b);
112 }
113
114
115 void BufferView::newFile(string const & fn, string const & tn, bool named)
116 {
117         pimpl_->newFile(fn, tn, named);
118 }
119
120
121 bool BufferView::loadLyXFile(string const & fn, bool tl)
122 {
123         return pimpl_->loadLyXFile(fn, tl);
124 }
125
126
127 void BufferView::reload()
128 {
129         string const fn = buffer()->fileName();
130         if (bufferlist.close(buffer(), false))
131                 loadLyXFile(fn);
132 }
133
134
135 void BufferView::resize()
136 {
137         if (pimpl_->buffer_)
138                 pimpl_->resizeCurrentBuffer();
139 }
140
141
142 bool BufferView::fitCursor()
143 {
144         return pimpl_->fitCursor();
145 }
146
147
148 void BufferView::update()
149 {
150         pimpl_->update();
151 }
152
153
154 void BufferView::updateScrollbar()
155 {
156         pimpl_->updateScrollbar();
157 }
158
159
160 void BufferView::scrollDocView(int value)
161 {
162         pimpl_->scrollDocView(value);
163 }
164
165
166 void BufferView::redoCurrentBuffer()
167 {
168         pimpl_->redoCurrentBuffer();
169 }
170
171
172 bool BufferView::available() const
173 {
174         return pimpl_->available();
175 }
176
177
178 Change const BufferView::getCurrentChange()
179 {
180         return pimpl_->getCurrentChange();
181 }
182
183
184 void BufferView::savePosition(unsigned int i)
185 {
186         pimpl_->savePosition(i);
187 }
188
189
190 void BufferView::restorePosition(unsigned int i)
191 {
192         pimpl_->restorePosition(i);
193 }
194
195
196 bool BufferView::isSavedPosition(unsigned int i)
197 {
198         return pimpl_->isSavedPosition(i);
199 }
200
201
202 void BufferView::switchKeyMap()
203 {
204         pimpl_->switchKeyMap();
205 }
206
207
208 int BufferView::workWidth() const
209 {
210         return pimpl_->workarea().workWidth();
211 }
212
213
214 void BufferView::center()
215 {
216         pimpl_->center();
217 }
218
219
220 int BufferView::top_y() const
221 {
222         return pimpl_->top_y();
223 }
224
225
226 void BufferView::top_y(int y)
227 {
228         pimpl_->top_y(y);
229 }
230
231
232 string const BufferView::getClipboard() const
233 {
234         return pimpl_->workarea().getClipboard();
235 }
236
237
238 void BufferView::stuffClipboard(string const & stuff) const
239 {
240         pimpl_->stuffClipboard(stuff);
241 }
242
243
244 bool BufferView::dispatch(FuncRequest const & ev)
245 {
246         return pimpl_->dispatch(ev);
247 }
248
249
250 void BufferView::scroll(int lines)
251 {
252         pimpl_->scroll(lines);
253 }
254
255
256 // Inserts a file into current document
257 bool BufferView::insertLyXFile(string const & filen)
258         //
259         // Copyright CHT Software Service GmbH
260         // Uwe C. Schroeder
261         //
262         // Insert a LyXformat - file into current buffer
263         //
264         // Moved from lyx_cb.C (Lgb)
265 {
266         BOOST_ASSERT(!filen.empty());
267
268         string const fname = MakeAbsPath(filen);
269
270         cursor().clearSelection();
271         text()->breakParagraph(cursor());
272
273         BOOST_ASSERT(cursor().inTexted());
274         bool res = buffer()->readFile(fname, cursor().par());
275         resize();
276         return res;
277 }
278
279
280 void BufferView::showErrorList(string const & action) const
281 {
282         if (getErrorList().size()) {
283                 string const title = bformat(_("LyX: %1$s errors (%2$s)"),
284                         action, buffer()->fileName());
285                 owner()->getDialogs().show("errorlist", title);
286                 pimpl_->errorlist_.clear();
287         }
288 }
289
290
291 ErrorList const & BufferView::getErrorList() const
292 {
293         return pimpl_->errorlist_;
294 }
295
296
297 void BufferView::setCursorFromRow(int row)
298 {
299         int tmpid = -1;
300         int tmppos = -1;
301
302         buffer()->texrow().getIdFromRow(row, tmpid, tmppos);
303
304         if (tmpid == -1)
305                 text()->setCursor(cursor(), 0, 0);
306         else
307                 text()->setCursor(cursor(), buffer()->getParFromID(tmpid).pit(),
308                         tmppos);
309 }
310
311
312 void BufferView::gotoLabel(string const & label)
313 {
314         for (InsetIterator it = inset_iterator_begin(buffer()->inset()); it; ++it) {
315                 vector<string> labels;
316                 it->getLabelList(*buffer(), labels);
317                 if (find(labels.begin(),labels.end(),label) != labels.end()) {
318                         cursor().clearSelection();
319                         text()->setCursor(cursor(), it.par(), it.pos());
320                         cursor().resetAnchor();
321                         update();
322                         return;
323                 }
324         }
325 }
326
327
328 void BufferView::hideCursor()
329 {
330         screen().hideCursor();
331 }
332
333
334 LyXText * BufferView::getLyXText() const
335 {
336         LyXText * text = cursor().innerText();
337         BOOST_ASSERT(text);
338         return text;
339 }
340
341
342 Language const * BufferView::getParentLanguage(InsetOld * inset) const
343 {
344         Paragraph const & par = ownerPar(*buffer(), inset);
345         return par.getFontSettings(buffer()->params(),
346                                    par.getPositionOfInset(inset)).language();
347 }
348
349
350 void BufferView::haveSelection(bool sel)
351 {
352         pimpl_->workarea().haveSelection(sel);
353 }
354
355
356 int BufferView::workHeight() const
357 {
358         return pimpl_->workarea().workHeight();
359 }
360
361
362 LyXText * BufferView::text() const
363 {
364         return buffer() ? &buffer()->text() : 0;
365 }
366
367
368 void BufferView::setCursor(ParIterator const & par, lyx::pos_type pos)
369 {
370         LCursor & cur = cursor();
371         cur.setCursor(makeDocumentIterator(par, pos), false);
372 }
373
374
375 /*
376 if the fitCursor call refers to some point in never-explored-land, then we
377 don't have y information in insets there, then we cannot even do an update
378 to get it (because we need the y infomation for setting top_y first). So
379 this is solved in putSelectionAt with:
380
381 - setting top_y to the y of the outerPar (that has good info)
382 - calling update
383 - calling cursor().updatePos()
384 - then call fitCursor()
385
386 Ab.
387 */
388
389 void BufferView::putSelectionAt(DocumentIterator const & cur,
390                                 int length, bool backwards)
391 {
392         ParIterator par(cur);
393
394         cursor().clearSelection();
395
396         LyXText & text = *par.text();
397         setCursor(par, cur.pos());
398         
399         // hack for the chicken and egg problem
400         top_y(text.getPar(par.outerPar()).y);
401
402         update();
403         text.setCursor(cursor(), cur.par(), cur.pos());
404         cursor().updatePos();
405
406         if (length) {
407                 setSelectionRange(cursor(), length);
408                 cursor().setSelection();
409                 if (backwards) {
410                         DocumentIterator const it = cursor();
411                         cursor().setCursor(cursor().anchor_, false);
412                         cursor().anchor_ = it;
413                 }
414         }
415
416         fitCursor();
417         update();
418 }
419
420
421 LCursor & BufferView::cursor()
422 {
423         return pimpl_->cursor_;
424 }
425
426
427 LCursor const & BufferView::cursor() const
428 {
429         return pimpl_->cursor_;
430 }