+
+
+pit_type BufferView::anchor_ref() const
+{
+ return anchor_ref_;
+}
+
+
+ViewMetricsInfo const & BufferView::viewMetricsInfo()
+{
+ return metrics_info_;
+}
+
+
+void BufferView::updateMetrics(bool singlepar)
+{
+ // Clear out the position cache in case of full screen redraw.
+ if (!singlepar)
+ coord_cache_.clear();
+
+ LyXText & buftext = buffer_->text();
+ pit_type size = int(buftext.paragraphs().size());
+
+ if (anchor_ref_ > int(buftext.paragraphs().size() - 1)) {
+ anchor_ref_ = int(buftext.paragraphs().size() - 1);
+ offset_ref_ = 0;
+ }
+
+ pit_type const pit = anchor_ref_;
+ int pit1 = pit;
+ int pit2 = pit;
+ size_t const npit = buftext.paragraphs().size();
+
+ // Rebreak anchor paragraph. In Single Paragraph mode, rebreak only
+ // the (main text, not inset!) paragraph containing the cursor.
+ // (if this paragraph contains insets etc., rebreaking will
+ // recursively descend)
+ if (!singlepar || pit == cursor_.bottom().pit())
+ buftext.redoParagraph(*this, pit);
+ int y0 = buftext.getPar(pit).ascent() - offset_ref_;
+
+ // Redo paragraphs above anchor if necessary; again, in Single Par
+ // mode, only if we encounter the (main text) one having the cursor.
+ int y1 = y0;
+ while (y1 > 0 && pit1 > 0) {
+ y1 -= buftext.getPar(pit1).ascent();
+ --pit1;
+ if (!singlepar || pit1 == cursor_.bottom().pit())
+ buftext.redoParagraph(*this, pit1);
+ y1 -= buftext.getPar(pit1).descent();
+ }
+
+
+ // Take care of ascent of first line
+ y1 -= buftext.getPar(pit1).ascent();
+
+ // Normalize anchor for next time
+ anchor_ref_ = pit1;
+ offset_ref_ = -y1;
+
+ // Grey at the beginning is ugly
+ if (pit1 == 0 && y1 > 0) {
+ y0 -= y1;
+ y1 = 0;
+ anchor_ref_ = 0;
+ }
+
+ // Redo paragraphs below the anchor if necessary. Single par mode:
+ // only the one containing the cursor if encountered.
+ int y2 = y0;
+ while (y2 < height_ && pit2 < int(npit) - 1) {
+ y2 += buftext.getPar(pit2).descent();
+ ++pit2;
+ if (!singlepar || pit2 == cursor_.bottom().pit())
+ buftext.redoParagraph(*this, pit2);
+ y2 += buftext.getPar(pit2).ascent();
+ }
+
+ // Take care of descent of last line
+ y2 += buftext.getPar(pit2).descent();
+
+ // The coordinates of all these paragraphs are correct, cache them
+ int y = y1;
+ CoordCache::InnerParPosCache & parPos = coord_cache_.parPos()[&buftext];
+ for (pit_type pit = pit1; pit <= pit2; ++pit) {
+ Paragraph const & par = buftext.getPar(pit);
+ y += par.ascent();
+ parPos[pit] = Point(0, y);
+ if (singlepar && pit == cursor_.bottom().pit()) {
+ // In Single Paragraph mode, collect here the
+ // y1 and y2 of the (one) paragraph the cursor is in
+ y1 = y - par.ascent();
+ y2 = y + par.descent();
+ }
+ y += par.descent();
+ }
+
+ if (singlepar) {
+ // collect cursor paragraph iter bounds
+ pit1 = cursor_.bottom().pit();
+ pit2 = cursor_.bottom().pit();
+ }
+
+ lyxerr[Debug::DEBUG]
+ << BOOST_CURRENT_FUNCTION
+ << " y1: " << y1
+ << " y2: " << y2
+ << " pit1: " << pit1
+ << " pit2: " << pit2
+ << " npit: " << npit
+ << " singlepar: " << singlepar
+ << "size: " << size
+ << endl;
+
+ metrics_info_ = ViewMetricsInfo(pit1, pit2, y1, y2, singlepar, size);
+
+ if (lyxerr.debugging(Debug::WORKAREA)) {
+ lyxerr[Debug::WORKAREA] << "BufferView::updateMetrics" << endl;
+ coord_cache_.dump();
+ }
+}
+
+
+void BufferView::menuInsertLyXFile(string const & filenm)
+{
+ BOOST_ASSERT(cursor_.inTexted());
+ string filename = filenm;
+
+ if (filename.empty()) {
+ // Launch a file browser
+ // FIXME UNICODE
+ string initpath = lyxrc.document_path;
+
+ if (buffer_) {
+ string const trypath = buffer_->filePath();
+ // If directory is writeable, use this as default.
+ if (isDirWriteable(trypath))
+ initpath = trypath;
+ }
+
+ // FIXME UNICODE
+ FileDialog fileDlg(_("Select LyX document to insert"),
+ LFUN_FILE_INSERT,
+ make_pair(_("Documents|#o#O"), from_utf8(lyxrc.document_path)),
+ make_pair(_("Examples|#E#e"), from_utf8(addPath(package().system_support(), "examples"))));
+
+ FileDialog::Result result =
+ fileDlg.open(from_utf8(initpath),
+ FileFilterList(_("LyX Documents (*.lyx)")),
+ docstring());
+
+ if (result.first == FileDialog::Later)
+ return;
+
+ // FIXME UNICODE
+ filename = to_utf8(result.second);
+
+ // check selected filename
+ if (filename.empty()) {
+ // emit message signal.
+ message(_("Canceled."));
+ return;
+ }
+ }
+
+ // Get absolute path of file and add ".lyx"
+ // to the filename if necessary
+ filename = fileSearch(string(), filename, "lyx");
+
+ docstring const disp_fn = makeDisplayPath(filename);
+ // emit message signal.
+ message(bformat(_("Inserting document %1$s..."), disp_fn));
+
+ docstring res;
+ Buffer buf("", false);
+ if (lyx::loadLyXFile(&buf, makeAbsPath(filename))) {
+ ErrorList & el = buffer_->errorList("Parse");
+ // Copy the inserted document error list into the current buffer one.
+ el = buf.errorList("Parse");
+ recordUndo(cursor_);
+ cap::pasteParagraphList(cursor_, buf.paragraphs(),
+ buf.params().textclass, el);
+ res = _("Document %1$s inserted.");
+ } else
+ res = _("Could not insert document %1$s");
+
+ // emit message signal.
+ message(bformat(res, disp_fn));
+ buffer_->errors("Parse");
+ resize();
+}
+
+
+} // namespace lyx