File indexing completed on 2024-05-12 15:59:03

0001 /*
0002  * SPDX-FileCopyrightText: 2016 Boudewijn Rempt <boud@valdyas.org>
0003  *
0004  * SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 #include "KisMimeDatabase.h"
0007 
0008 #include <QMimeDatabase>
0009 #include <QMimeType>
0010 #include <QFileInfo>
0011 #include <kis_debug.h>
0012 
0013 #include <klocalizedstring.h>
0014 
0015 QList<KisMimeDatabase::KisMimeType> KisMimeDatabase::s_mimeDatabase;
0016 #ifdef Q_OS_ANDROID
0017 static QString sanitizeSuffix(const QString &suffix)
0018 {
0019     return suffix.split(QLatin1Char(' ')).first();
0020 }
0021 #endif
0022 QString KisMimeDatabase::mimeTypeForFile(const QString &file, bool checkExistingFiles)
0023 {
0024     fillMimeData();
0025 
0026     QFileInfo fi(file);
0027     QString suffix = fi.suffix().toLower();
0028 
0029 #ifdef Q_OS_ANDROID
0030     // HACK: on Android we can save as .kra with no extension or as something like:
0031     // "untitled.kra (1)", (1) being added by the SAF because we can't overwrite the duplicate.
0032     // So, we need to be able to remove that number and get extension. If there is no extension,
0033     // perhaps try "kra"
0034     suffix = sanitizeSuffix(suffix);
0035     if (suffix.isEmpty())
0036         suffix = "kra";
0037 #endif
0038 
0039     Q_FOREACH(const KisMimeDatabase::KisMimeType &mimeType, s_mimeDatabase) {
0040         if (mimeType.suffixes.contains(suffix)) {
0041             dbgPlugins << "mimeTypeForFile(). KisMimeDatabase returned" << mimeType.mimeType << "for" << file;
0042             return mimeType.mimeType;
0043         }
0044     }
0045 
0046     QMimeDatabase db;
0047     QMimeType mime;
0048     if (checkExistingFiles && fi.size() > 0) {
0049         mime = db.mimeTypeForFile(file, QMimeDatabase::MatchContent);
0050         if (mime.name() != "application/octet-stream" && mime.name() != "application/zip") {
0051             dbgPlugins << "mimeTypeForFile(). QMimeDatabase returned" << mime.name() << "for" << file;
0052             return mime.name();
0053         }
0054     }
0055 
0056 #ifdef Q_OS_ANDROID
0057     QString basename = fi.baseName();
0058     // HACK: because we use sanitzed suffix
0059     mime = db.mimeTypeForFile(basename + "." + suffix);
0060 #else
0061     mime = db.mimeTypeForFile(file);
0062 #endif
0063     if (mime.name() != "application/octet-stream") {
0064         dbgPlugins << "mimeTypeForFile(). QMimeDatabase returned" << mime.name() << "for" << file;
0065         return mime.name();
0066     }
0067     return "";
0068 }
0069 
0070 QString KisMimeDatabase::mimeTypeForSuffix(const QString &suffix)
0071 {
0072     fillMimeData();
0073     QMimeDatabase db;
0074 
0075     QString s = suffix.toLower();
0076 
0077     Q_FOREACH(const KisMimeDatabase::KisMimeType &mimeType, s_mimeDatabase) {
0078         if (mimeType.suffixes.contains(s)) {
0079             dbgPlugins << "mimeTypeForSuffix(). KisMimeDatabase returned" << mimeType.mimeType << "for" << s;
0080             return mimeType.mimeType;
0081         }
0082     }
0083 
0084 
0085     // make the file look like a file so Qt would recognize it
0086     s = "file." + s;
0087 
0088     return mimeTypeForFile(s);
0089 }
0090 
0091 QString KisMimeDatabase::mimeTypeForData(const QByteArray ba)
0092 {
0093     QMimeDatabase db;
0094     QMimeType mtp = db.mimeTypeForData(ba);
0095     dbgPlugins << "mimeTypeForData(). QMimeDatabase returned" << mtp.name();
0096     return mtp.name();
0097 }
0098 
0099 QString KisMimeDatabase::descriptionForMimeType(const QString &mimeType)
0100 {
0101     fillMimeData();
0102 
0103     Q_FOREACH(const KisMimeDatabase::KisMimeType &m, s_mimeDatabase) {
0104         if (m.mimeType == mimeType) {
0105             dbgPlugins << "descriptionForMimeType. KisMimeDatabase returned" << m.description << "for" << mimeType;
0106             return m.description;
0107         }
0108     }
0109 
0110     QMimeDatabase db;
0111     QMimeType mime = db.mimeTypeForName(mimeType);
0112     if (mime.name() != "application/octet-stream") {
0113         dbgPlugins  << "descriptionForMimeType. QMimeDatabase returned" << mime.comment() << "for" << mimeType;
0114         return mime.comment();
0115     }
0116 
0117     return mimeType;
0118 }
0119 
0120 QStringList KisMimeDatabase::suffixesForMimeType(const QString &mimeType)
0121 {
0122     fillMimeData();
0123     Q_FOREACH(const KisMimeDatabase::KisMimeType &m, s_mimeDatabase) {
0124         if (m.mimeType == mimeType) {
0125             dbgPlugins << "suffixesForMimeType. KisMimeDatabase returned" << m.suffixes;
0126             return m.suffixes;
0127         }
0128     }
0129 
0130     QMimeDatabase db;
0131     QMimeType mime = db.mimeTypeForName(mimeType);
0132     if (mime.name() != "application/octet-stream" && !mime.suffixes().isEmpty()) {
0133         QString preferredSuffix = mime.preferredSuffix();
0134         if (mimeType == "image/x-tga") {
0135             preferredSuffix = "tga";
0136         }
0137         if (mimeType == "image/jpeg") {
0138             preferredSuffix = "jpg";
0139         }
0140         QStringList suffixes = mime.suffixes();
0141         if (preferredSuffix != suffixes.first()) {
0142             suffixes.removeAll(preferredSuffix);
0143             suffixes.prepend(preferredSuffix);
0144 
0145         }
0146         dbgPlugins << "suffixesForMimeType. QMimeDatabase returned" << suffixes;
0147         return suffixes;
0148     }
0149     return QStringList();
0150 }
0151 
0152 QString KisMimeDatabase::iconNameForMimeType(const QString &mimeType)
0153 {
0154     QMimeDatabase db;
0155     QMimeType mime = db.mimeTypeForName(mimeType);
0156     dbgPlugins << "iconNameForMimeType" << mime.iconName();
0157     return mime.iconName();
0158 }
0159 
0160 void KisMimeDatabase::fillMimeData()
0161 {
0162     // This should come from the import/export plugins, but the json files aren't translated,
0163     // which is bad for the description field
0164     if (s_mimeDatabase.isEmpty()) {
0165 
0166         KisMimeType mimeType;
0167 
0168         mimeType.mimeType = "image/x-gimp-brush";
0169         mimeType.description = i18nc("description of a file type", "Gimp Brush");
0170         mimeType.suffixes = QStringList() << "gbr" << "vbr";
0171         s_mimeDatabase << mimeType;
0172 
0173         mimeType.mimeType = "image/x-gimp-brush-animated";
0174         mimeType.description = i18nc("description of a file type", "Gimp Image Hose Brush");
0175         mimeType.suffixes = QStringList() << "gih";
0176         s_mimeDatabase << mimeType;
0177 
0178         mimeType.mimeType = "image/x-adobe-brushlibrary";
0179         mimeType.description = i18nc("description of a file type", "Adobe Brush Library");
0180         mimeType.suffixes = QStringList() << "abr";
0181         s_mimeDatabase << mimeType;
0182 
0183         mimeType.mimeType = "application/x-krita-paintoppreset";
0184         mimeType.description = i18nc("description of a file type", "Krita Brush Preset");
0185         mimeType.suffixes = QStringList() << "kpp";
0186         s_mimeDatabase << mimeType;
0187 
0188         mimeType.mimeType = "application/x-mypaint-brush";
0189         mimeType.description = i18nc("description of a file type", "MyPaint Brush");
0190         mimeType.suffixes = QStringList() << "myb";
0191         s_mimeDatabase << mimeType;
0192 
0193         mimeType.mimeType = "application/x-krita-assistant";
0194         mimeType.description = i18nc("description of a file type", "Krita Assistant");
0195         mimeType.suffixes = QStringList() << "paintingassistant";
0196         s_mimeDatabase << mimeType;
0197 
0198         mimeType.mimeType = "image/x-r32";
0199         mimeType.description = i18nc("description of a file type", "R32 Heightmap");
0200         mimeType.suffixes = QStringList() <<  "r32";
0201         s_mimeDatabase << mimeType;
0202 
0203         mimeType.mimeType = "image/x-r16";
0204         mimeType.description = i18nc("description of a file type", "R16 Heightmap");
0205         mimeType.suffixes = QStringList() <<  "r16";
0206         s_mimeDatabase << mimeType;
0207 
0208         mimeType.mimeType = "image/x-r8";
0209         mimeType.description = i18nc("description of a file type", "R8 Heightmap");
0210         mimeType.suffixes = QStringList() << "r8";
0211         s_mimeDatabase << mimeType;
0212 
0213         mimeType.mimeType = "application/x-spriter";
0214         mimeType.description = i18nc("description of a file type", "Spriter SCML");
0215         mimeType.suffixes = QStringList() << "scml";
0216         s_mimeDatabase << mimeType;
0217 
0218         mimeType.mimeType = "image/x-svm";
0219         mimeType.description = i18nc("description of a file type", "Starview Metafile");
0220         mimeType.suffixes = QStringList() << "svm";
0221         s_mimeDatabase << mimeType;
0222 
0223         mimeType.mimeType = "image/openraster";
0224         mimeType.description = i18nc("description of a file type", "OpenRaster Image");
0225         mimeType.suffixes = QStringList() << "ora";
0226         s_mimeDatabase << mimeType;
0227 
0228         mimeType.mimeType = "application/x-photoshop-style-library";
0229         mimeType.description = i18nc("description of a file type", "Photoshop Layer Style Library");
0230         mimeType.suffixes = QStringList() << "asl";
0231         s_mimeDatabase << mimeType;
0232 
0233         mimeType.mimeType = "application/x-gimp-color-palette";
0234         mimeType.description = i18nc("description of a file type", "Color Palette");
0235         mimeType.suffixes = QStringList() << "gpl" << "pal" << "act" << "aco" << "colors" << "xml" << "sbz" << "acb" << "ase";
0236         s_mimeDatabase << mimeType;
0237 
0238         mimeType.mimeType = "application/x-krita-palette";
0239         mimeType.description = i18nc("description of a file type", "Krita Color Palette");
0240         mimeType.suffixes = QStringList() << "kpl";
0241         s_mimeDatabase << mimeType;
0242 
0243         mimeType.mimeType = "application/x-opencolorio-configuration";
0244         mimeType.description = i18nc("description of a file type", "OpenColorIO Configuration");
0245         mimeType.suffixes = QStringList() << "ocio";
0246         s_mimeDatabase << mimeType;
0247 
0248         mimeType.mimeType = "application/x-gimp-gradient";
0249         mimeType.description = i18nc("description of a file type", "GIMP Gradients");
0250         mimeType.suffixes = QStringList() << "ggr";
0251         s_mimeDatabase << mimeType;
0252 
0253         mimeType.mimeType = "image/x-gimp-pat";
0254         mimeType.description = i18nc("description of a file type", "GIMP Patterns");
0255         mimeType.suffixes = QStringList() << "pat";
0256         s_mimeDatabase << mimeType;
0257 
0258         mimeType.mimeType = "application/x-krita-bundle";
0259         mimeType.description = i18nc("description of a file type", "Krita Resource Bundle");
0260         mimeType.suffixes = QStringList() << "bundle";
0261         s_mimeDatabase << mimeType;
0262 
0263         mimeType.mimeType = "application/x-krita-workspace";
0264         mimeType.description = i18nc("description of a file type", "Krita Workspace");
0265         mimeType.suffixes = QStringList() << "kws";
0266         s_mimeDatabase << mimeType;
0267 
0268         mimeType.mimeType = "application/x-krita-windowlayout";
0269         mimeType.description = i18nc("description of a file type", "Krita Window Layout");
0270         mimeType.suffixes = QStringList() << "kwl";
0271         s_mimeDatabase << mimeType;
0272 
0273         mimeType.mimeType = "application/x-krita-session";
0274         mimeType.description = i18nc("description of a file type", "Krita Session");
0275         mimeType.suffixes = QStringList() << "ksn";
0276         s_mimeDatabase << mimeType;
0277 
0278         mimeType.mimeType = "application/x-krita-taskset";
0279         mimeType.description = i18nc("description of a file type", "Krita Taskset");
0280         mimeType.suffixes = QStringList() << "kts";
0281         s_mimeDatabase << mimeType;
0282 
0283         mimeType.mimeType = "application/x-krita-reference-images";
0284         mimeType.description = i18nc("description of a file type", "Krita Reference Image Collection");
0285         mimeType.suffixes = QStringList() << "krf";
0286         s_mimeDatabase << mimeType;
0287 
0288         mimeType.mimeType = "application/x-krita-gamutmasks";
0289         mimeType.description = i18nc("description of a file type", "Krita Gamut Mask");
0290         mimeType.suffixes = QStringList() << "kgm";
0291         s_mimeDatabase << mimeType;
0292         
0293         mimeType.mimeType = "application/x-krita-shortcuts";
0294         mimeType.description = i18nc("description of a file type", "Krita Shortcut Scheme");
0295         mimeType.suffixes = QStringList() << "shortcuts";
0296         s_mimeDatabase << mimeType;
0297 
0298         mimeType.mimeType = "image/x-krita-raw";
0299         mimeType.description = i18nc("description of a file type", "Camera Raw Files");
0300         mimeType.suffixes = QStringList() << "bay" << "bmq" << "cr2" << "crw" << "cs1" << "dc2" << "dcr" << "dng" << "erf" << "fff" << "hdr" << "k25" << "kdc" << "mdc" << "mos" << "mrw" << "nef" << "orf" << "pef" << "pxn" << "raf" << "raw" << "rdc" << "sr2" << "srf" << "x3f" << "arw" << "3fr" << "cine" << "ia" << "kc2" << "mef" << "nrw" << "qtk" << "rw2" << "sti" << "rwl" << "srw";
0301         s_mimeDatabase << mimeType;
0302 
0303         mimeType.mimeType = "application/x-extension-exr";
0304         mimeType.description = i18nc("description of a file type", "OpenEXR (Extended)");
0305         mimeType.suffixes = QStringList() << "exr";
0306         s_mimeDatabase << mimeType;
0307 
0308         mimeType.mimeType = "image/x-psb";
0309         mimeType.description = i18nc("description of a file type", "Photoshop Image (Large)");
0310         mimeType.suffixes = QStringList() << "psb";
0311         s_mimeDatabase << mimeType;
0312 
0313         mimeType.mimeType = "image/heic";
0314         mimeType.description = i18nc("description of a file type", "HEIC/HEIF Image");
0315         mimeType.suffixes = QStringList() << "heic" << "heif";
0316         s_mimeDatabase << mimeType;
0317 
0318         mimeType.mimeType = "image/avif";
0319         mimeType.description = i18nc("description of a file type", "AVIF Image");
0320         mimeType.suffixes = QStringList() << "avif";
0321         s_mimeDatabase << mimeType;
0322 
0323 //        mimeType.mimeType = "image/jp2";
0324 //        mimeType.description = i18nc("description of a file type", "JP2 Image");
0325 //        mimeType.suffixes = QStringList() << "jp2" << "j2k";
0326 //        s_mimeDatabase << mimeType;
0327 
0328         mimeType.mimeType = "application/x-krita-seexpr-script";
0329         mimeType.description = i18nc("description of a file type", "SeExpr script package");
0330         mimeType.suffixes = QStringList() << "kse";
0331         s_mimeDatabase << mimeType;
0332 
0333         mimeType.mimeType = "application/x-krita-archive";
0334         mimeType.description = i18nc("description of a file type", "Krita Archival Image Format");
0335         mimeType.suffixes = QStringList() << "krz";
0336         s_mimeDatabase << mimeType;
0337 
0338         mimeType.mimeType = "image/apng";
0339         mimeType.description = i18nc("description of a file type", "Animated PNG Image");
0340         mimeType.suffixes = QStringList() << "apng";
0341         s_mimeDatabase << mimeType;
0342 
0343         mimeType.mimeType = "image/jxl";
0344         mimeType.description = i18nc("description of a file type", "JPEG-XL Image");
0345         mimeType.suffixes = QStringList() << "jxl";
0346         s_mimeDatabase << mimeType;
0347 
0348         mimeType.mimeType = "text/csv";
0349         mimeType.description = i18nc("description of a file type", "CSV Document");
0350         mimeType.suffixes = QStringList() << "csv";
0351         s_mimeDatabase << mimeType;
0352 
0353         dbgPlugins << "Filled mimedatabase with" << s_mimeDatabase.count() << "special mimetypes";
0354     }
0355 }