3636#endif
3737
3838#include " DisplayedFilesModel.h"
39+
40+ #include < QThreadPool>
41+
42+ #include " FileUtilities.h"
3943#include < App/Application.h>
4044#include < App/ProjectFile.h>
4145#include < Base/FileInfo.h>
@@ -89,73 +93,6 @@ FileStats fileInfoFromFreeCADFile(const std::string& path)
8993 return result;
9094}
9195
92- std::string getThumbnailsImage ()
93- {
94- return " thumbnails/Thumbnail.png" ;
95- }
96-
97- QString getThumbnailsName ()
98- {
99- #if defined(Q_OS_LINUX)
100- return QString::fromLatin1 (" thumbnails/normal" );
101- #else
102- return QString::fromLatin1 (" FreeCADStartThumbnails" );
103- #endif
104- }
105-
106- QDir getThumnailsParentDir ()
107- {
108- return {QStandardPaths::writableLocation (QStandardPaths::GenericCacheLocation)};
109- }
110-
111- QString getThumbnailsDir ()
112- {
113- QDir dir = getThumnailsParentDir ();
114- return dir.absoluteFilePath (getThumbnailsName ());
115- }
116-
117- void createThumbnailsDir ()
118- {
119- QString name = getThumbnailsName ();
120- QDir dir (getThumnailsParentDir ());
121- if (!dir.exists (name)) {
122- dir.mkpath (name);
123- }
124- }
125-
126- QString getMD5Hash (const std::string& path)
127- {
128- // Use MD5 hash as specified here:
129- // https://specifications.freedesktop.org/thumbnail-spec/0.8.0/thumbsave.html
130- QUrl url (QString::fromStdString (path));
131- url.setScheme (QString::fromLatin1 (" file" ));
132- QCryptographicHash hash (QCryptographicHash::Md5);
133- hash.addData (url.toEncoded ());
134- QByteArray ba = hash.result ().toHex ();
135- return QString::fromLatin1 (ba);
136- }
137-
138- QString getUniquePNG (const std::string& path)
139- {
140- QDir dir = getThumbnailsDir ();
141- QString md5 = getMD5Hash (path) + QLatin1String (" .png" );
142- return dir.absoluteFilePath (md5);
143- }
144-
145- bool useCachedPNG (const std::string& image, const std::string& project)
146- {
147- Base::FileInfo f1 (image);
148- Base::FileInfo f2 (project);
149- if (!f1.exists ()) {
150- return false ;
151- }
152- if (!f2.exists ()) {
153- return false ;
154- }
155-
156- return f1.lastModified () > f2.lastModified ();
157- }
158-
15996// / Load the thumbnail image data (if any) that is stored in an FCStd file.
16097// / \returns The image bytes, or an empty QByteArray (if no thumbnail was stored)
16198QByteArray loadFCStdThumbnail (const std::string& pathToFCStdFile)
@@ -187,39 +124,6 @@ QByteArray loadFCStdThumbnail(const std::string& pathToFCStdFile)
187124 return {};
188125}
189126
190- // / Attempt to generate a thumbnail image from a file using f3d or load from cache
191- // / \returns The image bytes, or an empty QByteArray (if thumbnail generation fails)
192- QByteArray getF3dThumbnail (const std::string& pathToFile)
193- {
194- QString thumbnailPath = getUniquePNG (pathToFile);
195- if (!useCachedPNG (thumbnailPath.toStdString (), pathToFile)) {
196- ParameterGrp::handle hGrp = App::GetApplication ().GetParameterGroupByPath (
197- " User parameter:BaseApp/Preferences/Mod/Start" );
198- auto f3d = QString::fromUtf8 (hGrp->GetASCII (" f3d" , " f3d" ).c_str ());
199- const int resolution = 128 ;
200- QStringList args;
201- args << QLatin1String (" --config=thumbnail" ) << QLatin1String (" --load-plugins=occt" )
202- << QLatin1String (" --verbose=quiet" ) << QLatin1String (" --output=" ) + thumbnailPath
203- << QLatin1String (" --resolution=" ) + QString::number (resolution) + QLatin1String (" ," )
204- + QString::number (resolution)
205- << QString::fromStdString (pathToFile);
206-
207- QProcess process;
208- process.start (f3d, args);
209- process.waitForFinished ();
210- if (process.exitCode () != 0 ) {
211- return {};
212- }
213- }
214-
215- QFile thumbnailFile (thumbnailPath);
216- if (thumbnailFile.exists ()) {
217- thumbnailFile.open (QIODevice::OpenModeFlag::ReadOnly);
218- return thumbnailFile.readAll ();
219- }
220- return {};
221- }
222-
223127FileStats getFileInfo (const std::string& path)
224128{
225129 FileStats result;
@@ -329,10 +233,12 @@ void DisplayedFilesModel::addFile(const QString& filePath)
329233 }
330234 }
331235 else {
332- auto thumbnail = getF3dThumbnail (filePath.toStdString ());
333- if (!thumbnail.isEmpty ()) {
334- _imageCache.insert (filePath, thumbnail);
335- }
236+ auto runner = new ThumbnailSource (filePath);
237+ connect (runner->signals (),
238+ &ThumbnailSourceSignals::thumbnailAvailable,
239+ this ,
240+ &DisplayedFilesModel::processNewThumbnail);
241+ QThreadPool::globalInstance ()->start (runner);
336242 }
337243}
338244
@@ -357,3 +263,10 @@ QHash<int, QByteArray> DisplayedFilesModel::roleNames() const
357263 };
358264 return nameMap;
359265}
266+
267+ void DisplayedFilesModel::processNewThumbnail (const QString& file, const QByteArray& thumbnail)
268+ {
269+ if (!thumbnail.isEmpty ()) {
270+ _imageCache.insert (file, thumbnail);
271+ }
272+ }
0 commit comments