mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-23 21:40:19 +00:00
* even setModel can trigger focus events. So move also those into
asynchronous handlers. git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@23438 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
parent
6e3e2ae19b
commit
de518abff5
@ -173,7 +173,8 @@ private:
|
||||
|
||||
GuiCompleter::GuiCompleter(GuiWorkArea * gui, QObject * parent)
|
||||
: QCompleter(parent), gui_(gui), updateLock_(0),
|
||||
inlineVisible_(false), popupVisible_(false)
|
||||
inlineVisible_(false), popupVisible_(false),
|
||||
modelActive_(false)
|
||||
{
|
||||
// Setup the completion popup
|
||||
setModel(new GuiCompletionModel(this, 0));
|
||||
@ -250,6 +251,9 @@ bool GuiCompleter::inlinePossible(Cursor const & cur) const
|
||||
|
||||
bool GuiCompleter::completionAvailable() const
|
||||
{
|
||||
if (!modelActive_)
|
||||
return false;
|
||||
|
||||
size_t n = popup()->model()->rowCount();
|
||||
|
||||
// if there is exactly one, we have to check whether it is a
|
||||
@ -308,7 +312,7 @@ void GuiCompleter::updateVisibility(Cursor & cur, bool start, bool keep, bool cu
|
||||
inline_timer_.start(int(lyxrc.completion_inline_delay * 1000));
|
||||
|
||||
// update prefix if any completion is possible
|
||||
bool modelActive = model()->rowCount() > 0;
|
||||
bool modelActive = modelActive_ && model()->rowCount() > 0;
|
||||
if (possiblePopupState || possibleInlineState) {
|
||||
if (modelActive)
|
||||
updatePrefix(cur);
|
||||
@ -402,14 +406,11 @@ void GuiCompleter::updatePopup(Cursor & cur)
|
||||
return;
|
||||
}
|
||||
|
||||
// show asynchronously to avoid lookups before the metrics
|
||||
// have been computed. This can happen because we might be in
|
||||
// the middle of a dispatch.
|
||||
QTimer::singleShot(0, this, SLOT(asyncCompletePopup()));
|
||||
QTimer::singleShot(0, this, SLOT(asyncUpdatePopup()));
|
||||
}
|
||||
|
||||
|
||||
void GuiCompleter::asyncCompletePopup()
|
||||
void GuiCompleter::asyncUpdatePopup()
|
||||
{
|
||||
Cursor cur = gui_->bufferView().cursor();
|
||||
if (!cur.inset().completionSupported(cur)) {
|
||||
@ -482,6 +483,7 @@ void GuiCompleter::updateModel(Cursor & cur, bool popupUpdate, bool inlineUpdate
|
||||
// set new model
|
||||
Inset::CompletionList const * list = cur.inset().createCompletionList(cur);
|
||||
setModel(new GuiCompletionModel(this, list));
|
||||
modelActive_ = true;
|
||||
if (list->sorted())
|
||||
setModelSorting(QCompleter::CaseSensitivelySortedModel);
|
||||
else
|
||||
@ -527,17 +529,26 @@ void GuiCompleter::showPopup(Cursor & cur)
|
||||
void GuiCompleter::hidePopup(Cursor & cur)
|
||||
{
|
||||
popupVisible_ = false;
|
||||
|
||||
|
||||
if (popup_timer_.isActive())
|
||||
popup_timer_.stop();
|
||||
|
||||
// hide popup asynchronously because we might be here inside of
|
||||
// LFUN dispatchers. Hiding a popup can trigger a focus event on the
|
||||
// workarea which then redisplays the cursor. But the metrics are not
|
||||
// yet up to date such that the coord cache has not all insets yet. The
|
||||
// cursorPos methods would triggers asserts in the coord cache then.
|
||||
QTimer::singleShot(0, popup(), SLOT(hide()));
|
||||
|
||||
if (popup_timer_.isActive())
|
||||
popup_timer_.stop();
|
||||
QTimer::singleShot(0, this, SLOT(asyncHidePopup()));
|
||||
|
||||
// mark that the asynchronous part will reset the model
|
||||
if (!inlineVisible())
|
||||
modelActive_ = false;
|
||||
}
|
||||
|
||||
|
||||
void GuiCompleter::asyncHidePopup()
|
||||
{
|
||||
popup()->hide();
|
||||
if (!inlineVisible())
|
||||
setModel(new GuiCompletionModel(this, 0));
|
||||
}
|
||||
@ -560,6 +571,19 @@ void GuiCompleter::hideInline(Cursor & cur)
|
||||
if (inline_timer_.isActive())
|
||||
inline_timer_.stop();
|
||||
|
||||
// Trigger asynchronous part of hideInline. We might be
|
||||
// in a dispatcher here and the setModel call might
|
||||
// trigger focus events which is are not healthy here.
|
||||
QTimer::singleShot(0, this, SLOT(asyncHideModel()));
|
||||
|
||||
// mark that the asynchronous part will reset the model
|
||||
if (!popupVisible())
|
||||
modelActive_ = false;
|
||||
}
|
||||
|
||||
|
||||
void GuiCompleter::asyncHideInline()
|
||||
{
|
||||
if (!popupVisible())
|
||||
setModel(new GuiCompletionModel(this, 0));
|
||||
}
|
||||
|
@ -88,8 +88,12 @@ private Q_SLOTS:
|
||||
void popupHighlighted(const QString & completion);
|
||||
///
|
||||
void updateAvailability();
|
||||
///
|
||||
void asyncCompletePopup();
|
||||
/// the asynchronous part of updatePopup(cur)
|
||||
void asyncUpdatePopup();
|
||||
/// the asynchronous part of hidePopup(cur)
|
||||
void asyncHidePopup();
|
||||
/// the asynchronous part of hideInline(cur)
|
||||
void asyncHideInline();
|
||||
|
||||
private:
|
||||
///
|
||||
@ -131,6 +135,9 @@ private:
|
||||
bool inlineVisible_;
|
||||
///
|
||||
bool popupVisible_;
|
||||
/// the model reset is asynchronous in hidePopup/Inline. So let's mark
|
||||
/// a coming reset here by setting it to false.
|
||||
bool modelActive_;
|
||||
///
|
||||
RtlItemDelegate * rtlItemDelegate_;
|
||||
}; // GuiCompleter
|
||||
|
Loading…
Reference in New Issue
Block a user