3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Alfredo Braunstein
7 * \author Lars Gullik Bjønnes
10 * \author Jürgen Vigna
12 * Full author contact details are available in file CREDITS.
17 #include "BufferView.h"
20 #include "bufferlist.h"
21 #include "BufferView_pimpl.h"
23 #include "funcrequest.h"
25 #include "iterators.h"
27 #include "lyxlayout.h"
29 #include "paragraph.h"
30 #include "paragraph_funcs.h"
31 #include "PosIterator.h"
34 #include "WordLangTuple.h"
36 #include "frontends/Alert.h"
37 #include "frontends/Dialogs.h"
38 #include "frontends/LyXView.h"
39 #include "frontends/screen.h"
40 #include "frontends/WorkArea.h"
42 #include "insets/insetcommand.h" // ChangeRefs
43 #include "insets/updatableinset.h"
45 #include "support/filetools.h"
46 #include "support/lyxalgo.h" // lyx_count
48 using lyx::support::bformat;
49 using lyx::support::MakeAbsPath;
56 extern BufferList bufferlist;
59 BufferView::BufferView(LyXView * owner, int xpos, int ypos,
60 int width, int height)
61 : pimpl_(new Pimpl(this, owner, xpos, ypos, width, height)),
66 BufferView::~BufferView()
72 void BufferView::unsetXSel()
74 pimpl_->xsel_cache_.set = false;
78 Buffer * BufferView::buffer() const
80 return pimpl_->buffer_;
84 LyXScreen & BufferView::screen() const
86 return pimpl_->screen();
90 LyXView * BufferView::owner() const
92 return pimpl_->owner_;
96 Painter & BufferView::painter() const
98 return pimpl_->painter();
102 void BufferView::buffer(Buffer * b)
108 bool BufferView::newFile(string const & fn, string const & tn, bool named)
110 return pimpl_->newFile(fn, tn, named);
114 bool BufferView::loadLyXFile(string const & fn, bool tl)
116 return pimpl_->loadLyXFile(fn, tl);
120 void BufferView::reload()
122 string const fn = buffer()->fileName();
123 if (bufferlist.close(buffer(), false))
128 void BufferView::resize()
131 pimpl_->resizeCurrentBuffer();
135 bool BufferView::fitCursor()
137 return pimpl_->fitCursor();
141 void BufferView::update()
147 void BufferView::updateScrollbar()
149 pimpl_->updateScrollbar();
153 void BufferView::scrollDocView(int value)
155 pimpl_->scrollDocView(value);
159 void BufferView::redoCurrentBuffer()
161 pimpl_->redoCurrentBuffer();
165 bool BufferView::available() const
167 return pimpl_->available();
171 Change const BufferView::getCurrentChange()
173 return pimpl_->getCurrentChange();
177 void BufferView::savePosition(unsigned int i)
179 pimpl_->savePosition(i);
183 void BufferView::restorePosition(unsigned int i)
185 pimpl_->restorePosition(i);
189 bool BufferView::isSavedPosition(unsigned int i)
191 return pimpl_->isSavedPosition(i);
195 void BufferView::switchKeyMap()
197 pimpl_->switchKeyMap();
201 int BufferView::workWidth() const
203 return pimpl_->workarea().workWidth();
207 void BufferView::center()
213 int BufferView::top_y() const
215 return pimpl_->top_y();
219 void BufferView::top_y(int y)
225 string const BufferView::getClipboard() const
227 return pimpl_->workarea().getClipboard();
231 void BufferView::stuffClipboard(string const & stuff) const
233 pimpl_->stuffClipboard(stuff);
237 bool BufferView::dispatch(FuncRequest const & ev)
239 return pimpl_->dispatch(ev);
243 void BufferView::scroll(int lines)
245 pimpl_->scroll(lines);
249 // Inserts a file into current document
250 bool BufferView::insertLyXFile(string const & filen)
252 // Copyright CHT Software Service GmbH
255 // Insert a LyXformat - file into current buffer
257 // Moved from lyx_cb.C (Lgb)
259 BOOST_ASSERT(!filen.empty());
261 string const fname = MakeAbsPath(filen);
264 text()->breakParagraph(buffer()->paragraphs());
266 bool res = buffer()->readFile(fname, text()->cursorPar());
272 void BufferView::showErrorList(string const & action) const
274 if (getErrorList().size()) {
275 string const title = bformat(_("LyX: %1$s errors (%2$s)"),
276 action, buffer()->fileName());
277 owner()->getDialogs().show("errorlist", title);
278 pimpl_->errorlist_.clear();
283 ErrorList const & BufferView::getErrorList() const
285 return pimpl_->errorlist_;
289 void BufferView::setCursorFromRow(int row)
294 buffer()->texrow().getIdFromRow(row, tmpid, tmppos);
297 text()->setCursor(0, 0);
299 text()->setCursor(buffer()->getParFromID(tmpid).pit(), tmppos);
303 bool BufferView::insertInset(InsetOld * inset, string const & lout)
305 return pimpl_->insertInset(inset, lout);
309 void BufferView::gotoLabel(string const & label)
311 for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
312 it != buffer()->inset_iterator_end(); ++it) {
313 vector<string> labels;
314 it->getLabelList(*buffer(), labels);
315 if (find(labels.begin(),labels.end(),label) != labels.end()) {
318 std::distance(text()->paragraphs().begin(), it.getPar()),
328 void BufferView::undo()
333 owner()->message(_("Undo"));
336 owner()->message(_("No further undo information"));
342 void BufferView::redo()
347 owner()->message(_("Redo"));
350 owner()->message(_("No further redo information"));
356 void BufferView::replaceWord(string const & replacestring)
361 LyXText * t = getLyXText();
363 t->replaceSelectionWithString(replacestring);
364 t->setSelectionRange(replacestring.length());
366 // Go back so that replacement string is also spellchecked
367 for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
370 // FIXME: should be done through LFUN
371 buffer()->markDirty();
376 void BufferView::hideCursor()
378 screen().hideCursor();
382 bool BufferView::ChangeRefsIfUnique(string const & from, string const & to)
384 // Check if the label 'from' appears more than once
385 vector<string> labels;
386 buffer()->getLabelList(labels);
388 if (lyx::count(labels.begin(), labels.end(), from) > 1)
391 return pimpl_->ChangeInsets(InsetOld::REF_CODE, from, to);
395 UpdatableInset * BufferView::innerInset() const
397 return static_cast<UpdatableInset*>(fullCursor().innerInset());
401 LyXText * BufferView::getLyXText() const
403 return fullCursor().innerText();
407 Language const * BufferView::getParentLanguage(InsetOld * inset) const
409 Paragraph const & par = ownerPar(*buffer(), inset);
410 return par.getFontSettings(buffer()->params(),
411 par.getPositionOfInset(inset)).language();
415 Encoding const * BufferView::getEncoding() const
417 LyXText * t = getLyXText();
420 return t->cursorPar()->getFont(
423 outerFont(t->cursorPar(), t->paragraphs())
424 ).language()->encoding();
428 void BufferView::haveSelection(bool sel)
430 pimpl_->workarea().haveSelection(sel);
434 int BufferView::workHeight() const
436 return pimpl_->workarea().workHeight();
440 void BufferView::fullCursor(LCursor const & cur)
442 pimpl_->cursor_ = cur;
446 LCursor & BufferView::fullCursor()
448 return pimpl_->cursor_;
452 LCursor const & BufferView::fullCursor() const
454 return pimpl_->cursor_;
458 CursorSlice & BufferView::cursor()
460 return fullCursor().cursor_.back();
464 CursorSlice const & BufferView::cursor() const
466 return fullCursor().cursor_.back();
470 CursorSlice & BufferView::anchor()
472 return fullCursor().anchor_.back();
476 CursorSlice const & BufferView::anchor() const
478 return fullCursor().anchor_.back();
482 Selection & BufferView::selection()
488 Selection const & BufferView::selection() const
494 void BufferView::x_target(int x)
500 int BufferView::x_target() const
506 void BufferView::updateParagraphDialog()
508 pimpl_->updateParagraphDialog();
512 LyXText * BufferView::text() const
514 return pimpl_->buffer_ ? &pimpl_->buffer_->text() : 0;
518 void BufferView::resetAnchor()
520 return fullCursor().resetAnchor();
524 CursorSlice const & BufferView::selStart() const
526 if (!selection().set())
528 // can't use std::min as this creates a new object
529 return anchor() < cursor() ? anchor() : cursor();
533 CursorSlice const & BufferView::selEnd() const
535 if (!selection().set())
537 return anchor() > cursor() ? anchor() : cursor();
541 CursorSlice & BufferView::selStart()
543 if (!selection().set())
545 return anchor() < cursor() ? anchor() : cursor();
549 CursorSlice & BufferView::selEnd()
551 if (selection().set())
553 return anchor() > cursor() ? anchor() : cursor();
557 void BufferView::setSelection()
559 selection().set(true);
560 // a selection with no contents is not a selection
561 if (cursor().par() == anchor().par() && cursor().pos() == anchor().pos())
562 selection().set(false);
566 void BufferView::clearSelection()
568 selection().set(false);
569 selection().mark(false);
577 if the fitCursor call refers to some point in never-explored-land, then we
578 don't have y information in insets there, then we cannot even do an update
579 to get it (because we need the y infomation for setting top_y first). So
580 this is solved in put_selection_at with:
582 - setting top_y to the y of the outerPar (that has good info)
584 - calling cursor().updatePos()
585 - then call fitCursor()
590 void BufferView::putSelectionAt(PosIterator const & cur,
591 int length, bool backwards)
593 ParIterator par(cur);
597 LyXText * text = par.text(*buffer());
599 // hack for the chicken and egg problem
601 top_y(par.outerPar()->y);
603 text->setCursor(cur.pit(), cur.pos());
604 fullCursor().updatePos();
607 text->setSelectionRange(length);
610 std::swap(cursor(), anchor());