File indexing completed on 2025-01-26 04:15:00

0001 /*
0002  * Copyright (C) 2016 Dan Leinir Turthra Jensen <admin@leinir.dk>
0003  *
0004  * This library is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU Lesser General Public
0006  * License as published by the Free Software Foundation; either
0007  * version 2.1 of the License, or (at your option) version 3, or any
0008  * later version accepted by the membership of KDE e.V. (or its
0009  * successor approved by the membership of KDE e.V.), which shall
0010  * act as a proxy defined in Section 6 of version 3 of the license.
0011  *
0012  * This library is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015  * Lesser General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU Lesser General Public
0018  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0019  *
0020  */
0021 
0022 #include "PeruseConfig.h"
0023 
0024 #include <KFileMetaData/UserMetaData>
0025 #include <KConfig>
0026 #include <KConfigGroup>
0027 #include <KNSCore/Engine>
0028 
0029 #include <QTimer>
0030 #include <QFile>
0031 #include <QFileInfo>
0032 #include <QImageReader>
0033 #include <QMimeDatabase>
0034 
0035 class PeruseConfig::Private
0036 {
0037 public:
0038     Private()
0039         : config("peruserc")
0040     {};
0041     KConfig config;
0042 };
0043 
0044 PeruseConfig::PeruseConfig(QObject* parent)
0045     : QObject(parent)
0046     , d(new Private)
0047 {
0048     QStringList locations = d->config.group("general").readEntry("book locations", QStringList());
0049     if(locations.count() < 1)
0050     {
0051         locations = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
0052         locations << QStandardPaths::standardLocations(QStandardPaths::DownloadLocation);
0053         locations << QString("%1/comics").arg(QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).first());
0054         d->config.group("general").writeEntry("book locations", locations);
0055         d->config.group("general").writeEntry("animate jump areas", true);
0056         d->config.sync();
0057     }
0058 }
0059 
0060 PeruseConfig::~PeruseConfig()
0061 {
0062     delete d;
0063 }
0064 
0065 void PeruseConfig::bookOpened(QString path)
0066 {
0067     QStringList recent = recentlyOpened();
0068 
0069     int i = recent.indexOf(path);
0070     if(i == 0)
0071     {
0072         // This is already first, don't do work we don't need to, because that's just silly
0073         return;
0074     }
0075     else
0076     {
0077         recent.removeAll(path);
0078         recent.prepend(path);
0079     }
0080     d->config.group("general").writeEntry("recently opened", recent);
0081     d->config.sync();
0082     emit recentlyOpenedChanged();
0083 }
0084 
0085 QStringList PeruseConfig::recentlyOpened() const
0086 {
0087     QStringList recent = d->config.group("general").readEntry("recently opened", QStringList());
0088     QStringList actualRecent;
0089     while(recent.count() > 0) {
0090         QString current = recent.takeFirst();
0091         if(QFile::exists(current)) {
0092             actualRecent.append(current);
0093         }
0094     }
0095     return actualRecent;
0096 }
0097 
0098 void PeruseConfig::addBookLocation(const QString& location)
0099 {
0100     if(location.startsWith("file://"))
0101     {
0102 #ifdef Q_OS_WIN
0103         QString newLocation = location.mid(8);
0104 #else
0105         QString newLocation = location.mid(7);
0106 #endif
0107         const QStringList locations = bookLocations();
0108         // First, get rid of all the entries which start with the newly added location, because that's silly
0109         QStringList newLocations;
0110         bool alreadyInThere = false;
0111         for(const QString& entry : locations) {
0112             if(!entry.startsWith(newLocation))
0113             {
0114                 newLocations.append(entry);
0115             }
0116             if(newLocation.startsWith(entry))
0117             {
0118                 alreadyInThere = true;
0119             }
0120         }
0121         if(alreadyInThere)
0122         {
0123             // Don't be silly, don't add a new location if it's already covered by something more high level...
0124             emit showMessage("Attempted to add a new location to the list of search folders which is a sub-folder to something already in the list.");
0125             return;
0126         }
0127         newLocations.append(newLocation);
0128         d->config.group("general").writeEntry("book locations", newLocations);
0129         d->config.sync();
0130         emit bookLocationsChanged();
0131     }
0132 }
0133 
0134 void PeruseConfig::removeBookLocation(const QString& location)
0135 {
0136     QStringList locations = bookLocations();
0137     locations.removeAll(location);
0138     d->config.group("general").writeEntry("book locations", locations);
0139     d->config.sync();
0140     QTimer::singleShot(100, this, SIGNAL(bookLocationsChanged()));
0141 }
0142 
0143 QStringList PeruseConfig::bookLocations() const
0144 {
0145     QStringList locations = d->config.group("general").readEntry("book locations", QStringList());
0146     return locations;
0147 }
0148 
0149 QString PeruseConfig::newstuffLocation() const
0150 {
0151     const QStringList locations = KNSCore::Engine::configSearchLocations();
0152     QString knsrc;
0153     for (const QString& location : locations) {
0154         knsrc = QString::fromLocal8Bit("%1/peruse.knsrc").arg(location);
0155         if (QFile(knsrc).exists()) {
0156             break;
0157         }
0158     }
0159     if(qEnvironmentVariableIsSet("APPDIR"))
0160     {
0161         // Because appimage install happens into /app/usr...
0162         knsrc = knsrc.prepend("/usr").prepend(qgetenv("APPDIR"));
0163     }
0164     return knsrc;
0165 }
0166 
0167 bool PeruseConfig::animateJumpAreas() const
0168 {
0169     return d->config.group("general").readEntry("animate jump areas", true);
0170 }
0171 
0172 void PeruseConfig::setAnimateJumpAreas(bool animate)
0173 {
0174     bool animateJumpAreasCurrentVal = animateJumpAreas();
0175 
0176     if(animateJumpAreasCurrentVal != animate) {
0177         d->config.group("general").writeEntry("animate jump areas", animate);
0178         d->config.sync();
0179         emit animateJumpAreasChanged();
0180     }
0181 }
0182 
0183 QString PeruseConfig::homeDir() const
0184 {
0185     return QStandardPaths::standardLocations(QStandardPaths::HomeLocation).first();
0186 }
0187 
0188 void PeruseConfig::setFilesystemProperty(QString fileName, QString propertyName, QString value)
0189 {
0190     KFileMetaData::UserMetaData data(fileName);
0191     if (propertyName == "rating") {
0192         data.setRating(value.toInt());
0193     } else if (propertyName == "tags") {
0194         data.setTags(value.split(","));
0195     } else if (propertyName == "comment") {
0196         data.setUserComment(value);
0197     } else {
0198         data.setAttribute(QString("peruse.").append(propertyName), value);
0199     }
0200 }
0201 
0202 QString PeruseConfig::getFilesystemProperty(QString fileName, QString propertyName)
0203 {
0204     QString value;
0205     KFileMetaData::UserMetaData data(fileName);
0206     if (propertyName == "rating") {
0207         value = QString::number(data.rating());
0208     } else if (propertyName == "tags") {
0209         value = data.tags().join(",");
0210     } else if (propertyName == "comment") {
0211         value = data.userComment();
0212     } else if (propertyName == "bytes") {
0213         value = QString::number(QFileInfo(fileName).size());
0214     } else if (propertyName == "mimetype") {
0215         QMimeDatabase db;
0216         QMimeType mime = db.mimeTypeForFile(fileName);
0217         value = mime.name();
0218     } else {
0219         value = data.attribute(QString("peruse.").append(propertyName));
0220     }
0221     return value;
0222 }
0223 
0224 QStringList PeruseConfig::supportedImageFormats() const
0225 {
0226     QStringList formats;
0227     for (const QByteArray& format : QImageReader::supportedImageFormats()) {
0228         formats << format;
0229     }
0230     return formats;
0231 }