forked from qt-creator/qt-creator
Utils: Cleanup MarkdownBrowser cache handling
Change-Id: I4eb7fa7247645a5b2a8db3b6164d0a40f258e14e Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -183,6 +183,18 @@ public:
|
|||||||
, m_entries(1024 * 1024 * 10) // 10 MB max image cache size
|
, m_entries(1024 * 1024 * 10) // 10 MB max image cache size
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
static Entry::Pointer makeEntry(const QByteArray &data, qsizetype maxSize)
|
||||||
|
{
|
||||||
|
// If the image is larger than what we allow in our cache,
|
||||||
|
// we still want to create an entry, but one with an empty image.
|
||||||
|
// So we clear it here, but still create the entry, so the painter can
|
||||||
|
// correctly show the "broken image" placeholder instead.
|
||||||
|
if (data.size() > maxSize)
|
||||||
|
return std::make_shared<Entry>(QByteArray());
|
||||||
|
|
||||||
|
return std::make_shared<Entry>(data);
|
||||||
|
}
|
||||||
|
|
||||||
virtual QSizeF intrinsicSize(
|
virtual QSizeF intrinsicSize(
|
||||||
QTextDocument *doc, int posInDocument, const QTextFormat &format) override
|
QTextDocument *doc, int posInDocument, const QTextFormat &format) override
|
||||||
{
|
{
|
||||||
@@ -229,15 +241,12 @@ public:
|
|||||||
painter->drawImage(rect, (*entryPtr)->movie.currentImage());
|
painter->drawImage(rect, (*entryPtr)->movie.currentImage());
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const QString &name, QByteArray data)
|
void set(const QString &name, const QByteArray &data)
|
||||||
{
|
{
|
||||||
if (data.size() > m_entries.maxCost())
|
set(name, makeEntry(data, m_entries.maxCost()));
|
||||||
data.clear();
|
|
||||||
|
|
||||||
set(name, std::make_shared<Entry>(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const QString &name, Entry::Pointer entry)
|
void set(const QString &name, const Entry::Pointer &entry)
|
||||||
{
|
{
|
||||||
entry->moveToThread(thread());
|
entry->moveToThread(thread());
|
||||||
|
|
||||||
@@ -247,12 +256,17 @@ public:
|
|||||||
}
|
}
|
||||||
const qint64 size = qMax(1, entry->buffer.size());
|
const qint64 size = qMax(1, entry->buffer.size());
|
||||||
|
|
||||||
|
if (size > m_entries.maxCost()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Entry::Pointer *entryPtr = new Entry::Pointer(entry);
|
Entry::Pointer *entryPtr = new Entry::Pointer(entry);
|
||||||
if (m_entries.insert(name, entryPtr, size))
|
if (m_entries.insert(name, entryPtr, size))
|
||||||
m_redraw();
|
m_redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMaximumCacheSize(qsizetype maxSize) { m_entries.setMaxCost(maxSize); }
|
void setMaximumCacheSize(qsizetype maxSize) { m_entries.setMaxCost(maxSize); }
|
||||||
|
qsizetype maximumCacheSize() const { return m_entries.maxCost(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<void()> m_redraw;
|
std::function<void()> m_redraw;
|
||||||
@@ -310,7 +324,13 @@ public:
|
|||||||
if (!m_loadRemoteImages)
|
if (!m_loadRemoteImages)
|
||||||
remoteUrls.clear();
|
remoteUrls.clear();
|
||||||
|
|
||||||
Storage<std::pair<QUrl, QByteArray>> remoteData;
|
struct RemoteData
|
||||||
|
{
|
||||||
|
QUrl url;
|
||||||
|
QByteArray data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Storage<RemoteData> remoteData;
|
||||||
|
|
||||||
const LoopList remoteIterator(Utils::toList(remoteUrls));
|
const LoopList remoteIterator(Utils::toList(remoteUrls));
|
||||||
const LoopList localIterator(Utils::toList(localUrls));
|
const LoopList localIterator(Utils::toList(localUrls));
|
||||||
@@ -327,7 +347,7 @@ public:
|
|||||||
|
|
||||||
query.setRequest(request);
|
query.setRequest(request);
|
||||||
query.setNetworkAccessManager(m_networkAccessManager);
|
query.setNetworkAccessManager(m_networkAccessManager);
|
||||||
remoteData->first = *remoteIterator;
|
remoteData->url = *remoteIterator;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onQueryDone = [this, remoteData](const NetworkQuery &query, DoneWith result) {
|
auto onQueryDone = [this, remoteData](const NetworkQuery &query, DoneWith result) {
|
||||||
@@ -336,43 +356,49 @@ public:
|
|||||||
m_urlsToLoad.remove(query.reply()->url());
|
m_urlsToLoad.remove(query.reply()->url());
|
||||||
|
|
||||||
if (result == DoneWith::Success) {
|
if (result == DoneWith::Success) {
|
||||||
remoteData->second = query.reply()->readAll();
|
remoteData->data = query.reply()->readAll();
|
||||||
} else {
|
} else {
|
||||||
m_imageHandler.set(remoteData->first.toString(), QByteArray{});
|
m_imageHandler.set(remoteData->url.toString(), QByteArray{});
|
||||||
markContentsDirty(0, this->characterCount());
|
markContentsDirty(0, this->characterCount());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using EntryPointer = AnimatedImageHandler::Entry::Pointer;
|
using EntryPointer = AnimatedImageHandler::Entry::Pointer;
|
||||||
|
|
||||||
auto onMakeEntrySetup = [remoteData](Async<EntryPointer> &async) {
|
auto onMakeEntrySetup = [remoteData, maxSize = m_imageHandler.maximumCacheSize()](
|
||||||
|
Async<EntryPointer> &async) {
|
||||||
async.setConcurrentCallData(
|
async.setConcurrentCallData(
|
||||||
[](const QByteArray &data) {
|
[](const QByteArray &data, qsizetype maxSize) {
|
||||||
return std::make_shared<AnimatedImageHandler::Entry>(data);
|
return AnimatedImageHandler::makeEntry(data, maxSize);
|
||||||
},
|
},
|
||||||
remoteData->second);
|
remoteData->data,
|
||||||
|
maxSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onMakeEntryDone =
|
auto onMakeEntryDone =
|
||||||
[this, remoteIterator, remoteData](const Async<EntryPointer> &async) {
|
[this, remoteIterator, remoteData](const Async<EntryPointer> &async) {
|
||||||
EntryPointer result = async.result();
|
EntryPointer result = async.result();
|
||||||
if (result) {
|
if (result) {
|
||||||
m_imageHandler.set(remoteData->first.toString(), result);
|
m_imageHandler.set(remoteData->url.toString(), result);
|
||||||
markContentsDirty(0, this->characterCount());
|
markContentsDirty(0, this->characterCount());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onLocalSetup = [localIterator, basePath = m_basePath](Async<EntryPointer> &async) {
|
auto onLocalSetup = [localIterator,
|
||||||
const FilePath u = basePath.resolvePath(localIterator->path());
|
basePath = m_basePath,
|
||||||
|
maxSize = m_imageHandler.maximumCacheSize()](
|
||||||
|
Async<EntryPointer> &async) {
|
||||||
|
const FilePath path = basePath.resolvePath(localIterator->path());
|
||||||
async.setConcurrentCallData(
|
async.setConcurrentCallData(
|
||||||
[](QPromise<EntryPointer> &promise, const FilePath &f) {
|
[](QPromise<EntryPointer> &promise, const FilePath &path, qsizetype maxSize) {
|
||||||
auto data = f.fileContents();
|
auto data = path.fileContents();
|
||||||
if (!data || promise.isCanceled())
|
if (!data || promise.isCanceled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
promise.addResult(std::make_shared<AnimatedImageHandler::Entry>(*data));
|
promise.addResult(AnimatedImageHandler::makeEntry(*data, maxSize));
|
||||||
},
|
},
|
||||||
u);
|
path,
|
||||||
|
maxSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto onLocalDone = [localIterator, this](const Async<EntryPointer> &async) {
|
auto onLocalDone = [localIterator, this](const Async<EntryPointer> &async) {
|
||||||
|
Reference in New Issue
Block a user