10 #include <QApplication>
13 #include <QStandardItemModel>
14 #include <QSortFilterProxyModel>
15 #include <QFileSystemWatcher>
24 , RelativePath_ (relPath)
25 , SubElemModel_ (new QStandardItemModel (this))
26 , SortModel_ (new QSortFilterProxyModel (this))
27 , Watcher_ (new QFileSystemWatcher (this))
28 , CacheFlushTimer_ (new QTimer (this))
30 if (RelativePath_.startsWith (
'/'))
31 RelativePath_ = RelativePath_.mid (1);
32 if (!RelativePath_.endsWith (
'/'))
33 RelativePath_.append (
'/');
35 SortModel_->setDynamicSortFilter (
true);
36 SortModel_->setSourceModel (SubElemModel_);
40 &QFileSystemWatcher::directoryChanged,
42 &ResourceLoader::HandleDirectoryChanged);
44 connect (CacheFlushTimer_,
52 if (!prefix.isEmpty () &&
53 !prefix.endsWith (
'/'))
55 QString result = QDir::homePath () +
"/.leechcraft/data/" + prefix;
56 LocalPrefixesChain_ << result;
58 QDir testDir = QDir::home ();
59 if (!testDir.exists (
".leechcraft/data/" + prefix + RelativePath_))
61 qDebug () << Q_FUNC_INFO
62 <<
".leechcraft/data/" + prefix + RelativePath_
63 <<
"doesn't exist, trying to create it...";
65 if (!testDir.mkpath (
".leechcraft/data/" + prefix + RelativePath_))
67 qWarning () << Q_FUNC_INFO
69 <<
".leechcraft/data/" + prefix + RelativePath_;
73 ScanPath (result + RelativePath_);
75 Watcher_->addPath (result + RelativePath_);
80 #if defined (Q_OS_MAC) && !defined (USE_UNIX_LAYOUT)
81 const QStringList prefixes { QApplication::applicationDirPath () +
"/../Resources/share/" };
82 #elif defined (Q_OS_WIN32)
83 const QStringList prefixes { QApplication::applicationDirPath () +
"/share/" };
84 #elif defined (INSTALL_PREFIX)
85 const QStringList prefixes { INSTALL_PREFIX
"/share/leechcraft/" };
87 const QStringList prefixes
89 "/usr/local/share/leechcraft/",
90 "/usr/share/leechcraft/"
93 bool hasBeenAdded =
false;
94 for (
const auto& prefix : prefixes)
96 GlobalPrefixesChain_ << prefix;
97 ScanPath (prefix + RelativePath_);
99 if (QFile::exists (prefix + RelativePath_))
101 Watcher_->addPath (prefix + RelativePath_);
107 qWarning () << Q_FUNC_INFO
108 <<
"no prefixes have been added:"
116 if (qApp->property (
"no-resource-caching").toBool ())
121 CacheFlushTimer_->stop ();
123 CachePathContents_.setMaxCost (0);
124 CachePixmaps_.setMaxCost (0);
129 CacheFlushTimer_->start (timeout);
131 CachePathContents_.setMaxCost (size * 1024);
132 CachePixmaps_.setMaxCost (size * 1024);
138 CachePathContents_.clear ();
139 CachePixmaps_.clear ();
143 const QStringList& nameFilters, QDir::Filters filters)
const
145 QSet<QString> alreadyListed;
146 QFileInfoList result;
147 for (
const auto& prefix : LocalPrefixesChain_ + GlobalPrefixesChain_)
149 const QDir dir { prefix + RelativePath_ + option };
150 const auto& list = dir.entryInfoList (nameFilters, filters);
151 for (
const auto& info : list)
153 const auto& fname = info.fileName ();
154 if (alreadyListed.contains (fname))
157 alreadyListed << fname;
167 for (
const auto& prefix : LocalPrefixesChain_ + GlobalPrefixesChain_)
168 for (
const auto& path : pathVariants)
171 qDebug () << Q_FUNC_INFO
173 << prefix + RelativePath_ + path;
174 const QString& can = QFileInfo (prefix + RelativePath_ + path).absoluteFilePath ();
176 qDebug () << Q_FUNC_INFO
177 <<
"absolute file path"
180 << QFile::exists (can);
181 if (QFile::exists (can))
190 QStringList IconizeBasename (
const QString& basename)
204 return GetPath (IconizeBasename (basename));
209 const auto& path =
GetPath (pathVariants);
213 if (CachePathContents_.contains (path))
216 qDebug () << Q_FUNC_INFO
221 auto result = std::make_shared<QBuffer> ();
222 result->setData (*CachePathContents_ [path]);
224 result->open (QIODevice::ReadOnly);
228 auto result = std::make_shared<QFile> (path);
230 if (!result->isSequential () &&
231 result->size () < CachePathContents_.maxCost () / 2)
233 if (result->open (QIODevice::ReadOnly))
235 const auto& data = result->readAll ();
236 CachePathContents_.insert (path,
new QByteArray { data }, data.size ());
244 if (open && !result->isOpen ())
245 if (!result->open (QIODevice::ReadOnly))
246 qWarning () << Q_FUNC_INFO
247 <<
"unable to open file"
249 << result->errorString ();
256 return Load (QStringList { pathVariant }, open);
261 return Load (IconizeBasename (basename), open);
266 if (CachePixmaps_.contains (basename))
267 return *CachePixmaps_ [basename];
273 const auto& data = dev->readAll ();
276 result.loadFromData (data);
277 CachePixmaps_.insert (basename,
new QPixmap (result), data.size ());
288 AttrFilters_ = filters;
293 NameFilters_ = filters;
301 void ResourceLoader::ScanPath (
const QString& path)
303 for (
const auto& entry : QDir (path).entryList (NameFilters_, AttrFilters_))
305 Entry2Paths_ [entry] << path;
306 if (!SubElemModel_->findItems (entry).isEmpty ())
309 SubElemModel_->appendRow (
new QStandardItem (entry));
313 void ResourceLoader::HandleDirectoryChanged (
const QString& path)
317 for (
auto& paths : Entry2Paths_)
318 paths.removeAll (path);
326 for (
auto i = Entry2Paths_.begin (); i != Entry2Paths_.end ();)
329 for (
auto item : SubElemModel_->findItems (i.key ()))
330 SubElemModel_->removeRow (item->row ());
331 i = Entry2Paths_.erase (i);