KisResourceLocator.cpp 6.05 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * Copyright (C) 2018 Boudewijn Rempt <boud@valdyas.org>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "KisResourceLocator.h"

22
#include <QDebug>
23 24
#include <QList>
#include <QDir>
25
#include <QDirIterator>
26 27
#include <QFileInfo>
#include <QMessageBox>
28
#include <QVersionNumber>
29 30 31 32 33 34

#include <kconfig.h>
#include <kconfiggroup.h>
#include <ksharedconfig.h>
#include <klocalizedstring.h>

35
#include <KritaVersionWrapper.h>
36
#include "KoResourcePaths.h"
37
#include "KisResourceStorage.h"
38
#include "KisResourceCacheDb.h"
39 40

const QString KisResourceLocator::resourceLocationKey {"ResourceDirectory"};
41 42


43 44 45 46 47 48 49 50 51 52 53
const QStringList KisResourceLocator::resourceTypeFolders = QStringList()
        << "tags"
        << "asl"
        << "bundles"
        << "brushes"
        << "gradients"
        << "paintoppresets"
        << "palettes"
        << "patterns"
        << "taskset"
        << "workspaces"
54
        << "symbols";
55

56 57
class KisResourceLocator::Private {
public:
58 59 60
    QString resourceLocation;
    QList<KisResourceStorageSP> storages;
    QStringList errorMessages;
61 62 63 64 65 66 67 68 69
};

KisResourceLocator::KisResourceLocator()
    : d(new Private())
{
}

KisResourceLocator::~KisResourceLocator()
{
70 71
}

72
KisResourceLocator::LocatorError KisResourceLocator::initialize(const QString &installationResourcesLocation)
73
{
74 75
    InitalizationStatus initalizationStatus = InitalizationStatus::Unknown;

76 77 78 79 80 81 82
    KConfigGroup cfg(KSharedConfig::openConfig(), "");
    d->resourceLocation = cfg.readEntry(resourceLocationKey, QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));

    QFileInfo fi(d->resourceLocation);

    if (!fi.exists()) {
        if (!QDir().mkpath(d->resourceLocation)) {
83
            d->errorMessages << i18n("1. Could not create the resource location at %1.", d->resourceLocation);
84 85
            return LocatorError::CannotCreateLocation;
        }
86
        initalizationStatus = InitalizationStatus::FirstRun;
87 88 89
    }

    if (!fi.isWritable()) {
90
        d->errorMessages << i18n("2. The resource location at %1 is not writable.", d->resourceLocation);
91 92 93
        return LocatorError::LocationReadOnly;
    }

94
    // Check whether we're updating from an older version
95 96 97 98
    if (initalizationStatus != InitalizationStatus::FirstRun) {
        QFile fi(d->resourceLocation + '/' + "KRITA_RESOURCE_VERSION");
        if (!fi.exists()) {
            initalizationStatus = InitalizationStatus::FirstUpdate;
99 100
        }
        else {
101 102 103 104 105 106 107 108 109
            fi.open(QFile::ReadOnly);
            QVersionNumber resource_version = QVersionNumber::fromString(QString::fromUtf8(fi.readAll()));
            QVersionNumber krita_version = QVersionNumber::fromString(KritaVersionWrapper::versionString());
            if (krita_version > resource_version) {
                initalizationStatus = InitalizationStatus::Updating;
            }
            else {
                initalizationStatus = InitalizationStatus::Initialized;
            }
110 111 112 113 114
        }
    }

    if (initalizationStatus != InitalizationStatus::Initialized) {
        KisResourceLocator::LocatorError res = firstTimeInstallation(initalizationStatus, installationResourcesLocation);
115 116 117
        if (res != LocatorError::Ok) {
            return res;
        }
118
        initalizationStatus = InitalizationStatus::Initialized;
119 120
    }

121 122 123 124 125 126 127
    // Add the folder
    d->storages.append(QSharedPointer<KisResourceStorage>::create(d->resourceLocation));

    // And add bundles and adobe libraries
    QStringList filters = QStringList() << "*.bundle" << "*.abr" << "*.asl";
    QDirIterator iter(d->resourceLocation, filters, QDir::Files, QDirIterator::Subdirectories);
    while (iter.hasNext()) {
128
        iter.next();
129 130 131
        d->storages.append(QSharedPointer<KisResourceStorage>::create(iter.filePath()));
    }

132
    return LocatorError::Ok;
133 134
}

135 136 137 138 139
QStringList KisResourceLocator::errorMessages() const
{
    return d->errorMessages;
}

140
KisResourceLocator::LocatorError KisResourceLocator::firstTimeInstallation(InitalizationStatus initalizationStatus, const QString &installationResourcesLocation)
141
{
142 143
    Q_UNUSED(initalizationStatus);

144
    Q_FOREACH(const QString &folder, resourceTypeFolders) {
145 146
        QDir dir(d->resourceLocation + '/' + folder + '/');
        if (!dir.exists()) {
147
            if (!QDir().mkpath(d->resourceLocation + '/' + folder + '/')) {
148
                d->errorMessages << i18n("3. Could not create the resource location at %1.", dir.path());
149 150 151 152
                return LocatorError::CannotCreateLocation;
            }
        }
    }
153

154
    Q_FOREACH(const QString &folder, resourceTypeFolders) {
155
        QDir dir(installationResourcesLocation + '/' + folder + '/');
156
        if (dir.exists()) {
157
            Q_FOREACH(const QString &entry, dir.entryList(QDir::Files | QDir::Readable)) {
158
                QFile f(dir.canonicalPath() + '/'+ entry);
159 160 161 162 163 164 165 166
                bool r = f.copy(d->resourceLocation + '/' + folder + '/' + entry);
                if (!r) {
                    d->errorMessages << "Could not copy resource" << f.fileName() << "to the resource folder";
                }
            }
        }
    }

167
    QFile f(d->resourceLocation + '/' + "KRITA_RESOURCE_VERSION");
168 169 170 171 172 173 174
    f.open(QFile::WriteOnly);
    f.write(KritaVersionWrapper::versionString().toUtf8());
    f.close();

    return LocatorError::Ok;
}

175
bool KisResourceLocator::synchronizeDb()
176
{
177 178 179 180
    Q_FOREACH(const KisResourceStorageSP storage, d->storages) {
        qDebug() << "Storage" << storage->location() << storage->valid();
    }
    return true;
181
}