mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-09 18:31:04 +00:00
Fix Undocked Outliner & multiple window crashes (#11004).
There are more independent crashes occuring in this scenario and this fix targets only one of them, in particular the one in which different window's outliner sends outliner command to a wrong window. The fix itself gives an option for lfun to know which window it belongs to. https://www.mail-archive.com/lyx-devel@lists.lyx.org/msg203619.html
This commit is contained in:
parent
e41c80e224
commit
8725614e3f
@ -31,38 +31,39 @@ FuncRequest const FuncRequest::noaction(LFUN_NOACTION);
|
||||
|
||||
FuncRequest::FuncRequest(Origin o)
|
||||
: action_(LFUN_NOACTION), origin_(o), x_(0), y_(0),
|
||||
button_(mouse_button::none), modifier_(NoModifier)
|
||||
button_(mouse_button::none), modifier_(NoModifier), view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
FuncRequest::FuncRequest(FuncCode act, Origin o)
|
||||
: action_(act), origin_(o), x_(0), y_(0),
|
||||
button_(mouse_button::none), modifier_(NoModifier)
|
||||
button_(mouse_button::none), modifier_(NoModifier), view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
FuncRequest::FuncRequest(FuncCode act, docstring const & arg, Origin o)
|
||||
: action_(act), argument_(arg), origin_(o), x_(0), y_(0),
|
||||
button_(mouse_button::none), modifier_(NoModifier)
|
||||
button_(mouse_button::none), modifier_(NoModifier), view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
FuncRequest::FuncRequest(FuncCode act, string const & arg, Origin o)
|
||||
: action_(act), argument_(from_utf8(arg)), origin_(o), x_(0), y_(0),
|
||||
button_(mouse_button::none), modifier_(NoModifier)
|
||||
button_(mouse_button::none), modifier_(NoModifier), view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
FuncRequest::FuncRequest(FuncCode act, int ax, int ay,
|
||||
mouse_button::state but, KeyModifier modifier, Origin o)
|
||||
: action_(act), origin_(o), x_(ax), y_(ay), button_(but),
|
||||
modifier_(modifier)
|
||||
modifier_(modifier), view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
FuncRequest::FuncRequest(FuncRequest const & cmd, docstring const & arg, Origin o)
|
||||
: action_(cmd.action()), argument_(arg), origin_(o),
|
||||
x_(cmd.x_), y_(cmd.y_), button_(cmd.button_), modifier_(NoModifier)
|
||||
x_(cmd.x_), y_(cmd.y_), button_(cmd.button_), modifier_(NoModifier),
|
||||
view_origin_(0)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -24,6 +24,10 @@ namespace lyx {
|
||||
|
||||
class LyXErr;
|
||||
|
||||
namespace frontend {
|
||||
class GuiView;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class encapsulates a LyX action and its argument
|
||||
* in order to pass it around easily.
|
||||
@ -70,6 +74,10 @@ public:
|
||||
///
|
||||
void setOrigin(Origin o) { origin_ = o; }
|
||||
///
|
||||
frontend::GuiView* view_origin() const { return view_origin_; }
|
||||
///
|
||||
void setViewOrigin(frontend::GuiView* o) { view_origin_ = o; }
|
||||
///
|
||||
int x() const { return x_; }
|
||||
///
|
||||
int y() const { return y_; }
|
||||
@ -97,6 +105,9 @@ private:
|
||||
docstring argument_;
|
||||
/// who initiated the action
|
||||
Origin origin_;
|
||||
/// to which view should be this command sent (see bug #11004)
|
||||
/// NULL=current view
|
||||
frontend::GuiView* view_origin_;
|
||||
/// the x coordinate of a mouse press
|
||||
int x_;
|
||||
/// the y coordinate of a mouse press
|
||||
|
@ -1387,7 +1387,16 @@ static docstring makeDispatchMessage(docstring const & msg,
|
||||
|
||||
DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
|
||||
{
|
||||
DispatchResult dr;
|
||||
|
||||
Buffer * buffer = 0;
|
||||
if (cmd.view_origin() && current_view_ != cmd.view_origin()) {
|
||||
//setCurrentView(cmd.view_origin); //does not work
|
||||
dr.setError(true);
|
||||
dr.setMessage(_("Wrong focus!"));
|
||||
d->dispatch_result_ = dr;
|
||||
return d->dispatch_result_;
|
||||
}
|
||||
if (current_view_ && current_view_->currentBufferView()) {
|
||||
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
|
||||
buffer = ¤t_view_->currentBufferView()->buffer();
|
||||
@ -1395,7 +1404,6 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
|
||||
// This handles undo groups automagically
|
||||
UndoGroupHelper ugh(buffer);
|
||||
|
||||
DispatchResult dr;
|
||||
// redraw the screen at the end (first of the two drawing steps).
|
||||
// This is done unless explicitly requested otherwise
|
||||
dr.screenUpdate(Update::FitCursor);
|
||||
|
@ -303,17 +303,17 @@ QModelIndex TocModels::currentIndex(QString const & type,
|
||||
}
|
||||
|
||||
|
||||
void TocModels::goTo(QString const & type, QModelIndex const & index) const
|
||||
FuncRequest TocModels::goTo(QString const & type, QModelIndex const & index) const
|
||||
{
|
||||
const_iterator it = models_.find(type);
|
||||
if (it == models_.end() || !index.isValid()) {
|
||||
LYXERR(Debug::GUI, "TocModels::goTo(): QModelIndex is invalid!");
|
||||
return;
|
||||
return FuncRequest(LFUN_NOACTION);
|
||||
}
|
||||
LASSERT(index.model() == it.value()->model(), return);
|
||||
LASSERT(index.model() == it.value()->model(), return FuncRequest(LFUN_NOACTION));
|
||||
TocItem const item = it.value()->tocItem(index);
|
||||
LYXERR(Debug::GUI, "TocModels::goTo " << item.asString());
|
||||
dispatch(item.action());
|
||||
return item.action();
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ namespace lyx {
|
||||
class Buffer;
|
||||
class BufferView;
|
||||
class DocIterator;
|
||||
class FuncRequest;
|
||||
|
||||
namespace frontend {
|
||||
|
||||
@ -124,9 +125,7 @@ public:
|
||||
QModelIndex currentIndex(QString const & type,
|
||||
DocIterator const & dit) const;
|
||||
///
|
||||
void goTo(QString const & type, QModelIndex const & index) const;
|
||||
///
|
||||
void init(Buffer const & buffer);
|
||||
FuncRequest goTo(QString const & type, QModelIndex const & index) const;
|
||||
///
|
||||
void updateItem(QString const & type, DocIterator const & dit);
|
||||
///
|
||||
|
@ -178,6 +178,7 @@ bool TocWidget::getStatus(Cursor & cur, FuncRequest const & cmd,
|
||||
|
||||
void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd)
|
||||
{
|
||||
|
||||
Inset * inset = itemInset();
|
||||
FuncRequest tmpcmd(cmd);
|
||||
|
||||
@ -235,6 +236,7 @@ void TocWidget::on_tocTV_activated(QModelIndex const & index)
|
||||
|
||||
void TocWidget::on_tocTV_pressed(QModelIndex const & index)
|
||||
{
|
||||
|
||||
Qt::MouseButtons const button = QApplication::mouseButtons();
|
||||
if (button & Qt::LeftButton) {
|
||||
goTo(index);
|
||||
@ -249,7 +251,7 @@ void TocWidget::goTo(QModelIndex const & index)
|
||||
LYXERR(Debug::GUI, "goto " << index.row()
|
||||
<< ", " << index.column());
|
||||
|
||||
gui_view_.tocModels().goTo(current_type_, index);
|
||||
sendDispatch(gui_view_.tocModels().goTo(current_type_, index));
|
||||
}
|
||||
|
||||
|
||||
@ -314,6 +316,7 @@ void TocWidget::setTreeDepth(int depth)
|
||||
|
||||
void TocWidget::on_typeCO_currentIndexChanged(int index)
|
||||
{
|
||||
|
||||
if (index == -1)
|
||||
return;
|
||||
current_type_ = typeCO->itemData(index).toString();
|
||||
@ -328,14 +331,29 @@ void TocWidget::outline(FuncCode func_code)
|
||||
QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
|
||||
if (list.isEmpty())
|
||||
return;
|
||||
|
||||
//if another window is active, this attempt will fail,
|
||||
//but it will work at least for the second attempt
|
||||
gui_view_.activateWindow();
|
||||
|
||||
enableControls(false);
|
||||
goTo(list[0]);
|
||||
dispatch(FuncRequest(func_code));
|
||||
sendDispatch(FuncRequest(func_code));
|
||||
enableControls(true);
|
||||
gui_view_.setFocus();
|
||||
}
|
||||
|
||||
|
||||
void TocWidget::sendDispatch(FuncRequest fr)
|
||||
{
|
||||
|
||||
fr.setViewOrigin(&gui_view_);
|
||||
DispatchResult dr=dispatch(fr);
|
||||
if (dr.error())
|
||||
gui_view_.message(dr.message());
|
||||
}
|
||||
|
||||
|
||||
void TocWidget::on_moveUpTB_clicked()
|
||||
{
|
||||
outline(LFUN_OUTLINE_UP);
|
||||
|
@ -40,6 +40,9 @@ public:
|
||||
void init(QString const & str);
|
||||
///
|
||||
void doDispatch(Cursor & cur, FuncRequest const & fr);
|
||||
///send request to lyx::dispatch with proper guiview handle
|
||||
///(if ToC is detached current_view can be different window)
|
||||
void sendDispatch(FuncRequest fr);
|
||||
///
|
||||
bool getStatus(Cursor & cur, FuncRequest const & fr, FuncStatus & status)
|
||||
const;
|
||||
|
Loading…
Reference in New Issue
Block a user