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;
58 extern BufferList bufferlist;
61 BufferView::BufferView(LyXView * owner, int xpos, int ypos,
62 int width, int height)
63 : pimpl_(new Pimpl(*this, owner, xpos, ypos, width, height))
67 BufferView::~BufferView()
73 void BufferView::unsetXSel()
75 pimpl_->xsel_cache_.set = false;
79 Buffer * BufferView::buffer() const
81 return pimpl_->buffer_;
85 LyXScreen & BufferView::screen() const
87 return pimpl_->screen();
91 LyXView * BufferView::owner() const
93 return pimpl_->owner_;
97 Painter & BufferView::painter() const
99 return pimpl_->painter();
103 void BufferView::buffer(Buffer * b)
109 bool BufferView::newFile(string const & fn, string const & tn, bool named)
111 return pimpl_->newFile(fn, tn, named);
115 bool BufferView::loadLyXFile(string const & fn, bool tl)
117 return pimpl_->loadLyXFile(fn, tl);
121 void BufferView::reload()
123 string const fn = buffer()->fileName();
124 if (bufferlist.close(buffer(), false))
129 void BufferView::resize()
132 pimpl_->resizeCurrentBuffer();
136 bool BufferView::fitCursor()
138 return pimpl_->fitCursor();
142 void BufferView::update()
148 void BufferView::updateScrollbar()
150 pimpl_->updateScrollbar();
154 void BufferView::scrollDocView(int value)
156 pimpl_->scrollDocView(value);
160 void BufferView::redoCurrentBuffer()
162 pimpl_->redoCurrentBuffer();
166 bool BufferView::available() const
168 return pimpl_->available();
172 Change const BufferView::getCurrentChange()
174 return pimpl_->getCurrentChange();
178 void BufferView::savePosition(unsigned int i)
180 pimpl_->savePosition(i);
184 void BufferView::restorePosition(unsigned int i)
186 pimpl_->restorePosition(i);
190 bool BufferView::isSavedPosition(unsigned int i)
192 return pimpl_->isSavedPosition(i);
196 void BufferView::switchKeyMap()
198 pimpl_->switchKeyMap();
202 int BufferView::workWidth() const
204 return pimpl_->workarea().workWidth();
208 void BufferView::center()
214 int BufferView::top_y() const
216 return pimpl_->top_y();
220 void BufferView::top_y(int y)
226 string const BufferView::getClipboard() const
228 return pimpl_->workarea().getClipboard();
232 void BufferView::stuffClipboard(string const & stuff) const
234 pimpl_->stuffClipboard(stuff);
238 bool BufferView::dispatch(FuncRequest const & ev)
240 return pimpl_->dispatch(ev);
244 void BufferView::scroll(int lines)
246 pimpl_->scroll(lines);
250 // Inserts a file into current document
251 bool BufferView::insertLyXFile(string const & filen)
253 // Copyright CHT Software Service GmbH
256 // Insert a LyXformat - file into current buffer
258 // Moved from lyx_cb.C (Lgb)
260 BOOST_ASSERT(!filen.empty());
262 string const fname = MakeAbsPath(filen);
264 cursor().clearSelection();
265 text()->breakParagraph(buffer()->paragraphs());
267 bool res = buffer()->readFile(fname, text()->cursorPar());
273 void BufferView::showErrorList(string const & action) const
275 if (getErrorList().size()) {
276 string const title = bformat(_("LyX: %1$s errors (%2$s)"),
277 action, buffer()->fileName());
278 owner()->getDialogs().show("errorlist", title);
279 pimpl_->errorlist_.clear();
284 ErrorList const & BufferView::getErrorList() const
286 return pimpl_->errorlist_;
290 void BufferView::setCursorFromRow(int row)
295 buffer()->texrow().getIdFromRow(row, tmpid, tmppos);
298 text()->setCursor(0, 0);
300 text()->setCursor(buffer()->getParFromID(tmpid).pit(), tmppos);
304 bool BufferView::insertInset(InsetBase * inset, string const & lout)
306 return pimpl_->insertInset(inset, lout);
310 void BufferView::gotoLabel(string const & label)
312 for (Buffer::inset_iterator it = buffer()->inset_iterator_begin();
313 it != buffer()->inset_iterator_end(); ++it) {
314 vector<string> labels;
315 it->getLabelList(*buffer(), labels);
316 if (find(labels.begin(),labels.end(),label) != labels.end()) {
317 cursor().clearSelection();
319 distance(text()->paragraphs().begin(), it.getPar()),
321 cursor().resetAnchor();
329 void BufferView::undo()
334 owner()->message(_("Undo"));
335 cursor().clearSelection();
336 if (!textUndo(*this))
337 owner()->message(_("No further undo information"));
343 void BufferView::redo()
348 owner()->message(_("Redo"));
349 cursor().clearSelection();
350 if (!textRedo(*this))
351 owner()->message(_("No further redo information"));
357 void BufferView::replaceWord(string const & replacestring)
362 LyXText * t = getLyXText();
364 t->replaceSelectionWithString(replacestring);
365 t->setSelectionRange(replacestring.length());
367 // Go back so that replacement string is also spellchecked
368 for (string::size_type i = 0; i < replacestring.length() + 1; ++i)
371 // FIXME: should be done through LFUN
372 buffer()->markDirty();
377 void BufferView::hideCursor()
379 screen().hideCursor();
383 bool BufferView::ChangeRefsIfUnique(string const & from, string const & to)
385 // Check if the label 'from' appears more than once
386 vector<string> labels;
387 buffer()->getLabelList(labels);
389 if (lyx::count(labels.begin(), labels.end(), from) > 1)
392 return pimpl_->ChangeInsets(InsetOld::REF_CODE, from, to);
396 LyXText * BufferView::getLyXText() const
398 return cursor().innerText();
402 Language const * BufferView::getParentLanguage(InsetOld * inset) const
404 Paragraph const & par = ownerPar(*buffer(), inset);
405 return par.getFontSettings(buffer()->params(),
406 par.getPositionOfInset(inset)).language();
410 Encoding const * BufferView::getEncoding() const
412 LyXText * t = getLyXText();
415 CursorSlice const & cur = cursor().innerTextSlice();
416 return t->getPar(cur.par())->getFont(
417 buffer()->params(), cur.pos(),
418 outerFont(t->getPar(cur.par()), t->paragraphs())
419 ).language()->encoding();
423 void BufferView::haveSelection(bool sel)
425 pimpl_->workarea().haveSelection(sel);
429 int BufferView::workHeight() const
431 return pimpl_->workarea().workHeight();
435 void BufferView::updateParagraphDialog()
437 pimpl_->updateParagraphDialog();
441 LyXText * BufferView::text() const
443 return pimpl_->buffer_ ? &pimpl_->buffer_->text() : 0;
447 void BufferView::setCursor(ParIterator const & par,
450 LCursor & cur = cursor();
452 ParIterator::PosHolder const & positions = par.positions();
453 int const last = par.size() - 1;
454 for (int i = 0; i < last; ++i)
455 (*positions[i].it)->inset->edit(cur, true);
457 LyXText * lt = par.text(*buffer());
458 lt->setCursor(par.pit(), pos);
463 if the fitCursor call refers to some point in never-explored-land, then we
464 don't have y information in insets there, then we cannot even do an update
465 to get it (because we need the y infomation for setting top_y first). So
466 this is solved in putSelectionAt with:
468 - setting top_y to the y of the outerPar (that has good info)
470 - calling cursor().updatePos()
471 - then call fitCursor()
476 void BufferView::putSelectionAt(PosIterator const & cur,
477 int length, bool backwards)
479 ParIterator par(cur);
481 cursor().clearSelection();
483 LyXText * text = par.text(*buffer());
484 setCursor(par, cur.pos());
486 // hack for the chicken and egg problem
488 top_y(par.outerPar()->y);
490 text->setCursor(cur.pit(), cur.pos());
491 cursor().updatePos();
494 text->setSelectionRange(length);
495 cursor().setSelection();
497 swap(cursor().cursor_, cursor().anchor_);
505 LCursor & BufferView::cursor()
507 return pimpl_->cursor_;
511 LCursor const & BufferView::cursor() const
513 return pimpl_->cursor_;