Tommaso Cucinotta ha scritto:
Abdelrazak Younes ha scritto:
Yes they help, and I hope they will help you in fixing all these
cases. I only had a quick look at them but your analysis seems correct.
Ok, I'll try to produce a patch, make some tests and send it to the list.
Please, find it attached. I could not test it as I was expecting due to
the lack of time.
T.
--
Tommaso Cucinotta, Computer Engineering PhD, Researcher
ReTiS Lab, Scuola Superiore Sant'Anna, Pisa, Italy
Tel +39 050 882 024, Fax +39 050 882 003
http://feanor.sssup.it/~tommaso
Index: src/LyXFunc.cpp
===================================================================
--- src/LyXFunc.cpp (revisione 31361)
+++ src/LyXFunc.cpp (copia locale)
@@ -817,6 +817,12 @@
Buffer * buffer = 0;
if (lyx_view_ && lyx_view_->currentBufferView())
buffer = &lyx_view_->currentBufferView()->buffer();
+ Buffer * doc_buffer = 0;
+ if (lyx_view_ && lyx_view_->documentBufferView())
+ doc_buffer = &lyx_view_->documentBufferView()->buffer();
+
+ LYXERR(Debug::ACTION, "buffer=" << buffer << ", doc_buffer=" << doc_buffer);
+
switch (action) {
case LFUN_COMMAND_PREFIX:
@@ -840,7 +846,7 @@
break;
case LFUN_BUFFER_TOGGLE_READ_ONLY: {
- LASSERT(lyx_view_ && lyx_view_->currentBufferView() && buffer, /**/);
+ LASSERT(buffer, /**/);
if (buffer->lyxvc().inUse())
buffer->lyxvc().toggleReadOnly();
else
@@ -851,19 +857,22 @@
// --- Menus -----------------------------------------------
case LFUN_BUFFER_CLOSE:
lyx_view_->closeBuffer();
- buffer = 0;
+ if (buffer == doc_buffer)
+ buffer = 0;
+ doc_buffer = 0;
updateFlags = Update::None;
break;
case LFUN_BUFFER_CLOSE_ALL:
lyx_view_->closeBufferAll();
buffer = 0;
+ doc_buffer = 0;
updateFlags = Update::None;
break;
case LFUN_BUFFER_RELOAD: {
- LASSERT(lyx_view_ && buffer, /**/);
- docstring const file = makeDisplayPath(buffer->absFileName(), 20);
+ LASSERT(doc_buffer, /**/);
+ docstring const file = makeDisplayPath(doc_buffer->absFileName(), 20);
docstring text = bformat(_("Any changes will be lost. Are you sure "
"you want to revert to the saved version of the document %1$s?"), file);
int const ret = Alert::prompt(_("Revert to saved document?"),
@@ -875,65 +884,61 @@
}
case LFUN_BUFFER_UPDATE: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer();
+ LASSERT(doc_buffer, /**/);
string format = argument;
if (argument.empty())
- format = doc_buffer.getDefaultOutputFormat();
- doc_buffer.doExport(format, true);
+ format = doc_buffer->getDefaultOutputFormat();
+ doc_buffer->doExport(format, true);
break;
}
case LFUN_BUFFER_VIEW: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer();
+ LASSERT(doc_buffer, /**/);
string format = argument;
if (argument.empty())
- format = doc_buffer.getDefaultOutputFormat();
- doc_buffer.preview(format);
+ format = doc_buffer->getDefaultOutputFormat();
+ doc_buffer->preview(format);
break;
}
case LFUN_MASTER_BUFFER_UPDATE: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer();
+ LASSERT(doc_buffer, /**/);
string format = argument;
if (argument.empty())
- format = doc_buffer.masterBuffer()->getDefaultOutputFormat();
- doc_buffer.masterBuffer()->doExport(format, true);
+ format = doc_buffer->masterBuffer()->getDefaultOutputFormat();
+ doc_buffer->masterBuffer()->doExport(format, true);
break;
}
case LFUN_MASTER_BUFFER_VIEW: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- Buffer & doc_buffer = lyx_view_->documentBufferView()->buffer();
+ LASSERT(doc_buffer, /**/);
string format = argument;
if (argument.empty())
- format = doc_buffer.masterBuffer()->getDefaultOutputFormat();
- doc_buffer.masterBuffer()->preview(format);
+ format = doc_buffer->masterBuffer()->getDefaultOutputFormat();
+ doc_buffer->masterBuffer()->preview(format);
break;
}
case LFUN_BUILD_PROGRAM:
- LASSERT(lyx_view_ && buffer, /**/);
- buffer->doExport("program", true);
+ LASSERT(doc_buffer, /**/);
+ doc_buffer->doExport("program", true);
break;
- case LFUN_BUFFER_CHKTEX:
- LASSERT(lyx_view_ && buffer, /**/);
- buffer->runChktex();
+ case LFUN_BUFFER_CHKTEX: // TODO: test if doc_buffer here
+ LASSERT(doc_buffer, /**/);
+ doc_buffer->runChktex();
break;
case LFUN_BUFFER_EXPORT:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
if (argument == "custom")
dispatch(FuncRequest(LFUN_DIALOG_SHOW, "sendto"));
else
- buffer->doExport(argument, false);
+ doc_buffer->doExport(argument, false);
break;
case LFUN_BUFFER_EXPORT_CUSTOM: {
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
string format_name;
string command = split(argument, format_name, ' ');
Format const * format = formats.getFormat(format_name);
@@ -949,16 +954,16 @@
// Output to filename
if (format->name() == "lyx") {
- string const latexname = buffer->latexName(false);
+ string const latexname = doc_buffer->latexName(false);
filename = changeExtension(latexname,
format->extension());
- filename = addName(buffer->temppath(), filename);
+ filename = addName(doc_buffer->temppath(), filename);
- if (!buffer->writeFile(FileName(filename)))
+ if (!doc_buffer->writeFile(FileName(filename)))
break;
} else {
- buffer->doExport(format_name, true, filename);
+ doc_buffer->doExport(format_name, true, filename);
}
// Substitute $$FName for filename
@@ -980,7 +985,8 @@
*/
case LFUN_BUFFER_AUTO_SAVE:
- buffer->autoSave();
+ LASSERT(doc_buffer, /**/);
+ doc_buffer->autoSave();
break;
case LFUN_RECONFIGURE:
@@ -1019,44 +1025,44 @@
// --- version control -------------------------------
case LFUN_VC_REGISTER:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
if (!ensureBufferClean(lyx_view_->documentBufferView()))
break;
- if (!buffer->lyxvc().inUse()) {
- if (buffer->lyxvc().registrer())
+ if (!doc_buffer->lyxvc().inUse()) {
+ if (doc_buffer->lyxvc().registrer())
reloadBuffer();
}
updateFlags = Update::Force;
break;
case LFUN_VC_CHECK_IN:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
if (!ensureBufferClean(lyx_view_->documentBufferView()))
break;
- if (buffer->lyxvc().inUse()
- && !buffer->isReadonly()) {
- setMessage(from_utf8(buffer->lyxvc().checkIn()));
+ if (doc_buffer->lyxvc().inUse()
+ && !doc_buffer->isReadonly()) {
+ setMessage(from_utf8(doc_buffer->lyxvc().checkIn()));
reloadBuffer();
}
break;
case LFUN_VC_CHECK_OUT:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
if (!ensureBufferClean(lyx_view_->documentBufferView()))
break;
- if (buffer->lyxvc().inUse()) {
- setMessage(from_utf8(buffer->lyxvc().checkOut()));
+ if (doc_buffer->lyxvc().inUse()) {
+ setMessage(from_utf8(doc_buffer->lyxvc().checkOut()));
reloadBuffer();
}
break;
case LFUN_VC_LOCKING_TOGGLE:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(doc_buffer, /**/);
if (!ensureBufferClean(lyx_view_->documentBufferView())
- || buffer->isReadonly())
+ || doc_buffer->isReadonly())
break;
- if (buffer->lyxvc().inUse()) {
- string res = buffer->lyxvc().lockingToggle();
+ if (doc_buffer->lyxvc().inUse()) {
+ string res = doc_buffer->lyxvc().lockingToggle();
if (res.empty())
frontend::Alert::error(_("Revision control error."),
_("Error when setting the locking property."));
@@ -1068,23 +1074,23 @@
break;
case LFUN_VC_REVERT:
- LASSERT(lyx_view_ && buffer, /**/);
- buffer->lyxvc().revert();
+ LASSERT(doc_buffer, /**/);
+ doc_buffer->lyxvc().revert();
reloadBuffer();
break;
case LFUN_VC_UNDO_LAST:
- LASSERT(lyx_view_ && buffer, /**/);
- buffer->lyxvc().undoLast();
+ LASSERT(doc_buffer, /**/);
+ doc_buffer->lyxvc().undoLast();
reloadBuffer();
break;
// --- lyxserver commands ----------------------------
case LFUN_SERVER_GET_FILENAME:
- LASSERT(lyx_view_ && buffer, /**/);
+ LASSERT(lyx_view_ && doc_buffer, /**/);
setMessage(from_utf8(buffer->absFileName()));
LYXERR(Debug::INFO, "FNAME["
- << buffer->absFileName() << ']');
+ << doc_buffer->absFileName() << ']');
break;
case LFUN_SERVER_NOTIFY:
@@ -1278,8 +1284,8 @@
}
case LFUN_BUFFER_CHILD_OPEN: {
- LASSERT(lyx_view_ && buffer, /**/);
- FileName filename = makeAbsPath(argument, buffer->filePath());
+ LASSERT(doc_buffer, /**/);
+ FileName filename = makeAbsPath(argument, doc_buffer->filePath());
lyx_view_->documentBufferView()->saveBookmark(false);
Buffer * child = 0;
bool parsed = false;
@@ -1295,7 +1301,7 @@
// 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.
- child->setParent(buffer);
+ child->setParent(doc_buffer);
child->masterBuffer()->updateLabels();
lyx_view_->setBuffer(child);
if (parsed)
@@ -1351,8 +1357,10 @@
case LFUN_COMMAND_SEQUENCE: {
// argument contains ';'-terminated commands
string arg = argument;
- if (theBufferList().isLoaded(buffer))
+ if (buffer && theBufferList().isLoaded(buffer))
buffer->undo().beginUndoGroup();
+ if (doc_buffer && doc_buffer != buffer && theBufferList().isLoaded(doc_buffer))
+ doc_buffer->undo().beginUndoGroup();
while (!arg.empty()) {
string first;
arg = split(arg, first, ';');
@@ -1360,8 +1368,12 @@
func.origin = cmd.origin;
dispatch(func);
}
- if (theBufferList().isLoaded(buffer))
+ /// \TODO: check if some of the dispatched LFUNs in the loop above may have
+ /// closed (deallocated) buffer or doc_buffer before the following
+ if (buffer && theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
+ if (doc_buffer && doc_buffer != buffer && theBufferList().isLoaded(doc_buffer))
+ buffer->undo().endUndoGroup();
break;
}
@@ -1416,16 +1428,16 @@
lyx_view_->message(from_utf8(argument));
break;
- case LFUN_BUFFER_LANGUAGE: {
- LASSERT(lyx_view_, /**/);
- Language const * oldL = buffer->params().language;
+ case LFUN_BUFFER_LANGUAGE: { // Check if this is for buffer or doc_buffer
+ LASSERT(doc_buffer, /**/);
+ Language const * oldL = doc_buffer->params().language;
Language const * newL = languages.getLanguage(argument);
if (!newL || oldL == newL)
break;
if (oldL->rightToLeft() == newL->rightToLeft()
- && !buffer->isMultiLingual())
- buffer->changeLanguage(oldL, newL);
+ && !doc_buffer->isMultiLingual())
+ doc_buffer->changeLanguage(oldL, newL);
break;
}
@@ -1455,17 +1467,18 @@
break;
}
+ /// \TODO Check/ask if this is for buffer or doc_buffer
case LFUN_BUFFER_PARAMS_APPLY: {
- LASSERT(lyx_view_, /**/);
+ LASSERT(doc_buffer, /**/);
- DocumentClass const * const oldClass = buffer->params().documentClassPtr();
+ DocumentClass const * const oldClass = doc_buffer->params().documentClassPtr();
Cursor & cur = lyx_view_->documentBufferView()->cursor();
cur.recordUndoFullDocument();
istringstream ss(argument);
Lexer lex;
lex.setStream(ss);
- int const unknown_tokens = buffer->readHeader(lex);
+ int const unknown_tokens = doc_buffer->readHeader(lex);
if (unknown_tokens != 0) {
lyxerr << "Warning in LFUN_BUFFER_PARAMS_APPLY!\n"
@@ -1474,7 +1487,7 @@
<< endl;
}
- updateLayout(oldClass, buffer);
+ updateLayout(oldClass, doc_buffer);
updateFlags = Update::Force | Update::FitCursor;
// We are most certainly here because of a change in the document
@@ -1484,20 +1497,21 @@
break;
}
+ /// \TODO check/ask if these MODULES_* LFUNs may work on internal WorkAreas as well
case LFUN_LAYOUT_MODULES_CLEAR: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- DocumentClass const * const oldClass = buffer->params().documentClassPtr();
+ LASSERT(doc_buffer, /**/);
+ DocumentClass const * const oldClass = doc_buffer->params().documentClassPtr();
lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
- buffer->params().clearLayoutModules();
- buffer->params().makeDocumentClass();
- updateLayout(oldClass, buffer);
+ doc_buffer->params().clearLayoutModules();
+ doc_buffer->params().makeDocumentClass();
+ updateLayout(oldClass, doc_buffer);
updateFlags = Update::Force | Update::FitCursor;
break;
}
case LFUN_LAYOUT_MODULE_ADD: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
- BufferParams const & params = buffer->params();
+ LASSERT(doc_buffer, /**/);
+ BufferParams const & params = doc_buffer->params();
if (!params.moduleCanBeAdded(argument)) {
LYXERR0("Module `" << argument <<
"' cannot be added due to failed requirements or "
@@ -1506,21 +1520,21 @@
}
DocumentClass const * const oldClass = params.documentClassPtr();
lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
- buffer->params().addLayoutModule(argument);
- buffer->params().makeDocumentClass();
- updateLayout(oldClass, buffer);
+ doc_buffer->params().addLayoutModule(argument);
+ doc_buffer->params().makeDocumentClass();
+ updateLayout(oldClass, doc_buffer);
updateFlags = Update::Force | Update::FitCursor;
break;
}
case LFUN_TEXTCLASS_APPLY: {
- LASSERT(lyx_view_ && lyx_view_->documentBufferView(), /**/);
+ LASSERT(doc_buffer, /**/);
- if (!loadLayoutFile(argument, buffer->temppath()) &&
- !loadLayoutFile(argument, buffer->filePath()))
+ if (!loadLayoutFile(argument, doc_buffer->temppath()) &&
+ !loadLayoutFile(argument, doc_buffer->filePath()))
break;
- LayoutFile const * old_layout = buffer->params().baseClass();
+ LayoutFile const * old_layout = doc_buffer->params().baseClass();
LayoutFile const * new_layout = &(LayoutFileList::get()[argument]);
if (old_layout == new_layout)
@@ -1529,30 +1543,30 @@
//Save the old, possibly modular, layout for use in conversion.
DocumentClass const * const oldDocClass =
- buffer->params().documentClassPtr();
+ doc_buffer->params().documentClassPtr();
lyx_view_->documentBufferView()->cursor().recordUndoFullDocument();
- buffer->params().setBaseClass(argument);
- buffer->params().makeDocumentClass();
- updateLayout(oldDocClass, buffer);
+ doc_buffer->params().setBaseClass(argument);
+ doc_buffer->params().makeDocumentClass();
+ updateLayout(oldDocClass, doc_buffer);
updateFlags = Update::Force | Update::FitCursor;
break;
}
case LFUN_LAYOUT_RELOAD: {
- LASSERT(lyx_view_, /**/);
- DocumentClass const * const oldClass = buffer->params().documentClassPtr();
- LayoutFileIndex bc = buffer->params().baseClassID();
+ LASSERT(doc_buffer, /**/);
+ DocumentClass const * const oldClass = doc_buffer->params().documentClassPtr();
+ LayoutFileIndex bc = doc_buffer->params().baseClassID();
LayoutFileList::get().reset(bc);
- buffer->params().setBaseClass(bc);
- buffer->params().makeDocumentClass();
- updateLayout(oldClass, buffer);
+ doc_buffer->params().setBaseClass(bc);
+ doc_buffer->params().makeDocumentClass();
+ updateLayout(oldClass, doc_buffer);
updateFlags = Update::Force | Update::FitCursor;
break;
}
case LFUN_TEXTCLASS_LOAD:
- loadLayoutFile(argument, buffer->temppath()) ||
- loadLayoutFile(argument, buffer->filePath());
+ loadLayoutFile(argument, doc_buffer->temppath()) ||
+ loadLayoutFile(argument, doc_buffer->filePath());
break;
case LFUN_LYXRC_APPLY: {
@@ -1597,7 +1611,7 @@
case LFUN_VC_COMMAND: {
string flag = cmd.getArg(0);
- if (buffer && contains(flag, 'R')
+ if (doc_buffer && contains(flag, 'R')
&& !ensureBufferClean(lyx_view_->documentBufferView()))
break;
docstring message;
@@ -1606,8 +1620,8 @@
break;
string path = cmd.getArg(1);
- if (contains(path, "$$p") && buffer)
- path = subst(path, "$$p", buffer->filePath());
+ if (contains(path, "$$p") && doc_buffer)
+ path = subst(path, "$$p", doc_buffer->filePath());
LYXERR(Debug::LYXVC, "Directory: " << path);
FileName pp(path);
if (!pp.isReadableDirectory()) {
@@ -1619,19 +1633,19 @@
string command = cmd.getArg(2);
if (command.empty())
break;
- if (buffer) {
- command = subst(command, "$$i", buffer->absFileName());
- command = subst(command, "$$p", buffer->filePath());
+ if (doc_buffer) {
+ command = subst(command, "$$i", doc_buffer->absFileName());
+ command = subst(command, "$$p", doc_buffer->filePath());
}
command = subst(command, "$$m", to_utf8(message));
LYXERR(Debug::LYXVC, "Command: " << command);
Systemcall one;
one.startscript(Systemcall::Wait, command);
- if (!buffer)
+ if (!doc_buffer)
break;
if (contains(flag, 'I'))
- buffer->markDirty();
+ doc_buffer->markDirty();
if (contains(flag, 'R'))
reloadBuffer();
@@ -1651,8 +1665,10 @@
// Start an undo group. This may be needed for
// some stuff like inset-apply on labels.
- if (theBufferList().isLoaded(buffer))
+ if (buffer && theBufferList().isLoaded(buffer))
buffer->undo().beginUndoGroup();
+ if (doc_buffer && doc_buffer != buffer && theBufferList().isLoaded(doc_buffer))
+ doc_buffer->undo().beginUndoGroup();
// Let the current LyXView dispatch its own actions.
if (lyx_view_->dispatch(cmd)) {
@@ -1661,20 +1677,32 @@
if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
}
+ if (lyx_view_->documentBufferView() && lyx_view_->documentBufferView() != lyx_view_->currentBufferView()) {
+ updateFlags = lyx_view_->documentBufferView()->cursor().result().update();
+ if (theBufferList().isLoaded(doc_buffer))
+ doc_buffer->undo().endUndoGroup();
+ }
break;
}
- LASSERT(lyx_view_->currentBufferView(), /**/);
-
- // Let the current BufferView dispatch its own actions.
- if (lyx_view_->currentBufferView()->dispatch(cmd)) {
+ // First try to dispatch to currentBufferView its own actions.
+ if (buffer && lyx_view_->currentBufferView()->dispatch(cmd)) {
// The BufferView took care of its own updates if needed.
updateFlags = Update::None;
if (theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
break;
+ } else if (doc_buffer && lyx_view_->documentBufferView()->dispatch(cmd)) {
+ /// \TODO Check if correct: we dispatch to documentBufferView() as well, in this case ?
+ // The BufferView took care of its own updates if needed.
+ updateFlags = Update::None;
+ if (theBufferList().isLoaded(doc_buffer))
+ doc_buffer->undo().endUndoGroup();
+ break;
}
+ LASSERT(buffer, /**/);
+
// OK, so try the Buffer itself
DispatchResult dr;
BufferView * bv = lyx_view_->currentBufferView();
@@ -1712,8 +1740,10 @@
bv->cursor().fixIfBroken();
}
- if (theBufferList().isLoaded(buffer))
+ if (buffer && theBufferList().isLoaded(buffer))
buffer->undo().endUndoGroup();
+ if (doc_buffer && doc_buffer != buffer && theBufferList().isLoaded(doc_buffer))
+ doc_buffer->undo().beginUndoGroup();
// update completion. We do it here and not in
// processKeySym to avoid another redraw just for a
@@ -1732,10 +1762,11 @@
}
// if we executed a mutating lfun, mark the buffer as dirty
- if (theBufferList().isLoaded(buffer) && flag.enabled()
+ if (doc_buffer && !doc_buffer->isInternal()
+ && theBufferList().isLoaded(doc_buffer) && flag.enabled()
&& !lyxaction.funcHasFlag(action, LyXAction::NoBuffer)
&& !lyxaction.funcHasFlag(action, LyXAction::ReadOnly))
- buffer->markDirty();
+ doc_buffer->markDirty();
if (lyx_view_ && lyx_view_->currentBufferView()) {
// BufferView::update() updates the ViewMetricsInfo and
@@ -1747,7 +1778,7 @@
// Do we have a selection?
theSelection().haveSelection(
lyx_view_->currentBufferView()->cursor().selection());
-
+
// update gui
lyx_view_->restartCursor();
}