mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-11-22 10:00:33 +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)
|
FuncRequest::FuncRequest(Origin o)
|
||||||
: action_(LFUN_NOACTION), origin_(o), x_(0), y_(0),
|
: 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)
|
FuncRequest::FuncRequest(FuncCode act, Origin o)
|
||||||
: action_(act), origin_(o), x_(0), y_(0),
|
: 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)
|
FuncRequest::FuncRequest(FuncCode act, docstring const & arg, Origin o)
|
||||||
: action_(act), argument_(arg), origin_(o), x_(0), y_(0),
|
: 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)
|
FuncRequest::FuncRequest(FuncCode act, string const & arg, Origin o)
|
||||||
: action_(act), argument_(from_utf8(arg)), origin_(o), x_(0), y_(0),
|
: 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,
|
FuncRequest::FuncRequest(FuncCode act, int ax, int ay,
|
||||||
mouse_button::state but, KeyModifier modifier, Origin o)
|
mouse_button::state but, KeyModifier modifier, Origin o)
|
||||||
: action_(act), origin_(o), x_(ax), y_(ay), button_(but),
|
: 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)
|
FuncRequest::FuncRequest(FuncRequest const & cmd, docstring const & arg, Origin o)
|
||||||
: action_(cmd.action()), argument_(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;
|
class LyXErr;
|
||||||
|
|
||||||
|
namespace frontend {
|
||||||
|
class GuiView;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates a LyX action and its argument
|
* This class encapsulates a LyX action and its argument
|
||||||
* in order to pass it around easily.
|
* in order to pass it around easily.
|
||||||
@ -70,6 +74,10 @@ public:
|
|||||||
///
|
///
|
||||||
void setOrigin(Origin o) { origin_ = o; }
|
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 x() const { return x_; }
|
||||||
///
|
///
|
||||||
int y() const { return y_; }
|
int y() const { return y_; }
|
||||||
@ -97,6 +105,9 @@ private:
|
|||||||
docstring argument_;
|
docstring argument_;
|
||||||
/// who initiated the action
|
/// who initiated the action
|
||||||
Origin origin_;
|
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
|
/// the x coordinate of a mouse press
|
||||||
int x_;
|
int x_;
|
||||||
/// the y coordinate of a mouse press
|
/// 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 const & GuiApplication::dispatch(FuncRequest const & cmd)
|
||||||
{
|
{
|
||||||
|
DispatchResult dr;
|
||||||
|
|
||||||
Buffer * buffer = 0;
|
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()) {
|
if (current_view_ && current_view_->currentBufferView()) {
|
||||||
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
|
current_view_->currentBufferView()->cursor().saveBeforeDispatchPosXY();
|
||||||
buffer = ¤t_view_->currentBufferView()->buffer();
|
buffer = ¤t_view_->currentBufferView()->buffer();
|
||||||
@ -1395,7 +1404,6 @@ DispatchResult const & GuiApplication::dispatch(FuncRequest const & cmd)
|
|||||||
// This handles undo groups automagically
|
// This handles undo groups automagically
|
||||||
UndoGroupHelper ugh(buffer);
|
UndoGroupHelper ugh(buffer);
|
||||||
|
|
||||||
DispatchResult dr;
|
|
||||||
// redraw the screen at the end (first of the two drawing steps).
|
// redraw the screen at the end (first of the two drawing steps).
|
||||||
// This is done unless explicitly requested otherwise
|
// This is done unless explicitly requested otherwise
|
||||||
dr.screenUpdate(Update::FitCursor);
|
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);
|
const_iterator it = models_.find(type);
|
||||||
if (it == models_.end() || !index.isValid()) {
|
if (it == models_.end() || !index.isValid()) {
|
||||||
LYXERR(Debug::GUI, "TocModels::goTo(): QModelIndex is invalid!");
|
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);
|
TocItem const item = it.value()->tocItem(index);
|
||||||
LYXERR(Debug::GUI, "TocModels::goTo " << item.asString());
|
LYXERR(Debug::GUI, "TocModels::goTo " << item.asString());
|
||||||
dispatch(item.action());
|
return item.action();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ namespace lyx {
|
|||||||
class Buffer;
|
class Buffer;
|
||||||
class BufferView;
|
class BufferView;
|
||||||
class DocIterator;
|
class DocIterator;
|
||||||
|
class FuncRequest;
|
||||||
|
|
||||||
namespace frontend {
|
namespace frontend {
|
||||||
|
|
||||||
@ -124,9 +125,7 @@ public:
|
|||||||
QModelIndex currentIndex(QString const & type,
|
QModelIndex currentIndex(QString const & type,
|
||||||
DocIterator const & dit) const;
|
DocIterator const & dit) const;
|
||||||
///
|
///
|
||||||
void goTo(QString const & type, QModelIndex const & index) const;
|
FuncRequest goTo(QString const & type, QModelIndex const & index) const;
|
||||||
///
|
|
||||||
void init(Buffer const & buffer);
|
|
||||||
///
|
///
|
||||||
void updateItem(QString const & type, DocIterator const & dit);
|
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)
|
void TocWidget::doDispatch(Cursor & cur, FuncRequest const & cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
Inset * inset = itemInset();
|
Inset * inset = itemInset();
|
||||||
FuncRequest tmpcmd(cmd);
|
FuncRequest tmpcmd(cmd);
|
||||||
|
|
||||||
@ -235,6 +236,7 @@ void TocWidget::on_tocTV_activated(QModelIndex const & index)
|
|||||||
|
|
||||||
void TocWidget::on_tocTV_pressed(QModelIndex const & index)
|
void TocWidget::on_tocTV_pressed(QModelIndex const & index)
|
||||||
{
|
{
|
||||||
|
|
||||||
Qt::MouseButtons const button = QApplication::mouseButtons();
|
Qt::MouseButtons const button = QApplication::mouseButtons();
|
||||||
if (button & Qt::LeftButton) {
|
if (button & Qt::LeftButton) {
|
||||||
goTo(index);
|
goTo(index);
|
||||||
@ -249,7 +251,7 @@ void TocWidget::goTo(QModelIndex const & index)
|
|||||||
LYXERR(Debug::GUI, "goto " << index.row()
|
LYXERR(Debug::GUI, "goto " << index.row()
|
||||||
<< ", " << index.column());
|
<< ", " << 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)
|
void TocWidget::on_typeCO_currentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (index == -1)
|
if (index == -1)
|
||||||
return;
|
return;
|
||||||
current_type_ = typeCO->itemData(index).toString();
|
current_type_ = typeCO->itemData(index).toString();
|
||||||
@ -328,14 +331,29 @@ void TocWidget::outline(FuncCode func_code)
|
|||||||
QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
|
QModelIndexList const & list = tocTV->selectionModel()->selectedIndexes();
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
return;
|
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);
|
enableControls(false);
|
||||||
goTo(list[0]);
|
goTo(list[0]);
|
||||||
dispatch(FuncRequest(func_code));
|
sendDispatch(FuncRequest(func_code));
|
||||||
enableControls(true);
|
enableControls(true);
|
||||||
gui_view_.setFocus();
|
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()
|
void TocWidget::on_moveUpTB_clicked()
|
||||||
{
|
{
|
||||||
outline(LFUN_OUTLINE_UP);
|
outline(LFUN_OUTLINE_UP);
|
||||||
|
@ -40,6 +40,9 @@ public:
|
|||||||
void init(QString const & str);
|
void init(QString const & str);
|
||||||
///
|
///
|
||||||
void doDispatch(Cursor & cur, FuncRequest const & fr);
|
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)
|
bool getStatus(Cursor & cur, FuncRequest const & fr, FuncStatus & status)
|
||||||
const;
|
const;
|
||||||
|
Loading…
Reference in New Issue
Block a user