diff --git a/libs/resources/CMakeLists.txt b/libs/resources/CMakeLists.txt index 5f34adfff3..c6677a79de 100644 --- a/libs/resources/CMakeLists.txt +++ b/libs/resources/CMakeLists.txt @@ -1,65 +1,66 @@ include_directories(${QUAZIP_INCLUDE_DIRS}) add_subdirectory(tests) set(kritaresources_LIB_SRCS KisResourceCacheDb.cpp KisResourceLoader.cpp KisResourceLoaderRegistry.cpp KisResourceLocator.cpp KisResourceStorage.cpp KisResourceModel.cpp KisResourceGridProxyModel.cpp KisTagFilterResourceProxyModel.cpp KisResourceModelProvider.cpp KisResourceTypeModel.cpp + KisStorageModel.cpp KisStoragePlugin.cpp KisAbrStorage.cpp KisAslStorage.cpp KisBundleStorage.cpp KisFolderStorage.cpp KisMemoryStorage.cpp KisTag.cpp KisTagModel.cpp KoResource.cpp KoResourceBundle.cpp KoResourceBundleManifest.cpp KoMD5Generator.cpp KoHashGeneratorProvider.cpp KoResourcePaths.cpp kconfigini.cpp kconfigdata.cpp kconfigbackend.cpp ) qt5_add_resources(kritaresources_LIB_SRCS sql.qrc) add_library(kritaresources SHARED ${kritaresources_LIB_SRCS}) generate_export_header(kritaresources BASE_NAME kritaresources) target_link_libraries(kritaresources PUBLIC Qt5::Core Qt5::Widgets PRIVATE Qt5::Sql kritaversion kritaglobal kritaplugin kritastore KF5::ConfigCore KF5::CoreAddons KF5::I18n ${QUAZIP_LIBRARIES} ) set_target_properties(kritaresources PROPERTIES VERSION ${GENERIC_KRITA_LIB_VERSION} SOVERSION ${GENERIC_KRITA_LIB_SOVERSION} ) install(TARGETS kritaresources ${INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/libs/resources/KisResourceTypeModel.cpp b/libs/resources/KisResourceTypeModel.cpp index 91c29349d5..0121d4d2a6 100644 --- a/libs/resources/KisResourceTypeModel.cpp +++ b/libs/resources/KisResourceTypeModel.cpp @@ -1,124 +1,121 @@ /* * Copyright (c) 2018 boud * * 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 of the License, or * (at your option) any later version. * * 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, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "KisResourceTypeModel.h" #include #include "KisResourceLoader.h" #include "KisResourceLoaderRegistry.h" struct KisResourceTypeModel::Private { int cachedRowCount {-1}; QSqlQuery query; }; KisResourceTypeModel::KisResourceTypeModel(QObject *parent) : QAbstractTableModel(parent) , d(new Private) { prepareQuery(); } KisResourceTypeModel::~KisResourceTypeModel() { delete d; } int KisResourceTypeModel::rowCount(const QModelIndex &/*parent*/) const { if (d->cachedRowCount < 0) { QSqlQuery q; q.prepare("SELECT count(*)\n" "FROM resource_types\n"); q.exec(); q.first(); const_cast(this)->d->cachedRowCount = q.value(0).toInt(); - - qDebug() << "KisResourceTypeModel::rowCount()" << d->cachedRowCount; } return d->cachedRowCount; } int KisResourceTypeModel::columnCount(const QModelIndex &/*parent*/) const { return 3; } QVariant KisResourceTypeModel::data(const QModelIndex &index, int role) const { - QVariant v; if (!index.isValid()) return v; if (index.row() > rowCount()) return v; if (index.column() > (int)Name) return v; bool pos = d->query.seek(index.row()); if (pos) { QString id = d->query.value("id").toString(); QString resourceType = d->query.value("name").toString(); QString name = resourceType; QVector loaders = KisResourceLoaderRegistry::instance()->resourceTypeLoaders(resourceType); Q_ASSERT(loaders.size() > 0); name = loaders.first()->name(); switch(role) { case Qt::DisplayRole: { switch(index.column()) { case Id: return id; case ResourceType: return resourceType; case Name: default: return name; } } case Qt::UserRole + Id: return id; case Qt::UserRole + ResourceType: return resourceType; case Qt::UserRole + Name: return name; default: ; } } return v; } bool KisResourceTypeModel::prepareQuery() { beginResetModel(); bool r = d->query.prepare("SELECT id\n" - ", name\n" - "FROM resource_types\n"); + ", name\n" + "FROM resource_types\n"); if (!r) { qWarning() << "Could not prepare KisResourceTypeModel query" << d->query.lastError(); } r = d->query.exec(); if (!r) { qWarning() << "Could not execute KisResourceTypeModel query" << d->query.lastError(); } d->cachedRowCount = -1; endResetModel(); return r; } diff --git a/libs/resources/KisStorageModel.cpp b/libs/resources/KisStorageModel.cpp new file mode 100644 index 0000000000..0683ab401a --- /dev/null +++ b/libs/resources/KisStorageModel.cpp @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2019 boud + * + * 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 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "KisStorageModel.h" + +#include + +struct KisStorageModel::Private { + int cachedRowCount {-1}; + QSqlQuery query; +}; + +KisStorageModel::KisStorageModel(QObject *parent) + : QAbstractTableModel(parent) + , d(new Private()) +{ + +} + +KisStorageModel::~KisStorageModel() +{ + +} + +int KisStorageModel::rowCount(const QModelIndex & /*parent*/) const +{ + if (d->cachedRowCount < 0) { + QSqlQuery q; + q.prepare("SELECT count(*)\n" + "FROM storages\n"); + q.exec(); + q.first(); + + const_cast(this)->d->cachedRowCount = q.value(0).toInt(); + } + return d->cachedRowCount; +} + +int KisStorageModel::columnCount(const QModelIndex &/*parent*/) const +{ + return 6; +} + +QVariant KisStorageModel::data(const QModelIndex &index, int role) const +{ + QVariant v; + if (!index.isValid()) return v; + if (index.row() > rowCount()) return v; + if (index.column() > (int)Active) return v; + + bool pos = d->query.seek(index.row()); + + if (pos) { + switch(role) { + case Qt::DisplayRole: + { + switch(index.column()) { + case Id: + return d->query.value("id"); + case StorageType: + return d->query.value("storage_type"); + case Location: + return d->query.value("location"); + case TimeStamp: + return d->query.value("timestamp"); + case PreInstalled: + return d->query.value("pre_installed"); + case Active: + return d->query.value("active"); + default: + return v; + } + } + case Qt::UserRole + Id: + return d->query.value("id"); + case Qt::UserRole + StorageType: + return d->query.value("storage_type"); + case Qt::UserRole + Location: + return d->query.value("location"); + case Qt::UserRole + TimeStamp: + return d->query.value("timestamp"); + case Qt::UserRole + PreInstalled: + return d->query.value("pre_installed"); + case Qt::UserRole + Active: + return d->query.value("active"); + default: + ; + } + } + return v; + +} + +bool KisStorageModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (index.isValid()) { + if (role == Qt::CheckStateRole) { + QSqlQuery q; + bool r = q.prepare("UPDATE storages\n" + "SET active = :active\n" + "WHERE id = :id\n"); + q.bindValue(":active", value); + q.bindValue(":id", index.data(Qt::UserRole + Id)); + if (!r) { + qWarning() << "Could not prepare KisStorageModel update query" << d->query.lastError(); + return false; + } + r = q.exec(); + if (!r) { + qWarning() << "Could not execute KisStorageModel update query" << d->query.lastError(); + return false; + } + + } + } + QAbstractTableModel::setData(index, value, role); + return prepareQuery(); +} + +Qt::ItemFlags KisStorageModel::flags(const QModelIndex &index) const +{ + return QAbstractTableModel::flags(index) | Qt::ItemIsEditable; +} + +bool KisStorageModel::prepareQuery() +{ + beginResetModel(); + bool r = d->query.prepare("SELECT storages.id\n" + ", storage_types.name as storage_type\n" + ", location\n" + ", timestamp\n" + ", pre_installed\n" + ", active\n" + "FROM storages\n" + ", storage_types\n" + "WHERE storages.storage_type_id = storage_types.id\n"); + if (!r) { + qWarning() << "Could not prepare KisStorageModel query" << d->query.lastError(); + } + r = d->query.exec(); + if (!r) { + qWarning() << "Could not execute KisStorageModel query" << d->query.lastError(); + } + d->cachedRowCount = -1; + endResetModel(); + return r; +} diff --git a/libs/resources/KisStorageModel.h b/libs/resources/KisStorageModel.h new file mode 100644 index 0000000000..2b8315129e --- /dev/null +++ b/libs/resources/KisStorageModel.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2019 boud + * + * 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 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef KISSTORAGEMODEL_H +#define KISSTORAGEMODEL_H + +#include +#include +#include + +#include "kritaresources_export.h" + +class KRITARESOURCES_EXPORT KisStorageModel : public QAbstractTableModel +{ +public: + + enum Columns { + Id = 0, + StorageType, + Location, + TimeStamp, + PreInstalled, + Active + }; + + KisStorageModel(QObject *parent = 0); + ~KisStorageModel() override; + + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + +private: + + bool prepareQuery(); + + struct Private; + QScopedPointer d; + + +}; + +#endif // KISSTORAGEMODEL_H diff --git a/libs/resources/tests/CMakeLists.txt b/libs/resources/tests/CMakeLists.txt index 59e0665ecc..000a31510c 100644 --- a/libs/resources/tests/CMakeLists.txt +++ b/libs/resources/tests/CMakeLists.txt @@ -1,25 +1,26 @@ add_definitions(-DFILES_DEST_DIR="${CMAKE_CURRENT_BINARY_DIR}/data/") set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} ) include(ECMAddTests) include(KritaAddBrokenUnitTest) macro_add_unittest_definitions() ecm_add_tests( TestResourceCacheDb TestResourceLoaderRegistry TestResourceLocator TestResourceStorage TestFolderStorage TestMemoryStorage TestTag TestBundleStorage TestResourceModel TestResourceProxyModel TestTagFilterResourceProxyModel TestTagModel TestResourceTypeModel + TestStorageModel NAME_PREFIX "libs-kritaresources-" LINK_LIBRARIES kritaglobal kritaplugin kritaresources kritaversion KF5::ConfigCore Qt5::Sql Qt5::Test) diff --git a/libs/resources/tests/TestStorageModel.cpp b/libs/resources/tests/TestStorageModel.cpp new file mode 100644 index 0000000000..da5b670008 --- /dev/null +++ b/libs/resources/tests/TestStorageModel.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2018 boud + * + * 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 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "TestStorageModel.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +#ifndef FILES_DATA_DIR +#error "FILES_DATA_DIR not set. A directory with the data used for testing installing resources" +#endif + +#ifndef FILES_DEST_DIR +#error "FILES_DEST_DIR not set. A directory where data will be written to for testing installing resources" +#endif + + +void TestStorageModel::initTestCase() +{ + ResourceTestHelper::initTestDb(); + ResourceTestHelper::createDummyLoaderRegistry(); + + m_srcLocation = QString(FILES_DATA_DIR); + QVERIFY2(QDir(m_srcLocation).exists(), m_srcLocation.toUtf8()); + + m_dstLocation = QString(FILES_DEST_DIR); + ResourceTestHelper::cleanDstLocation(m_dstLocation); + + KConfigGroup cfg(KSharedConfig::openConfig(), ""); + cfg.writeEntry(KisResourceLocator::resourceLocationKey, m_dstLocation); + + m_locator = KisResourceLocator::instance(); + + if (!KisResourceCacheDb::initialize(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))) { + qDebug() << "Could not initialize KisResourceCacheDb on" << QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + } + QVERIFY(KisResourceCacheDb::isValid()); + + KisResourceLocator::LocatorError r = m_locator->initialize(m_srcLocation); + if (!m_locator->errorMessages().isEmpty()) qDebug() << m_locator->errorMessages(); + + QVERIFY(r == KisResourceLocator::LocatorError::Ok); + QVERIFY(QDir(m_dstLocation).exists()); +} + + +void TestStorageModel::testRowCount() +{ + QSqlQuery q; + QVERIFY(q.prepare("SELECT count(*)\n" + "FROM storages")); + QVERIFY(q.exec()); + q.first(); + int rowCount = q.value(0).toInt(); + + KisStorageModel storageModel; + QCOMPARE(storageModel.rowCount(), rowCount); +} + +void TestStorageModel::testSetActive() +{ + KisStorageModel storageModel; + for (int i = 0; i < storageModel.rowCount(); ++i) { + QModelIndex idx = storageModel.index(i, 0); + + storageModel.setData(idx, QVariant(true), Qt::CheckStateRole); + QVERIFY(idx.data(Qt::UserRole + KisStorageModel::Active).toBool() == true); + + storageModel.setData(idx, QVariant(false), Qt::CheckStateRole); + + idx = storageModel.index(i, 0); + QVERIFY(idx.data(Qt::UserRole + KisStorageModel::Active).toBool() == false); + + } +} + + +void TestStorageModel::cleanupTestCase() +{ + ResourceTestHelper::rmTestDb(); + ResourceTestHelper::cleanDstLocation(m_dstLocation); +} + + + + +QTEST_MAIN(TestStorageModel) + diff --git a/libs/resources/tests/TestStorageModel.h b/libs/resources/tests/TestStorageModel.h new file mode 100644 index 0000000000..bbd0f6e498 --- /dev/null +++ b/libs/resources/tests/TestStorageModel.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018 boud + * + * 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 of the License, or + * (at your option) any later version. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#ifndef TESTRESOURCETYPEMODEL_H +#define TESTRESOURCETYPEMODEL_H + +#include +class KisResourceLocator; + +class TestStorageModel : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void testRowCount(); + void testSetActive(); + void cleanupTestCase(); +private: + + QString m_srcLocation; + QString m_dstLocation; + KisResourceLocator *m_locator; +}; + +#endif