X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FBufferView.cpp;h=dcaabbefe33ab669853bb85daaf56dddac1e2f4a;hb=a84b8ca6bea87573e77d76aae9bbd25ccf8942f5;hp=438de83b42cfb85db03c8f0619444566a96e6d06;hpb=9d0ea8aeff32833a90b3fe64df0c5518a9e241be;p=lyx.git diff --git a/src/BufferView.cpp b/src/BufferView.cpp index 438de83b42..dcaabbefe3 100644 --- a/src/BufferView.cpp +++ b/src/BufferView.cpp @@ -59,7 +59,6 @@ #include "frontends/alert.h" #include "frontends/Delegates.h" -#include "frontends/FileDialog.h" #include "frontends/FontMetrics.h" #include "frontends/Painter.h" #include "frontends/Selection.h" @@ -75,37 +74,17 @@ #include "support/Package.h" #include "support/types.h" -#include - #include #include #include #include #include -using std::distance; -using std::endl; -using std::ifstream; -using std::istringstream; -using std::istream_iterator; -using std::make_pair; -using std::min; -using std::max; -using std::mem_fun_ref; -using std::string; -using std::vector; +using namespace std; +using namespace lyx::support; namespace lyx { -using support::addPath; -using support::bformat; -using support::FileFilterList; -using support::FileName; -using support::fileSearch; -using support::makeDisplayPath; -using support::makeAbsPath; -using support::package; - namespace Alert = frontend::Alert; namespace { @@ -208,7 +187,7 @@ void gotoInset(BufferView * bv, InsetCode code, bool same_content) /// A map from a Text to the associated text metrics -typedef std::map TextMetricsCache; +typedef map TextMetricsCache; enum ScreenUpdateStrategy { NoScreenUpdate, @@ -413,9 +392,16 @@ void BufferView::processUpdateFlags(Update::flags flags) bool const full_metrics = flags & Update::Force; - if (full_metrics || !singleParUpdate()) + if (full_metrics || !singleParUpdate()) { + if (flags & Update::FitCursor) { + CursorSlice const & bot = d->cursor_.bottom(); + TextMetrics const & tm = d->text_metrics_[bot.text()]; + if (!tm.has(bot.pit())) + center(); + } // We have to update the full screen metrics. updateMetrics(); + } if (!(flags & Update::FitCursor)) { buffer_.changed(); @@ -424,6 +410,7 @@ void BufferView::processUpdateFlags(Update::flags flags) //FIXME: updateMetrics() does not update paragraph position // This is done at draw() time. So we need a redraw! + buffer_.changed(); if (!fitCursor()) // The screen has already been updated thanks to the @@ -449,8 +436,8 @@ void BufferView::updateScrollbar() d->offset_ref_ = 0; } - LYXERR(Debug::GUI, BOOST_CURRENT_FUNCTION - << " Updating scrollbar: height: " << t.paragraphs().size() + LYXERR(Debug::GUI, " Updating scrollbar: height: " + << t.paragraphs().size() << " curr par: " << d->cursor_.bottom().pit() << " default height " << defaultRowHeight()); @@ -463,12 +450,6 @@ void BufferView::updateScrollbar() int h = tm.parMetrics(d->anchor_ref_).height(); - // Normalize anchor/offset (MV): - while (d->offset_ref_ > h && d->anchor_ref_ < parsize) { - d->anchor_ref_++; - d->offset_ref_ -= h; - h = tm.parMetrics(d->anchor_ref_).height(); - } // Look at paragraph heights on-screen int sumh = 0; int nh = 0; @@ -501,7 +482,7 @@ ScrollbarParameters const & BufferView::scrollbarParameters() const void BufferView::scrollDocView(int value) { - LYXERR(Debug::GUI, BOOST_CURRENT_FUNCTION << "[ value = " << value << "]"); + LYXERR(Debug::GUI, "[ value = " << value << "]"); Text & t = buffer_.text(); TextMetrics & tm = d->text_metrics_[&t]; @@ -693,13 +674,20 @@ void BufferView::updateOffsetRef() if (height_ == 0) return; + d->need_centering_ = false; + CursorSlice & bot = d->cursor_.bottom(); TextMetrics & tm = d->text_metrics_[bot.text()]; ParagraphMetrics const & pm = tm.parMetrics(bot.pit()); - int y = coordOffset(d->cursor_, d->cursor_.boundary()).y_; - d->offset_ref_ = y + pm.ascent() - height_ / 2; - - d->need_centering_ = false; + if (d->anchor_ref_ == 0) + d->offset_ref_ = 0; + else if (d->anchor_ref_ >= pos_type(bot.text()->paragraphs().size() - 1)) { + d->anchor_ref_ = bot.text()->paragraphs().size() - 1; + d->offset_ref_ = pm.height() - height_; + } else { + int y = coordOffset(d->cursor_, d->cursor_.boundary()).y_; + d->offset_ref_ = y + pm.ascent() - height_ / 2; + } } @@ -863,12 +851,10 @@ FuncStatus BufferView::getStatus(FuncRequest const & cmd) Update::flags BufferView::dispatch(FuncRequest const & cmd) { - //lyxerr << BOOST_CURRENT_FUNCTION - // << [ cmd = " << cmd << "]" << endl; + //lyxerr << [ cmd = " << cmd << "]" << endl; // Make sure that the cached BufferView is correct. - LYXERR(Debug::ACTION, BOOST_CURRENT_FUNCTION - << " action[" << cmd.action << ']' + LYXERR(Debug::ACTION, " action[" << cmd.action << ']' << " arg[" << to_utf8(cmd.argument()) << ']' << " x[" << cmd.x << ']' << " y[" << cmd.y << ']' @@ -898,21 +884,6 @@ Update::flags BufferView::dispatch(FuncRequest const & cmd) } break; - case LFUN_FILE_INSERT: - // FIXME UNICODE - menuInsertLyXFile(to_utf8(cmd.argument())); - break; - - case LFUN_FILE_INSERT_PLAINTEXT_PARA: - // FIXME UNICODE - insertPlaintextFile(to_utf8(cmd.argument()), true); - break; - - case LFUN_FILE_INSERT_PLAINTEXT: - // FIXME UNICODE - insertPlaintextFile(to_utf8(cmd.argument()), false); - break; - case LFUN_FONT_STATE: cur.message(cur.currentState()); break; @@ -1308,7 +1279,7 @@ Inset const * BufferView::getCoveringInset(Text const & text, int x, int y) void BufferView::mouseEventDispatch(FuncRequest const & cmd0) { - //lyxerr << BOOST_CURRENT_FUNCTION << "[ cmd0 " << cmd0 << "]" << endl; + //lyxerr << "[ cmd0 " << cmd0 << "]" << endl; // This is only called for mouse related events including // LFUN_FILE_OPEN generated by drag-and-drop. @@ -1401,7 +1372,7 @@ void BufferView::scrollDown(int offset) TextMetrics & tm = d->text_metrics_[text]; int ymax = height_ + offset; while (true) { - std::pair last = tm.last(); + pair last = tm.last(); int bottom_pos = last.second->position() + last.second->descent(); if (last.first + 1 == int(text->paragraphs().size())) { if (bottom_pos <= height_) @@ -1425,7 +1396,7 @@ void BufferView::scrollUp(int offset) TextMetrics & tm = d->text_metrics_[text]; int ymin = - offset; while (true) { - std::pair first = tm.first(); + pair first = tm.first(); int top_pos = first.second->position() - first.second->ascent(); if (first.first == 0) { if (top_pos >= 0) @@ -1463,7 +1434,7 @@ void BufferView::gotoLabel(docstring const & label) for (InsetIterator it = inset_iterator_begin(buffer_.inset()); it; ++it) { vector labels; it->getLabelList(buffer_, labels); - if (std::find(labels.begin(), labels.end(), label) != labels.end()) { + if (find(labels.begin(), labels.end(), label) != labels.end()) { setCursor(it); processUpdateFlags(Update::FitCursor); return; @@ -1570,7 +1541,7 @@ bool BufferView::mouseSetCursor(Cursor & cur, bool select) // For an example, see bug 2933: // http://bugzilla.lyx.org/show_bug.cgi?id=2933 // The code below could maybe be moved to a DocIterator method. - //lyxerr << "cur before " << cur <cursor_.setCursor(dit); d->cursor_.boundary(cur.boundary()); @@ -1648,8 +1619,7 @@ bool BufferView::singleParUpdate() d->update_strategy_ = SingleParUpdate; - LYXERR(Debug::PAINTING, BOOST_CURRENT_FUNCTION - << "\ny1: " << pm.position() - pm.ascent() + LYXERR(Debug::PAINTING, "\ny1: " << pm.position() - pm.ascent() << " y2: " << pm.position() + pm.descent() << " pit: " << bottom_pit << " singlepar: 1"); @@ -1724,8 +1694,7 @@ void BufferView::updateMetrics() // Take care of descent of last line y2 += tm.parMetrics(pit2).descent(); - LYXERR(Debug::PAINTING, BOOST_CURRENT_FUNCTION - << "\n y1: " << y1 + LYXERR(Debug::PAINTING, "\n y1: " << y1 << " y2: " << y2 << " pit1: " << pit1 << " pit2: " << pit2 @@ -1734,6 +1703,8 @@ void BufferView::updateMetrics() d->update_strategy_ = FullScreenUpdate; + updateScrollbar(); + if (lyxerr.debugging(Debug::WORKAREA)) { LYXERR(Debug::WORKAREA, "BufferView::updateMetrics"); d->coord_cache_.dump(); @@ -1741,57 +1712,21 @@ void BufferView::updateMetrics() } -void BufferView::menuInsertLyXFile(string const & filenm) +void BufferView::insertLyXFile(FileName const & fname) { BOOST_ASSERT(d->cursor_.inTexted()); - string filename = filenm; - - if (filename.empty()) { - // Launch a file browser - // FIXME UNICODE - string initpath = lyxrc.document_path; - string const trypath = buffer_.filePath(); - // If directory is writeable, use this as default. - if (FileName(trypath).isDirWritable()) - initpath = trypath; - - // FIXME UNICODE - FileDialog dlg(_("Select LyX document to insert"), LFUN_FILE_INSERT); - dlg.setButton1(_("Documents|#o#O"), from_utf8(lyxrc.document_path)); - dlg.setButton2(_("Examples|#E#e"), - from_utf8(addPath(package().system_support().absFilename(), - "examples"))); - - FileDialog::Result result = - dlg.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").absFilename(); + FileName filename = fileSearch(string(), fname.absFilename(), "lyx"); - docstring const disp_fn = makeDisplayPath(filename); + docstring const disp_fn = makeDisplayPath(filename.absFilename()); // emit message signal. message(bformat(_("Inserting document %1$s..."), disp_fn)); docstring res; Buffer buf("", false); - if (buf.loadLyXFile(FileName(filename))) { + if (buf.loadLyXFile(filename)) { ErrorList & el = buffer_.errorList("Parse"); // Copy the inserted document error list into the current buffer one. el = buf.errorList("Parse"); @@ -1803,10 +1738,11 @@ void BufferView::menuInsertLyXFile(string const & filenm) res = _("Could not insert document %1$s"); } + updateMetrics(); + buffer_.changed(); // emit message signal. message(bformat(res, disp_fn)); buffer_.errors("Parse"); - updateMetrics(); } @@ -1872,7 +1808,7 @@ Point BufferView::coordOffset(DocIterator const & dit, bool boundary) const int pos = sl.pos(); if (pos && boundary) --pos; -// lyxerr << "coordOffset: boundary:" << boundary << " depth:" << dit.depth() << " pos:" << pos << " sl.pos:" << sl.pos() << std::endl; +// lyxerr << "coordOffset: boundary:" << boundary << " depth:" << dit.depth() << " pos:" << pos << " sl.pos:" << sl.pos() << endl; rend = pm.pos2row(pos); } else rend = pm.pos2row(sl.pos()); @@ -1954,7 +1890,7 @@ void BufferView::draw(frontend::Painter & pain) tm.draw(pi, 0, y); // and possibly grey out below - std::pair lastpm = tm.last(); + pair lastpm = tm.last(); int const y2 = lastpm.second->position() + lastpm.second->descent(); if (y2 < height_) pain.fillRectangle(0, y2, width_, height_ - y2, Color_bottomarea); @@ -1972,22 +1908,22 @@ void BufferView::message(docstring const & msg) } -void BufferView::showDialog(std::string const & name) +void BufferView::showDialog(string const & name) { if (d->gui_) d->gui_->showDialog(name, string()); } -void BufferView::showDialog(std::string const & name, - std::string const & data, Inset * inset) +void BufferView::showDialog(string const & name, + string const & data, Inset * inset) { if (d->gui_) d->gui_->showDialog(name, data, inset); } -void BufferView::updateDialog(std::string const & name, std::string const & data) +void BufferView::updateDialog(string const & name, string const & data) { if (d->gui_) d->gui_->updateDialog(name, data); @@ -2001,30 +1937,8 @@ void BufferView::setGuiDelegate(frontend::GuiBufferViewDelegate * gui) // FIXME: Move this out of BufferView again -docstring BufferView::contentsOfPlaintextFile(string const & f, - bool asParagraph) +docstring BufferView::contentsOfPlaintextFile(FileName const & fname) { - FileName fname(f); - - if (fname.empty()) { - FileDialog dlg(_("Select file to insert"), - ( asParagraph - ? LFUN_FILE_INSERT_PLAINTEXT_PARA - : LFUN_FILE_INSERT_PLAINTEXT) ); - - FileDialog::Result result = - dlg.open(from_utf8(buffer().filePath()), - FileFilterList(), docstring()); - - if (result.first == FileDialog::Later) - return docstring(); - - if (result.second.empty()) - return docstring(); - - fname = makeAbsPath(to_utf8(result.second)); - } - if (!fname.isReadableFile()) { docstring const error = from_ascii(strerror(errno)); docstring const file = makeDisplayPath(fname.absFilename(), 50); @@ -2035,36 +1949,16 @@ docstring BufferView::contentsOfPlaintextFile(string const & f, return docstring(); } - ifstream ifs(fname.toFilesystemEncoding().c_str()); - if (!ifs) { - docstring const error = from_ascii(strerror(errno)); + if (!fname.isReadableFile()) { docstring const file = makeDisplayPath(fname.absFilename(), 50); docstring const text = - bformat(_("Could not open the specified document\n" - "%1$s\ndue to the error: %2$s"), file, error); + bformat(_("%1$s\n is not readable."), file); Alert::error(_("Could not open file"), text); return docstring(); } - ifs.unsetf(std::ios::skipws); - istream_iterator ii(ifs); - istream_iterator end; -#if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD) - // We use this until the compilers get better... - std::vector tmp; - copy(ii, end, back_inserter(tmp)); - string const tmpstr(tmp.begin(), tmp.end()); -#else - // This is what we want to use and what we will use once the - // compilers get good enough. - //string tmpstr(ii, end); // yet a reason for using std::string - // alternate approach to get the file into a string: - string tmpstr; - copy(ii, end, back_inserter(tmpstr)); -#endif - // FIXME UNICODE: We don't know the encoding of the file - docstring file_content = from_utf8(tmpstr); + docstring file_content = fname.fileContents("UTF-8"); if (file_content.empty()) { Alert::error(_("Reading not UTF-8 encoded file"), _("The file is not UTF-8 encoded.\n" @@ -2072,16 +1966,16 @@ docstring BufferView::contentsOfPlaintextFile(string const & f, "If this does not give the correct result\n" "then please change the encoding of the file\n" "to UTF-8 with a program other than LyX.\n")); - file_content = from_local8bit(tmpstr); + file_content = fname.fileContents("local8bit"); } return normalize_c(file_content); } -void BufferView::insertPlaintextFile(string const & f, bool asParagraph) +void BufferView::insertPlaintextFile(FileName const & f, bool asParagraph) { - docstring const tmpstr = contentsOfPlaintextFile(f, asParagraph); + docstring const tmpstr = contentsOfPlaintextFile(f); if (tmpstr.empty()) return; @@ -2093,6 +1987,9 @@ void BufferView::insertPlaintextFile(string const & f, bool asParagraph) cur.innerText()->insertStringAsParagraphs(cur, tmpstr); else cur.innerText()->insertStringAsLines(cur, tmpstr); + + updateMetrics(); + buffer_.changed(); } } // namespace lyx