TextEditor: Optionally auto-save refactored files

This is particularly helpful with clangd, which considers only the on-
disk state of header files when parsing dependent sources.

Fixes: QTCREATORBUG-25924
Change-Id: I41d313f8a203a576d3ed5fbe75bbe918334486d4
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Christian Kandeler
2021-08-17 17:59:51 +02:00
parent 3d920bc000
commit 35fcd96b85
6 changed files with 283 additions and 241 deletions

View File

@@ -116,6 +116,7 @@ static const char documentStatesKey[] = "EditorManager/DocumentStates";
static const char reloadBehaviorKey[] = "EditorManager/ReloadBehavior";
static const char autoSaveEnabledKey[] = "EditorManager/AutoSaveEnabled";
static const char autoSaveIntervalKey[] = "EditorManager/AutoSaveInterval";
static const char autoSaveAfterRefactoringKey[] = "EditorManager/AutoSaveAfterRefactoring";
static const char autoSuspendEnabledKey[] = "EditorManager/AutoSuspendEnabled";
static const char autoSuspendMinDocumentCountKey[] = "EditorManager/AutoSuspendMinDocuments";
static const char warnBeforeOpeningBigTextFilesKey[] = "EditorManager/WarnBeforeOpeningBigTextFiles";
@@ -1232,6 +1233,9 @@ void EditorManagerPrivate::saveSettings()
qsettings->setValueWithDefault(autoSaveIntervalKey,
d->m_settings.autoSaveInterval,
def.autoSaveInterval);
qsettings->setValueWithDefault(autoSaveAfterRefactoringKey,
d->m_settings.autoSaveAfterRefactoring,
def.autoSaveAfterRefactoring);
qsettings->setValueWithDefault(autoSuspendEnabledKey,
d->m_settings.autoSuspendEnabled,
def.autoSuspendEnabled);
@@ -1303,6 +1307,8 @@ void EditorManagerPrivate::readSettings()
d->m_settings.autoSaveEnabled = qs->value(autoSaveEnabledKey, def.autoSaveEnabled).toBool();
d->m_settings.autoSaveInterval = qs->value(autoSaveIntervalKey, def.autoSaveInterval).toInt();
d->m_settings.autoSaveAfterRefactoring = qs->value(autoSaveAfterRefactoringKey,
def.autoSaveAfterRefactoring).toBool();
d->m_settings.autoSuspendEnabled = qs->value(autoSuspendEnabledKey, def.autoSuspendEnabled)
.toBool();
@@ -1334,6 +1340,16 @@ int EditorManagerPrivate::autoSaveInterval()
return d->m_settings.autoSaveInterval;
}
void EditorManagerPrivate::setAutoSaveAfterRefactoring(bool enabled)
{
d->m_settings.autoSaveAfterRefactoring = enabled;
}
bool EditorManagerPrivate::autoSaveAfterRefactoring()
{
return d->m_settings.autoSaveAfterRefactoring;
}
void EditorManagerPrivate::setAutoSuspendEnabled(bool enabled)
{
d->m_settings.autoSuspendEnabled = enabled;
@@ -3141,6 +3157,11 @@ bool EditorManager::isAutoSaveFile(const QString &filePath)
return filePath.endsWith(".autosave");
}
bool EditorManager::autoSaveAfterRefactoring()
{
return EditorManagerPrivate::autoSaveAfterRefactoring();
}
/*!
Opens the document specified by \a filePath in the external editor specified
by \a editorId.

View File

@@ -154,6 +154,8 @@ public:
static bool isAutoSaveFile(const QString &fileName);
static bool autoSaveAfterRefactoring();
static QTextCodec *defaultTextCodec();
static Utils::TextFileFormat::LineTerminationMode defaultLineEnding();

View File

@@ -116,6 +116,8 @@ public:
static bool autoSaveEnabled();
static void setAutoSaveInterval(int interval);
static int autoSaveInterval();
static void setAutoSaveAfterRefactoring(bool enabled);
static bool autoSaveAfterRefactoring();
static void setAutoSuspendEnabled(bool enabled);
static bool autoSuspendEnabled();
static void setAutoSuspendMinDocumentCount(int count);
@@ -282,6 +284,7 @@ private:
bool autoSuspendEnabled = true;
int autoSuspendMinDocumentCount = 30;
bool autoSaveAfterRefactoring = true;
bool warnBeforeOpeningBigFilesEnabled = true;
int bigFileSizeLimitInMB = 5;
int maxRecentFiles = 8;

View File

@@ -126,6 +126,10 @@ public:
"a crash or power failure, it asks whether to "
"recover the auto-saved content.")
.arg(Constants::IDE_DISPLAY_NAME));
m_ui.autoSaveRefactoringCheckBox->setChecked(EditorManager::autoSaveAfterRefactoring());
m_ui.autoSaveRefactoringCheckBox->setToolTip(tr("Automatically saves all open files "
"affected by a refactoring operation,\n provided they were unmodified before the "
"refactoring."));
m_ui.autoSaveInterval->setValue(EditorManagerPrivate::autoSaveInterval());
m_ui.autoSuspendCheckBox->setChecked(EditorManagerPrivate::autoSuspendEnabled());
m_ui.autoSuspendMinDocumentCount->setValue(EditorManagerPrivate::autoSuspendMinDocumentCount());
@@ -268,6 +272,8 @@ void SystemSettingsWidget::apply()
PatchTool::setPatchCommand(m_ui.patchChooser->filePath());
EditorManagerPrivate::setAutoSaveEnabled(m_ui.autoSaveCheckBox->isChecked());
EditorManagerPrivate::setAutoSaveInterval(m_ui.autoSaveInterval->value());
EditorManagerPrivate::setAutoSaveAfterRefactoring(
m_ui.autoSaveRefactoringCheckBox->isChecked());
EditorManagerPrivate::setAutoSuspendEnabled(m_ui.autoSuspendCheckBox->isChecked());
EditorManagerPrivate::setAutoSuspendMinDocumentCount(m_ui.autoSuspendMinDocumentCount->value());
EditorManagerPrivate::setWarnBeforeOpeningBigFilesEnabled(

View File

@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>599</width>
<width>628</width>
<height>545</height>
</rect>
</property>
@@ -17,26 +17,10 @@
<string>System</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLabel" name="fileSystemCaseSensitivityLabel">
<property name="toolTip">
<string>Influences how file names are matched to decide if they are the same.</string>
</property>
<item row="1" column="0">
<widget class="QLabel" name="terminalLabel">
<property name="text">
<string>File system case sensitivity:</string>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="autoSuspendCheckBox">
<property name="toolTip">
<string>Automatically free resources of old documents that are not visible and not modified. They stay visible in the list of open documents.</string>
</property>
<property name="text">
<string>Auto-suspend unmodified files</string>
</property>
<property name="checked">
<bool>true</bool>
<string>Terminal:</string>
</property>
</widget>
</item>
@@ -74,14 +58,17 @@
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="terminalLabel">
<item row="4" column="0">
<widget class="QLabel" name="fileSystemCaseSensitivityLabel">
<property name="toolTip">
<string>Influences how file names are matched to decide if they are the same.</string>
</property>
<property name="text">
<string>Terminal:</string>
<string>File system case sensitivity:</string>
</property>
</widget>
</item>
<item row="7" column="1" colspan="2">
<item row="8" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="autoSuspendLabel">
@@ -121,212 +108,6 @@
</item>
</layout>
</item>
<item row="9" column="0" colspan="2">
<widget class="QLabel" name="maxRecentFilesLabel">
<property name="text">
<string>Maximum number of entries in &quot;Recent Files&quot;:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="autoSaveCheckBox">
<property name="text">
<string>Auto-save modified files</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="modifiedLabel">
<property name="text">
<string>When files are externally modified:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="externalFileBrowserLabel">
<property name="text">
<string>External file browser:</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="Utils::PathChooser" name="patchChooser" native="true"/>
</item>
<item row="9" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QSpinBox" name="maxRecentFilesSpinBox"/>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="6" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="autoSaveIntervalLabel">
<property name="text">
<string>Interval:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="autoSaveInterval">
<property name="suffix">
<string extracomment="unit for minutes">min</string>
</property>
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="8" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="warnBeforeOpeningBigFiles">
<property name="text">
<string>Warn before opening text files greater than</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="bigFilesLimitSpinBox">
<property name="suffix">
<string>MB</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="5" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QComboBox" name="reloadBehavior">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Always Ask</string>
</property>
</item>
<item>
<property name="text">
<string>Reload All Unchanged Editors</string>
</property>
</item>
<item>
<property name="text">
<string>Ignore Modifications</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="3" column="0">
<widget class="QLabel" name="patchCommandLabel">
<property name="text">
<string>Patch command:</string>
</property>
</widget>
</item>
<item row="10" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QCheckBox" name="askBeforeExitCheckBox">
<property name="text">
<string>Ask for confirmation before exiting</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="12" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QPushButton" name="clearCrashReportsButton">
<property name="text">
<string>Clear Local Crash Reports</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="crashReportsSizeText">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="1" colspan="2">
<widget class="QWidget" name="externalFileBrowserWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_9">
@@ -365,6 +146,46 @@
</layout>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QLabel" name="maxRecentFilesLabel">
<property name="text">
<string>Maximum number of entries in &quot;Recent Files&quot;:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="autoSuspendCheckBox">
<property name="toolTip">
<string>Automatically free resources of old documents that are not visible and not modified. They stay visible in the list of open documents.</string>
</property>
<property name="text">
<string>Auto-suspend unmodified files</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="10" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QSpinBox" name="maxRecentFilesSpinBox"/>
</item>
<item>
<spacer name="horizontalSpacer_8">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QLabel" name="environmentLabel">
<property name="text">
@@ -372,6 +193,90 @@
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="modifiedLabel">
<property name="text">
<string>When files are externally modified:</string>
</property>
</widget>
</item>
<item row="12" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item>
<widget class="QCheckBox" name="enableCrashReportingCheckBox">
<property name="toolTip">
<string>Allow crashes to be automatically reported. Collected reports are used for the sole purpose of fixing bugs.</string>
</property>
<property name="text">
<string>Enable crash reporting</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="helpCrashReportingButton">
<property name="text">
<string>?</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="9" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QCheckBox" name="warnBeforeOpeningBigFiles">
<property name="text">
<string>Warn before opening text files greater than</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="bigFilesLimitSpinBox">
<property name="suffix">
<string>MB</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>500</number>
</property>
<property name="value">
<number>5</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="1" column="1" colspan="2">
<widget class="QWidget" name="terminalWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_8">
@@ -429,6 +334,16 @@
</layout>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="patchCommandLabel">
<property name="text">
<string>Patch command:</string>
</property>
</widget>
</item>
<item row="3" column="1" colspan="2">
<widget class="Utils::PathChooser" name="patchChooser" native="true"/>
</item>
<item row="0" column="1" colspan="2">
<widget class="QWidget" name="environmentWidget" native="true">
<layout class="QHBoxLayout" name="environmentLayout">
@@ -473,27 +388,43 @@
</layout>
</widget>
</item>
<item row="11" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_10">
<item row="11" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_7">
<item>
<widget class="QCheckBox" name="enableCrashReportingCheckBox">
<property name="toolTip">
<string>Allow crashes to be automatically reported. Collected reports are used for the sole purpose of fixing bugs.</string>
</property>
<widget class="QCheckBox" name="askBeforeExitCheckBox">
<property name="text">
<string>Enable crash reporting</string>
<string>Ask for confirmation before exiting</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QToolButton" name="helpCrashReportingButton">
<property name="text">
<string>?</string>
<widget class="QComboBox" name="reloadBehavior">
<property name="currentIndex">
<number>0</number>
</property>
<item>
<property name="text">
<string>Always Ask</string>
</property>
</item>
<item>
<property name="text">
<string>Reload All Unchanged Editors</string>
</property>
</item>
<item>
<property name="text">
<string>Ignore Modifications</string>
</property>
</item>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@@ -507,6 +438,82 @@
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="externalFileBrowserLabel">
<property name="text">
<string>External file browser:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QCheckBox" name="autoSaveCheckBox">
<property name="text">
<string>Auto-save modified files</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="13" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
<widget class="QPushButton" name="clearCrashReportsButton">
<property name="text">
<string>Clear Local Crash Reports</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="crashReportsSizeText">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="autoSaveIntervalLabel">
<property name="text">
<string>Interval:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="autoSaveInterval">
<property name="suffix">
<string extracomment="unit for minutes">min</string>
</property>
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="7" column="0">
<widget class="QCheckBox" name="autoSaveRefactoringCheckBox">
<property name="text">
<string>Auto-save files after refactoring</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>

View File

@@ -342,6 +342,7 @@ bool RefactoringFile::apply()
m_editorCursorPosition = -1;
}
const bool withUnmodifiedEditor = m_editor && !m_editor->textDocument()->isModified();
bool result = true;
// apply changes, if any
@@ -390,6 +391,8 @@ bool RefactoringFile::apply()
}
fileChanged();
if (withUnmodifiedEditor && EditorManager::autoSaveAfterRefactoring())
m_editor->textDocument()->save(nullptr, m_filePath, false);
}
}