2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-09-02 23:55:12 +00:00

First version on loading themes is ready.

This commit is contained in:
John Preston
2016-10-28 15:44:28 +03:00
parent b2414939c9
commit dbb6371e67
89 changed files with 4686 additions and 795 deletions

View File

@@ -26,7 +26,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
#include "serialize/serialize_document.h"
#include "serialize/serialize_common.h"
#include "data/data_drafts.h"
#include "window/chat_background.h"
#include "window/window_theme.h"
#include "observer_peer.h"
#include "mainwidget.h"
#include "mainwindow.h"
@@ -38,10 +38,12 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
namespace Local {
namespace {
constexpr int kThemeFileSizeLimit = 5 * 1024 * 1024;
using FileKey = quint64;
static const char tdfMagic[] = { 'T', 'D', 'F', '$' };
static const int32 tdfMagicLen = sizeof(tdfMagic);
constexpr char tdfMagic[] = { 'T', 'D', 'F', '$' };
constexpr int tdfMagicLen = sizeof(tdfMagic);
QString toFilePart(FileKey val) {
QString result;
@@ -68,30 +70,32 @@ bool _userWorking() {
return _manager && !_basePath.isEmpty() && !_userBasePath.isEmpty();
}
enum FileOptions {
UserPath = 0x01,
SafePath = 0x02,
enum class FileOption {
User = 0x01,
Safe = 0x02,
};
Q_DECLARE_FLAGS(FileOptions, FileOption);
Q_DECLARE_OPERATORS_FOR_FLAGS(FileOptions);
bool keyAlreadyUsed(QString &name, int options = UserPath | SafePath) {
bool keyAlreadyUsed(QString &name, FileOptions options = FileOption::User | FileOption::Safe) {
name += '0';
if (QFileInfo(name).exists()) return true;
if (options & SafePath) {
if (options & (FileOption::Safe)) {
name[name.size() - 1] = '1';
return QFileInfo(name).exists();
}
return false;
}
FileKey genKey(int options = UserPath | SafePath) {
if (options & UserPath) {
FileKey genKey(FileOptions options = FileOption::User | FileOption::Safe) {
if (options & FileOption::User) {
if (!_userWorking()) return 0;
} else {
if (!_working()) return 0;
}
FileKey result;
QString base = (options & UserPath) ? _userBasePath : _basePath, path;
QString base = (options & FileOption::User) ? _userBasePath : _basePath, path;
path.reserve(base.size() + 0x11);
path += base;
do {
@@ -103,18 +107,18 @@ FileKey genKey(int options = UserPath | SafePath) {
return result;
}
void clearKey(const FileKey &key, int options = UserPath | SafePath) {
if (options & UserPath) {
void clearKey(const FileKey &key, FileOptions options = FileOption::User | FileOption::Safe) {
if (options & FileOption::User) {
if (!_userWorking()) return;
} else {
if (!_working()) return;
}
QString base = (options & UserPath) ? _userBasePath : _basePath, name;
QString base = (options & FileOption::User) ? _userBasePath : _basePath, name;
name.reserve(base.size() + 0x11);
name.append(base).append(toFilePart(key)).append('0');
QFile::remove(name);
if (options & SafePath) {
if (options & FileOption::Safe) {
name[name.size() - 1] = '1';
QFile::remove(name);
}
@@ -193,14 +197,14 @@ struct EncryptedDescriptor {
};
struct FileWriteDescriptor {
FileWriteDescriptor(const FileKey &key, int options = UserPath | SafePath) : dataSize(0) {
FileWriteDescriptor(const FileKey &key, FileOptions options = FileOption::User | FileOption::Safe) {
init(toFilePart(key), options);
}
FileWriteDescriptor(const QString &name, int options = UserPath | SafePath) : dataSize(0) {
FileWriteDescriptor(const QString &name, FileOptions options = FileOption::User | FileOption::Safe) {
init(name, options);
}
void init(const QString &name, int options) {
if (options & UserPath) {
void init(const QString &name, FileOptions options) {
if (options & FileOption::User) {
if (!_userWorking()) return;
} else {
if (!_working()) return;
@@ -208,9 +212,9 @@ struct FileWriteDescriptor {
// detect order of read attempts and file version
QString toTry[2];
toTry[0] = ((options & UserPath) ? _userBasePath : _basePath) + name + '0';
if (options & SafePath) {
toTry[1] = ((options & UserPath) ? _userBasePath : _basePath) + name + '1';
toTry[0] = ((options & FileOption::User) ? _userBasePath : _basePath) + name + '0';
if (options & FileOption::Safe) {
toTry[1] = ((options & FileOption::User) ? _userBasePath : _basePath) + name + '1';
QFileInfo toTry0(toTry[0]);
QFileInfo toTry1(toTry[1]);
if (toTry0.exists()) {
@@ -295,15 +299,15 @@ struct FileWriteDescriptor {
QString toDelete;
HashMd5 md5;
int32 dataSize;
int32 dataSize = 0;
~FileWriteDescriptor() {
finish();
}
};
bool readFile(FileReadDescriptor &result, const QString &name, int options = UserPath | SafePath) {
if (options & UserPath) {
bool readFile(FileReadDescriptor &result, const QString &name, FileOptions options = FileOption::User | FileOption::Safe) {
if (options & FileOption::User) {
if (!_userWorking()) return false;
} else {
if (!_working()) return false;
@@ -311,11 +315,11 @@ bool readFile(FileReadDescriptor &result, const QString &name, int options = Use
// detect order of read attempts
QString toTry[2];
toTry[0] = ((options & UserPath) ? _userBasePath : _basePath) + name + '0';
if (options & SafePath) {
toTry[0] = ((options & FileOption::User) ? _userBasePath : _basePath) + name + '0';
if (options & FileOption::Safe) {
QFileInfo toTry0(toTry[0]);
if (toTry0.exists()) {
toTry[1] = ((options & UserPath) ? _userBasePath : _basePath) + name + '1';
toTry[1] = ((options & FileOption::User) ? _userBasePath : _basePath) + name + '1';
QFileInfo toTry1(toTry[1]);
if (toTry1.exists()) {
QDateTime mod0 = toTry0.lastModified(), mod1 = toTry1.lastModified();
@@ -435,7 +439,7 @@ bool decryptLocal(EncryptedDescriptor &result, const QByteArray &encrypted, cons
return true;
}
bool readEncryptedFile(FileReadDescriptor &result, const QString &name, int options = UserPath | SafePath, const MTP::AuthKey &key = _localKey) {
bool readEncryptedFile(FileReadDescriptor &result, const QString &name, FileOptions options = FileOption::User | FileOption::Safe, const MTP::AuthKey &key = _localKey) {
if (!readFile(result, name, options)) {
return false;
}
@@ -465,7 +469,7 @@ bool readEncryptedFile(FileReadDescriptor &result, const QString &name, int opti
return true;
}
bool readEncryptedFile(FileReadDescriptor &result, const FileKey &fkey, int options = UserPath | SafePath, const MTP::AuthKey &key = _localKey) {
bool readEncryptedFile(FileReadDescriptor &result, const FileKey &fkey, FileOptions options = FileOption::User | FileOption::Safe, const MTP::AuthKey &key = _localKey) {
return readEncryptedFile(result, toFilePart(fkey), options, key);
}
@@ -552,6 +556,7 @@ enum {
dbiNativeNotifications = 0x44,
dbiNotificationsCount = 0x45,
dbiNotificationsCorner = 0x46,
dbiTheme = 0x47,
dbiEncryptedWithSalt = 333,
dbiEncrypted = 444,
@@ -591,6 +596,9 @@ FileKey _savedGifsKey = 0;
FileKey _backgroundKey = 0;
bool _backgroundWasRead = false;
bool _backgroundCanWrite = true;
FileKey _themeKey = 0, _applyingThemeKey = 0;
bool _readingUserSettings = false;
FileKey _userSettingsKey = 0;
@@ -1057,6 +1065,15 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
};
} break;
case dbiTheme: {
quint64 themeKey = 0, applyingThemeKey = 0;
stream >> themeKey >> applyingThemeKey;
if (!_checkStreamStatus(stream)) return false;
_themeKey = themeKey;
_applyingThemeKey = applyingThemeKey;
} break;
case dbiTryIPv6: {
qint32 v;
stream >> v;
@@ -1185,7 +1202,7 @@ bool _readSetting(quint32 blockId, QDataStream &stream, int version) {
if (!_checkStreamStatus(stream)) return false;
bool tile = (version < 8005 && !_backgroundKey) ? false : (v == 1);
Window::chatBackground()->setTile(tile);
Window::Theme::Background()->setTile(tile);
} break;
case dbiAdaptiveForWide: {
@@ -1610,7 +1627,7 @@ void _writeUserSettings() {
EncryptedDescriptor data(size);
data.stream << quint32(dbiSendKey) << qint32(cCtrlEnter() ? dbiskCtrlEnter : dbiskEnter);
data.stream << quint32(dbiTileBackground) << qint32(Window::chatBackground()->tile() ? 1 : 0);
data.stream << quint32(dbiTileBackground) << qint32(Window::Theme::Background()->tile() ? 1 : 0);
data.stream << quint32(dbiAdaptiveForWide) << qint32(Global::AdaptiveForWide() ? 1 : 0);
data.stream << quint32(dbiAutoLock) << qint32(Global::AutoLock());
data.stream << quint32(dbiReplaceEmojis) << qint32(cReplaceEmojis() ? 1 : 0);
@@ -1691,7 +1708,7 @@ void _readUserSettings() {
}
void _writeMtpData() {
FileWriteDescriptor mtp(toFilePart(_dataNameKey), SafePath);
FileWriteDescriptor mtp(toFilePart(_dataNameKey), FileOption::Safe);
if (!_localKey.created()) {
LOG(("App Error: localkey not created in _writeMtpData()"));
return;
@@ -1714,7 +1731,7 @@ void _writeMtpData() {
void _readMtpData() {
FileReadDescriptor mtp;
if (!readEncryptedFile(mtp, toFilePart(_dataNameKey), SafePath)) {
if (!readEncryptedFile(mtp, toFilePart(_dataNameKey), FileOption::Safe)) {
if (_localKey.created()) {
_readOldMtpData();
_writeMtpData();
@@ -2074,11 +2091,12 @@ void finish() {
_manager->finish();
_manager->deleteLater();
_manager = 0;
delete _localLoader;
_localLoader = 0;
delete base::take(_localLoader);
}
}
void readTheme();
void start() {
t_assert(_manager == 0);
@@ -2089,7 +2107,7 @@ void start() {
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
FileReadDescriptor settingsData;
if (!readFile(settingsData, cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath)) {
if (!readFile(settingsData, cTestMode() ? qsl("settings_test") : qsl("settings"), FileOption::Safe)) {
_readOldSettings();
_readOldUserSettings(false); // needed further in _readUserSettings
_readOldMtpData(false); // needed further in _readMtpData
@@ -2156,6 +2174,8 @@ void start() {
_oldSettingsVersion = settingsData.version;
_settingsSalt = salt;
readTheme();
}
void writeSettings() {
@@ -2166,7 +2186,7 @@ void writeSettings() {
if (!QDir().exists(_basePath)) QDir().mkpath(_basePath);
FileWriteDescriptor settings(cTestMode() ? qsl("settings_test") : qsl("settings"), SafePath);
FileWriteDescriptor settings(cTestMode() ? qsl("settings_test") : qsl("settings"), FileOption::Safe);
if (_settingsSalt.isEmpty() || !_settingsKey.created()) {
_settingsSalt.resize(LocalEncryptSaltSize);
memset_rand(_settingsSalt.data(), _settingsSalt.size());
@@ -2212,7 +2232,9 @@ void writeSettings() {
auto &proxy = Global::ConnectionProxy();
size += Serialize::stringSize(proxy.host) + sizeof(qint32) + Serialize::stringSize(proxy.user) + Serialize::stringSize(proxy.password);
}
if (_themeKey || _applyingThemeKey) {
size += sizeof(quint32) + 2 * sizeof(quint64);
}
size += sizeof(quint32) + sizeof(qint32) * 7;
EncryptedDescriptor data(size);
@@ -2242,6 +2264,9 @@ void writeSettings() {
data.stream << proxy.host << qint32(proxy.port) << proxy.user << proxy.password;
}
data.stream << quint32(dbiTryIPv6) << qint32(Global::TryIPv6());
if (_themeKey || _applyingThemeKey) {
data.stream << quint32(dbiTheme) << quint64(_themeKey) << quint64(_applyingThemeKey);
}
TWindowPos pos(cWindowPos());
data.stream << quint32(dbiWindowPosition) << qint32(pos.x) << qint32(pos.y) << qint32(pos.w) << qint32(pos.h) << qint32(pos.moncrc) << qint32(pos.maximized);
@@ -2604,7 +2629,7 @@ void writeImage(const StorageKey &location, const StorageImageSaved &image, bool
qint32 size = _storageImageSize(image.data.size());
StorageMap::const_iterator i = _imagesMap.constFind(location);
if (i == _imagesMap.cend()) {
i = _imagesMap.insert(location, FileDesc(genKey(UserPath), size));
i = _imagesMap.insert(location, FileDesc(genKey(FileOption::User), size));
_storageImagesSize += size;
_mapChanged = true;
_writeMap();
@@ -2613,7 +2638,7 @@ void writeImage(const StorageKey &location, const StorageImageSaved &image, bool
}
EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + image.data.size());
data.stream << quint64(location.first) << quint64(location.second) << quint32(image.type) << image.data;
FileWriteDescriptor file(i.value().first, UserPath);
FileWriteDescriptor file(i.value().first, FileOption::User);
file.writeEncrypted(data);
if (i.value().second != size) {
_storageImagesSize += size;
@@ -2630,7 +2655,7 @@ public:
}
void process() {
FileReadDescriptor image;
if (!readEncryptedFile(image, _key, UserPath)) {
if (!readEncryptedFile(image, _key, FileOption::User)) {
return;
}
@@ -2701,7 +2726,7 @@ public:
void clearInMap() {
StorageMap::iterator j = _imagesMap.find(_location);
if (j != _imagesMap.cend() && j->first == _key) {
clearKey(_key, UserPath);
clearKey(_key, FileOption::User);
_storageImagesSize -= j->second;
_imagesMap.erase(j);
}
@@ -2730,7 +2755,7 @@ void writeStickerImage(const StorageKey &location, const QByteArray &sticker, bo
qint32 size = _storageStickerSize(sticker.size());
StorageMap::const_iterator i = _stickerImagesMap.constFind(location);
if (i == _stickerImagesMap.cend()) {
i = _stickerImagesMap.insert(location, FileDesc(genKey(UserPath), size));
i = _stickerImagesMap.insert(location, FileDesc(genKey(FileOption::User), size));
_storageStickersSize += size;
_mapChanged = true;
_writeMap();
@@ -2739,7 +2764,7 @@ void writeStickerImage(const StorageKey &location, const QByteArray &sticker, bo
}
EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + sticker.size());
data.stream << quint64(location.first) << quint64(location.second) << sticker;
FileWriteDescriptor file(i.value().first, UserPath);
FileWriteDescriptor file(i.value().first, FileOption::User);
file.writeEncrypted(data);
if (i.value().second != size) {
_storageStickersSize += size;
@@ -2760,7 +2785,7 @@ public:
void clearInMap() {
auto j = _stickerImagesMap.find(_location);
if (j != _stickerImagesMap.cend() && j->first == _key) {
clearKey(j.value().first, UserPath);
clearKey(j.value().first, FileOption::User);
_storageStickersSize -= j.value().second;
_stickerImagesMap.erase(j);
}
@@ -2804,7 +2829,7 @@ void writeAudio(const StorageKey &location, const QByteArray &audio, bool overwr
qint32 size = _storageAudioSize(audio.size());
StorageMap::const_iterator i = _audiosMap.constFind(location);
if (i == _audiosMap.cend()) {
i = _audiosMap.insert(location, FileDesc(genKey(UserPath), size));
i = _audiosMap.insert(location, FileDesc(genKey(FileOption::User), size));
_storageAudiosSize += size;
_mapChanged = true;
_writeMap();
@@ -2813,7 +2838,7 @@ void writeAudio(const StorageKey &location, const QByteArray &audio, bool overwr
}
EncryptedDescriptor data(sizeof(quint64) * 2 + sizeof(quint32) + sizeof(quint32) + audio.size());
data.stream << quint64(location.first) << quint64(location.second) << audio;
FileWriteDescriptor file(i.value().first, UserPath);
FileWriteDescriptor file(i.value().first, FileOption::User);
file.writeEncrypted(data);
if (i.value().second != size) {
_storageAudiosSize += size;
@@ -2834,7 +2859,7 @@ public:
void clearInMap() {
auto j = _audiosMap.find(_location);
if (j != _audiosMap.cend() && j->first == _key) {
clearKey(j.value().first, UserPath);
clearKey(j.value().first, FileOption::User);
_storageAudiosSize -= j.value().second;
_audiosMap.erase(j);
}
@@ -2882,7 +2907,7 @@ void writeWebFile(const QString &url, const QByteArray &content, bool overwrite)
qint32 size = _storageWebFileSize(url, content.size());
WebFilesMap::const_iterator i = _webFilesMap.constFind(url);
if (i == _webFilesMap.cend()) {
i = _webFilesMap.insert(url, FileDesc(genKey(UserPath), size));
i = _webFilesMap.insert(url, FileDesc(genKey(FileOption::User), size));
_storageWebFilesSize += size;
_writeLocations();
} else if (!overwrite) {
@@ -2890,7 +2915,7 @@ void writeWebFile(const QString &url, const QByteArray &content, bool overwrite)
}
EncryptedDescriptor data(Serialize::stringSize(url) + sizeof(quint32) + sizeof(quint32) + content.size());
data.stream << url << content;
FileWriteDescriptor file(i.value().first, UserPath);
FileWriteDescriptor file(i.value().first, FileOption::User);
file.writeEncrypted(data);
if (i.value().second != size) {
_storageWebFilesSize += size;
@@ -2909,7 +2934,7 @@ public:
}
void process() {
FileReadDescriptor image;
if (!readEncryptedFile(image, _key, UserPath)) {
if (!readEncryptedFile(image, _key, FileOption::User)) {
return;
}
@@ -2925,7 +2950,7 @@ public:
} else {
WebFilesMap::iterator j = _webFilesMap.find(_url);
if (j != _webFilesMap.cend() && j->first == _key) {
clearKey(j.value().first, UserPath);
clearKey(j.value().first, FileOption::User);
_storageWebFilesSize -= j.value().second;
_webFilesMap.erase(j);
}
@@ -3592,11 +3617,11 @@ void readSavedGifs() {
}
void writeBackground(int32 id, const QImage &img) {
if (!_working()) return;
if (!_working() || !_backgroundCanWrite) return;
QByteArray png;
QByteArray bmp;
if (!img.isNull()) {
QBuffer buf(&png);
QBuffer buf(&bmp);
if (!img.save(&buf, "BMP")) return;
}
if (!_backgroundKey) {
@@ -3604,17 +3629,19 @@ void writeBackground(int32 id, const QImage &img) {
_mapChanged = true;
_writeMap(WriteMapFast);
}
quint32 size = sizeof(qint32) + sizeof(quint32) + (png.isEmpty() ? 0 : (sizeof(quint32) + png.size()));
quint32 size = sizeof(qint32) + sizeof(quint32) + (bmp.isEmpty() ? 0 : (sizeof(quint32) + bmp.size()));
EncryptedDescriptor data(size);
data.stream << qint32(id);
if (!png.isEmpty()) data.stream << png;
if (!bmp.isEmpty()) data.stream << bmp;
FileWriteDescriptor file(_backgroundKey);
file.writeEncrypted(data);
}
bool readBackground() {
if (_backgroundWasRead) return false;
if (_backgroundWasRead || Global::ApplyingTheme()) {
return false;
}
_backgroundWasRead = true;
FileReadDescriptor bg;
@@ -3628,30 +3655,116 @@ bool readBackground() {
QByteArray pngData;
qint32 id;
bg.stream >> id;
if (!id || id == DefaultChatBackground) {
if (id == Window::Theme::kOldBackground || id == Window::Theme::kDefaultBackground) {
_backgroundCanWrite = false;
if (bg.version < 8005) {
App::initBackground(DefaultChatBackground, QImage(), true);
if (!id) Window::chatBackground()->setTile(!DefaultChatBackground);
Window::Theme::Background()->setImage(Window::Theme::kDefaultBackground);
if (id == Window::Theme::kOldBackground) {
Window::Theme::Background()->setTile(false);
}
} else {
App::initBackground(id, QImage(), true);
Window::Theme::Background()->setImage(id);
}
_backgroundCanWrite = true;
return true;
}
bg.stream >> pngData;
QImage img;
QImage image;
QBuffer buf(&pngData);
QImageReader reader(&buf);
#ifndef OS_MAC_OLD
reader.setAutoTransform(true);
#endif // OS_MAC_OLD
if (reader.read(&img)) {
App::initBackground(id, img, true);
if (reader.read(&image)) {
_backgroundCanWrite = false;
Window::Theme::Background()->setImage(id, std_::move(image));
_backgroundCanWrite = true;
return true;
}
return false;
}
bool readThemeUsingKey(FileKey key) {
FileReadDescriptor theme;
if (!readEncryptedFile(theme, key, FileOption::Safe, _settingsKey)) {
return false;
}
QByteArray themeContent;
QString pathRelative, pathAbsolute;
Window::Theme::Cached cache;
theme.stream >> themeContent;
theme.stream >> pathRelative >> pathAbsolute;
if (theme.stream.status() != QDataStream::Ok) {
return false;
}
QFile file(pathRelative);
if (pathRelative.isEmpty() || !file.exists()) {
file.setFileName(pathAbsolute);
}
auto changed = false;
if (!file.fileName().isEmpty() && file.exists() && file.open(QIODevice::ReadOnly)) {
if (file.size() > kThemeFileSizeLimit) {
LOG(("Error: theme file too large: %1 (should be less than 5 MB, got %2)").arg(file.fileName()).arg(file.size()));
return false;
}
auto fileContent = file.readAll();
file.close();
if (themeContent != fileContent) {
themeContent = fileContent;
changed = true;
}
}
if (!changed) {
quint32 backgroundIsTiled = 0;
theme.stream >> cache.paletteChecksum >> cache.contentChecksum >> cache.colors >> cache.background >> backgroundIsTiled;
cache.tiled = (backgroundIsTiled == 1);
if (theme.stream.status() != QDataStream::Ok) {
return false;
}
}
return Window::Theme::Load(pathRelative, pathAbsolute, themeContent, cache);
}
void writeTheme(const QString &pathRelative, const QString &pathAbsolute, const QByteArray &content, const Window::Theme::Cached &cache) {
auto key = _applyingThemeKey ? _applyingThemeKey : _themeKey;
if (!key) {
key = _themeKey = genKey();
writeSettings();
}
auto backgroundTiled = static_cast<quint32>(cache.tiled ? 1 : 0);
quint32 size = Serialize::bytearraySize(content);
size += Serialize::stringSize(pathRelative) + Serialize::stringSize(pathAbsolute);
size += sizeof(int32) * 2 + Serialize::bytearraySize(cache.colors) + Serialize::bytearraySize(cache.background) + sizeof(quint32);
EncryptedDescriptor data(size);
data.stream << content;
data.stream << pathRelative << pathAbsolute;
data.stream << cache.paletteChecksum << cache.contentChecksum << cache.colors << cache.background << backgroundTiled;
FileWriteDescriptor file(key, FileOption::Safe);
file.writeEncrypted(data, _settingsKey);
}
void readTheme() {
if (_applyingThemeKey) {
if (readThemeUsingKey(_applyingThemeKey)) {
Global::SetApplyingTheme(true);
} else {
clearKey(_applyingThemeKey);
_applyingThemeKey = 0;
writeSettings();
readTheme();
}
} else if (_themeKey && !readThemeUsingKey(_themeKey)) {
clearKey(_themeKey);
_themeKey = 0;
writeSettings();
}
}
uint32 _peerSize(PeerData *peer) {
uint32 result = sizeof(quint64) + sizeof(quint64) + Serialize::storageImageLocationSize();
if (peer->isUser()) {
@@ -4330,16 +4443,16 @@ void ClearManager::onStart() {
break;
case ClearManagerStorage:
for (StorageMap::const_iterator i = images.cbegin(), e = images.cend(); i != e; ++i) {
clearKey(i.value().first, UserPath);
clearKey(i.value().first, FileOption::User);
}
for (StorageMap::const_iterator i = stickers.cbegin(), e = stickers.cend(); i != e; ++i) {
clearKey(i.value().first, UserPath);
clearKey(i.value().first, FileOption::User);
}
for (StorageMap::const_iterator i = audios.cbegin(), e = audios.cend(); i != e; ++i) {
clearKey(i.value().first, UserPath);
clearKey(i.value().first, FileOption::User);
}
for (WebFilesMap::const_iterator i = webFiles.cbegin(), e = webFiles.cend(); i != e; ++i) {
clearKey(i.value().first, UserPath);
clearKey(i.value().first, FileOption::User);
}
result = true;
break;