#include "Gui.h"
#include "Buffer.h"
+#include "buffer_funcs.h"
+#include "BufferList.h"
#include "BufferParams.h"
#include "BufferView.h"
#include "bufferview_funcs.h"
#include "gettext.h"
#include "Intl.h"
#include "callback.h"
+#include "LyX.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "Text.h"
using lyx::frontend::ControlCommandBuffer;
-string current_layout;
+docstring current_layout;
LyXView::LyXView(int id)
}
-void LyXView::setBuffer(Buffer * b)
+void LyXView::setBuffer(Buffer * b, bool child_document)
{
busy(true);
BOOST_ASSERT(work_area_);
- if (work_area_->bufferView().buffer())
- disconnectBuffer();
-
- if (!b)
+ Buffer * oldBuffer = work_area_->bufferView().buffer();
+ // parentfilename will be used in case when we switch to a child
+ // document (hence when child_document is true)
+ string parentfilename;
+ if (oldBuffer)
+ parentfilename = oldBuffer->fileName();
+
+ if (!b && theBufferList().empty())
getDialogs().hideBufferDependent();
- work_area_->bufferView().setBuffer(b);
- // Make sure the TOC is updated before anything else.
- updateToc();
+ Buffer * newBuffer = work_area_->bufferView().setBuffer(b);
+
+ if (newBuffer) {
+ //Are we closing an oldBuffer which was a child document?
+ if (!b && oldBuffer && oldBuffer->getMasterBuffer() != oldBuffer)
+ // Update the labels and section numbering of its master Buffer.
+ updateLabels(*oldBuffer->getMasterBuffer());
+ //Are we opening a new child document?
+ else if (child_document && newBuffer->getMasterBuffer() != oldBuffer) {
+ // Set the parent name of the child document.
+ // This makes insertion of citations and references in the child work,
+ // when the target is in the parent or another child document.
+ newBuffer->setParentName(parentfilename);
+ // Update the labels and section numbering to the new master Buffer.
+ updateLabels(*newBuffer->getMasterBuffer());
+ }
+ //Now that all the updating of the old buffer has been done, we can
+ //connect the new buffer. Note that this will also disconnect the old
+ //buffer, if such there is.
+ //FIXME Is it clear that this should go right here? Or should it go
+ //earlier before the previous if (in which case we'd remove the "else")?
+ connectBuffer(*newBuffer);
+
+ /* FIXME: We need to rebuild the Toc dialog before the others even
+ if it will be rebuilt again in the next line. This avoid a crash when
+ other dialogs are rebuilt before the Toc dialog. The reason is
+ that closing a Buffer triggers an update of all opened dialogs
+ when dispatching LFUN_DIALOG_UPDATE (hence the patch).
+ The path is as following:
+ setBuffer() -> updateBufferDependent() -> RestoreButton() -> LFUN
+ The problem here is that the Toc dialog has not been
+ reconstructed (because it comes after in the list of dialogs). */
+ updateToc();
- if (work_area_->bufferView().buffer()) {
// Buffer-dependent dialogs should be updated or
// hidden. This should go here because some dialogs (eg ToC)
// require bv_->text.
getDialogs().updateBufferDependent(true);
- connectBuffer(*work_area_->bufferView().buffer());
- }
+ } else
+ //Disconnect the old buffer...there's no new one.
+ disconnectBuffer();
if (quitting)
return;
}
-bool LyXView::loadLyXFile(FileName const & filename, bool tolastfiles)
+bool LyXView::loadLyXFile(FileName const & filename, bool tolastfiles,
+ bool child_document, bool auto_open)
{
busy(true);
BOOST_ASSERT(work_area_);
- if (work_area_->bufferView().buffer())
- disconnectBuffer();
+ string parentfilename;
+ Buffer * oldBuffer = work_area_->bufferView().buffer();
+ if (oldBuffer)
+ parentfilename = oldBuffer->fileName();
+
+ bool alreadyLoaded = checkIfLoaded(filename);
+ Buffer * newBuffer = checkAndLoadLyXFile(filename);
+
+ if (!newBuffer) {
+ message(_("Document not loaded."));
+ updateStatusBar();
+ busy(false);
+ work_area_->redraw();
+ return false;
+ }
- bool loaded = work_area_->bufferView().loadLyXFile(filename, tolastfiles);
+ if (child_document && newBuffer != oldBuffer) {
+ // Set the parent name of the child document.
+ // This makes insertion of citations and references in the child work,
+ // when the target is in the parent or another child document.
+ newBuffer->setParentName(parentfilename);
+ message(bformat(_("Opening child document %1$s..."),
+ makeDisplayPath(filename.absFilename())));
+ }
- updateToc();
- updateMenubar();
- updateToolbars();
- updateLayoutChoice();
- updateWindowTitle();
- updateTab();
- if (loaded) {
- connectBuffer(*work_area_->bufferView().buffer());
- showErrorList("Parse");
+ // Update the labels and section numbering.
+ updateLabels(*newBuffer->getMasterBuffer());
+
+ bool const parse_error = !newBuffer->errorList("Parse").empty();
+ bool const need_switch = parse_error || !auto_open;
+ if (need_switch) {
+ setBuffer(newBuffer, child_document);
+ if (!alreadyLoaded) {
+ if (parse_error)
+ showErrorList("Parse");
+ // scroll to the position when the file was last closed
+ if (lyxrc.use_lastfilepos) {
+ pit_type pit;
+ pos_type pos;
+ boost::tie(pit, pos) = LyX::ref().session().lastFilePos().load(filename);
+ // if successfully move to pit (returned par_id is not zero),
+ // update metrics and reset font
+ if (work_area_->bufferView().moveToPosition(pit, pos, 0, 0).get<1>()) {
+ if (work_area_->bufferView().fitCursor())
+ work_area_->bufferView().updateMetrics(false);
+ newBuffer->text().setCurrentFont(work_area_->bufferView().cursor());
+ updateMenubar();
+ updateToolbars();
+ updateLayoutChoice();
+ updateStatusBar();
+ work_area_->redraw();
+ }
+ }
+ if (tolastfiles)
+ LyX::ref().session().lastFiles().add(filename);
+ }
}
- updateStatusBar();
+
busy(false);
- work_area_->redraw();
- return loaded;
+ return true;
}
closingConnection_ =
buf.closing.connect(
- boost::bind(&LyXView::setBuffer, this, (Buffer *)0));
+ boost::bind(&LyXView::setBuffer, this, (Buffer *)0, false));
}
bool const review =
lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).enabled() &&
lyx::getStatus(FuncRequest(LFUN_CHANGES_TRACK)).onoff(true);
-
+
toolbars_->update(math, table, review);
// update redaonly status of open dialogs. This could also be in
// updateMenubar(), but since updateToolbars() and updateMenubar()
}
-ToolbarInfo::Flags LyXView::getToolbarState(string const & name)
+ToolbarInfo * LyXView::getToolbarInfo(string const & name)
{
- return toolbars_->getToolbarState(name);
+ return toolbars_->getToolbarInfo(name);
}
-void LyXView::toggleToolbarState(string const & name)
+void LyXView::toggleToolbarState(string const & name, bool allowauto)
{
// it is possible to get current toolbar status like this,...
// but I decide to obey the order of ToolbarBackend::flags
// toolbars_->saveToolbarInfo();
//
// toggle state on/off/auto
- toolbars_->toggleToolbarState(name);
+ toolbars_->toggleToolbarState(name, allowauto);
// update toolbar
updateToolbars();
}
}
BOOST_ASSERT(work_area_);
- if (work_area_->bufferView().cursor().inMathed())
- return;
-
- string const & layout =
- work_area_->bufferView().cursor().paragraph().layout()->name();
+ docstring const & layout = work_area_->bufferView().cursor().
+ innerParagraph().layout()->name();
if (layout != current_layout) {
toolbars_->setLayout(layout);