forked from qt-creator/qt-creator
improve file change notification suppression in saveFile()
for one, entirely stop monitoring the own IFile. second, expect changes on the filename - in case other IFiles use it as well. these two ensure that nothing weird happens, especially if we show a dialog and thus enter an event loop.
This commit is contained in:
@@ -279,24 +279,6 @@ void FileManager::addFileInfo(const QString &fileName, IFile *file, bool isLink)
|
|||||||
d->m_filesWithWatch[file].append(fileName); // inserts a new QStringList if not already there
|
d->m_filesWithWatch[file].append(fileName); // inserts a new QStringList if not already there
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Updates the time stamp and permission information of the files
|
|
||||||
registered for this IFile (in m_filesWithWatch; can be the IFile's file + final link target) */
|
|
||||||
void FileManager::updateFileInfo(IFile *file)
|
|
||||||
{
|
|
||||||
foreach (const QString &fileName, d->m_filesWithWatch.value(file)) {
|
|
||||||
// If the filename is empty there's nothing to do
|
|
||||||
if (fileName.isEmpty())
|
|
||||||
continue;
|
|
||||||
const QFileInfo fi(fileName);
|
|
||||||
Internal::FileStateItem item;
|
|
||||||
item.modified = fi.lastModified();
|
|
||||||
item.permissions = fi.permissions();
|
|
||||||
QTC_ASSERT(d->m_states.contains(fileName), continue);
|
|
||||||
QTC_ASSERT(d->m_states.value(fileName).lastUpdatedState.contains(file), continue);
|
|
||||||
d->m_states[fileName].lastUpdatedState.insert(file, item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dumps the state of the file manager's map
|
/// Dumps the state of the file manager's map
|
||||||
/// For debugging purposes
|
/// For debugging purposes
|
||||||
void FileManager::dump()
|
void FileManager::dump()
|
||||||
@@ -410,18 +392,21 @@ void FileManager::fileDestroyed(QObject *obj)
|
|||||||
|
|
||||||
Removes a IFile object from the collection.
|
Removes a IFile object from the collection.
|
||||||
|
|
||||||
Returns true if the file specified by \a file has been part of the file list.
|
Returns true if the file specified by \a file had the addWatcher argument to addFile() set.
|
||||||
*/
|
*/
|
||||||
void FileManager::removeFile(IFile *file)
|
bool FileManager::removeFile(IFile *file)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(file, return);
|
QTC_ASSERT(file, return false);
|
||||||
|
|
||||||
|
bool addWatcher = false;
|
||||||
// Special casing unwatched files
|
// Special casing unwatched files
|
||||||
if (!d->m_filesWithoutWatch.removeOne(file)) {
|
if (!d->m_filesWithoutWatch.removeOne(file)) {
|
||||||
|
addWatcher = true;
|
||||||
removeFileInfo(file);
|
removeFileInfo(file);
|
||||||
disconnect(file, SIGNAL(changed()), this, SLOT(checkForNewFileName()));
|
disconnect(file, SIGNAL(changed()), this, SLOT(checkForNewFileName()));
|
||||||
}
|
}
|
||||||
disconnect(file, SIGNAL(destroyed(QObject *)), this, SLOT(fileDestroyed(QObject *)));
|
disconnect(file, SIGNAL(destroyed(QObject *)), this, SLOT(fileDestroyed(QObject *)));
|
||||||
|
return addWatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Slot reacting on IFile::changed. We need to check if the signal was sent
|
/* Slot reacting on IFile::changed. We need to check if the signal was sent
|
||||||
@@ -633,7 +618,11 @@ QList<IFile *> FileManager::saveModifiedFiles(const QList<IFile *> &files,
|
|||||||
|
|
||||||
bool FileManager::saveFile(IFile *file, const QString &fileName, bool *isReadOnly)
|
bool FileManager::saveFile(IFile *file, const QString &fileName, bool *isReadOnly)
|
||||||
{
|
{
|
||||||
|
bool ret = true;
|
||||||
QString effName = fileName.isEmpty() ? file->fileName() : fileName;
|
QString effName = fileName.isEmpty() ? file->fileName() : fileName;
|
||||||
|
expectFileChange(effName); // This only matters to other IFiles which refer to this file
|
||||||
|
bool addWatcher = removeFile(file); // So that our own IFile gets no notification at all
|
||||||
|
|
||||||
QString errorString;
|
QString errorString;
|
||||||
if (!file->save(&errorString, fileName)) {
|
if (!file->save(&errorString, fileName)) {
|
||||||
if (isReadOnly) {
|
if (isReadOnly) {
|
||||||
@@ -642,28 +631,18 @@ bool FileManager::saveFile(IFile *file, const QString &fileName, bool *isReadOnl
|
|||||||
if (ofi.exists() && !ofi.open(QIODevice::ReadWrite)
|
if (ofi.exists() && !ofi.open(QIODevice::ReadWrite)
|
||||||
&& ofi.error() == QFile::PermissionsError) {
|
&& ofi.error() == QFile::PermissionsError) {
|
||||||
*isReadOnly = true;
|
*isReadOnly = true;
|
||||||
return false;
|
goto out;
|
||||||
}
|
}
|
||||||
*isReadOnly = false;
|
*isReadOnly = false;
|
||||||
}
|
}
|
||||||
QMessageBox::critical(d->m_mainWindow, tr("File Error"), errorString);
|
QMessageBox::critical(d->m_mainWindow, tr("File Error"), errorString);
|
||||||
return false;
|
out:
|
||||||
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We are updating the lastUpdated time to the current modification time
|
addFile(file, addWatcher);
|
||||||
// in changedFile we'll compare the modification time with the last updated
|
unexpectFileChange(effName);
|
||||||
// time, and if they are the same, then we don't deliver that notification
|
return ret;
|
||||||
// to corresponding IFile
|
|
||||||
//
|
|
||||||
// Also we are updating the expected time of the file
|
|
||||||
// in changedFile we'll check if the modification time
|
|
||||||
// is the same as the saved one here
|
|
||||||
// If so then it's a expected change
|
|
||||||
updateFileInfo(file);
|
|
||||||
foreach (const QString &fileName, d->m_filesWithWatch.value(file))
|
|
||||||
updateExpectedState(fileName);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FileManager::getSaveFileName(const QString &title, const QString &pathIn,
|
QString FileManager::getSaveFileName(const QString &title, const QString &pathIn,
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public:
|
|||||||
// file pool to monitor
|
// file pool to monitor
|
||||||
void addFiles(const QList<IFile *> &files, bool addWatcher = true);
|
void addFiles(const QList<IFile *> &files, bool addWatcher = true);
|
||||||
void addFile(IFile *file, bool addWatcher = true);
|
void addFile(IFile *file, bool addWatcher = true);
|
||||||
void removeFile(IFile *file);
|
bool removeFile(IFile *file);
|
||||||
QList<IFile *> modifiedFiles() const;
|
QList<IFile *> modifiedFiles() const;
|
||||||
|
|
||||||
void renamedFile(const QString &from, const QString &to);
|
void renamedFile(const QString &from, const QString &to);
|
||||||
@@ -159,7 +159,6 @@ private:
|
|||||||
void addFileInfo(const QString &fileName, IFile *file, bool isLink);
|
void addFileInfo(const QString &fileName, IFile *file, bool isLink);
|
||||||
void removeFileInfo(IFile *file);
|
void removeFileInfo(IFile *file);
|
||||||
|
|
||||||
void updateFileInfo(IFile *file);
|
|
||||||
void updateExpectedState(const QString &fileName);
|
void updateExpectedState(const QString &fileName);
|
||||||
|
|
||||||
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
|
QList<IFile *> saveModifiedFiles(const QList<IFile *> &files,
|
||||||
|
|||||||
Reference in New Issue
Block a user