forked from qt-creator/qt-creator
Fix a crash on codestylesettings
Task-number: QTCREATORBUG-10235 Instead of rely on ICodeStylePreferences::destroyed() signal, when all other objects might be in destruction phase, clear project code style settings explicitly, when project closes. Change-Id: I0dd6675d54c5495d4006acbc9ad12c95f1d0a00c Reviewed-by: Eike Ziller <eike.ziller@digia.com> Reviewed-by: Jarek Kobus <jaroslaw.kobus@digia.com>
This commit is contained in:
@@ -33,6 +33,7 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
|
|
||||||
#include <coreplugin/id.h>
|
#include <coreplugin/id.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <texteditor/basetexteditor.h>
|
#include <texteditor/basetexteditor.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
#include <texteditor/simplecodestylepreferences.h>
|
#include <texteditor/simplecodestylepreferences.h>
|
||||||
@@ -91,22 +92,32 @@ EditorConfiguration::EditorConfiguration() : d(new EditorConfigurationPrivate)
|
|||||||
while (itCodeStyle.hasNext()) {
|
while (itCodeStyle.hasNext()) {
|
||||||
itCodeStyle.next();
|
itCodeStyle.next();
|
||||||
Core::Id languageId = itCodeStyle.key();
|
Core::Id languageId = itCodeStyle.key();
|
||||||
|
// global prefs for language
|
||||||
ICodeStylePreferences *originalPreferences = itCodeStyle.value();
|
ICodeStylePreferences *originalPreferences = itCodeStyle.value();
|
||||||
ICodeStylePreferencesFactory *factory = textEditorSettings->codeStyleFactory(languageId);
|
ICodeStylePreferencesFactory *factory = textEditorSettings->codeStyleFactory(languageId);
|
||||||
|
// clone of global prefs for language - it will became project prefs for language
|
||||||
ICodeStylePreferences *preferences = factory->createCodeStyle();
|
ICodeStylePreferences *preferences = factory->createCodeStyle();
|
||||||
|
// project prefs can point to the global language pool, which contains also the global language prefs
|
||||||
preferences->setDelegatingPool(textEditorSettings->codeStylePool(languageId));
|
preferences->setDelegatingPool(textEditorSettings->codeStylePool(languageId));
|
||||||
preferences->setId(languageId.toString() + QLatin1String("Project"));
|
preferences->setId(languageId.toString() + QLatin1String("Project"));
|
||||||
preferences->setDisplayName(tr("Project %1", "Settings, %1 is a language (C++ or QML)").arg(factory->displayName()));
|
preferences->setDisplayName(tr("Project %1", "Settings, %1 is a language (C++ or QML)").arg(factory->displayName()));
|
||||||
|
// project prefs by default point to global prefs (which in turn can delegate to anything else or not)
|
||||||
preferences->setCurrentDelegate(originalPreferences);
|
preferences->setCurrentDelegate(originalPreferences);
|
||||||
d->m_languageCodeStylePreferences.insert(languageId, preferences);
|
d->m_languageCodeStylePreferences.insert(languageId, preferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clone of global prefs (not language specific), for project scope
|
||||||
d->m_defaultCodeStyle = new SimpleCodeStylePreferences(this);
|
d->m_defaultCodeStyle = new SimpleCodeStylePreferences(this);
|
||||||
d->m_defaultCodeStyle->setDelegatingPool(textEditorSettings->codeStylePool());
|
d->m_defaultCodeStyle->setDelegatingPool(textEditorSettings->codeStylePool());
|
||||||
d->m_defaultCodeStyle->setDisplayName(tr("Project", "Settings"));
|
d->m_defaultCodeStyle->setDisplayName(tr("Project", "Settings"));
|
||||||
d->m_defaultCodeStyle->setId(kId);
|
d->m_defaultCodeStyle->setId(kId);
|
||||||
|
// if setCurrentDelegate is 0 values are read from *this prefs
|
||||||
d->m_defaultCodeStyle->setCurrentDelegate(d->m_useGlobal
|
d->m_defaultCodeStyle->setCurrentDelegate(d->m_useGlobal
|
||||||
? TextEditorSettings::instance()->codeStyle() : 0);
|
? TextEditorSettings::instance()->codeStyle() : 0);
|
||||||
|
|
||||||
|
const SessionManager *session = ProjectExplorerPlugin::instance()->session();
|
||||||
|
connect(session, SIGNAL(aboutToRemoveProject(ProjectExplorer::Project*)),
|
||||||
|
this, SLOT(slotAboutToRemoveProject(ProjectExplorer::Project*)));
|
||||||
}
|
}
|
||||||
|
|
||||||
EditorConfiguration::~EditorConfiguration()
|
EditorConfiguration::~EditorConfiguration()
|
||||||
@@ -243,6 +254,15 @@ void EditorConfiguration::configureEditor(ITextEditor *textEditor) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorConfiguration::deconfigureEditor(ITextEditor *textEditor) const
|
||||||
|
{
|
||||||
|
BaseTextEditorWidget *baseTextEditor = qobject_cast<BaseTextEditorWidget *>(textEditor->widget());
|
||||||
|
if (baseTextEditor)
|
||||||
|
baseTextEditor->setCodeStyle(TextEditorSettings::instance()->codeStyle(baseTextEditor->languageSettingsId()));
|
||||||
|
|
||||||
|
// TODO: what about text codec and switching settings?
|
||||||
|
}
|
||||||
|
|
||||||
void EditorConfiguration::setUseGlobalSettings(bool use)
|
void EditorConfiguration::setUseGlobalSettings(bool use)
|
||||||
{
|
{
|
||||||
d->m_useGlobal = use;
|
d->m_useGlobal = use;
|
||||||
@@ -325,6 +345,27 @@ void EditorConfiguration::setTextCodec(QTextCodec *textCodec)
|
|||||||
d->m_textCodec = textCodec;
|
d->m_textCodec = textCodec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EditorConfiguration::slotAboutToRemoveProject(ProjectExplorer::Project *project)
|
||||||
|
{
|
||||||
|
if (project->editorConfiguration() != this)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::EditorManager *em = Core::ICore::editorManager();
|
||||||
|
const SessionManager *session = ProjectExplorerPlugin::instance()->session();
|
||||||
|
QList<Core::IEditor*> editors = em->openedEditors();
|
||||||
|
for (int i = 0; i < editors.count(); i++) {
|
||||||
|
Core::IEditor *editor = editors.at(i);
|
||||||
|
if (TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor)) {
|
||||||
|
Core::IDocument *document = editor->document();
|
||||||
|
if (document) {
|
||||||
|
Project *editorProject = session->projectForFile(document->fileName());
|
||||||
|
if (project == editorProject)
|
||||||
|
deconfigureEditor(textEditor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TabSettings actualTabSettings(const QString &fileName,
|
TabSettings actualTabSettings(const QString &fileName,
|
||||||
const BaseTextEditorWidget *baseTextEditor)
|
const BaseTextEditorWidget *baseTextEditor)
|
||||||
{
|
{
|
||||||
|
@@ -50,6 +50,7 @@ class ExtraEncodingSettings;
|
|||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
|
class Project;
|
||||||
struct EditorConfigurationPrivate;
|
struct EditorConfigurationPrivate;
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT EditorConfiguration : public QObject
|
class PROJECTEXPLORER_EXPORT EditorConfiguration : public QObject
|
||||||
@@ -77,6 +78,7 @@ public:
|
|||||||
QMap<Core::Id, TextEditor::ICodeStylePreferences *> codeStyles() const;
|
QMap<Core::Id, TextEditor::ICodeStylePreferences *> codeStyles() const;
|
||||||
|
|
||||||
void configureEditor(TextEditor::ITextEditor *textEditor) const;
|
void configureEditor(TextEditor::ITextEditor *textEditor) const;
|
||||||
|
void deconfigureEditor(TextEditor::ITextEditor *textEditor) const;
|
||||||
|
|
||||||
QVariantMap toMap() const;
|
QVariantMap toMap() const;
|
||||||
void fromMap(const QVariantMap &map);
|
void fromMap(const QVariantMap &map);
|
||||||
@@ -96,6 +98,7 @@ private slots:
|
|||||||
|
|
||||||
void setTextCodec(QTextCodec *textCodec);
|
void setTextCodec(QTextCodec *textCodec);
|
||||||
|
|
||||||
|
void slotAboutToRemoveProject(ProjectExplorer::Project *project);
|
||||||
private:
|
private:
|
||||||
void switchSettings(TextEditor::BaseTextEditorWidget *baseTextEditor) const;
|
void switchSettings(TextEditor::BaseTextEditorWidget *baseTextEditor) const;
|
||||||
template <class NewSenderT, class OldSenderT>
|
template <class NewSenderT, class OldSenderT>
|
||||||
|
@@ -4623,8 +4623,6 @@ void BaseTextEditorWidget::setCodeStyle(ICodeStylePreferences *preferences)
|
|||||||
this, SLOT(setTabSettings(TextEditor::TabSettings)));
|
this, SLOT(setTabSettings(TextEditor::TabSettings)));
|
||||||
disconnect(d->m_codeStylePreferences, SIGNAL(currentValueChanged(QVariant)),
|
disconnect(d->m_codeStylePreferences, SIGNAL(currentValueChanged(QVariant)),
|
||||||
this, SLOT(slotCodeStyleSettingsChanged(QVariant)));
|
this, SLOT(slotCodeStyleSettingsChanged(QVariant)));
|
||||||
disconnect(d->m_codeStylePreferences, SIGNAL(destroyed()),
|
|
||||||
this, SLOT(onCodeStylePreferencesDestroyed()));
|
|
||||||
}
|
}
|
||||||
d->m_codeStylePreferences = preferences;
|
d->m_codeStylePreferences = preferences;
|
||||||
if (d->m_codeStylePreferences) {
|
if (d->m_codeStylePreferences) {
|
||||||
@@ -4632,25 +4630,11 @@ void BaseTextEditorWidget::setCodeStyle(ICodeStylePreferences *preferences)
|
|||||||
this, SLOT(setTabSettings(TextEditor::TabSettings)));
|
this, SLOT(setTabSettings(TextEditor::TabSettings)));
|
||||||
connect(d->m_codeStylePreferences, SIGNAL(currentValueChanged(QVariant)),
|
connect(d->m_codeStylePreferences, SIGNAL(currentValueChanged(QVariant)),
|
||||||
this, SLOT(slotCodeStyleSettingsChanged(QVariant)));
|
this, SLOT(slotCodeStyleSettingsChanged(QVariant)));
|
||||||
connect(d->m_codeStylePreferences, SIGNAL(destroyed()),
|
|
||||||
this, SLOT(onCodeStylePreferencesDestroyed()));
|
|
||||||
setTabSettings(d->m_codeStylePreferences->currentTabSettings());
|
setTabSettings(d->m_codeStylePreferences->currentTabSettings());
|
||||||
slotCodeStyleSettingsChanged(d->m_codeStylePreferences->currentValue());
|
slotCodeStyleSettingsChanged(d->m_codeStylePreferences->currentValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTextEditorWidget::onCodeStylePreferencesDestroyed()
|
|
||||||
{
|
|
||||||
if (sender() != d->m_codeStylePreferences)
|
|
||||||
return;
|
|
||||||
ICodeStylePreferences *prefs = TextEditorSettings::instance()->codeStyle(languageSettingsId());
|
|
||||||
if (prefs == d->m_codeStylePreferences)
|
|
||||||
prefs = 0;
|
|
||||||
// avoid failing disconnects, m_codeStylePreferences has already been reduced to QObject
|
|
||||||
d->m_codeStylePreferences = 0;
|
|
||||||
setCodeStyle(prefs);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseTextEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
|
void BaseTextEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@@ -381,7 +381,6 @@ private slots:
|
|||||||
bool inFindScope(const QTextCursor &cursor);
|
bool inFindScope(const QTextCursor &cursor);
|
||||||
bool inFindScope(int selectionStart, int selectionEnd);
|
bool inFindScope(int selectionStart, int selectionEnd);
|
||||||
void inSnippetMode(bool *active);
|
void inSnippetMode(bool *active);
|
||||||
void onCodeStylePreferencesDestroyed();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Internal::BaseTextEditorWidgetPrivate *d;
|
Internal::BaseTextEditorWidgetPrivate *d;
|
||||||
|
Reference in New Issue
Block a user