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)
|
GuiCompleter::GuiCompleter(GuiWorkArea * gui, QObject * parent)
|
||||||
: QCompleter(parent), gui_(gui), updateLock_(0),
|
: QCompleter(parent), gui_(gui), updateLock_(0),
|
||||||
inlineVisible_(false), popupVisible_(false)
|
inlineVisible_(false), popupVisible_(false),
|
||||||
|
modelActive_(false)
|
||||||
{
|
{
|
||||||
// Setup the completion popup
|
// Setup the completion popup
|
||||||
setModel(new GuiCompletionModel(this, 0));
|
setModel(new GuiCompletionModel(this, 0));
|
||||||
@ -250,6 +251,9 @@ bool GuiCompleter::inlinePossible(Cursor const & cur) const
|
|||||||
|
|
||||||
bool GuiCompleter::completionAvailable() const
|
bool GuiCompleter::completionAvailable() const
|
||||||
{
|
{
|
||||||
|
if (!modelActive_)
|
||||||
|
return false;
|
||||||
|
|
||||||
size_t n = popup()->model()->rowCount();
|
size_t n = popup()->model()->rowCount();
|
||||||
|
|
||||||
// if there is exactly one, we have to check whether it is a
|
// 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));
|
inline_timer_.start(int(lyxrc.completion_inline_delay * 1000));
|
||||||
|
|
||||||
// update prefix if any completion is possible
|
// update prefix if any completion is possible
|
||||||
bool modelActive = model()->rowCount() > 0;
|
bool modelActive = modelActive_ && model()->rowCount() > 0;
|
||||||
if (possiblePopupState || possibleInlineState) {
|
if (possiblePopupState || possibleInlineState) {
|
||||||
if (modelActive)
|
if (modelActive)
|
||||||
updatePrefix(cur);
|
updatePrefix(cur);
|
||||||
@ -402,14 +406,11 @@ void GuiCompleter::updatePopup(Cursor & cur)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// show asynchronously to avoid lookups before the metrics
|
QTimer::singleShot(0, this, SLOT(asyncUpdatePopup()));
|
||||||
// have been computed. This can happen because we might be in
|
|
||||||
// the middle of a dispatch.
|
|
||||||
QTimer::singleShot(0, this, SLOT(asyncCompletePopup()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GuiCompleter::asyncCompletePopup()
|
void GuiCompleter::asyncUpdatePopup()
|
||||||
{
|
{
|
||||||
Cursor cur = gui_->bufferView().cursor();
|
Cursor cur = gui_->bufferView().cursor();
|
||||||
if (!cur.inset().completionSupported(cur)) {
|
if (!cur.inset().completionSupported(cur)) {
|
||||||
@ -482,6 +483,7 @@ void GuiCompleter::updateModel(Cursor & cur, bool popupUpdate, bool inlineUpdate
|
|||||||
// set new model
|
// set new model
|
||||||
Inset::CompletionList const * list = cur.inset().createCompletionList(cur);
|
Inset::CompletionList const * list = cur.inset().createCompletionList(cur);
|
||||||
setModel(new GuiCompletionModel(this, list));
|
setModel(new GuiCompletionModel(this, list));
|
||||||
|
modelActive_ = true;
|
||||||
if (list->sorted())
|
if (list->sorted())
|
||||||
setModelSorting(QCompleter::CaseSensitivelySortedModel);
|
setModelSorting(QCompleter::CaseSensitivelySortedModel);
|
||||||
else
|
else
|
||||||
@ -527,17 +529,26 @@ void GuiCompleter::showPopup(Cursor & cur)
|
|||||||
void GuiCompleter::hidePopup(Cursor & cur)
|
void GuiCompleter::hidePopup(Cursor & cur)
|
||||||
{
|
{
|
||||||
popupVisible_ = false;
|
popupVisible_ = false;
|
||||||
|
|
||||||
|
if (popup_timer_.isActive())
|
||||||
|
popup_timer_.stop();
|
||||||
|
|
||||||
// hide popup asynchronously because we might be here inside of
|
// hide popup asynchronously because we might be here inside of
|
||||||
// LFUN dispatchers. Hiding a popup can trigger a focus event on the
|
// LFUN dispatchers. Hiding a popup can trigger a focus event on the
|
||||||
// workarea which then redisplays the cursor. But the metrics are not
|
// 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
|
// 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.
|
// cursorPos methods would triggers asserts in the coord cache then.
|
||||||
QTimer::singleShot(0, popup(), SLOT(hide()));
|
QTimer::singleShot(0, this, SLOT(asyncHidePopup()));
|
||||||
|
|
||||||
if (popup_timer_.isActive())
|
|
||||||
popup_timer_.stop();
|
|
||||||
|
|
||||||
|
// mark that the asynchronous part will reset the model
|
||||||
|
if (!inlineVisible())
|
||||||
|
modelActive_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GuiCompleter::asyncHidePopup()
|
||||||
|
{
|
||||||
|
popup()->hide();
|
||||||
if (!inlineVisible())
|
if (!inlineVisible())
|
||||||
setModel(new GuiCompletionModel(this, 0));
|
setModel(new GuiCompletionModel(this, 0));
|
||||||
}
|
}
|
||||||
@ -560,6 +571,19 @@ void GuiCompleter::hideInline(Cursor & cur)
|
|||||||
if (inline_timer_.isActive())
|
if (inline_timer_.isActive())
|
||||||
inline_timer_.stop();
|
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())
|
if (!popupVisible())
|
||||||
setModel(new GuiCompletionModel(this, 0));
|
setModel(new GuiCompletionModel(this, 0));
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,12 @@ private Q_SLOTS:
|
|||||||
void popupHighlighted(const QString & completion);
|
void popupHighlighted(const QString & completion);
|
||||||
///
|
///
|
||||||
void updateAvailability();
|
void updateAvailability();
|
||||||
///
|
/// the asynchronous part of updatePopup(cur)
|
||||||
void asyncCompletePopup();
|
void asyncUpdatePopup();
|
||||||
|
/// the asynchronous part of hidePopup(cur)
|
||||||
|
void asyncHidePopup();
|
||||||
|
/// the asynchronous part of hideInline(cur)
|
||||||
|
void asyncHideInline();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
@ -131,6 +135,9 @@ private:
|
|||||||
bool inlineVisible_;
|
bool inlineVisible_;
|
||||||
///
|
///
|
||||||
bool popupVisible_;
|
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_;
|
RtlItemDelegate * rtlItemDelegate_;
|
||||||
}; // GuiCompleter
|
}; // GuiCompleter
|
||||||
|
Loading…
Reference in New Issue
Block a user