]> git.lyx.org Git - lyx.git/blob - src/BufferView.C
a0b4084495f76ba853593da9be8fd6e6a1e24fee
[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 "iterators.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 "texrow.h"
35 #include "undo.h"
36 #include "WordLangTuple.h"
37
38 #include "frontends/Alert.h"
39 #include "frontends/Dialogs.h"
40 #include "frontends/LyXView.h"
41 #include "frontends/screen.h"
42 #include "frontends/WorkArea.h"
43
44 #include "insets/insetcommand.h" // ChangeRefs
45 #include "insets/updatableinset.h"
46 #include "insets/insettext.h"
47
48 #include "support/filetools.h"
49 #include "support/lyxalgo.h" // lyx_count
50
51 using lyx::support::bformat;
52 using lyx::support::MakeAbsPath;
53
54 using lyx::cap::setSelectionRange;
55
56 using std::distance;
57 using std::find;
58 using std::string;
59 using std::swap;
60 using std::vector;
61
62
63 extern BufferList bufferlist;
64
65
66 BufferView::BufferView(LyXView * owner, int xpos, int ypos,
67                        int width, int height)
68         : pimpl_(new Pimpl(*this, owner, xpos, ypos, width, height))
69 {}
70
71
72 BufferView::~BufferView()
73 {
74         delete pimpl_;
75 }
76
77
78 void BufferView::unsetXSel()
79 {
80         pimpl_->xsel_cache_.set = false;
81 }
82
83
84 Buffer * BufferView::buffer() const
85 {
86         return pimpl_->buffer_;
87 }
88
89
90 LyXScreen & BufferView::screen() const
91 {
92         return pimpl_->screen();
93 }
94
95
96 LyXView * BufferView::owner() const
97 {
98         return pimpl_->owner_;
99 }
100
101
102 Painter & BufferView::painter() const
103 {
104         return pimpl_->painter();
105 }
106
107
108 void BufferView::setBuffer(Buffer * b)
109 {
110         pimpl_->setBuffer(b);
111 }
112
113
114 void BufferView::newFile(string const & fn, string const & tn, bool named)
115 {
116         pimpl_->newFile(fn, tn, named);
117 }
118
119
120 bool BufferView::loadLyXFile(string const & fn, bool tl)
121 {
122         return pimpl_->loadLyXFile(fn, tl);
123 }
124
125
126 void BufferView::reload()
127 {
128         string const fn = buffer()->fileName();
129         if (bufferlist.close(buffer(), false))
130                 loadLyXFile(fn);
131 }
132
133
134 void BufferView::resize()
135 {
136         if (pimpl_->buffer_)
137                 pimpl_->resizeCurrentBuffer();
138 }
139
140
141 bool BufferView::fitCursor()
142 {
143         return pimpl_->fitCursor();
144 }
145
146
147 void BufferView::update()
148 {
149         pimpl_->update();
150 }
151
152
153 void BufferView::updateScrollbar()
154 {
155         pimpl_->updateScrollbar();
156 }
157
158
159 void BufferView::scrollDocView(int value)
160 {
161         pimpl_->scrollDocView(value);
162 }
163
164
165 void BufferView::redoCurrentBuffer()
166 {
167         pimpl_->redoCurrentBuffer();
168 }
169
170
171 bool BufferView::available() const
172 {
173         return pimpl_->available();
174 }
175
176
177 Change const BufferView::getCurrentChange()
178 {
179         return pimpl_->getCurrentChange();
180 }
181
182
183 void BufferView::savePosition(unsigned int i)
184 {
185         pimpl_->savePosition(i);
186 }
187
188
189 void BufferView::restorePosition(unsigned int i)
190 {
191         pimpl_->restorePosition(i);
192 }
193
194
195 bool BufferView::isSavedPosition(unsigned int i)
196 {
197         return pimpl_->isSavedPosition(i);
198 }
199
200
201 void BufferView::switchKeyMap()
202 {
203         pimpl_->switchKeyMap();
204 }
205
206
207 int BufferView::workWidth() const
208 {
209         return pimpl_->workarea().workWidth();
210 }
211
212
213 void BufferView::center()
214 {
215         pimpl_->center();
216 }
217
218
219 int BufferView::top_y() const
220 {
221         return pimpl_->top_y();
222 }
223
224
225 void BufferView::top_y(int y)
226 {
227         pimpl_->top_y(y);
228 }
229
230
231 string const BufferView::getClipboard() const
232 {
233         return pimpl_->workarea().getClipboard();
234 }
235
236
237 void BufferView::stuffClipboard(string const & stuff) const
238 {
239         pimpl_->stuffClipboard(stuff);
240 }
241
242
243 bool BufferView::dispatch(FuncRequest const & ev)
244 {
245         return pimpl_->dispatch(ev);
246 }
247
248
249 void BufferView::scroll(int lines)
250 {
251         pimpl_->scroll(lines);
252 }
253
254
255 // Inserts a file into current document
256 bool BufferView::insertLyXFile(string const & filen)
257         //
258         // Copyright CHT Software Service GmbH
259         // Uwe C. Schroeder
260         //
261         // Insert a LyXformat - file into current buffer
262         //
263         // Moved from lyx_cb.C (Lgb)
264 {
265         BOOST_ASSERT(!filen.empty());
266
267         string const fname = MakeAbsPath(filen);
268
269         cursor().clearSelection();
270         text()->breakParagraph(cursor());
271
272         BOOST_ASSERT(cursor().inTexted());
273         bool res = buffer()->readFile(fname, cursor().par());
274         resize();
275         return res;
276 }
277
278
279 void BufferView::showErrorList(string const & action) const
280 {
281         if (getErrorList().size()) {
282                 string const title = bformat(_("LyX: %1$s errors (%2$s)"),
283                         action, buffer()->fileName());
284                 owner()->getDialogs().show("errorlist", title);
285                 pimpl_->errorlist_.clear();
286         }
287 }
288
289
290 ErrorList const & BufferView::getErrorList() const
291 {
292         return pimpl_->errorlist_;
293 }
294
295
296 void BufferView::setCursorFromRow(int row)
297 {
298         int tmpid = -1;
299         int tmppos = -1;
300
301         buffer()->texrow().getIdFromRow(row, tmpid, tmppos);
302
303         if (tmpid == -1)
304                 text()->setCursor(cursor(), 0, 0);
305         else
306                 text()->setCursor(cursor(), buffer()->getParFromID(tmpid).pit(),
307                         tmppos);
308 }
309
310
311 void BufferView::gotoLabel(string const & label)
312 {
313         for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
314              it != buffer()->inset_iterator_end(); ++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.getPar(), it.getPos());
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.reset(buffer()->inset());
372         ParIterator::PosHolder const & positions = par.positions();
373         int const last = par.size() - 1;
374         for (int i = 0; i < last; ++i)
375                 (*positions[i].it)->inset->edit(cur, true);
376         cur.resetAnchor();
377         par.text(*buffer())->setCursor(cur, par.pit(), pos);
378 }
379
380
381 /*
382 if the fitCursor call refers to some point in never-explored-land, then we
383 don't have y information in insets there, then we cannot even do an update
384 to get it (because we need the y infomation for setting top_y first). So
385 this is solved in putSelectionAt with:
386
387 - setting top_y to the y of the outerPar (that has good info)
388 - calling update
389 - calling cursor().updatePos()
390 - then call fitCursor()
391
392 Ab.
393 */
394
395 void BufferView::putSelectionAt(DocumentIterator const & cur,
396                       int length, bool backwards)
397 {
398         ParIterator par(cur);
399
400         cursor().clearSelection();
401
402         LyXText * text = par.text(*buffer());
403         setCursor(par, cur.pos());
404         
405         // hack for the chicken and egg problem
406         if (par.inset())
407                 top_y(text->getPar(par.outerPar()).y);
408         update();
409         text->setCursor(cursor(), cur.par(), cur.pos());
410         cursor().updatePos();
411
412         if (length) {
413                 setSelectionRange(cursor(), length);
414                 cursor().setSelection();
415                 if (backwards) {
416                         DocumentIterator const it = cursor();
417                         cursor().setCursor(cursor().anchor_, false);
418                         cursor().anchor_ = it;
419                 }
420         }
421
422         fitCursor();
423         update();
424 }
425
426
427 LCursor & BufferView::cursor()
428 {
429         return pimpl_->cursor_;
430 }
431
432
433 LCursor const & BufferView::cursor() const
434 {
435         return pimpl_->cursor_;
436 }