diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e82d4e..415718b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,10 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) # 查找qt组件 -find_package(Qt5 COMPONENTS - Core Gui Quick Widgets LinguistTools DBus X11Extras - REQUIRED) +find_package(QT NAMES Qt6 Qt5 + COMPONENTS Core Gui Quick Widgets LinguistTools DBus X11Extras REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} + COMPONENTS Core Gui Quick Widgets LinguistTools DBus X11Extras REQUIRED) # find kde framework components # see: https://api.kde.org/frameworks/index.html > KWindowSystem @@ -63,10 +64,19 @@ set(QML_IMPORT_PATH "${QML_MODULE_DIRS}" CACHE STRING "Qt Creator extra qml impo # 基础设置 set(UKUI_MENU_DATA_DIR "/usr/share/ukui-menu") +set(UKUI_MENU_SO_DIR "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-menu") set(UKUI_MENU_TRANSLATION_DIR "${UKUI_MENU_DATA_DIR}/translations") -set(UKUI_MENU_EXTENSION_DIR "${UKUI_MENU_DATA_DIR}/extensions") set(UKUI_MENU_GLOBAL_CONFIG_FILE "${UKUI_MENU_DATA_DIR}/ukui-menu-global-config.conf") -set(UKUI_MENU_LIBRARY_NAME "ukui-menu-extension") +set(UKUI_MENU_EXTENSION_DIR "${UKUI_MENU_SO_DIR}/extensions") +set(UKUI_MENU_CONTEXT_MENU_DIR "${UKUI_MENU_SO_DIR}/context-menu") + + +set(UKUI_MENU_LIBRARY_VERSION 1.0.0) +set(UKUI_MENU_LIBRARY_API_VERSION 1) +#set(UKUI_MENU_LIBRARY_NAME "ukui-menu${UKUI_MENU_LIBRARY_API_VERSION}") +set(UKUI_MENU_LIBRARY_NAME "ukui-menu-interface") +set(PC_INSTALL_DIR "/usr/lib/pkgconfig") +set(CMAKE_CONFIG_INSTALL_DIR "/usr/share/cmake/${UKUI_MENU_LIBRARY_NAME}") # 子项目 add_subdirectory(extension/recent-file) @@ -74,6 +84,7 @@ add_subdirectory(extension/recent-file) # 宏定义 add_compile_definitions(UKUI_MENU_TRANSLATION_DIR="${UKUI_MENU_TRANSLATION_DIR}" UKUI_MENU_DATA_DIR="${UKUI_MENU_DATA_DIR}" + UKUI_MENU_CONTEXT_MENU_DIR="${UKUI_MENU_CONTEXT_MENU_DIR}" UKUI_MENU_EXTENSION_DIR="${UKUI_MENU_EXTENSION_DIR}" UKUI_MENU_GLOBAL_CONFIG_FILE="${UKUI_MENU_GLOBAL_CONFIG_FILE}" ) @@ -112,7 +123,17 @@ set(SOURCE_FILES ) # library sources -set(LIBRARY_SOURCES src/extension/menu-extension-iface.h) +set(LIBRARY_SOURCES + src/data-entity.cpp + src/extension/menu-extension-iface.h + ) + +set(LIBRARY_HEADERS_DIR "/usr/include/${UKUI_MENU_LIBRARY_NAME}") +set(LIBRARY_HEADERS + src/data-entity.h + src/menu/menu-provider.h + src/extension/menu-extension-iface.h + ) # qrc文件 set(QRC_FILES qml/qml.qrc res/res.qrc) @@ -133,7 +154,10 @@ qt5_create_translation(QM_FILES ${PROJECT_SOURCE_DIR} ${TS_FILES}) # add_custom_target(generate_qm ALL DEPENDS ${QM_FILES}) add_library(${UKUI_MENU_LIBRARY_NAME} SHARED ${LIBRARY_SOURCES}) -SET_TARGET_PROPERTIES(${UKUI_MENU_LIBRARY_NAME} PROPERTIES VERSION 1.0.0 SOVERSION 0) +set_target_properties(${UKUI_MENU_LIBRARY_NAME} PROPERTIES + VERSION ${UKUI_MENU_LIBRARY_VERSION} + SOVERSION ${UKUI_MENU_LIBRARY_API_VERSION} + ) target_link_libraries(${UKUI_MENU_LIBRARY_NAME} PRIVATE Qt5::Core) add_executable( @@ -161,7 +185,11 @@ target_link_libraries(${PROJECT_NAME} # 安装ukui-menu install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "/usr/bin") -install(TARGETS ${UKUI_MENU_LIBRARY_NAME} LIBRARY DESTINATION "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}") +install(TARGETS ${UKUI_MENU_LIBRARY_NAME} + EXPORT ${UKUI_MENU_LIBRARY_NAME} + PUBLIC_HEADER DESTINATION ${LIBRARY_HEADERS_DIR} + LIBRARY DESTINATION "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}" + ) # 安装翻译文件 install(FILES ${QM_FILES} DESTINATION "${UKUI_MENU_TRANSLATION_DIR}") # 安装desktop文件 @@ -169,4 +197,38 @@ install(FILES ${DESKTOP_FILE} DESTINATION "/etc/xdg/autostart") install(FILES ${GSETTING_FILE} DESTINATION "/usr/share/glib-2.0/schemas") install(FILES ${GLOBAL_CONFIG_FILE} DESTINATION "${UKUI_MENU_DATA_DIR}") install(FILES ${DBUS_SERVICE_FILE} DESTINATION "/usr/share/dbus-1/services/") +install(FILES ${LIBRARY_HEADERS} DESTINATION "${LIBRARY_HEADERS_DIR}") install(DIRECTORY "qml/org" DESTINATION "/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/qt5/qml") + +## 生成开发配置文件 +include(CMakePackageConfigHelpers) +target_include_directories(${UKUI_MENU_LIBRARY_NAME} PUBLIC $) + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}-config.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}-config.cmake" + INSTALL_DESTINATION ${CMAKE_CONFIG_INSTALL_DIR} +) + +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}-config-version.cmake + VERSION ${UKUI_MENU_LIBRARY_VERSION} + COMPATIBILITY SameMajorVersion +) + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}.pc.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}.pc" + INSTALL_DESTINATION ${PC_INSTALL_DIR} +) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}.pc DESTINATION ${PC_INSTALL_DIR}) + +install(EXPORT ${UKUI_MENU_LIBRARY_NAME} + FILE ${UKUI_MENU_LIBRARY_NAME}-targets.cmake + DESTINATION ${CMAKE_CONFIG_INSTALL_DIR}) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}-config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/cmake/${UKUI_MENU_LIBRARY_NAME}-config-version.cmake + DESTINATION ${CMAKE_CONFIG_INSTALL_DIR}) diff --git a/cmake/ukui-menu-interface-config.cmake.in b/cmake/ukui-menu-interface-config.cmake.in new file mode 100644 index 0000000..4ec4835 --- /dev/null +++ b/cmake/ukui-menu-interface-config.cmake.in @@ -0,0 +1,9 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(Qt@QT_VERSION_MAJOR@Core ) +if(TARGET Qt6::Core) + find_dependency(Qt6Core5Compat @REQUIRED_QT_VERSION@) +endif() + +include("${CMAKE_CURRENT_LIST_DIR}/@UKUI_MENU_LIBRARY_NAME@-targets.cmake") diff --git a/cmake/ukui-menu-interface.pc.in b/cmake/ukui-menu-interface.pc.in new file mode 100644 index 0000000..b1b7901 --- /dev/null +++ b/cmake/ukui-menu-interface.pc.in @@ -0,0 +1,11 @@ +prefix=/usr +exec_prefix=${prefix} +libdir=${prefix}/lib/@CMAKE_LIBRARY_ARCHITECTURE@ +includedir=${prefix}/include/@UKUI_MENU_LIBRARY_NAME@ + +Name: @UKUI_MENU_LIBRARY_NAME@ +Description: @UKUI_MENU_LIBRARY_NAME@ lib header files +URL: https://www.ukui.org/ +Version: @UKUI_MENU_LIBRARY_VERSION@ +Cflags: -I${includedir} +Libs: -L${libdir} -l@UKUI_MENU_LIBRARY_NAME@ diff --git a/extension/recent-file/CMakeLists.txt b/extension/recent-file/CMakeLists.txt index 6742391..8c01ac7 100644 --- a/extension/recent-file/CMakeLists.txt +++ b/extension/recent-file/CMakeLists.txt @@ -35,7 +35,7 @@ file(GLOB TS_FILES "translations/*.ts") # 更新翻译并创建.qm文件 qt5_create_translation(QM_FILES ${PROJECT_SOURCE_DIR} ${TS_FILES}) -set(RECENT_FILE_TRANSLATION_DIR "${UKUI_MENU_EXTENSION_DIR}/${PROJECT_NAME}") +set(RECENT_FILE_TRANSLATION_DIR "${UKUI_MENU_TRANSLATION_DIR}/${PROJECT_NAME}") add_compile_definitions(RECENT_FILE_TRANSLATION_DIR="${RECENT_FILE_TRANSLATION_DIR}") add_library(${PROJECT_NAME} SHARED ${SOURCE} ${QM_FILES} ${QRC_FILES}) diff --git a/src/appdata/app-data-manager.h b/src/appdata/app-data-manager.h index 6baa7ab..40411ff 100644 --- a/src/appdata/app-data-manager.h +++ b/src/appdata/app-data-manager.h @@ -25,6 +25,7 @@ #include #include #include +#include #include "commons.h" diff --git a/src/appdata/plugin/app-search-plugin.cpp b/src/appdata/plugin/app-search-plugin.cpp index 6398ca6..9d54111 100644 --- a/src/appdata/plugin/app-search-plugin.cpp +++ b/src/appdata/plugin/app-search-plugin.cpp @@ -19,6 +19,8 @@ #include "app-search-plugin.h" #include +#include +#include namespace UkuiMenu { diff --git a/src/commons.cpp b/src/commons.cpp index 39143c5..32b29e1 100644 --- a/src/commons.cpp +++ b/src/commons.cpp @@ -20,144 +20,6 @@ #include -UkuiMenu::DataEntity::DataEntity(UkuiMenu::DataType::Type type, QString name, QString icon, QString comment, QString extraData) - : m_type(type), m_name(std::move(name)), m_icon(std::move(icon)), m_comment(std::move(comment)), m_extraData(std::move(extraData)) -{ - -} - -int UkuiMenu::DataEntity::top() const -{ - return m_top; -} - -void UkuiMenu::DataEntity::setTop(int top) -{ - m_top = top; -} - -bool UkuiMenu::DataEntity::isLock() const -{ - return m_lock; -} - -void UkuiMenu::DataEntity::setLock(bool lock) -{ - m_lock = lock; -} - -int UkuiMenu::DataEntity::favorite() const -{ - return m_favorite; -} - -void UkuiMenu::DataEntity::setFavorite(int favorite) -{ - m_favorite = favorite; -} - -int UkuiMenu::DataEntity::launchTimes() const -{ - return m_launchTimes; -} - -void UkuiMenu::DataEntity::setLaunchTimes(int launchTimes) -{ - m_launchTimes = launchTimes; -} - -QString UkuiMenu::DataEntity::id() const -{ - return m_id; -} - -void UkuiMenu::DataEntity::setId(const QString &id) -{ - m_id = id; -} - -void UkuiMenu::DataEntity::setCategory(const QString &category) -{ - m_category = category; -} - -QString UkuiMenu::DataEntity::category() const -{ - return m_category; -} - -void UkuiMenu::DataEntity::setFirstLetter(const QString &firstLetter) -{ - m_firstLetter = firstLetter; -} - -QString UkuiMenu::DataEntity::firstLetter() const -{ - return m_firstLetter; -} - -void UkuiMenu::DataEntity::setType(UkuiMenu::DataType::Type type) -{ - m_type = type; -} - -UkuiMenu::DataType::Type UkuiMenu::DataEntity::type() const -{ - return m_type; -} - -void UkuiMenu::DataEntity::setIcon(const QString &icon) -{ - m_icon = icon; -} - -QString UkuiMenu::DataEntity::icon() const -{ - return m_icon; -} - -void UkuiMenu::DataEntity::setName(const QString &name) -{ - m_name = name; -} - -QString UkuiMenu::DataEntity::name() const -{ - return m_name; -} - -void UkuiMenu::DataEntity::setComment(const QString &comment) -{ - m_comment = comment; -} - -QString UkuiMenu::DataEntity::comment() const -{ - return m_comment; -} - -void UkuiMenu::DataEntity::setExtraData(const QString &extraData) -{ - m_extraData = extraData; -} - -QString UkuiMenu::DataEntity::extraData() const -{ - return m_extraData; -} - -QHash UkuiMenu::DataEntity::AppRoleNames() -{ - QHash names; - names.insert(DataEntity::Id, "id"); - names.insert(DataEntity::Type, "type"); - names.insert(DataEntity::Icon, "icon"); - names.insert(DataEntity::Name, "name"); - names.insert(DataEntity::Comment, "comment"); - names.insert(DataEntity::ExtraData, "extraData"); - return names; -} - // ====== LabelItem ====== // UkuiMenu::LabelItem::LabelItem(bool disable, int index, QString id, QString displayName) : m_disable(disable), m_index(index), m_id(std::move(id)), m_displayName(std::move(displayName)) {} diff --git a/src/commons.h b/src/commons.h index a2b3ec0..0dcb2dc 100644 --- a/src/commons.h +++ b/src/commons.h @@ -19,8 +19,7 @@ #ifndef UKUI_MENU_COMMONS_H #define UKUI_MENU_COMMONS_H -#include -#include +#include "data-entity.h" namespace UkuiMenu { @@ -74,106 +73,6 @@ public: Q_ENUM(Type) }; -class DataType -{ - Q_GADGET -public: - enum Type { - Normal, // 普通Item - Label, // 标签数据 - Folder // 文件夹 - }; - Q_ENUM(Type); -}; - -// 应用数据 -class DataEntity -{ - // TODO 改用 Q_OBJECT ? - Q_GADGET - Q_PROPERTY(DataType::Type type READ type WRITE setType) - Q_PROPERTY(QString id READ id) - Q_PROPERTY(QString icon READ icon WRITE setIcon) - Q_PROPERTY(QString name READ name WRITE setName) - Q_PROPERTY(QString comment READ comment WRITE setComment) - Q_PROPERTY(QString extraData READ extraData WRITE setExtraData) -public: - static QHash AppRoleNames(); - enum PropertyName { - Id = 0, - Type, - Icon, - Name, - Comment, - ExtraData - }; - DataEntity() = default; - DataEntity(DataType::Type type, QString name, QString icon, QString comment, QString extraData); - - int top() const; - void setTop(int top); - - bool isLock() const; - void setLock(bool lock); - - int favorite() const; - void setFavorite(int favorite); - - int launchTimes() const; - void setLaunchTimes(int launchTimes); - - QString id() const; - void setId(const QString& id); - - void setCategory(const QString& category); - QString category() const; - - void setFirstLetter(const QString& firstLetter); - QString firstLetter() const; - - void setType(DataType::Type type); - DataType::Type type() const; - - void setIcon(const QString& icon); - QString icon() const; - - void setName(const QString& name); - QString name() const; - - void setComment(const QString& comment); - QString comment() const; - - void setExtraData(const QString& extraData); - QString extraData() const; - -private: - bool m_lock{false}; // 应用锁定 - int m_top{0}; // 置顶状态及序号 - int m_favorite{0}; // 收藏状态及序号 - int m_launchTimes{0}; // 启动次数 - DataType::Type m_type {DataType::Normal}; - QString m_id; // 应用可执行文件路径 - QString m_icon; - QString m_name; - QString m_category; - QString m_firstLetter; - QString m_comment; // 应用描述 - QString m_extraData; // 额外的数据 -}; - -class CommonsModule -{ -public: - static void defineModule(const char *uri, int versionMajor, int versionMinor) { - qRegisterMetaType("DataType::Type"); - qRegisterMetaType("DataEntity"); - - qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "Display", "Use enums only."); - qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataType", "Use enums only"); -// qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataEntity", "unknown"); - } -}; - } // UkuiMenu #endif //UKUI_MENU_COMMONS_H diff --git a/src/data-entity.cpp b/src/data-entity.cpp new file mode 100644 index 0000000..0b7ffd6 --- /dev/null +++ b/src/data-entity.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2023, 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 "data-entity.h" + +using namespace UkuiMenu; + +class DataEntityPrivate +{ +public: + DataEntityPrivate() = default; + DataEntityPrivate(DataType::Type type, QString name, QString icon, QString comment, QString extraData) + : type(type), name(std::move(name)), icon(std::move(icon)), comment(std::move(comment)), extraData(std::move(extraData)) {} + + bool lock{false}; // 应用锁定 + int top{0}; // 置顶状态及序号 + int favorite{0}; // 收藏状态及序号 + int launchTimes{0}; // 启动次数 + DataType::Type type {DataType::Normal}; + QString id; // 应用可执行文件路径 + QString icon; + QString name; + QString category; + QString firstLetter; + QString comment; // 应用描述 + QString extraData; // 额外的数据 +}; + +DataEntity::DataEntity() : d(new DataEntityPrivate) {} + +DataEntity::DataEntity(DataType::Type type, const QString& name, const QString& icon, const QString& comment, const QString& extraData) + : d(new DataEntityPrivate(type, name, icon, comment, extraData)) +{ + +} + +int DataEntity::top() const +{ + return d->top; +} + +void DataEntity::setTop(int top) +{ + d->top = top; +} + +bool DataEntity::isLock() const +{ + return d->lock; +} + +void DataEntity::setLock(bool lock) +{ + d->lock = lock; +} + +int DataEntity::favorite() const +{ + return d->favorite; +} + +void DataEntity::setFavorite(int favorite) +{ + d->favorite = favorite; +} + +int DataEntity::launchTimes() const +{ + return d->launchTimes; +} + +void DataEntity::setLaunchTimes(int launchTimes) +{ + d->launchTimes = launchTimes; +} + +QString DataEntity::id() const +{ + return d->id; +} + +void DataEntity::setId(const QString &id) +{ + d->id = id; +} + +void DataEntity::setCategory(const QString &category) +{ + d->category = category; +} + +QString DataEntity::category() const +{ + return d->category; +} + +void DataEntity::setFirstLetter(const QString &firstLetter) +{ + d->firstLetter = firstLetter; +} + +QString DataEntity::firstLetter() const +{ + return d->firstLetter; +} + +void DataEntity::setType(DataType::Type type) +{ + d->type = type; +} + +DataType::Type DataEntity::type() const +{ + return d->type; +} + +void DataEntity::setIcon(const QString &icon) +{ + d->icon = icon; +} + +QString DataEntity::icon() const +{ + return d->icon; +} + +void DataEntity::setName(const QString &name) +{ + d->name = name; +} + +QString DataEntity::name() const +{ + return d->name; +} + +void DataEntity::setComment(const QString &comment) +{ + d->comment = comment; +} + +QString DataEntity::comment() const +{ + return d->comment; +} + +void DataEntity::setExtraData(const QString &extraData) +{ + d->extraData = extraData; +} + +QString DataEntity::extraData() const +{ + return d->extraData; +} + +QHash DataEntity::AppRoleNames() +{ + QHash names; + names.insert(DataEntity::Id, "id"); + names.insert(DataEntity::Type, "type"); + names.insert(DataEntity::Icon, "icon"); + names.insert(DataEntity::Name, "name"); + names.insert(DataEntity::Comment, "comment"); + names.insert(DataEntity::ExtraData, "extraData"); + return names; +} + +DataEntity::DataEntity(const DataEntity &other) : d(new DataEntityPrivate) +{ + *d = *(other.d); +} + +DataEntity& DataEntity::operator=(const DataEntity &other) +{ + if (this != &other) { + *d = *(other.d); + } + return *this; +} + +DataEntity::DataEntity(DataEntity &&other) noexcept : d(new DataEntityPrivate) +{ + *d = *(other.d); +} + +DataEntity &DataEntity::operator=(DataEntity &&other) noexcept +{ + *d = *(other.d); + return *this; +} + +DataEntity::~DataEntity() +{ + if (d) { + delete d; + d = nullptr; + } +} diff --git a/src/data-entity.h b/src/data-entity.h new file mode 100644 index 0000000..ddd00e7 --- /dev/null +++ b/src/data-entity.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2023, 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 . + * + */ + +#ifndef UKUI_MENU_DATA_ENTITY_H +#define UKUI_MENU_DATA_ENTITY_H + +#include +#include + +class DataEntityPrivate; + +namespace UkuiMenu { + +class DataType +{ + Q_GADGET +public: + enum Type { + Normal, // 普通Item + Label, // 标签数据 + Folder // 文件夹 + }; + Q_ENUM(Type); +}; + +// 应用数据 +class DataEntity +{ + // TODO 改用 Q_OBJECT ? + Q_GADGET + Q_PROPERTY(DataType::Type type READ type WRITE setType) + Q_PROPERTY(QString id READ id) + Q_PROPERTY(QString icon READ icon WRITE setIcon) + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString comment READ comment WRITE setComment) + Q_PROPERTY(QString extraData READ extraData WRITE setExtraData) +public: + static QHash AppRoleNames(); + enum PropertyName { + Id = 0, + Type, + Icon, + Name, + Comment, + ExtraData + }; + DataEntity(); + DataEntity(DataType::Type type, const QString& name, const QString& icon, const QString& comment, const QString& extraData); + + virtual ~DataEntity(); + + DataEntity(const DataEntity& other); + DataEntity &operator=(const DataEntity& other); + DataEntity(DataEntity&& other) noexcept; + DataEntity &operator=(DataEntity&& other) noexcept; + + int top() const; + void setTop(int top); + + bool isLock() const; + void setLock(bool lock); + + int favorite() const; + void setFavorite(int favorite); + + int launchTimes() const; + void setLaunchTimes(int launchTimes); + + QString id() const; + void setId(const QString& id); + + void setCategory(const QString& category); + QString category() const; + + void setFirstLetter(const QString& firstLetter); + QString firstLetter() const; + + void setType(DataType::Type type); + DataType::Type type() const; + + void setIcon(const QString& icon); + QString icon() const; + + void setName(const QString& name); + QString name() const; + + void setComment(const QString& comment); + QString comment() const; + + void setExtraData(const QString& extraData); + QString extraData() const; + +private: + DataEntityPrivate *d {nullptr}; +}; + +} // UkuiMenu + +#endif //UKUI_MENU_DATA_ENTITY_H diff --git a/src/menu/menu-manager.cpp b/src/menu/menu-manager.cpp index b3093ad..7073646 100644 --- a/src/menu/menu-manager.cpp +++ b/src/menu/menu-manager.cpp @@ -24,8 +24,17 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include -namespace UkuiMenu { +using namespace UkuiMenu; class AppMenuProvider : public MenuProvider { @@ -157,14 +166,20 @@ MenuManager *MenuManager::instance() return &manager; } -MenuManager::MenuManager() +class MenuManagerPrivate { - registerMenuProvider(new AppMenuProvider); +public: + QList providers; +}; + +MenuManager::MenuManager() : d(new MenuManagerPrivate) +{ + loadMenus(); } MenuManager::~MenuManager() { - for (auto &provider : m_providers) { + for (auto &provider : d->providers) { delete provider; provider = nullptr; } @@ -176,7 +191,11 @@ void MenuManager::registerMenuProvider(MenuProvider *provider) return; } - m_providers.append(provider); + d->providers.append(provider); + + std::sort(d->providers.begin(), d->providers.end(), [=] (MenuProvider *a, MenuProvider *b) { + return a->index() < b->index(); + }); } void MenuManager::showMenu(const QString &appid, const QPoint &point) @@ -197,7 +216,7 @@ void MenuManager::showMenu(const MenuProvider::RequestType &type, const QVariant QMenu menu; QList actions; - for (const auto &provider : m_providers) { + for (const auto &provider : d->providers) { actions.append(provider->generateActions(&menu, type, data)); } @@ -217,4 +236,34 @@ inline QPoint MenuManager::checkPoint(const QPoint &rawPoint) return rawPoint; } -} // UkuiMenu +void MenuManager::loadMenus() +{ + QDir pluginsDir(UKUI_MENU_CONTEXT_MENU_DIR); + pluginsDir.setFilter(QDir::Files); + for(const QString& fileName : pluginsDir.entryList(QDir::Files)) { + QPluginLoader pluginLoader(pluginsDir.absoluteFilePath(fileName)); + QJsonObject metaData = pluginLoader.metaData().value("MetaData").toObject(); + QString type = metaData.value("Type").toString(); + QString version = metaData.value("Version").toString(); + if(type != UKUI_MENU_CONTEXTMENU_TYPE) { + continue; + } + + if(version != UKUI_MENU_CONTEXTMENU_IFACE_VERSION) { + qWarning() << "UKUI_MENU_CONTEXTMENU version check failed:" << fileName << "version:" << version << "iface version : " << UKUI_MENU_CONTEXTMENU_IFACE_VERSION; + continue; + } + + QObject *obj = pluginLoader.instance(); + if (!obj) { + continue; + } + + MenuProvider *provider = qobject_cast(obj); + if (!provider) { + continue; + } + + registerMenuProvider(provider); + } +} diff --git a/src/menu/menu-manager.h b/src/menu/menu-manager.h index 4e3d199..935e26e 100644 --- a/src/menu/menu-manager.h +++ b/src/menu/menu-manager.h @@ -20,25 +20,15 @@ #define UKUI_MENU_MENU_MANAGER_H #include -#include #include -#include "commons.h" +#include "data-entity.h" +#include "menu-provider.h" + +class MenuManagerPrivate; namespace UkuiMenu { -class MenuProvider -{ -public: - enum RequestType { - DataType = 0, - Custom, - }; - virtual ~MenuProvider() = default; - virtual int index() = 0; - virtual QList generateActions(QObject *parent, const RequestType &type, const QVariant &data) = 0; -}; - class MenuManager : public QObject { Q_OBJECT @@ -52,10 +42,11 @@ public: private: MenuManager(); + void loadMenus(); inline QPoint checkPoint(const QPoint &rawPoint); private: - QList m_providers; + MenuManagerPrivate *d {nullptr}; }; } // UkuiMenu diff --git a/src/menu/menu-provider.h b/src/menu/menu-provider.h new file mode 100644 index 0000000..4c9a7c5 --- /dev/null +++ b/src/menu/menu-provider.h @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2023, 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 . + * + */ + +#ifndef UKUI_MENU_MENU_PROVIDER_H +#define UKUI_MENU_MENU_PROVIDER_H + +#include +#include + +#define UKUI_MENU_CONTEXTMENU_TYPE "UKUI_MENU_CONTEXTMENU" +#define UKUI_MENU_CONTEXTMENU_IFACE_IID "org.ukui.menu.contextMenu" +#define UKUI_MENU_CONTEXTMENU_IFACE_VERSION "1.0.0" + +namespace UkuiMenu { + +class MenuProvider +{ +public: + enum RequestType { + DataType = 0, + Custom, + }; + virtual ~MenuProvider() = default; + virtual int index() = 0; + virtual QList generateActions(QObject *parent, const RequestType &type, const QVariant &data) = 0; +}; + +} // UkuiMenu + +Q_DECLARE_INTERFACE(UkuiMenu::MenuProvider, UKUI_MENU_CONTEXTMENU_IFACE_IID) + +#endif //UKUI_MENU_MENU_PROVIDER_H diff --git a/src/ukui-menu-application.cpp b/src/ukui-menu-application.cpp index d1bc280..60b9158 100644 --- a/src/ukui-menu-application.cpp +++ b/src/ukui-menu-application.cpp @@ -56,13 +56,19 @@ void UkuiMenuApplication::registerQmlTypes() { const char *uri = "org.ukui.menu.core"; int versionMajor = 1, versionMinor = 0; - CommonsModule::defineModule(uri, versionMajor, versionMinor); SettingModule::defineModule(uri, versionMajor, versionMinor); WindowModule::defineModule(uri, versionMajor, versionMinor); PowerButton::defineModule(uri, versionMajor, versionMinor); ModelManager::registerMetaTypes(); + // commons + qRegisterMetaType("DataType::Type"); + qRegisterMetaType("DataEntity"); + qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "Display", "Use enums only."); + qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataType", "Use enums only"); +// qmlRegisterUncreatableType(uri, versionMajor, versionMinor, "DataEntity", "unknown"); + // vis colors qmlRegisterType(uri, versionMajor, versionMinor, "ThemeIcon"); qRegisterMetaType("Palette::ColorRole");