/* * Copyright (C) 2022, KylinSoft Co., Ltd. * * 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 3 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, see . * */ #include "ukui-menu-application.h" #include "menu-dbus-service.h" #include "settings.h" #include "commons.h" #include "menu-main-window.h" #include "power-button.h" #include "app-manager.h" #include "context-menu-manager.h" #include "event-track.h" #include "sidebar-button-utils.h" #include "widget-model.h" #include "app-page-backend.h" #include "app-group-model.h" #include "favorite/favorites-model.h" #include "favorite/folder-model.h" #include #include #include #include #include using namespace UkuiMenu; UkuiMenuApplication::UkuiMenuApplication(MenuMessageProcessor *processor) : QObject(nullptr) { registerQmlTypes(); startUkuiMenu(); initDbusService(); connect(processor, &MenuMessageProcessor::request, this, &UkuiMenuApplication::execCommand); } void UkuiMenuApplication::startUkuiMenu() { initQmlEngine(); loadMenuUI(); } void UkuiMenuApplication::registerQmlTypes() { const char *uri = "org.ukui.menu.core"; int versionMajor = 1, versionMinor = 0; SettingModule::defineModule(uri, versionMajor, versionMinor); WindowModule::defineModule(uri, versionMajor, versionMinor); PowerButton::defineModule(uri, versionMajor, versionMinor); SidebarButtonUtils::defineModule(uri, versionMajor, versionMinor); qmlRegisterType(uri, versionMajor, versionMinor, "WidgetModel"); qmlRegisterType(uri, versionMajor, versionMinor, "AppGroupModel"); //qmlRegisterType(uri, versionMajor, versionMinor, "AppPageBackend"); qmlRegisterSingletonInstance(uri, versionMajor, versionMinor, "AppPageBackend", AppPageBackend::instance()); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "PluginGroup", "Use enums only."); // commons qRegisterMetaType("DataType::Type"); qRegisterMetaType("DataEntity"); qRegisterMetaType("MenuInfo::Location"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "Display", "Use enums only."); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataType", "Use enums only"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "MenuInfo", "Use enums only."); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "LabelItem", "Use enums only."); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "WidgetMetadata", "Use enums only."); // qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataEntity", "unknown"); qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "EventTrack", "Attached only."); } void UkuiMenuApplication::initQmlEngine() { m_engine = new QQmlEngine(this); m_engine->addImportPath("qrc:/qml"); QQmlContext *context = m_engine->rootContext(); context->setContextProperty("menuSetting", MenuSetting::instance()); context->setContextProperty("menuManager", ContextMenuManager::instance()); context->setContextProperty("appManager", AppManager::instance()); context->setContextProperty("favoriteModel", &FavoritesModel::instance()); context->setContextProperty("FolderModel", &FolderModel::instance()); // MenuMainWindow // const QUrl url(QStringLiteral("qrc:/qml/MenuMainWindow.qml")); // QQmlApplicationEngine *m_applicationEngine{nullptr}; // m_applicationEngine = new QQmlApplicationEngine(this); // QObject::connect(m_applicationEngine, &QQmlApplicationEngine::objectCreated, // this, [url](QObject *obj, const QUrl &objUrl) { // if (!obj && url == objUrl) // QCoreApplication::exit(-1); // }, Qt::QueuedConnection); // // m_applicationEngine->load(url); connect(AppManager::instance(), &AppManager::request, this, &UkuiMenuApplication::execCommand); } void UkuiMenuApplication::loadMenuUI() { const QUrl url(QStringLiteral("qrc:/qml/main.qml")); m_mainWindow = new MenuWindow(m_engine, nullptr); m_mainWindow->setSource(url); connect(m_mainWindow, &QQuickView::activeFocusItemChanged, m_mainWindow, [this] { if (m_mainWindow->activeFocusItem()) { return; } execCommand(Hide); }); } void UkuiMenuApplication::initDbusService() { m_menuDbusService = new MenuDbusService(QGuiApplication::instance()->property("display").toString(), this); if (m_menuDbusService) { connect(m_menuDbusService, &MenuDbusService::menuActive, this, [this] { execCommand(Active); }); // connect(m_menuDbusService, &MenuDbusService::reloadConfigSignal, this, [this] { //// reload ... // }); } } void UkuiMenuApplication::execCommand(Command command) { switch (command) { case Active: { if (m_mainWindow) { m_mainWindow->activeMenuWindow(!m_mainWindow->isVisible()); } break; } case Show: { if (m_mainWindow) { m_mainWindow->activeMenuWindow(true); } break; } case Quit: { if (m_mainWindow) { m_mainWindow->activeMenuWindow(false); m_engine->quit(); } QCoreApplication::quit(); break; } case Hide: { if (m_mainWindow) { m_mainWindow->activeMenuWindow(false); } break; } default: break; } // TODO: 发送窗口显示隐藏信号到插件 } UkuiMenuApplication::~UkuiMenuApplication() { if (m_mainWindow) { m_mainWindow->deleteLater(); } } // == MenuMessageProcessor == // QCommandLineOption MenuMessageProcessor::showUkuiMenu({"s", "show"}, QObject::tr("Show ukui-menu.")); QCommandLineOption MenuMessageProcessor::quitUkuiMenu({"q", "quit"}, QObject::tr("Quit ukui-menu.")); MenuMessageProcessor::MenuMessageProcessor() : QObject(nullptr) {} void MenuMessageProcessor::processMessage(const QString &message) { QStringList options = QString(message).split(' '); QCommandLineParser parser; parser.addOption(MenuMessageProcessor::showUkuiMenu); parser.addOption(MenuMessageProcessor::quitUkuiMenu); parser.parse(options); if (parser.isSet(MenuMessageProcessor::showUkuiMenu)) { Q_EMIT request(UkuiMenuApplication::Show); return; } if (parser.isSet(MenuMessageProcessor::quitUkuiMenu)) { Q_EMIT request(UkuiMenuApplication::Quit); return; } } /** * 已知问题,使用命令quit时,会出现 QFileSystemWatcher::removePaths: list is empty * 可见该bug: https://bugreports.qt.io/browse/QTBUG-68607 * @param message * @return */ bool MenuMessageProcessor::preprocessMessage(const QStringList& message) { qDebug() << "Hey, there."; QCommandLineParser parser; QCommandLineOption helpOption = parser.addHelpOption(); QCommandLineOption versionOption = parser.addVersionOption(); parser.addOption(MenuMessageProcessor::showUkuiMenu); parser.addOption(MenuMessageProcessor::quitUkuiMenu); parser.parse(message); if (message.size() <= 1 || parser.isSet(helpOption) || !parser.unknownOptionNames().isEmpty()) { if (!parser.unknownOptionNames().isEmpty()) { qDebug() << "Unknown options:" << parser.unknownOptionNames(); } parser.showHelp(); return false; } if (parser.isSet(versionOption)) { parser.showVersion(); return false; } return parser.isSet(MenuMessageProcessor::showUkuiMenu) || parser.isSet(MenuMessageProcessor::quitUkuiMenu); }