#include "buffer_funcs.h"
#include "BufferList.h"
#include "BufferParams.h"
-#include "callback.h" // added for Dispatch functions
#include "CoordCache.h"
#include "CutAndPaste.h"
#include "debug.h"
#include "insets/InsetText.h"
#include "frontends/alert.h"
+#include "frontends/Delegates.h"
#include "frontends/FileDialog.h"
#include "frontends/FontMetrics.h"
#include "frontends/Painter.h"
#include "support/filetools.h"
#include "support/Package.h"
#include "support/types.h"
+#include "support/fs_extras.h"
#include <boost/bind.hpp>
#include <boost/current_function.hpp>
+#include <boost/next_prior.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <cerrno>
+#include <fstream>
#include <functional>
#include <vector>
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::string;
using std::vector;
+namespace fs = boost::filesystem;
namespace lyx {
using support::isDirWriteable;
using support::isFileReadable;
using support::makeDisplayPath;
+using support::makeAbsPath;
using support::package;
namespace Alert = frontend::Alert;
: width_(0), height_(0), buffer_(buf), wh_(0),
cursor_(*this),
multiparsel_cache_(false), anchor_ref_(0), offset_ref_(0),
- need_centering_(false), intl_(new Intl), last_inset_(0)
+ need_centering_(false), intl_(new Intl), last_inset_(0),
+ gui_(0)
{
xsel_cache_.set = false;
intl_->initKeyMapper(lyxrc.use_kbmap);
case LFUN_FILE_INSERT_PLAINTEXT_PARA:
// FIXME UNICODE
- insertPlaintextFile(this, to_utf8(cmd.argument()), true);
+ insertPlaintextFile(to_utf8(cmd.argument()), true);
break;
case LFUN_FILE_INSERT_PLAINTEXT:
// FIXME UNICODE
- insertPlaintextFile(this, to_utf8(cmd.argument()), false);
+ insertPlaintextFile(to_utf8(cmd.argument()), false);
break;
case LFUN_FONT_STATE:
}
-bool BufferView::workAreaDispatch(FuncRequest const & cmd0)
+void BufferView::mouseEventDispatch(FuncRequest const & cmd0)
{
//lyxerr << BOOST_CURRENT_FUNCTION << "[ cmd0 " << cmd0 << "]" << endl;
getCoveringInset(buffer_.text(), cmd.x, cmd.y);
if (covering_inset == last_inset_)
// Same inset, no need to do anything...
- return false;
+ return;
bool need_redraw = false;
// const_cast because of setMouseHover().
need_redraw |= inset->setMouseHover(true);
last_inset_ = inset;
if (!need_redraw)
- return false;
+ return;
// if last metrics update was in singlepar mode, WorkArea::redraw() will
// not expose the button for redraw. We adjust here the metrics dimension
// This event (moving without mouse click) is not passed further.
// This should be changed if it is further utilized.
- return true;
+ buffer_.changed();
+ return;
}
// Build temporary cursor.
// via the temp cursor. If the inset wishes to change the real
// cursor it has to do so explicitly by using
// cur.bv().cursor() = cur; (or similar)
- if (inset) {
+ if (inset)
inset->dispatch(cur, cmd);
- }
// Now dispatch to the temporary cursor. If the real cursor should
// be modified, the inset's dispatch has to do so explicitly.
//Do we have a selection?
theSelection().haveSelection(cursor().selection());
- // Redraw if requested and necessary.
- if (cur.result().dispatched() && cur.result().update())
- return update(cur.result().update());
-
- return false;
+ // If the command has been dispatched,
+ if (cur.result().dispatched()
+ // an update is asked,
+ && cur.result().update()
+ // and redraw is needed,
+ && update(cur.result().update()))
+ // then trigger a redraw.
+ buffer_.changed();
}
height_ - metrics_info_.y2, Color::bottomarea);
}
+
+void BufferView::message(docstring const & msg)
+{
+ if (gui_)
+ gui_->message(msg);
+}
+
+
+void BufferView::showDialog(std::string const & name)
+{
+ if (gui_)
+ gui_->showDialog(name);
+}
+
+
+void BufferView::showDialogWithData(std::string const & name,
+ std::string const & data)
+{
+ if (gui_)
+ gui_->showDialogWithData(name, data);
+}
+
+
+void BufferView::showInsetDialog(std::string const & name,
+ std::string const & data, Inset * inset)
+{
+ if (gui_)
+ gui_->showInsetDialog(name, data, inset);
+}
+
+
+void BufferView::updateDialog(std::string const & name, std::string const & data)
+{
+ if (gui_)
+ gui_->updateDialog(name, data);
+}
+
+
+void BufferView::setGuiDelegate(frontend::GuiBufferViewDelegate * gui)
+{
+ gui_ = gui;
+}
+
+
+// FIXME: Move this out of BufferView again
+docstring BufferView::contentsOfPlaintextFile(string const & f,
+ bool asParagraph)
+{
+ FileName fname(f);
+
+ if (fname.empty()) {
+ FileDialog fileDlg(_("Select file to insert"),
+ ( asParagraph
+ ? LFUN_FILE_INSERT_PLAINTEXT_PARA
+ : LFUN_FILE_INSERT_PLAINTEXT) );
+
+ FileDialog::Result result =
+ fileDlg.open(from_utf8(buffer().filePath()),
+ FileFilterList(), docstring());
+
+ if (result.first == FileDialog::Later)
+ return docstring();
+
+ fname = makeAbsPath(to_utf8(result.second));
+
+ if (fname.empty())
+ return docstring();
+ }
+
+ if (!fs::is_readable(fname.toFilesystemEncoding())) {
+ docstring const error = from_ascii(strerror(errno));
+ docstring const file = makeDisplayPath(fname.absFilename(), 50);
+ docstring const text =
+ bformat(_("Could not read the specified document\n"
+ "%1$s\ndue to the error: %2$s"), file, error);
+ Alert::error(_("Could not read file"), text);
+ return docstring();
+ }
+
+ ifstream ifs(fname.toFilesystemEncoding().c_str());
+ if (!ifs) {
+ docstring const error = from_ascii(strerror(errno));
+ 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);
+ Alert::error(_("Could not open file"), text);
+ return docstring();
+ }
+
+ ifs.unsetf(std::ios::skipws);
+ istream_iterator<char> ii(ifs);
+ istream_iterator<char> end;
+#if !defined(USE_INCLUDED_STRING) && !defined(STD_STRING_IS_GOOD)
+ // We use this until the compilers get better...
+ std::vector<char> 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);
+ if (file_content.empty()) {
+ Alert::error(_("Reading not UTF-8 encoded file"),
+ _("The file is not UTF-8 encoded.\n"
+ "It will be read as local 8Bit-encoded.\n"
+ "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);
+ }
+
+ return normalize_c(file_content);
+}
+
+
+void BufferView::insertPlaintextFile(string const & f, bool asParagraph)
+{
+ docstring const tmpstr = contentsOfPlaintextFile(f, asParagraph);
+
+ if (tmpstr.empty())
+ return;
+
+ Cursor & cur = cursor();
+ cap::replaceSelection(cur);
+ recordUndo(cur);
+ if (asParagraph)
+ cur.innerText()->insertStringAsParagraphs(cur, tmpstr);
+ else
+ cur.innerText()->insertStringAsLines(cur, tmpstr);
+}
+
+
} // namespace lyx