@@ -62,9 +62,18 @@ MaterialManagerTree::MaterialManagerTree(QWidget *parent)
6262 QObject::connect (Application::instance ()->getSession (), &Session::modelAdded, this , &MaterialManagerTree::onModelAdded,Qt::BlockingQueuedConnection);
6363 QObject::connect (Application::instance ()->getSession (), &Session::problemSelectionChanged, this , &MaterialManagerTree::onProblemChanged);
6464
65+ // Every refresh reads all material files, so a burst of changes (e.g. the
66+ // material database being copied in) is refreshed only once it settles.
67+ this ->directoryChangedTimer = new QTimer (this );
68+ this ->directoryChangedTimer ->setSingleShot (true );
69+ this ->directoryChangedTimer ->setInterval (500 );
70+ QObject::connect (this ->directoryChangedTimer ,&QTimer::timeout,this ,[this ](){
71+ this ->onDirectoryChanged (Application::instance ()->getApplicationSettings ()->getMaterialsDir ());
72+ });
73+
6574 QFileSystemWatcher *fileSystemWatcher = new QFileSystemWatcher (this );
6675 fileSystemWatcher->addPath (Application::instance ()->getApplicationSettings ()->getMaterialsDir ());
67- QObject::connect (fileSystemWatcher,&QFileSystemWatcher::directoryChanged,this ,&MaterialManagerTree::onDirectoryChanged );
76+ QObject::connect (fileSystemWatcher,&QFileSystemWatcher::directoryChanged,this -> directoryChangedTimer ,qOverload<>(&QTimer::start) );
6877
6978 this ->onDirectoryChanged (Application::instance ()->getApplicationSettings ()->getMaterialsDir ());
7079
@@ -320,13 +329,25 @@ RMaterial MaterialManagerTree::read(QString &filePath)
320329 QString suggestedFilePath = MaterialManagerTree::buildFilePath (material);
321330 if (filePath != suggestedFilePath)
322331 {
323- RLogger::info (" Converting material file \" %s\" to \" %s\" .\n " ,
324- filePath.toUtf8 ().constData (),
325- suggestedFilePath.toUtf8 ().constData ());
332+ if (QFileInfo (filePath) != QFileInfo (suggestedFilePath) && QFile::exists (suggestedFilePath))
333+ {
334+ // The material already exists in the default format, which is the
335+ // newer one - the former file is a leftover and must not overwrite it.
336+ RLogger::info (" Material file \" %s\" is superseded by \" %s\" .\n " ,
337+ filePath.toUtf8 ().constData (),
338+ suggestedFilePath.toUtf8 ().constData ());
339+ material.read (suggestedFilePath);
340+ }
341+ else
342+ {
343+ RLogger::info (" Converting material file \" %s\" to \" %s\" .\n " ,
344+ filePath.toUtf8 ().constData (),
345+ suggestedFilePath.toUtf8 ().constData ());
326346
327- // Write the material in the default format first so that the material
328- // is never lost in case the conversion fails.
329- MaterialManagerTree::write (suggestedFilePath,material);
347+ // Write the material in the default format first so that the material
348+ // is never lost in case the conversion fails.
349+ MaterialManagerTree::write (suggestedFilePath,material);
350+ }
330351
331352 // Remove the former file only if it is not the file which has just been
332353 // written - the paths may differ while pointing to the same file on
@@ -411,9 +432,19 @@ void MaterialManagerTree::onDirectoryChanged(const QString &path)
411432 for (const QFileInfo &fileInfo : std::as_const (fileInfoList))
412433 {
413434 QString filePath = fileInfo.filePath ();
435+ if (this ->materialCache .contains (filePath))
436+ {
437+ // Already added from a former file which was converted to this one.
438+ continue ;
439+ }
414440 try
415441 {
416442 RMaterial material = MaterialManagerTree::read (filePath);
443+ if (this ->materialCache .contains (filePath))
444+ {
445+ // Former file was converted to a file which is already in the tree.
446+ continue ;
447+ }
417448 QTreeWidgetItem *item = new QTreeWidgetItem (this ->treeWidget );
418449 this ->updateItem (item, material, filePath, false );
419450 }
0 commit comments