Commit 88a4421a authored by Tobias Hunger's avatar Tobias Hunger
Browse files

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: default avatarTobias Hunger <tobias.hunger@digia.com>
parent 063075ec
......@@ -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);
......
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