diff options
author | louib <code@louib.net> | 2021-03-13 22:07:49 +0300 |
---|---|---|
committer | Jonathan White <support@dmapps.us> | 2021-11-12 15:41:30 +0300 |
commit | 004f2b6801d93116277778611920793b7dbe0afb (patch) | |
tree | ab328622af017c0e5735ffd0588480321bbed07d /src/core | |
parent | 6f5bbf7ad1048abc3db7e378df654a61954f77e3 (diff) |
Removing QWidget dependency from src/core.
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/DatabaseIcons.cpp | 118 | ||||
-rw-r--r-- | src/core/DatabaseIcons.h | 59 | ||||
-rw-r--r-- | src/core/Entry.cpp | 39 | ||||
-rw-r--r-- | src/core/Entry.h | 4 | ||||
-rw-r--r-- | src/core/Global.h | 7 | ||||
-rw-r--r-- | src/core/Group.cpp | 48 | ||||
-rw-r--r-- | src/core/Group.h | 4 | ||||
-rw-r--r-- | src/core/Merger.cpp | 3 | ||||
-rw-r--r-- | src/core/Metadata.cpp | 73 | ||||
-rw-r--r-- | src/core/Metadata.h | 16 | ||||
-rw-r--r-- | src/core/Tools.cpp | 22 | ||||
-rw-r--r-- | src/core/Tools.h | 1 |
12 files changed, 40 insertions, 354 deletions
diff --git a/src/core/DatabaseIcons.cpp b/src/core/DatabaseIcons.cpp deleted file mode 100644 index a284d3842..000000000 --- a/src/core/DatabaseIcons.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2010 Felix Geyer <debfx@fobos.de> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "DatabaseIcons.h" - -#include "core/Config.h" -#include "core/Global.h" - -#include <QDir> -#include <QImageReader> -#include <QPainter> -#include <QPixmapCache> - -DatabaseIcons* DatabaseIcons::m_instance(nullptr); - -namespace -{ - const QString iconDir = QStringLiteral(":/icons/database/"); - QStringList iconList; - - const QString badgeDir = QStringLiteral(":/icons/badges/"); - QStringList badgeList; -} // namespace - -DatabaseIcons::DatabaseIcons() -{ - iconList = QDir(iconDir).entryList(QDir::NoFilter, QDir::Name); - badgeList = QDir(badgeDir).entryList(QDir::NoFilter, QDir::Name); - - // Set this early and once to ensure consistent icon size until app restart - m_compactMode = config()->get(Config::GUI_CompactMode).toBool(); -} - -DatabaseIcons* DatabaseIcons::instance() -{ - if (!m_instance) { - m_instance = new DatabaseIcons(); - } - - return m_instance; -} - -QPixmap DatabaseIcons::icon(int index, IconSize size) -{ - if (index < 0 || index >= count()) { - qWarning("DatabaseIcons::icon: invalid icon index %d", index); - return {}; - } - - auto cacheKey = QString::number(index); - auto icon = m_iconCache.value(cacheKey); - if (icon.isNull()) { - icon.addFile(iconDir + iconList[index]); - icon.addPixmap(icon.pixmap(64)); - m_iconCache.insert(cacheKey, icon); - } - - return icon.pixmap(iconSize(size)); -} - -QPixmap DatabaseIcons::applyBadge(const QPixmap& basePixmap, Badges badgeIndex) -{ - const auto cacheKey = QStringLiteral("badgedicon-%1-%2").arg(basePixmap.cacheKey()).arg(badgeIndex); - QPixmap pixmap = basePixmap; - if (badgeIndex < 0 || badgeIndex >= badgeList.size()) { - qWarning("DatabaseIcons: Out-of-range badge index given to applyBadge: %d", badgeIndex); - } else if (!QPixmapCache::find(cacheKey, &pixmap)) { - int baseSize = basePixmap.width(); - int badgeSize = - baseSize <= iconSize(IconSize::Default) * basePixmap.devicePixelRatio() ? baseSize * 0.6 : baseSize * 0.5; - QPoint badgePos(baseSize - badgeSize, baseSize - badgeSize); - badgePos /= basePixmap.devicePixelRatio(); - - QImageReader reader(badgeDir + badgeList[badgeIndex]); - reader.setScaledSize({badgeSize, badgeSize}); - auto badge = QPixmap::fromImageReader(&reader); - badge.setDevicePixelRatio(basePixmap.devicePixelRatio()); - - QPainter painter(&pixmap); - painter.setCompositionMode(QPainter::CompositionMode_SourceOver); - painter.drawPixmap(badgePos, badge); - - QPixmapCache::insert(cacheKey, pixmap); - } - - return pixmap; -} - -int DatabaseIcons::count() -{ - return iconList.size(); -} - -int DatabaseIcons::iconSize(IconSize size) -{ - switch (size) { - case Medium: - return m_compactMode ? 26 : 30; - case Large: - return m_compactMode ? 30 : 36; - default: - return m_compactMode ? 16 : 22; - } -} diff --git a/src/core/DatabaseIcons.h b/src/core/DatabaseIcons.h deleted file mode 100644 index 2abb8a485..000000000 --- a/src/core/DatabaseIcons.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2010 Felix Geyer <debfx@fobos.de> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef KEEPASSX_DATABASEICONS_H -#define KEEPASSX_DATABASEICONS_H - -#include "core/Global.h" -#include <QIcon> - -class DatabaseIcons -{ -public: - static DatabaseIcons* instance(); - - static constexpr int ExpiredIconIndex = 45; - - enum Badges - { - ShareActive = 0, - ShareInactive, - Expired - }; - - QPixmap icon(int index, IconSize size = IconSize::Default); - QPixmap applyBadge(const QPixmap& basePixmap, Badges badgeIndex); - int count(); - - int iconSize(IconSize size); - -private: - DatabaseIcons(); - - static DatabaseIcons* m_instance; - QHash<QString, QIcon> m_iconCache; - bool m_compactMode; - - Q_DISABLE_COPY(DatabaseIcons) -}; - -inline DatabaseIcons* databaseIcons() -{ - return DatabaseIcons::instance(); -} - -#endif // KEEPASSX_DATABASEICONS_H diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index e386a349d..e7e000c2d 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -19,7 +19,7 @@ #include "Entry.h" #include "core/Config.h" -#include "core/DatabaseIcons.h" +#include "core/Database.h" #include "core/Group.h" #include "core/Metadata.h" #include "core/PasswordHealth.h" @@ -159,40 +159,6 @@ const QString Entry::uuidToHex() const return Tools::uuidToHex(m_uuid); } -QImage Entry::icon() const -{ - if (m_data.customIcon.isNull()) { - return databaseIcons()->icon(m_data.iconNumber).toImage(); - } else { - Q_ASSERT(database()); - - if (database()) { - return database()->metadata()->customIcon(m_data.customIcon); - } else { - return QImage(); - } - } -} - -QPixmap Entry::iconPixmap(IconSize size) const -{ - QPixmap icon(size, size); - if (m_data.customIcon.isNull()) { - icon = databaseIcons()->icon(m_data.iconNumber, size); - } else { - Q_ASSERT(database()); - if (database()) { - icon = database()->metadata()->customIconPixmap(m_data.customIcon, size); - } - } - - if (isExpired()) { - icon = databaseIcons()->applyBadge(icon, DatabaseIcons::Badges::Expired); - } - - return icon; -} - int Entry::iconNumber() const { return m_data.iconNumber; @@ -1217,7 +1183,8 @@ void Entry::setGroup(Group* group) // copy custom icon to the new database if (!iconUuid().isNull() && group->database() && m_group->database()->metadata()->hasCustomIcon(iconUuid()) && !group->database()->metadata()->hasCustomIcon(iconUuid())) { - group->database()->metadata()->addCustomIcon(iconUuid(), icon()); + group->database()->metadata()->addCustomIcon(iconUuid(), + m_group->database()->metadata()->customIcon(iconUuid())); } } } diff --git a/src/core/Entry.h b/src/core/Entry.h index 99c0e6024..1fcd09572 100644 --- a/src/core/Entry.h +++ b/src/core/Entry.h @@ -19,7 +19,7 @@ #ifndef KEEPASSX_ENTRY_H #define KEEPASSX_ENTRY_H -#include <QImage> +#include <QMap> #include <QPointer> #include <QUuid> @@ -80,8 +80,6 @@ public: ~Entry(); const QUuid& uuid() const; const QString uuidToHex() const; - QImage icon() const; - QPixmap iconPixmap(IconSize size = IconSize::Default) const; int iconNumber() const; const QUuid& iconUuid() const; QString foregroundColor() const; diff --git a/src/core/Global.h b/src/core/Global.h index fe51b9b5d..e9a4db739 100644 --- a/src/core/Global.h +++ b/src/core/Global.h @@ -45,13 +45,6 @@ static const auto TRUE_STR = QStringLiteral("true"); static const auto FALSE_STR = QStringLiteral("false"); -enum IconSize -{ - Default, - Medium, - Large -}; - enum class AuthDecision { Undecided, diff --git a/src/core/Group.cpp b/src/core/Group.cpp index 196f230c1..6684d1ab9 100644 --- a/src/core/Group.cpp +++ b/src/core/Group.cpp @@ -20,14 +20,16 @@ #include "config-keepassx.h" #include "core/Config.h" -#include "core/DatabaseIcons.h" -#include "core/Metadata.h" -#include "core/Tools.h" #ifdef WITH_XC_KEESHARE #include "keeshare/KeeShare.h" #endif +#include "core/Global.h" +#include "core/Metadata.h" +#include "core/Tools.h" + +#include <QtConcurrent> #include <QtConcurrentFilter> const int Group::DefaultIconNumber = 48; @@ -123,44 +125,6 @@ QString Group::notes() const return m_data.notes; } -QImage Group::icon() const -{ - if (m_data.customIcon.isNull()) { - return databaseIcons()->icon(m_data.iconNumber).toImage(); - } else { - Q_ASSERT(m_db); - if (m_db) { - return m_db->metadata()->customIcon(m_data.customIcon); - } else { - return QImage(); - } - } -} - -QPixmap Group::iconPixmap(IconSize size) const -{ - QPixmap icon(size, size); - if (m_data.customIcon.isNull()) { - icon = databaseIcons()->icon(m_data.iconNumber, size); - } else { - Q_ASSERT(m_db); - if (m_db) { - icon = m_db->metadata()->customIconPixmap(m_data.customIcon, size); - } - } - - if (isExpired()) { - icon = databaseIcons()->applyBadge(icon, DatabaseIcons::Badges::Expired); - } -#ifdef WITH_XC_KEESHARE - else if (KeeShare::isShared(this)) { - icon = KeeShare::indicatorBadge(this, icon); - } -#endif - - return icon; -} - int Group::iconNumber() const { return m_data.iconNumber; @@ -469,7 +433,7 @@ void Group::setParent(Group* parent, int index) // copy custom icon to the new database if (!iconUuid().isNull() && parent->m_db && m_db->metadata()->hasCustomIcon(iconUuid()) && !parent->m_db->metadata()->hasCustomIcon(iconUuid())) { - parent->m_db->metadata()->addCustomIcon(iconUuid(), icon()); + parent->m_db->metadata()->addCustomIcon(iconUuid(), m_db->metadata()->customIcon(iconUuid())); } } if (m_db != parent->m_db) { diff --git a/src/core/Group.h b/src/core/Group.h index c564d1609..c283a89a2 100644 --- a/src/core/Group.h +++ b/src/core/Group.h @@ -19,7 +19,7 @@ #ifndef KEEPASSX_GROUP_H #define KEEPASSX_GROUP_H -#include <QImage> +#include <QPointer> #include "core/CustomData.h" #include "core/Database.h" @@ -82,8 +82,6 @@ public: const QString uuidToHex() const; QString name() const; QString notes() const; - QImage icon() const; - QPixmap iconPixmap(IconSize size = IconSize::Default) const; int iconNumber() const; const QUuid& iconUuid() const; const TimeInfo& timeInfo() const; diff --git a/src/core/Merger.cpp b/src/core/Merger.cpp index a5f532af2..b7c832951 100644 --- a/src/core/Merger.cpp +++ b/src/core/Merger.cpp @@ -611,8 +611,7 @@ Merger::ChangeList Merger::mergeMetadata(const MergeContext& context) for (const auto& iconUuid : sourceMetadata->customIconsOrder()) { if (!targetMetadata->hasCustomIcon(iconUuid)) { - QImage customIcon = sourceMetadata->customIcon(iconUuid); - targetMetadata->addCustomIcon(iconUuid, customIcon); + targetMetadata->addCustomIcon(iconUuid, sourceMetadata->customIcon(iconUuid)); changes << tr("Adding missing icon %1").arg(QString::fromLatin1(iconUuid.toRfc4122().toHex())); } } diff --git a/src/core/Metadata.cpp b/src/core/Metadata.cpp index f99f42499..8bb0b52e4 100644 --- a/src/core/Metadata.cpp +++ b/src/core/Metadata.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Felix Geyer <debfx@fobos.de> + * Copyright (C) 2021 KeePassXC Team <team@keepassxc.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,7 +18,8 @@ #include "Metadata.h" -#include "core/DatabaseIcons.h" +#include "core/Clock.h" +#include "core/Entry.h" #include "core/Group.h" #include <QApplication> @@ -64,7 +66,6 @@ void Metadata::clear() { init(); m_customIcons.clear(); - m_customIconsRaw.clear(); m_customIconsOrder.clear(); m_customIconsHashes.clear(); m_customData->clear(); @@ -175,33 +176,14 @@ bool Metadata::protectNotes() const return m_data.protectNotes; } -QImage Metadata::customIcon(const QUuid& uuid) const +QByteArray Metadata::customIcon(const QUuid& uuid) const { - return m_customIconsRaw.value(uuid); -} - -QPixmap Metadata::customIconPixmap(const QUuid& uuid, IconSize size) const -{ - if (!hasCustomIcon(uuid)) { - return {}; - } - return m_customIcons.value(uuid).pixmap(databaseIcons()->iconSize(size)); -} - -QHash<QUuid, QPixmap> Metadata::customIconsPixmaps(IconSize size) const -{ - QHash<QUuid, QPixmap> result; - - for (const QUuid& uuid : m_customIconsOrder) { - result.insert(uuid, customIconPixmap(uuid, size)); - } - - return result; + return m_customIcons.value(uuid); } bool Metadata::hasCustomIcon(const QUuid& uuid) const { - return m_customIconsRaw.contains(uuid); + return m_customIcons.contains(uuid); } QList<QUuid> Metadata::customIconsOrder() const @@ -357,32 +339,19 @@ void Metadata::setProtectNotes(bool value) set(m_data.protectNotes, value); } -void Metadata::addCustomIcon(const QUuid& uuid, const QImage& image) +void Metadata::addCustomIcon(const QUuid& uuid, const QByteArray& iconData) { Q_ASSERT(!uuid.isNull()); - Q_ASSERT(!m_customIconsRaw.contains(uuid)); + Q_ASSERT(!m_customIcons.contains(uuid)); - m_customIconsRaw[uuid] = image; + m_customIcons[uuid] = iconData; // remove all uuids to prevent duplicates in release mode m_customIconsOrder.removeAll(uuid); m_customIconsOrder.append(uuid); // Associate image hash to uuid - QByteArray hash = hashImage(image); + QByteArray hash = hashIcon(iconData); m_customIconsHashes[hash] = uuid; - Q_ASSERT(m_customIconsRaw.count() == m_customIconsOrder.count()); - - // TODO: This check can go away when we move all QIcon handling outside of core - // On older versions of Qt, loading a QPixmap from QImage outside of a GUI - // environment causes ASAN to fail and crash on nullptr violation - static bool isGui = qApp->inherits("QGuiApplication"); - if (isGui) { - // Generate QIcon with pre-baked resolutions - auto basePixmap = QPixmap::fromImage(image.scaled(64, 64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); - QIcon icon(basePixmap); - m_customIcons.insert(uuid, icon); - } else { - m_customIcons.insert(uuid, QIcon()); - } + Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count()); emitModified(); } @@ -390,24 +359,23 @@ void Metadata::addCustomIcon(const QUuid& uuid, const QImage& image) void Metadata::removeCustomIcon(const QUuid& uuid) { Q_ASSERT(!uuid.isNull()); - Q_ASSERT(m_customIconsRaw.contains(uuid)); + Q_ASSERT(m_customIcons.contains(uuid)); // Remove hash record only if this is the same uuid - QByteArray hash = hashImage(m_customIconsRaw[uuid]); + QByteArray hash = hashIcon(m_customIcons[uuid]); if (m_customIconsHashes.contains(hash) && m_customIconsHashes[hash] == uuid) { m_customIconsHashes.remove(hash); } m_customIcons.remove(uuid); - m_customIconsRaw.remove(uuid); m_customIconsOrder.removeAll(uuid); - Q_ASSERT(m_customIconsRaw.count() == m_customIconsOrder.count()); + Q_ASSERT(m_customIcons.count() == m_customIconsOrder.count()); emitModified(); } -QUuid Metadata::findCustomIcon(const QImage& candidate) +QUuid Metadata::findCustomIcon(const QByteArray& candidate) { - QByteArray hash = hashImage(candidate); + QByteArray hash = hashIcon(candidate); return m_customIconsHashes.value(hash, QUuid()); } @@ -422,14 +390,9 @@ void Metadata::copyCustomIcons(const QSet<QUuid>& iconList, const Metadata* othe } } -QByteArray Metadata::hashImage(const QImage& image) +QByteArray Metadata::hashIcon(const QByteArray& iconData) { -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - auto data = QByteArray(reinterpret_cast<const char*>(image.bits()), static_cast<int>(image.sizeInBytes())); -#else - auto data = QByteArray(reinterpret_cast<const char*>(image.bits()), image.byteCount()); -#endif - return QCryptographicHash::hash(data, QCryptographicHash::Md5); + return QCryptographicHash::hash(iconData, QCryptographicHash::Md5); } void Metadata::setRecycleBinEnabled(bool value) diff --git a/src/core/Metadata.h b/src/core/Metadata.h index 51276ec61..1b87ec2ad 100644 --- a/src/core/Metadata.h +++ b/src/core/Metadata.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2010 Felix Geyer <debfx@fobos.de> + * Copyright (C) 2021 KeePassXC Team <team@keepassxc.org> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +20,7 @@ #define KEEPASSX_METADATA_H #include <QDateTime> -#include <QIcon> +#include <QHash> #include <QPointer> #include <QUuid> @@ -78,10 +79,8 @@ public: bool protectPassword() const; bool protectUrl() const; bool protectNotes() const; - QImage customIcon(const QUuid& uuid) const; + QByteArray customIcon(const QUuid& uuid) const; bool hasCustomIcon(const QUuid& uuid) const; - QPixmap customIconPixmap(const QUuid& uuid, IconSize size = IconSize::Default) const; - QHash<QUuid, QPixmap> customIconsPixmaps(IconSize size = IconSize::Default) const; QList<QUuid> customIconsOrder() const; bool recycleBinEnabled() const; Group* recycleBin(); @@ -117,10 +116,10 @@ public: void setProtectPassword(bool value); void setProtectUrl(bool value); void setProtectNotes(bool value); - void addCustomIcon(const QUuid& uuid, const QImage& image); + void addCustomIcon(const QUuid& uuid, const QByteArray& iconData); void removeCustomIcon(const QUuid& uuid); void copyCustomIcons(const QSet<QUuid>& iconList, const Metadata* otherMetadata); - QUuid findCustomIcon(const QImage& candidate); + QUuid findCustomIcon(const QByteArray& candidate); void setRecycleBinEnabled(bool value); void setRecycleBin(Group* group); void setRecycleBinChanged(const QDateTime& value); @@ -148,13 +147,12 @@ private: template <class P, class V> bool set(P& property, const V& value); template <class P, class V> bool set(P& property, const V& value, QDateTime& dateTime); - QByteArray hashImage(const QImage& image); + QByteArray hashIcon(const QByteArray& iconData); MetadataData m_data; - QHash<QUuid, QIcon> m_customIcons; - QHash<QUuid, QImage> m_customIconsRaw; QList<QUuid> m_customIconsOrder; + QHash<QUuid, QByteArray> m_customIcons; QHash<QByteArray, QUuid> m_customIconsHashes; QPointer<Group> m_recycleBin; diff --git a/src/core/Tools.cpp b/src/core/Tools.cpp index 7c6d52a59..61c8cb6e2 100644 --- a/src/core/Tools.cpp +++ b/src/core/Tools.cpp @@ -24,9 +24,11 @@ #include "core/Clock.h" +#include <QCoreApplication> #include <QElapsedTimer> +#include <QEventLoop> #include <QFileInfo> -#include <QImageReader> +#include <QIODevice> #include <QLocale> #include <QMetaProperty> #include <QRegularExpression> @@ -172,24 +174,6 @@ namespace Tools } } - QString imageReaderFilter() - { - const QList<QByteArray> formats = QImageReader::supportedImageFormats(); - QStringList formatsStringList; - - for (const QByteArray& format : formats) { - for (char codePoint : format) { - if (!QChar(codePoint).isLetterOrNumber()) { - continue; - } - } - - formatsStringList.append("*." + QString::fromLatin1(format).toLower()); - } - - return formatsStringList.join(" "); - } - bool isHex(const QByteArray& ba) { for (const uchar c : ba) { diff --git a/src/core/Tools.h b/src/core/Tools.h index cf3b3593d..2c22e7427 100644 --- a/src/core/Tools.h +++ b/src/core/Tools.h @@ -32,7 +32,6 @@ namespace Tools QString humanReadableFileSize(qint64 bytes, quint32 precision = 2); bool readFromDevice(QIODevice* device, QByteArray& data, int size = 16384); bool readAllFromDevice(QIODevice* device, QByteArray& data); - QString imageReaderFilter(); bool isHex(const QByteArray& ba); bool isBase64(const QByteArray& ba); void sleep(int ms); |