So the crash John reported comes in at r31203. Here's the recipe, again:
1. Open LyX. File>New. Document>Outline, to make sure the TOC is open.
That isn't necessary, but it helps you to see what is happening.
2. Create a section heading (alt-P, 2) with an x in it.
3. Split the screen.
4. File>New. You should now still see the TOC for the OLD buffer.
5. Click in the top screen. You now see an empty TOC (the one for the
empty buffer).
6. Click in the empty buffer. Other TOC!
7. Back to the "x" buffer. Empty TOC. Type something. Boom!
So the issue is that the TOC is out of sync. It gets out of sync when
(a) Buffer 1 is open in both top and bottom, but (b) it is actually
viewed in only one of them and (c) you click back and forth between
top and bottom. You can get it back into sync by clicking on the tabs
in the bottom view.
I can explain why this happens, but I am not sure how to fix it. The
attached patch solves the problem, but looks ugly.
The change that caused the crash is here:
void GuiView::structureChanged()
{
//** used to be d.toc_models_.reset(view());
d.toc_models_.reset(documentBufferView());
LYXERR0(documentBufferView());
// Navigator needs more than a simple update in this case. It needs
to be
// rebuilt.
updateDialog("toc", "");
}
The LYXERR0 call is worth adding if you investigate: You can see from it
that we're setting the TOC for the wrong BufferView.
We get there from:
void GuiView::setCurrentWorkArea(GuiWorkArea * wa)
{
....
for (int i = 0; i != d.splitter_->count(); ++i) {
if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) { // << THIS LINE
d.current_main_work_area_ = wa;
return;
}
}
It is the setCurrentWorkArea() call that eventually gets us to
structureChanged(). The crucial point is that it does so BEFORE the
current_main_work_area_ is reset. That means that documentBufferView(),
which is
¤tMainWorkArea()->bufferView()
still points to the OLD BufferView. That's why we have the wrong TOC.
Given the LYXERR0 call above, you can see that this is in fact happening
even with a split view for a single document. There's no bad effect with
the TOC, since they have the same TOC, but there's surely some other bug
in the offing.
Richard
Index: src/frontends/qt4/GuiView.cpp
===================================================================
--- src/frontends/qt4/GuiView.cpp (revision 35965)
+++ src/frontends/qt4/GuiView.cpp (working copy)
@@ -1216,17 +1216,23 @@
theGuiApp()->setCurrentView(this);
d.current_work_area_ = wa;
+
+ // We need to reset this now, because it will need to be
+ // right if the tabWorkArea gets reset in the for loop. We
+ // will change it back if we aren't in that case.
+ GuiWorkArea * const old_cmwa = d.current_main_work_area_;
+ d.current_main_work_area_ = wa;
+
for (int i = 0; i != d.splitter_->count(); ++i) {
if (d.tabWorkArea(i)->setCurrentWorkArea(wa)) {
- //if (d.current_main_work_area_)
- //
d.current_main_work_area_->setFrameStyle(QFrame::NoFrame);
- d.current_main_work_area_ = wa;
- //d.current_main_work_area_->setFrameStyle(QFrame::Box
| QFrame::Plain);
- //d.current_main_work_area_->setLineWidth(2);
- LYXERR(Debug::DEBUG, "Current wa: " <<
currentWorkArea() << ", Current main wa: " << currentMainWorkArea());
+ LYXERR(Debug::DEBUG, "Current wa: " <<
currentWorkArea()
+ << ", Current main wa: " <<
currentMainWorkArea());
return;
}
}
+
+ d.current_main_work_area_ = old_cmwa;
+
LYXERR(Debug::DEBUG, "This is not a tabbed wa");
on_currentWorkAreaChanged(wa);
BufferView & bv = wa->bufferView();
@@ -1394,6 +1400,7 @@
void GuiView::structureChanged()
{
d.toc_models_.reset(documentBufferView());
+ LYXERR0(documentBufferView());
// Navigator needs more than a simple update in this case. It needs to
be
// rebuilt.
updateDialog("toc", "");