QFileSystemModel remove bug
Hi,
I have a qfilesystemmodel and I have a menu to delete a file/folder.
Here the code :
Code:
for( int i = 0; i < SelectedIndexes.count(); ++i )
{
const QFileInfo FileInfo
= Model
->fileInfo
( SelectedIndexes
[ i
] );
if( FileInfo.isDir() )
{
if( QDir( FileInfo.
absoluteFilePath() ).
removeRecursively() == false ) DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", FileInfo.absoluteFilePath().toUtf8().data() );
}
else
{
if( QDir( FileInfo.
dir().
absolutePath() ).
remove( FileInfo.
fileName() ) == false ) DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", FileInfo.absoluteFilePath().toUtf8().data() );
}
}
The problem is when you enter the folder inside a folder and try to remove, you can't remove.
* Root
** Folder
*** Inside_Folder
Once a setRootIndex is called on the "Inside_Folder" if you set the rootIndex to the root and try to remove Folder, you can't.
That removes "Inside_Folder" but not "Folder" you have to redo a remove action on Folder a second time to remove it.
A fix exists on this problem ? How ?
Thanks for the help
Re: QFileSystemModel remove bug
Maybe it is a bug, but you can always check to see if the file / folder exists after you do a remove, and have your code do it again. You don't have to make your user do it twice when you can do it for them.
Re: QFileSystemModel remove bug
Doing it twice if the remove return false gives two times the error message and I can't remove the folder outside the app using Windows explorer, Windows says the folder is used can't be deleted. Looks like a QFileWatcher problem. I tried to remove recursively manually but gives the same result, that remove all inside recursively but not the folder where the delete starts.
Re: QFileSystemModel remove bug
I think the problem might be that because the QFileInfo instance is still in scope and is still "looking" at the folder, that is why you are getting the "in use" message.
Since you don't actually need the QFileInfo instance (you need the absolute path, filename and a bool to say if it is a directory), then you could put the QFileInfo instance into its own local scope:
Code:
for( int i = 0; i < SelectedIndexes.count(); ++i )
{
bool isDir = false;
{
const QFileInfo FileInfo
= Model
->fileInfo
( SelectedIndexes
[ i
] );
absPath = FileInfo.absoluteFilePath();
isDir = FileInfo.isDir();
if ( isDir )
fileName = FileInfo.fileName();
}
if ( isDir )
{
if( QDir( absPath
).
removeRecursively() == false ) DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", absPath.toUtf8().data() );
}
else
{
if( QDir( absPath
).
remove( fileName
) == false ) DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", absPath.toUtf8().data() );
}
}
Re: QFileSystemModel remove bug
Same result, needs double action.
I found the code can be reduced like that :
Code:
for( int i = 0; i < SelectedIndexes.count(); ++i )
{
if( Model->remove( SelectedIndexes[ i ] ) == false )
{
const QString AbsoluteFilePath
= Model
->fileInfo
( SelectedIndexes
[ i
] ).
absoluteFilePath();
DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", AbsoluteFilePath.toUtf8().data() );
}
}
The problem is there only if I enter in the folder before remove it, I delete it on the start of the application, that works fine.
Root
**Folder
***Inside_Folder
Only if you enter the "Inside_Folder", if you just enter "Folder" and go back to "Root" and delete "Folder" that delete "Folder" and "Inside_Folder" correctly.
The Qt doc says that installs a file system watcher : http://doc.qt.io/qt-5/qfilesystemmodel.html#setRootPath
I'm pretty sure that doesn't remove it when you change the path, must be the problem, I only see that.
When I change folder I do : m_DetailList->setRootIndex( DetailModel->index( CurrentPath ) );
That shows me the inside of the folder since I use an icon view on the list.
Re: QFileSystemModel remove bug
If you are calling setRootIndex() then it possibly invalidates any existing QModelIndexes, including those in your SelectionIndexes vector/list. Are you rebuilding this list after your change of root index? Have you checked the indexes are valid and pointing where you think they are?
Is there a reason for not deleting through the model?
Re: QFileSystemModel remove bug
Quote:
Originally Posted by
ChrisW67
Is there a reason for not deleting through the model?
I have changed to use "Model->remove( SelectedIndexes[ i ] )" like I showed before.
"setRootIndex()" is called only when double on a folder, when delete is involved, "setRootIndex()" is not called.
On the beginning of the delete function I do :
const QModelIndexList SelectedIndexes = selectedIndexes();
I use icon view on the list, the user can not select inside folder since he only see the root folder of the delete.
Since that deletes all folder inside, the index is valid. Only if I enter in the inside folder then it's impossible to delete without two delete actions.
The full function :
Code:
void DeleteSelectedItems()
{
const QModelIndexList SelectedIndexes = selectedIndexes();
if( selectedIndexes().empty() )
return;
CFileSystemModel* Model = static_cast< CFileSystemModel* >( model() );
for( int i = 0; i < SelectedIndexes.count(); ++i )
{
if( Model->remove( SelectedIndexes[ i ] ) == false )
{
const QString AbsoluteFilePath
= Model
->fileInfo
( SelectedIndexes
[ i
] ).
absoluteFilePath();
DE::CEngine::GetLogger().LogError( "\"%s\" can not be deleted", AbsoluteFilePath.toUtf8().data() );
}
}
}