* \author André Pönitz
* \author Dekel Tsur
* \author Jürgen Vigna
+ * \author Abdelrazak Younes
*
* Full author contact details are available in file CREDITS.
*/
#include "CutAndPaste.h"
#include "debug.h"
#include "dispatchresult.h"
+#include "errorlist.h"
#include "factory.h"
#include "FloatList.h"
#include "funcrequest.h"
unsigned int const saved_positions_num = 20;
+
/// Return an inset of this class if it exists at the current cursor position
template <class T>
T * getInsetByCode(LCursor & cur, InsetBase::Code code)
BufferView::Pimpl::Pimpl(BufferView & bv, LyXView * owner)
: bv_(&bv), owner_(owner), buffer_(0), wh_(0),
cursor_(bv),
- multiparsel_cache_(false), anchor_ref_(0), offset_ref_(0), needs_redraw_(false)
+ multiparsel_cache_(false), anchor_ref_(0), offset_ref_(0)
{
xsel_cache_.set = false;
}
-void BufferView::Pimpl::addError(ErrorItem const & ei)
-{
- errorlist_.push_back(ei);
-}
-
-
-void BufferView::Pimpl::showReadonly(bool)
-{
- owner_->updateWindowTitle();
- owner_->getDialogs().updateBufferDependent(false);
-}
-
-
-void BufferView::Pimpl::connectBuffer(Buffer & buf)
-{
- if (errorConnection_.connected())
- disconnectBuffer();
-
- errorConnection_ =
- buf.error.connect(
- boost::bind(&BufferView::Pimpl::addError, this, _1));
-
- messageConnection_ =
- buf.message.connect(
- boost::bind(&LyXView::message, owner_, _1));
-
- busyConnection_ =
- buf.busy.connect(
- boost::bind(&LyXView::busy, owner_, _1));
-
- titleConnection_ =
- buf.updateTitles.connect(
- boost::bind(&LyXView::updateWindowTitle, owner_));
-
- timerConnection_ =
- buf.resetAutosaveTimers.connect(
- boost::bind(&LyXView::resetAutosaveTimer, owner_));
-
- readonlyConnection_ =
- buf.readonly.connect(
- boost::bind(&BufferView::Pimpl::showReadonly, this, _1));
-
- closingConnection_ =
- buf.closing.connect(
- boost::bind(&BufferView::Pimpl::setBuffer, this, (Buffer *)0));
-}
-
-
-void BufferView::Pimpl::disconnectBuffer()
-{
- errorConnection_.disconnect();
- messageConnection_.disconnect();
- busyConnection_.disconnect();
- titleConnection_.disconnect();
- timerConnection_.disconnect();
- readonlyConnection_.disconnect();
- closingConnection_.disconnect();
-}
-
-
-void BufferView::Pimpl::newFile(string const & filename, string const & tname,
- bool isNamed)
-{
- setBuffer(::newFile(filename, tname, isNamed));
-}
-
-
bool BufferView::Pimpl::loadLyXFile(string const & filename, bool tolastfiles)
{
// Get absolute path of file and add ".lyx"
if (found) {
b = bufferlist.newBuffer(s);
- connectBuffer(*b);
if (!::loadLyXFile(b, s)) {
bufferlist.release(b);
return false;
int const ret = Alert::prompt(_("Create new document?"),
text, 0, 1, _("&Create"), _("Cancel"));
- if (ret == 0)
- b = ::newFile(s, string(), true);
- else
+ if (ret == 0) {
+ b = newFile(s, string(), true);
+ if (!b)
+ return false;
+ } else
return false;
}
setBuffer(b);
- bv_->showErrorList(_("Parse"));
+ // Send the "errors" signal in case of parsing errors
+ b->errors("Parse");
// scroll to the position when the file was last closed
if (lyxrc.use_lastfilepos) {
}
-lyx::frontend::Gui & BufferView::Pimpl::gui() const
-{
- return owner_->gui();
-}
-
-
int BufferView::Pimpl::width() const
{
return width_;
<< "[ b = " << b << "]" << endl;
if (buffer_) {
- disconnectBuffer();
// Save the actual cursor position and anchor inside the
// buffer so that it can be restored in case we rechange
// to this buffer later on.
boost::tie(cursor_.pit(), cursor_.pos()) );
}
+ // If we're quitting lyx, don't bother updating stuff
+ if (quitting) {
+ buffer_ = 0;
+ return;
+ }
+
// If we are closing current buffer, switch to the first in
// buffer list.
if (!b) {
<< " No Buffer!" << endl;
// We are closing the buffer, use the first buffer as current
buffer_ = bufferlist.first();
- owner_->getDialogs().hideBufferDependent();
} else {
// Set current buffer
buffer_ = b;
anchor_ref_ = 0;
offset_ref_ = 0;
-
- // If we're quitting lyx, don't bother updating stuff
- if (quitting)
- return;
-
if (buffer_) {
lyxerr[Debug::INFO] << BOOST_CURRENT_FUNCTION
<< "Buffer addr: " << buffer_ << endl;
- connectBuffer(*buffer_);
cursor_.push(buffer_->inset());
cursor_.resetAnchor();
buffer_->text().init(bv_);
cursor_.setCursor(buffer_->getCursor().asDocIterator(&(buffer_->inset())));
cursor_.setSelection();
}
-
- // Buffer-dependent dialogs should be updated or
- // hidden. This should go here because some dialogs (eg ToC)
- // require bv_->text.
- owner_->getDialogs().updateBufferDependent(true);
}
update();
- owner_->updateMenubar();
- owner_->updateToolbars();
- owner_->updateLayoutChoice();
- owner_->updateWindowTitle();
+
+ if (buffer_ && lyx::graphics::Previews::status() != LyXRC::PREVIEW_OFF)
+ lyx::graphics::Previews::get().generateBufferPreviews(*buffer_);
+}
+
+string BufferView::Pimpl::firstLayout()
+{
+ string firstlayout;
// This is done after the layout combox has been populated
if (buffer_) {
CursorSlice const & slice = cursor_[i];
if (!slice.inset().inMathed()) {
LyXLayout_ptr const layout = slice.paragraph().layout();
- owner_->setLayout(layout->name());
+ firstlayout = layout->name();
break;
}
BOOST_ASSERT(i>0);
--i;
}
}
-
- if (buffer_ && lyx::graphics::Previews::status() != LyXRC::PREVIEW_OFF)
- lyx::graphics::Previews::get().generateBufferPreviews(*buffer_);
+ return firstlayout;
}
void BufferView::Pimpl::resizeCurrentBuffer()
{
lyxerr[Debug::DEBUG] << BOOST_CURRENT_FUNCTION << endl;
- owner_->busy(true);
- owner_->message(_("Formatting document..."));
LyXText * text = bv_->text();
if (!text)
text->init(bv_);
update();
-
switchKeyMap();
- owner_->busy(false);
-
- // Reset the "Formatting..." message
- owner_->clearMessage();
}
t.redoParagraph(anchor_ref_);
int const h = t.getPar(anchor_ref_).height();
offset_ref_ = int((bar * t.paragraphs().size() - anchor_ref_) * h);
- update();
+}
- if (!lyxrc.cursor_follows_scrollbar)
- return;
+
+void BufferView::Pimpl::setCursorFromScrollbar()
+{
+ LyXText & t = *bv_->text();
int const height = 2 * defaultRowHeight();
int const first = height;
t.setCursorFromCoordinates(cur, 0, newy);
}
}
- owner_->updateLayoutChoice();
}
// scrollDocView(new_top_y);
//
// // Update the scrollbar.
-// workArea_->setScrollbarParams(t->height(), top_y(), defaultRowHeight());
-}
-
-
-void BufferView::Pimpl::workAreaKeyPress(LyXKeySymPtr key,
- key_modifier::state state)
-{
- owner_->getLyXFunc().processKeySym(key, state);
+// workArea_->setScrollbarParams(t->height(), top_y(), defaultRowHeight());}
}
height_ = height;
if (buffer_ && widthChange) {
- // The visible LyXView need a resize
+ // The WorkArea content needs a resize
resizeCurrentBuffer();
}
if (widthChange || heightChange)
update();
-
- owner_->updateLayoutChoice();
}
}
-void BufferView::Pimpl::update(Update::flags flags)
+bool BufferView::Pimpl::update(Update::flags flags)
{
// This is close to a hot-path.
if (lyxerr.debugging(Debug::DEBUG)) {
}
// Check needed to survive LyX startup
- if (buffer_) {
- // Update macro store
- buffer_->buildMacros();
+ if (!buffer_)
+ return false;
- // First drawing step
- bool singlePar = flags & Update::SinglePar;
- needs_redraw_ = flags & (Update::Force | Update::SinglePar);
+ // Update macro store
+ buffer_->buildMacros();
- updateMetrics(singlePar);
+ // First drawing step
+ updateMetrics(flags & Update::SinglePar);
- if ((flags & (Update::FitCursor | Update::MultiParSel))
- && (fitCursor() || multiParSel())) {
- needs_redraw_ = true;
- singlePar = false;
- }
+ // The second drawing step is done in WorkArea::redraw() if needed.
+ bool const need_second_step =
+ (flags & (Update::Force | Update::FitCursor | Update::MultiParSel))
+ && (fitCursor() || multiParSel());
- if (needs_redraw_) {
- // Second drawing step
- updateMetrics(singlePar);
- }
- }
-
- owner_->redrawWorkArea();
- owner_->view_state_changed();
+ return need_second_step;
}
}
-
void BufferView::Pimpl::menuInsertLyXFile(string const & filenm)
{
BOOST_ASSERT(cursor_.inTexted());
string initpath = lyxrc.document_path;
if (available()) {
- string const trypath = owner_->buffer()->filePath();
+ string const trypath = buffer_->filePath();
// If directory is writeable, use this as default.
if (isDirWriteable(trypath))
initpath = trypath;
string res;
Buffer buf("", false);
- buf.error.connect(boost::bind(&BufferView::Pimpl::addError, this, _1));
if (::loadLyXFile(&buf, makeAbsPath(filename))) {
+ ErrorList & el = buffer_->errorList("Parse");
+ // Copy the inserted document error list into the current buffer one.
+ el = buf.errorList("Parse");
lyx::cap::pasteParagraphList(cursor_, buf.paragraphs(),
- buf.params().textclass);
+ buf.params().textclass, el);
res = _("Document %1$s inserted.");
} else
res = _("Could not insert document %1$s");
owner_->message(bformat(res, disp_fn));
- bv_->showErrorList(_("Document insertion"));
+ buffer_->errors("Parse");
resizeCurrentBuffer();
}
// LFUN_FILE_OPEN generated by drag-and-drop.
FuncRequest cmd = cmd0;
- // Handle drag&drop
- if (cmd.action == LFUN_FILE_OPEN) {
- owner_->dispatch(cmd);
- return true;
- }
-
if (!buffer_)
return false;
update(Update::FitCursor | Update::MultiParSel);
}
- // Skip these when selecting
- if (cmd.action != LFUN_MOUSE_MOTION) {
- owner_->updateLayoutChoice();
- owner_->updateToolbars();
- }
-
- // Slight hack: this is only called currently when we
- // clicked somewhere, so we force through the display
- // of the new status here.
- owner_->clearMessage();
return true;
}
case LFUN_OUTLINE_DOWN:
case LFUN_OUTLINE_IN:
case LFUN_OUTLINE_OUT:
- case LFUN_ERROR_NEXT:
case LFUN_NOTE_NEXT:
case LFUN_REFERENCE_NEXT:
case LFUN_WORD_FIND:
case LFUN_BIBTEX_DATABASE_ADD:
case LFUN_BIBTEX_DATABASE_DEL:
case LFUN_WORDS_COUNT:
+ case LFUN_NEXT_INSET_TOGGLE:
flag.enabled(true);
break;
updateLabels(*buffer_);
break;
- case LFUN_ERROR_NEXT:
- bv_funcs::gotoInset(bv_, InsetBase::ERROR_CODE, false);
- break;
-
case LFUN_NOTE_NEXT:
bv_funcs::gotoInset(bv_, InsetBase::NOTE_CODE, false);
break;
buffer_->params().compressed = !buffer_->params().compressed;
break;
+ case LFUN_NEXT_INSET_TOGGLE: {
+ // this is the real function we want to invoke
+ FuncRequest tmpcmd = FuncRequest(LFUN_INSET_TOGGLE, cmd.origin);
+ // if there is an inset at cursor, see whether it
+ // wants to toggle.
+ InsetBase * inset = cur.nextInset();
+ if (inset && inset->isActive()) {
+ LCursor tmpcur = cur;
+ tmpcur.pushLeft(*inset);
+ inset->dispatch(tmpcur, tmpcmd);
+ if (tmpcur.result().dispatched()) {
+ cur.dispatched();
+ }
+ }
+ // if it did not work, try the underlying inset.
+ if (!cur.result().dispatched())
+ cur.dispatch(tmpcmd);
+
+ if (cur.result().dispatched())
+ cur.clearSelection();
+
+ break;
+ }
+
default:
return false;
}