forked from qt-creator/qt-creator
EditorManager: Warn before opening big text files
...since these might lead to out of memory situations and thus to crashes. The warning and the file size limited is configurable in Environment > General. Task-number: QTCREATORBUG-14390 Change-Id: I868ceca0bee5551ed55f0df990ed334a8b539a7d Reviewed-by: David Schulz <david.schulz@theqtcompany.com> Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
This commit is contained in:
@@ -65,6 +65,7 @@
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/checkablemessagebox.h>
|
||||
#include <utils/executeondestruction.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
@@ -107,6 +108,8 @@ 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 warnBeforeOpeningBigTextFilesKey[] = "EditorManager/WarnBeforeOpeningBigTextFiles";
|
||||
static const char bigTextFileSizeLimitKey[] = "EditorManager/BigTextFileSizeLimitInMB";
|
||||
|
||||
static const char scratchBufferKey[] = "_q_emScratchBuffer";
|
||||
|
||||
@@ -280,7 +283,9 @@ EditorManagerPrivate::EditorManagerPrivate(QObject *parent) :
|
||||
m_coreListener(0),
|
||||
m_reloadSetting(IDocument::AlwaysAsk),
|
||||
m_autoSaveEnabled(true),
|
||||
m_autoSaveInterval(5)
|
||||
m_autoSaveInterval(5),
|
||||
m_warnBeforeOpeningBigFilesEnabled(true),
|
||||
m_bigFileSizeLimitInMB(5)
|
||||
{
|
||||
d = this;
|
||||
}
|
||||
@@ -544,6 +549,47 @@ EditorArea *EditorManagerPrivate::mainEditorArea()
|
||||
return d->m_editorAreas.at(0);
|
||||
}
|
||||
|
||||
bool EditorManagerPrivate::skipOpeningBigTextFile(const QString &filePath)
|
||||
{
|
||||
if (!d->m_warnBeforeOpeningBigFilesEnabled)
|
||||
return false;
|
||||
|
||||
const QFileInfo fileInfo(filePath);
|
||||
if (!fileInfo.exists(filePath))
|
||||
return false;
|
||||
|
||||
Utils::MimeDatabase mdb;
|
||||
Utils::MimeType mimeType = mdb.mimeTypeForFile(filePath);
|
||||
if (!mimeType.inherits(QLatin1String("text/plain")))
|
||||
return false;
|
||||
|
||||
const double fileSizeInMB = fileInfo.size() / 1000.0 / 1000.0;
|
||||
if (fileSizeInMB > d->m_bigFileSizeLimitInMB) {
|
||||
const QString title = EditorManager::tr("Continue Opening Huge Text File?");
|
||||
const QString text = EditorManager::tr(
|
||||
"The text file \"%1\" has the size %2MB and might take more memory to open"
|
||||
" and process than available.\n"
|
||||
"\n"
|
||||
"Continue?")
|
||||
.arg(fileInfo.fileName())
|
||||
.arg(fileSizeInMB, 0, 'f', 2);
|
||||
|
||||
CheckableMessageBox messageBox(ICore::mainWindow());
|
||||
messageBox.setWindowTitle(title);
|
||||
messageBox.setText(text);
|
||||
messageBox.setStandardButtons(QDialogButtonBox::Yes|QDialogButtonBox::No);
|
||||
messageBox.setDefaultButton(QDialogButtonBox::No);
|
||||
messageBox.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question));
|
||||
messageBox.setCheckBoxVisible(true);
|
||||
messageBox.setCheckBoxText(CheckableMessageBox::msgDoNotAskAgain());
|
||||
messageBox.exec();
|
||||
d->setWarnBeforeOpeningBigFilesEnabled(!messageBox.isChecked());
|
||||
return messageBox.clickedStandardButton() != QDialogButtonBox::Yes;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
IEditor *EditorManagerPrivate::openEditor(EditorView *view, const QString &fileName, Id editorId,
|
||||
EditorManager::OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
@@ -960,6 +1006,11 @@ void EditorManagerPrivate::saveSettings()
|
||||
settings->setValue(QLatin1String(autoSaveEnabledKey), d->m_autoSaveEnabled);
|
||||
settings->setValue(QLatin1String(autoSaveIntervalKey), d->m_autoSaveInterval);
|
||||
settings->endTransaction();
|
||||
|
||||
QSettings *qsettings = ICore::settings();
|
||||
qsettings->setValue(QLatin1String(warnBeforeOpeningBigTextFilesKey),
|
||||
d->m_warnBeforeOpeningBigFilesEnabled);
|
||||
qsettings->setValue(QLatin1String(bigTextFileSizeLimitKey), d->m_bigFileSizeLimitInMB);
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::readSettings()
|
||||
@@ -973,6 +1024,12 @@ void EditorManagerPrivate::readSettings()
|
||||
qs->remove(QLatin1String(documentStatesKey));
|
||||
}
|
||||
|
||||
if (qs->contains(QLatin1String(warnBeforeOpeningBigTextFilesKey))) {
|
||||
d->m_warnBeforeOpeningBigFilesEnabled
|
||||
= qs->value(QLatin1String(warnBeforeOpeningBigTextFilesKey)).toBool();
|
||||
d->m_bigFileSizeLimitInMB = qs->value(QLatin1String(bigTextFileSizeLimitKey)).toInt();
|
||||
}
|
||||
|
||||
SettingsDatabase *settings = ICore::settingsDatabase();
|
||||
if (settings->contains(QLatin1String(documentStatesKey)))
|
||||
d->m_editorStates = settings->value(QLatin1String(documentStatesKey))
|
||||
@@ -1010,6 +1067,26 @@ int EditorManagerPrivate::autoSaveInterval()
|
||||
return d->m_autoSaveInterval;
|
||||
}
|
||||
|
||||
bool EditorManagerPrivate::warnBeforeOpeningBigFilesEnabled()
|
||||
{
|
||||
return d->m_warnBeforeOpeningBigFilesEnabled;
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::setWarnBeforeOpeningBigFilesEnabled(bool enabled)
|
||||
{
|
||||
d->m_warnBeforeOpeningBigFilesEnabled = enabled;
|
||||
}
|
||||
|
||||
int EditorManagerPrivate::bigFileSizeLimit()
|
||||
{
|
||||
return d->m_bigFileSizeLimitInMB;
|
||||
}
|
||||
|
||||
void EditorManagerPrivate::setBigFileSizeLimit(int limitInMB)
|
||||
{
|
||||
d->m_bigFileSizeLimitInMB = limitInMB;
|
||||
}
|
||||
|
||||
EditorManager::EditorFactoryList EditorManagerPrivate::findFactories(Id editorId, const QString &fileName)
|
||||
{
|
||||
if (debugEditorManager)
|
||||
@@ -2451,6 +2528,9 @@ EditorManager::ExternalEditorList
|
||||
IEditor *EditorManager::openEditor(const QString &fileName, Id editorId,
|
||||
OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
if (EditorManagerPrivate::skipOpeningBigTextFile(fileName))
|
||||
return 0;
|
||||
|
||||
if (flags & EditorManager::OpenInOtherSplit)
|
||||
EditorManager::gotoOtherSplit();
|
||||
|
||||
@@ -2461,6 +2541,9 @@ IEditor *EditorManager::openEditor(const QString &fileName, Id editorId,
|
||||
IEditor *EditorManager::openEditorAt(const QString &fileName, int line, int column,
|
||||
Id editorId, OpenEditorFlags flags, bool *newEditor)
|
||||
{
|
||||
if (EditorManagerPrivate::skipOpeningBigTextFile(fileName))
|
||||
return 0;
|
||||
|
||||
if (flags & EditorManager::OpenInOtherSplit)
|
||||
EditorManager::gotoOtherSplit();
|
||||
|
||||
|
@@ -111,6 +111,10 @@ public:
|
||||
static bool autoSaveEnabled();
|
||||
static void setAutoSaveInterval(int interval);
|
||||
static int autoSaveInterval();
|
||||
static void setWarnBeforeOpeningBigFilesEnabled(bool enabled);
|
||||
static bool warnBeforeOpeningBigFilesEnabled();
|
||||
static void setBigFileSizeLimit(int limitInMB);
|
||||
static int bigFileSizeLimit();
|
||||
|
||||
static void splitNewWindow(Internal::EditorView *view);
|
||||
static void closeView(Internal::EditorView *view);
|
||||
@@ -188,6 +192,7 @@ private:
|
||||
static void setupSaveActions(IDocument *document, QAction *saveAction,
|
||||
QAction *saveAsAction, QAction *revertToSavedAction);
|
||||
static void updateWindowTitle();
|
||||
static bool skipOpeningBigTextFile(const QString &filePath);
|
||||
|
||||
private:
|
||||
explicit EditorManagerPrivate(QObject *parent);
|
||||
@@ -251,6 +256,9 @@ private:
|
||||
bool m_autoSaveEnabled;
|
||||
int m_autoSaveInterval;
|
||||
|
||||
bool m_warnBeforeOpeningBigFilesEnabled;
|
||||
int m_bigFileSizeLimitInMB;
|
||||
|
||||
QString m_placeholderText;
|
||||
};
|
||||
|
||||
|
@@ -144,8 +144,10 @@ QWidget *GeneralSettings::widget()
|
||||
m_page->patchChooser->setPath(PatchTool::patchCommand());
|
||||
m_page->autoSaveCheckBox->setChecked(EditorManagerPrivate::autoSaveEnabled());
|
||||
m_page->autoSaveInterval->setValue(EditorManagerPrivate::autoSaveInterval());
|
||||
m_page->resetWarningsButton->setEnabled(InfoBar::anyGloballySuppressed()
|
||||
|| CheckableMessageBox::hasSuppressedQuestions(ICore::settings()));
|
||||
m_page->warnBeforeOpeningBigFiles->setChecked(
|
||||
EditorManagerPrivate::warnBeforeOpeningBigFilesEnabled());
|
||||
m_page->bigFilesLimitSpinBox->setValue(EditorManagerPrivate::bigFileSizeLimit());
|
||||
m_page->resetWarningsButton->setEnabled(canResetWarnings());
|
||||
|
||||
connect(m_page->resetColorButton, SIGNAL(clicked()),
|
||||
this, SLOT(resetInterfaceColor()));
|
||||
@@ -188,6 +190,9 @@ void GeneralSettings::apply()
|
||||
PatchTool::setPatchCommand(m_page->patchChooser->path());
|
||||
EditorManagerPrivate::setAutoSaveEnabled(m_page->autoSaveCheckBox->isChecked());
|
||||
EditorManagerPrivate::setAutoSaveInterval(m_page->autoSaveInterval->value());
|
||||
EditorManagerPrivate::setWarnBeforeOpeningBigFilesEnabled(
|
||||
m_page->warnBeforeOpeningBigFiles->isChecked());
|
||||
EditorManagerPrivate::setBigFileSizeLimit(m_page->bigFilesLimitSpinBox->value());
|
||||
m_page->themeWidget->apply();
|
||||
}
|
||||
|
||||
@@ -207,6 +212,7 @@ void GeneralSettings::resetWarnings()
|
||||
{
|
||||
InfoBar::clearGloballySuppressed();
|
||||
CheckableMessageBox::resetAllDoNotAskAgainQuestions(ICore::settings());
|
||||
m_page->warnBeforeOpeningBigFiles->setChecked(true);
|
||||
m_page->resetWarningsButton->setEnabled(false);
|
||||
}
|
||||
|
||||
@@ -230,6 +236,13 @@ void GeneralSettings::updatePath()
|
||||
m_page->patchChooser->setEnvironment(env);
|
||||
}
|
||||
|
||||
bool GeneralSettings::canResetWarnings() const
|
||||
{
|
||||
return InfoBar::anyGloballySuppressed()
|
||||
|| CheckableMessageBox::hasSuppressedQuestions(ICore::settings())
|
||||
|| !EditorManagerPrivate::warnBeforeOpeningBigFilesEnabled();
|
||||
}
|
||||
|
||||
void GeneralSettings::variableHelpDialogCreator(const QString &helpText)
|
||||
{
|
||||
if (m_dialog) {
|
||||
|
@@ -64,6 +64,7 @@ private slots:
|
||||
void updatePath();
|
||||
|
||||
private:
|
||||
bool canResetWarnings() const;
|
||||
void variableHelpDialogCreator(const QString &helpText);
|
||||
void fillLanguageBox() const;
|
||||
QString language() const;
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>527</width>
|
||||
<height>359</height>
|
||||
<height>366</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
@@ -310,6 +310,49 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="4">
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -362,12 +405,28 @@
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>161</x>
|
||||
<y>262</y>
|
||||
<x>181</x>
|
||||
<y>310</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>342</x>
|
||||
<y>263</y>
|
||||
<x>340</x>
|
||||
<y>311</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>warnBeforeOpeningBigFiles</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>bigFilesLimitSpinBox</receiver>
|
||||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>124</x>
|
||||
<y>330</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>305</x>
|
||||
<y>332</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
Reference in New Issue
Block a user