File indexing completed on 2025-01-05 04:55:03

0001 /*
0002     Copyright (c) 2016 Michael Bohlender <michael.bohlender@kdemail.net>
0003     Copyright (c) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
0004 
0005     This library is free software; you can redistribute it and/or modify it
0006     under the terms of the GNU Library General Public License as published by
0007     the Free Software Foundation; either version 2 of the License, or (at your
0008     option) any later version.
0009 
0010     This library is distributed in the hope that it will be useful, but WITHOUT
0011     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0012     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
0013     License for more details.
0014 
0015     You should have received a copy of the GNU Library General Public License
0016     along with this library; see the file COPYING.LIB.  If not, write to the
0017     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0018     02110-1301, USA.
0019 */
0020 
0021 #include "frameworkplugin.h"
0022 
0023 #include "domain/maillistmodel.h"
0024 #include "domain/folderlistmodel.h"
0025 #include "domain/mime/htmlutils.h"
0026 #include "domain/perioddayeventmodel.h"
0027 #include "domain/multidayeventmodel.h"
0028 #include "domain/eventoccurrencemodel.h"
0029 #include "domain/todomodel.h"
0030 #include "domain/composercontroller.h"
0031 #include "domain/mime/messageparser.h"
0032 #include "domain/retriever.h"
0033 #include "domain/outboxmodel.h"
0034 #include "domain/mouseproxy.h"
0035 #include "domain/contactcontroller.h"
0036 #include "domain/eventcontroller.h"
0037 #include "domain/invitationcontroller.h"
0038 #include "domain/todocontroller.h"
0039 #include "domain/peoplemodel.h"
0040 #include "domain/textdocumenthandler.h"
0041 #include "domain/settings/accountsettings.h"
0042 #include "accounts/accountsmodel.h"
0043 #include "accounts/accountfactory.h"
0044 #include "settings/settings.h"
0045 #include "fabric.h"
0046 #include "kubeimage.h"
0047 #include "clipboardproxy.h"
0048 #include "startupcheck.h"
0049 #include "keyring.h"
0050 #include "controller.h"
0051 #include "domainobjectcontroller.h"
0052 #include "extensionmodel.h"
0053 #include "viewhighlighter.h"
0054 #include "file.h"
0055 #include "logmodel.h"
0056 #include "inboundmodel.h"
0057 #include "entitymodel.h"
0058 #include "entitycontroller.h"
0059 #include "qquicktreemodeladaptor.h"
0060 
0061 #include <QtQml>
0062 #include <QQuickImageProvider>
0063 #include <QIcon>
0064 #include <QApplication>
0065 
0066 class KubeImageProvider : public QQuickImageProvider
0067 {
0068 public:
0069     KubeImageProvider()
0070         : QQuickImageProvider(QQuickImageProvider::Pixmap)
0071     {
0072     }
0073 
0074     static QSize selectSize(const QSize &requestedSize, const QList<QSize> &availableSizes)
0075     {
0076         auto expectedSize = requestedSize;
0077         //Get the largest size that is still smaller or equal than requested
0078         //Except if we only have larger sizes, then just pick the closest one
0079         bool first = true;
0080         for (const auto &s : availableSizes) {
0081             if (first && s.width() > requestedSize.width()) {
0082                 return s;
0083             }
0084             first = false;
0085             if (s.width() <= requestedSize.width()) {
0086                 expectedSize = s;
0087             }
0088         }
0089         return expectedSize;
0090     }
0091 
0092     QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) Q_DECL_OVERRIDE
0093     {
0094         //The platform theme plugin can overwrite our setting again once it gets loaded,
0095         //so we check on every icon load request...
0096         if (QIcon::themeName() != "kube") {
0097             QIcon::setThemeName("kube");
0098         }
0099         const auto icon = QIcon::fromTheme(id);
0100         static auto devicePixelRatio = static_cast<QApplication*>(QApplication::instance())->devicePixelRatio();
0101         //availableSizes() does not take the devicePixelRatio into account, so if we divide the request by it first,
0102         //we will end up with the correct size after multiplying it later.
0103         const auto expectedSize = selectSize(requestedSize / devicePixelRatio, icon.availableSizes());
0104         auto pixmap = icon.pixmap(expectedSize * devicePixelRatio);
0105         pixmap.setDevicePixelRatio(devicePixelRatio);
0106         if (size) {
0107             *size = pixmap.size();
0108         }
0109         return pixmap;
0110     }
0111 };
0112 
0113 
0114 static QObject *fabric_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
0115 {
0116     Q_UNUSED(engine)
0117     Q_UNUSED(scriptEngine)
0118     return new Kube::Fabric::Fabric;
0119 }
0120 
0121 static QObject *htmlutils_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
0122 {
0123     Q_UNUSED(engine)
0124     Q_UNUSED(scriptEngine)
0125     return new HtmlUtils::HtmlUtils;
0126 }
0127 
0128 static QObject *keyring_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
0129 {
0130     Q_UNUSED(engine)
0131     Q_UNUSED(scriptEngine)
0132     auto instance = Kube::Keyring::instance();
0133     QQmlEngine::setObjectOwnership(instance, QQmlEngine::CppOwnership);
0134     return instance;
0135 }
0136 
0137 static QString findFile(const QString file, const QStringList importPathList)
0138 {
0139     for (const auto &path : importPathList) {
0140         const QString f = path + file;
0141         if (QFileInfo::exists(f)) {
0142             return f;
0143         }
0144     }
0145     return {};
0146 }
0147 
0148 void FrameworkPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
0149 {
0150     Q_UNUSED(uri);
0151     engine->addImageProvider(QLatin1String("kube"), new KubeImageProvider);
0152 
0153     QString kubeIcons = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("kube-icons.rcc"));
0154     //For windows
0155     if (kubeIcons.isEmpty()) {
0156         const auto locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation) + QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
0157         kubeIcons = findFile(QStringLiteral("/kube/kube-icons.rcc"), locations);
0158     }
0159     //For osx
0160     if (kubeIcons.isEmpty()) {
0161         //On Mac OS we want to include Contents/Resources/ in the bundle, and that path is in AppDataLocations.
0162         QStringList iconSearchPaths;
0163         for (const auto &p : QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)) {
0164             auto iconPath = p;
0165             //I'm getting broken paths reported from standardLocations
0166             if (iconPath.contains("kube.appContents")) {
0167                 iconPath.replace("kube.appContents", "kube.app/Contents");
0168             }
0169             if (iconPath.contains("kube-kolabnow.appContents")) {
0170                 iconPath.replace("kube-kolabnow.appContents", "kube-kolabnow.app/Contents");
0171             }
0172             iconSearchPaths << iconPath;
0173         }
0174         kubeIcons = findFile(QStringLiteral("/kube/kube-icons.rcc"), iconSearchPaths);
0175     }
0176 
0177     if (!QResource::registerResource(kubeIcons, "/icons/kube")) {
0178         qWarning() << "Failed to register icon resource!" << kubeIcons;
0179         qWarning() << "Searched paths: " << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation) + QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
0180         Q_ASSERT(false);
0181     } else {
0182         QIcon::setThemeSearchPaths(QStringList() << QStringLiteral(":/icons"));
0183         QIcon::setThemeName(QStringLiteral("kube"));
0184     }
0185 }
0186 
0187 void FrameworkPlugin::registerTypes (const char *uri)
0188 {
0189     qmlRegisterType<FolderListModel>(uri, 1, 0, "FolderListModel");
0190     qmlRegisterType<MailListModel>(uri, 1, 0, "MailListModel");
0191     qmlRegisterType<PeriodDayEventModel>(uri, 1, 0, "PeriodDayEventModel");
0192     qmlRegisterType<MultiDayEventModel>(uri, 1, 0, "MultiDayEventModel");
0193     qmlRegisterType<EventOccurrenceModel>(uri, 1, 0, "EventOccurrenceModel");
0194     qmlRegisterType<EventController>(uri, 1, 0, "EventController");
0195     qmlRegisterType<InvitationController>(uri, 1, 0, "InvitationController");
0196     qmlRegisterType<TodoModel>(uri, 1, 0, "TodoModel");
0197     qmlRegisterType<TodoController>(uri, 1, 0, "TodoController");
0198     qmlRegisterType<ComposerController>(uri, 1, 0, "ComposerController");
0199     qmlRegisterUncreatableType<Kube::ListPropertyController>(uri, 1, 0, "ListPropertyController", "abstract");
0200     qmlRegisterUncreatableType<Selector>(uri, 1, 0, "Selector", "abstract");
0201     qmlRegisterUncreatableType<Completer>(uri, 1, 0, "Completer", "abstract");
0202     qmlRegisterType<Kube::ControllerAction>(uri, 1, 0, "ControllerAction");
0203     qmlRegisterType<MessageParser>(uri, 1, 0, "MessageParser");
0204     qmlRegisterType<Retriever>(uri, 1, 0, "Retriever");
0205     qmlRegisterType<OutboxModel>(uri, 1, 0, "OutboxModel");
0206     qmlRegisterType<MouseProxy>(uri, 1, 0, "MouseProxy");
0207     qmlRegisterType<ContactController>(uri, 1, 0,"ContactController");
0208     qmlRegisterType<PeopleModel>(uri, 1, 0,"PeopleModel");
0209     qmlRegisterType<TextDocumentHandler>(uri, 1, 0, "TextDocumentHandler");
0210     qmlRegisterType<LogModel>(uri, 1, 0, "LogModel");
0211     qmlRegisterType<InboundModel>(uri, 1, 0, "InboundModel");
0212     qmlRegisterType<EntityModel>(uri, 1, 0, "EntityModel");
0213     qmlRegisterType<EntityLoader>(uri, 1, 0, "EntityLoader");
0214     qmlRegisterType<EntityController>(uri, 1, 0, "EntityController");
0215     qmlRegisterType<CheckedEntities>(uri, 1, 0, "CheckedEntities");
0216     qmlRegisterType<CheckableEntityModel>(uri, 1, 0, "CheckableEntityModel");
0217     qmlRegisterType<QQuickTreeModelAdaptor1>(uri, 1, 0, "TreeModelAdaptor");
0218     qmlRegisterSingletonType<HtmlUtils::HtmlUtils>(uri, 1, 0, "HtmlUtils", htmlutils_singletontype_provider);
0219 
0220     qmlRegisterType<AccountFactory>(uri, 1, 0, "AccountFactory");
0221     qmlRegisterType<AccountsModel>(uri, 1, 0, "AccountsModel");
0222     qmlRegisterType<AccountSettings>(uri, 1, 0, "AccountSettings");
0223     qmlRegisterType<Kube::ExtensionModel>(uri, 1, 0, "ExtensionModel");
0224     qmlRegisterType<Kube::File>(uri, 1, 0, "File");
0225 
0226     qmlRegisterType<Kube::Settings>(uri, 1, 0, "Settings");
0227 
0228     qmlRegisterType<Kube::Fabric::Listener>(uri, 1, 0, "Listener");
0229     qmlRegisterType<Kube::DomainObjectController>(uri, 1, 0, "DomainObjectController");
0230     qmlRegisterSingletonType<Kube::Fabric::Fabric>(uri, 1, 0, "Fabric", fabric_singletontype_provider);
0231 
0232     qmlRegisterType<KubeImage>(uri, 1, 0, "KubeImage");
0233     qmlRegisterType<ClipboardProxy>(uri, 1, 0, "Clipboard");
0234     qmlRegisterType<StartupCheck>(uri, 1, 0, "StartupCheck");
0235     qmlRegisterType<ViewHighlighter>(uri, 1, 0, "ViewHighlighter");
0236     qmlRegisterSingletonType<Kube::Keyring>(uri, 1, 0, "Keyring", keyring_singletontype_provider);
0237 }