]> git.lyx.org Git - lyx.git/blob - src/BufferView.C
Anchor globalization
[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 "BufferView_pimpl.h"
22 #include "debug.h"
23 #include "funcrequest.h"
24 #include "gettext.h"
25 #include "iterators.h"
26 #include "language.h"
27 #include "lyxlayout.h"
28 #include "lyxtext.h"
29 #include "paragraph.h"
30 #include "paragraph_funcs.h"
31 #include "texrow.h"
32 #include "undo.h"
33 #include "WordLangTuple.h"
34
35 #include "frontends/Alert.h"
36 #include "frontends/Dialogs.h"
37 #include "frontends/LyXView.h"
38 #include "frontends/screen.h"
39 #include "frontends/WorkArea.h"
40
41 #include "insets/insetcommand.h" // ChangeRefs
42 #include "insets/updatableinset.h"
43
44 #include "support/filetools.h"
45 #include "support/lyxalgo.h" // lyx_count
46
47 using lyx::support::bformat;
48 using lyx::support::MakeAbsPath;
49
50 using std::find;
51 using std::string;
52 using std::vector;
53
54
55 extern BufferList bufferlist;
56
57
58 BufferView::BufferView(LyXView * owner, int xpos, int ypos,
59                        int width, int height)
60         : pimpl_(new Pimpl(this, owner, xpos, ypos, width, height)),
61           x_target_(0)
62 {}
63
64
65 BufferView::~BufferView()
66 {
67         delete pimpl_;
68 }
69
70
71 void BufferView::unsetXSel()
72 {
73         pimpl_->xsel_cache_.set = false;
74 }
75
76
77 Buffer * BufferView::buffer() const
78 {
79         return pimpl_->buffer_;
80 }
81
82
83 LyXScreen & BufferView::screen() const
84 {
85         return pimpl_->screen();
86 }
87
88
89 LyXView * BufferView::owner() const
90 {
91         return pimpl_->owner_;
92 }
93
94
95 Painter & BufferView::painter() const
96 {
97         return pimpl_->painter();
98 }
99
100
101 void BufferView::buffer(Buffer * b)
102 {
103         pimpl_->buffer(b);
104 }
105
106
107 bool BufferView::newFile(string const & fn, string const & tn, bool named)
108 {
109         return pimpl_->newFile(fn, tn, named);
110 }
111
112
113 bool BufferView::loadLyXFile(string const & fn, bool tl)
114 {
115         return pimpl_->loadLyXFile(fn, tl);
116 }
117
118
119 void BufferView::reload()
120 {
121         string const fn = buffer()->fileName();
122         if (bufferlist.close(buffer(), false))
123                 loadLyXFile(fn);
124 }
125
126
127 void BufferView::resize()
128 {
129         if (pimpl_->buffer_)
130                 pimpl_->resizeCurrentBuffer();
131 }
132
133
134 bool BufferView::fitCursor()
135 {
136         return pimpl_->fitCursor();
137 }
138
139
140 void BufferView::update()
141 {
142         pimpl_->update();
143 }
144
145
146 void BufferView::updateScrollbar()
147 {
148         pimpl_->updateScrollbar();
149 }
150
151
152 void BufferView::scrollDocView(int value)
153 {
154         pimpl_->scrollDocView(value);
155 }
156
157
158 void BufferView::redoCurrentBuffer()
159 {
160         pimpl_->redoCurrentBuffer();
161 }
162
163
164 bool BufferView::available() const
165 {
166         return pimpl_->available();
167 }
168
169
170 Change const BufferView::getCurrentChange()
171 {
172         return pimpl_->getCurrentChange();
173 }
174
175
176 void BufferView::savePosition(unsigned int i)
177 {
178         pimpl_->savePosition(i);
179 }
180
181
182 void BufferView::restorePosition(unsigned int i)
183 {
184         pimpl_->restorePosition(i);
185 }
186
187
188 bool BufferView::isSavedPosition(unsigned int i)
189 {
190         return pimpl_->isSavedPosition(i);
191 }
192
193
194 void BufferView::switchKeyMap()
195 {
196         pimpl_->switchKeyMap();
197 }
198
199
200 int BufferView::workWidth() const
201 {
202         return pimpl_->workarea().workWidth();
203 }
204
205
206 void BufferView::center()
207 {
208         pimpl_->center();
209 }
210
211
212 int BufferView::top_y() const
213 {
214         return pimpl_->top_y();
215 }
216
217
218 void BufferView::top_y(int y)
219 {
220         pimpl_->top_y(y);
221 }
222
223
224 string const BufferView::getClipboard() const
225 {
226         return pimpl_->workarea().getClipboard();
227 }
228
229
230 void BufferView::stuffClipboard(string const & stuff) const
231 {
232         pimpl_->stuffClipboard(stuff);
233 }
234
235
236 bool BufferView::dispatch(FuncRequest const & ev)
237 {
238         return pimpl_->dispatch(ev);
239 }
240
241
242 void BufferView::scroll(int lines)
243 {
244         pimpl_->scroll(lines);
245 }
246
247
248 // Inserts a file into current document
249 bool BufferView::insertLyXFile(string const & filen)
250         //
251         // Copyright CHT Software Service GmbH
252         // Uwe C. Schroeder
253         //
254         // Insert a LyXformat - file into current buffer
255         //
256         // Moved from lyx_cb.C (Lgb)
257 {
258         BOOST_ASSERT(!filen.empty());
259
260         string const fname = MakeAbsPath(filen);
261
262         text()->clearSelection();
263         text()->breakParagraph(buffer()->paragraphs());
264
265         bool res = buffer()->readFile(fname, text()->cursorPar());
266         resize();
267         return res;
268 }
269
270
271 void BufferView::showErrorList(string const & action) const
272 {
273         if (getErrorList().size()) {
274                 string const title = bformat(_("LyX: %1$s errors (%2$s)"),
275                         action, buffer()->fileName());
276                 owner()->getDialogs().show("errorlist", title);
277                 pimpl_->errorlist_.clear();
278         }
279 }
280
281
282 ErrorList const & BufferView::getErrorList() const
283 {
284         return pimpl_->errorlist_;
285 }
286
287
288 void BufferView::setCursorFromRow(int row)
289 {
290         int tmpid = -1;
291         int tmppos = -1;
292
293         buffer()->texrow().getIdFromRow(row, tmpid, tmppos);
294
295         if (tmpid == -1)
296                 text()->setCursor(0, 0);
297         else
298                 text()->setCursor(buffer()->getParFromID(tmpid).pit(), tmppos);
299 }
300
301
302 bool BufferView::insertInset(InsetOld * inset, string const & lout)
303 {
304         return pimpl_->insertInset(inset, lout);
305 }
306
307
308 void BufferView::gotoLabel(string const & label)
309 {
310         for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
311              it != buffer()->inset_iterator_end(); ++it) {
312                 vector<string> labels;
313                 it->getLabelList(*buffer(), labels);
314                 if (find(labels.begin(),labels.end(),label) != labels.end()) {
315                         text()->clearSelection();
316                         text()->setCursor(
317                                 std::distance(text()->paragraphs().begin(), it.getPar()),
318                                 it.getPos());
319                         resetAnchor();
320                         update();
321                         return;
322                 }
323         }
324 }
325
326
327 void BufferView::undo()
328 {
329         if (!available())
330                 return;
331
332         owner()->message(_("Undo"));
333         text()->clearSelection();
334         if (!textUndo(this))
335                 owner()->message(_("No further undo information"));
336         update();
337         switchKeyMap();
338 }
339
340
341 void BufferView::redo()
342 {
343         if (!available())
344                 return;
345
346         owner()->message(_("Redo"));
347         text()->clearSelection();
348         if (!textRedo(this))
349                 owner()->message(_("No further redo information"));
350         update();
351         switchKeyMap();
352 }
353
354
355 void BufferView::replaceWord(string const & replacestring)
356 {
357         if (!available())
358                 return;
359
360         LyXText * t = getLyXText();
361
362         t->replaceSelectionWithString(replacestring);
363         t->setSelectionRange(replacestring.length());
364
365         // Go back so that replacement string is also spellchecked
366         for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
367                 t->cursorLeft(this);
368
369         // FIXME: should be done through LFUN
370         buffer()->markDirty();
371         update();
372 }
373
374
375 void BufferView::hideCursor()
376 {
377         screen().hideCursor();
378 }
379
380
381 bool BufferView::ChangeRefsIfUnique(string const & from, string const & to)
382 {
383         // Check if the label 'from' appears more than once
384         vector<string> labels;
385         buffer()->getLabelList(labels);
386
387         if (lyx::count(labels.begin(), labels.end(), from) > 1)
388                 return false;
389
390         return pimpl_->ChangeInsets(InsetOld::REF_CODE, from, to);
391 }
392
393
394 UpdatableInset * BufferView::innerInset() const
395 {
396         return static_cast<UpdatableInset*>(fullCursor().innerInset());
397 }
398
399
400 LyXText * BufferView::getLyXText() const
401 {
402         return fullCursor().innerText();
403 }
404
405
406 Language const * BufferView::getParentLanguage(InsetOld * inset) const
407 {
408         Paragraph const & par = ownerPar(*buffer(), inset);
409         return par.getFontSettings(buffer()->params(),
410                                    par.getPositionOfInset(inset)).language();
411 }
412
413
414 Encoding const * BufferView::getEncoding() const
415 {
416         LyXText * t = getLyXText();
417         if (!t)
418                 return 0;
419         return t->cursorPar()->getFont(
420                 buffer()->params(),
421                 t->cursor().pos(),
422                 outerFont(t->cursorPar(), t->paragraphs())
423         ).language()->encoding();
424 }
425
426
427 void BufferView::haveSelection(bool sel)
428 {
429         pimpl_->workarea().haveSelection(sel);
430 }
431
432
433 int BufferView::workHeight() const
434 {
435         return pimpl_->workarea().workHeight();
436 }
437
438
439 void BufferView::fullCursor(LCursor const & cur)
440 {
441         pimpl_->cursor_ = cur;
442 }
443
444
445 LCursor & BufferView::fullCursor()
446 {
447         return pimpl_->cursor_;
448 }
449
450
451 LCursor const & BufferView::fullCursor() const
452 {
453         return pimpl_->cursor_;
454 }
455
456
457 CursorSlice & BufferView::cursor()
458 {
459         return fullCursor().cursor_.back();
460 }
461
462
463 CursorSlice const & BufferView::cursor() const
464 {
465         return fullCursor().cursor_.back();
466 }
467
468
469 CursorSlice & BufferView::anchor()
470 {
471         return fullCursor().anchor_.back();
472 }
473
474
475 CursorSlice const & BufferView::anchor() const
476 {
477         return fullCursor().anchor_.back();
478 }
479
480
481 void BufferView::x_target(int x)
482 {
483         x_target_ = x;
484 }
485
486
487 int BufferView::x_target() const
488 {
489         return x_target_;
490 }
491
492
493 void BufferView::updateParagraphDialog()
494 {
495         pimpl_->updateParagraphDialog();
496 }
497
498
499 LyXText * BufferView::text() const
500 {
501         return pimpl_->buffer_ ? &pimpl_->buffer_->text() : 0;
502 }
503
504
505 void BufferView::resetAnchor()
506 {
507         return fullCursor().resetAnchor();
508 }