------------------------------------------------------------------------
Index: Buffer.cpp
===================================================================
--- Buffer.cpp (revision 18822)
+++ Buffer.cpp (working copy)
@@ -1616,7 +1616,11 @@
void Buffer::setParentName(string const & name)
{
- params().parentname = name;
+ if (name == pimpl_->filename.absFilename())
+ // Avoids recursive include.
+ params().parentname.clear();
+ else
+ params().parentname = name;
}
Index: buffer_funcs.cpp
===================================================================
--- buffer_funcs.cpp (revision 18822)
+++ buffer_funcs.cpp (working copy)
@@ -180,6 +180,47 @@
return false;
}
+// FIXME: all of this should go in a helper file in buffer_func.
+Buffer * checkAndLoadLyXFile(FileName const & filename)
+{
+ // File already open?
+ if (theBufferList().exists(filename.absFilename())) {
+ docstring const file = makeDisplayPath(filename.absFilename(),
20);
+ docstring text = bformat(_("The document %1$s is already "
+ "loaded.\n\nDo you want to
revert "
+ "to the saved version?"),
file);
+ if (Alert::prompt(_("Revert to saved document?"),
+ text, 0, 1, _("&Revert"), _("&Switch to
document")))
+ return
theBufferList().getBuffer(filename.absFilename());
+
+ // FIXME: should be LFUN_REVERT
+ if
(theBufferList().close(theBufferList().getBuffer(filename.absFilename()),
false))
+ // Load it again.
+ return checkAndLoadLyXFile(filename);
+ else
+ // The file could not be closed.
+ return 0;
+ }
+
+ if (isFileReadable(filename)) {
+ Buffer * b = theBufferList().newBuffer(filename.absFilename());
+ if (!lyx::loadLyXFile(b, filename)) {
+ theBufferList().release(b);
+ return 0;
+ }
+ return b;
+ }
+
+ docstring text = bformat(_("The document %1$s does not yet "
+ "exist.\n\nDo you want to create a new document?"),
+ from_utf8(filename.absFilename()));
+ if (Alert::prompt(_("Create new document?"),
+ text, 0, 1, _("&Create"), _("Cancel")))
+ return newFile(filename.absFilename(), string(), true);
+
+ return 0;
+}
+
// FIXME newFile() should probably be a member method of Application...
Buffer * newFile(string const & filename, string const & templatename,
bool const isNamed)
Index: buffer_funcs.h
===================================================================
--- buffer_funcs.h (revision 18822)
+++ buffer_funcs.h (working copy)
@@ -34,6 +34,13 @@
*/
bool loadLyXFile(Buffer *, support::FileName const & filename);
+/**
+ * Checks and loads a LyX file \param filename.
+ * \retval the newly created \c Buffer pointer if successful or 0.
+ * \retval 0 if the \c Buffer could not be created.
+ */
+Buffer * checkAndLoadLyXFile(support::FileName const & filename);
+
/* Make a new file (buffer) with name \c filename based on a template
* named \c templatename
*/
Index: BufferView.cpp
===================================================================
--- BufferView.cpp (revision 18822)
+++ BufferView.cpp (working copy)
@@ -233,78 +233,6 @@
graphics::Previews::get().generateBufferPreviews(*buffer_);
}
-
-bool BufferView::loadLyXFile(FileName const & filename, bool tolastfiles)
-{
- // File already open?
- if (theBufferList().exists(filename.absFilename())) {
- docstring const file = makeDisplayPath(filename.absFilename(),
20);
- docstring text = bformat(_("The document %1$s is already "
- "loaded.\n\nDo you want to
revert "
- "to the saved version?"),
file);
- int const ret = Alert::prompt(_("Revert to saved document?"),
- text, 0, 1, _("&Revert"), _("&Switch to document"));
-
- if (ret != 0) {
-
setBuffer(theBufferList().getBuffer(filename.absFilename()));
- return true;
- }
- // FIXME: should be LFUN_REVERT
- if
(!theBufferList().close(theBufferList().getBuffer(filename.absFilename()),
false))
- return false;
- // Fall through to new load. (Asger)
- buffer_ = 0;
- }
-
- Buffer * b = 0;
-
- if (isFileReadable(filename)) {
- b = theBufferList().newBuffer(filename.absFilename());
- if (!lyx::loadLyXFile(b, filename)) {
- theBufferList().release(b);
- return false;
- }
- } else {
- docstring text = bformat(_("The document %1$s does not yet "
- "exist.\n\nDo you want to
create "
- "a new document?"),
from_utf8(filename.absFilename()));
- int const ret = Alert::prompt(_("Create new document?"),
- text, 0, 1, _("&Create"), _("Cancel"));
-
- if (ret == 0) {
- b = newFile(filename.absFilename(), string(), true);
- if (!b)
- return false;
- } else
- return false;
- }
-
- setBuffer(b);
- // Send the "errors" signal in case of parsing errors
- b->errors("Parse");
-
- // Update the labels and section numbering.
- updateLabels(*buffer_);
- // 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 (moveToPosition(pit, pos, 0, 0).get<1>()) {
- if (fitCursor())
- updateMetrics(false);
- buffer_->text().setCurrentFont(cursor_);
- }
- }
-
- if (tolastfiles)
- LyX::ref().session().lastFiles().add(FileName(b->fileName()));
-
- return true;
-}
-
-
void BufferView::resize()
{
if (!buffer_)
Index: BufferView.h
===================================================================
--- BufferView.h (revision 18822)
+++ BufferView.h (working copy)
@@ -93,9 +93,6 @@
/// resize the BufferView.
void resize();
- /// load a buffer into the view.
- bool loadLyXFile(support::FileName const & name, bool tolastfiles =
true);
-
/// perform pending metrics updates.
/** \c Update::FitCursor means first to do a FitCursor, and to
* force an update if screen position changes.
Index: frontends/LyXView.cpp
===================================================================
--- frontends/LyXView.cpp (revision 18822)
+++ frontends/LyXView.cpp (working copy)
@@ -20,6 +20,7 @@
#include "Gui.h"
#include "Buffer.h"
+#include "buffer_funcs.h"
#include "BufferList.h"
#include "BufferParams.h"
#include "BufferView.h"
@@ -31,6 +32,7 @@
#include "gettext.h"
#include "Intl.h"
#include "callback.h"
+#include "LyX.h"
#include "LyXFunc.h"
#include "LyXRC.h"
#include "Text.h"
@@ -122,27 +124,44 @@
}
-void LyXView::setBuffer(Buffer * b)
+void LyXView::setBuffer(Buffer * b, bool child_document)
{
busy(true);
BOOST_ASSERT(work_area_);
- if (work_area_->bufferView().buffer())
+ 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();
disconnectBuffer();
+ }
if (!b && theBufferList().empty())
getDialogs().hideBufferDependent();
work_area_->bufferView().setBuffer(b);
- // Make sure the TOC is updated before anything else.
- updateToc();
- if (work_area_->bufferView().buffer()) {
+ Buffer * newBuffer = work_area_->bufferView().buffer();
+ if (newBuffer) {
+ 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);
+ // updateLabels() will emit Buffer::structureChanged()
so better
+ // connect it before.
+ connectBuffer(*newBuffer);
+ // Update the labels and section numbering.
+ updateLabels(*newBuffer->getMasterBuffer());
+ } else
+ connectBuffer(*newBuffer);
+
// 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());
}
if (quitting)
@@ -159,34 +178,64 @@
}
-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_);
- bool const hadBuffer = work_area_->bufferView().buffer();
- if (hadBuffer)
- disconnectBuffer();
+ string parentfilename;
+ Buffer * oldBuffer = work_area_->bufferView().buffer();
+ if (oldBuffer)
+ parentfilename = oldBuffer->fileName();
- bool const loaded =
- work_area_->bufferView().loadLyXFile(filename, tolastfiles);
+ Buffer * newBuffer = checkAndLoadLyXFile(filename);
- updateToc();
- updateMenubar();
- updateToolbars();
- updateLayoutChoice();
- updateWindowTitle();
- updateTab();
- if (loaded) {
- connectBuffer(*work_area_->bufferView().buffer());
+ if (!newBuffer) {
+ message(_("Document not loaded."));
+ updateStatusBar();
+ busy(false);
+ work_area_->redraw();
+ return false;
+ }
+
+ 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())));
+ }
+
+ bool const parse_error = !newBuffer->errorList("Parse").empty();
+ if (parse_error || !auto_open) {
+ setBuffer(newBuffer, child_document);
showErrorList("Parse");
- } else if (hadBuffer)
- //Need to reconnect the buffer if the load failed
- connectBuffer(*work_area_->bufferView().buffer());
- updateStatusBar();
+ }
+
+ // Update the labels and section numbering.
+ updateLabels(*newBuffer->getMasterBuffer());
+
+ // scroll to the position when the file was last closed
+ if (!auto_open && 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());
+ }
+ }
+
+ if (tolastfiles)
+ LyX::ref().session().lastFiles().add(filename);
+
busy(false);
- work_area_->redraw();
- return loaded;
+ return true;
}
@@ -230,7 +279,7 @@
closingConnection_ =
buf.closing.connect(
- boost::bind(&LyXView::setBuffer, this, (Buffer *)0));
+ boost::bind(&LyXView::setBuffer, this, (Buffer *)0,
false));
}
Index: frontends/LyXView.h
===================================================================
--- frontends/LyXView.h (revision 18822)
+++ frontends/LyXView.h (working copy)
@@ -142,11 +142,15 @@
//@}
- /// load a buffer into the current workarea
- bool loadLyXFile(support::FileName const & name, bool tolastfiles =
true);
+ /// load a buffer into the current workarea.
+ bool loadLyXFile(support::FileName const & name, ///< File to load.
+ bool tolastfiles = true, ///< append to the "Open recent" menu?
+ bool child_document = false, ///< Is this a child document?
+ bool auto_open = false); ///< Is this being opened by LyX itself?
- /// set a buffer to the current workarea
- void setBuffer(Buffer * b);
+ /// set a buffer to the current workarea.
+ void setBuffer(Buffer * b, ///< \c Buffer to set.
+ bool child_document = false); ///< Is this a child document?
/// updates the possible layouts selectable
void updateLayoutChoice();
Index: insets/InsetInclude.cpp
===================================================================
--- insets/InsetInclude.cpp (revision 18822)
+++ insets/InsetInclude.cpp (working copy)
@@ -52,6 +52,9 @@
namespace lyx {
+
+// Implementation is in LyX.cpp
+extern void dispatch(FuncRequest const & action);
using support::addName;
using support::absolutePath;
@@ -400,12 +403,10 @@
// the readonly flag can/will be wrong, not anymore I think.
if (!fs::exists(included_file.toFilesystemEncoding()))
return false;
- buf = theBufferList().newBuffer(included_file.absFilename());
- if (!loadLyXFile(buf, included_file)) {
- //close the buffer we just opened
- theBufferList().close(buf, false);
- return false;
- }
+ lyx::dispatch(FuncRequest(LFUN_BUFFER_CHILD_OPEN,
+ included_file.absFilename() + "|true"));
+ buf = theBufferList().getBuffer(included_file.absFilename());
+ return buf;
}
buf->setParentName(parentFilename(buffer));
return true;
Index: LyX.cpp
===================================================================
--- LyX.cpp (revision 18822)
+++ LyX.cpp (working copy)
@@ -613,7 +613,7 @@
if (!pimpl_->files_to_load_.empty()) {
for_each(pimpl_->files_to_load_.begin(),
pimpl_->files_to_load_.end(),
- bind(&LyXView::loadLyXFile, view, _1, true));
+ bind(&LyXView::loadLyXFile, view, _1, true, false,
false));
// clear this list to save a few bytes of RAM
pimpl_->files_to_load_.clear();
pimpl_->session_->lastOpened().clear();
@@ -628,7 +628,7 @@
// last session, and should be already there (regular files), or should
// not be added at all (help files).
for_each(lastopened.begin(), lastopened.end(),
- bind(&LyXView::loadLyXFile, view, _1, false));
+ bind(&LyXView::loadLyXFile, view, _1, false, false, false));
// clear this list to save a few bytes of RAM
pimpl_->session_->lastOpened().clear();
Index: LyXFunc.cpp
===================================================================
--- LyXFunc.cpp (revision 18822)
+++ LyXFunc.cpp (working copy)
@@ -1410,23 +1410,34 @@
}
case LFUN_BUFFER_CHILD_OPEN: {
+ // takes an optional argument, "|bool", at the end
+ // indicating whether this file is being opened
automatically
+ // by LyX itself, in which case we will not want to
switch
+ // buffers after opening. The default is false, so in
practice
+ // it is used only when true.
BOOST_ASSERT(lyx_view_);
- FileName const filename =
+ int const arglength = argument.length();
+ FileName filename;
+ bool autoOpen = false;
+ if (argument.substr(arglength - 5, 5) == "|true") {
+ autoOpen = true;
+ filename = makeAbsPath(argument.substr(0, arglength - 5),
+ lyx_view_->buffer()->filePath());
+ } else if (argument.substr(arglength - 6, 6) ==
"|false") {
+ filename = makeAbsPath(argument.substr(0, arglength - 6),
+ lyx_view_->buffer()->filePath());
+ } else filename =
makeAbsPath(argument, lyx_view_->buffer()->filePath());
view()->saveBookmark(false);
- string const parentfilename =
lyx_view_->buffer()->fileName();
- if (theBufferList().exists(filename.absFilename()))
-
lyx_view_->setBuffer(theBufferList().getBuffer(filename.absFilename()));
- else
- if (lyx_view_->loadLyXFile(filename)) {
- // 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.
-
lyx_view_->buffer()->setParentName(parentfilename);
- setMessage(bformat(_("Opening child document
%1$s..."),
-
makeDisplayPath(filename.absFilename())));
- } else
- setMessage(_("Document not loaded."));
+ if (theBufferList().exists(filename.absFilename())) {
+ Buffer * buf =
theBufferList().getBuffer(filename.absFilename());
+ if (!autoOpen)
+ lyx_view_->setBuffer(buf, true);
+ else
+
buf->setParentName(lyx_view_->buffer()->fileName());
+ } else
+ lyx_view_->loadLyXFile(filename, true, true,
autoOpen);
+
break;
}