Commit a4e34a80 authored by Martin Aumüller's avatar Martin Aumüller Committed by hjk
Browse files

fakevim: make sure that FakeVimHandler has returned before being deleted



some actions might cause the parent editor to be deleted,
don't crash in that case

Merge-request: 101
Reviewed-by: default avatarhjk <qtc-committer@nokia.com>
parent 7c9c7a0f
......@@ -662,17 +662,20 @@ EventResult FakeVimHandler::Private::handleEvent(QKeyEvent *ev)
EventResult result = handleKey(key, um, ev->text());
//endEditBlock();
// We fake vi-style end-of-line behaviour
m_fakeEnd = atEndOfLine() && m_mode == CommandMode && !isVisualBlockMode();
// the command might have destroyed the editor
if (m_textedit || m_plaintextedit) {
// We fake vi-style end-of-line behaviour
m_fakeEnd = atEndOfLine() && m_mode == CommandMode && !isVisualBlockMode();
QTC_ASSERT(!(m_mode != InsertMode && m_tc.atBlockEnd() && m_tc.block().length() > 1),
qDebug() << "Cursor at EOL after key handler");
QTC_ASSERT(!(m_mode != InsertMode && m_tc.atBlockEnd() && m_tc.block().length() > 1),
qDebug() << "Cursor at EOL after key handler");
if (m_fakeEnd)
moveLeft();
if (m_fakeEnd)
moveLeft();
EDITOR(setTextCursor(m_tc));
m_oldPosition = m_tc.position();
EDITOR(setTextCursor(m_tc));
m_oldPosition = m_tc.position();
}
return result;
}
......@@ -1033,6 +1036,9 @@ void FakeVimHandler::Private::updateSelection()
void FakeVimHandler::Private::updateMiniBuffer()
{
if (!m_textedit && !m_plaintextedit)
return;
QString msg;
if (m_passing) {
msg = "-- PASSING -- ";
......@@ -2060,8 +2066,10 @@ EventResult FakeVimHandler::Private::handleMiniBufferModes(int key, int unmodifi
m_commandHistory.append(m_commandBuffer);
EDITOR(setTextCursor(m_tc));
handleExCommand(m_commandBuffer);
m_tc = EDITOR(textCursor());
leaveVisualMode();
if (m_textedit || m_plaintextedit) {
m_tc = EDITOR(textCursor());
leaveVisualMode();
}
}
} else if (unmodified == Key_Return && isSearchMode()) {
if (!m_commandBuffer.isEmpty()) {
......@@ -3428,6 +3436,13 @@ FakeVimHandler::~FakeVimHandler()
delete d;
}
// gracefully handle that the parent editor is deleted
void FakeVimHandler::disconnectFromEditor()
{
d->m_textedit = 0;
d->m_plaintextedit = 0;
}
bool FakeVimHandler::eventFilter(QObject *ob, QEvent *ev)
{
bool active = theFakeVimSetting(ConfigUseFakeVim)->value().toBool();
......
......@@ -48,6 +48,9 @@ public:
QWidget *widget();
// call before widget is deleted
void disconnectFromEditor();
public slots:
void setCurrentFileName(const QString &fileName);
void showBlackMessage(const QString &msg);
......
......@@ -744,6 +744,30 @@ void FakeVimPluginPrivate::findNext(bool reverse)
triggerAction(Find::Constants::FIND_NEXT);
}
// this class defers deletion of a child FakeVimHandler using 'deleteLater'
// - direct children QObject's would be 'delete'ed immediately before their parents
class DeferredDeleter : public QObject
{
Q_OBJECT
FakeVimHandler *m_handler;
public:
DeferredDeleter(QObject *parent, FakeVimHandler *handler)
: QObject(parent)
, m_handler(handler)
{}
virtual ~DeferredDeleter()
{
if (m_handler) {
m_handler->disconnectFromEditor();
m_handler->deleteLater();
m_handler = 0;
}
}
};
void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
{
if (!editor)
......@@ -760,7 +784,10 @@ void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
//qDebug() << "OPENING: " << editor << editor->widget()
// << "MODE: " << theFakeVimSetting(ConfigUseFakeVim)->value();
FakeVimHandler *handler = new FakeVimHandler(widget, widget);
FakeVimHandler *handler = new FakeVimHandler(widget, 0);
// the handler might have triggered the deletion of the editor:
// make sure that it can return before being deleted itself
new DeferredDeleter(widget, handler);
m_editorToHandler[editor] = handler;
connect(handler, SIGNAL(extraInformationChanged(QString)),
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment