forked from qt-creator/qt-creator
DocumentManager: Refactor saveModified methods
Introduce methods to save a document/list of documents/all documents, both silently and with a dialog to the DocumentManager. All of these return a bool that signifies whether the save was successful or not. Detailed information on which files failed to load or whether the save was canceled by the user are still available as optional in/out parameters. Change-Id: Id17798302f2a8ba6b85a07c1f0b91f03b20da03f Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
This commit is contained in:
@@ -104,11 +104,11 @@ namespace Core {
|
||||
|
||||
static void readSettings();
|
||||
|
||||
static QList<IDocument *> saveModifiedFilesHelper(const QList<IDocument *> &documents,
|
||||
bool *cancelled, bool silently,
|
||||
const QString &message,
|
||||
const QString &alwaysSaveMessage = QString(),
|
||||
bool *alwaysSave = 0);
|
||||
static bool saveModifiedFilesHelper(const QList<IDocument *> &documents,
|
||||
const QString &message,
|
||||
bool *cancelled, bool silently,
|
||||
const QString &alwaysSaveMessage,
|
||||
bool *alwaysSave, QList<IDocument *> *failedToSave);
|
||||
|
||||
namespace Internal {
|
||||
|
||||
@@ -549,47 +549,10 @@ void DocumentManager::unexpectFileChange(const QString &fileName)
|
||||
updateExpectedState(fixedResolvedName);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Tries to save the files listed in \a documents. The \a cancelled argument is set to true
|
||||
if the user cancelled the dialog. Returns the files that could not be saved. If the files
|
||||
listed in documents have no write permissions, an additional dialog will be
|
||||
displayed to
|
||||
query the user for these permissions.
|
||||
*/
|
||||
QList<IDocument *> DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *cancelled)
|
||||
{
|
||||
return saveModifiedFilesHelper(documents, cancelled, true, QString());
|
||||
}
|
||||
|
||||
/*!
|
||||
Asks the user whether to save the files listed in \a documents. Opens a
|
||||
dialog that displays the \a message, and additional text to ask the users
|
||||
if they want to enable automatic saving
|
||||
of modified files (in this context).
|
||||
|
||||
The \a cancelled argument is set to true if the user cancels the dialog.
|
||||
\a alwaysSave is set to match the selection of the user if files should
|
||||
always automatically be saved. If the files listed in documents have no write
|
||||
permissions, an additional dialog will be displayed to query the user for
|
||||
these permissions.
|
||||
|
||||
Returns the files that have not been saved.
|
||||
*/
|
||||
QList<IDocument *> DocumentManager::saveModifiedDocuments(const QList<IDocument *> &documents,
|
||||
bool *cancelled, const QString &message,
|
||||
const QString &alwaysSaveMessage,
|
||||
bool *alwaysSave)
|
||||
{
|
||||
return saveModifiedFilesHelper(documents, cancelled, false, message, alwaysSaveMessage, alwaysSave);
|
||||
}
|
||||
|
||||
static QList<IDocument *> saveModifiedFilesHelper(const QList<IDocument *> &documents,
|
||||
bool *cancelled,
|
||||
bool silently,
|
||||
const QString &message,
|
||||
const QString &alwaysSaveMessage,
|
||||
bool *alwaysSave)
|
||||
static bool saveModifiedFilesHelper(const QList<IDocument *> &documents,
|
||||
const QString &message, bool *cancelled, bool silently,
|
||||
const QString &alwaysSaveMessage, bool *alwaysSave,
|
||||
QList<IDocument *> *failedToSave)
|
||||
{
|
||||
if (cancelled)
|
||||
(*cancelled) = false;
|
||||
@@ -626,9 +589,10 @@ static QList<IDocument *> saveModifiedFilesHelper(const QList<IDocument *> &docu
|
||||
if (cancelled)
|
||||
(*cancelled) = true;
|
||||
if (alwaysSave)
|
||||
*alwaysSave = dia.alwaysSaveChecked();
|
||||
notSaved = modifiedDocuments;
|
||||
return notSaved;
|
||||
(*alwaysSave) = dia.alwaysSaveChecked();
|
||||
if (failedToSave)
|
||||
(*failedToSave) = modifiedDocuments;
|
||||
return false;
|
||||
}
|
||||
if (alwaysSave)
|
||||
*alwaysSave = dia.alwaysSaveChecked();
|
||||
@@ -648,8 +612,9 @@ static QList<IDocument *> saveModifiedFilesHelper(const QList<IDocument *> &docu
|
||||
if (roDialog.exec() == Core::Internal::ReadOnlyFilesDialog::RO_Cancel) {
|
||||
if (cancelled)
|
||||
(*cancelled) = true;
|
||||
notSaved = modifiedDocuments;
|
||||
return notSaved;
|
||||
if (failedToSave)
|
||||
(*failedToSave) = modifiedDocuments;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
foreach (IDocument *document, documentsToSave) {
|
||||
@@ -660,7 +625,9 @@ static QList<IDocument *> saveModifiedFilesHelper(const QList<IDocument *> &docu
|
||||
}
|
||||
}
|
||||
}
|
||||
return notSaved;
|
||||
if (failedToSave)
|
||||
(*failedToSave) = notSaved;
|
||||
return notSaved.isEmpty();
|
||||
}
|
||||
|
||||
bool DocumentManager::saveDocument(IDocument *document, const QString &fileName, bool *isReadOnly)
|
||||
@@ -780,6 +747,118 @@ QString DocumentManager::getSaveAsFileName(const IDocument *document, const QStr
|
||||
return absoluteFilePath;
|
||||
}
|
||||
|
||||
/*!
|
||||
Silently saves all documents and will return true if all modified documents were saved
|
||||
successfully.
|
||||
|
||||
This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
|
||||
a file is not writeable).
|
||||
|
||||
\a Canceled will be set if the user canceled any of the dialogs that he interacted with.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveAllModifiedDocumentsSilently(bool *canceled,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedDocumentsSilently(modifiedDocuments(), canceled, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Silently saves \a documents and will return true if all of them were saved successfully.
|
||||
|
||||
This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
|
||||
a file is not writeable).
|
||||
|
||||
\a Canceled will be set if the user canceled any of the dialogs that he interacted with.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *canceled,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedFilesHelper(documents, QString(), canceled, true, QString(), 0, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Silently saves a \a document and will return true if it was saved successfully.
|
||||
|
||||
This method will try to avoid showing dialogs to the user, but can do so anyway (e.g. if
|
||||
a file is not writeable).
|
||||
|
||||
\a Canceled will be set if the user canceled any of the dialogs that he interacted with.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveModifiedDocumentSilently(IDocument *document, bool *canceled,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedDocumentsSilently(QList<IDocument *>() << document, canceled, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Presents a dialog with all modified documents to the user and will ask him which of these
|
||||
should be saved.
|
||||
|
||||
This method may show additional dialogs to the user, e.g. if a file is not writeable).
|
||||
|
||||
The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
|
||||
of the dialogs that he interacted with (the method will also return false in this case).
|
||||
The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
|
||||
this checkbox will be written into \a alwaysSave if set.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveAllModifiedDocuments(const QString &message, bool *canceled,
|
||||
const QString &alwaysSaveMessage, bool *alwaysSave,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedDocuments(modifiedDocuments(), message, canceled,
|
||||
alwaysSaveMessage, alwaysSave, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Presents a dialog with \a documents to the user and will ask him which of these should be saved.
|
||||
|
||||
This method may show additional dialogs to the user, e.g. if a file is not writeable).
|
||||
|
||||
The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
|
||||
of the dialogs that he interacted with (the method will also return false in this case).
|
||||
The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
|
||||
this checkbox will be written into \a alwaysSave if set.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveModifiedDocuments(const QList<IDocument *> &documents,
|
||||
const QString &message, bool *canceled,
|
||||
const QString &alwaysSaveMessage, bool *alwaysSave,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedFilesHelper(documents, message, canceled, false,
|
||||
alwaysSaveMessage, alwaysSave, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Presents a dialog with the one \a document to the user and will ask him whether he wants it
|
||||
saved.
|
||||
|
||||
This method may show additional dialogs to the user, e.g. if the file is not writeable).
|
||||
|
||||
The dialog text can be set using \a message. \a Canceled will be set if the user canceled any
|
||||
of the dialogs that he interacted with (the method will also return false in this case).
|
||||
The \a alwaysSaveMessage will show an additional checkbox asking in the dialog. The state of
|
||||
this checkbox will be written into \a alwaysSave if set.
|
||||
\a FailedToClose will contain a list of documents that could not be saved if passed into the
|
||||
method.
|
||||
*/
|
||||
bool DocumentManager::saveModifiedDocument(IDocument *document, const QString &message, bool *canceled,
|
||||
const QString &alwaysSaveMessage, bool *alwaysSave,
|
||||
QList<IDocument *> *failedToClose)
|
||||
{
|
||||
return saveModifiedDocuments(QList<IDocument *>() << document, message, canceled,
|
||||
alwaysSaveMessage, alwaysSave, failedToClose);
|
||||
}
|
||||
|
||||
/*!
|
||||
Asks the user for a set of file names to be opened. The \a filters
|
||||
and \a selectedFilter arguments are interpreted like in
|
||||
|
||||
@@ -99,12 +99,27 @@ public:
|
||||
static QString getSaveAsFileName(const IDocument *document, const QString &filter = QString(),
|
||||
QString *selectedFilter = 0);
|
||||
|
||||
static QList<IDocument *> saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *cancelled = 0);
|
||||
static QList<IDocument *> saveModifiedDocuments(const QList<IDocument *> &documents,
|
||||
bool *cancelled = 0,
|
||||
const QString &message = QString(),
|
||||
static bool saveAllModifiedDocumentsSilently(bool *canceled = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
static bool saveModifiedDocumentsSilently(const QList<IDocument *> &documents, bool *canceled = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
static bool saveModifiedDocumentSilently(IDocument *document, bool *canceled = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
|
||||
static bool saveAllModifiedDocuments(const QString &message = QString(), bool *canceled = 0,
|
||||
const QString &alwaysSaveMessage = QString(),
|
||||
bool *alwaysSave = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
static bool saveModifiedDocuments(const QList<IDocument *> &documents,
|
||||
const QString &message = QString(), bool *canceled = 0,
|
||||
const QString &alwaysSaveMessage = QString(),
|
||||
bool *alwaysSave = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
static bool saveModifiedDocument(IDocument *document,
|
||||
const QString &message = QString(), bool *canceled = 0,
|
||||
const QString &alwaysSaveMessage = QString(),
|
||||
bool *alwaysSave = 0);
|
||||
bool *alwaysSave = 0,
|
||||
QList<IDocument *> *failedToClose = 0);
|
||||
|
||||
static QString fileDialogLastVisitedDirectory();
|
||||
static void setFileDialogLastVisitedDirectory(const QString &);
|
||||
|
||||
@@ -1084,7 +1084,9 @@ bool EditorManager::closeEditors(const QList<IEditor*> &editorsToClose, bool ask
|
||||
//ask whether to save modified files
|
||||
if (askAboutModifiedEditors) {
|
||||
bool cancelled = false;
|
||||
QList<IDocument*> list = DocumentManager::saveModifiedDocuments(acceptedDocuments.toList(), &cancelled);
|
||||
QList<IDocument *> list;
|
||||
DocumentManager::saveModifiedDocuments(acceptedDocuments.toList(), QString(), &cancelled,
|
||||
QString(), 0, &list);
|
||||
if (cancelled)
|
||||
return false;
|
||||
if (!list.isEmpty()) {
|
||||
|
||||
@@ -593,9 +593,7 @@ void ExternalToolRunner::run()
|
||||
if (m_tool->modifiesCurrentDocument()) {
|
||||
if (IDocument *document = EditorManager::currentDocument()) {
|
||||
m_expectedFileName = document->filePath();
|
||||
bool cancelled = false;
|
||||
DocumentManager::saveModifiedDocuments(QList<IDocument *>() << document, &cancelled);
|
||||
if (cancelled) {
|
||||
if (!DocumentManager::saveModifiedDocument(document)) {
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -360,9 +360,7 @@ void MainWindow::closeEvent(QCloseEvent *event)
|
||||
ICore::saveSettings();
|
||||
|
||||
// Save opened files
|
||||
bool cancelled;
|
||||
QList<IDocument*> notSaved = DocumentManager::saveModifiedDocuments(DocumentManager::modifiedDocuments(), &cancelled);
|
||||
if (cancelled || !notSaved.isEmpty()) {
|
||||
if (!DocumentManager::saveAllModifiedDocuments()) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
@@ -925,7 +923,7 @@ bool MainWindow::showOptionsDialog(Id category, Id page, QWidget *parent)
|
||||
|
||||
void MainWindow::saveAll()
|
||||
{
|
||||
DocumentManager::saveModifiedDocumentsSilently(DocumentManager::modifiedDocuments());
|
||||
DocumentManager::saveAllModifiedDocuments();
|
||||
}
|
||||
|
||||
void MainWindow::exit()
|
||||
|
||||
@@ -1945,8 +1945,9 @@ void FakeVimPluginPrivate::handleExCommand(bool *handled, const ExCommand &cmd)
|
||||
} else if (cmd.matches(_("wa"), _("wall"))) {
|
||||
// :w[all]
|
||||
QList<IDocument *> toSave = DocumentManager::modifiedDocuments();
|
||||
QList<IDocument *> failed = DocumentManager::saveModifiedDocumentsSilently(toSave);
|
||||
if (failed.isEmpty())
|
||||
QList<IDocument *> failed;
|
||||
bool success = DocumentManager::saveModifiedDocuments(toSave, QString(), 0, QString(), 0, &failed);
|
||||
if (!success)
|
||||
handler->showMessage(MessageInfo, tr("Saving succeeded"));
|
||||
else
|
||||
handler->showMessage(MessageError, tr("%n files not saved", 0, failed.size()));
|
||||
|
||||
@@ -719,14 +719,6 @@ void GitPlugin::submitEditorMerge(const QStringList &unmerged)
|
||||
m_gitClient->merge(m_submitRepository, unmerged);
|
||||
}
|
||||
|
||||
static bool ensureAllDocumentsSaved()
|
||||
{
|
||||
bool cancelled;
|
||||
Core::DocumentManager::saveModifiedDocuments(Core::DocumentManager::modifiedDocuments(),
|
||||
&cancelled);
|
||||
return !cancelled;
|
||||
}
|
||||
|
||||
void GitPlugin::diffCurrentFile()
|
||||
{
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
@@ -788,7 +780,7 @@ void GitPlugin::reflogRepository()
|
||||
|
||||
void GitPlugin::undoFileChanges(bool revertStaging)
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasFile(), return);
|
||||
@@ -798,7 +790,7 @@ void GitPlugin::undoFileChanges(bool revertStaging)
|
||||
|
||||
void GitPlugin::undoUnstagedFileChanges()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
undoFileChanges(false);
|
||||
}
|
||||
@@ -832,7 +824,7 @@ protected:
|
||||
|
||||
void GitPlugin::resetRepository()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return);
|
||||
@@ -847,7 +839,7 @@ void GitPlugin::resetRepository()
|
||||
|
||||
void GitPlugin::startRebase()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return);
|
||||
@@ -889,7 +881,7 @@ void GitPlugin::startChangeRelatedAction()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
|
||||
switch (dialog.command()) {
|
||||
@@ -1150,7 +1142,7 @@ void GitPlugin::fetch()
|
||||
|
||||
void GitPlugin::pull()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return);
|
||||
@@ -1187,7 +1179,7 @@ void GitPlugin::startMergeTool()
|
||||
|
||||
void GitPlugin::continueOrAbortCommand()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
QTC_ASSERT(state.hasTopLevel(), return);
|
||||
@@ -1286,11 +1278,7 @@ void GitPlugin::updateSubmodules()
|
||||
static bool ensureFileSaved(const QString &fileName)
|
||||
{
|
||||
Core::IDocument *document = Core::EditorManager::documentModel()->documentForFilePath(fileName);
|
||||
if (!document || !document->isModified())
|
||||
return true;
|
||||
bool canceled;
|
||||
Core::DocumentManager::saveModifiedDocuments(QList<Core::IDocument *>() << document, &canceled);
|
||||
return !canceled;
|
||||
return Core::DocumentManager::saveModifiedDocument(document);
|
||||
}
|
||||
|
||||
void GitPlugin::applyCurrentFilePatch()
|
||||
@@ -1342,7 +1330,7 @@ void GitPlugin::applyPatch(const QString &workingDirectory, QString file)
|
||||
|
||||
void GitPlugin::stash()
|
||||
{
|
||||
if (!ensureAllDocumentsSaved())
|
||||
if (!Core::DocumentManager::saveAllModifiedDocuments())
|
||||
return;
|
||||
// Simple stash without prompt, reset repo.
|
||||
const VcsBase::VcsBasePluginState state = currentState();
|
||||
|
||||
@@ -1075,15 +1075,7 @@ void ProjectExplorerPlugin::unloadProject()
|
||||
if (!document || document->filePath().isEmpty()) //nothing to save?
|
||||
return;
|
||||
|
||||
QList<IDocument*> documentsToSave;
|
||||
documentsToSave << document;
|
||||
bool success = false;
|
||||
if (document->isFileReadOnly())
|
||||
success = DocumentManager::saveModifiedDocuments(documentsToSave).isEmpty();
|
||||
else
|
||||
success = DocumentManager::saveModifiedDocumentsSilently(documentsToSave).isEmpty();
|
||||
|
||||
if (!success)
|
||||
if (!DocumentManager::saveModifiedDocumentSilently(document))
|
||||
return;
|
||||
|
||||
addToRecentProjects(document->filePath(), d->m_currentProject->displayName());
|
||||
@@ -1967,13 +1959,13 @@ bool ProjectExplorerPlugin::saveModifiedFiles()
|
||||
} else {
|
||||
bool cancelled = false;
|
||||
bool alwaysSave = false;
|
||||
DocumentManager::saveModifiedDocuments(documentsToSave, &cancelled, QString(),
|
||||
tr("Always save files before build"), &alwaysSave);
|
||||
|
||||
if (cancelled)
|
||||
return false;
|
||||
if (alwaysSave)
|
||||
d->m_projectExplorerSettings.saveBeforeBuild = true;
|
||||
if (!DocumentManager::saveModifiedDocuments(documentsToSave, QString(), &cancelled,
|
||||
tr("Always save files before build"), &alwaysSave)) {
|
||||
if (cancelled)
|
||||
return false;
|
||||
if (alwaysSave)
|
||||
d->m_projectExplorerSettings.saveBeforeBuild = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -1065,11 +1065,11 @@ bool QmakePriFileNode::saveModifiedEditors()
|
||||
if (!document || !document->isModified())
|
||||
return true;
|
||||
|
||||
bool cancelled;
|
||||
Core::DocumentManager::saveModifiedDocuments(QList<Core::IDocument *>() << document, &cancelled,
|
||||
tr("There are unsaved changes for project file %1.").arg(m_projectFilePath));
|
||||
if (cancelled)
|
||||
if (!Core::DocumentManager::saveDocument(document,
|
||||
tr("There are unsaved changes for project file %1.")
|
||||
.arg(m_projectFilePath))) {
|
||||
return false;
|
||||
}
|
||||
// force instant reload of ourselves
|
||||
QtSupport::ProFileCacheManager::instance()->discardFile(m_projectFilePath);
|
||||
m_project->qmakeProjectManager()->notifyChanged(m_projectFilePath);
|
||||
|
||||
Reference in New Issue
Block a user